This chapter describes the debugging macros and routines provided by Digital for SCSI/CAM peripheral device driver writers.
There are two levels of debugging within the CAM modules: debugging independent of a bus, target, or LUN; and debugging that tracks a specific bus, target, or LUN. S/CA debugging is turned on by defining the program constant CAMDEBUG in the /usr/sys/include/io/cam/cam_debug.h file and by recompiling the source files.
This section describes the variables that contain the information for each level of debugging the CAM subsystem. The variables are:
The macros PRINTD and CALLD use the variables for tracking target-specific messages and for allowing specific subsets of the DEBUG statements to be printed. The macros are defined in the /usr/sys/include/io/cam/cam_debug.h file.
The most significant bit, bit 31, of the camdbg_flag variable is the bit that indicates whether the target information is valid. If set, it indicates that the camdbg_id variable contains valid bus, target, and LUN information for the device to be tracked. Bits 30 to 0 define the debug flag setting. The possible settings, in ascending hexadecimal order, with a brief description of each, follow:
Flag Name | Description |
CAMD_INOUT | Routine entry and exit |
CAMD_FLOW | Code flow through the modules |
CAMD_PHASE | SCSI phase values |
CAMD_SM | State machine settings |
CAMD_ERRORS | Error handling |
CAMD_CMD_EXP | Expansion of commands and responses |
CAMD_IO_MAPPING | Data Movement Engine I/O mapping for user space |
CAMD_DMA_FLOW | Data Movement Engine flow |
CAMD_DISCONNECT | Signal disconnect handling |
CAMD_TAGS | Tag queuing code |
CAMD_POOL | XPT tracking in the DEC CAM packet pool |
CAMD_AUTOS | Autosense handling |
CAMD_CCBALLOC | CCB allocation and free flow |
CAMD_MSGOUT | Messages going out |
CAMD_MSGIN | Messages coming in |
CAMD_STATUS | SCSI status bytes |
CAMD_CONFIG | CAM configuration paths |
CAMD_SCHED | SIM scheduler points |
CAMD_SIMQ | SIM queue manipulation |
CAMD_TAPE | SCSI/CAM peripheral tape flow |
CAMD_COMMON | SCSI/CAM peripheral common flow |
CAMD_DISK | SCSI/CAM peripheral disk flow |
CAMD_DISK_REC | SCSI/CAM peripheral disk recovery flow |
CAMD_DBBR | SCSI/CAM peripheral disk Dynamic Bad Block Recovery flow |
CAMD_CDROM | SCSI/CAM peripheral CDROM functions |
CAMD_INTERRUPT | SIM trace Interrupts |
TVALID | Bus, target, and LUN bits are valid in the camdbg_id variable |
The camdbg_id variable contains the bus, target, and LUN (B, T, and L) information for a specific target to track for debugging information. In the current implementation, the bits are divided into three parts, with the remainder reserved. The bits are allocated as follows: bits 31 to 16, reserved; bits 15 to 8, bus number; bits 7 to 4, target number; and bits 3 to 0, LUN number. Multiples of 4 bits are used to assign hexadecimal values into the camdbg_id variable.
The PRINTD and CALLD macros track target-specific messages and allow specific subsets of the debugging statements to be printed.
This PRINTD macro, which prints debugging information if CAMDEBUG is defined, follows.
/* * Conditionally Print Debug Information. */ #if defined(CAMDEBUG) && !defined(lint) # define PRINTD(B, T, L, F, X) { \ [1] /* NOSTRICT */ \ if( camdbg_flag & (int)F ) \ [2] { \ if( ((camdbg_flag & TVALID) == 0) || \ [3] (((camdbg_flag & TVALID) != 0) && \ [4] ((((camdbg_id & BMASK) >> BSHIFT) == B) || (B == NOBTL)) && \ [5] ((((camdbg_id & TMASK) >> TSHIFT) == T) || (T == NOBTL)) && \ ((((camdbg_id & LMASK) >> LSHIFT) == L) || (L == NOBTL))) ) \ { \ /* VARARGS */ \ (void)(*cdbg_printf) X ; \ } \ } \ } #endif
((((camdbg_id & BMASK) >> BSHIFT) == B) || (B == NOBTL))
The statement masks out the other fields and shifts the bus value down to allow comparison with the B argument. The arguments can also have a wildcard value, NOBTL. When the wildcard value is used, the B or T or L comparison is always true. [Return to example]
The CALLD macro uses the same if statement constructs to conditionally call a debugging function by using the following define statement:
# define CALLD(B, T, L, F, X)
The X is a call to a CAM debugging routine described in the following section.
The SCSI/CAM peripheral device debugging routines can be allocated into categories as follows:
Appendix C lists the routines alphabetically and includes descriptions and syntax information in Digital UNIX reference-page format.
This section describes the SCSI/CAM peripheral device debugging routines that report status. Table 10-1 lists the name of each routine and gives a summary description of its function. The sections that follow contain a more detailed description of each routine.
Routine | Summary Description |
cdbg_CamFunction | Reports CAM XPT function codes. |
cdbg_CamStatus | Decodes CAM CCB status codes. |
cdbg_ScsiStatus | Reports SCSI status codes. |
cdbg_SystemStatus | Reports system error codes. |
The cdbg_CamFunction routine reports CAM XPT function codes. Program constants are defined to allow either the function code name only or a brief explanation to be printed. The XPT function codes are defined in the /usr/sys/include/io/cam/cam.h file.
The cdbg_CamStatus routine decodes CAM CCB status codes. Program constants are defined to allow either the status code name only or a brief explanation to be printed. The CAM status codes are defined in the /usr/sys/include/io/cam/cam.h file.
The cdbg_ScsiStatus routine reports SCSI status codes. Program constants are defined to allow either the status code name only or a brief explanation to be printed. The SCSI status codes are defined in the /usr/sys/include/io/cam/scsi_status.h file.
The cdbg_SystemStatus routine reports system error codes. The system error codes are defined in the /usr/sys/include/sys/errno.h file.
This section describes the SCSI/CAM peripheral device debugging routines that dump contents for examination. Table 10-2 lists the name of each routine and gives a summary description of its function. The sections that follow contain a more detailed description of each routine.
Routine | Summary Description |
cdbg_DumpCCBHeader | Dumps the contents of a CAM control block (CCB) header structure. |
cdbg_DumpCCBHeaderFlags | Dumps the contents of the cam_flags member of a CAM control block (CCB) header structure. |
cdbg_DumpSCSIIO | Dumps the contents of a SCSI I/O CCB. |
cdbg_DumpPDRVws | Dumps the contents of a SCSI/CAM Peripheral Device Driver Working Set structure. |
cdbg_DumpABORT | Dumps the contents of an ABORT CCB. |
cdbg_DumpTERMIO | Dumps the contents of a TERMINATE I/O CCB. |
cdbg_DumpBuffer | Dumps the contents of a data buffer in hexadecimal bytes. |
cdbg_GetDeviceName | Returns a pointer to a character string that describes the dtype member of an ALL_INQ_DATA structure. |
cdbg_DumpInquiryData | Dumps the contents of an ALL_INQ_DATA structure. |
The cdbg_DumpCCBHeader routine dumps the contents of a CAM control block (CCB) header structure. The CCB header structure is defined in the /usr/sys/include/io/cam/cam.h file.
The cdbg_DumpCCBHeaderFlags routine dumps the contents of the cam_flags member of a CAM control block (CCB) header structure. The CCB header structure is defined in the /usr/sys/include/io/cam/cam.h file.
The cdbg_DumpSCSIIO routine dumps the contents of a SCSI I/O CCB. The SCSI I/O CCB is defined in the /usr/sys/include/io/cam/cam.h file.
The cdbg_DumpPDRVws routine dumps the contents of a SCSI/CAM Peripheral Device Driver Working Set structure. The SCSI/CAM Peripheral Device Driver Working Set structure is defined in the /usr/sys/include/io/cam/pdrv.h file.
The cdbg_DumpABORT routine dumps the contents of an ABORT CCB. The ABORT CCB is defined in the /usr/sys/include/io/cam/cam.h file.
The cdbg_DumpTERMIO routine dumps the contents of a TERMINATE I/O CCB. The TERMINATE I/O CCB is defined in the /usr/sys/include/io/cam/cam.h file.
The cdbg_DumpBuffer routine dumps the contents of a data buffer in hexadecimal bytes. The calling routine must display a header line. The format of the dump is 16 bytes per line.
The cdbg_GetDeviceName routine returns a pointer to a character string that describes the dtype member of an ALL_INQ_DATA structure. The ALL_INQ_DATA structure is defined in the /usr/sys/include/io/cam/scsi_all.h file.
The cdbg_DumpInquiryData routine dumps the contents of an ALL_INQ_DATA structure. The ALL_INQ_DATA structure is defined in the /usr/sys/include/io/cam/scsi_all.h file.