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


3    S/CA Common Modules

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.


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


3.1    Common SCSI Device Driver Data Structures

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.


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


3.1.1    Peripheral Device Unit Table

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.


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


3.1.2    Peripheral Device Structure

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.

Table 3-1: Members of the PDRV_DEVICE Structure

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.


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


3.1.2.1    The pd_dev Member

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.


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


3.1.2.2    The pd_spec_size Member

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.


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


3.1.3    Device Descriptor Structure

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;


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


3.1.4    Mode Select Table Structure

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;


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


3.1.5    Density Table Structure

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;


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


3.1.5.1    The den_blocking Member

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.


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


3.1.6    SCSI/CAM Peripheral Device Driver Working Set Structure

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;


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


3.1.6.1    The pws_flink Member

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.


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


3.1.6.2    The pws_blink Member

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.


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


3.1.6.3    The pws_ccb Member

The pws_ccb member is a pointer to this CCB. The CCB header is filled in by the common routines.


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


3.2    Common SCSI Device Driver Macros

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.

Table 3-2: Common Identification Macros

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.

Table 3-3: Common Lock Macros

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.


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


3.3    Common SCSI Device Driver Routines

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.


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


3.3.1    Common I/O Routines

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.

Table 3-4: Common I/O Routines

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.


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


3.3.1.1    The ccmn_init Routine

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.


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


3.3.1.2    The ccmn_open_unit Routine

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.


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


3.3.1.3    The ccmn_close_unit Routine

The ccmn_close_unit routine handles the common close for all SCSI/CAM peripheral device drivers. It sets the open count to zero.


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


3.3.2    Common Queue Manipulation Routines

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.

Table 3-5: Common Queue Manipulation Routines

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.


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


3.3.2.1    The ccmn_send_ccb Routine

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


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


3.3.2.2    The ccmn_send_ccb_wait Routine

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


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


3.3.2.3    The ccmn_rem_ccb Routine

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.


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


3.3.2.4    The ccmn_abort_que Routine

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.


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


3.3.2.5    The ccmn_term_que Routine

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.


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


3.3.3    Common CCB Management Routines

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.

Table 3-6: Common CCB Management Routines

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.


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


3.3.3.1    The ccmn_get_ccb Routine

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.


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


3.3.3.2    The ccmn_rel_ccb Routine

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.


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


3.3.3.3    The ccmn_io_ccb_bld Routine

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.


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


3.3.3.4    The ccmn_gdev_ccb_bld 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.


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


3.3.3.5    The ccmn_sdev_ccb_bld Routine

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.


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


3.3.3.6    The ccmn_sasy_ccb_bld Routine

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.


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


3.3.3.7    The ccmn_rsq_ccb_bld Routine

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.


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


3.3.3.8    The ccmn_pinq_ccb_bld Routine

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.


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


3.3.3.9    The ccmn_abort_ccb_bld Routine

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.


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


3.3.3.10    The ccmn_term_ccb_bld Routine

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.


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


3.3.3.11    The ccmn_bdr_ccb_bld Routine

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.


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


3.3.3.12    The ccmn_br_ccb_bld Routine

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.


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


3.3.4    Common SCSI I/O Command Building Routines

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.

Table 3-7: Common SCSI I/O Command Building Routines

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.


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


3.3.4.1    The ccmn_tur Routine

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.


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


3.3.4.2    The ccmn_start_unit Routine

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.


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


3.3.4.3    The ccmn_mode_select Routine

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.


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


3.3.5    Common CCB Status Routine

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


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


3.3.6    Common Buf Structure Pool Management Routines

This section describes the common SCSI/CAM peripheral device driver buf structure pool allocation and deallocation routines.


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


3.3.6.1    The ccmn_get_bp Routine

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.


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


3.3.6.2    The ccmn_rel_bp Routine

The ccmn_rel_bp routine deallocates a buf structure.


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


3.3.7    Common Data Buffer Pool Management Routines

This section describes the common SCSI/CAM peripheral device driver data buffer pool allocation and deallocation routines.


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


3.3.7.1    The ccmn_get_dbuf Routine

The ccmn_get_dbuf routine allocates a data buffer area of the size specified by calling the kernel memory allocation routines.


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


3.3.7.2    The ccmn_rel_dbuf Routine

The ccmn_rel_dbuf routine deallocates a data buffer.


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


3.3.8    Common Routines for Loadable Drivers

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.

Table 3-8: Common Routines for 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.


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


3.3.8.1    The ccmn_check_idle Routine

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.


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


3.3.8.2    The ccmn_find_ctlr Routine

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.


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


3.3.8.3    The ccmn_attach_device Routine

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.


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


3.3.9    Miscellaneous Common Routines

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.

Table 3-9: Miscellaneous Common Routines

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.


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


3.3.9.1    The ccmn_DoSpecialCmd Routine

The ccmn_DoSpecialCmd routine provides a simplified interface to the special command routine. The routine prepares for and issues special commands.


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


3.3.9.2    The ccmn_SysSpecialCmd Routine

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.


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


3.3.9.3    The ccmn_errlog Routine

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.