Universal Serial Bus: Difference between revisions

m
fixed misspelling
[unchecked revision][unchecked revision]
(finished usb protocl information, rearranged and fixed other minor things)
m (fixed misspelling)
 
(46 intermediate revisions by 16 users not shown)
Line 1:
The Universal Serial Bus was first introduced in 1994 with the intention of replacing various specialized interfaces, and to simplify the configuration of communication devices. The communication industry did not develop as the USB-IF foresaw, but the various transfer modes that USB introduced allowed it to become one of the most popular standards in use today. Virtually every modern computer supports USB.
 
== Introduction ==
Despite how attractive USB support is, the 650-page USB 2.0 specification manages to deter even some of the most driven hobbyists (especially if English isn't their primary language). Not only is the USB 2.0 specification long, but it's a prerequisite for the [[XHCI]], [[EHCI]], [[UHCI]], and [[OHCI]] specifications, which define the actual hardware OSes interface with. Furthermore, the USB specification defines a plethora of terms, some used interchangeably and seemingly lazily; as a lengthy technical document, it is neither easy nor practical to flip back and forth to clarify a confusing term or concept.
 
=== What this text covers ===
The truth is that a software developer doesn't need to read the entire USB 2.0 specification; there are sections specific to hardware developers, for example. The information presented here attempts to summarize chapters 4, 5, and 8 through 10.
 
Chapter 11 is specific to hubs and is also essential for a full USB 2.0 implementation, however it is almost as long as chapters 4, 5, 8, 9, and 10 combined, and could be regarded as the documentation for a specific (albeit special) class of USB devices. Chapter 11 is covered thusly in its own wiki entry, [[USB Hubs]]. Even so, some concepts which pertain to USB hubs are briefly discussed where relevant in this article.
 
Ideally, the text here will establish familiarity with the terms and concepts that a hobby OS developer needs to begin implementing USB support and, if necessary, easily parse the USB specification without becoming intimidated by the amount of information. At the very least, the system programmer should keep a copy of the USB 2.0 specification for reference while working with USB-related hardware.
 
Fortunately, all of the necessary documentation is available for free (see [http://wiki.osdev.org/USB#Links Links]).
 
=== What this text does not cover ===
Please note that USB, unlike other standards like [[VGA]] or [[PCI]], is agnostic of the hardware interface to the system bus (and, by extension, to the operating system). Such an interface is provided by one or more [[#Host_Controllers|USB host controllers]] and is defined by the appropriate documentation. Therefore, one should not expect this text to discuss specifics or code samples (e.g., as one finds in the wiki entries about [[VGA]] or [[PCI]]) detailing how the operating system initiates and maintains communication with USB devices. Although such information may be found on wiki entries discussing a particular [[#Host_Controller_Driver|Host Controller Driver]], those wiki entries assume an understanding of the concepts and terms discussed here.
 
== Host Controllers ==
Line 5 ⟶ 20:
 
=== USB 1.0 Host Controllers ===
{{Main|Universal Host Controller Interface}}
Intel brought USB 1.0 to the market with its '''Universal Host Controller Interface''' ('''UHCI'''), while Compaq, Microsoft, and National Semiconductors did the same with their '''Open Host Controller Interface''' ('''OHCI'''). Naturally, the two interfaces are incompatible, and to make things worse, VIA Technologies licensed Intel's UHCI standard, thereby ensuring that both standards survived. Typically, an on-board chip set will contain a UHCI implementation, whereas a peripheral card typically implements the OHCI standard (but this is by no means a guarantee).
{{Main|Open Host Controller Interface}}
 
Intel brought USB 1.0 to the market with its '''Universal Host Controller Interface''' ('''UHCI'''), while Compaq, Microsoft, and National Semiconductors did the same with their '''Open Host Controller Interface''' ('''OHCI'''). Naturally, the two interfaces are incompatible, and to make things worse, VIA Technologies licensed Intel's UHCI standard, thereby ensuring that both standards survived. Typically, an on-board chip set will contain a UHCI implementation, whereas a peripheral card typically implements the OHCI standard (but this is by no means a guarantee).
'''Specifications'''
* [http://download.intel.com/technology/usb/UHCI11D.pdf Universal Host Controller Interface (UHCI) Specifiations]
* [http://www.o3one.org/hwdocs/usb/hcir1_0a.pdf Open Host Controller Interface (OHCI) Specifications]
 
=== USB 2.0 Host Controllers ===
{{Main|Enhanced Host Controller Interface}}
[[Image:PortRoutingBlockDiagram.gif|frame|Figure 1: Block Diagram of Port Routing Behavior]]
In designing USB 2.0, the USB-IF insisted on a single implementation. That single implementation is Intel's '''Extended Host Controller Interface''' ('''EHCI'''). However, even though the USB 2.0 specification requires that a USB 2.0 interface support USB 1.0 devices, this doesn't mean that the EHCI must support USB 1.0 devices, and in fact, it doesn't. Each EHCI host controller is accompanied by (usually several) UHCI and/or OHCI host controllers. When a USB 1.0 device is attached, the EHCI simply hands control over to a '''companion controller'''. Refer to figure 1 for a simple block diagram implementation of this behavior. Therefore, the system programmer must support all three standards in order to support USB 2.0.
 
[[Image:PortRoutingBlockDiagram.gif|frame|Figure 1: Block Diagram of Port Routing Behavior]]
The EHCI host controller only handles USB 1.0 devices if they are attached indirectly through a USB 2.0 hub. The specifics of handling USB 1.0 devices attached to a USB 2.0 hub are briefly discussed and illustrated in [[#Hubs|hubs]], and in more detail under [[#Split Transactions|Split Transactions]]
In designing USB 2.0, the USB-IF insisted on a single implementation. That single implementation is Intel's '''Enhanced Host Controller Interface''' ('''EHCI'''). However, even though the USB 2.0 specification requires that a USB 2.0 interface support USB 1.0 devices, this doesn't mean that the EHCI must support USB 1.0 devices, and in fact, it doesn't. Each EHCI host controller is accompanied by (usually several) UHCI and/or OHCI host controllers. When a USB 1.0 device is attached, the EHCI simply hands control over to a '''companion controller'''. Refer to figure 1 for a simple block diagram implementation of this behavior. Therefore, the system programmer must support all three standards in order to support USB 2.0.
 
The EHCI host controller only handles USB 1.0 devices if they are attached indirectly through a USB 2.0 hub. The specifics of handling USB 1.0 devices attached to a USB 2.0 hub are briefly discussed and illustrated in the [[#Hubs|hubs]] section, and in more detail in the wiki entry for [[USB Hubs]]. Note that some newer chipsets like the Intel 5-series chipsets do not have companion controllers at all and instead have internal "rate matching" hubs that all USB devices go through.
'''Specifications'''
* [http://www.intel.com/technology/usb/download/ehci-r10.pdf Extended Host Controller Interface (EHCI) Specifications]
 
=== USB 3.0 Host Controllers ===
{{Main|eXtensible Host Controller Interface}}
In late 2008, the USB-IF released the USB 3.0 specifications. USB 3.0 host controllers are just starting to make their way into consumer devices since NEC introduced the world's first “SuperSpeed USB 3.0 host controller” in May, 2009, [http://www.techspot.com/news/34763-nec-introduces-worlds-first-usb-30-host-controller.html techspot reports].
 
Like its predecessor USB 2.0, USB 3.0 has only one host controller specification: Intel's '''eXtensible Host Controller Interface'''. Unlike its predecessor EHCI, however, xHCI controllers can and do interface with USB 1.0 and 2.0 devices without the use of companion controllers. Even on early hardware where there was both an EHCI and xHCI controller included (so that OSes which did not yet support xHCI could still use at least some USB devices), ports attached to the EHCI controller could generally be "re-routed" to the xHCI controller, and the EHCI controller disabled entirely.
'''Specifications'''
* [http://www.usb.org/developers/docs/usb_30_spec_052109.zip USB 3.0 Specifications]
 
Also unlike its predecessors, xHCI was designed with some degree of ''forwards compatibility'', so that revisions to the USB specification can be made without designing a new host controller interface (for instance, USB 3.1 and 3.2 add new speeds, with only minor updates to the specification to match them.) Unfortunately, this means that xHCI bears only a passing resemblance to the controllers that came before it, and make it challenging to write drivers for.
== Supporting USB ==
Despite how attractive USB support is, the 650-page USB 2.0 specification manages to deter even some of the most driven hobbyists (especially if English isn't a his/her primary language). Not only is the USB 2.0 specification long, but it's a prerequisite for the EHCI, UHCI, and OHCI specifications, all of which must be implemented for full USB 2.0 support.
 
The truth is that you don't need to read the entire USB 2.0 specification; there are sections specific to hardware developers, for example. The information presented here attempts to summarize chapters 4, 5, and 8 through 11, but reading those sections of the specification is recommended.
 
On the other hand, the specifications were not written to simply take up space. The USB architecture is relatively extensive and can only be summarized so much. At the very least, the system programmer should keep a copy of the USB 2.0 specifications to reference when he/she is unsure about something. Hopefully the information here will also make the specifications easier to understand, as some terms can be confusing at first.
 
Fortunately, all of the necessary documentation is available or free:
* [http://www.usb.org/developers/docs/usb_20_052709.zip USB 2.0 Specifications]
* [http://www.intel.com/technology/usb/download/ehci-r10.pdf EHCI Specifications]
* [http://download.intel.com/technology/usb/UHCI11D.pdf UHCI Specifications]
* [http://www.o3one.org/hwdocs/usb/hcir1_0a.pdf OHCI Specifications]
 
== Basic Concepts and Nomenclature ==
Line 52 ⟶ 53:
All functions understand the USB protocol, respond to standard operations (e.g, configuration or reset), and describe capabilities to the USB host.
 
There are threefour speed classes of functions:
* '''Super-speed''' functions operate at up to 5 Gb/s.
* '''High-speed''' functions operate at up to 480 Mb/s.
* '''Full-speed''' functions operate at up to 12 Mb/s.
* '''Low-speed''' functions operate at up to 1.5 Mb/s.
 
The original USB specification defined low- and full-speed devices, while USB 2.0 added high-speed devices. and USB 3.0 will add a fourth transferadded super-speed of up to 5 Gb/s, called SuperSpeeddevices.
 
===== Hubs =====
Line 65 ⟶ 67:
 
But what happens when a full- or low-speed device is connected to the high-speed hub in figure 5? If the EHCI controller were to relinquish ownership of the port, the high-speed devices will no longer be able to operate at high-speed, if at all, as in figure 6. Instead, the host controller and the hub support a special type of transaction called a split transaction. A '''split transaction''' involves only the host controller and a high-speed hub; it is transparent to any devices. This scheme of using split-transaction to support low- and full-speed devices on a high-speed hub is illustrated in figure 7.
 
Note that some newer chipsets like the Intel 5-series chipsets do not have companion controllers at all and instead have internal "rate matching" hubs that all USB devices go through.
 
<gallery perrow=5>
Image:LFSpeedDevToHSPort.gif|Figure 3: Low- or Full-speed device connected to a high-speed capable USB port
Line 73 ⟶ 78:
</gallery>
 
<!--
[[Image:LFSpeedDevToHSPort.gif|thumb|left|Figure 3: Low- or Full-speed device connected to a high-speed capable USB port]]
[[Image:HSHubToHSPort.gif|thumb|Figure 4: High-speed hub connected to a high-speed capable USB port]]
[[Image:HSDevsToHSHubToHSPort.gif|thumb|none|Figure 5: High-speed devices connected to a high-speed hub which is connected to a high-speed USB port]][[Image:LFHSDevsHSHubHSPortIncorrect.gif|thumb|none|Figure 6: Incorrect illustration of Low- and Full-speed devices on a high-speed bus]][[Image:LFHSDevsHSHubHSPortCorrect.gif|thumb|none|Figure 7: Correct illustration of split transactions allowing Low- and Full-speed devices on a high-speed bus]]
-->
[[Image:USBTopology.gif|thumb|right|Figure 8: USB Topology]]
 
==== USB Interconnect ====
The '''USB interconnect''' provides a connection from the USB device(s) to the USB host. Physically, the USB interconnect is a tiered star topology. A maximum of seven tiers are allowed, and the root hub occupies the first tier. Since compound devices contain an embedded hub, a compound device cannot be attached in tier 7. Figure 8 illustrates a USB topology (taken from Figure 4-1 of the USB 2.0 specifications).
Line 107 ⟶ 108:
Besides the two required endpoints, functions may implement additional endpoints as necessary, with the following limitations:
* Low-speed functions may implement up to two additional endpoints.
* Full- and high-speed devices may implement up to 15 additional input endpoints and 15 additional output endpoints. TheThis reasonsis fora thisphysical limitlimitation willof bethe clearUSB laterprotocol onand is discussed under [[#Endpoint_field|Endpoint_Field]].
 
==== Endpoint Zero ====
Line 165 ⟶ 166:
A control transfer always uses it's maximum data payload size for data payloads unless the data payload is less than the maximum data payload size. That is, if an endpoint has a maximum data payload size of 64 bytes, and a control transfer intends to transmit 100 bytes, the first data payload must contain 64 bytes and no less. The remaining 36 bytes are transferred in the second payload and need not be padded to 64 bytes. When the host receives a data payload less than the maximum data payload, the host may consider the transfer complete.
 
A SETUP packettransaction's data payload is always 8 bytes and thus receivable by the endpoint of any USB device. Consequently, the host may query the appropriate descriptor from a newly-attached full-speed device during configuration in order to determine the maximum data payload size for any endpoint; the host can then adhere to that maximum for any future transmissions.
 
===== Transmission Errors =====
Line 267 ⟶ 268:
 
==== Bus Time Rationing ====
There are separate rules for the allocation of frames on a full- or /low-speed bus, and for the rules for allocation of microframes on a high-speed bus.
 
For full- or low- speed buses:
Line 433 ⟶ 434:
 
==== Address Fields ====
Address fields select a specific endpoint on a specific function. Naturally, two such fields are defined: an address field and an endpoint field. All devices must fully decode these fields; a mistmatchmismatch of either field (including an endpoint field which specifies an endpoint that have not been initialized) must be ignored.
 
===== Address Field =====
Line 481 ⟶ 482:
 
==== Cyclic Redundancy Checks ====
Cyclic Redundancy Checks (CRC) protect all non-PID fields and provide 100% converagecoverage for all single- and double-bit errors. CRCs are provided for each token field as well as the data field. This provides a mechanism for the host or device to recognize and either correct or ignore corrupted fields or, in most cases, an entire corrupted packet.
 
=== Handshakes ===
Line 513 ⟶ 514:
An ACK handshake is issued to communicate that a data packet was successfully received without any bit stuffing or CRC errors over the data field, and the PID field was not corrupted.
 
ACK packets may be issued when the receiver's sequence bit matches the sequence bit of the received data packet (and the data can be accepted), but the an ACK packet may also be issued when the receiver's sequence bit does not match the sequence bit of the received data packet (and the data cannot be accepted). This may seem counterintuitivecounter intuitive, but the reasoning will become clear in the sections discussing data toggling.
 
===== NAK =====
Line 580 ⟶ 581:
 
==== Function/Host Response Circumstances ====
This section describes the functional circumstances that cause the host or a function to issue an expected response, no response, or certain handshake packet responses. The tables in this section are taken and slightly modified for clarity from the USB 2.0 Specificationsspecifications, section 8.4.6. Dashes denote a "don't care."
 
===== Function Response to IN Transactions =====
Line 685 ⟶ 686:
The PING transaction protocol is very straightforward. Rather than an OUT transaction, the host issues a PING transaction to the function when the host wishes to send data. The function responds with either NAK to indicate that it is not ready to receive data (specifically, the function's buffer cannot accommodate the endpoint's maximum data payload amount of data), or ACK to indicate that the host may start sending data.
 
The USB 2.0 framework allows endpoints to specify an interval, in terms of microframes, which is the amount of micorframesmicroframes that the host should wait before issuing another PING packet to the endpoint. However, the host is not required to wait this interval before issuing the next PING packet.
 
During a high-speed control or bulk transfer from the host to function, when an OUT transactions causes a function's free buffer space to drop below the endpoint's maximum data payload, the function responds with a NYET handshake packet. This indicates that the host should start issuing PING packets rather than additional OUT transactions.
Line 713 ⟶ 714:
[[Image:FailedDataTx.gif|thumb|left|Figure 13: Illustration of how the sender and receiver manage their data toggle bits during a failed or corrupt data transfer]]
==== Failed or corrupted data transmissions ====
Figure 13 illustrates a failed or corrupted data transmission. Both devices have data toggle bits set to 0 at the beginning of transfer i. Accordingly, the sending device issues a DATA0 PID followed by the data packet. The receiving device either does not see the data packet, or reads a corrupted data packet. The receieverreceiver maintains its data toggle bit and issues a NAK handshake. The sender successfully sees the NAK handshake and thus does not toggle its data toggle bit.
 
At the beginning of the next transfer, both the sending and receiving device have data toggle bits still set to 0. Supposing this transfer completes successfully, it is carried as as described above, under [[#Successful_transmissions|successful transmissions]].
Line 776 ⟶ 777:
[[Image:HSHBIsoOUT.gif|frame|center|Figure 19: Data Phase Sequence for Isochronous OUT High Bandwidth Endpoints]]
 
== TODOUSB Device Framework ==
The USB device framework is the thing that makes USB support so appealing. The transfer types and USB protocol are well-designed, of course, but the USB device framework defines standard device states that all devices must support, as well as standard requests and responses that allow the host to retrieve more than enough information about a device to determine the correct device driver and report information about the device even if the correct device driver isn't available (e.g, the manufacturer's name, the product's name, etc).
Currently the above article is missing the following topics:
* USB Framework
** Device States
** Standard requests and descriptors
* Typical organization of system software
* Hubs (including Split Transactions)
 
=== Functions, Configurations, Interfaces, and Endpoints ===
== Original USB Wiki Content ==
[[Image:FunctionConfigsIFacesEPs.gif|frame|right|Figure 20: Illustration of the relationship between functions, configurations, interfaces, and endpoints.]]
Until the above sections are complete, the original content of this wiki entry that has not been covered in more depth is placed here.
All USB devices, or functions, have at least one configuration, and every configuration has at least one interface. An interface may define zero or more endpoints. This relationship is illustrated in figure 20.
 
Although configurations descriptors are addressed sequentially starting with configuration descriptor zero, each configuration specifies a unique (within the scope of the function), none-zero configuration value. The '''configuration value''' is what the host needs to know in order to apply a certain configuration to a device. When asking for the current configuration of a device, a returned value of zero indicates that the device is not configured and is thus in the address state.
=== USB keyboards/mice ===
 
An '''interface''' defines the functional use of a set of endpoints and may imply that certain class-specific requests can be executed via the default control pipe. Thus, an interface need not necessarily define any additional endpoints. No interface may define the functional use of endpoint zero.
Keyboards and mice are what the USB standard calls HID (Human Interface Device) class devices, and follow a special superset of the USB standard. Once you have a driver for a HID device, all USB HID devices will work with it, including mice, keyboards, joysticks, game controllers, and so forth. The HID standard is built on top of lower-level USB API's to send and receive data packets across the wire, but provides a translation layer that interprets the USB data so that the HID layer could conceivably be implemented on top of other protocols (Like PS/2 or serial).
 
Each interface describes a unique set of endpoints within the scope of the configuration. However, an interface may provide one or more '''alternate settings''', which may have different definitions for the same set of endpoints. When the host selects an alternate setting for an interface, the alternate setting's definitions are used instead of the default settings of the same interface.
For early stages, you can probably ignore the fact that those devices are USB. Virtually every chipsets will offer a good old PS/2 emulation of the USB human interface devices, so you can use I/O port 0x60 like the rest of us ...
 
=== Booting off of a USB flashDevice diskStates ===
A USB device may define states that are internal to the device, however the USB device framework defines a set of states that are visible to both the host and the device. Those visible states are the following:
 
* '''Attached''' - Immediately after the USB device is attached to the USB system, it is in this state. The USB specifications do not define the state of a USB device that is detached from a USB system.
If the [[BIOS]] supports it is it as simple as selecting USB-FDD in the boot order and putting a simple bootloader (grub might do, I rolled my own) into the first 512 bytes of the device. The BIOS will handle all the fancy PCI / USB stuff via int 0x13. Note that there is no need for any specific filesystem or partitions (which means you can just "dd" a 2.2 linux kernel (which used to contain a simple floppy loader) to /dev/sda and it will easily come up).
* '''Powered''' - A device is in this state after it has both been attached to the bus, and the V<span style="vertical-align:sub;">BUS</span> line is applied to the device (the host controller drives the V<span style="vertical-align:sub;">BUS</span> at +5V, however this is only particularly important for hardware developers). In this state, the device must not respond to any bus transactions. The USB specification recognizes three potential scenarios with respect to how a device draws power:
** ''Self-Powered Devices'' draw power from an external power source (e.g, a USB printer plugs into the wall as well as a USB port). Although the device may be considered technically "powered" even before attachment to the USB, it is still only considered powered after the V<span style="vertical-align:sub;">BUS</span> line is applied to the device.
** ''Bus-Powered Devices'' draw power solely from the USB up to 100mA.
** ''Self- or Bus-Powered Devices'' may draw power from either the bus or an external power source, depending on the configuration. These devices may change power source at any time. If a device is currently self-powered and requires more than 100mA of power, but switches to being bus-powered, then the device must return to the Address state.
* '''Default''' - A device in the powered state enters the default state after receiving a bus reset. In this state, the device is addressable at the default, reserved address of 0. At this point, the device is operating at the correct speed. The host is expected to allow 10 milliseconds before expecting the device to respond to data transfers after reset.
* '''Address''' - A device enters this state after the host assigns it an address via the default control pipe, which is always accessible whether the device's address has been set or not.
* '''Configured''' - A device is in this state after the host examines its possible configurations and selects one. All endpoint's data toggle bits are initialized to zero when a device enters this state.
* '''Suspended''' - When no traffic is observed on the bus for a period of 1 millisecond, a USB device enters this state, characterized by its low power consumption. The device's address and configuration settings are maintained while suspended. A device exits the suspended state as soon as it begins seeing bus activity again. The host is expected to allow 10 milliseconds before expecting the device to respond to data transfers after resume.
 
=== AddingRemote USBWakeup supportCapability ===
One of the reasons a USB device may stop seeing USB traffic and thus enter a suspended state is because the host may have entered a suspended state as well. Some devices, typically keyboards and mice, support the ability to issue a remote wakeup signal to the host. In case the host software does not support remote wakeup, this capability must be disabled when a USB device is reset. If the host does support remote wakeup, then it may selectively enable the remote wakeup capability for specific devices (typically as chosen by the user). Then, these devices may issue a remote wakeup signal while in a suspended state to request that the host exits its own suspended state.
 
=== USB Device Enumeration ===
As a first step, you'll need to provide a driver for the USB Host Controller, which appears in most cases as a [[PCI]] device and will allow you to enumerate devices on the USB [[:Category:Buses|bus]] and send packets to the identified devices. Documentation about the [http://www.o3one.org/hwdocs/usb/hcir1_0a.pdf Open Host Controller Interface], [http://developer.intel.com/design/USB/UHCI11D.htm Universal Host Controller Interface] and [http://www.intel.com/technology/usb/download/ehci-r10.pdf Extended Host Controller Interface] are available freely. Your USB-aware chipset should support one of these three.
The following describes the process of bus enumeration, which occurs after a device is connected to a powered port:
 
# The hub to which the device has been attached notifies the host via its status change pipe. The newly attached device is in the powered state at this point, and the port to which it has been attached is disabled.
Once you know what devices are present, you'll have to identify a device-specific driver that will match that hardware. For some devices (webcams, scanners, etc), this may require a vendor-specific driver while other devices (USB keychains, HID etc) have to adhere to _class_ standards. This means that one can write a generic USB storage driver that will work with all possible keychains, embedded mp3 players, flash card readers, etc.
# The host queries more information from the hub to determine that a device has been attached, and to which port.
# The host must wait at least 100 millisecond to allow a device to complete its insertion process, and for power to stabilize at the device. After the delay, the host enables the port and issues a reset signal to the device for at least 50 milliseconds.
# The hub performs any required reset processing. After the reset signal has been released, the port is enabled and the device enters the default state.
# The host assigns the device a unique address, thereby transitioning the device into the address state.
# The host requests the device descriptor from the device via the default control pipe in order to determine the actual maximum data payload size of the default control pipe for the device. This step may occur before or after the host assigns the device an address.
# The host reads all the possible device configuration information.
# The host selects a certain configuration from the list of configurations supported by the device and sets the device to use that configuration. Optionally, the host may also select alternate interface settings within a configuration. All endpoints are initialized as described by the selected configuration, and the device is ready to use.
 
=== USB Device Requests ===
Don't forget that USB devices are hot-pluggable, that is they can be added and removed at any time while the system is running.
Standard, class-specific, and vendor-specific requests are made to the USB device over the default control pipe. The SETUP transaction always has a data payload size of 8 bytes, as noted in the [[#Maximum_Data_Payload_Size|Maximum Data Payload Size]] section of [[#Control_Transfers|Control Transfers]]. The format of the setup data is as follows:
 
{| border="1" cellpadding="5"
=== Brief Sequence of Operation ===
!Offset
!Field
Note: This is taken from [http://forum.osdev.org/viewtopic.php?f=1&t=17111 this thread] and may be inaccurate. It needs adding to at any rate.
!Size
!Type
'''Setup'''
!Description
|- valign="top" align="center"
* 1) Find ''Host Controller Type'', ''Info'' and ''IO address'' using the [[PCI]] bus
|0
* 2) Reset Host
|bmRequestType
* 3) Reset Port
|1
* 4) Check Port status to detect for device insertion
|Bitmap
* 5) Enable Port.
|align="center" |
{| border="1" cellpadding="15"
'''Device Interaction'''
|D<span style="vertical-align:sub;">7</span>
|D<span style="vertical-align:sub;">6</span>
* 1) Get ''Device Descriptor'' of device
|D<span style="vertical-align:sub;">5</span>
* 2) Get ''Config Descriptor'' of device
|D<span style="vertical-align:sub;">4</span>
* 3) Set ''Address'' of device
|D<span style="vertical-align:sub;">3</span>
* 4) Set ''Configuration'' of device
|D<span style="vertical-align:sub;">2</span>
|D<span style="vertical-align:sub;">1</span>
'''Sending Commands'''
|D<span style="vertical-align:sub;">0</span>
|}
Sending commands is protocol specific, this is dependant on the ''Device Type'' (OHCI, UHCI and EHCI - UHCI being the easiest).
{| border="0" cellpadding="0"
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">7</span>'''
The command is send in a similar manner to the Device Interaction section:
|'''Data transfer direction''' ''* The value of this bit is ignored when wLength is zero''
* 0b = Host-to-device
* 1) Setup ''Queue Heads'' linked list
* 1b = Device-to-host
* 2) Setup ''Transfer Descriptors'' linked list
|-
* 3) Populate both lists with valid data
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">6...5</span>'''
* 4) Inform ''USB Host Controller'' to start command transaction
|'''Type of request'''
* 00b = Standard
For '''Mass Storage Devices''' you must send specific commands using the ''CBW'' and ''CBS'' structures. You will also have to implement the following SCSI commands:
* 01b = Class
* 10b = Vendor
Inquiry, Get_Capacity and Read_10 or Write_10
* 11b = Reserved
|-
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">4...0</span>'''
|'''Recipient'''
* 00000b = Device
* 00001b = Interface
* 00010b = Endpoint
* 00011b = Other
* 00100b to 11111b = Reserved
|}
|- valign="top" align="center"
|1
|bRequest
|1
|Value
|align="left" |Specific request
|- valign="top" align="center"
|2
|wValue
|2
|Value
|align="left" |Word-sized field the may (or may not) serve as a parameter to the request, depending on the specific request.
|- valign="top" align="center"
|4
|wIndex
|2
|Index or offset
|align="left" |Word-sized field that may (or may not) serve as a parameter to the request, depending on the specific request. Typically this field holds an index or an offset value.<br /><br />
When bmRequestType specifies an endpoint as the recipient, the format of this field is as follows:
{| border="1" align="center"
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">7</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">6</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">5</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">4</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">3</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">2</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">1</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">0</span>'''
|- align="center"
|Direction
|colspan="3" |Reserved (reset to zero)
|colspan="4" |Endpoint Number
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">15</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">14</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">13</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">12</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">11</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">10</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">9</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">8</span>'''
|- align="center"
|colspan="8" |Reserved (reset to zero)
|}
The direction bit (bit '''D<span style="vertical-align:sub;">7</span>''') is set to zero to indicate the OUT endpoint with the specified endpoint number, or it is set to one to indicate the IN endpoint with the specified endpoint number. The host should always set the direction bit to zero (but the device should accept either value) when the endpoint is part of a control pipe.
 
When bmRequestType specifies an interface as the recipient, the format of this field is as follows:
==== Configuration ====
{| border="1" align="center"
The configuration part of the USB standard occurs through the notion of descriptors. Descriptors are blocks of information retrieved through the host controller which defines things like vendor/product identifiers for each device and class/subclass/protocol codes for each device's interface. Based on these informations, the Operating System can assign the proper driver to each device/interface.
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">7</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">6</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">5</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">4</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">3</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">2</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">1</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">0</span>'''
|- align="center"
|colspan="8" |Interface Number
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">15</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">14</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">13</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">12</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">11</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">10</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">9</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">8</span>'''
|- align="center"
|colspan="8" |Reserved (reset to zero)
|}
|- valign="top" align="center"
|6
|wLength
|2
|Count
|align="left" |Number of bytes to transfer if there is a DATA stage.<br /><br />
* If this field is non-zero, and bmRequestType indicates a transfer from device-to-host, then the device must never return more than ''wLength'' bytes of data. However, a device may return less.
* If this field is non-zero, and the bmRequestType indicates a transfer from host-to-device, then the host must send exactly ''wLength'' bytes of data. If the host sends more than ''wLength'' bytes, the behavior of the device is undefined.
|}
 
When a device receives a request that is undefined, is inappropriate given the current setting or state of the device, or uses values that are inappropriate for the particular request, then a '''Request Error''' exists. The device handles a Request Error by returning a STALL PID to the next DATA or STATUS stage, preferably at the next DATA stage transaction.
A list of structures defining USB descriptors is available in [http://clicker.cvs.sourceforge.net/*checkout*/clicker/c32-lxsdk/kernel/src/mods/io/include/usbdescr.h usbdescr.h] from Clicker's CVS (LGPL)
 
===== ReadingStandard descriptorsRequests =====
{|border="1" cellpadding="2" style="float:right;margin-left:20px;"
The host has to explicitly request descriptors from the device before it manipulates them. This is achieved by a setup transfer using a GET_DESCRIPTOR as the host->device data and receiving the descriptor as the data from the host. The whole transfer will look like
|+align="bottom" |'''Standard USB Request Codes'''
!bRequest
!Value
|-
|[[#GET_STATUS|GET_STATUS]]
|align="center" |0
|-
|[[#CLEAR_FEATURE|CLEAR_FEATURE]]
|align="center" |1
|-
|''Reserved''
|align="center" |2
|-
|[[#SET_FEATURE|SET_FEATURE]]
|align="center" |3
|-
|''Reserved''
|align="center" |4
|-
|[[#SET_ADDRESS|SET_ADDRESS]]
|align="center" |5
|-
|[[#GET_DESCRIPTOR|GET_DESCRIPTOR]]
|align="center" |6
|-
|[[#SET_DESCRIPTOR|SET_DESCRIPTOR]]
|align="center" |7
|-
|[[#GET_CONFIGURATION|GET_CONFIGURATION]]
|align="center" |8
|-
|[[#SET_CONFIGURATION|SET_CONFIGURATION]]
|align="center" |9
|-
|[[#GET_INTERFACE|GET_INTERFACE]]
|align="center" |10
|-
|[[#SET_INTERFACE|SET_INTERFACE]]
|align="center" |11
|-
|[[#SYNC_FRAME|SYNC_FRAME]]
|align="center" |12
|}
The standard requests are defined for all USB devices, and all USB devices must respond to these standard requests even if the device hasn't been assigned an address, or the device hasn't been configured. To issue a certain request, the software creates the SETUP stage's DATA packet using the appropriate '''request code''', a valid bmRequestType, the appropriate parameter values (or zero, if not applicable) for wValue and wIndex, and the amount of data bytes to be transfered for wLength. To the right are the standard USB device request codes, and the remainder of this section discusses each request.
 
==== SET_ADDRESS ====
* command transaction:
The SET_ADDRESS request has the following SETUP DATA packet format:
Setup_TOKEN(addr=device, endpoint=0) : host -> device
{| align="center" border="1" cellpadding="5"
DATA[ RequestType=0x80, Request=0x06, value=DESCR_TYPE|DESCR_SELECTOR,
|+align="bottom" |'''SET_ADDRESS SETUP DATA Packet Format'''
index=0, length=wished_length] : h->d, 8 bytes
!bmRequestType
ACK : host <- device
!bRequest
!wValue
!wIndex
!wLength
|- align="center"
|00000000b
|SET_ADDRESS<br />5
|Device Address
|Zero
|Zero
|}
 
This request does not have a DATA stage, only a SETUP and STATUS stage.
* response transaction:
IN_TOKEN(addr=device, endpoint=0) : host -> device
DATA(the_descriptor) : host <- device (as much bytes as requested)
ACK : host -> device
 
''wValue'' specifies the address to be assigned to the device. The behavior of a device is undefined when ''wValue'' specifies an address greater than 127.
* confirm transaction:
OUT_TOKEN(addr=device, endpoint=0) : host -> device
DATA() : host -> device (empty)
ACK : host <- device
 
The exact behavior of the device after the SET_ADDRESS requests depends on the current state of the device:
The DATA packet in the command transaction is called the "Setup Packet" (according to Beyond Logic), and carries almost all of the 'interesting' stuff:
* When a device is in the default state, a non-zero ''wValue'' causes the device to transition into the address state. When a device is in the default state, a ''wValue'' of zero has no effect.
* When a device is in the address state, a non-zero ''wValue'' keeps a device in the Address state, but the device responds to the newly set address. When a device is in the address state, a ''wValue'' of zero transitions the device into the default state.
* When a device is in the configurd state, device behavior is not defined for the SET_ADDRESS request.
 
This is the only request that is complete after the STATUS stage completes successfully. After the reset/resume recovery interval (10 milliseconds), a device is expected to be able to complete the STATUS stage of this request within 50 milliseconds. After the STATUS stage is complete, the device is allowed a 2 millisecond recovery interval before it must be able to accept farther SETUP packets for additional requests.
* the RequestType of 0x80 (DeviceToHost=0x80| StandardRequest=0| DeviceTargetted=0)
* the Request (command) 0x06 for "GET_DESCRIPTOR"
* the value (encoding unknown atm)
 
==== See AlsoGET_DESCRIPTOR ====
{|border="1" cellpadding="2" style="float:right;clear:right;margin-left:20px;"
|+align="bottom" |'''Standard USB Descriptor Types'''
!Descriptor Type
!Value
|-
|[[#DEVICE|DEVICE]]
|align="center" |1
|-
|[[#CONFIGURATION|CONFIGURATION]]
|align="center" |2
|-
|[[#STRING|STRING]]
|align="center" |3
|-
|[[#INTERFACE|INTERFACE]]
|align="center" |4
|-
|[[#ENDPOINT|ENDPOINT]]
|align="center" |5
|-
|[[#DEVICE_QUALIFIER|DEVICE_QUALIFIER]]
|align="center" |6
|-
|[[#OTHER_SPEED_CONFIGURATION|OTHER_SPEED_CONFIGURATION]]
|align="center" |7
|-
|INTERFACE_POWER
|align="center" |8
|}
The GET_DESCRIPTOR request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''GET_DESCRIPTOR SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!colspan="2" |wValue
!wIndex
!wLength
|- align="center"
|10000000b
|GET_DESCRIPTOR<br />6
|Descriptor Type
|Descriptor Index
|Zero or<br />Language ID
|Descriptor<br />Length
|}
 
The high-order byte of ''wValue'' specifies the descriptor type (see table of usb standard descriptor types, to the right). The low-order byte of ''wValue'' is only used for selecting a specific STRING or CONFIGURATION descriptor, and should be reset to zero otherwise.
=== Links ===
* [http://www.usb.org/home USB.org]
* [http://www.usb.org/developers/docs The USB 2.0 Specification]. Here you can download the official '''Universal Serial Bus Revision 2.0 specification''', which defines the hardware and software. This is by far the best place to start, although not a light reading.
* [http://www.usb.org/developers/hidpage/ information about the HID standard].
* [http://www.kernel.org/ The Linux kernel] (though things tends to be confusing there, and you have to be careful with educating yourself from Linux sources if your project isn't GPL'ed).
* In [http://developer.intel.com/ Intel] chipsets manuals.
* [http://www.beyondlogic.org/usbnutshell/usb1.htm USB in a Nutshell] may also interest you. It looks like a really good tutorial giving all the required knowledge to understand any other USB documentation/source code in a couple of HTML pages ...
 
The ''wIndex'' field is only used for STRING descriptors to specify the desired language and should be reset to zero for other descriptor types.
:''any link to a description of USBstorage, USBprinter, HID, USB vendor list, etc. is of course welcome ;)''
 
Different descriptor types have different lengths which will be discussed soon. If ''wLength'' is less than the size of the descriptor being returned, then the device only returns the first ''wLength'' bytes of the descriptor data. If ''wLength'' is larger than the size of the descriptor being returned, than the full descriptor is returned, followed by a short packet (a packet shorter than the maximum data payload size, including a length of 0 bytes).
=== Forum Topics ===
 
All USB devices must support requests for DEVICE, CONFIGURATION, and STRING descriptors. All high-speed devices must support basic operations at full-speed; such devices also support DEVICE_QUALIFIER and OTHER_SPEED_CONFIGURATION descriptors which return the same data that the device would return for DEVICE and CONFIGURATION descriptor requests, respectively, if the device were operating at the speed at which it is not currently operating.
* [[Topic:9334|USB stick]] - discusses the feasability of booting from an USB memory stick
* [[Topic:8096|USB driver]] - suggests a few startup links about USB
* [[Topic:8692|support USB keyboard]] explained by Schol-R-Lea
* [[Topic:9063|Collecting links about USB]] - PypeClicker and Df's collection of links about USB
 
A request for a CONFIGURATION descriptor also returns all the INTERFACE descriptors for the specified configuration descriptor index (i.e, the low-order byte of ''wValue''), as well as all of the ENDPOINT descriptors associated with all of the returned INTERFACE descriptors, all in a single request.
 
GET_DESCRIPTOR is a valid request for a device in the default, address, or configured state.
 
==== SET_DESCRIPTOR ====
The SET_DESCRIPTOR request is optional; when it is supported, it may be used to update descriptors or add new ones.
 
The SET_DESCRIPTOR request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''SET_DESCRIPTOR SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!colspan="2" |wValue
!wIndex
!wLength
|- align="center"
|00000000b
|SET_DESCRIPTOR<br />7
|Descriptor Type
|Descriptor Index
|Zero or<br />Language ID
|Descriptor<br />Length
|}
 
The high-order byte of ''wValue'' specifies the descriptor type. The low-order byte of ''wValue'' is only used for selecting a specific STRING or CONFIGURATION descriptor, and should be reset to zero otherwise.
 
The ''wIndex'' field is only used for STRING descriptors to specify the desired language and should be reset to zero for other descriptor types.
 
The ''wLength'' field specifies how many bytes will be transfered from the host to the device.
 
This request only supports DEVICE, CONFIGURATIOn, and STRING descriptor types.
 
If this request is not supported, the device responds with a Reuqest Error.
 
If this request is supported, it is only valid when the device is in the address or configured state; the behavior of the device is undefined if this request is made while the device is in the default state.
 
==== GET_CONFIGURATION ====
The GET_CONFIGURATION request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''GET_CONFIGURATION SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!wValue
!wIndex
!wLength
|- align="center"
|10000000b
|GET_CONFIGURATION<br />8
|Zero
|Zero
|One
|}
 
The device sends a one-byte DATA packet during the DATA phase of the control transfer. This byte is the value of the current configuration of the device. A value of zero indicates that the device has not yet been configured (it is in the address state). Behavior of a device is undefined if this request is issued while the device is in the default state.
 
==== SET_CONFIGURATION ====
The SET_CONFIGURATION request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''SET_CONFIGURATION SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!colspan="2" |wValue
!wIndex
!wLength
|- align="center"
|00000000b
|SET_CONFIGURATION<br />9
|''Reserved''
|Configuration Value
|Zero
|Zero
|}
 
The low-order byte of ''wValue'' specifies the desired configuration value. The low-order byte of ''wValue'' must either be zero, or it must match the configuration value field of a configuration descriptor returned by the device. Specifying a configuration value of zero sets the device into the address state.
 
If the device is in the default state, or if the high-order byte of ''wValue'' is not zero, ''wIndex'' is not zero, or ''wLength'' is not zero, then the behavior after issuing this request is undefined.
 
If the specified configuration value is neither zero nor a valid configuration value specified by a configuration descriptor of the device, the device responds with a Request Error.
 
==== GET_INTERFACE ====
The GET_INTERFACE request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''GET_INTERFACE SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!wValue
!wIndex
!wLength
|- align="center"
|10000001b
|GET_INTERFACE<br />10
|Zero
|Interface
|One
|}
 
The host uses this request to determine which alternate setting (as described in [[#Functions.2C_Configurations.2C_Interfaces.2C_and_Endpoints|Functions, Configurations, Interfaces, and Endpoints]]) is used for a particular interface of the current configuration. The device responds with a one-byte long DATA packet during the data phase, the transfered byte being the alternate setting value for the interface specified in this request.
 
If ''wValue'' is not zero, ''wLength'' is not one, ''wIndex'' specifies an invalid interface, or the device is in the address state, then the device responds with a Request Error.
 
The behavior of a device in the default state after receiving this request is undefined.
 
This request is valid for a device in the configured state.
 
==== SET_INTERFACE ====
The SET_INTERFACE request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''SET_INTERFACE SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!wValue
!wIndex
!wLength
|- align="center"
|00000001b
|SET_INTERFACE<br />11
|Alternate Setting
|Interface
|Zero
|}
 
The host uses this request to select an alternate setting (as described in [[#Functions.2C_Configurations.2C_Interfaces.2C_and_Endpoints|Functions, Configurations, Interfaces, and Endpoints]]) to be used for a particular interface of the current configuration. If the interface specified only supports a default setting, then the device may return a STALL handshake during the STATUS stage of the request.
 
If the interface or alternate setting do not exist, or if the device is in the address state, then the device responds with a Request Error. The behavior of the device is undefined if ''wLength'' is not zero, or the device is in the default state.
 
This is a valid request when the device is in the configured state.
 
==== CLEAR_FEATURE ====
{| style="clear:right;float:right;margin-left:20px;" border="1" cellpadding="2"
|+align="bottom" |'''Standard USB Feature Selectors'''
!Feature Selector
!Recipient
!Value
|-
|DEVICE_REMOTE_WAKEUP
|align="center" |Device
|align="center" |1
|-
|ENDPOINT_HALT
|align="center" |Endpoint
|align="center" |0
|-
|TEST_MODE
|align="center" |Device
|align="center" |2
|}
The CLEAR_FEATURE request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''CLEAR_FEATURE SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!wValue
!wIndex
!wLength
|- align="center"
|00000000b<br />00000001b<br />00000010b
|CLEAR_FEATURE<br />1
|Feature Selector
|Zero or<br />Interface or<br />Endpoint
|Zero
|}
 
The host uses this request to clear or disable a specific feature.
 
''wValue'' must contain a feature selector (see table of Standard USB Feature Selectors, to the right) which corresponds with the recipient as specified in the ''bmRequestType'' value.
 
Issuing this request while referencing a feature that cannot be cleared or does not exist, or referencing an interface or endpoint that does not exist will cause the device to respond with a Request Error.
 
If the device is in the default state, or ''wLength'' is non-zero, then the behavior of the device is undefined.
 
This request is valid when the device is in the configured state. When the device is in the address state, this request is only valid when referencing endpoint zero, otherwise the device responds with a Request Error.
 
The TEST_MODE feature cannot be cleared by this request.
 
==== SET_FEATURE ====
{| style="clear:right;float:right;margin-left:20px;" border="1" cellpadding="2"
|+align="bottom" |'''Standard USB Test Selectors'''
!Value
!Description
|-
|align="center" |00h
|''Reserved''
|-
|align="center" |01h
|Test_J
|-
|align="center" |02h
|Test_K
|-
|align="center" |03h
|Test_SE0_NAK
|-
|align="center" |04h
|Test_Packet
|-
|align="center" |05h
|Test_Force_Enable
|-
|align="center" |06h-3Fh
|''Reserved for standard test selectors''
|-
|align="center" |3Fh-BFh
|''Reserved''
|-
|align="center" |C0h-FFh
|''Reserved for vendor-specific test modes''
|}
The SET_FEATURE request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''SET_FEATURE SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!wValue
!colspan="2" |wIndex
!wLength
|- align="center"
|00000000b<br />00000001b<br />00000010b
|SET_FEATURE<br />3
|Feature Selector
|Test selector
|Zero or<br />Interface or<br />Endpoint
|Zero
|}
The host uses this request to set or enable a specific feature.
 
''wValue'' must contain a feature selector which corresponds with the recipient as specified in the ''bmRequestType'' value.
 
When ''wValue'' selects the TEST_MODE feature, ''bmRequestType'' and the low-order byte of ''wIndex'' must both be reset to zero. The high-order byte of ''wIndex'' must be a valid test selector (see table of Standard USB Test Selectors, to the right), or the device respond with Request Error. The device must set its upstream-facing port into test mode no longer than 3milliseconds after completing the STATUS stage of this request. In order to exit test mode, the power to the device must be cycled. A device must support the TEST_MODE feature in the default, address, and configured high-speed device states.
 
If this request references a feature that does not exist or cannot be set, then the devices responds with a STALL handshake during the STATUS stage.
 
If an endpoint or interface is specified that does not exist, or if the device is in the address state and an endpoint other than endpoint zero is specified, the device responds with a Request Error.
 
Besides requests which select the TEST_MODE feature, issuing this request to a device in the default state results in undefined behavior. A non-zero value for ''wLength'' also results in undefined behavior.
 
This request is valid when a device is in the configured state, or when the device is in the address state and only endpoint zero is referenced.
 
==== GET_STATUS ====
The GET_STATUS request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''GET_STATUS SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!wValue
!wIndex
!wLength
|- align="center"
|10000000b<br />10000001b<br />10000010b
|GET_STATUS<br />0
|Zero
|Zero or<br />Interface or<br />Endpoint
|Two
|}
 
The host uses this request to learn the status of the recipient, as specified by the ''bmRequestType'' field and, in the case of an interface or endpoint recipient, the ''wIndex'' field.
 
If ''wValue'' is not zero, ''wLength'' is not two, or ''wIndex'' is non-zero when ''bmRequestType'' specifies a device recipient, or the device is in the default state, then the behavior of the device is undefined.
 
If this request references an endpoint or interface that does not exist (including any endpoint other than endpoint zero when the device is in the address state), then the device responds with a Request Error.
 
In response to this request, the device issues a 2 byte long data transfer during the DATA stage to the host. These two bytes represent the requested status and the meaning depends on the recipient type.
 
===== Device Recipient =====
When the recipient was a device, the two bytes describe the status as follows:
{| align="center" border="1"
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">7</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">6</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">5</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">4</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">3</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">2</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">1</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">0</span>'''
|- align="center"
|colspan="6" |''Reserved (reset to zero)''
|Remote<br />Wakeup
|Self<br />Powered
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">15</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">14</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">13</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">12</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">11</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">10</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">9</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">8</span>'''
|- align="center"
|colspan="8" |''Reserved (reset to zero)''
|}
The ''Self Powered'' field is set to 1 to indicate that the device is currently powered by an external power source, or 0 to indicate that the device is currently running on power supplied by the bus.
 
The ''Remote Wakeup'' field is set to 0 when the device is reset and indicates whether or not the device is currently enabled to perform remote wakeup signaling (see [[#Remote_Wakeup_Capability|Remote Wakeup Capability]]). The host may modify the value of the ''Remote Wakeup'' field by issuing either a CLEAR_FEATURE or SET_FEATURE request using the DEVICE_REMOTE_WAKEUP feature selector.
 
===== Interface Recipient =====
When the recipient was an interface, the two bytes describe the status as follows:
{| align="center" border="1"
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">7</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">6</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">5</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">4</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">3</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">2</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">1</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">0</span>'''
|- align="center"
|colspan="8" |''Reserved (reset to zero)''
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">15</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">14</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">13</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">12</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">11</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">10</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">9</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">8</span>'''
|- align="center"
|colspan="8" |''Reserved (reset to zero)''
|}
 
===== Endpoint Recipient =====
When the recipient was an endpoint, the two bytes describe the status as follows:
{| align="center" border="1"
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">7</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">6</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">5</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">4</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">3</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">2</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">1</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">0</span>'''
|- align="center"
|colspan="7" |''Reserved (reset to zero)''
|Halt
|- align="center"
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">15</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">14</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">13</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">12</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">11</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">10</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">9</span>'''
|style="padding:15px 15px 15px 15px;" |'''D<span style="vertical-align:sub;">8</span>'''
|- align="center"
|colspan="8" |''Reserved (reset to zero)''
|}
 
All interrupt and bulk endpoint types must implement the halt feature, otherwise it is optional. The ''Halt'' field reflects the status of the halt feature of the endpoint. A value of 0 in the ''Halt'' field indicates that the endpoint is not halted, and a value of 1 in the ''Halt'' field indicates that the endpoint is halted.
 
The host may set the halt feature of an endpoint with the SET_FEATURE request using the ENDPOINT_HALT feature selector, or the host may clear the halt feature of an endpoint with the CLEAR_FEATURE request using the ENDPOINT_HALT feature selector. When the CLEAR_FEATURE request is used in this manner, and the endpoint uses a data toggle bit, the data toggle bit is reset to zero.
 
The default control pipe is not required nor recommended to implement the halt feature, but some devices may choose to use the halt feature on the default control pipe to reflect a functional error condition. When the halt feature is set on the default control pipe, the device responds with a STALL handshake during the DATA or STATUS stage of all transfers with the exception of the GET_STATUS, CLEAR_FEATURE, and SET_FEATURE standard requests. Additionally, the device is not required to stall vendor- or class-specific requests when the halt feature is set.
 
==== SYNCH_FRAME ====
The SYNCH_FRAME request has the following SETUP DATA packet format:
{| align="center" border="1" cellpadding="5"
|+align="bottom" |'''SYNCH_FRAME SETUP DATA Packet Format'''
!bmRequestType
!bRequest
!wValue
!wIndex
!wLength
|- align="center"
|10000010b
|SYNCH_FRAME<br />12
|Zero
|Endpoint
|Two
|}
 
This request is only used for isochronous endpoints that use implicit pattern synchronization. That is, some isochronous endpoints require per-frame transfers to vary in size according to a specific pattern (in order to attain an application-specific bit rate, for example). This call causes the device to send the host a 2 byte value that is the number of the frame where the pattern began.
 
High-speed isochronous endpoints that support this request must synchronize to the zeroth microframe, as well as have a time notion of classic frames (1 millisecond as opposed to 125 microsecond intervals).
 
If ''wValue'' is not zero, ''wLength'' is not two, or the device is in the default state, then the behavior of the device is undefined.
 
If the specified endpoint does not support this request, or the device is in the address state, then the device responds with a Request Error.
 
This request is valid when the device is in the configured state.
 
=== Standard USB Descriptors ===
A '''descriptor''' is a data structure with a defined format. All standard descriptors begin with two bytes. The first byte specifies the total length of the descriptor in bytes, including the first two mandatory bytes. The second byte identifies the type of the descriptor.
 
Some descriptors contain fields which specify an index of a STRING descriptor, but it is optional for a device to support STRING descriptors. If a device does not support STRING descriptors, then all fields which reference an index of a STRING descriptor should be reset to zero. Thus, a value of zero in any field that is meant to supply an index of a STRING descriptor indicates that no such STRING descriptor is available.
 
If the second byte of a descriptor identifies that descriptor as one of the standard USB descriptors, but the first byte of that descriptor specifies a length less than the lengths defined in the USB 2.0 specifications (and, transitively, here), then the descriptor should be rejected by the host. If the length field reports that the descriptor is longer than expected, then the extra data should be ignored, but still considered part of the descriptor (this is important when the device is returning multiple descriptors, as is the case when the host requests a CONFIGURATION descriptor).
 
If class- or vendor-specific descriptors use the same format as standard descriptors (i.e, the two mandatory bytes at the beginning of the descriptor), then the class- or vendor-specific descriptors are interleaved within the results when the host requests a CONFIGURATION descriptor. Otherwise, the class- or vendor-specific descriptors are accessed by passing a class- or vendor-specific descriptor type in a GET_DESCRIPTOR request.
 
The remainder of this section serves to catalog the standard USB device descriptors and very closely mirrors section 9.6 of the USB 2.0 specifications. These descriptor definitions supplement the [[#GET_DESCRIPTOR|GET_DESCRIPTOR]] request.
 
==== DEVICE ====
Every USB device has exactly one DEVICE descriptor. This descriptor provides general information about the device, as well as information that applies globally to the device and all of its configurations.
{| align="center" border="1"
!Offset
!Field
!Size
!Type
!Description
|- valign="top"
|align="center" |0
|bLength
|align="center" |1
|align="center" |Number
|Size of this descriptor in bytes
|- valign="top"
|align="center" |1
|bDescriptorType
|align="center" |1
|align="center" |Constant
|DEVICE Descriptor Type
|- valign="top"
|align="center" |2
|bcdUSB
|align="center" |2
|align="center" |BCD
|USB Specification Release Number in Binary-Coded Decimal (i.e, 2.10 is expressed as 210h). Identifies the release of the USB Specification with with the device and its descriptors are compliant.
|- valign="top"
|align="center" |4
|bDeviceClass
|align="center" |1
|align="center" |Class
|Class code (assigned by the USB-IF)
* This field is reset to zero if each interface within a configuration specifies its own class information and the various interfaces operate independently.
* A value of FFh in this field indicates the device class is vendor-specific.
|- valign="top"
|align="center" |5
|bDeviceSubClass
|align="center" |1
|align="center" |SubClass
|Subclass Code (assigned by the USB-IF)
* The subclass code of a device is qualified by the class code of that device.
* If ''bDeviceClass'' is reset to zero, then this field must also be reset to zero.
* When ''bDeviceClass'' is not set to FFh, then all values for this field are reserved for assignment by the USB-IF.
|- valign="top"
|align="center" |6
|bDeviceProtocol
|align="center" |1
|align="center" |Protocol
|Protocol code (assigned by the USB-IF)
* The protocol code of a device is qualified by both the class and subclass codes of that device.
* A value of 00h in this field means that the device may specify class-specific protocols on an interface basis, though this is not a requirement.
* If this field is set to FFh, then the device uses a vendor-specific protocol.
|- valign="top"
|align="center" |7
|bMaxPacketSize0
|align="center" |1
|align="center" |Number
|Maximum packet size for endpoint zero (8, 16, 32, or 64 are the only valid options)
|- valign="top"
|align="center" |8
|idVendor
|align="center" |2
|align="center" |ID
|Vendor ID (assigned by the USB-IF)
|- valign="top"
|align="center" |10
|idProduct
|align="center" |2
|align="center" |ID
|Product ID (assigned by the USB-IF)
|- valign="top"
|align="center" |12
|bcdDevice
|align="center" |2
|align="center" |BCD
|Device release number in binary-coded decimal
|- valign="top"
|align="center" |14
|iManufacturer
|align="center" |1
|align="center" |Index
|Index of STRING descriptor describing manufacturer
|- valign="top"
|align="center" |15
|iProduct
|align="center" |1
|align="center" |Index
|Index of STRING descriptor describing product
|- valign="top"
|align="center" |16
|iSerialNumber
|align="center" |1
|align="center" |Index
|Index of STRING descriptor describing the device's serial number
|- valign="top"
|align="center" |17
|bNumConfigurations
|align="center" |1
|align="center" |Number
|Number of possible configurations
|}
 
==== DEVICE_QUALIFIER ====
A high-speed capable device that has different device information depending on the speed in which the device operating, then that device must also have a DEVICE_QUALIFIER descriptor. This descriptor provides information about the device that would change if the device were operating at the alternate speed (i.e, when the device is operating at high-speed, this descriptor provides the differences if the device were operating a full-speed, and vice versa). This descriptor leaves out fields from the DEVICE descriptor that would not reasonably depend on the speed of the device (e.g, index of the STRING descriptor describing the product).
 
If a full-speed only device with a ''bcdUSB'' field of at least 0200h in its DEVICE descriptor receives a request for a DEVICE_QUALIFIER descriptor, it must respond with a Request Error.
{| align="center" border="1"
!Offset
!Field
!Size
!Type
!Description
|- valign="top"
|align="center" |0
|bLength
|align="center" |1
|align="center" |Number
|Size of this descriptor in bytes
|- valign="top"
|align="center" |1
|bDescriptorType
|align="center" |1
|align="center" |Constant
|DEVICE_QUALIFIER Descriptor Type
|- valign="top"
|align="center" |2
|bcdUSB
|align="center" |2
|align="center" |BCD
|USB Specification Release Number in Binary-Coded Decimal (i.e, 2.00 is expressed as 200h). Identifies the release of the USB Specification with with the device and its descriptors are compliant.<br /><br />
This field must be at least 0200h.
|- valign="top"
|align="center" |4
|bDeviceClass
|align="center" |1
|align="center" |Class
|Class code (assigned by the USB-IF)
|- valign="top"
|align="center" |5
|bDeviceSubClass
|align="center" |1
|align="center" |SubClass
|Subclass Code (assigned by the USB-IF)
|- valign="top"
|align="center" |6
|bDeviceProtocol
|align="center" |1
|align="center" |Protocol
|Protocol code (assigned by the USB-IF)
|- valign="top"
|align="center" |7
|bMaxPacketSize0
|align="center" |1
|align="center" |Number
|Maximum packet size for endpoint zero (8, 16, 32, or 64 are the only valid options)
|- valign="top"
|align="center" |8
|bNumConfigurations
|align="center" |1
|align="center" |Number
|Number of possible configurations
|- valign="top"
|align="center" |9
|bReserved
|align="center" |1
|align="center" | -
|Reserved for future uses, must be zero.
|}
 
==== CONFIGURATION ====
All USB devices have at least one CONFIGURATION descriptor. The host may request a specific CONFIGURATION descriptor by its descriptor indexx, which is zero based and has ''bNumConfigurations'' (as returned in the DEVICE descriptor) used indices. That is, the valid values to be used as a descriptor index when requesting a CONFIGURATION descriptor are any integer in the range of 0 to ''bNumConfigurations''-1, inclusive.
 
Each CONFIGURATION descriptor has at least one INTERFACE descriptor, and each INTERFACE descriptor may have up to 15 ENDPOINT descriptors. When the host requests a certain CONFIGURATION descriptor, the device returns the CONFIGURATION descriptor followed immediately by the first INTERFACE descriptor, followed immediately by all of the ENDPOINT descriptors for endpoints that the interface defines (which may be none). This is followed immediately by the next INTERFACE descriptor if one exists, and then by its ENDPOINT descriptors if applicable. This pattern continues until all the information within the scope of the specific configuration is transfered.
 
When a device has vendor- or class-specific descriptors that conform to the standard USB descriptor format (that is, the first byte of the descriptor determines the length of the descriptor, and the second byte identifies the type of descriptor), those descriptors are also returned interleaved among the CONFIGURATION, INTERFACE, and ENDPOINT descriptors when the host requests a specific CONFIGURATION descriptor. Therefore, the system software cannot assume continuous standard descriptors as implied by the previous paragraph; instead, the system software should check the descriptor type and skip that descriptor if it is not a standard descriptor. The software should also check that standard descriptors report at least the expected length.
 
Note that the CONFIGURATION descriptor index is not the same as the value ''bConfigurationValue'' in the CONFIGURATION descriptor. ''bConfigurationValue'' is the value that the host passes as a parameter with the SET_CONFIGURATION request in order to select a particular configuration, whereas this cannot be done using the CONFIGURATION descriptor index.
{| align="center" border="1"
!Offset
!Field
!Size
!Type
!Description
|- valign="top"
|align="center" |0
|bLength
|align="center" |1
|align="center" |Number
|Size of this descriptor in bytes
|- valign="top"
|align="center" |1
|bDescriptorType
|align="center" |1
|align="center" |Constant
|CONFIGURATION Descriptor Type
|- valign="top"
|align="center" |2
|wTotalLength
|align="center" |2
|align="center" |Number
|The total combined length in bytes of all the descriptors returned with the request for this CONFIGURATION descriptor (including CONFIGURATION, INTERFACE, ENDPOINT, class- and vendor-specific descriptors).
|- valign="top"
|align="center" |4
|bNumInterfaces
|align="center" |1
|align="center" |Number
|Number of interfaces supported by this configuration
|- valign="top"
|align="center" |5
|bConfigurationValue
|align="center" |1
|align="center" |Number
|Value which when used as an argument in the SET_CONFIGURATION request, causes the device to assume the configuration described by this descriptor.
|- valign="top"
|align="center" |6
|iConfiguration
|align="center" |1
|align="center" |Index
|Index of STRING descriptor describing this configuration.
|- valign="top"
|align="center" |7
|bmAttributes
|align="center" |1
|align="center" |Bitmap
|Configuration Characteristics
{| border="1" cellpadding="15" align="center"
|D<span style="vertical-align:sub;">7</span>
|D<span style="vertical-align:sub;">6</span>
|D<span style="vertical-align:sub;">5</span>
|D<span style="vertical-align:sub;">4</span>
|D<span style="vertical-align:sub;">3</span>
|D<span style="vertical-align:sub;">2</span>
|D<span style="vertical-align:sub;">1</span>
|D<span style="vertical-align:sub;">0</span>
|}
{| border="0" cellpadding="0" align="center" style="max-width:500px;"
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">7</span>'''
|''Reserved, must be set to one for historical reasons''
|-
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">6</span>'''
|'''Self-Powered'''
* 0 = Device runs on power supplied by the bus
* 1 = Device provides a local power source, if ''bMaxPower'' is non-zero, the device also may use bus power.
|-
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">5</span>'''
|'''Remote Wakeup'''
* 0 = Remote Wakeup not supported
* 1 = Remote Wakeup supported
|-
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">4...0</span>'''
|''Reserved, reset to zero''
|}
|- valign="top"
|align="center" |8
|bMaxPower
|align="center" |1
|align="center" |mA
|Maximum power consumption of this device from the bus when fully operational and using this configuration.
* Expressed in units of 2mA (i.e., a value of 50 in this field indicates 100mA).
* A device reports with the ''bmAttributes'' field whether the configuration is bus- or self-powered, but the device status (retrieved with a GET_STATUS request) reports whether the device is currently self-powered.
* If a device is disconnected from an external power source, it may not draw more power from the bus than specified in this field.
* Some devices may be able to operate solely on bus power. A device that cannot and has lost its external power source will fail the operations it can no longer support. It is up to the software on the host to determine when this is the case, which may be accomplished with a GET_STATUS request.
|}
 
 
==== OTHER_SPEED_CONFIGURATION ====
This descriptor describes the configuration of a high-speed device if it were operating at it's alternative speed. The host should not request this descriptor unless it already successfully received a DEVICE_QUALIFIER descriptor from the device. The structure of the OTHER_SPEED_CONFIGURATION is identical to that of the CONFIGURATION descriptor shown above. The only difference is that the ''bDescriptorType'' field reflects that the descriptor is an OTHER_SPEED_CONFIGURATION descriptor rather than a CONFIGURATION descriptor.
 
==== INTERFACE ====
INTERFACE descriptors are only returned following a CONFIGURATION descriptor when the host requests a specific CONFIGURATION descriptor; it is not possible to directly request a specific INTERFACE descriptor. An interface may provide alternate settings within a configuration that allow the endpoints and/or their characteristics to be varied. A default interface has the ''bAlternateSetting'' field in its INTERFACE descriptor reset to zero.
{| align="center" border="1"
!Offset
!Field
!Size
!Type
!Description
|- valign="top"
|align="center" |0
|bLength
|align="center" |1
|align="center" |Number
|Size of this descriptor in bytes
|- valign="top"
|align="center" |1
|bDescriptorType
|align="center" |1
|align="center" |Constant
|INTERFACE Descriptor Type
|- valign="top"
|align="center" |2
|bInterfaceNumber
|align="center" |1
|align="center" |Number
|Number of this interface. Zero-based value which identifies the index of this interface in the array of interfaces supported within a configuration.
|- valign="top"
|align="center" |3
|bAlternateSetting
|align="center" |1
|align="center" |Number
|Value used to select the alternate settings described by this INTERFACE descriptor for the interface with the ''bInterfaceNumber'' in the previous field. This value is zero if this descriptor describes the default settings for a particular interface.
|- valign="top"
|align="center" |4
|bNumEndpoints
|align="center" |1
|align="center" |Number
|Number of endpoints used by this interface, not including endpoint zero.
|- valign="top"
|align="center" |5
|bInterfaceClass
|align="center" |1
|align="center" |Class
|Class code (assigned by the USB-IF)
* A value of zero here is reserved for future standardization.
* If this value is FFh, the interface class is vendor-specific.
* All other values are reserved for assignment by the USB-IF.
|- valign="top"
|align="center" |6
|bInterfaceSubClass
|align="center" |1
|align="center" |SubClass
|Subclass code (assigned by the USB-IF)
* The subclass code in this field is qualified by the value of the ''bInterfaceClass'' field.
* If ''bInterfaceClass'' is reset to zero, then this field must also be reset to zero.
* If ''bInterfaceClass'' is not set to the value of FFh, then all values of this field are reserved for assignment by the USB-IF.
|- valign="top"
|align="center" |7
|bInterfaceProtocol
|align="center" |1
|align="center" |Protocol
|Protocol code (assigned by the USB-IF)
* The protocol code in this field is qualified by the values of the ''bInterfaceClass'' and ''bInterfaceSubClass'' fields.
* If an interface supports class-specific requests, then this field identifies the protocols that the device uses as defined by the specifications of the device class.
* If this field is reset to zero, then the device does not use a class-specific protocol on this interface.
* If this field is set to FFh, then the devices uses a vendor-specific protocol on this interface.
|- valign="top"
|align="center" |8
|iInterface
|align="center" |1
|align="center" |Index
|Index of STRING descriptor describing this interface
|}
 
 
 
==== ENDPOINT ====
Each endpoint used for a particular interface has a descriptor which follows after that particular interface's descriptor when the host requests a specific CONFIGURATION descriptor; the host cannot request a specific ENDPOINT descriptor explicitly. And ENDPOINT descriptor never describes endpoint zero.
{| align="center" border="1"
!Offset
!Field
!Size
!Type
!Description
|- valign="top"
|align="center" |0
|bLength
|align="center" |1
|align="center" |Number
|Size of this descriptor in bytes
|- valign="top"
|align="center" |1
|bDescriptorType
|align="center" |1
|align="center" |Constant
|ENDPOINT Descriptor Type
|- valign="top"
|align="center" |2
|bEndpointAddress
|align="center" |1
|align="center" |Endpoint
|The address of the endpoint on the USB device described by this descriptor. This field has the following format:
{| border="1" cellpadding="15" align="center"
|D<span style="vertical-align:sub;">7</span>
|D<span style="vertical-align:sub;">6</span>
|D<span style="vertical-align:sub;">5</span>
|D<span style="vertical-align:sub;">4</span>
|D<span style="vertical-align:sub;">3</span>
|D<span style="vertical-align:sub;">2</span>
|D<span style="vertical-align:sub;">1</span>
|D<span style="vertical-align:sub;">0</span>
|}
{| border="0" cellpadding="0" align="center" style="max-width:500px;"
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">7</span>'''
|'''Direction''' (ignored for control endpoints)
* 0 = OUT endpoint
* 1 = IN endpoint
|-
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">6...4</span>'''
|''Reserved, reset to zero''
|-
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">3...0</span>'''
|'''Endpoint Number'''
|}
|- valign="top"
|align="center" |3
|bmAttributes
|align="center" |1
|align="center" |Bitmap
|This field describes the endpoint's attributes as follows:
{| border="1" cellpadding="15" align="center"
|D<span style="vertical-align:sub;">7</span>
|D<span style="vertical-align:sub;">6</span>
|D<span style="vertical-align:sub;">5</span>
|D<span style="vertical-align:sub;">4</span>
|D<span style="vertical-align:sub;">3</span>
|D<span style="vertical-align:sub;">2</span>
|D<span style="vertical-align:sub;">1</span>
|D<span style="vertical-align:sub;">0</span>
|}
{| border="0" cellpadding="0" align="center" style="max-width:500px;"
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">7...6</span>'''
|''Reserved, reset to zero''
|-
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">5...4</span>'''
|'''Usage Type''' (Isochronous endpoints only; reserved and reset to zero for other endpoints)
* 00 = Data endpoint
* 01 = Feedback endpoint
* 10 = Implicit feedback data endpoint
* 11 = Reserved
|-
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">3...2</span>'''
|'''Synchronization Type''' (Isochronous endpoints only; reserved and reset to zero for other endpoint types)
* 00 = No synchronization
* 01 = Asynchronous
* 10 = Adaptive
* 11 = Synchronous
|-
|valign="top" style="min-width:80px;" |'''D<span style="vertical-align:sub;">1...0</span>'''
|'''Transfer Type'''
* 00 = Control
* 01 = Isochronous
* 10 = Bulk
* 11 = Interrupt
|}
|- valign="top"
|align="center" |4
|wMaxPacketSize
|align="center" |2
|align="center" |Number
|Maximum packet size that this endpoint is capable of sending or receiving.
* For isochronous endpoints, this value is used to reserve bus time; the pipe, however, may not always use all of the reserved bus time.
* Bits 10...0 specify the maximum packet size in bytes.
* For high-speed isochronous and interrupt endpoints, bits 12...11 specify the number of additional transaction opportunities per microframe (see [[#High-Speed.2C_High-Bandwidth_Endpoints|High-Speed, High-Bandwidth Endpoints]]). The format is as follows:
** 00 = None (1 transaction per microframe)
** 01 = 1 additional (2 transactions per microframe)
** 10 = 2 additional (3 transactions per microframe)
** 11 = Reserved
* Bits 15...13 are reserved and must be reset to zero.
|- valign="top"
|align="center" |6
|bInterval
|align="center" |1
|align="center" |Number
|Interval for polling a device during a data transfer, expressed in units of microframes for high-speed devices, and frames for low- and full-speed devices. The exact meaning of the value in this field depends on the endpoint type and the operating speed of the device:
* Full- and High-speed isochronous endpoints, and high-speed interrupt endpoints:
** This field must be in the range from 1 to 16.
** This field is used to calculate the period as 2<span style="vertical-align:super;">''bInterval'' - 1</span>. That is, a value of 4 calculates to 2<span style="vertical-align:super;">4 - 1</span> = 2<span style="vertical-align:super;">3</span> = 8.
* Full- and Low-speed interrupt endpoints:
** This field must be in the range from 1 to 255.
* High-speed bulk and control OUT endpoints:
** This field must be in the range from 0 to 255.
** This field specifies the maximum NAK rate of the endpoint.
** A value of zero indicates that the endpoint never NAKs
** Other values indicate at most 1 NAK each ''bInterval'' number of microframes.
** See [[#PING_Transaction_Protocol|PING Transaction Protocol]]
|}
 
==== STRING ====
Devices may optionally support STRING descriptors. If a device does not support STRING descriptors, any field which references the index of a STRING descriptor must be reset to zero. STRING descriptors use unicode encodings and may support multiple languages. The host requests a STRING descriptor with the [[#GET_DESCRIPTOR|GET_DECRIPTOR]] request and must pass the 16-bit LANGID (as defined by the USB-IF) of the desired language in the ''wIndex'' field. The list of currently accepted LANGIDs is located [http://www.usb.org/developers/docs/USB_LANGIDs.pdf here].
 
String index 0 for all languages returns a STRING descriptor that contains an array of all the two-byte LANGID codes that the device supports.
 
Whether requesting a string or an array of LANGIDs, the data is not NULL-terminated. Instead, the host determines the length of the data by subtracting 2 from the ''bLength'' field of the descriptor.
 
When the host requests string index 0, the following descriptor is returned:
{| align="center" border="1"
!Offset
!Field
!Size
!Type
!Description
|- valign="top"
|align="center" |0
|bLength
|align="center" |1
|align="center" |Number
|Size of this descriptor in bytes
|- valign="top"
|align="center" |1
|bDescriptorType
|align="center" |1
|align="center" |Constant
|STRING Descriptor Type
|- valign="top"
|align="center" |2
|wLangID[0]
|align="center" |2
|align="center" |Number
|LANGID code zero
|- valign="top"
|align="center" |...
|align="center" |...
|align="center" |...
|align="center" |...
|align="center" |...
|- valign="top"
|align="center" |N
|wLangID[x]
|align="center" |2
|align="center" |Number
|LANGID code x
|}
 
When the host requests a valid string index other than string index 0 for a supported LANGID, the following descriptor is returned:
{| align="center" border="1"
!Offset
!Field
!Size
!Type
!Description
|- valign="top"
|align="center" |0
|bLength
|align="center" |1
|align="center" |Number
|Size of this descriptor in bytes
|- valign="top"
|align="center" |1
|bDescriptorType
|align="center" |1
|align="center" |Constant
|STRING Descriptor Type
|- valign="top"
|align="center" |2
|bString
|align="center" |N
|align="center" |Number
|Unicode string
|}
 
== Typical organization of system software ==
This section discusses how system software is typically, reasonably organized. This section also serves as an index to the wiki entries which provide, or will provide, farther information and perhaps programming examples.
 
=== USB Device Drivers ===
As with any device driver, a USB device driver abstracts away from the low-level details on just how a specific device is being accessed, and provides the rest of the system and applications with a common interface (e.g, a file manager shouldn't have to know whether it is dealing with an external versus internal hard drive).
 
USB device drivers typically implement a certain class of device as per the appropriate specifications. Such classes of USB devices include, but are not limited to:
* [[USB Mass Storage Class Devices]]
* [[USB Human Input Devices]]
 
=== USB Driver ===
Even a USB device driver need not be concerned with some of the lower-level details. For instance, it shouldn't matter to the device driver if a device is connected directly to the root hub, or if it lies behind 3 hubs. The device driver shouldn't worry about how much power the device needs from the bus. This is where the USB driver comes in.
 
The USB driver essentially provides the USB framework interface to device drivers. The USB driver also handles connect and disconnect events on the USB, as well as determining which device driver is needed (according to the Class, Subclass, and Protocol codes), and if that device driver even exists.
 
=== USB Hub Driver ===
Although the USB Driver knows some details about the USB topography, the responsibility of hub-specific communication (including split-transactions) is often separated from the USB Driver into another module called the USB Hub Driver.
 
Depending on the design of the system, the USB Driver might bypass the USB Hub Driver when communicating with devices on the root hub, or the system may use the reserved address of 0 to indicate the root hub to the USB Hub Driver (it appears that Linux does this).
 
Details on USB Hubs will eventually be discussed in the [[USB Hubs]] wiki entry.
 
=== Host Controller Driver ===
As a request for a data transfer moves from the device driver, through the USB Driver, and through the USB Hub Driver, the request gains all the information needed for the host controller to generate the appropriate transactions on the bus. However, depending on the host controller, this information needs to be formatted in a certain way and added for scheduling by the host controller.
 
This task if given to the host controller driver. Requests reach the host controller driver in a system-defined format, often called a USB Request Block (URB), or an I/O Request Packet (IRP).
 
Additionally, host controller drivers are loaded by the PCI subsystem when a corresponding host controller is discovered during PCI enumeration. The host controller driver is thus also responsible for initializing the host controller and perhaps loading the USB Hub Driver and the USB driver. Combined, the USB driver, USB hub driver, and the host controller driver make up a USB subsystem.
 
== See Also ==
=== External Links ===
* [http://www.usb.org/home USB.org]
* [https://usb.org/document-library/usb-20-specification USB Universal Serial Bus Revision 2.0 Specification]
* [https://usb.org/document-library/usb-32-specification-released-september-22-2017-and-ecns Universal Serial Bus Revision 3.2 Specification]
* [http://www.usb.org/developers/wusb/wusb1_1_20100910.zip Wireless USB Specification Revision 1.1]
* [http://www.kernel.org/ The Linux kernel] (things tend to be confusing there, plus you have to be careful with educating yourself from Linux sources if your project isn't GPL'ed).
* [http://www.beyondlogic.org/usbnutshell/usb1.shtml USB in a NutShell] may also interest you. It looks like a really good tutorial giving all the required knowledge to understand any other USB documentation/source code in a couple of HTML pages
* [http://www.usb.org/developers/docs/USB_LANGIDs.pdf Currently accepted LANGIDs]
* [http://www.usbmadesimple.co.uk/index.html USB Made Simple]
* [https://www.fysnet.net/the_universal_serial_bus.htm USB: The Universal Serial Bus] is a book on writing device/system drivers for UHCI, OHCI, EHCI, and xHCI with various example devices and available source code.
 
[[Category:USB]]
[[Category:Buses]]
 
[[de:Universal_Serial_Bus]]
9

edits