Page 2 of 2
Re: How are we supposed to send commands to USB flash drives
Posted: Sun Mar 08, 2015 2:09 pm
by glauxosdev
I managed just today to get the device descriptor.
But I broke some other code trying to implement more than one device...
Don't worry anyway, I will get out of it.
Edit: I just forgot to print the hex string containing values of the descriptor.
Re: How are we supposed to send commands to USB flash drives
Posted: Sat Mar 14, 2015 9:25 am
by glauxosdev
I saved device endpoints (if bit 7 set -> in endpoint, else -> out endpoint).
Then I issued the SCSI commands listed below.
- Set_address (address = 2, endpoint = 0)
- Set_config (address = 2, config = byte [ehci_config_descriptor + 5], endpoint = 0, address = 2)
- Inquiry (address = 2, endpoint (cmd = out, data = in))
- Test_unit (address = 2, endpoint = out)
- Request_sense (address = 2, endpoint (cmd = out, data = in))
- Test_unit (address = 2, endpoint = out)
- Request_sense (address = 2, endpoint (cmd = out, data = in))
- Read_capacity (address = 2, endpoint (cmd = out, data = in)
This is the sequence used in TatOS.
But capacity happens to be 0. Am I missing something?
Thanks for your attention again.
Edit: when I get this working, I will be open for discussion about data-toggle bit.
Re: How are we supposed to send commands to USB flash drives
Posted: Sat Mar 14, 2015 11:05 am
by bigbob
I set address right after getting the Device Descriptor, and only then do I get the String and Config Descriptors. The book does that too. If you managed to get the Config-Descriptor, that can't be the problem.
I am not sure about TatOS and PrettyOS because I checked their SCSI-code only.
I assume that your code is only an example: the device-address needs to be incremented from e.g. 1, whenever a new device encountered.
This is how I initialize a USB mass-storage device (EndPts and MaxPacketSize aleady saved from Config/Interface/Endpoint-Descs):
1. SetConfig(1)
2. Do a bulk reset (to clear data-toggles of EndPts)
3. 100ms delay
4. Inquiry
5. TestUnit
6. RequestSense
7. TestUnit
8. ReadCapacity10 (or 16)
but TatOS' sequence works too.
There are no more things to say about the dt-bit.
Re: How are we supposed to send commands to USB flash drives
Posted: Sat Mar 14, 2015 11:32 am
by glauxosdev
Of course device address needs to be incremented.
I just use address 2 for boot device (dev0), on which I am focused.
In your sequence, I think you missed Set_address.
Edit: I was tired and I didn't read your post carefully. Sorry.
Re: How are we supposed to send commands to USB flash drives
Posted: Sat Mar 14, 2015 12:06 pm
by bigbob
In your sequence, I think you missed Set_address.
No, I didn't.
I set it right after getting the Device-Descriptor, and that I do before the above mentioned sequence (the one after getting the Config-Descriptor).
Re: How are we supposed to send commands to USB flash drives
Posted: Mon Mar 16, 2015 2:37 pm
by glauxosdev
Edit:
I found that inquiry returns an invalid serial number.
If I insert my device into an unrecognized port, I get no descriptors, but the same inquiry result.
I guess I didn't setup my device properly (set_address, set_config).
By the way, inquiry result happens to be cd drive's serial number without its first two digits.
Maybe it is a coincidence?
Is there something else I should check?
Re: How are we supposed to send commands to USB flash drives
Posted: Wed Mar 18, 2015 1:47 am
by bigbob
I am still just a beginner in USB, but I had a similar bug in the beginning and it occured because there was an extra pointer-increment in my bulk-io code.
Inquiry is the first bulk command to send and it doesn't work in your case.
First, I would check my bulk-io code, if I were you.
A 13-byte CSW needs to be read after every command(i.e. CBW), so it can also be a good idea to try to read it after the failed Inquiry. Just to see what happens.
It is always a good idea to read back the values you set (as you also suggested).
This is setConfig and getConfig copied from my code (and the usb 2.0 specification) [at least I hope
]:
Code: Select all
ehci_set_config_packet db 0, 9,
dw 1, 0, 0 // config value: 1
ehci_req_getcon_packet db 0x80, 8,
dw 0, 0, 1
My USB-code runs without problems on an old desktop computer, but on a Dell D820 laptop, the first TestUnit failed with a "CSW-tag mismatch". It turned out that the tag of that CSW was zero. Everything works if I ignore it.
I read somewhere that every USB command should be executed in a loop at least 3 times, and if it still fails, should it fail.
I am just trying to say, that USB is complex and probably a never-ending story.
Re: How are we supposed to send commands to USB flash drives
Posted: Thu Mar 19, 2015 8:37 am
by glauxosdev
bigbob wrote:First, I would check my bulk-io code, if I were you.
I will check it. I will also rewrite set_address, set_config, etc.
Re: How are we supposed to send commands to USB flash drives
Posted: Sat Mar 21, 2015 1:31 pm
by glauxosdev
Finally, I got it working!
I was just ignoring status transfers.
Lesson learned: First get something working, and only then try to optimize it.
I wrote a useless program (print a useless string using a system call)
and I loaded it from USB in 32 bits protected mode.
bigbob wrote:ehci2.asm is 2500+ lines
I got it in 989 lines, including numerous labels and empty lines above each label.
But still I implemented only one device and the data-toggle bit is in the TD, not the QH.
Also, thank you very much for your patience bigbob and ehenkes!
And of course thank you TomT for USB related source code!
Now I will rest a bit and then I will go on implementing ext2 file system.
Best regards,
glauxosdev
Re: How are we supposed to send commands to USB flash drives
Posted: Sat Mar 21, 2015 1:49 pm
by bigbob
Congratulations!