USB · Module 13
Enumeration as Worked Example
One real enumeration end to end — and the discovery that the canonical sequence is not canonical: Linux carries two schemes, picks between them per attempt, and says in a comment why.
Every piece is now built: packets, transactions, stages, requests, states, descriptors. This chapter assembles them into the one sequence every USB device must survive.
And it begins with a correction, because the sequence has a name it does not deserve.
1. The Canonical Sequence Is Not Canonical
There is no single enumeration sequence. Linux carries two, chooses between them per attempt, and the comment in hub.c explaining the choice is unusually candid:
“Why interleave
GET_DESCRIPTORandSET_ADDRESSthis way? Because device hardware and firmware is sometimes buggy in this area, and this is how Linux has done it for ages. Change it cautiously.”
The two schemes differ in what happens first:
| “New scheme” | “Old scheme” | |
|---|---|---|
| 1 | GET_DESCRIPTOR(DEVICE), 64 bytes | SET_ADDRESS |
| 2 | bus reset | GET_DESCRIPTOR(DEVICE), 8 bytes |
| 3 | SET_ADDRESS | full descriptor read |
| Origin | “This is what Windows does, so it may help with some non-standards-compliant devices” | how Linux did it first |
And the choice is not fixed. use_new_scheme() disables the new scheme entirely for SuperSpeed — with a reason worth reading:
“New scheme enumeration causes an extra state transition to be exposed to an xhci host and causes USB3 devices to receive control commands in the default state. This has been seen to cause enumeration failures.”
— and when use_both_schemes is set, the host uses one scheme for the larger half of its retries and the other for the rest.
2. The Sequence, Step by Step
Taking the new scheme, which is what a modern Linux host does for full and high speed:
| # | Step | Device state | Why here |
|---|---|---|---|
| 1 | Bus reset | → Default | Chapter 8.3: establish a known state |
| 2 | GET_DESCRIPTOR(DEVICE), wLength 64 | Default | learn bMaxPacketSize0 |
| 3 | Bus reset | → Default | see §3 |
| 4 | SET_ADDRESS(n) | → Address | Chapter 8.4 |
| 5 | GET_DESCRIPTOR(DEVICE), 18 bytes | Address | the full descriptor |
| 6 | GET_DESCRIPTOR(CONFIG), 9 bytes | Address | read wTotalLength |
| 7 | GET_DESCRIPTOR(CONFIG), wTotalLength | Address | the whole tree |
| 8 | SET_CONFIGURATION(1) | → Configured | Chapter 8.5 |
Steps 2, 6 and 7 are all the same pattern: read a fixed prefix to learn a length, then read the whole thing. Chapter 13.2 §3's probe, applied twice to different descriptors.
And steps 6 and 7 are not optional. A configuration descriptor is the head of a tree — Chapter 7.2 — whose total size is in wTotalLength at bytes 2–3 of the 9-byte header. The host cannot know how much to ask for until it has asked for the header.
3. Why There Are Two Resets
The step that looks redundant and is not.
After reading the descriptor in Default, the host resets the bus again — throwing away nothing it has learned, because Chapter 13.4 §9 established that a bus reset clears the device's state and not the host's knowledge.
The kernel's own comment gives the reason:
“Some devices time out if they are powered on when already connected. They need a second reset.”
So the second reset is a workaround, and the code says so — it is applied only on the first attempt, lest we get into a time-out/reset loop.
4. What Each Step Depends On
The dependencies are what make the order the only one that works — and they are not all obvious.
| Step | Cannot happen before | Because |
|---|---|---|
| Descriptor read | a bus reset | the device must be in a known state |
SET_ADDRESS | — | legal in Default; it is the only exit |
Any read of >bMaxPacketSize0 bytes | the probe | the host cannot packetise correctly |
| Config tree read | the 9-byte config read | wTotalLength is inside it |
SET_CONFIGURATION | SET_ADDRESS | Chapter 13.4 §2: illegal in Default |
| Any interface request | SET_CONFIGURATION | interfaces do not exist before it |
Chapter 13.4 §3's graph is what enforces the fourth and fifth rows, and the rest are data dependencies — a value the host needs is inside something it has not read yet.
5. The Enumeration Monitor, as a Verification Model
// ─────────────────────────────────────────────────────────────────────────
// usb_enum_monitor
//
// Classification: VERIFICATION MODEL. Not synthesizable and not intended to
// be -- it is a passive observer for a bench or an emulation harness, and it
// exists because the properties this chapter is about are properties of a
// SEQUENCE, which no per-transfer check can express.
//
// WHAT IT MODELS. The device state a sequence of control transfers implies
// (Chapter 13.4's graph), whether the host has learned bMaxPacketSize0, and
// three anomalies: a request issued where it is not legal, a configuration
// selected before an address, and a descriptor read too short to learn what
// it was issued to learn.
//
// WHAT IT DOES NOT MODEL. Anything below a completed control transfer --
// stages (Chapters 13.1 to 13.3), transactions (Module 12), packets (Module
// 11); the descriptors' CONTENTS (Module 7); the two schemes of section 1,
// which it must ACCEPT BOTH of rather than prefer either; and the host's
// retry policy, whose constants are in section 1's table.
//
// ── WHY A MONITOR AND NOT A DESIGN ──────────────────────────────────────
// Enumeration is not a block. It is an interaction, and the thing that can
// be wrong about it is an ORDER. A monitor is the only shape that can hold
// an opinion about an order, which is why this chapter's RTL is a checker.
// ─────────────────────────────────────────────────────────────────────────
module usb_enum_monitor
import usb_req_pkg::*;
(
input logic clk,
input logic rst_n,
input logic bus_reset,
input logic xfer_done, // a control transfer completed
input logic [7:0] bRequest,
input logic [15:0] wValue,
input logic [15:0] wLength,
input logic stalled,
output dev_state_e state,
output logic maxp0_known,
output logic enumerated,
output logic illegal_order,
output logic premature_config,
output logic blind_read
);
dev_state_e st_q;
logic maxp_q, enum_q, ill_q, prem_q, blind_q;
assign state = st_q;
assign maxp0_known = maxp_q;
assign enumerated = enum_q;
assign illegal_order = ill_q;
assign premature_config = prem_q;
assign blind_read = blind_q;
// Chapter 13.4's legality table, as a function.
function automatic logic legal(input [7:0] r, input dev_state_e s);
case (r)
REQ_GET_DESCRIPTOR: return 1'b1;
REQ_SET_ADDRESS: return (s <= ST_ADDRESS);
REQ_SET_CONFIGURATION,
REQ_GET_CONFIGURATION,
REQ_GET_STATUS,
REQ_SET_DESCRIPTOR: return (s >= ST_ADDRESS);
REQ_GET_INTERFACE,
REQ_SET_INTERFACE,
REQ_SYNCH_FRAME: return (s == ST_CONFIGURED);
REQ_CLEAR_FEATURE,
REQ_SET_FEATURE: return 1'b1;
default: return 1'b0;
endcase
endfunction
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
st_q <= ST_DEFAULT; maxp_q <= 1'b0; enum_q <= 1'b0;
ill_q <= 1'b0; prem_q <= 1'b0; blind_q <= 1'b0;
end else if (bus_reset) begin
// Chapter 8.3: a bus reset returns the DEVICE to Default and discards
// its address. It does NOT discard what the HOST learned -- section 3
// -- because bMaxPacketSize0 is a property of the device rather than
// of the connection. Clearing maxp_q here would make the second reset
// of section 2 undo the probe that preceded it.
st_q <= ST_DEFAULT; enum_q <= 1'b0;
ill_q <= 1'b0; prem_q <= 1'b0; blind_q <= 1'b0;
end else begin
ill_q <= 1'b0; prem_q <= 1'b0; blind_q <= 1'b0; // pulses
if (xfer_done) begin
if (!legal(bRequest, st_q)) ill_q <= 1'b1;
if (!stalled) begin
case (bRequest)
REQ_GET_DESCRIPTOR: begin
if (wValue[15:8] == 8'd1) begin // the DEVICE descriptor
// SECTION 4'S CALLOUT. bMaxPacketSize0 is at BYTE 7, so any
// read of 8 or more teaches it -- including the 64-byte read
// the kernel's new scheme opens with. "Probe with exactly 8"
// is folklore, and encoding it rejects a real host.
if (wLength >= 16'd8) maxp_q <= 1'b1;
else if (!maxp_q) blind_q <= 1'b1;
end
end
REQ_SET_ADDRESS: begin
// Address zero returns the device to Default -- Chapter 13.4
// section 11's confusion, and it goes a different distance
// from SET_CONFIGURATION(0).
if (wValue[6:0] != 7'd0) st_q <= ST_ADDRESS;
else st_q <= ST_DEFAULT;
end
REQ_SET_CONFIGURATION: begin
if (st_q < ST_ADDRESS) prem_q <= 1'b1;
// Configuration zero returns the device to ADDRESS, not to
// Default. The two zero cases are not symmetric.
if (wValue[7:0] != 8'd0) st_q <= ST_CONFIGURED;
else st_q <= ST_ADDRESS;
// Enumeration is complete only if this was legal AND selected
// a real configuration.
if ((wValue[7:0] != 8'd0) && (st_q >= ST_ADDRESS)) enum_q <= 1'b1;
end
default: ;
endcase
end
end
end
end
endmoduleWhat it models. The state and knowledge a sequence of control transfers implies, plus three anomalies about the sequence's order.
Engineering reason. Because enumeration's failures are failures of order, and an order is not observable from any single transfer.
Inputs. Completed control transfers with their request fields, and bus resets.
State retained. Two bits of device state, a knowledge bit, an enumerated bit, and three pulses.
Outputs. The implied state, what the host has learned, completion, and three anomalies.
Hardware implied. None intentionally — this is a monitor.
Reset behaviour. A hard reset clears everything including maxp0_known; a bus reset clears only the device-side state. That asymmetry is the model's most important line and §7's bench initially got it backwards.
Assumptions. That xfer_done marks a completed transfer including its status stage; that stalled distinguishes a refused request from an honoured one; and that the observer sees every control transfer — a monitor that misses one draws wrong conclusions from then on.
Omissions. Everything below a transfer, descriptor contents, the schemes' selection, and the retry policy — in the header.
What DV should verify. That both schemes of §1 are accepted with no anomaly; that retries and repeated resets are accepted; that a configuration selected before an address is flagged; that an interface request before Configured is flagged; that SET_ADDRESS(0) returns to Default and SET_CONFIGURATION(0) to Address; and that a descriptor read too short to reach byte 7 is flagged.
One enumeration, as the monitor sees it
9 cycles6. Mutation Test
Five mutations over a bench that drives both schemes, retries with stalls, repeated bus resets, un-configuration, un-addressing, and six deliberately illegal orders.
The unmutated monitor: both schemes accepted with zero anomalies, every illegal order flagged, and 0 errors of every kind.
| valid enumeration flagged | invalid order not flagged | state disagreed | |
|---|---|---|---|
| golden | 0 | 0 | 0 |
| E1 legality not checked | 0 | 4 | 0 |
| E2 short-probe check removed | 0 | 1 | 0 |
E3 SET_ADDRESS(0) → Address | 0 | 1 | 2 |
E4 SET_CONFIGURATION(0) → Default | 1 | 0 | 2 |
| E5 enumerated on any configuration | 0 | 1 | 0 |
E1 — do not check legality at all
Measured: 4 illegal orders accepted.
The monitor becomes a state tracker with no opinion. SET_CONFIGURATION in Default, GET_INTERFACE in Address — all pass, which is the whole of what a sequence monitor exists to prevent.
E2 — remove the short-probe check
Measured: 1 escape — a device-descriptor read of 4 bytes, which cannot reach bMaxPacketSize0 at byte 7.
Small, and the §4 callout is why it is worth having at all: the check nearly encoded the folklore version of this rule, which would have rejected a real Linux host.
E3 — make SET_ADDRESS(0) move to Address
Measured: 2 state divergences and 1 missed illegal order.
Chapter 13.4 §11's confusion, half of it. A device un-addressed by SET_ADDRESS(0) returns to Default, and a monitor that thinks otherwise then believes SET_CONFIGURATION is legal when it is not.
E4 — make SET_CONFIGURATION(0) move to Default
Measured: 2 state divergences, and a valid enumeration flagged as anomalous.
The other half. SET_CONFIGURATION(0) returns to Address, not Default — so a monitor that goes too far then rejects the perfectly legal SET_CONFIGURATION(1) that follows.
And note the column it lands in: this is the only mutation that produces a false positive. E1, E2, E3 and E5 all miss something; E4 invents something.
E5 — declare enumeration complete on any SET_CONFIGURATION
Measured: 1 escape — a SET_CONFIGURATION issued in Default, which is illegal, is nonetheless counted as completing enumeration.
The monitor reports success for a sequence it simultaneously flagged as illegal. Two outputs disagreeing about the same event, which is worse than either being wrong alone.
7. Verification
This chapter's commit point is the sequence was one a real host would produce, and every departure from one was reported.
Stimulus. Both schemes of §1, complete; a stalled GET_DESCRIPTOR followed by a retry; a stalled SET_ADDRESS followed by a retry; two bus resets in one enumeration; SET_CONFIGURATION(0) followed by SET_CONFIGURATION(1); SET_ADDRESS(0) followed by an illegal SET_CONFIGURATION; and six deliberately illegal orders.
Observation. The implied state against an independently-maintained model, all three anomaly flags, and completion — after every transfer, plus explicit checks that a valid enumeration produces no anomaly and that each illegal order produces the right one.
Reference model. The state graph maintained separately in the bench from Chapter 13.4's table. Its independence is partial — it is the same table — which is why the bench's strongest checks are the two sequence-level obligations: a valid enumeration is never flagged, and an invalid order is always flagged. Neither references the table.
Coverage — crosses:
- scheme (new / old) × completion
- retry after a stall on each of
GET_DESCRIPTORandSET_ADDRESS - bus reset before the probe, after it, and mid-sequence
SET_ADDRESSvalue zero and non-zero;SET_CONFIGURATIONvalue zero and non-zero- descriptor read lengths of 4, 8, 18 and 64 — spanning byte 7 from both sides
- every illegal request × the state that makes it illegal
Negative cases with defined outcomes: a valid enumeration in either scheme raises no flag; a configuration before an address is flagged; an interface request before Configured is flagged; a too-short probe is flagged; and enumeration is never declared complete from an illegal request.
8. Debugging: the Device That Works on Windows and Not on Linux
A device enumerates reliably on Windows. On Linux it fails perhaps one time in three, and succeeds on a retry. Nothing about the device or the cable changes between attempts.
What does succeeds on a retry tell you? That the device is not broken in a way that is always wrong. Something differs between attempts, and §1 says what: the host may be using a different scheme.
Which scheme does Windows use? The kernel's comment names it: the new scheme is “what Windows does”. So a device that works on Windows works in the new scheme — and the Linux failures are the attempts that used the old one.
When does Linux switch? use_new_scheme() — with use_both_schemes set, the first scheme covers the larger half of the retries and the other covers the rest. So a device that fails in one scheme fails on some attempts and not others, at a ratio determined by PORT_INIT_TRIES.
What differs between the schemes for the device? §1: which state the descriptor is read in. The new scheme reads it in Default at address 0; the old scheme reads it after SET_ADDRESS, in Address.
So what is the likely defect? That the device only serves GET_DESCRIPTOR correctly in one of those states — most often that it cannot serve it in Address before a configuration, or that its descriptor data is only prepared after SET_ADDRESS runs.
How do you confirm it without touching the device? Set old_scheme_first. It is a module parameter, so forcing the old scheme is one boot argument — and if the device then fails every time instead of one time in three, the hypothesis is confirmed and the failing scheme is identified in a single experiment.
And why is the one-in-three ratio itself informative? Because it is not random. It is PORT_INIT_TRIES divided by the scheme split, and a failure rate that matches a retry constant is evidence that the retry machinery is what is varying — not the device, not the cable, not the electrical margin.
The signature to keep: an intermittent enumeration failure whose rate matches a small integer ratio is a host-scheme problem, not a marginal one — and the module parameter that forces one scheme turns it into a deterministic test.
9. Common Misconceptions
10. Reason It Through
A device works with every host except one embedded controller, which reports enumeration failure at
SET_CONFIGURATION. A trace shows the host reading the device descriptor, then the 9-byte configuration header, thenSET_CONFIGURATION(1)— with no full configuration read in between.
Is that host legal? §4's table lists the config tree read as a dependency of knowing what the configuration contains — not of SET_CONFIGURATION itself. Chapter 13.4 §2: SET_CONFIGURATION is legal in Address, full stop.
So the host is within its rights. It read enough to know configuration 1 exists — bConfigurationValue is in the 9-byte header — and selected it without reading the interfaces it contains.
Why would a device care? Because a device that builds its endpoint configuration while serving the descriptor tree read has made that read a prerequisite. Skip the read and the endpoints were never built.
Is that a defect? Yes, and an easy one to introduce: the tree read is present in every trace the developer has ever looked at, so it always happens becomes an assumption without anybody deciding it.
What is the correct structure? SET_CONFIGURATION is the event that creates the endpoints — Chapter 8.5 — and the descriptor read is a read, which must have no side effects at all.
How would you have caught it? §5's monitor would not — it checks orders that are illegal, and this order is legal. The check that catches it is a different one: that no descriptor read changes any device state, which is a property about side effects rather than about sequence.
And the transferable point: a step that always happens is not the same as a step that must happen, and the difference is invisible in a trace. Every observed sequence contains steps in an order; only the specification says which of them are dependencies — and a device that infers dependencies from traces encodes the habits of the hosts it was tested against.
11. Understanding Check
12. Summary
There is no canonical enumeration sequence. Linux carries two schemes — one opening with a 64-byte descriptor read in Default, one opening with SET_ADDRESS — chooses between them per attempt, disables the new one entirely for SuperSpeed, and exposes the order as a module parameter. The comment explaining it is candid: “this is how Linux has done it for ages. Change it cautiously.”
So a device is tested against one sample from a family, and the family member is chosen at run time by the host, from retry counts of 2, 3, 4 and 5.
The sequence's order is fixed by dependencies, some structural and some data: a bus reset before anything; SET_ADDRESS as the only exit from Default; the nine-byte configuration header before the tree, because wTotalLength is inside it; and SET_CONFIGURATION after SET_ADDRESS because Chapter 13.4's graph says so.
And one widely-repeated dependency is folklore. Probe with exactly 8 bytes is wrong; the rule is at least 8, because bMaxPacketSize0 is at byte 7 — and the kernel proves it by opening with 64.
§7 is the chapter's finding, and it is about checkers rather than designs. The monitor written for this chapter encoded the folklore and rejected a real Linux host — caught only because the bench drives both schemes and asserts that neither produces an anomaly.
A checker's false positives are only visible against stimulus its author did not design.
Two further bench defects had the same shape — SET_ADDRESS(0) was never sent, because the bench enumerated devices and never un-enumerated one; and a fresh-host case used a bus reset where it needed a hard one, because the model deliberately keeps host knowledge across a bus reset. All three modelled the sequence the author had in mind rather than the one the environment produces.
And §6's E3/E4 pair is the reason it matters which direction a checker is wrong in: both come from reading value zero means go back as one rule when it is two that go back different distances. The permissive error misses bugs; the strict error reports them — and is believed.
13. What Comes Next
Module 13 is complete, and with it the whole of USB's logical layer: a device is described, addressed, configured, and talked to, in packets carried by transactions grouped into transfers.
Everything so far has assumed the bits arrive. That a packet's boundaries can be found, that a one can be told from a zero, that a receiver can recover a clock from a wire carrying no clock, and that a device just plugged in can work out what speed to talk at before it can talk at all.
None of that is free, and it is what the remaining modules are about — beginning with how a bit is put on a wire such that the other end can find it again.
Browse the full path on the USB tutorials index.
Continue learning
Related tutorials
- Related topic
The Peripheral-Connectivity Problem
Before a universal peripheral bus, every class of device arrived with its own connector, signalling, host interface, configuration story and driver model — and the cost of that fragmentation landed on the host, the operating system, the peripheral vendor and the user at once. The problem, layer by layer, and the requirements it forces on any architecture meant to replace it.
- Related topic
Why USB Was Created
The synthesis chapter: what three examined legacy interfaces had structurally in common, the six architectural decisions that follow from that evidence, the cost each decision carries, and why standardising peripheral attachment changes the economics of controller silicon, verification IP and compliance rather than removing the engineering.
- Related topic
SuperSpeed (SS)
A mode that does not compete for the conductors the others use — it has its own. What active mode means when two modes run concurrently on one connection, why that makes mode a per-path property, and the verification model that must observe rather than assume.
- Related topic
Device Connection
What the host actually observes when a device is plugged in, why four different kinds of state are involved, and why debounce is a correctness requirement rather than a convenience.
Standards & specifications
- Governing standard
- USB-IF (Universal Serial Bus Specification)(opens USB Implementers Forum (USB-IF) in a new tab)
Defines the USB bus — its electrical signalling, connectors, packet and transaction model, device framework and the descriptors a device must expose — together with the device-class specifications layered on it. It does not define host-controller register interfaces (xHCI and EHCI are separate documents) nor any operating system's driver architecture.
This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.
Where this fits
Part of the USB curriculum.
