Protocols

USB enumeration

By CourseTron Team ·  7 min read ·  Updated Oct 2026 💬 𝕏 in f
Table of Contents
    ? Print / Save as PDF

    In short: USB enumeration is the handshake that runs the moment a device is plugged in — the host detects the device from a pull-up resistor, resets it, reads its descriptors over the default endpoint at address 0, assigns a unique bus address, then selects a configuration so the right class driver can bind and the device becomes usable.

    Plug a flash drive into a laptop and within roughly 100 milliseconds the operating system knows exactly what it is, which driver to load, and how much current it may draw. That choreography is enumeration, and understanding it is a staple of embedded and SoC-verification interviews because it sits exactly where hardware signalling, protocol state machines, and driver software meet.

    What triggers enumeration: the physical detection

    USB is a host-centric, polled bus. Devices never speak unless spoken to. Detection is purely electrical: a full-speed device ties a 1.5 kΩ pull-up resistor from D+ to 3.3 V (a low-speed device pulls up D- instead). The downstream port on the host or hub holds both lines low through 15 kΩ pull-downs. When the device is attached, the pull-up wins and the host sees one data line rise — that edge is the "connect" event.

    Speed is signalled before a single bit is exchanged: which data line floats high (D+ = full/high-speed, D- = low-speed) tells the host the device's base speed. High-speed (480 Mbps) devices start as full-speed, then negotiate up with the chirp-J/chirp-K handshake during reset.

    The host then drives an SE0 reset (both lines low) for at least 10 ms. Reset forces the device into a known state: it responds only to address 0 and has only endpoint 0 (the bidirectional control endpoint) active.

    The six phases on plug-in

    USB enumeration: attach to driver bound1 Attachpull-up seen2 ResetSE0 ≥10 ms3 Get Desc.addr 0, 8 B4 Set Address1–1275 Read treeall descriptors6 Set Configdriver bindsDevice answers at address 0 until step 4Configured: endpoints active, class driver boundCourseTron · coursetron.com
    The enumeration state flow from attach to a configured, driver-bound device.
    1. Attach & detect — pull-up resistor raises a data line; host notes the connect and base speed.
    2. Reset — host drives SE0; high-speed chirp handshake happens here.
    3. First Get_Descriptor(Device) — host reads the first 8 bytes at address 0 to learn bMaxPacketSize0 for endpoint 0.
    4. Set_Address — host issues a SET_ADDRESS request assigning a value 1–127; the device switches to it after the status stage.
    5. Read full descriptor tree — device, configuration, interface, endpoint and string descriptors.
    6. Set_Configuration — host selects a configuration; non-zero endpoints activate and the matching class driver binds.

    Control transfers carry every request

    All of enumeration rides on control transfers over endpoint 0. Each standard request is an 8-byte Setup packet with fields bmRequestType, bRequest, wValue, wIndex, wLength. For example, GET_DESCRIPTOR for the device descriptor is bRequest=0x06, wValue=0x0100 (descriptor type 1, index 0). A control transfer has a Setup stage, an optional Data stage, and a Status stage — and the host must honour the device's bMaxPacketSize0 (8, 16, 32, or 64 bytes) when splitting the data stage, which is precisely why the host reads those first 8 bytes before anything else.

    The 8-byte Setup packet (GET_DESCRIPTOR, device)byte 0bmRequestType1 B0x80byte 1bRequest1 B0x06bytes 2-3wValue2 B0x0100bytes 4-5wIndex2 B0x0000bytes 6-7wLength2 B0x0008Setup stageData stage (optional)Status stageOrange: values for the first device-descriptor readCourseTron · coursetron.com
    Layout of the 8-byte Setup packet, filled in for the first Get_Descriptor(Device) read of 8 bytes.

    The descriptor hierarchy

    Descriptors are a nested tree the device exposes as read-only data structures. They tell the host what the device is and what it can do.

    DescriptorKey fieldsPurpose
    DeviceidVendor, idProduct, bcdUSB, bMaxPacketSize0Identifies the device; one per device
    ConfigurationbNumInterfaces, bMaxPower, bmAttributesPower + a set of interfaces; host picks one
    InterfacebInterfaceClass, bInterfaceSubClassA function (HID, MSC, CDC…) that a driver binds to
    EndpointbEndpointAddress, wMaxPacketSize, bmAttributesData pipes: bulk, interrupt, isochronous
    StringUNICODE textHuman-readable names (optional)

    The idVendor/idProduct pair in the device descriptor is the identity the OS matches against its driver database. A Windows VID_0781&PID_5567 string, for instance, maps directly to those two 16-bit fields read during enumeration.

    Addressing: why Set_Address comes before the big read

    At reset every device answers to address 0, so only one un-enumerated device can be addressed at a time — hubs enforce this by holding other newly-attached ports in reset. The host hands out a unique address (1–127, giving a theoretical 127 devices per host controller) before reading the rest of the descriptors, moving the device off the shared default address so the next device can be enumerated. This serialisation is a classic interview gotcha: the full descriptor tree is read after addressing, not before.

    Watching it move: live packet exchange

    Control handshake on endpoint 0HOSTDEVICESETUPACKOrange: SETUP token, host to deviceBlue: ACK handshake, device to hostCourseTron · coursetron.com
    Animated control handshake: the host sends a SETUP token, the device acknowledges with ACK. Capture the real thing with Wireshark + usbmon, or a protocol analyzer like a Total Phase Beagle.

    For verification engineers, a USB device model is exercised in simulation with a VIP (verification IP) — Synopsys VC VIP, Cadence's USB UVM VIP, or Siemens/Mentor's Questa VIP — which drives exactly this enumeration sequence as a reusable UVM sequence and scoreboards the descriptor responses. On silicon, the same transactions are captured live with Wireshark's usbmon backend or a hardware analyzer so you can see every Setup/Data/ACK packet in order.

    Common failure modes

    • Wrong bMaxPacketSize0 — if firmware reports 64 but the control endpoint FIFO is 8 bytes, the data stage fragments wrongly and the host times out: "Device descriptor read/64, error -71" in Linux dmesg.
    • Over-current on bMaxPower — requesting more than 100 mA (unconfigured) or 500 mA (USB 2.0 configured) can make a bus-powered hub refuse the device.
    • Stalled Setup stage — a device that STALLs a mandatory standard request fails enumeration and shows as "unknown device."

    Where to go next

    Enumeration is the gateway topic; from here the natural next steps are the underlying signalling and the transfer types that follow. Start with our USB protocol basics primer, then move on to USB transfer types (control, bulk, interrupt, isochronous) to see how the pipes opened at Set_Configuration actually carry data. For hands-on protocol and SoC verification coaching beyond these notes, the structured programs at ChipXpert VLSI training complement the free material here. Browse the full catalog on our courses page.

    Ready to master USB, PCIe and AMBA protocols for design and verification roles? Join the CourseTron Protocol & Verification track and practice real enumeration debug with industry-grade VIP.

    FAQ

    How long does USB enumeration take?

    Typically tens to a few hundred milliseconds. The reset alone is at least 10 ms, and the spec requires the device to accept a new address within 50 ms and complete the Set_Address recovery within 2 ms, but real-world times depend on hub topology and host polling.

    Why is the device descriptor read twice?

    The host first reads only 8 bytes to learn bMaxPacketSize0 for endpoint 0, since it cannot correctly size later control transfers without it. After Set_Address it reads the full 18-byte device descriptor.

    What is address 0 used for?

    Address 0 is the default address every device responds to immediately after reset. Only one device can use it at a time, which is why Set_Address is issued early to free it for the next device.

    Can a device have more than one configuration?

    Yes. A device may expose several configuration descriptors (for example bus-powered vs. self-powered modes), and the host activates exactly one via Set_Configuration. Most consumer devices ship with a single configuration.

    Advertisement