Skip to content
VLSI Mentor

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_DESCRIPTOR and SET_ADDRESS this 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”
1GET_DESCRIPTOR(DEVICE), 64 bytesSET_ADDRESS
2bus resetGET_DESCRIPTOR(DEVICE), 8 bytes
3SET_ADDRESSfull 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:

#StepDevice stateWhy here
1Bus reset→ DefaultChapter 8.3: establish a known state
2GET_DESCRIPTOR(DEVICE), wLength 64Defaultlearn bMaxPacketSize0
3Bus reset→ Defaultsee §3
4SET_ADDRESS(n)→ AddressChapter 8.4
5GET_DESCRIPTOR(DEVICE), 18 bytesAddressthe full descriptor
6GET_DESCRIPTOR(CONFIG), 9 bytesAddressread wTotalLength
7GET_DESCRIPTOR(CONFIG), wTotalLengthAddressthe whole tree
8SET_CONFIGURATION(1)→ ConfiguredChapter 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.

A sequence diagram of a complete USB enumeration in the kernel's new scheme. The host first resets the bus, putting the device into the Default state where it answers at address zero. It then issues a GET_DESCRIPTOR for the device descriptor asking for sixty-four bytes; the device returns what it has, and the host reads the maximum packet size for endpoint zero from byte seven. The host resets the bus a second time, because some devices need one. It then issues SET_ADDRESS, moving the device to the Address state, and reads the full eighteen-byte device descriptor. It reads the first nine bytes of the configuration descriptor to obtain the total length of the configuration tree, then reads the whole tree using that length. Finally it issues SET_CONFIGURATION, moving the device to the Configured state, at which point the device's endpoints exist and enumeration is complete.Eight steps, three statesHostDeviceDevice statebus resetDefault — answers ataddress 0GET_DESCRIPTOR(DEVICE)· wLength 64…bMaxPacketSize0 isat byte 7bus reset again —some devices need itSET_ADDRESS(10)AddressGET_DESCRIPTOR(DEVICE)· 18 bytesGET_DESCRIPTOR(CONFIG)· 9 bytes →wTotalLengthGET_DESCRIPTOR(CONFIG)· wTotalLength — thewhole treeSET_CONFIGURATION(1)Configured —endpoints exist
Figure 1 — one complete enumeration in the new scheme, with the device's state and the reason for each step. Note the second reset after the descriptor probe, and that steps 6 and 7 are a probe-then-read pair exactly like step 2 — a pattern that appears three times in eight steps.

4. What Each Step Depends On

The dependencies are what make the order the only one that works — and they are not all obvious.

StepCannot happen beforeBecause
Descriptor reada bus resetthe device must be in a known state
SET_ADDRESS—legal in Default; it is the only exit
Any read of >bMaxPacketSize0 bytesthe probethe host cannot packetise correctly
Config tree readthe 9-byte config readwTotalLength is inside it
SET_CONFIGURATIONSET_ADDRESSChapter 13.4 §2: illegal in Default
Any interface requestSET_CONFIGURATIONinterfaces 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

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ─────────────────────────────────────────────────────────────────────────
// 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

endmodule

What 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 cycles
A waveform of the enumeration monitor over nine events. The first is a bus reset, leaving the device in the Default state with the maximum packet size not yet known. The second is a sixty-four byte device-descriptor read, still in Default, after which the maximum packet size is known. The third is a second bus reset, which returns the device to Default but does not un-learn the packet size. The fourth is SET_ADDRESS, after which the device is in the Address state. The fifth, sixth and seventh are descriptor reads of eighteen, nine and thirty-four bytes, all in the Address state. The eighth is SET_CONFIGURATION, after which the device is Configured and enumeration is complete.64 bytes, in Default, before any address64 bytes, in Default,before any addressreset again — state clears, knowledge does notreset again — state clears,knowledge does not9 bytes to learn wTotalLength9 bytes to learnwTotalLengthConfigured — endpoints existConfigured — endpointsexiststepbus resetGET_DESC 64bus resetSET_ADDRESSGET_DESC 18GET_CFG 9GET_CFG 34SET_CONFIGidledevice stateDefaultDefaultDefaultDefaultAddressAddressAddressAddressConfiguredwLength—64—0189340—maxp0_knownenumeratedt0t1t2t3t4t5t6t7t8
Figure 2 — the eight steps of §2, every column taken from a simulation of the monitor above. The device's state advances only twice in eight steps; what changes more often is what the host knows. Note that the second bus reset returns the state to Default without un-learning bMaxPacketSize0.

6. 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 flaggedinvalid order not flaggedstate disagreed
golden000
E1 legality not checked040
E2 short-probe check removed010
E3 SET_ADDRESS(0) → Address012
E4 SET_CONFIGURATION(0) → Default102
E5 enumerated on any configuration010

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_DESCRIPTOR and SET_ADDRESS
  • bus reset before the probe, after it, and mid-sequence
  • SET_ADDRESS value zero and non-zero; SET_CONFIGURATION value 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, then SET_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

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.