Hello there.
I've been reading a bunch about USB and USB specifications (especially OHCI since it's what's available on the old laptop that currently serves as my testing hardware) over the last two weeks.
If I get it right, the os should talk to the Host Controller Interface in order to talk to a specific device. HCI are typically PCI devices and their memory space can be accessed through BAR0 and they require enabling bus mastering in order for them to reply as they typically talk via user-specified memory locations. There are many HCI types depending on the USB protocol version, but they all allow the os to send packets to specific functions.
You can read or send a packet to the USB device by queuing up a transfer descriptor in a space pointed to by an endpoint descriptor that contains a pointer to (I guess) memory on the bus, without paging as it has nothing to do with the CPU, the HCI being the bus master here (so I guess it would be possible to pipe those packets to another device on the bus, but it's more a subsidiary question).
I get that most USB devices don't have internal addresses as USB drives do, USB is more like a unified transaction protocol that establishes a master/slave transmission protocol.
So my current guess is that I have to implement at least 3 drivers :
1 for my HCI (in this case OHCI)
1 that uses my HCI driver to talk to USB devices by doing all the USB bus administration/wrapping USB packets
1 for the particular device I want to talk to
I guess USB drives have a standardized way to read data from address and write data to address, as well as commands to get information from them, and this way lives on USB, which is only the way to make information transit to them. I tried looking that up on the internet but I was unable to find this, so I guess I missed something. I know for a fact that the USB SET_ADDRESS command is likely not what i'm looking for. Can someone tell me if I get things wrong and if not, where to find this information ?
usb drive commands
-
- Member
- Posts: 5563
- Joined: Mon Mar 25, 2013 7:01 pm
Re: usb drive commands
All of the USB specifications are here.
Since you're looking at storage devices, there's a helpful list in the Mass Storage Class Specification Overview that can tell you which specification you need to read based on the class code of your USB storage device.
Since you're looking at storage devices, there's a helpful list in the Mass Storage Class Specification Overview that can tell you which specification you need to read based on the class code of your USB storage device.
Re: usb drive commands
Thanks a lot !! have a nice day !!
Re: usb drive commands
Hi,
In theory, once you set up the Host Controller, you seldom need to "communicate" with it. All communication is done via physical RAM. About the only thing you need to do with the Host Controller (HC) is acknowledge interrupts and other events.
Then, you send/receive 8-byte packets (OHCI) through the Control and Status Pipes, using larger packet sizes (possible max of 64 for full-speed devices) for the Data Pipe.
Once you enumerate the attached device, which will tell you what protocol to use to read/write sectors, for example, you then use the Data Pipe to transfer sectors. Older devices, especially when plugged into an OHCI, will most likely use the BBB protocol, or Bulk/Bulk/Bulk protocol, also known as the Bulk-Only protocol. You send a command packet, send or receive sectors, and receive a Status packet, all on the Data Pipe via Bulk transfers.
As for the Memory Bus, this is completely transparent to your drivers. All communication is done via physical RAM.
1) You need a HC driver, which simply sets up the HC and monitors events.
2) You need a packet transfer driver. A layer between the device layer and the HC layer.
3) You need a device specific driver, in this example a Bulk-only driver.
Number 2) is optional, though a more advanced system will benefit greatly with this option.
As Octocontrabass has shown, find the Mass Storage Class Specification (MSD) and read over it, then come back with your questions.
Ben
- https://www.fysnet.net/the_universal_serial_bus.htm
In theory, once you set up the Host Controller, you seldom need to "communicate" with it. All communication is done via physical RAM. About the only thing you need to do with the Host Controller (HC) is acknowledge interrupts and other events.
Then, you send/receive 8-byte packets (OHCI) through the Control and Status Pipes, using larger packet sizes (possible max of 64 for full-speed devices) for the Data Pipe.
Once you enumerate the attached device, which will tell you what protocol to use to read/write sectors, for example, you then use the Data Pipe to transfer sectors. Older devices, especially when plugged into an OHCI, will most likely use the BBB protocol, or Bulk/Bulk/Bulk protocol, also known as the Bulk-Only protocol. You send a command packet, send or receive sectors, and receive a Status packet, all on the Data Pipe via Bulk transfers.
As for the Memory Bus, this is completely transparent to your drivers. All communication is done via physical RAM.
In theory, yes.So my current guess is that I have to implement at least 3 drivers :
1 for my HCI (in this case OHCI)
1 that uses my HCI driver to talk to USB devices by doing all the USB bus administration/wrapping USB packets
1 for the particular device I want to talk to
1) You need a HC driver, which simply sets up the HC and monitors events.
2) You need a packet transfer driver. A layer between the device layer and the HC layer.
3) You need a device specific driver, in this example a Bulk-only driver.
Number 2) is optional, though a more advanced system will benefit greatly with this option.
As Octocontrabass has shown, find the Mass Storage Class Specification (MSD) and read over it, then come back with your questions.
Ben
- https://www.fysnet.net/the_universal_serial_bus.htm
Re: usb drive commands
I suspect, Iaen may have meant a USB core driver as his number two.BenLunt wrote:In theory, yes.So my current guess is that I have to implement at least 3 drivers :
1 for my HCI (in this case OHCI)
1 that uses my HCI driver to talk to USB devices by doing all the USB bus administration/wrapping USB packets
1 for the particular device I want to talk to
1) You need a HC driver, which simply sets up the HC and monitors events.
2) You need a packet transfer driver. A layer between the device layer and the HC layer.
3) You need a device specific driver, in this example a Bulk-only driver.
Number 2) is optional, though a more advanced system will benefit greatly with this option.
I would model it something akin to the way Seabios does it. I have seen similar systems replicated in different pieces of software, so they must be doing something right. The idea is that you have, as abstract entities, a USB host controller, a USB device, a USB hub, and a USB pipe. A host controller knows how to open a pipe to a specific endpoint on a specific device, and how to dispose of the pipe again, and how to transfer packets in all of the four modes and all of the two directions through any pipe opened through it.
A USB device knows not much more than its device address and the configuration descriptor. From that, configuration, interfaces, and endpoints intrinsically follow. It is just part of the spec. Again, host controllers can open pipes to given endpoints on given devices.
A USB hub knows how many ports it has, and how to enable, disable, query the status of, and reset the device behind each port.
And finally the pipes are the means of communication. They know what endpoint they connect to, and the host controller uses them to transfer data in the given way to the given endpoint. Obviously, there is some leeway in the division of labor here.
Each actual host controller implementation then must provide both a USB host controller and a root hub for the implementation. The USB core can provide routines such as the enumerator, because that is the same for all host controllers. Actually, all hubs: You enumerate a hub by doing this, for each port in parallel:
- enable port
- wait until "Power Good"
- check to see if there is a device there
- if not, disable port and exit
- else take lock on the bus (the "reset lock")
- reset the port
- address the device
- release the reset lock
- then enumerate the device itself
The point of all that modularity, is, of course, to insulate the USB class drivers from the host controllers themselves. So adding a new host controller doesn't mean you have to write all you USB MSC stuff again.
Carpe diem!
Re: usb drive commands
Hi.
First thanks everyone to have taken the time to reply.
I am currently digesting all the information that I read and I started a really basic implementation in order to see if I'm able to set up at least drivers 1) and 2) to be able to communicate with USB devices/functions.
I'll be probably coming back in a few month either if I haven't successed at all, or to share good news !
Once again, thanks all for your time,
have a wonderful day,
Laen
First thanks everyone to have taken the time to reply.
I have looked through it and it's what I meant. I'm sorry if I described it poorly as english isn't my mother tongue.nullplan wrote: I suspect, Iaen may have meant a USB core driver as his number two.
That's about the core of the idea I had, even though I wasn't exactly sure about what are USB pipes, my guess being it was in some way analog to UNIX pipe files, but to communicate with USB.nullplan wrote: he idea is that you have, as abstract entities, a USB host controller, a USB device, a USB hub, and a USB pipe.
I am currently digesting all the information that I read and I started a really basic implementation in order to see if I'm able to set up at least drivers 1) and 2) to be able to communicate with USB devices/functions.
My basic idea currently is to first checkout what USB devices and what functions are available, then check if I currently support drivers by using class/subclass,and then if it's a USB HUB, repeat by communicating with it, else mount the device into the file system. That should keep me busy for a while as you said.nullplan wrote: And that last one then entails such things as reading its config descriptor and seeing if you can do anything with the device. That enumeration then initializes a USB class driver. That is where they come in. You will definitely need a driver for USB hub devices. Those are also USB hubs as specified above, only with specific methods (which typically entail sending configuration requests on the default control pipe). And yes, USB MSC is also a class that needs a driver, as is USB UAS, and USB HID. Those four should tide you over for a while.
The first purpose of this post was that I was at lost for documentation, as I didn't really know what I was looking for and how to find it (I'm no USB expert )BenLunt wrote: As Octocontrabass has shown, find the Mass Storage Class Specification (MSD) and read over it, then come back with your questions.
Ben
- https://www.fysnet.net/the_universal_serial_bus.htm
I'll be probably coming back in a few month either if I haven't successed at all, or to share good news !
Once again, thanks all for your time,
have a wonderful day,
Laen
Re: usb drive commands
It isn't mine, either. But no worries, misunderstandings will always happen.laen wrote:I'm sorry if I described it poorly as english isn't my mother tongue.
Not quite. USB has endpoints. A pipe is a connection to an endpoint. I just kept noticing this same term, and it was usually used to abstract away the host-controller dependent parts of sending a message to an endpoint.laen wrote:That's about the core of the idea I had, even though I wasn't exactly sure about what are USB pipes, my guess being it was in some way analog to UNIX pipe files, but to communicate with USB.
Carpe diem!
Re: usb drive commands
Yeah, the USB specification (both 2.0 and 3.2) just define a pipe as "an association between an endpoint on a device and software on the host". The USB 2.0 specification goes into significantly more detail on pipes in section 5.3.2, but the USB 3.2 specification just notes (in 4.2.1) that the behavior is identical for enhanced SuperSpeed pipes, with the proviso that "when a non-isochronous Enhanced SuperSpeed endpoint is busy it returns a Not Ready (NRDY) response and must send an Endpoint Ready (ERDY) notification when it wants to be serviced again".