USB SCSI ? [SOLVED]
Posted: Sat Oct 25, 2014 6:43 am
I can successfully get the device, strings and configuration descriptors from USB(EHCI) devices. The configuration descriptor contains the interface and endpoints descriptors.
However I have problems with sending SCSI commands to a pendrive (e.g. READ_CAPACITY(10) - CBW).
I checked Lunt's book, PrettyOS and tatOS but it is not clear to me what my mistake is but it is obvious that there is no need for the SetupTD and StatusTD.
String descriptors return: "Sony Storage Media" for the pendrive.
InterfaceNum is 0
EndpointDescriptor1 is IN and its Num is 1
EndpointDescriptor2 is OUT and its Num is 2
The device address is 2 in this case (my pendrive, 4 Gb).
This is how I try to read the capacity of the pendrive (SetConfiguration(1) has already been called):
1. send READ_CAPACITY(10) CBW to the device (see the bytes of the command below) by creating a TDout with 31 bytes to transfer and with the address of the CBW-buffer. Create a QH with the device address and with EndPt set to 2 (BulkOut). Insert the QH and wait for ready, then remove QH. Check for errors, if there are any then print and exit.
2. get the capacity (8 bytes in case of READ_CAP10) by creating a TDin with 8 bytes to transfer and the address of the buffer to read to. Create a QH with the device address and with EndPt set to 1 (BulkIn). Insert the QH and wait for ready, then remove QH. Check for errors, if there are any then print and exit.
3. get the CSW (13 bytes by creating a TDin with 13 bytes to transfer and the address of the buffer to read to. Create a QH with the device address and with EndPt set to 1 (BulkIn). Insert the QH and wait for ready, then remove QH. Check for errors, if there are any then print and exit.
Result (memdump)
8 bytes of Capacity(hex): 01 00 00 00 01 00 00 00
13 bytes of CSW(hex): 00 77 FF FF 00 00 02 00 00 00 00 00 00
Both buffers contain garbage because e.g. CSW should contain the Tag that was given in the CBW (0x04A67A83 in this case).
The first 4 bytes of the 8-byte-capacity-buffer is the LBA and if it contained 0xFFFFFFFFF, then READ_CAPACITY(16) should be used. The last 4 bytes should be 00 00 02 00 (512), the sector-size.
I also tried to send a Bulk-Only Reset Request(see below) to the device before sending the READ_CAPACITY(10) CBW but that didn't help either, the result was the same.
Data-toggle bit (dt) of the TDS is always zero, but I have tried to set the dt-bit to 1 in case of TDin(step2 above), but the result was the same.
In case I sent READ_CAPACITY(16), getting CSW failed. Without getting the CSW, the result of ReadCap16 is similar.
ehci_read_capacity10
dd 0x43425355 ; Signature, 'USBC'
dd 0x04A67A83 ; Tag, arbitrary, will be returned in CSW
dd 0x00000008 ; Transfer Length, we want at most 8 bytes returned
db 0x80 ; Flags, receive an in packet
db 0x00 ; LUN, first volume
db 0x0A ; Command Len, this command is 10 bytes
db 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
ehci_req_reset_packet
db 0x21, 0xFF,
dw 0, 0, 0 ; interfacenum is 0
Is there something else I should do, or is this enough and there is a bug somewhere?
However I have problems with sending SCSI commands to a pendrive (e.g. READ_CAPACITY(10) - CBW).
I checked Lunt's book, PrettyOS and tatOS but it is not clear to me what my mistake is but it is obvious that there is no need for the SetupTD and StatusTD.
String descriptors return: "Sony Storage Media" for the pendrive.
InterfaceNum is 0
EndpointDescriptor1 is IN and its Num is 1
EndpointDescriptor2 is OUT and its Num is 2
The device address is 2 in this case (my pendrive, 4 Gb).
This is how I try to read the capacity of the pendrive (SetConfiguration(1) has already been called):
1. send READ_CAPACITY(10) CBW to the device (see the bytes of the command below) by creating a TDout with 31 bytes to transfer and with the address of the CBW-buffer. Create a QH with the device address and with EndPt set to 2 (BulkOut). Insert the QH and wait for ready, then remove QH. Check for errors, if there are any then print and exit.
2. get the capacity (8 bytes in case of READ_CAP10) by creating a TDin with 8 bytes to transfer and the address of the buffer to read to. Create a QH with the device address and with EndPt set to 1 (BulkIn). Insert the QH and wait for ready, then remove QH. Check for errors, if there are any then print and exit.
3. get the CSW (13 bytes by creating a TDin with 13 bytes to transfer and the address of the buffer to read to. Create a QH with the device address and with EndPt set to 1 (BulkIn). Insert the QH and wait for ready, then remove QH. Check for errors, if there are any then print and exit.
Result (memdump)
8 bytes of Capacity(hex): 01 00 00 00 01 00 00 00
13 bytes of CSW(hex): 00 77 FF FF 00 00 02 00 00 00 00 00 00
Both buffers contain garbage because e.g. CSW should contain the Tag that was given in the CBW (0x04A67A83 in this case).
The first 4 bytes of the 8-byte-capacity-buffer is the LBA and if it contained 0xFFFFFFFFF, then READ_CAPACITY(16) should be used. The last 4 bytes should be 00 00 02 00 (512), the sector-size.
I also tried to send a Bulk-Only Reset Request(see below) to the device before sending the READ_CAPACITY(10) CBW but that didn't help either, the result was the same.
Data-toggle bit (dt) of the TDS is always zero, but I have tried to set the dt-bit to 1 in case of TDin(step2 above), but the result was the same.
In case I sent READ_CAPACITY(16), getting CSW failed. Without getting the CSW, the result of ReadCap16 is similar.
ehci_read_capacity10
dd 0x43425355 ; Signature, 'USBC'
dd 0x04A67A83 ; Tag, arbitrary, will be returned in CSW
dd 0x00000008 ; Transfer Length, we want at most 8 bytes returned
db 0x80 ; Flags, receive an in packet
db 0x00 ; LUN, first volume
db 0x0A ; Command Len, this command is 10 bytes
db 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
ehci_req_reset_packet
db 0x21, 0xFF,
dw 0, 0, 0 ; interfacenum is 0
Is there something else I should do, or is this enough and there is a bug somewhere?