[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


10    S/CA Debugging Facilities

This chapter describes the debugging macros and routines provided by Digital for SCSI/CAM peripheral device driver writers.


[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


10.1    CAM Debugging Variables

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.1.1    The camdbg_flag Variable

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


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.1.2    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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.2    CAM Debugging Macros

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

  1. The B, T, and L arguments are for target-specific tracking. The F argument is a flag for tracking specific subsets of the printf statements. The F flag argument is compared with the camdbg_flag variable to determine if the user wants to see the message. The X argument must be a complete printf argument set enclosed within parentheses ( ) to allow the preprocessor to include it in the final printf statement. [Return to example]

  2. Checks to see if any of the flags for the PRINTD macro are turned on. It does not look for an exact match so that the same PRINTD macro can be used for different settings of the flags in camdbg_flag. [Return to example]

  3. Checks for any target information available for tracing a target. The first condition checks to see if the target valid bit is not set. If it is not, the OR condition is met and the call to the printf utility is made. [Return to example]

  4. If the TVALID bit is set, the bus, target, and LUN fields in the camdbg_id variable must be compared to the B, T, and L arguments. If TVALID is true and bus equals B, target equals T, and LUN equals L, then also print. [Return to example]

  5. Checks the B, T, and L fields. For example, the following statement checks the B field:

    ((((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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3    CAM Debugging Routines

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3.1    CAM Debugging Status Routines

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.

Table 10-1: CAM Debugging Status Routines

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3.1.1    The cdbg_CamFunction Routine

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3.1.2    The cdbg_CamStatus Routine

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3.1.3    The cdbg_ScsiStatus Routine

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3.1.4    The cdbg_SystemStatus Routine

The cdbg_SystemStatus routine reports system error codes. The system error codes are defined in the /usr/sys/include/sys/errno.h file.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3.2    CAM Dump Routines

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.

Table 10-2: CAM Dump Routines

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3.2.1    The cdbg_DumpCCBHeader Routine

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3.2.2    The cdbg_DumpCCBHeaderFlags Routine

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3.2.3    The cdbg_DumpSCSIIO Routine

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3.2.4    The cdbg_DumpPDRVws Routine

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3.2.5    The cdbg_DumpABORT Routine

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3.2.6    The cdbg_DumpTERMIO Routine

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3.2.7    The cdbg_DumpBuffer Routine

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


10.3.2.8    The cdbg_GetDeviceName Routine

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.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Chapter] [Index] [Help]


10.3.2.9    The cdbg_DumpInquiryData Routine

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.