Writing Device Drivers

General Flow of Control

Before transferring data, ensure that the disk is spun up. When transferring data to or from a user address space (using the read(9E) or write(9E) entry points), SCSI target character device drivers must use physio(9F), which locks down memory, prepares a buf(9S) structure, and calls the driver's strategy(9E) routine.

physio(9F) locks down the user buffer into memory before issuing a SCSI command. The file system locks down memory for block device drivers. See Chapter 9, "Drivers for Block Devices", for more information on writing a strategy(9E) entry point and Chapter 8, "Drivers for Character Devices", for more information on using physio(9F).

Assuming no transport errors occur, the following steps describe the general flow of control for a read or write request, starting from the call to the target driver's strategy routine.

  1. The target driver's strategy(9E) routine checks the request and allocates a scsi_pkt(9S) using scsi_init_pkt(9F). The target driver initializes the packet and sets the SCSI command descriptor block (CDB) using the scsi_setup_cbd(9F) function. The target driver also specifies a timeout and provides a pointer to a callback function, which is called by the host bus adapter driver on completion of the command. The buf(9S) pointer should be saved in the SCSI packet's target-private space.

  2. The target driver submits the packet to the host bus adapter driver using scsi_transport(9F). The target driver is then free to accept other requests. The target driver should not access the packet while it is in transport. If either the host bus adapter driver or the target supports queueing, new requests can be submitted while the packet is in transport.

  3. As soon as the SCSI bus is free and the target not busy, the host bus adapter driver selects the target and passes the CDB. The target executes the command and performs the requested data transfers. The target controls the SCSI bus phase transitions. The host bus adapter just responds to these transitions until the command is completed.

  4. After the target sends completion status and disconnects, the host bus adapter driver notifies the target driver by calling the completion function that was specified in the SCSI packet. At this time the host bus adapter driver is no longer responsible for the packet, and the target driver has regained ownership of the packet.

  5. The SCSI packet's completion routine analyzes the returned information and determines whether the SCSI operation was successful. If a failure has occurred, the target driver may retry the command by calling scsi_transport(9F) again. If the host bus adapter driver does not support auto request sense, the target driver must submit a request sense packet to retrieve the sense data in the event of a check condition.

  6. If either the command was completed successfully or cannot be retried, the target driver calls scsi_destroy_pkt(9F), which synchronizes the data and frees the packet. If the target driver needs to access the data before freeing the packet, it calls scsi_sync_pkt(9F).

  7. Finally, the target driver notifies the application program that originally requested the read or write that the transaction is complete, either by returning from the read(9E) entry point in the driver (for a character device) or indirectly through biodone(9F).

The SCSA allows the execution of many of such operations, both overlapped and queued at various points in the process. The model places the management of system resources on the host bus adapter driver. The software interface enables the execution of target driver functions on host bus adapter drivers using SCSI bus adapters of varying degrees of intelligence.