How are we supposed to send commands to USB flash drives?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
glauxosdev
Member
Member
Posts: 119
Joined: Tue Jan 20, 2015 9:01 am
Libera.chat IRC: glauxosdever

Re: How are we supposed to send commands to USB flash drives

Post 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. :)
glauxosdev
Member
Member
Posts: 119
Joined: Tue Jan 20, 2015 9:01 am
Libera.chat IRC: glauxosdever

Re: How are we supposed to send commands to USB flash drives

Post 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.
bigbob
Member
Member
Posts: 122
Joined: Tue Oct 01, 2013 2:50 am
Location: Budapest, Hungary
Contact:

Re: How are we supposed to send commands to USB flash drives

Post 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.
glauxosdev
Member
Member
Posts: 119
Joined: Tue Jan 20, 2015 9:01 am
Libera.chat IRC: glauxosdever

Re: How are we supposed to send commands to USB flash drives

Post 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.
Last edited by glauxosdev on Sun Mar 15, 2015 6:15 am, edited 1 time in total.
bigbob
Member
Member
Posts: 122
Joined: Tue Oct 01, 2013 2:50 am
Location: Budapest, Hungary
Contact:

Re: How are we supposed to send commands to USB flash drives

Post 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).
glauxosdev
Member
Member
Posts: 119
Joined: Tue Jan 20, 2015 9:01 am
Libera.chat IRC: glauxosdever

Re: How are we supposed to send commands to USB flash drives

Post 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?
bigbob
Member
Member
Posts: 122
Joined: Tue Oct 01, 2013 2:50 am
Location: Budapest, Hungary
Contact:

Re: How are we supposed to send commands to USB flash drives

Post 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.
glauxosdev
Member
Member
Posts: 119
Joined: Tue Jan 20, 2015 9:01 am
Libera.chat IRC: glauxosdever

Re: How are we supposed to send commands to USB flash drives

Post 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.
glauxosdev
Member
Member
Posts: 119
Joined: Tue Jan 20, 2015 9:01 am
Libera.chat IRC: glauxosdever

Re: How are we supposed to send commands to USB flash drives

Post by glauxosdev »

Finally, I got it working! :D 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
bigbob
Member
Member
Posts: 122
Joined: Tue Oct 01, 2013 2:50 am
Location: Budapest, Hungary
Contact:

Re: How are we supposed to send commands to USB flash drives

Post by bigbob »

Congratulations! :)
Post Reply