Home > USB Complete > From Chapter 4
USB Complete Fifth Edition
From Chapter 4
Enumeration: How the Host Learns about Devices
One of a hub’s duties is to detect attachment and removal of devices on its downstream-facing ports. Each hub has an interrupt IN endpoint for reporting these events to the host. On system boot-up, hubs inform the host if any devices are attached including additional downstream hubs and any devices attached to those hubs. After boot-up, a host continues to poll periodically (USB 2.0) or receives ERDY TPs (Enhanced SuperSpeed) that request communications to learn of any newly attached or removed devices.
On learning of a new device, the host sends requests to the device’s hub to cause the hub to establish a communications path between the host and device. The host then attempts to enumerate the device by issuing control transfers containing standard USB requests to the device. All USB devices must support control transfers, standard requests, and endpoint zero. For a successful enumeration, the device must respond to requests by returning requested information and taking other requested actions.
From the user’s perspective, enumeration is invisible and automatic but may display a message that announces the new device and whether the attempt to configure it succeeded. Sometimes on first use, the user needs to assist in selecting a driver or telling the host where to look for driver files. Under Windows, when enumeration is complete, the new device appears in the Device Manager. (Right-click Computer, click Manage, and in the Computer Management pane, select Device Manager.) On detaching, the device disappears from Device Manager. In a typical device, firmware decodes and responds to received requests for information. Some controllers can manage enumeration entirely in hardware except possibly for vendor-provided values in EEPROM or other memory. On the host side, the operating system handles enumeration.
Getting to the Configured state
The USB 2.0 specification defines six device states. During enumeration, a device moves through the Powered, Default, Address, and Configured states. (The other defined states are Attached and Suspend.) In each state, the device has defined capabilities and behavior.
Typical USB 2.0 sequence
The steps below are a typical sequence of events that occurs during enumeration of a USB 2.0 device under Windows. Device firmware shouldn’t assume that enumeration requests and events will occur in a particular order. Different OSes and different OS editions might use a different sequence. To function successfully, a device must detect and respond to any control request or other bus event at any time as required by the USB specifications. Figure 4-1 shows received requests and other events during a device enumeration.
1. The system has a new device. A user attaches a device to a USB port, or the system powers up with a device attached. The port may be on the root hub at the host or on a hub that connects downstream from the host. The hub provides power to the port, and the device is in the Powered state. The device is in the Attached state and can draw up to 100 mA from the bus.
2. The hub detects the device. The hub monitors the voltages on the signal lines (D+ and D-) at each of its ports. The hub has a pull-down resistor of 14.25k–24.8kW on each line. A device has a pull-up resistor of 900–1575W on D+ for a full-speed device or on D- for a low-speed device. High-speed-capable devices attach at full speed. On attaching to a port, the device connects to the bus by bringing the appropriate pull-up line high so the hub can detect that a device is attached. Except for some devices with weak or dead batteries, the device must connect within 1 s after detecting that VBUS is at least 0.8 V. A device can continue to draw 100 mA of bus current for 1 s after connecting regardless of whether the upstream bus segment is suspended. On detecting a device, the hub continues to provide power but doesn’t yet transmit USB traffic to the device. Chapter 16 has more on how hubs detect devices.
3. The host learns of the new device. Each hub uses its interrupt endpoint to report events at the hub. The report indicates only whether the hub or a port (and if so, which port) has experienced an event. On learning of an event, the host sends the hub a Get Port Status request to find out more. Get Port Status and the other hub-class requests used during enumeration are standard requests that all hubs support. The information returned tells the host when a device is newly attached.
4. The hub detects whether a device is low or full speed. Just before resetting the device, the hub determines whether the device is low or full speed by detecting which signal line has a higher voltage when idle. The hub sends the information to the host in response to the next Get Port Status request. A USB 1.1 hub may instead detect the device’s speed just after a bus reset. USB 2.0 requires speed detection before the reset so the hub knows whether to check for a high-speed-capable device during reset as described below.
5. The hub resets the device. When a host learns of a new device, the host sends the hub a Set Port Feature request that asks the hub to reset the port. The hub places the device’s USB data lines in the Reset condition for at least 10 ms. Reset is a special condition where both D+ and D- are logic low. (Normally, the lines have opposite logic states.) The hub sends the reset only to the new device. Other hubs and devices on the bus don’t see the reset.
6. The host learns if a full-speed device supports high speed. Detecting whether a device supports high speed uses two special signal states. In the Chirp J state, only the D+ line is driven, and in the Chirp K state, only the D- line is driven.
During the reset, a device that supports high speed sends a Chirp K. A high-speed-capable hub detects the Chirp K and responds with a series of alternating Chirp K and Chirp J. On detecting the pattern KJKJKJ, the device removes its full-speed pull-up and performs all further communications at high speed. If the hub doesn’t respond to the device’s Chirp K, the device knows it must continue to communicate at full speed. All high-speed devices must be capable of responding to control-transfer requests at full speed.
7. The hub establishes a signal path between the device and the bus. The host verifies that the device has exited the reset state by sending a Get Port Status request. A bit in the returned data indicates whether the device is still in the reset state. If necessary, the host repeats the request until the device has exited the reset state.
When the hub removes the reset, the device is in the Default state. The device’s USB registers are in their reset states, and the device is ready to respond to control transfers at endpoint zero. The device communicates with the host using the default address of 0x00.
8. The host sends a Get Descriptor request to learn the maximum packet size of the default pipe. The host sends the request to device address 0x00, endpoint zero. Because the host enumerates only one device at a time, only one device will respond to communications addressed to device address 0x00 even if several devices attach at once.
The eighth byte of the device descriptor contains the maximum packet size supported by endpoint zero. The host may request 64 bytes but after receiving just one packet (whether or not it has 64 bytes), may begin the Status stage of the transfer.
On completing the Status stage, Windows may request the hub to reset the device as in step 5 above. The USB 2.0 specification doesn’t require a reset here. The reset is a precaution that ensures that the device will be in a known state when the reset ends. Windows 8 and later skip the second reset for high-speed devices because these devices typically don’t require a second reset. If enumeration fails without the second reset, Windows includes the reset on the next enumeration attempt.
9. The host assigns an address. When the reset is complete, the host controller assigns a unique address to the device by sending a Set Address request. The device completes the Status stage of the request using the default address and then implements the new address. The device is now in the Address state. All communications from this point on use the new address. The address is valid until the device is detached, a hub resets the port, or the system reboots. On the next enumeration, the host may assign a different address to the device.
10. The host learns about the device’s abilities. The host sends a Get Descriptor request to the new address to read the device descriptor. This time the host retrieves the entire descriptor. The descriptor contains the maximum packet size for endpoint zero, the number of configurations the device supports, and other information about the device.
The host continues to learn about the device by requesting the configuration descriptor(s) specified in the device descriptor. A request for a configuration descriptor is actually a request for the configuration descriptor followed by all of its subordinate descriptors up to the number of bytes requested.
If the host requests 255 bytes, the device responds by sending the configuration descriptor followed by all of the configuration’s subordinate descriptors, including interface descriptor(s), with each interface descriptor followed by any endpoint descriptors for the interface. Some configurations also have class- or vendor-specific descriptors.
One of the configuration descriptor’s fields is the total length of the configuration descriptor and its subordinate descriptors. If the value is greater than 255, the device returns 255 bytes. Windows then requests the configuration descriptor again, this time requesting the number of bytes in the total length specified in the configuration descriptor.
Earlier Windows editions began by requesting just the configuration descriptor’s nine bytes to retrieve the total length value, then requesting the complete descriptor set.
11. The host requests additional information from the device. The host then may request additional descriptors from the device. In every case, a device that doesn’t support a requested descriptor should return STALL.
When the device descriptor reports that the device is USB 2.1 or higher, the host requests a BOS descriptor. If the device returns the BOS descriptor, the host uses the descriptor’s total length value to request the BOS descriptor followed by its subordinate descriptor(s).
The host requests string descriptor zero, which contains one or more codes indicating what languages additional strings use.
If the device descriptor reports that the device contains a serial number string descriptor, the host requests that descriptor.
If the device descriptor indicates that the device contains a Product string descriptor, the host requests that descriptor.
For USB 2.0 and higher devices, if Windows doesn’t have a record of previously retrieving a Microsoft-specific MS OS string descriptor, the OS may request that descriptor.
If a BOS descriptor or a Microsoft OS string descriptor indicates support for additional Microsoft-defined descriptors, the host may request these descriptors.
For USB 2.0 or higher devices operating at full speed with an upstream USB 1.1 hub, the host requests a device qualifier descriptor. A device that returns this descriptor is capable of operating at high speed if all upstream ports are USB 2.0 or higher.
12. The host assigns and loads a device driver (except for composite devices). After learning about a device from its descriptors, the host looks for the best match in a driver to manage communications with the device. Windows hosts use INF files to identify the best match. The INF file may be a system file for a USB class or a vendor-provided file that contains the device’s Vendor ID and Product ID. Chapter 9 has more about INF files and selecting a driver.
For devices that have been enumerated previously, Windows may use stored information instead of searching the INF files. After the operating system assigns and loads a driver, the driver may request the device to resend descriptors or send other class-specific descriptors.
An exception to this sequence is composite devices, which can have different drivers assigned to multiple interfaces in a configuration. The host can assign these drivers only after enabling the interfaces, so the host must first configure the device as described below.
13. The host’s device driver selects a configuration. After learning about a device from the descriptors, the device driver requests a configuration by sending a Set Configuration request with the desired configuration number. Many devices support only one configuration. When a device supports multiple configurations, many drivers just select the first configuration, but a driver can decide based on information the driver has about how the device will be used, or the driver can ask the user what to do. On receiving the request, the device implements the requested configuration. The device is now in the Configured state and the device’s interface(s) are enabled.
For composite devices, the host can now assign drivers. As with other devices, the host uses the information retrieved from the device to find a driver for each active interface in the configuration. The device is then ready for use.
Hubs are also USB devices, and the host enumerates a newly attached hub in the same way as other devices. If the hub has devices attached, the host enumerates these after the hub informs the host of their presence.
Attached state. If the hub isn’t providing power to a device’s VBUS line, the device is in the Attached state. The absence of power may occur if the hub has detected an over-current condition or if the host requests the hub to remove power from the port. With no power on VBUS, the host and device can’t communicate, so from their perspective, the situation is the same as when the device isn’t attached.
Suspend State. A device enters the Suspend state after detecting no bus activity, including SOF markers, for at least 3 ms. In the Suspend state, the device should limit its use of bus power. Both configured and unconfigured devices must support this state. Chapter 17 has more about the Suspend state.
Enhanced SuperSpeed differences
[Note: Enhanced SuperSpeed is the USB 3.1 spec's term for SuperSpeed and SuperSpeedPlus.]
Enumerating Enhanced SuperSpeed devices has some differences compared to USB 2.0:
On detecting a downstream Enhanced SuperSpeed termination at a port, a hub initializes and trains the port’s link. Enumeration then proceeds at SuperSpeed or SuperSpeedPlus with no need for further speed detecting.
The host isn’t required to reset the port after learning of a new device.
The bus-current limits are 150 mA before configuration and 900 mA after configuration.
The host sends a Set Isochronous Delay request to inform the device of the bus delay for isochronous packets.
The host sends a Set SEL request to inform the device of the system exit latency (the amount of time required to transition out of a low-power state).
Protocols for entering and exiting the Suspend state differ.
For hubs, the host sends a Set Hub Depth request to set the hub-depth value.
Device removal
When a user removes a device from the bus, the hub disables the device’s port. The host knows that the removal occurred after the hub notifies the host that an event has occurred, and the host sends a Get Port Status request to learn what the event was. The device disappears from Device Manager and the device’s address becomes available to another newly attached device.
Tips for successful enumeration
Without successful enumeration, the device and host can’t perform other communications. Most chip companies provide example enumeration code that can serve as a model even if your application doesn’t exactly match the example application. If your controller interfaces to an external CPU, you may have to adapt code written for another chip.
In general, a device should assume nothing about what requests or events the host will initiate and should concentrate on responding to requests and events as they occur. The following tips can help avoid problems.
Don’t assume requests or events will occur in a specific order. Some requests, such as Set Configuration, require the device to be in the Address or Configured state so the request is valid only after the device has accepted a Set Address request. But the host has some flexibility in what requests to issue and in what order during enumeration. A host might also reset or suspend the bus at any time, and a device that has been connected for at least 1 s must detect the event and respond appropriately.
Be ready to abandon a control transfer or end it early. On receiving a new Setup packet, a device must abandon any transfer in progress and begin the new one. On receiving an OUT token packet (USB 2.0) or STATUS TP (Enhanced SuperSpeed), the device must assume that the host is beginning the Status stage of the transfer even if the device hasn’t sent all of the requested data in the Data stage.
Don’t attempt to send more data than the host requests. In the Data stage of a control read transfer, a device should send no more than the amount of data the host has requested. If the host requests nine bytes, the device should send no more than nine bytes.
Send a zero-length data packet when required. In some cases, the device returns less than the requested amount of data, and the amount of data is an exact multiple of the endpoint’s maximum packet size. On receiving a request for more data, the device should indicate that it has no more data by returning a ZLP (USB 2.0) or a zero-length Data Payload (Enhanced SuperSpeed).
Stall unsupported requests. A device shouldn’t assume it knows every request the host might send. The device should return STALL in response to any request the device doesn’t support.
Don’t set the address too soon. In a Set Address request, the device should set its new address only after the Status stage of the request is complete.
Be ready to enter the Suspend state. A host can suspend the bus when the device is in any powered state. Except within 1 s after the device connects, the device must reduce its use of bus power when the bus is in the Suspend state.
Test under different host-controller types. Devices should be able operate with any host controller that complies with the specifications. For example, some full-speed host controllers schedule multiple stages of a control transfer in a single frame, while others don’t. Devices should be able to handle either way.