This chapter describes the common data structures, macros, and routines provided by Digital for SCSI/CAM peripheral device driver writers. The generic SCSI/CAM peripheral device driver routines described in Chapter 4 use these data structures, macros, and routines.
Using the common and generic routines helps ensure that your SCSI/CAM peripheral device drivers are consistent with the SCSI/CAM Architecture. See Chapter 11 if you plan to define your own SCSI/CAM peripheral device drivers. See Chapter 12 for information about the SCSI/CAM special I/O interface to process special SCSI I/O commands.
This section describes the following SCSI/CAM peripheral common data structures:
The descriptions provide information only for those members of a data structure that a SCSI/CAM device driver writer needs to understand.
The Peripheral Device Unit Table is an array of SCSI/CAM peripheral device unit elements. The size of the array is the maximum number of possible devices, which is determined by the maximum number of SCSI controllers allowed for the system.
The structure is allocated statically and is defined as follows:
typedef struct pdrv_unit_elem { PDRV_DEVICE *pu_device; /* Pointer to peripheral device structure */ u_short pu_opens; /* Total number of opens against unit */ u_short pu_config; /* Indicates whether the device type */ /* configured at this address */ u_char pu_type; /* Device type - byte 0 from inquiry data */ PDRV_UNIT_ELEM;
The pu_device field is filled in with a pointer to a CAM-allocated peripheral SCSI device (PDRV_DEVICE) structure when the first call to the ccmn_open_unit routine is issued for a SCSI device that exists.
A SCSI/CAM peripheral device structure, PDRV_DEVICE, is allocated for each SCSI device that exists in the system. This structure contains the queue header structure for the SCSI/CAM peripheral device driver CAM control block (CCB) request queue. It also contains the inquiry data obtained from a GET DEVICE TYPE CCB.
Table 3-1 lists the members of the PDRV_DEVICE structure that a SCSI/CAM peripheral device driver writer, using the common routines provided by Digital, must use. Chapter 11 shows the complete structure for those driver writers who are not using the common routines.
Member Name | Data Type | Description |
pd_dev | dev_t | The major/minor device number pair that identifies the bus number, target ID, and LUN associated with this SCSI device. Passed to the common open routine. |
pd_bus | u_char | SCSI target's bus controller number. |
pd_target | u_char | SCSI target's ID number. |
pd_lun | u_char | SCSI target's logical unit number. |
pd_flags | u_long | May be used to indicate the state of a SCSI device driver. |
pd_state | u_char | May be used for recovery. |
pd_abort_cnt | u_char | May be used for recovery. |
pd_dev_inq[INQLEN] | u_char | Inquiry data obtained from issuing a GET DEVICE TYPE CCB. |
*pd_dev_desc | DEV_DESC | Pointer to the SCSI device descriptor. |
pd_specific | caddr_t | Pointer to device-specific information. |
pd_spec_size | u_long | Size of device-specific information structure. |
*(pd_recov_hand)() | void | Recovery handler. |
pd_lk_device | lock_t | SMP lock for the device. |
The pd_specific field is filled in with a pointer to an allocated structure that contains device-specific information.
The pd_dev member specifies the major/minor device number pair that identifies the bus number, target ID, and LUN associated with this SCSI device.
The pd_spec_size member specifies the size (in bytes) of the device-specific information structure passed from the SCSI device driver to the common open routine.
There is a read-only SCSI device descriptor structure, DEV_DESC, defined for each device supported by Digital. A user may supply a new DEV_DESC structure by adding it to /usr/sys/data/cam_data.c and relinking the kernel. The DEV_DESC structure follows:
typedef struct dev_desc { u_char dd_pv_name[IDSTRING_SIZE]; /* Product ID and vendor string from */ /* Inquiry data */ u_char dd_length; /* Length of dd_pv_name string */ u_char dd_dev_name[DEV_NAME_SIZE]; /* Device name string - see defines */ /* in devio.h */ U32 dd_device_type; /* Bits 0 - 23 contain the device */ /* class, bits 24-31 contain the */ /* SCSI device type */ struct pt_info *dd_def_partition; /* Default partition sizes - disks */ U32 dd_block_size; /* Block/sector size */ U32 dd_max_record; /* Maximum transfer size in bytes */ /* allowed for the device */ DENSITY_TBL *dd_density_tbl; /* Pointer to density table - tapes */ MODESEL_TBL *dd_modesel_tbl; /* Mode select table pointer - used */ /* on open and recovery */ U32 dd_flags; /* Option flags (bbr, etc) */ U32 dd_scsi_optcmds; /* Optional commands supported */ U32 dd_ready_time; /* Time in seconds for powerup dev ready */ u_short dd_que_depth; /* Device queue depth for devices */ /* which support command queueing */ u_char dd_valid; /* Indicates which data length */ /* fields are valid */ u_char dd_inq_len; /* Inquiry data length for device */ u_char dd_req_sense_len; /* Request sense data length for */ /* this device */ }DEV_DESC;
The Mode Select Table structure is read and sent to the SCSI device when the first call to the SCSI/CAM peripheral open routine is issued on a SCSI device. There can be a maximum of eight entries in the Mode Select Table structure. Chapter 11 contains a description of each structure member. The definition for the Mode Select Table structure, MODESEL_TBL, follows:
typedef struct modesel_tbl { struct ms_entry{ u_char ms_page; /* Page number */ u_char *ms_data; /* Pointer to Mode Select data */ u_char ms_data_len; /* Mode Select data length */ u_char ms_ent_sp_pf; /* Save Page and Page format bits */ /* BIT 0 1=Save Page, */ /* 0=Don't Save Page */ /* BIT 1 1=SCSI-2, 0=SCSI-1 */ }ms_entry[MAX_OPEN_SELS]; }MODESEL_TBL;
The Density Table structure allows for the definition of eight densities for each type of SCSI tape device unit. Chapter 11 contains a description of each structure member. The definition for the Density Table structure, DENSITY_TBL, follows:
typedef struct density_tbl { struct density{ u_char den_flags; /* VALID, ONE_FM etc */ u_char den_density_code; u_char den_compress_code; /* Compression code if supported */ u_char den_speed_setting; /* for this density */ u_char den_buffered_setting; /* Buffer control setting */ u_long den_blocking; /* 0 variable etc. */ }density[MAX_TAPE_DENSITY]; }DENSITY_TBL;
The den_blocking member contains the blocking factor for this SCSI tape device. A NULL (0) setting specifies that the blocking factor is variable. A positive value represents the number of bytes in a block, for example, 512 or 1024.
The SCSI I/O CCB contains cam_pdrv_ptr, a pointer to the SCSI/CAM peripheral device driver working set area for the CCB. This structure is also allocated by the XPT when the xpt_ccb_alloc routine is called to allocate a CCB. The PDRV_WS structure follows:
typedef struct pdrv_ws { struct pdrv_ws *pws_flink; /* Linkage of working set CCBs */ struct pdrv_ws *pws_blink; /* that we have queued */ CCB_SCSIIO *pws_ccb; /* Pointer to this CCB. */ u_long pws_flags; /* Generic to driver */ u_long pws_retry_cnt; /* Retry count for this request */ u_char *pws_pdrv; /* Pointer to peripheral device */ /* structure */ u_char pws_sense_buf[DEC_AUTO_SENSE_SIZE]; } PDRV_WS;
The pws_flink member of the pdrv_ws structure is a pointer to the forward link of the working set CCBs that have been queued.
The pws_blink member of the pdrv_ws structure is a pointer to the backward link of the working set CCBs that have been queued.
The pws_ccb member is a pointer to this CCB. The CCB header is filled in by the common routines.
The SCSI/CAM peripheral device driver common macros are supplied by Digital for SCSI device driver writers to use. These macros are defined in the /usr/sys/include/io/cam/pdrv.h file. There are two categories of macros:
Table 3-2 lists each identification macro name, its call syntax, and a brief description of its purpose.
Name | Syntax | Description |
DEV_BUS_ID | DEV_BUS_ID(dev) | |
Returns the bus ID of the device that is identified in the major/minor device number pair. | ||
DEV_TARGET | DEV_TARGET(dev) | |
Returns the target ID of the device that is identified in the major/minor device number pair. | ||
DEV_LUN | DEV_LUN(dev) | |
Returns the target LUN of the device that is identified in the major/minor device number pair. | ||
GET_PDRV_UNIT_ELEM | GET_PDRV_UNIT_ELEM(dev) | |
Returns the Peripheral Device Unit Table entry for the device that is identified in the major/minor device number pair. | ||
GET_PDRV_PTR | GET_PDRV_PTR(dev) | |
Returns the pointer to the Peripheral Device structure for the device that is identified in the major/minor device number pair. |
Table 3-3 lists each locking macro name, its call syntax, and a brief description of its purpose.
Note
Symmetric Multiprocessing (SMP) is not enabled in this release.
Name | Syntax | Description |
PDRV_INIT_LOCK | PDRV_INIT_LOCK(pd) | |
Initializes the Peripheral Device structure lock. | ||
PDRV_IPLSMP_LOCK | PDRV_IPLSMP_LOCK(pd, lk_type, saveipl) | |
Raises the IPL and locks the Peripheral Device structure. | ||
PDRV_IPLSMP_UNLOCK | PDRV_IPLSMP_UNLOCK(pd, saveipl) | |
Unlocks the Peripheral Device structure and lowers the IPL. | ||
PDRV_SMP_LOCK | PDRV_SMP_LOCK(pd) | |
Locks the Peripheral Device structure. | ||
PDRV_SMP_SLEEPUNLOCK | PDRV_SMP_SLEEPUNLOCK(chan, pri, pd) | |
Unlocks the Peripheral Device structure. |
The SCSI/CAM peripheral common device driver 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 common SCSI/CAM peripheral device driver initialization and I/O routines. Table 3-4 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 |
ccmn_init | Initializes the XPT and the unit table lock structure. |
ccmn_open_unit | Handles the common open for all SCSI/CAM peripheral device drivers. |
ccmn_close_unit | Handles the common close for all SCSI/CAM peripheral device drivers. |
The ccmn_init routine initializes the XPT and the unit table lock structure. The first time the ccmn_init routine is called, it calls the xpt_init routine to request the XPT to initialize the CAM subsystem.
The ccmn_open_unit routine handles the common open for all SCSI/CAM peripheral device drivers. It must be called for each open before any SCSI device-specific open code is executed.
On the first call to the ccmn_open_unit routine for a device, the ccmn_gdev_ccb_bld routine is called to issue a GET DEVICE TYPE CCB to obtain the Inquiry data. The ccmn_open_unit routine allocates the Peripheral Device structure, PDRV_DEVICE, and a device-specific structure, either TAPE_SPECIFIC or DISK_SPECIFIC, based on the device size argument passed. The routine also searches the cam_devdesc_tab to obtain a pointer to the Device Descriptor structure for the SCSI device and increments the open count. The statically allocated pdrv_unit_table structure contains a pointer to the PDRV_DEVICE structure. The PDRV_DEVICE structure contains pointers to the DEV_DESC structure and to the device-specific structure.
The ccmn_close_unit routine handles the common close for all SCSI/CAM peripheral device drivers. It sets the open count to zero.
This section describes the common SCSI/CAM peripheral device driver queue manipulation routines. Table 3-5 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 |
ccmn_send_ccb | Sends CCBs to the XPT layer by calling the xpt_action routine. |
ccmn_send_ccb_wait | Sends SCSI I/O CCBs to the XPT layer by calling the xpt_action routine and then sleeps while waiting for the CCB to complete. This function assumes that the callback completion function for the SCSI I/O CCB will issue the wakeup. |
ccmn_rem_ccb | Removes a SCSI I/O CCB request from the SCSI/CAM peripheral driver active queue and starts a tagged request if a tagged CCB is pending. |
ccmn_abort_que | Sends an ABORT CCB request for each SCSI I/O CCB on the active queue. |
ccmn_term_que | Sends a TERMINATE I/O CCB request for each SCSI I/O CCB on the active queue. |
The ccmn_send_ccb routine sends CCBs to the XPT layer by calling the xpt_action routine. This routine must be called with the Peripheral Device structure locked.
For SCSI I/O CCBs that are not retries, the request is placed on the active queue. If the CCB is a tagged request and the tag queue size for the device has been reached, the request is placed on the tagged pending queue so that the request can be sent to the XPT at a later time. A high-water mark of half the queue depth for the SCSI device is used for tagged requests so that other initiators on the SCSI bus will not be blocked from using the device. (The queue depth is defined in the device descriptor entry for the device.)
The ccmn_send_ccb_wait routine sends SCSI I/O CCBs to the XPT layer by calling xpt_action. The routine then calls sleep to wait for the CCB to complete. This routine must be called with the peripheral device structure locked. The ccmn_send_ccb_wait routine requires the callback completion function to issue a wakeup on the address of the CCB. If the sleep priority is greater than PZERO, the ccmn_send_ccb_wait routine sleeps at an interruptible priority in order to catch signals.
For SCSI I/O CCBs that are not retries, the request is placed on the active queue. If the CCB is a tagged request and the tag queue size for the device has been reached, the request is placed on the tagged pending queue so that the request can be sent to the XPT at a later time. A high-water mark of half the queue depth for the SCSI device is used for tagged requests so that other initiators on the SCSI bus will not be blocked from using the device. (The queue depth is defined in the device descriptor entry for the device.)
The ccmn_rem_ccb routine removes a SCSI I/O CCB request from the SCSI/CAM peripheral driver active queue and starts a tagged request if a tagged CCB is pending. If a tagged CCB is pending, the ccmn_rem_ccb routine places the request on the active queue and calls the xpt_action routine to start the tagged request.
The ccmn_abort_que routine sends an ABORT CCB request for each SCSI I/O CCB on the active queue. This routine must be called with the Peripheral Device structure locked.
The ccmn_abort_que routine calls the ccmn_abort_ccb_bld routine to create an ABORT CCB for the first active CCB on the active queue and to send it to the XPT. It calls the ccmn_send_ccb routine to send the ABORT CCB for each of the other CCBs on the active queue that are marked as active to the XPT. The ccmn_abort_que routine then calls the ccmn_rel_ccb routine to return the ABORT CCB to the XPT.
The ccmn_term_que routine sends a TERMINATE I/O CCB request for each SCSI I/O CCB on the active queue. This routine must be called with the Peripheral Device structure locked.
The ccmn_term_que routine calls the ccmn_term_ccb_bld routine to create a TERMINATE I/O CCB for the first active CCB on the active queue and to send it to the XPT. It calls the ccmn_send_ccb routine to send the TERMINATE I/O CCB for each of the other CCBs on the active queue that are marked as active to the XPT. The ccmn_term_que routine then calls the ccmn_rel_ccb routine to return the TERMINATE I/O CCB to the XPT.
This section describes the common SCSI/CAM peripheral device driver CCB allocation, build, and deallocation routines. Table 3-6 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 |
ccmn_get_ccb | Allocates a CCB and fills in the common portion of the CCB header. |
ccmn_rel_ccb | Releases a CCB and returns the sense data buffer for SCSI I/O CCBs, if allocated. |
ccmn_io_ccb_bld | Allocates a SCSI I/O CCB and fills it in. |
ccmn_gdev_ccb_bld | Creates a GET DEVICE TYPE CCB and sends it to the XPT. |
ccmn_sdev_ccb_bld | Creates a SET DEVICE TYPE CCB and sends it to the XPT. |
ccmn_sasy_ccb_bld | Creates a SET ASYNCHRONOUS CALLBACK CCB and sends it to the XPT. |
ccmn_rsq_ccb_bld | Creates a RELEASE SIM QUEUE CCB and sends it to the XPT. |
ccmn_pinq_ccb_bld | Creates a PATH INQUIRY CCB and sends it to the XPT. |
ccmn_abort_ccb_bld | Creates an ABORT CCB and sends it to the XPT. |
ccmn_term_ccb_bld | Creates a TERMINATE I/O CCB and sends it to the XPT. |
ccmn_bdr_ccb_bld | Creates a BUS DEVICE RESET CCB and sends it to the XPT. |
ccmn_br_ccb_bld | Creates a BUS RESET CCB and sends it to the XPT. |
The ccmn_get_ccb routine allocates a CCB and fills in the common portion of the CCB header. The routine calls the xpt_ccb_alloc routine to allocate a CCB structure. The ccmn_get_ccb routine fills in the common portion of the CCB header and returns a pointer to that CCB_HEADER.
The ccmn_rel_ccb routine releases a CCB and returns the sense data buffer for SCSI I/O CCBs, if allocated. The routine calls the xpt_ccb_free routine to release a CCB structure. For SCSI I/O CCBs, if the sense data length is greater than the default sense data length, the ccmn_rel_ccb routine calls the ccmn_rel_dbuf routine to return the sense data buffer to the data buffer pool.
The ccmn_io_ccb_bld routine allocates a SCSI I/O CCB and fills it in. The routine calls the ccmn_get_ccb routine to obtain a CCB structure with the header portion filled in. The ccmn_io_ccb_bld routine fills in the SCSI I/O-specific fields from the parameters passed and checks the length of the sense data to see if it exceeds the length of the reserved sense buffer. If it does, a sense buffer is allocated using the ccmn_get_dbuf routine.
The ccmn_gdev_ccb_bld routine creates a GET DEVICE TYPE CCB and sends it to the XPT. The routine calls the ccmn_get_ccb routine to allocate a CCB structure and to fill in the common portion of the CCB header. The ccmn_gdev_ccb_bld routine calls the ccmn_send_ccb routine to send the CCB structure to the XPT. The request is carried out immediately, so it is not placed on the device driver's active queue.
The ccmn_sdev_ccb_bld routine creates a SET DEVICE TYPE CCB and sends it to the XPT. The routine calls the ccmn_get_ccb routine to allocate a CCB structure and to fill in the common portion of the CCB header. The routine fills in the device type field of the CCB and calls the ccmn_send_ccb routine to send the CCB structure to the XPT. The request is carried out immediately, so it is not placed on the device driver's active queue.
The ccmn_sasy_ccb_bld routine creates a SET ASYNCHRONOUS CALLBACK CCB and sends it to the XPT. The routine calls the ccmn_get_ccb routine to allocate a CCB structure and to fill in the common portion of the CCB header. The routine fills in the asynchronous fields of the CCB and calls the ccmn_send_ccb routine to send the CCB structure to the XPT. The request is carried out immediately, so it is not placed on the device driver's active queue.
The ccmn_rsq_ccb_bld routine creates a RELEASE SIM QUEUE CCB and sends it to the XPT. The routine calls the ccmn_get_ccb routine to allocate a CCB structure and to fill in the common portion of the CCB header. The routine calls the ccmn_send_ccb routine to send the CCB structure to the XPT. The request is carried out immediately, so it is not placed on the device driver's active queue.
The ccmn_pinq_ccb_bld routine creates a PATH INQUIRY CCB and sends it to the XPT. The routine calls the ccmn_get_ccb routine to allocate a CCB structure and to fill in the common portion of the CCB header. The routine calls the ccmn_send_ccb routine to send the CCB structure to the XPT. The request is carried out immediately, so it is not placed on the device driver's active queue.
The ccmn_abort_ccb_bld routine creates an ABORT CCB and sends it to the XPT. The routine calls the ccmn_get_ccb routine to allocate a CCB structure and to fill in the common portion of the CCB header. The routine fills in the address of the CCB to be aborted and calls the ccmn_send_ccb routine to send the CCB structure to the XPT. The request is carried out immediately, so it is not placed on the device driver's active queue.
The ccmn_term_ccb_bld routine creates a TERMINATE I/O CCB and sends it to the XPT. The routine calls the ccmn_get_ccb routine to allocate a CCB structure and to fill in the common portion of the CCB header. The routine fills in the CCB to be terminated and calls the ccmn_send_ccb routine to send the CCB structure to the XPT. The request is carried out immediately, so it is not placed on the device driver's active queue.
The ccmn_bdr_ccb_bld routine creates a BUS DEVICE RESET CCB and sends it to the XPT. The routine calls the ccmn_get_ccb routine to allocate a CCB structure and to fill in the common portion of the CCB header. The routine calls the ccmn_send_ccb routine to send the CCB structure to the XPT. The request is carried out immediately, so it is not placed on the device driver's active queue.
The ccmn_br_ccb_bld routine creates a BUS RESET CCB and sends it to the XPT. The routine calls the ccmn_get_ccb routine to allocate a CCB structure and to fill in the common portion of the CCB header. The routine calls the ccmn_send_ccb routine to send the CCB structure to the XPT. The request is carried out immediately, so it is not placed on the device driver's active queue.
This section describes the common SCSI/CAM peripheral device driver SCSI I/O command build and send routines. Table 3-7 lists the name of the routine and gives a summary description of its function. The sections that follow contain a more detailed description of each routine.
Routine | Summary Description |
ccmn_tur | Creates a SCSI I/O CCB for the TEST UNIT READY command and sends it to the XPT for processing. It sleeps while waiting for its completion. |
ccmn_start_unit | Creates a SCSI I/O CCB for the START UNIT command and sends it to the XPT for processing. It sleeps waiting for its completion. |
ccmn_mode_select | Creates a SCSI I/O CCB for the MODE SELECT command and sends it to the XPT for processing. It sleeps while waiting for its completion. |
The ccmn_tur routine creates a SCSI I/O CCB for the TEST UNIT READY command, sends it to the XPT for processing, and waits for it to complete.
The ccmn_tur routine calls the ccmn_io_ccb_bld routine to obtain a SCSI I/O CCB structure. The ccmn_tur routine calls the ccmn_send_ccb_wait routine to send the SCSI I/O CCB to the XPT and to wait for it to complete.
The ccmn_start_unit routine creates a SCSI I/O CCB for the START UNIT command, sends it to the XPT for processing, and waits for it to complete.
The ccmn_start_unit routine calls the ccmn_io_ccb_bld routine to obtain a SCSI I/O CCB structure. The ccmn_start_unit routine calls the ccmn_send_ccb_wait routine to send the SCSI I/O CCB to the XPT and to wait for it to complete.
The ccmn_mode_select routine creates a SCSI I/O CCB for the MODE SELECT command, sends it to the XPT for processing, and waits for it to complete.
The routine calls the ccmn_io_ccb_bld routine to obtain a SCSI I/O CCB structure. It uses the ms_index parameter to index into the Mode Select Table pointed to by the dd_modesel_tbl member of the Device Descriptor structure for the SCSI device. The ccmn_mode_select routine calls the ccmn_send_ccb_wait routine to send the SCSI I/O CCB to the XPT and to wait for it to complete.
This section describes the common SCSI/CAM peripheral device driver CCB status routine. The ccmn_ccb_status routine assigns individual CAM status values to generic categories. The following table shows the returned category for each CAM status value:
CAM Status | Assigned Category |
CAM_REQ_INPROG | CAT_INPROG |
CAM_REQ_CMP | CAT_CMP |
CAM_REQ_ABORTED | CAT_ABORT |
CAM_UA_ABORT | CAT_ABORT |
CAM_REQ_CMP_ERR | CAT_CMP_ERR |
CAM_BUSY | CAT_BUSY |
CAM_REQ_INVALID | CAT_CCB_ERR |
CAM_PATH_INVALID | CAT_NO_DEVICE |
CAM_DEV_NOT_THERE | CAT_NO_DEVICE |
CAM_UA_TERMIO | CAT_ABORT |
CAM_SEL_TIMEOUT | CAT_DEVICE_ERR |
CAM_CMD_TIMEOUT | CAT_DEVICE_ERR |
CAM_MSG_REJECT_REC | CAT_DEVICE_ERR |
CAM_SCSI_BUS_RESET | CAT_RESET |
CAM_UNCOR_PARITY | CAT_DEVICE_ERR |
CAM_AUTOSENSE_FAIL | CAT_BAD_AUTO |
CAM_NO_HBA | CAT_NO_DEVICE |
CAM_DATA_RUN_ERR | CAT_DEVICE_ERR |
CAM_UNEXP_BUSFREE | CAT_DEVICE_ERR |
CAM_SEQUENCE_FAIL | CAT_DEVICE_ERR |
CAM_CCB_LEN_ERR | CAT_CCB_ERR |
CAM_PROVIDE_FAIL | CAT_CCB_ERR |
CAM_BDR_SENT | CAT_RESET |
CAM_REQ_TERMIO | CAT_ABORT |
CAM_LUN_INVALID | CAT_NO_DEVICE |
CAM_TID_INVALID | CAT_NO_DEVICE |
CAM_FUNC_NOTAVAIL | CAT_CCB_ERR |
CAM_NO_NEXUS | CAT_NO_DEVICE |
CAM_IID_INVALID | CAT_NO_DEVICE |
CAM_SCSI_BUSY | CAT_SCSI_BUSY |
Other | CAT_UNKNOWN |
This section describes the common SCSI/CAM peripheral device driver buf structure pool allocation and deallocation routines.
The ccmn_get_bp routine allocates a buf structure. This function must not be called at interrupt context. The function may sleep while waiting for resources.
The ccmn_rel_bp routine deallocates a buf structure.
This section describes the common SCSI/CAM peripheral device driver data buffer pool allocation and deallocation routines.
The ccmn_get_dbuf routine allocates a data buffer area of the size specified by calling the kernel memory allocation routines.
The ccmn_rel_dbuf routine deallocates a data buffer.
This section describes the common SCSI/CAM peripheral device driver routines specific to loadable device drivers. Table 3-8 provides a summary description of the routines specific to loadable drivers.
Routine | Summary Description |
ccmn_check_idle | Checks that there are no opens against a device. |
ccmn_find_ctlr | Finds the controller structure that corresponds to the SCSI controller that the device must be attached to. |
ccmn_attach_device | Creates and attaches a device structure to the controller structure that corresponds to the SCSI controller. |
The ccmn_check_idle routine checks that there are no opens against a device. This routine calls the ccmn_rel_dbuf routine to deallocate all structures that pertain to the device whose driver is being unloaded.
The ccmn_check_idle routine scans the Peripheral Device Unit Table looking for devices that match the block device major number and the character device major number in the PDRV_DEVICE structure members pd_bmajor and pd_cmajor. If no opens exist for the devices that are to be unloaded, it rescans the Peripheral Device Unit Table and deallocates all structures that relate to the devices whose driver is being unloaded. The ccmn_check_idle routine must be called with the Peripheral Device Unit Table locked.
The ccmn_find_ctlr routine finds the controller structure that corresponds to the SCSI controller that the device must be attached to. This routine must be called with the Peripheral Device Unit Table locked.
The ccmn_attach_device routine creates and attaches a device structure to the controller structure that corresponds to the SCSI controller. The routine finds the controller structure for a device, fills in the device structure, and attaches the device structure to the controller structure.
This section describes the common SCSI/CAM peripheral device driver routines that perform miscellaneous operations. Table 3-9 lists the name of each routine and gives a summary description of its function.
Routine | Summary Description |
ccmn_DoSpecialCmd | Provides a simplified interface to the special command routine. |
ccmn_SysSpecialCmd | Lets a system request issue SCSI I/O commands to the SCSI/CAM special I/O interface. |
ccmn_errlog | Reports error conditions for the SCSI/CAM peripheral device driver. |
The ccmn_DoSpecialCmd routine provides a simplified interface to the special command routine. The routine prepares for and issues special commands.
The ccmn_SysSpecialCmd routine lets a system request issue SCSI I/O commands to the SCSI/CAM special I/O interface. This permits existing SCSI commands to be issued from within kernel code.
The ccmn_errlog routine reports error conditions for the SCSI/CAM peripheral device driver. The routine is passed a pointer to the name of the function in which the error was detected. The routine builds informational strings based on the error condition.