Files
RedBear-OS/local/docs/USB-IMPLEMENTATION-PLAN.md
T
vasilito 1bc5f8ac88 docs: USB v3 plan + runbook — first-class-citizen roadmap
v3 USB-IMPLEMENTATION-PLAN supersedes v2 (archived).  Comprehensive
audit-driven roadmap with 9 phases (P1–P9) to make USB a first-class
citizen in Red Bear OS:

  P1: Trait unification (all 4 controllers implement UsbHostController)
      + panic hardening (usbscsid 0 panics, xhcid <20 unwraps)
      + remove 3 empty stubs (usbaudiod, acmd, ecmd)
  P2: xHCI core — 51-quirk table, HCCPARAMS2 parsing, 36-code error
      recovery (babble, transaction error, stall, split)
  P3: Hub driver — full enumeration (wHubDelay, power timing, USB 3 SS)
      + interrupt-driven change detection + port LED
  P4: Storage — UAS protocol, multi-LUN, SYNCHRONIZE_CACHE, UNMAP, mass-storage
      quirks applied at runtime
  P5: HID — report descriptor parser, usage→evdev mapping, LED sync, quirks,
      multi-touch
  P6: Class driver completeness — CDC ACM, CDC NCM, USB Audio, USB-serial
      (FTDI/CP210x/PL2303/CH341), compliance test driver
  P7: Power management — USB 2.0 LPM, USB 3.0 U1/U2/U3, runtime PM autosuspend
  P8: Validation — hardware matrix ≥10 rows + 6 new QEMU scripts
      + error-injection tests
  P9: Modern USB scope ADR (host-only; already written in v2 §12)

Linux 7.1 is the implementation of excellence — every feature has a
concrete cross-reference (file:line) and a 'port line-by-line' strategy
when implementation detail is in doubt.

USB-VALIDATION-RUNBOOK v3 replaces v2 (archived): test matrix with
per-phase exit gates, operator runbook for failures.

Stale items cleared:
  - v2 active plan archived as USB-IMPLEMENTATION-PLAN-v2-2026-07.md
  - v2 active runbook archived as USB-VALIDATION-RUNBOOK-2026-07.md
  - archived/README.md supersession table extended
2026-07-07 05:21:35 +03:00

