Writing Device Drivers

Auto-Request Sense Mode

Auto-request sense mode is most desirable if queuing is used, whether the queuing is tagged or untagged. A contingent allegiance condition is cleared by any subsequent command and, consequently, the sense data is lost. Most HBA drivers start the next command before performing the target driver callback. Other HBA drivers can use a separate, lower-priority thread to perform the callbacks. This approach might increase the time needed to notify the target driver that the packet completed with a check condition. In this case, the target driver might not be able to submit a request sense command in time to retrieve the sense data.

To avoid this loss of sense data, the HBA driver, or controller, should issue a request sense command if a check condition has been detected. This mode is known as auto-request sense mode. Note that not all HBA drivers are capable of auto-request sense mode, and some drivers can only operate with auto-request sense mode enabled.

A target driver enables auto-request-sense mode by using scsi_ifsetcap(9F). The following example shows auto-request sense enabling.


Example 17–6 Enabling Auto-Request Sense Mode

static int
xxattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
    struct xxstate *xsp;
    struct scsi_device *sdp = (struct scsi_device *)
    ddi_get_driver_private(dip);
   /*
    * Enable auto-request-sense; an auto-request-sense cmd might
    * fail due to a BUSY condition or transport error. Therefore,
    * it is recommended to allocate a separate request sense
    * packet as well.
    * Note that scsi_ifsetcap(9F) can return -1, 0, or 1
    */
    xsp->sdp_arq_enabled =
    ((scsi_ifsetcap(ROUTE, “auto-rqsense”, 1, 1) == 1) ? 1 :
0);
   /*
    * If the HBA driver supports auto request sense then the
    * status blocks should be sizeof (struct scsi_arq_status);
    */
else
   /*
    * One byte is sufficient
    */
    xsp->sdp_cmd_stat_size =  (xsp->sdp_arq_enabled ?
    sizeof (struct scsi_arq_status) : 1);
   /* ... */
}

If a packet is allocated using scsi_init_pkt(9F) and auto-request sense is desired on this packet, additional space is needed. The target driver must request this space for the status block to hold the auto-request sense structure. The sense length used in the request sense command is sizeof, from struct scsi_extended_sense. Auto-request sense can be disabled per individual packet by allocating sizeof, from struct scsi_status, for the status block.

The packet is submitted using scsi_transport(9F) as usual. When a check condition occurs on this packet, the host adapter driver takes the following steps:

The target driver's callback routine should verify that sense data is available by checking the STATE_ARQ_DONE bit in pkt_state. STATE_ARQ_DONE implies that a check condition has occurred and that a request sense has been performed. If auto-request sense has been temporarily disabled in a packet, subsequent retrieval of the sense data cannot be guaranteed.

The target driver should then verify whether the auto-request sense command completed successfully and decode the sense data.