USB Device Enumeration Failure: What Firmware Engineers Should Capture First
A practical guide to diagnosing USB devices that are not recognized, fail enumeration, or disappear during descriptor negotiation. Covers usb driver not detected, windows not recognizing usb, and computer not seeing usb in Bus Scope.
When a USB device is not recognized, the first question is rarely "which UI button should I click?" The useful question is: "how far did enumeration get, and what evidence proves where it stopped?" USB enumeration is a structured conversation between host and device. The host resets the port, asks for descriptors, assigns an address, selects a configuration, and loads a driver based on class and interface evidence. A firmware issue, descriptor mismatch, timing problem, cable issue, or driver binding problem can all produce the same user-facing symptom: "the device does not appear."
Direct answer: capture from before plug-in, keep every endpoint-zero request and completion, then mark the last successful enumeration stage. If the host never receives an initial device descriptor, investigate readiness, speed, cable, hub, power, or physical-bus behavior. If it reads the device descriptor but rejects configuration, validate lengths, interface counts, endpoint fields, and class-specific descriptors. If SET_CONFIGURATION succeeds, enumeration completed; move to driver binding, class setup, endpoints, and application policy.
Start with the Enumeration Timeline
A good USB capture should show:
- device attach or port reset
- setup packets
GET_DESCRIPTORrequests- device descriptor response
- address assignment
- configuration descriptor request
- string descriptor requests when present
SET_CONFIGURATION- class-specific requests after configuration
If the timeline stops before the device descriptor, the problem may be electrical, timing, hub, cable, or low-level device readiness. If it stops at configuration parsing, inspect descriptor length, endpoint definitions, interface classes, and total length fields. If enumeration succeeds but the application fails, the issue may be class protocol, endpoint behavior, or driver expectations.
Descriptor Evidence Beats Guesswork
Firmware teams often know what they intended to expose: HID, CDC, mass storage, vendor-specific endpoints, or a composite layout. The host only sees descriptors. If the descriptors are inconsistent, the host may reject the device even if the firmware logic is otherwise correct.
Important fields include:
- vendor ID and product ID
- device class, subclass, and protocol
- configuration total length
- interface count
- endpoint address and direction
- endpoint transfer type
- max packet size
- HID report descriptor availability
- CDC functional descriptors
Small descriptor mistakes can cause large symptoms. A mismatched total length or missing endpoint can make the whole device look broken.
Capture Before Installing More Drivers
Installing drivers can change behavior, but it can also hide the original failure. For diagnostics, capture the first clean enumeration attempt. Then capture after driver changes if needed. The comparison is valuable.
A practical support workflow is:
- capture attach and enumeration
- identify the last successful host request
- inspect descriptor fields around the failure
- compare against the intended USB class
- repeat after firmware or driver changes
This avoids the trap of debugging only the final application error.
Linux and Windows Need Different Capture Paths
On Linux, usbmon provides kernel-level USB traffic evidence. On Windows, USBPcap is the common capture driver path. The captures are not identical in operational setup, but the engineering goal is the same: preserve request, response, endpoint, direction, and class evidence.
For teams supporting both platforms, the report should call out the capture source. A device that enumerates on Linux but fails on Windows may have a driver binding issue. A device that fails before descriptors on both platforms is more likely to be firmware, cable, hub, or electrical timing.
Where Bus Scope Fits
Bus Scope is built around USB evidence rather than broad protocol sprawl. It helps firmware and hardware teams inspect transfers, descriptors, endpoints, and class observations in a dense workbench. The goal is not to replace every vendor analyzer. The goal is to make everyday USB evidence easier to capture, inspect, save, and hand off.
For enumeration failures, the valuable deliverable is a clear boundary:
- host made this request
- device returned this response
- enumeration stopped here
- descriptor evidence suggests this mismatch
- next action belongs to firmware, driver, cable, hub, or host policy
That is what turns "USB device not recognized" into an engineering case.
Enumeration stage table
Host sequences vary, and requests may repeat, but this table gives diagnostic boundaries:
| Stage | Expected evidence | If it stops here |
|---|---|---|
| Attach/reset | Port event and reset/readiness | Power, cable, hub, speed, device readiness, physical layer |
| Initial device descriptor | Short/full GET_DESCRIPTOR(Device) response |
EP0, descriptor length/type, timing, max packet handling |
| Address assignment | Successful SET_ADDRESS and traffic at new address |
Address-state transition or control handling |
| Full descriptors | Device/configuration/string/BOS/class descriptors | Malformed length, stall, encoding, descriptor contract |
| Configuration selection | Successful SET_CONFIGURATION |
Configuration value, endpoint setup, firmware state |
| Interface/class setup | HID/CDC/UVC/storage/vendor requests | Class implementation or driver expectation |
| Driver binding | OS chooses driver/function | Interface identity, policy, driver package, OS descriptors |
| Application traffic | Endpoint transfers | Endpoint activation, protocol, permissions, application |
Do not call every failure “enumeration.” Once configuration succeeds, the next failing class request may still prevent useful operation, but the device has crossed the basic enumeration boundary.
Endpoint zero is the primary evidence source
Enumeration runs through the default control pipe. For each transfer, retain:
- setup packet;
- data stage where present;
- status/completion;
- requested and actual length;
- device address;
- timestamp and retry context.
Key setup fields:
| Field | Diagnostic use |
|---|---|
bmRequestType |
Direction, request type, recipient |
bRequest |
GET_DESCRIPTOR, SET_ADDRESS, SET_CONFIGURATION, or class/vendor operation |
wValue |
Descriptor type/index or request-specific value |
wIndex |
Language, interface, endpoint, or request-specific target |
wLength |
Host-requested data length |
Firmware must support short descriptor reads, full reads, correct data direction, and the status stage. A response can contain the right bytes and still fail because length or control-state handling is wrong.
Device descriptor checks
Verify:
bLengthand descriptor type;- USB version;
- class/subclass/protocol placement;
- endpoint-zero maximum packet size encoding;
- VID/PID;
bcdDevice;- string indexes;
- number of configurations.
Check decoded values against raw bytes. If the host first requests only part of the descriptor, firmware must return the allowed prefix rather than insisting on one fixed length.
Configuration descriptor checks
The configuration hierarchy is a common failure source:
- configuration header length and type;
wTotalLength;- number of interfaces;
- configuration value;
- attributes and power;
- interface descriptors and alternate settings;
- class-specific descriptors;
- endpoint descriptors;
- companion descriptors where required.
Walk the raw bytes by each descriptor's bLength. The sum should align with wTotalLength, and descriptor count/relationships should match the declared interfaces and endpoints.
Common defects:
- zero or invalid
bLength; - total length shorter/longer than the chain;
- duplicate endpoint addresses in one active alternate;
- endpoint count mismatch;
- impossible packet-size or interval fields;
- class-specific descriptor attached to wrong interface;
- interface association range mismatch;
- missing required HID report or CDC functional evidence.
String descriptors and LANGID
String failures can be intermittent or host-specific:
- string index 0 should advertise supported language IDs;
- later string requests specify a language in
wIndex; - descriptor length counts bytes and must fit UTF-16LE payload;
- serial strings should be stable and valid if used for instance identity;
- unsupported language/index behavior should be consistent.
A bad serial descriptor may not stop basic enumeration on every host but can change device-instance mapping or driver behavior. The string descriptor guide covers details.
SET_ADDRESS state transition
The device must apply the new address at the correct point in the control transfer. If it switches too early or too late, the host and device can stop speaking.
Capture questions:
- Did the host send
SET_ADDRESS? - Did the status stage complete?
- Did following requests use the new address?
- Did the device answer there?
- Did the host reset and retry?
Software capture may show the host's view but not every on-wire detail. If the trace becomes ambiguous exactly at address transition, correlate firmware logs and consider hardware capture.
SET_CONFIGURATION boundary
When the host selects a configuration, firmware commonly:
- validates the configuration value;
- enables required interfaces/endpoints;
- allocates buffers;
- starts class state;
- completes the control request.
Do not acknowledge success before endpoint/state initialization can actually support following traffic. A successful completion followed immediately by class failure may indicate a state transition bug rather than descriptor parsing.
Enumeration versus driver binding
If descriptors and SET_CONFIGURATION succeed but the expected driver or COM port does not appear, inspect:
- interface class/subclass/protocol;
- composite/IAD grouping;
- HID/CDC/class-specific descriptors;
- Microsoft OS compatible IDs or BOS platform capability where used;
- existing driver packages and OS policy;
- device instance identity and cache;
- permissions for user-space access.
The BOS and Microsoft OS descriptor guide covers WinUSB/WebUSB discovery. USB capture proves descriptor exchange; OS setup logs explain binding policy.
Known-good comparison
Capture the same device with known-good firmware or a reference device implementing the same class. Align:
| Sequence point | Reference | Failing |
|---|---|---|
| Reset/readiness | Time to first request | |
| Device descriptor | Length/bytes/status | |
| Address | Assignment and next response | |
| Configuration header | Total length | |
| Full configuration | Descriptor chain | |
| Configuration select | Status | |
| First class request | Fields/status |
The first divergence is more actionable than a broad diff of every timestamp.
Windows and Linux comparison
Run the same firmware on both platforms when possible:
- If both fail before device descriptor, focus below driver policy.
- If both read standard descriptors but one rejects configuration, compare parser tolerance and descriptor contract.
- If enumeration succeeds on both but only one binds a driver, investigate OS/class policy.
- If only one application lacks access, inspect permissions and application behavior.
Record capture backend and host version. USBPcap and usbmon represent host-stack events differently, so compare semantic stages rather than frame numbering.
Physical and topology experiments
When the failure is early or intermittent:
| Change | Hypothesis |
|---|---|
| Known-good short cable | Cable/signal/power sensitivity |
| Direct host port | Hub/dock/transaction path |
| Different controller | Host-controller behavior |
| Powered hub | Power/current/transient behavior |
| Disconnect other devices | Shared topology and bus load |
| Delayed firmware readiness | Control-response timing |
| Another host | Host-specific policy or physical implementation |
Change one variable per capture. A working cable does not prove the firmware descriptor contract; it narrows the failure.
Firmware instrumentation
Log:
- reset and speed event;
- endpoint-zero setup bytes;
- data-stage lengths;
- status-stage completion;
- address applied;
- configuration selected;
- descriptor source/offset;
- stall reason;
- control timeout;
- endpoint initialization;
- watchdog/brownout/reset cause.
Add a sequence number so firmware logs can align with host requests. Avoid logging so heavily that timing changes and hides the bug.
When software capture is insufficient
Escalate when:
- no useful host event exists before failure;
- device and host disagree about whether a transfer occurred;
- exact handshake/retry behavior is required;
- reset/address timing cannot be resolved;
- speed negotiation or signal integrity is suspected;
- cable/topology changes strongly affect early enumeration.
Keep the software trace for host intent and correlate it with hardware evidence.
Bus Scope workflow
- Verify USBPcap or usbmon and select the target controller/bus.
- Start capture before connection.
- clear filters until target traffic is confirmed.
- identify the last successful enumeration stage.
- inspect raw and decoded control evidence.
- validate descriptor lengths/relationships.
- compare known-good firmware.
- correlate firmware and OS logs.
- perform one-variable topology tests.
- export the bounded sequence with host/device/build metadata.
Use the Bus Scope platform capture guide before drawing conclusions from an empty trace.
Common mistakes
Installing drivers before preserving first enumeration
Capture the original state; driver changes can alter or cache behavior.
Filtering out endpoint zero
The control request that caused the symptom may disappear from view.
Trusting one decoded total length
Walk the raw descriptor chain and verify every bLength.
Calling driver binding an enumeration failure
If configuration succeeds, separate USB protocol success from OS driver policy.
Assuming software capture proves electrical behavior
It records the host backend's evidence, not every wire transaction.
Questions and answers
What is USB enumeration?
It is the host/device process that resets the port, reads descriptors, assigns an address, selects configuration, and prepares interfaces for driver/class use.
What should I capture first?
Capture from before plug-in through the first class/application request, keeping endpoint-zero setup, data, status, descriptors, reset, address, and configuration events.
What does it mean if SET_CONFIGURATION succeeds?
Basic descriptor selection and configuration completed. Continue with driver binding, class requests, endpoint activation, and application behavior.
Why does Windows say “device descriptor request failed”?
The host could not complete the expected descriptor exchange. Inspect whether a request was sent, whether bytes returned, status/length, retries/resets, and physical/topology variables.
Can Bus Scope diagnose an electrical failure?
It can show host-visible behavior and where evidence stops. Electrical or exact on-wire proof requires suitable hardware instrumentation.
Why does the device work on Linux but not Windows?
Compare standard descriptor exchange first, then driver binding, Microsoft OS descriptors, composite grouping, instance cache, and permissions. Different host behavior does not automatically identify one cause.
<!-- multilingual-related-reading:start -->Related guides
Continue with the same-language pages below. They cover adjacent stages without changing the canonical owner of this topic:
<!-- multilingual-related-reading:end -->