9.1.4 Fast Disk Commands

A client calls the BlockDev_Send_Command service to send commands to the fast disk device. The call includes a pointer to the BDD identifying the fast disk device to receive the command, and a second pointer to the head of a linked list of command blocks. Commands are submitted in arbitrarily long chains of command blocks, but fast disk devices can choose to have the block device queue the commands and send them one command at a time. This greatly reduces the amount of work needed to support a new hardware controller.

The basic commands are read, write, verify, and cancel. Any command that has been sent to a fast disk device but has not yet completed can be canceled (although commands that are in progress usually can not be canceled). Windows only requires that the fast disk device support multiple sector read and write commands.

Commands have either high or low priority. A high priority command is indicated by setting the appropriate flag in the command block; low priority is indicated by clearing this flag. All high priority commands will be processed before low priority commands. However, if a low priority command is in progress when a high priority command is submitted, the command that is in progress will usually be completed before the high priority command begins. Any queued low priority commands will not be processed until all high priority commands have completed.

Because all commands are asynchronous, the BlockDev_Send_Command service does not return status information about the command or commands sent. Instead, when a command completes or when an error is detected, the caller is called back at an address specified by the BD_CB_Cmd_Cplt_Proc field. The callback procedure receives a pointer to the BDD in the EDI register, and a pointer to the command block in the ESI register. The client must examine the command status field to determine whether or not the command has succeeded. Command blocks contain a CB_Reserved_Client field that can be used by the client to uniquely identify the command block when it completes. The virtual block device will not use or modify any data in the portion of the command block. Interrupts will be disabled when the callback is called. The client is allowed to enable interrupts. Once the command complete callback has been called, the command block is no longer busy, and may be used again immediately.

The BlockDev_Send_Command service can be called from an interrupt handler. This allows clients to submit a new command to a fast disk device from a command complete callback procedure. Note, however, that the callback will be called at interrupt time and so only asynchronous services may be called. If the virtual device needs to call any other services then it should schedule an event and complete the processing of the command completion when the event procedure is called.

Upon command completion the following fields may have been modified in the command block:

BD_CB_Next
BD_CB_Cmd_Status
BD_CB_Reserved_BlockDev
BD_CB_Reserved_FastDisk

All other fields will remain unmodified. This allows clients to easily resubmit the same command block without having to completely reinitialize it each time.