usb: P3-A complete — Linux hub.c enumeration state machine in usbhubd
Track base pointer to bd379e07 (usbhubd debounce/reset-wait/U0-wait/
wHubDelay + SET_ISOCH_DELAY, HubDescriptorV3 device_removable fix).
USB-IMPLEMENTATION-PLAN.md: P3-A marked CORE COMPLETE with the full
Linux equivalence inventory and documented follow-ups (USB 2.0 bitmaps,
SS.Inactive warm-reset loop, multi-TT, hub LPM). Hub gap-table row
updated (249 -> ~700 LoC with Linux state machine).
HARDWARE-VALIDATION-MATRIX.md: hub row updated — enumeration core
complete with 14 unit tests; runtime hub proof tracked under P8-B.
This commit is contained in:
@@ -15,7 +15,12 @@
|
||||
| AC97 | 🔲 | 🔲 | Basic driver |
|
||||
| **Input** | | | |
|
||||
| PS/2 | ✅ | 🔲 | QEMU keyboard/mouse work |
|
||||
| USB HID | 🔲 | 🔲 | Hardened (P3), not validated on real HW |
|
||||
| USB HID | ✅ | 🔲 | Keyboard/mouse autospawn via test-usb-qemu.sh (P1 hardening); not validated on real HW |
|
||||
| **USB** | | | |
|
||||
| xHCI host controller | ✅ | 🔲 | Interrupt-driven mode proven (test-xhci-irq-qemu.sh); 51-flag quirk table + HCCPARAMS2 gating (P2-A/B); 36-code error recovery (P2-C); not HW-validated |
|
||||
| EHCI/UHCI/OHCI controllers | 🔲 | 🔲 | Compile clean; runtime enumeration proofs planned (P8-B) |
|
||||
| USB storage (BOT) | ✅ | 🔲 | usbscsid autospawn + bounded sector readback proven (test-usb-storage-qemu.sh); guest-side write verify open |
|
||||
| USB hub (non-root) | 🔲 | 🔲 | P3-A enumeration core complete (debounce/reset-wait/U0-wait/wHubDelay, 14 unit tests); runtime hub proof pending (P8-B test-usb-hub-qemu.sh) |
|
||||
| **GPU/Display** | | | |
|
||||
| VESA | ✅ | 🔲 | QEMU framebuffer works |
|
||||
| virtio-gpu | ✅ | N/A | 2D only, QEMU |
|
||||
|
||||
@@ -40,7 +40,7 @@ Where the v2 plan referenced Redox upstream commits, v3 references **Linux 7.1**
|
||||
| Storage protocols | 1 (BOT) | 5+ (BOT, UAS, SAT, UASP, multi-LUN) | 4 missing |
|
||||
| HID class features | Boot protocol only | Full report descriptor parsing, multi-touch, quirks | ~80% gap |
|
||||
| Class drivers | 6 working (acm 133, ecm 261, audio 308, HID, storage, hub) | 80+ drivers | ~75 missing |
|
||||
| Hub driver lines | 249 | 6,567 (hub.c) | ~95% gap |
|
||||
| Hub driver lines | ~700 (usbhubd + port_ops) with Linux state machine | 6,567 (hub.c) | Enumeration core done (P3-A); interrupt EP/LED/TT gaps |
|
||||
| xHCI quirks | 51 flags + ~85-entry canonical table (redox-driver-sys, P2-A); ~40 check sites in xhcid | 51 quirks | ✅ Done |
|
||||
| Error recovery | All 36 codes with active recovery (P2-C core ✅); runtime injection tests open | Babble, transaction error, split error, clear-TT | Core done; validation gap |
|
||||
| Power management | HW LPM substrate + U3 gate + PORTPMSC helpers (P2-B); per-device LPM, U1/U2, autosuspend missing | Runtime PM, U1/U2, LPM, autosuspend | Core missing |
|
||||
@@ -316,31 +316,60 @@ stall injection, 10k random disconnects without panic).
|
||||
|
||||
**Why this matters:** The current usbhubd is 249 LoC doing basic port-change detection. Linux hub.c is 6,567 lines doing full enumeration. The gap is 95%.
|
||||
|
||||
### P3-A: Full enumeration sequence
|
||||
### P3-A: Full enumeration sequence ✅ CORE COMPLETE (2026-07-18)
|
||||
|
||||
**Reference:** `local/reference/linux-7.1/drivers/usb/core/hub.c:1449` `hub_configure()` and `hub_port_connect()`.
|
||||
|
||||
**Tasks:**
|
||||
**Status:** usbhubd (now ~700 LoC incl. `port_ops.rs`) implements the full
|
||||
Linux port state machine with injected-side-effect, unit-tested ops
|
||||
(14 tests). Enumeration of hub-attached devices remains delegated to
|
||||
xhcid's `attach_device()` — architecturally correct (xhcid owns slot
|
||||
allocation/addressing for root and hub ports alike).
|
||||
|
||||
1. Read hub descriptor (already done — `HubDescriptorV2` / `HubDescriptorV3`).
|
||||
2. Power-on delay: `bPwrOn2PwrGood * 2ms` (USB 2.0 spec §7.1.6.1).
|
||||
3. USB 3.0 hub initial state: wait for polling → U0 (tPollingLFPSTimeout = 360ms, polled 10×36ms).
|
||||
4. Per-port enumeration:
|
||||
- Reset signaling (USB 2 ≥10ms, USB 3 warm reset with PORT_WR)
|
||||
- Wait for reset completion
|
||||
- Read device descriptor (8 bytes → full 18 bytes)
|
||||
- Set address
|
||||
- Read configuration descriptors
|
||||
- Configure endpoints
|
||||
5. Hub-specific class requests for USB 3 hubs:
|
||||
- `HUB_SET_DEPTH` (request 0x0C) — set hub tier depth
|
||||
6. `wHubDelay` accumulation through the TT path (for split-transaction scheduling).
|
||||
**Implemented (Linux hub.c equivalence):**
|
||||
|
||||
**Linux cross-reference:** `hub.c:1497-1521` for wHubDelay; `hub.c:3000-3300` for the full port-connect path.
|
||||
1. ✅ Hub descriptor read (V2/V3) — pre-existing. **Fixed:** `HubDescriptorV3`
|
||||
now reads the full 12-byte SS descriptor including `device_removable: u16`
|
||||
(spec Table 10-15; previously under-read by 2 bytes; SS descriptors have
|
||||
no PortPwrCtrlMask — stale TODO comment corrected). Non-removable ports
|
||||
logged at startup.
|
||||
2. ✅ Power-on delay `max(bPwrOn2PwrGood * 2ms, 100ms)` — pre-existing,
|
||||
verified vs `hub_power_on_good_delay()` (hub.h:165-173).
|
||||
3. ✅ USB 3.0 polling→U0 wait (`port_ops::wait_for_u0`) — after port
|
||||
power-on, poll link state every 36 ms until out of Polling(7), 400 ms
|
||||
ceiling (tPollingLFPSTimeout = 360 ms; Linux hub.c:1226 debounce path).
|
||||
4. ✅ Per-port enumeration:
|
||||
- Reset signaling + **completion wait** (`port_ops::wait_for_reset`) —
|
||||
Linux `hub_port_wait_reset()` (hub.c:2953-3047): 10 ms polls until
|
||||
RESET clears with CONNECTION set, escalate to 200 ms after two short
|
||||
waits, 800 ms budget; then 50 ms TRSTRCY recovery (hub.c:3159) and
|
||||
C_PORT_RESET clear. **Replaces** the previous bare `sleep(10ms)`.
|
||||
- **Debounce** (`port_ops::debounce_until_connected`) — Linux
|
||||
`hub_port_debounce_be_connected()` (hub.c:4696-4737): 25 ms polls,
|
||||
connection stable for 100 ms, 2 s budget, change bit cleared in-loop.
|
||||
- **Change-bit hygiene** — C_PORT_CONNECTION (debounce), C_PORT_RESET
|
||||
(reset-wait), C_PORT_ENABLE (post-handling) all cleared per Linux
|
||||
`port_event()` semantics; over-current recovery preserved.
|
||||
- Address/descriptor/configuration — via xhcid `attach_device()`
|
||||
(enable slot → address device → descriptors → driver spawn), the
|
||||
same path as root-hub ports.
|
||||
5. ✅ `HUB_SET_DEPTH` (0x0C) for USB 3 hubs — pre-existing.
|
||||
6. ✅ `wHubDelay` chain accumulation — `port_ops::accumulate_hub_delay_ns`
|
||||
(Linux hub.c:1507-1519: `wHubDelay + parent->hub_delay + 40ns`, cap
|
||||
65535 ns). usbhubd walks the PortId ancestor chain fetching ancestor
|
||||
V3 hub descriptors, then delivers the result to each newly attached
|
||||
SuperSpeed child via `SET_ISOCH_DELAY` (USB 3.0 §9.4.11; Linux
|
||||
message.c:1142-1158 — hubs and non-SS skipped; children inherit the
|
||||
hub's accumulated delay verbatim per hub.c:5128-5129).
|
||||
|
||||
**Files:** `local/sources/base/drivers/usb/usbhubd/src/main.rs`
|
||||
**Remaining (documented follow-ups):** USB 2.0 `device_removable`/
|
||||
`PortPwrCtrlMask` variable-length bitmaps unparsed (separate fetch needed);
|
||||
SS.Inactive warm-reset recovery loop (hub.c:5841-5868); multi-TT switching;
|
||||
U1/U2 LPM on hub ports (P7); interrupt-EP usage on USB 3 hubs without one
|
||||
(polling fallback works).
|
||||
|
||||
**Exit:** complete hub enumeration including power timing, USB 3 hub handling, and TT accumulation.
|
||||
**Exit met:** complete hub enumeration including power timing, USB 3 hub
|
||||
handling, and TT accumulation.
|
||||
|
||||
### P3-B: Hub interrupt-driven change detection
|
||||
|
||||
|
||||
+1
-1
Submodule local/sources/base updated: 260003331e...bd379e0771
Reference in New Issue
Block a user