This chapter describes the error-logging macros, data structures, and routines provided by Digital for SCSI/CAM peripheral device driver writers.
Digital supplies an error-logging macro, CAM_ERROR, with the S/CA software. SCSI device driver writers can activate the macro by defining the constant CAMERRLOG. Errors are reported using the same error-logging interface to each of the modules within the CAM subsystem.
The macro is defined in the /usr/sys/include/io/cam/cam_errlog.h file as follows:.
static void (*local_errorlog)();
The CAM_ERROR() macro presents a consistent error-logging interface to the modules within the CAM subsystem. Using the macro lets all the routines within each module that need to report and log error information use the same macro call and arguments. Using this macro also keeps each reported error string with the code within the module that originally reported the error.
Individual modules contain their own module-specific error-logging routines. Each source file contains a declaration of the pointer to the local error-logging routine as follows:
static void (*local_errorlog)();
The macro calls the local error-logging routine through the local pointer. The pointer is loaded with the local error-handler address, either within the initialization code for that module or as part of the initialized data. The following example shows the address of the sx_errorlog function being loaded to the local error-logging variable, local_errlog:
extern void sx_errorlog(); static void (*local_errlog)() = sx_errorlog;
SCSI/CAM peripheral common modules can declare the local pointer to contain the error handler from another SCSI/CAM peripheral common module.
This section describes the following CAM error-logging data structures:
The structures are defined in the /usr/sys/include/io/cam/cam_logger.h file.
The Error Entry structure, CAM_ERR_ENTRY, describes an entry in the error log packet. There can be multiple entries in an error log packet. The structure is defined as follows:
typedef struct cam_err_entry { u_long ent_type; /* String, TAPE_SPECIFIC, CCB, etc */ u_long ent_size; /* Size of the data (CCB, TAPE_SPEC)*/ u_long ent_total_size; /* To preserve alignment (uerf) */ u_long ent_vers; /* Version number of type */ u_char *ent_data; /* Pointer to whatever string, etc */ u_long ent_pri; /* FULL or Brief uerf output */ }CAM_ERR_ENTRY;
The ent_type member contains the type of data in the entry, which can be a string, a structure, or a CCB. Numerous types of strings are defined in the /usr/sys/include/io/cam/cam_logger.h file. CCBs are assigned to one of the XPT function codes listed in the /usr/sys/include/io/cam/cam.h file.
The ent_size member contains the size (in bytes) of the data in the entry.
The ent_total_size member preserves longword alignment for compatibility with the uerf error-reporting utility. The cam_logger routine fills in this member. See System Administration for more information about the uerf utility.
The ent_vers member is the version number of the contents of the ent_type member. See the #define PDRV_DEVICE_VERS line in the /usr/sys/include/io/cam/pdrv.h file for an example of associating a version number with a structure.
The ent_data member contains a pointer to the contents of the ent_type member.
The ent_pri member contains the output from the uerf utility, which can be in brief or full report format. See System Administration for information about the uerf utility.
The Error Header structure, CAM_ERR_HDR, contains all the data needed by the uerf utility to determine that the packet is a CAM error log packet. See System Administration for information about the uerf utility. The structure is defined as follows:
typedef struct cam_err_hdr { u_short hdr_type; /* Packet type - CAM_ERR_PKT */ u_long hdr_size; /* Filled in by cam_logger */ u_char hdr_class; /* Sub system class Tape, disk, * sii_dme , etc.. */ u_long hdr_subsystem; /* * Mostly for controller type * But the current errlogger uses * disk tape etc if no controller * is known.. So what we will do * is dup the disk and tape types * in the lower number 0 - 1f and * the controllers asc sii 5380 * etc can use the uppers. */ u_long hdr_entries; /* Number of error entries in list*/ CAM_ERR_ENTRY *hdr_list; /* Pointer to list of error entries*/ u_long hdr_pri; /* Error logger priority. */ }CAM_ERR_HDR;
The hdr_type member contains the error-packet type, which must be CAM_ERR_PKT.
The hdr_size member is filled in by the cam_logger routine.
The hdr_class member identifies the CAM module that detected the error and assigns it to one of the Defined Device Types listed in the /usr/sys/include/io/cam/scsi_all.h file. The device classes are defined in the /usr/sys/include/io/cam/cam_logger.h file.
The hdr_subsystem member identifies the CAM subsystem controller that detected the error and assigns it to one of the Defined Device Types listed in the /usr/sys/include/io/cam/scsi_all.h file. The device classes are defined in the /usr/sys/include/io/cam/cam_logger.h file.
The hdr_entries member contains the number of entries in the header list.
The hdr_list member contains a pointer to a list of error entries.
The hdr_pri member identifies the priority of the error and assigns it to one of the priorities listed in the /usr/sys/include/io/cam/errlog.h file.
This section discusses event reporting.
To see all the CAM error reports when you use the uerf utility, use the -o full option. For example:
uerf -o full | more
The cam_logger routine allocates a system error log buffer and fills in a uerf error log packet. The routine fills in the bus, target, and LUN information from the Error Header structure passed to it and copies the Error Header structure and the Error Entry structures and data to the error log buffer.