The Command Status Wrapper
Table 3-7 shows the fields in the CSW, which is 13 bytes. The _USB_MSD_CSW structure can contain a CSW:
#define MSD_CSW_SIZE 0×0d
typedef struct _USB_MSD_CSW
On receiving a CSW, a host should check that the structure is valid and has
meaningful content. A CSW is valid if all of the following are true:
• The CSW is 13 bytes.
• The dCSWSignature field has the correct value.
• The value of dCSWTag equals the value in the dCBWTag field of a previously sent CBW.
The contents are considered meaningful if either of the following is true:
• The bCSWStatus field equals 02h.
• The bCSWStatus field equals 00h or 01h and dCSWDataResidue is less than or equal to dCBWDataTransferLength.
In the dCSWDataResidue field in the CSW, a device indicates whether it has received and processed all of the data the host promised to send in the CBW or whether the device has sent all of the data requested by the CBW.
In a command where the host sends data in the data-transport phase, dCSWDataResidue contains the difference between dCBWDataTransfer- Length in the command’s CBW and the amount of data the device has processed. If the device processes dCBWDataTransferLength bytes, dCSWDataResidue is zero.
Table 3-7: The CSW contains status and related information about a command.
In a command where the device sends data in the data-transport phase, dCSWDataResidue contains the difference between dCBWDataTransfer- Length in the command’s CBW and the amount of valid data the device sent, excluding any pad bytes. If the device has sent dCBWDataTransfer- Length bytes, dCSWDataResidue is zero.
The bCSWStatus field indicates whether the command completed without error. A value of 00h means success. A value of 01h means the command failed and the host should immediately issue a SCSI REQUEST SENSE command to get status information. The protocol that causes the host to send REQUEST SENSE on receiving a response code of 01h is sometimes called auto sense because the host’s USB driver, rather than higher-level code, requests the status information. The handling of the error and sense data is thus “automatic” to higher-level software. Chapter 6 has more about the REQUEST SENSE command.
A value of 02h means that the host should perform a reset recovery on the device. A reset recovery consists of the following control transfers in order:
1. Bulk-only Mass Storage Reset. On completion of the request, the device is ready to receive a new CBW. The reset should not change the states of data-toggle bits and endpoint STALL conditions. This is a class-specific request for the mass-storage class.
2. Clear Feature(ENDPOINT_HALT) request for the bulk IN endpoint. The device resets the endpoint’s data toggle to DATA0. The endpoint resumes normal communications if possible. This request is a standard USB request.
3. Clear Feature(ENDPOINT_HALT) request for the bulk OUT endpoint. The device resets the endpoint’s data toggle to DATA0. The endpoint resumes normal communications if possible. This request is a standard USB request.
As an alternative to a reset recovery, a host might issue a Set Port Feature (PORT_RESET) request to the device’s hub port. The host must then re-enumerate the device. This option isn’t ideal for composite devices, which have multiple active interfaces, because the port reset will affect all of the device’s interfaces. But a port reset can be necessary when communicating with a device that crashes when the host attempts a reset recovery. (Such devices exist.) The Windows mass-storage driver favors the port reset over the reset recovery.
The PrepareCSWData function sets the CSWTag and CSWSignature fields in the CSW. The other fields in the CSW are set in other functions later in this chapter.
volatile far USB_MSD_CSW msd_csw;
// Set dCSWTag to match dCBWTag in the command’s CBW.
msd_csw.dCSWTag = gblCBW.dCBWTag;
msd_csw.dCSWSignature = 0×53425355;