696 lines
32 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Red Bear OS USB Plan — v3
> **Status:** Canonical. Replaces v1 (archived `archived/USB-IMPLEMENTATION-PLAN-v1-2026-04.md`) and v2 (archived `archived/USB-IMPLEMENTATION-PLAN-v2-2026-07.md`).
> **Date:** 2026-07-07.
> **Goal:** Make USB a first-class citizen in Red Bear OS — mature, reliable, feature-complete host stack matching the user-visible capability of Linux 7.1.
## 0. Scope and method
This plan is the comprehensive roadmap for Red Bear OS USB. It is built from three sources:
1. **Code audit (v2 era, 2026-07-07):** every USB source file enumerated; TODOs, unwraps, and panic sites catalogued; maturity assessed per component.
2. **Linux 7.1 reference deep-dive:** `local/reference/linux-7.1/drivers/usb/` mapped feature-by-feature against Red Bear. Linux is treated as the implementation of excellence — structures, sequences, and edge-case handling are cross-referenced and reimplemented in Rust as needed.
3. **Upstream Redox commit scan:** 33 USB-relevant upstream commits (Jan 2025 May 2026) tracked; 28 already adopted, 4 needing verification, 1 outstanding.
### Validation labels
- **builds** — code is in tree and compiles.
- **enumerates** — runtime surfaces can discover controllers, ports, descriptors.
- **usable-narrow** — one controller family / one class family works in a bounded scenario.
- **validated-QEMU** — a documented QEMU script passed on the matching recipe, config, and commit.
- **validated-hardware** — a named physical controller + class, with a captured log, on real bare metal.
- **experimental** — present for bring-up but not in any support-promised path.
### Linux 7.1 as the implementation of excellence
Where the v2 plan referenced Redox upstream commits, v3 references **Linux 7.1** as the canonical reference. When implementation detail is in doubt:
1. Check Linux 7.1 first.
2. If Linux has the algorithm, port it to Rust line-by-line (preserving the data structure layouts).
3. If Linux has multiple approaches (e.g., kernel vs. userspace), use the userspace model since Red Bear's USB drivers are all userspace.
4. Cite the Linux source file:line in commit messages.
## 1. Executive summary — gap analysis
| Dimension | Red Bear | Linux 7.1 | Gap |
|---|---|---|---|
| Total USB source lines | ~13,000 | ~280,000+ | ~22× |
| Host controllers with real implementations | 1 (xhcid) | 4 (xHCI, EHCI, UHCI, OHCI) | 3 missing |
| Host controllers building | 3 (ehcid, uhcid, ohcid) | — | — |
| 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 | 3 working + 3 empty stubs | 80+ drivers | ~75 missing |
| Hub driver lines | 249 | 6,567 (hub.c) | ~95% gap |
| xHCI quirks | 0 | 51 quirks | **CRITICAL** |
| Error recovery | Stall only | Babble, transaction error, split error, clear-TT | ~90% gap |
| Power management | None | Runtime PM, U1/U2, LPM, autosuspend | All missing |
| Hardware validation matrix | 0 entries | ~200 known-good controllers | All missing |
### P0 — already done (carried from v2)
P0 is complete and committed:
- **P0-A1** xHCI interrupts re-enabled (base fork `cbd40e0d`)
- **P0-A2** Reset fix verified in 0.1.0 baseline
- **P0-A3** CSZ cleanup (removed stale TODO, base fork `7cfed158`)
- **P0-A4** Bounds check on `root_hub_port_index()` (base fork `774a0ac1`)
- **P0-B1** EHCI auto-spawn + xhcid-compat scheme (ehcid + usb-core)
- **P0-B2** UHCI + OHCI real drivers (459 + 280 LoC, compile clean)
### Architectural goal
The single architectural goal of v3: **every host controller implements `usb_core::UsbHostController`** and registers under the same scheme namespace. Currently only `ehcid` implements the trait; `xhcid`, `uhcid`, `ohcid` each have ad-hoc scheme implementations. Unifying these is the prerequisite for every other improvement in v3.
### Critical risks (unconditional stop-ship)
Three risks make Red Bear USB unsupportable today. They MUST be fixed before any further phase:
1. **usbscsid has 12 `panic!()` calls in hot path.** A USB stick disconnect during transfer crashes the entire system. Must convert all to `Result` returns.
2. **xhcid has ~125 panic sites / unwrap() / expect() calls.** Mutex poison panic = full kernel panic. Most are fixable with proper error propagation.
3. **3 class drivers are 32-line stubs** (`redbear-usbaudiod`, `redbear-acmd`, `redbear-ecmd`) that print "not yet implemented" and exit. They are wired in configs but do nothing — dead weight in every image.
## 2. Phase roadmap
| Phase | Goal | Exit criteria |
|---|---|---|
| **P1** | Trait unification + panic hardening | All 4 controllers implement `UsbHostController`; usbscsid 0 panic sites; xhcid <20 unwraps |
| **P2** | xHCI core completeness | Quirk table populated; HCCPARAMS2 parsed; error recovery for babble/transaction/stall/split |
| **P3** | Hub driver maturity | Full enumeration sequence; USB 3.0 SS hub support; port power/reset timing; wHubDelay accumulation |
| **P4** | Storage: UAS + multi-LUN | UAS protocol implementation; multi-LUN dispatch; SYNCHRONIZE_CACHE; WRITE SAME/UNMAP |
| **P5** | HID: report descriptor parser + input mapping | Full HID report descriptor parser; usage→evdev mapping; HID quirks; multi-touch support |
| **P6** | Class driver completeness | CDC ACM; CDC NCM; USB Audio; remove the 3 empty stubs |
| **P7** | Power management | USB 2.0 LPM; USB 3.0 U1/U2/U3; runtime PM autosuspend; xHCI link state management |
| **P8** | Validation: hardware matrix + QEMU harness expansion | Hardware-validation matrix with one row per controller; new QEMU tests for OHCI/UHCI/EHCI; error-injection tests |
| **P9** | Modern USB scope ADR (inherited from v2 §12) | Decided: host-only. Already written. |
---
## 3. P1 — Trait unification and panic hardening
**Why first:** Without a unified trait, every later phase has to write per-controller glue. Panic hardening is unconditional — the system cannot ship with mass-storage and xHCI crashes.
### P1-A: All four controllers implement `usb_core::UsbHostController`
**Reference:** `local/reference/linux-7.1/drivers/usb/core/hcd.c` (Host Controller Driver framework, 3,194 lines) and `drivers/usb/host/` (4 host drivers, all conforming to a shared `struct hc_driver`).
Current state:
| Controller | Trait | Scheme | Status |
|---|---|---|---|
| xhcid | ❌ | own scheme.rs | ad-hoc |
| ehcid | ✅ | redox-scheme::SchemeSync | good template |
| uhcid | ❌ | none | enum-only |
| ohcid | ❌ | none | enum-only |
**Tasks:**
1. **Define unified scheme path:** `usb-core::SCHEME_NAMESPACE = "usb.<pci_name>_<controller_name>"` (xhcid-style). All controllers register under this namespace.
2. **Refactor xhcid's `scheme.rs`** to satisfy `UsbHostController` trait. The trait's `control_transfer` / `bulk_transfer` / `interrupt_transfer` delegate to existing xhcid scheme handlers.
3. **Add scheme registration to uhcid and ohcid** using the same pattern. Their existing in-guest enumeration stays; we add a `SchemeSync` server under the new namespace.
4. **Replace ad-hoc class spawn** in all four controllers with `usb-core::spawn::spawn_class_driver_for_port`. Class daemons open the namespace from the controller's `scheme_name`.
**Files to touch:**
- `local/sources/base/drivers/usb/xhcid/src/xhci/scheme.rs` (refactor)
- `local/recipes/drivers/uhcid/source/src/main.rs` (add scheme)
- `local/recipes/drivers/ohcid/source/src/main.rs` (add scheme)
- `local/recipes/drivers/usb-core/source/src/scheme.rs` (extend trait if needed)
**Linux 7.1 cross-reference:** `drivers/usb/core/hcd.c:1700` `usb_create_hcd()` — uniform scheme-name pattern `bus_name-hcd_name`. Adapt for Redox's scheme namespace.
**Exit:** all four controllers implement the trait; class daemons can connect to all four via the same scheme.
### P1-B: usbscsid panic hardening
**Reference:** `local/reference/linux-7.1/drivers/usb/storage/transport.c` (1,462 lines) and `drivers/usb/core/urb.c` (1,021 lines). Linux USB storage never panics on stall — it returns `-EPIPE`, `-ETIME`, `-EIO`, etc.
**Files to touch:** `local/sources/base/drivers/storage/usbscsid/src/`
**Tasks:**
1. Replace every `panic!()` in `protocol/bot.rs` (12 sites) with `return Err(...)` or `bail!()`.
2. Each panic site maps to a specific failure mode. Audit each one:
- CBW send failure → `Err(StorageError::CommandBlockError)`
- Data-phase stall → `Err(StorageError::Stall)` (don't kill the daemon)
- CSW parse error → `Err(StorageError::InvalidStatusWrapper)`
- Mass storage reset → call `usbscsid::reset_port()` instead of panicking
3. Replace `mod uas { // TODO }` stub with either a real UAS implementation (see P4) or a clean `unimplemented!()` that returns `Err(UasError::NotSupported)`.
4. Add `#[derive(Debug, thiserror::Error)]` for all error types — no string-based panic messages.
**Exit:** `cargo check` passes; `grep -c panic!()` on the usbscsid tree returns 0.
### P1-C: xhcid panic reduction
**Reference:** `local/reference/linux-7.1/drivers/usb/host/xhci.c` — uses `dev_err()`, `dev_warn()`, and explicit `return -EINVAL` for every error path. Linux xhci never panics in normal operation.
**Files to touch:** `local/sources/base/drivers/usb/xhcid/src/xhci/`
**Tasks:**
1. Replace each `.unwrap()` on Mutex locks with `.lock().unwrap_or_else(|e| e.into_inner())` — already done in some sites; complete across the tree.
2. Replace each `.expect()` with explicit error logging + fallible helper functions.
3. Remove the 5 explicit `panic!()` calls in hot paths:
- `irq_reactor.rs:31``Failed to received an enumeration request!` → log error + return
- `irq_reactor.rs:71``No XHCI controllers found` → log error + abort init cleanly
- `irq_reactor.rs:620``Polling finished EventTrbFuture again` → log warning + skip
- `irq_reactor.rs:672/703/731``Invalid TRB type` → log error + corrupt-ring recovery
- `scheme.rs:2011``unreachable` HandleKind → log error + return EBADF
4. Convert `mod.rs:694` `TODO handle the second unwrap` and similar known-fragile sites.
**Target:** ≤20 unwrap/expect total in xhcid (down from ~125).
**Exit:** `grep -c 'panic!\|\\.unwrap()\|\\.expect(' local/sources/base/drivers/usb/xhcid/src/xhci/*.rs` ≤20.
### P1-D: Remove the 3 empty stubs
**Files:**
- `local/recipes/system/redbear-usbaudiod/` (32 LoC stub)
- `local/recipes/system/redbear-acmd/` (32 LoC stub)
- `local/recipes/system/redbear-ecmd/` (32 LoC stub)
**Task:** Either implement them properly (see P6 for class driver work) or remove them from the configs. Stub classes inflate image size and mislead operators about USB capability.
---
## 4. P2 — xHCI core completeness
**Why this matters:** The 51-entry xHCI quirk table in Linux is the difference between "works on QEMU" and "works on real hardware." Without quirks, xhcid will silently misbehave on Intel, AMD, NEC, ASMedia, Etron, Cadence, and Fresco Logic controllers.
### P2-A: xHCI quirk table
**Reference:** `local/reference/linux-7.1/drivers/usb/host/xhci.h:1587-1649` (51 quirk flags).
**Tasks:**
1. Define a `XhciQuirks` bitflags struct in `xhcid/src/xhci/mod.rs` matching the Linux 51-entry enum.
2. Implement a per-controller quirk probe: read `PCI_VENDOR_ID` + `PCI_DEVICE_ID`, look up in a quirk table keyed by `{vendor, device}`.
3. Implement the behavior change for each quirk. Reference: `drivers/usb/host/xhci-pci.c:600+` `xhci_pci_quirks()`.
4. Start with the highest-priority quirks:
- `XHCI_RESET_TO_DEFAULT` — all xhci drivers should program MaxSlotsEn = 1 on reset
- `XHCI_LPM_SUPPORT` — Intel Panther Point and later
- `XHCI_BROKEN_STREAMS` — disable streams on affected controllers
- `XHCI_WRITE_64_HI_LO` — write 64-bit registers high-then-low on AMD
- `XHCI_ZERO_64B_REGS` — read 32-bit only on old hardware
- `XHCI_DEFAULT_PM_RUNTIME_ALLOW` — enable runtime PM by default on Intel
5. Wire quirk flags into all relevant code paths: reset, run, MSI-X allocation, streams, ring sizing, error recovery.
**Linux cross-reference:** `xhci-pci.c:617-900` lists the per-controller quirk table. Translate to a Rust match expression.
**Files:** `xhcid/src/xhci/quirks.rs` (new), `xhcid/src/xhci/mod.rs`, `xhcid/src/xhci/pci_quirks.rs` (new).
**Exit:** per-controller quirk probe running at init; quirk-aware behavior in 5+ paths.
### P2-B: HCCPARAMS2 parsing (xHCI 1.1+ features)
**Reference:** `local/reference/linux-7.1/drivers/usb/host/xhci-caps.h:94-119`
13 HCCPARAMS2 bits enable U3 entry, extended TBC, eUSB2, etc. Current xhcid reads only HCCPARAMS1.
**Tasks:**
1. Read and cache `HCSPARAMS2` and `HCCPARAMS2` in `capability.rs`.
2. Define bitflags for each of the 13 capabilities.
3. Gate xHCI 1.1+ features on these bits:
- `HCC2_U3C` — U3 Entry Capability
- `HCC2_CMC` — Configure Endpoint Max Exit Latency Too Large
- `HCC2_LEC` — Large ESIT Payload (>48KB)
- `HCC2_CIC` — Configuration Information Capability (used for Set Latency Tolerance)
4. Extended port capabilities from `xhci-ext-caps.h:62-66`: `XHCI_L1C`, `XHCI_HLC`, `XHCI_BLC` for LPM.
**Exit:** HCCPARAMS2 parsed; 3+ features gated on it.
### P2-C: Error recovery
**Reference:** `local/reference/linux-7.1/drivers/usb/host/xhci-ring.c` (4,472 lines), specifically `handle_tx_event()` for the 36 completion codes.
**Tasks:**
1. Extend `TrbCompletionCode` handling from 3 codes (Success, ShortPacket, Stall) to all 36.
2. For each error code, implement recovery:
- `COMP_STALL_ERROR` → endpoint halt + clear-stall control transfer + retry
- `COMP_DATA_BUFFER_ERROR` → re-queue transfer with new DMA mapping
- `COMP_BABBLE_DETECTED_ERROR` → reset endpoint + check port disable
- `COMP_USB_TRANSACTION_ERROR` → retry up to 3 (per `MAX_SOFT_RETRY`)
- `COMP_TRB_ERROR` → log + fatal to upper layer
- `COMP_RESOURCE_ERROR` → re-queue later
- `COMP_SPLIT_TRANSACTION_ERROR` → call Clear-TT-Buffer on parent hub
3. Track retry counts in `Urb` struct. Reference: `xhci-ring.c:1700+` `xhci_urb_request()`.
**Linux cross-reference:** `xhci-ring.c:1700-1900` `xhci_handle_completion()` — the canonical error-handling function.
**Exit:** 36 completion codes handled with appropriate recovery.
---
## 5. P3 — Hub driver maturity
**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
**Reference:** `local/reference/linux-7.1/drivers/usb/core/hub.c:1449` `hub_configure()` and `hub_port_connect()`.
**Tasks:**
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).
**Linux cross-reference:** `hub.c:1497-1521` for wHubDelay; `hub.c:3000-3300` for the full port-connect path.
**Files:** `local/sources/base/drivers/usb/usbhubd/src/main.rs`
**Exit:** complete hub enumeration including power timing, USB 3 hub handling, and TT accumulation.
### P3-B: Hub interrupt-driven change detection
**Reference:** `linux-7.1/drivers/usb/core/hub.c:1000+` `hub_irq()`.
Current usbhubd polls at 100ms intervals. Linux uses hub interrupt endpoints (`USB_ENDPOINT_DIR_IN` + `USB_USAGE_TYPE_INTERRUPT`) for immediate change notification.
**Tasks:**
1. Add interrupt endpoint configuration to usbhubd (USB hub interrupt endpoint is always EP1).
2. Subscribe to interrupt IN transfers for status change bitmap.
3. Fall back to polling only when interrupt endpoint is unavailable.
**Exit:** interrupt-driven on USB 2 hubs; polling fallback on USB 3 hubs (which lack interrupt endpoints).
### P3-C: Port LED control
**Reference:** `linux-7.1/drivers/usb/host/xhci-port.h:64-67` (PORT_LED_OFF/AMBER/GREEN).
**Tasks:**
1. Expose hub port LED control via `SET_HUB_FEATURE(PORT_INDICATOR)`.
2. Implement in usbhidd keyboard LED sync (cross-couple with P5-C).
**Exit:** port LEDs controllable via scheme.
---
## 6. P4 — Storage: UAS + multi-LUN + SAT
**Why this matters:** BOT alone limits USB 3.0 storage to ~30-40 MB/s. UAS unlocks 350+ MB/s. Multi-LUN is needed for card readers. SYNCHRONIZE_CACHE / UNMAP are needed for SSD correctness and TRIM.
### P4-A: UAS protocol
**Reference:** `local/reference/linux-7.1/drivers/usb/storage/uas.c` (1,304 lines).
UAS uses 4 endpoints (cmd BULK OUT, status BULK IN, data-in BULK IN, data-out BULK OUT) and Information Units (Command IU, Sense IU, Response IU).
**Tasks:**
1. Detect UAS interface (interface class 0x08, subclass 0x04, protocol 0x62 for UAS; 0x50 for BOT).
2. Implement the 4-endpoint setup in usbscsid.
3. Implement Command IU submission (32-byte structured).
4. Implement Sense IU / Response IU parsing.
5. Wire to xHCI streams (P2 prerequisite): UAS needs streams for true concurrent commands.
**Files:** `local/sources/base/drivers/storage/usbscsid/src/protocol/uas.rs` (new).
**Linux cross-reference:** `uas.c:35-74` struct definitions; `uas.c:600-900` command submission.
**Exit:** UAS path functional, fallback to BOT for non-UAS devices.
### P4-B: Multi-LUN dispatch
**Reference:** `linux-7.1/drivers/usb/storage/usb.c:1258` (`usb_stor_scan_thread()`).
**Tasks:**
1. Extend SCSI dispatch to iterate LUN 0..max_lun.
2. REPORT_LUNS opcode handling — list of LUNs available.
3. Per-LUN device state — each LUN gets its own BlockDevice.
**Files:** `local/sources/base/drivers/storage/usbscsid/src/scsi/cmds.rs`, `scsi/mod.rs`.
**Exit:** 4-slot card reader enumerates as 4 separate block devices.
### P4-C: SYNCHRONIZE_CACHE / WRITE SAME / UNMAP
**Reference:** `linux-7.1/drivers/scsi/sd.c` (sd driver issues these).
**Tasks:**
1. Add `SYNCHRONIZE_CACHE(10)` and `SYNCHRONIZE_CACHE(16)` opcodes to `scsi/opcodes.rs`.
2. Add `WRITE_SAME(10/16)` and `UNMAP` opcodes.
3. Dispatch them in `scsi/cmds.rs` to the BOT transport.
**Exit:** SSD TRIM works, data integrity on disconnect improves.
### P4-D: Mass-storage quirks integration
**Reference:** `linux-7.1/drivers/usb/storage/unusual_devs.h` (2,513 lines, 323 entries).
**Current state:** Red Bear has 214 mass-storage quirks extracted from `unusual_devs.h`. Verify they're loaded at runtime and applied during enumeration.
**Tasks:**
1. Verify `usb-core::spawn::class_driver_for_usb_class()` for mass storage (0x08).
2. Add runtime quirk lookup: when usbscsid enumerates a device, look up its VID:PID in the quirk table, apply `IGNORE_RESIDUE`, `FIX_CAPACITY`, `SINGLE_LUN`, `MAX_SECTORS_64`, etc.
3. Implement the runtime application in `usbscsid/src/main.rs` at the `read_capacity()` and `read_write()` paths.
**Exit:** quirks applied at enumeration; redbear-usb-storage-check verifies a quirk-affected device behaves correctly.
---
## 7. P5 — HID: report descriptor parser + input mapping
**Why this matters:** usbhidd at 566 LoC only handles boot-protocol keyboard/mouse. Linux's `hid-core.c` (3,228 LoC) + `hid-input.c` (2,454 LoC) together handle every HID device class. The gap blocks touchscreens, gamepads (partially), consumer keys, and every non-trivial mouse/keyboard.
### P5-A: HID report descriptor parser
**Reference:** `local/reference/linux-7.1/drivers/hid/hid-core.c:1273` `hid_open_report()`.
**Tasks:**
1. Implement a full HID Report Descriptor parser in a new crate `local/recipes/drivers/redbear-hid-core/source/src/lib.rs`:
- `ReportDescriptor` struct: tree of `UsagePage`, `Usage`, `Collection` (Application/Physical/Logical), `Field` (Input/Output/Feature with bit fields), `Report` (with report IDs and sizes).
2. Parse the main item types: `Usage Page`, `Usage`, `Logical Minimum/Maximum`, `Report Size`, `Report Count`, `Report ID`, `Push/Pop`, `Collection/End Collection`.
3. Output a tree that other HID drivers can walk.
**Files:** new crate `local/recipes/drivers/redbear-hid-core/`.
**Exit:** parses a Logitech mouse descriptor correctly into a structured tree.
### P5-B: HID input mapping (usages → evdev)
**Reference:** `local/reference/linux-7.1/drivers/hid/hid-input.c:1244` `hidinput_configure_usage()`.
**Tasks:**
1. Implement usage → input event mapping table:
- Generic Desktop 0x01: X/Y/Wheel → ABS_X/ABS_Y/REL_WHEEL
- Keyboard 0x07: a/A/Enter/etc → KEY_A/KEY_A/KEY_ENTER
- Button 0x09: mouse buttons → BTN_MOUSE/BTN_LEFT
- LED 0x08: keyboard LEDs
- Consumer 0x0C: Mute/Volume → KEY_MUTE/KEY_VOLUMEUP
- Digitizer 0x0D: Touch/Position → BTN_TOUCH/ABS_MT_POSITION_X
2. Wire to `redbear-inputd` via evdev events (or whatever input daemon we use).
3. Switch from Orbital KeyEvent protocol to evdev for unified input.
**Linux cross-reference:** `hid-input.c:140-200` (the usage→keycode mapping table).
**Exit:** media keys, gamepad buttons, and touchpad gestures work via USB HID.
### P5-C: LED sync
**Reference:** `local/reference/linux-7.1/drivers/hid/hid-input.c:317` `hidinput_output_event()` (Caps Lock → LED report).
**Tasks:**
1. usbhidd: after boot completion, send `SET_REPORT` to set Caps Lock / Num Lock / Scroll Lock LED state.
2. Wire to `redbear-inputd` LED state events.
3. For both USB HID boot protocol and report protocol.
**Exit:** Caps Lock LED on a USB keyboard actually lights up when toggled.
### P5-D: HID quirks
**Reference:** `local/reference/linux-7.1/drivers/hid/hid-quirks.c` (1,397 lines, ~200 device quirks).
**Tasks:**
1. Add HID quirks table in `redbear-hid-core`.
2. Per-device VID:PID overrides: `HID_QUIRK_NOTOUCH`, `HID_QUIRK_NO_INIT_REPORTS`, `HID_QUIRK_NOGET`, `HID_QUIRK_MULTI_INPUT`, etc.
3. Apply at `usbhidd` enumeration time.
**Exit:** Logitech Unifying receivers, Apple Magic Mouse, and Surface keyboards all work.
### P5-E: Multi-touch
**Reference:** `local/reference/linux-7.1/drivers/hid/hid-multitouch.c` (2,756 lines).
**Tasks:**
1. Detect multi-touch class (Usage Page 0x0D).
2. Implement slot-based protocol (Type B) and report-based protocol (Type A).
3. Forward ABS_MT_POSITION_X, ABS_MT_POSITION_Y, ABS_MT_SLOT, BTN_TOUCH to `inputd`.
**Exit:** a USB touchscreen or touchpad produces touch events.
---
## 8. P6 — Class driver completeness
**Why this matters:** Red Bear has 6 class drivers, of which only 3 work (usbhubd, usbhidd, usbscsid). The other 3 are 32-line stubs. Plus we're missing CDC NCM (ethernet), USB Audio, USB-serial, and others.
### P6-A: CDC ACM (remove the stub)
**Reference:** `local/reference/linux-7.1/drivers/usb/class/cdc-acm.c` (2,186 lines).
**Files:** `local/recipes/system/redbear-acmd/` (currently stub).
**Tasks:**
1. Implement a real CDC ACM class driver (`redbear-cdc-acmd` or just keep the name and add code).
2. Line coding: baud rate, parity, stop bits, data bits.
3. Flow control: RTS/CTS, DTR/DSR via control transfers.
4. Break signaling.
5. Multi-port modems (data + control + notification interfaces).
6. Expose `/scheme/tty` for userspace clients (replacing the stub `redbear-acmd` admin CLI).
**Exit:** an FTDI USB-serial adapter or Arduino appears as a TTY device.
### P6-B: CDC NCM (Ethernet over USB)
**Reference:** `linux-7.1/drivers/net/usb/cdc_ncm.c` (in `drivers/net/usb/`).
**Tasks:**
1. Detect CDC NCM interface (subclass 0x0D).
2. NTB (Network Transfer Block) framing.
3. Aggregate frames into NTBs for efficiency.
4. Wire to the netstack as a new interface.
**Exit:** a USB-Ethernet adapter (e.g., a phone-tethered device) works.
### P6-C: USB Audio
**Reference:** `local/reference/linux-7.1/sound/usb/` (USB audio class driver, ~5,000 lines).
`redbear-usbaudiod/` is currently a 32-line stub. Replace with a real USB Audio Class 1.0 driver:
**Tasks:**
1. Detect AudioControl interface + AudioStreaming interface.
2. Parse Audio Control descriptors (unit IDs, terminals, mixer units).
3. Configure audio streaming endpoint (alternate settings, packet size, format).
4. Isochronous transfer ring setup (xHCI isoch — new code path).
5. PCM playback/capture path to `redbear-audiod`.
**Exit:** USB headphones / headset produce audio.
### P6-D: USB-serial (top 5 drivers)
**Reference:** `linux-7.1/drivers/usb/serial/` (56 .c files).
For v3, implement only the top 5 most common USB-serial chip families:
1. **FTDI** (`ftdi_sio.c`, 3,176 lines) — FT232, FT2232, FT4232
2. **CP210x** (`cp210x.c`, 753 lines) — Silicon Labs CP2102/CP2104
3. **PL2303** (`pl2303.c`, 615 lines) — Prolific PL2303
4. **CH341** (`ch341.c`, 583 lines) — QinHeng CH341
5. **CDC-ACM subset** (covered by P6-A)
**Exit:** common USB-serial adapters work.
### P6-E: USB compliance test driver
**Reference:** `linux-7.1/drivers/usb/misc/usbtest.c` (3,079 lines).
A `redbear-usbtest` tool that exercises:
- Bulk IN/OUT loopback with pattern verification
- Control endpoint round-trip
- Interrupt endpoint reception
- Isochronous endpoint loopback
- Halt/reset recovery
**Exit:** USB protocol compliance can be validated in-tree.
---
## 9. P7 — Power management
**Why this matters:** Without PM, USB devices draw full power forever, draining laptop batteries and overheating peripherals. Linux's PM framework handles U1/U2/U3/LPM/autosuspend.
### P7-A: USB 2.0 LPM
**Reference:** `linux-7.1/drivers/usb/host/xhci-port.h:135-173`, `xhci-hub.c`.
**Tasks:**
1. Parse `HCCPARAMS1.HLC` (Hardware LPM Capability).
2. Implement `usb_set_device_initiated_lpm()` (port hardware LPM control via PORTSC.PORT_L1DEV).
3. xhcid: implement `PORT_HLE` enabling per port.
4. ehcid: implement via USBCMD.HIRD (Host Initiated Resume Duration).
**Exit:** USB 2.0 devices on HWA LPM-capable hubs enter L1 state when idle.
### P7-B: USB 3.0 U1/U2/U3
**Reference:** `linux-7.1/drivers/usb/host/xhci-port.h:17-30`, `xhci.c:2800+` `xhci_stop_device()`.
**Tasks:**
1. Implement U1/U2 entry per port via `PORT_U1_TIMEOUT` / `PORT_U2_TIMEOUT` registers.
2. U3 (suspend) via `Port Link State Write` command TRB.
3. U3 → Resume (U0) detection on PORTSC.PLC.
4. xHC-initiated suspend/resume (device responds to `SetPortFeature(PORT_SUSPEND)`).
**Exit:** USB 3.0 devices enter U1/U2/U3 when idle, resume on traffic.
### P7-C: Runtime PM autosuspend
**Reference:** `linux-7.1/drivers/usb/core/driver.c:2081` `usb_autosuspend()`.
**Tasks:**
1. Add per-device idle timer (default 2s).
2. Suspend device (U1/U2/U3) when timer expires.
3. Resume on URBs being submitted (auto-resume).
4. Disable autosuspend for devices that explicitly opt out.
**Exit:** USB mice, keyboards, storage automatically suspend after idle, resume instantly on activity.
---
## 10. P8 — Validation: hardware matrix + QEMU harness expansion
**Why this matters:** All USB work so far is QEMU-only. We need to validate on real hardware. This phase builds the harness for that.
### P8-A: Hardware validation matrix
**Reference:** `local/docs/HARDWARE-VALIDATION-MATRIX.md` (existing, currently tiny).
**Tasks:**
1. Expand the matrix: one row per (controller, class, board) tuple.
2. Required test points per row:
- Controller PCI ID → driver recognizes
- Device enumeration succeeds
- Specific class test (HID keypress, storage read+write, audio playback)
- Hot-plug works (USB 3.x + USB 2.0)
- Suspend/resume works (if device supports)
3. Minimum viable matrix entries (10+):
- xhcid on AMD Ryzen (USB 3.2, multiple hubs)
- xhcid on Intel Tiger Lake (USB 4 / Thunderbolt 3 compatible)
- xhcid on Intel C620 server chipset
- ehcid on a USB 2.0-only motherboard
- uhcid on a Via-based legacy system
- ohcid on an Nvidia nForce board
- USB HID: Logitech MX Master, Apple Magic Mouse, Cherry keyboard
- USB Storage: Samsung T7 SSD (UAS-capable), SanDisk Ultra (BOT-only)
- USB Hub: Anker 7-port powered hub, USB 3.0 hub chain
**Exit:** matrix has ≥10 rows; each row's last-tested date <6 months.
### P8-B: New QEMU tests
The v3 plan calls for QEMU test scripts that don't exist yet:
**Tasks:**
1. `test-uhci-runtime-qemu.sh --check` — boot with `-device piix3-usb-uhci`, verify enumeration.
2. `test-ohci-runtime-qemu.sh --check` — boot with `-device nec-usb-xhci` emulating OHCI compat, verify enumeration.
3. `test-ehci-class-autospawn-qemu.sh --check` — boot with USB keyboard on EHCI route, verify usbhidd spawns and keypress reaches inputd.
4. `test-usb-hub-qemu.sh --check` — boot with a USB hub attached, verify the hub enumerates and devices behind it enumerate.
5. `test-usb-error-recovery-qemu.sh --check` — hot-unplug during transfer, verify graceful error (not panic).
6. `test-usb-uas-qemu.sh --check` — boot with USB 3.0 storage device supporting UAS, verify UAS path active.
**Exit:** all 6 scripts pass.
### P8-C: Error injection tests
**Reference:** Linux's `usbtest.c` includes error injection patterns.
**Tasks:**
1. Build a `redbear-usb-fuzz` tool that performs:
- Random disconnects mid-transfer
- Stall injection on specific endpoints
- Babble simulation
- CRC error injection (in conjunction with `usbtest` if available)
2. Verify usbscsid / usbhidd / usbaudiod handle errors without panic.
**Exit:** no panics under 10,000 random disconnect events.
---
## 11. Build-and-verify workflow (per-session)
```bash
# After any P-phase change:
cd local/sources/base && git checkout <phase-branch>
cargo check -p xhcid --offline
cd local/recipes/drivers/uhcid/source && cargo check --offline
cd local/recipes/drivers/ohcid/source && cargo check --offline
cd local/recipes/drivers/ehcid/source && cargo check --offline
cd local/recipes/drivers/usb-core/source && cargo check --offline
# Full build:
./local/scripts/build-redbear.sh --upstream redbear-mini
# QEMU tests:
./local/scripts/test-xhci-irq-qemu.sh --check
./local/scripts/test-xhci-device-lifecycle-qemu.sh --check
./local/scripts/test-usb-storage-qemu.sh
./local/scripts/test-usb-qemu.sh
./local/scripts/test-usb-maturity-qemu.sh
# After P1 completes:
./local/scripts/test-uhci-runtime-qemu.sh --check # new
./local/scripts/test-ohci-runtime-qemu.sh --check # new
./local/scripts/test-ehci-class-autospawn-qemu.sh --check # new
./local/scripts/test-usb-hub-qemu.sh --check # new
./local/scripts/test-usb-error-recovery-qemu.sh --check # new
```
## 12. Stale documentation cleared
This v3 supersedes:
- `local/docs/USB-IMPLEMENTATION-PLAN.md` (v2 active) → archived as `local/docs/archived/USB-IMPLEMENTATION-PLAN-v2-2026-07.md`
- `local/docs/USB-VALIDATION-RUNBOOK.md` (v2 active) → archived as `local/docs/archived/USB-VALIDATION-RUNBOOK-2026-07.md`
`archived/README.md` updated to record the v1 → v2 → v3 supersession chain.
All Linux 7.0 references in active docs migrated to Linux 7.1 (this happened earlier in the v2 era).
## 13. Cross-reference summary
For every feature in v3, the cross-reference is to Linux 7.1 at `local/reference/linux-7.1/`:
| Feature | Linux 7.1 file | Lines | Implementation strategy |
|---|---|---|---|
| xHCI quirk table | `drivers/usb/host/xhci.h:1587-1649` | 63 | Reimplement as bitflags struct + per-controller lookup table |
| xHCI error recovery | `drivers/usb/host/xhci-ring.c:1700-1900` | 200+ | Port 36-code dispatch table; line-by-line Rust translation |
| USB 2.0 LPM | `drivers/usb/host/xhci-port.h:135-173` | 39 | Reimplement port-link-state transitions |
| Full hub enumeration | `drivers/usb/core/hub.c:1449-1521,3000-3300` | 300+ | Sequential port-and-hub init with timing-aware power-on |
| UAS protocol | `drivers/usb/storage/uas.c` | 1304 | Port full protocol, port 4-endpoint + IU framing |
| HID report descriptor parser | `drivers/hid/hid-core.c:1273` | 200+ | Token-based parser → tree of usage/collection/field |
| HID input mapping | `drivers/hid/hid-input.c:1244+` | 200+ | Usage page → keycode/rel/abs table |
| CDC ACM | `drivers/usb/class/cdc-acm.c` | 2186 | Line discipline + tty interface |
| Multi-touch HID | `drivers/hid/hid-multitouch.c` | 2756 | Slot-based protocol parser |
For all of these: when implementation detail is unclear, **port line-by-line from Linux 7.1**, preserving the data structure layouts and edge-case handling.
## 14. See also
- `local/docs/archived/USB-IMPLEMENTATION-PLAN-v1-2026-04.md` — v1 (P0 host work)
- `local/docs/archived/USB-IMPLEMENTATION-PLAN-v2-2026-07.md` — v2 (P0 + P5 host-only ADR)
- `local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md` — IRQ/MSI-X quality surface that P2-A depends on
- `local/docs/WIFI-IMPLEMENTATION-PLAN.md` — Wi-Fi subsystem plan; sibling first-class-citizen effort
- `local/docs/BLUETOOTH-IMPLEMENTATION-PLAN.md` — Bluetooth plan; uses `redbear-btusb` (USB Bluetooth transport)
- `local/reference/linux-7.1/drivers/usb/` — Linux 7.1 reference (the implementation of excellence)