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?
USB SCSI ? [SOLVED]
USB SCSI ? [SOLVED]
Last edited by bigbob on Fri Oct 31, 2014 3:58 am, edited 1 time in total.
Re: USB SCSI ?
It seems that the three steps described above are correct. However there is an initialization sequence: Lunt's book, PrettyOS and tatOS send an Inquiry CBW first (PrettyOS sends BulkReset and then Inquiry). Unfortunately, if I send Inquiry-CBW in those three steps instead of ReadCapacity(10), I still get garbage.
Of course, if I send Inquiry, I request 36 bytes from BulkIN.
I ruled out sending BulkReset, because two out of my three sources don't send it.
By the way, I clear the buffers before setting their addresses to the TDs.
Of course, if I send Inquiry, I request 36 bytes from BulkIN.
I ruled out sending BulkReset, because two out of my three sources don't send it.
By the way, I clear the buffers before setting their addresses to the TDs.
Re: USB SCSI ?
You may find some help by taking a look at tatOS.
There is code in the /usb directory to init the ehci controller and then init the flash with ehci.
The sequence of SetAddress, SetConfiguration, TestUnitReady, RequestSense, TestUnitReady, ReadCapacity etc... is important before doing any READ WRITE.
TomT
https://code.google.com/p/tatos/
There is code in the /usb directory to init the ehci controller and then init the flash with ehci.
The sequence of SetAddress, SetConfiguration, TestUnitReady, RequestSense, TestUnitReady, ReadCapacity etc... is important before doing any READ WRITE.
TomT
https://code.google.com/p/tatos/
Re: USB SCSI ?
Hi Tom,TomT wrote:You may find some help by taking a look at tatOS.
There is code in the /usb directory to init the ehci controller and then init the flash with ehci.
The sequence of SetAddress, SetConfiguration, TestUnitReady, RequestSense, TestUnitReady, ReadCapacity etc... is important before doing any READ WRITE.
TomT
https://code.google.com/p/tatos/
A quote from my first post: "I checked Lunt's book, PrettyOS and tatOS"
I looked at your code and I understand the USB-related part of it.
I decided to do an INQUIRY instead of READCAPACITY(10). In both tatOS and Lunt's book INQUIRY is the first CBW to send to the device after SetConfig. (tatOS: initflash.s)
SetAddress() has already been called succesfully in my code.
Then I first call SetConfiguration(1) and then do I send an INQUIRY CBW to the device.
Having called SetConfiguration(1), I succesfully read 1 back by calling GetConfiguration() immediately after calling SetConfiguration(1).
The buffer that contains the result of INQUIRY is garbage. but it's from the pendrive, because I clear the buffer right in the beginning.
What you do differently are the followings:
1. you create three QHs (Control, IN, OUT). I have a few dummy QHs and I always insert/remove a QH that I create (let it be Control, IN or OUT)
2. you use the data-toggle in the QH (dtc set to 0). I use data-toggle of the TDs (dtc set to 1)
3. you set CERR to 0 (infinite loop if error occured). I set it to 11b.
I also put a 100ms-delay before getting the TDin of INQUIRY, but it didn't help.
Currently I have no idea what else to try.
EDIT:
If I send a TestUnitReady-CBW right after SetConfiguration(1), then I receive a correct CSW (but with Status 01).
This is the first correct CSW for me.
So, it seems TestUnitReady-RequestSense-TestUnitReady is the correct order (as Tom said).
However I still don't understand why sending Inquiry right after SetConfiguration(1) works in tatOS and in the Lunt-book.
Probably not every pendrive works the same way.
I consider this topic solved.
Thank you for the help!
Re: USB SCSI ? [SOLVED]
On alt.os.development I have corresponded with the author of the USB-book and despite a few silly things of mine, it can be useful for beginners (in USB and SCSI):
https://groups.google.com/forum/#!topic ... nLxJAQNvOY
or
https://groups.google.com/forum/#!forum ... evelopment
and "USB SCSI Inquiry RequestSense Problem"
https://groups.google.com/forum/#!topic ... nLxJAQNvOY
or
https://groups.google.com/forum/#!forum ... evelopment
and "USB SCSI Inquiry RequestSense Problem"