From bfd56bac7ef9b2e6060467598c46fa2144d5a347 Mon Sep 17 00:00:00 2001 From: vasilito Date: Sun, 19 Jul 2026 00:28:29 +0900 Subject: [PATCH] =?UTF-8?q?usb:=20P3-A=20complete=20=E2=80=94=20Linux=20hu?= =?UTF-8?q?b.c=20enumeration=20state=20machine=20in=20usbhubd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- local/docs/HARDWARE-VALIDATION-MATRIX.md | 7 ++- local/docs/USB-IMPLEMENTATION-PLAN.md | 67 +++++++++++++++++------- local/sources/base | 2 +- 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/local/docs/HARDWARE-VALIDATION-MATRIX.md b/local/docs/HARDWARE-VALIDATION-MATRIX.md index 3e6465bc3c..0e2ef1e11d 100644 --- a/local/docs/HARDWARE-VALIDATION-MATRIX.md +++ b/local/docs/HARDWARE-VALIDATION-MATRIX.md @@ -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 | diff --git a/local/docs/USB-IMPLEMENTATION-PLAN.md b/local/docs/USB-IMPLEMENTATION-PLAN.md index d4cea51ec5..886e973fe2 100644 --- a/local/docs/USB-IMPLEMENTATION-PLAN.md +++ b/local/docs/USB-IMPLEMENTATION-PLAN.md @@ -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 diff --git a/local/sources/base b/local/sources/base index 260003331e..bd379e0771 160000 --- a/local/sources/base +++ b/local/sources/base @@ -1 +1 @@ -Subproject commit 260003331ed78736a033b3dce645c36935a1e0be +Subproject commit bd379e0771e7cfffdf2b74ccee207d3195a0544a