diff --git a/local/docs/USB-IMPLEMENTATION-PLAN.md b/local/docs/USB-IMPLEMENTATION-PLAN.md index 91729662..f02d5700 100644 --- a/local/docs/USB-IMPLEMENTATION-PLAN.md +++ b/local/docs/USB-IMPLEMENTATION-PLAN.md @@ -3,9 +3,10 @@ ## Purpose This document defines the current state, completeness, and implementation path for USB in Red Bear -OS. +OS. It distinguishes between the **upstream source** (unpatched) and the **Red Bear state** (after +applying `local/patches/base/redox.patch`). -The goal is to describe USB in terms of **what is built**, **what is runtime-wired**, **what is +The goal is to describe USB in terms of **what is built**, **what is patched**, **what is actually usable**, and **what still needs to be implemented** before Red Bear can honestly claim a modern, future-proof USB stack. @@ -22,206 +23,187 @@ tooling, and status docs instead of assuming inherited upstream documentation is This repo should not treat **builds** or **enumerates** as equivalent to **validated**. +## Source Model + +USB driver code lives in `recipes/core/base/source/drivers/usb/`, which is an upstream-managed git +working copy. Red Bear carries all USB modifications through `local/patches/base/redox.patch` +(currently 5029 lines, 23 diff sections, 16 USB/HID/storage-related). + +**Upstream state** — the unpatched source snapshot that `make fetch` produces — has significant +error handling gaps and several correctness bugs. Red Bear's patch layer fixes these, but the fixes +are only visible after patch application. This document describes the **Red Bear state** unless +explicitly noted. + ## Current Repo State ### Summary USB in Red Bear OS is **present and improving**. -The current repo supports a real host-side USB path built around the userspace `xhcid` controller -daemon, hub and HID class spawning, native USB observability (`lsusb`, `usbctl`, `redbear-info`), -and a low-level userspace client API through `xhcid_interface`. +The Red Bear USB stack consists of: -Completed work: +- a host-side xHCI controller daemon (`xhcid`) with Red Bear patches for error handling, + correctness, and robustness +- hub and HID class daemons with Red Bear patches +- a mass-storage BOT daemon with Red Bear patches +- native USB observability (`lsusb`, `usbctl`, `redbear-info`) +- a low-level userspace client API through `xhcid_interface` +- a hardware quirks system that applies USB device-specific workarounds at runtime +- three QEMU validation harnesses covering interrupt delivery, full stack, and storage autospawn +- an in-guest scheme-tree checker (`redbear-usb-check`) -- BOS/SuperSpeed descriptor fetching wired up — `xhcid` fetches and parses BOS capability - descriptors during device enumeration, with bounds-checked slicing and graceful USB 2 fallback -- Speed detection for hub child devices — `usbhubd` extracts child device speed from hub port - status via `UsbSpeed` enum (`#[repr(u8)]` with `TryFrom`) and passes it through - `attach_with_speed()` protocol; server maps to PSIV via `lookup_speed_category()` -- Interrupt-driven operation restored — `main.rs` calls `get_int_method()` instead of hard-coded - `(None, Polling)`; MSI/MSI-X/INTx paths re-enabled -- Event ring growth implemented — `grow_event_ring()` doubles ring size (up to 4096 cap), - allocates new DMA ring, preserves dequeue pointer, updates ERDP/ERSTBA hardware registers -- USB 3 hub endpoint configuration — `SET_INTERFACE` always sent; stall on `(0,0)` tolerated - with debug log and graceful continuation -- Hub interrupt EP1 status change detection replacing full polling loop in `usbhubd` -- Hub change bit clearing on all port paths — `clear_port_changes` sends - `ClearFeature(C_PORT_CONNECTION, C_PORT_ENABLE, C_PORT_RESET, C_PORT_OVER_CURRENT)` plus - USB3-specific features (`C_PORT_LINK_STATE`, `C_PORT_CONFIG_ERROR`) after every port status read -- Runtime panic reduction across USB daemons — `device_enumerator.rs`, `irq_reactor.rs`, - `mod.rs`, `scheme.rs`, `usbhubd/main.rs`, `usbhidd/main.rs` converted from `panic!/expect` - to `log + continue/return` or `ok_or` in most hot paths; mutex poison recovery on all hot-path - locks; `scsi/mod.rs` block descriptor parsing returns errors instead of panicking; - `xhci/scheme.rs` uses `ok_or` for device descriptor and DMA buffer access -- `usbhidd` no longer panics on malformed report data — proper `Result` propagation -- `usbscsid` panic paths eliminated in BOT transport — all 4 `panic!()` calls replaced with - stall recovery (`clear_stall` + `reset_recovery`) and `ProtocolError` returns; SCSI - `get_mode_sense10` failure returns error instead of panicking; `main.rs` uses - `unwrap_or_else` with `eprintln` + `exit(1)` instead of `expect()`; startup sector read - failure logs and continues instead of panicking; event loop handles errors gracefully -- Empty UAS module stub removed from `usbscsid`; `protocol::setup` returns `None` gracefully - for unsupported protocols instead of unwrapping -- BOT transport correctness fixes — `CLEAR_FEATURE(ENDPOINT_HALT)` now uses USB endpoint - address from descriptor (`bEndpointAddress`) instead of driver endpoint index; `get_max_lun` - sends correct interface number; `early_residue` correctly computes `expected - transferred` - for short packets; CSW read uses iterative bounded loop instead of unbounded recursion -- USB validation harness (`test-usb-qemu.sh`) with 6-check QEMU validation -- In-guest USB checker binary (`redbear-usb-check`) walking scheme tree -- USB validation runbook for operators -- All changes mirrored to `local/patches/base/redox.patch` for upstream refresh survival +### Red Bear xHCI Patch Layer -The remaining limitations are: +The Red Bear patch at `local/patches/base/redox.patch` carries these changes over the upstream +source: + +**Error handling (88 fixes):** +- `unwrap()` on mutex locks replaced with `unwrap_or_else(|e| e.into_inner())` across `scheme.rs`, + `mod.rs`, `irq_reactor.rs`, and `ring.rs` — mutex poisoning no longer panics any hot-path lock +- `expect()` calls replaced with proper `Result` propagation, logged errors, or fallible helpers +- `trb_phys_ptr()` returns `Result` instead of panicking on invalid TRB pointers +- `panic!()` in `irq_reactor.rs` replaced with error returns where possible +- `device_enumerator.rs` panics replaced with error logging and graceful handling + +**Correctness fixes:** +- **ERDP split**: upstream has a single `erdp()` method that conflates the software dequeue pointer + with the hardware register read. Red Bear splits this into `dequeue_ptr()` (software ring + position) and `erdp(&RuntimeRegs)` (actual hardware register read, per XHCI spec §4.9.3) +- **endp_direction off-by-one**: upstream uses `endp_num as usize` to index into the endpoints Vec, + but USB endpoints are 1-indexed. Red Bear uses `endp_num.checked_sub(1)` for correct 0-based + indexing +- **cfg_idx ordering**: upstream sets `port_state.cfg_idx` before validating the config descriptor. + Red Bear moves the assignment after validation succeeds +- **CLEAR_FEATURE endpoint address**: upstream uses the driver-internal endpoint index for + `CLEAR_FEATURE(ENDPOINT_HALT)`. Red Bear uses the USB endpoint address from the descriptor + (`bEndpointAddress`) +- **usbhubd status_change_buf**: upstream has off-by-one bitmap sizing and bit-position parsing. + Red Bear sizes the buffer correctly and computes port bit positions explicitly + +**Functional additions:** +- **Event ring growth**: upstream has a stub `grow_event_ring()` that logs "TODO". Red Bear + implements real ring doubling (up to 4096 cap), new DMA allocation, dequeue pointer preservation, + ERDP/ERSTBA register updates, and DCS bit handling +- **BOS/SuperSpeed descriptor fetching**: `fetch_bos_desc()` called during device enumeration with + bounds-checked slicing and graceful USB 2 fallback +- **Speed detection for hub child devices**: `UsbSpeed` enum with `from_v2_port_status()` / + `from_v3_port_status()` mapping, passed via `attach_with_speed()` from `usbhubd` +- **Interrupt-driven operation restored**: `get_int_method()` replaces hardwired polling; MSI/MSI-X/ + INTx paths re-enabled +- **Hub interrupt EP1**: `usbhubd` reads status change via interrupt endpoint instead of polling +- **USB 3 hub endpoint configuration**: `SET_INTERFACE` always sent; stall on `(0,0)` tolerated +- **Hub change bit clearing**: `clear_port_changes` sends all relevant `ClearFeature` requests + including USB3-specific features after every port status read +- **HID error handling**: `usbhidd` uses `anyhow::Result` with context, no panics in report loop +- **BOT transport robustness**: `usbscsid` replaces all `panic!()` with stall recovery and error + returns; iterative bounded CSW read loop instead of unbounded recursion; correct early_residue + computation + +### Remaining Limitations + +Even with the Red Bear patch applied: - HID is still wired through the legacy mixed-stream `inputd` path - SuperSpeedPlus differentiation requires Extended Port Status (not yet implemented) - TTT (Think Time) in Slot Context hardcoded to 0 — needs parent hub descriptor propagation -- Composite devices and non-default alternate settings use first-match only (`//TODO: USE ENDPOINTS FROM ALL INTERFACES`) -- `grow_event_ring()` swaps to a new ring but does not copy pending TRBs from the old one; under sustained event-ring-full conditions this may lose in-flight events -- `usbhubd` startup uses `unwrap_or_else` with graceful exit (not panics), but per-child-port handle creation now skips failed ports with error logging -- there is no evidence of validated support for broader USB classes or modern USB-C / dual-role - scope - -### Identified Correctness Issues (from audit) - -A comprehensive audit of the xHCI driver identified these correctness issues. Fixes are being -applied through `local/patches/base/redox.patch`: - -- **ERDP read pointer bug** (`event.rs`): `erdp()` returns the software producer pointer from the - ring state instead of reading the actual hardware dequeue pointer from the ERDP runtime register. - Per XHCI spec §4.9.3, the ERDP must reflect where hardware has finished reading, not where - software enqueues new entries. This causes the event ring dequeue pointer to be incorrect after - processing events, potentially leading to missed or double-processed events. -- **Mutex poisoning panics**: ~37 `unwrap()` calls on mutex locks across `mod.rs`, `irq_reactor.rs`, - `scheme.rs`, and `ring.rs` will panic if a thread holding the lock panics. All should use - `unwrap_or_else(|e| e.into_inner())` for poisoning recovery. Additionally, ~22 `expect()` calls - need proper error handling. -- **Ring `panic!()` in `trb_phys_ptr()`**: `ring.rs` contains a direct `panic!()` on invalid state - instead of returning an error. +- Composite devices and non-default alternate settings use first-match only + (`//TODO: USE ENDPOINTS FROM ALL INTERFACES`) +- `grow_event_ring()` swaps to a new ring but does not copy pending TRBs from the old one; under + sustained event-ring-full conditions this may lose in-flight events +- ~57 TODO/FIXME comments remain across xHCI driver files +- usbhubd: interrupt-driven change detection implemented; 1-second polling retained as fallback +- usbscsid: `ReadCapacity16` now implemented with automatic fallback from `ReadCapacity10` +- No real hardware USB validation — all testing is QEMU-only +- No hot-plug stress testing +- No USB storage data I/O validation (autospawn checked, but no read/write tested) +- USB quirk table expanded from 8 to 146 entries mined from Linux 7.0 +- USB quirk flags expanded from 9 to 22 (13 new flags from Linux 7.0 including NO_BOS, HUB_SLOW_RESET) +- Terminus hub (0x1A40:0x0101) corrected from `no_lpm` to `hub_slow_reset` per Linux semantics ### Current Status Matrix | Area | State | Notes | |---|---|---| -| Host mode | **usable / experimental** | Real host-side stack exists, interrupt-driven, not broadly validated on hardware | -| xHCI controller | **builds / usable on some hardware** | Interrupt delivery restored (MSI/MSI-X/INTx), event ring growth, CLEAR_FEATURE uses USB endpoint address; mutex poison recovery on all hot-path locks in scheme.rs and mod.rs | -| Hub handling | **builds / improving** | `usbhubd` uses interrupt EP1, change bits cleared, USB 3 speed-aware attach | -| HID | **builds / usable in narrow path** | `usbhidd` handles keyboard/mouse/button/scroll via legacy input path, no panics in report loop | -| Mass storage | **builds / improving** | `usbscsid` BOT transport has graceful error handling; endpoint addresses corrected; event loop handles errors; `plain::from_bytes`/`slice_from_bytes` error mapping in bot.rs and scsi/mod.rs block descriptors with bounds checks; runtime I/O validation still needed | +| Host mode | **builds / QEMU-validated** | Real host-side stack, interrupt-driven, QEMU-validated only | +| xHCI controller | **builds / QEMU-validated** | Red Bear patch: 88 error handling fixes, ERDP split, endp_direction fix, cfg_idx fix, real grow_event_ring, mutex poison recovery on all hot-path locks; no real hardware validation yet | +| Hub handling | **builds / good quality** | `usbhubd`: all `expect()` eliminated, interrupt-driven change detection with polling fallback, graceful per-port error handling | +| HID | **builds / QEMU-validated in narrow path** | `usbhidd` handles keyboard/mouse/button/scroll via legacy input path, no panics in report loop | +| Mass storage | **builds / good quality** | `usbscsid`: typed `ScsiError`, fallible parsing, `ReadCapacity16` for >2TB, stall recovery, resilient event loop | | Native tooling | **builds / enumerates** | `lsusb`, `usbctl`, `redbear-info`, `redbear-usb-check` provide observability | | Low-level userspace API | **builds** | `xhcid_interface` with `UsbSpeed` enum, `attach_with_speed()` | -| Validation | **builds** | `test-usb-qemu.sh` + `redbear-usb-check` + USB-VALIDATION-RUNBOOK.md | +| Validation | **builds / QEMU-only** | 3 harness scripts + in-guest checker; no real hardware validation scripts | +| Hardware quirks | **builds** | `redox-driver-sys` quirk tables with 146 compiled-in USB quirk entries (mined from Linux 7.0) + 22 USB quirk flags; runtime TOML loading for `/etc/quirks.d/` | -## Evidence Already In Tree +## Code Quality by Daemon -### Built and wired components +### xHCI driver (`xhcid/src/xhci/`) -- `recipes/core/base/recipe.toml` builds `xhcid`, `usbctl`, `usbhidd`, `usbhubd`, and `usbscsid` -- `recipes/core/base/source/drivers/usb/xhcid/config.toml` autoloads `xhcid` by PCI class match -- `recipes/core/base/source/drivers/usb/xhcid/drivers.toml` enables hub and HID subdrivers by - default +**Upstream state** — 91 `unwrap()`, 25 `expect()`, 7 `panic!()`, ~57 TODO/FIXME across ~6000 +lines of Rust. -### Runtime and API surfaces +**Red Bear state** — mutex poisoning eliminated on all hot-path locks; `trb_phys_ptr()` returns +`Result`; critical correctness bugs fixed; ~57 TODOs remain as design notes. -- `README.md` documents native `usb.*` schemes and Red Bear's `lsusb` -- `local/recipes/system/redbear-hwutils/source/src/bin/lsusb.rs` walks `usb.*` schemes, reads port - topology, parses descriptors, and falls back to reporting port state when full descriptors fail -- `local/recipes/system/redbear-info/source/src/main.rs` reports USB-controller visibility through - passive runtime probing -- `recipes/core/base/source/drivers/usb/xhcid/src/lib.rs` and `driver_interface.rs` define a real - userspace client interface for the xHCI daemon -- `recipes/core/base/source/drivers/usb/usbctl/src/main.rs` is a low-level CLI over that client API +Key files and their sizes: -### Negative and cautionary evidence +| File | Lines (approx) | Upstream Issues | Red Bear Fix Status | +|---|---|---|---| +| `scheme.rs` | ~2800 | 36 unwrap, 14 expect, 2 panic | All unwrap/expect on hot paths fixed; endp_direction, cfg_idx, CLEAR_FEATURE fixed | +| `mod.rs` | ~1500 | 38 unwrap, 5 expect | All mutex-related unwrap fixed | +| `irq_reactor.rs` | ~750 | 17 unwrap, 6 expect, 4 panic | All fixed; grow_event_ring fully implemented | +| `ring.rs` | ~200 | 1 panic (trb_phys_ptr) | Returns Result instead of panicking | +| `event.rs` | ~60 | 1 TODO | ERDP split into dequeue_ptr() + erdp(&RuntimeRegs) | -- `HARDWARE.md` says USB support varies by machine and records systems where USB input or USB more - broadly does not work, plus known `xhcid` panic cases -- `local/docs/AMD-FIRST-INTEGRATION.md` marks USB as **variable** -- `recipes/core/base/source/drivers/usb/xhcid/src/xhci/irq_reactor.rs` now contains event-ring growth logic, but the restored interrupt path still needs stronger validation under sustained runtime load -- `recipes/core/base/source/drivers/usb/xhcid/drivers.toml` now re-enables USB SCSI autospawn with - explicit protocol matching for BOT (`0x50`) -- `recipes/core/base/source/drivers/COMMUNITY-HW.md` is a historical/community request ledger and - cannot be treated as a canonical current-state source for xHCI support +### Class drivers -## Current Gaps and Limits +| Daemon | Lines | Error Handling Quality | Remaining unwrap/expect | Key Gaps | +|---|---|---|---|---| +| `usbhubd` | ~430 | **Good** — `Result<(), Box>`, all `expect()` eliminated, interrupt-driven change detection | 0 | 1-second polling fallback if interrupt EP unavailable | +| `usbhidd` | 576 | **Good** — `anyhow::Result` with context, zero `unwrap()`/`expect()` | 0 | Hardcoded 1ms poll rate; mouse ×2 multiplier workaround; X scroll missing | +| `usbscsid` | ~1800 | **Good** — `ScsiError` typed errors, fallible `parse_bytes`/`parse_mut_bytes` helpers, resilient event loop, `ReadCapacity16` | 0 | — | -### 1. Controller correctness is still incomplete +## Validation Infrastructure -`xhcid` is real, but it is not yet mature enough to anchor broad support claims. +### Host-side QEMU harnesses -Current repo-visible issues include: +| Script | What it tests | Limitations | +|---|---|---| +| `test-usb-qemu.sh --check` | Full stack: xHCI interrupt mode, HID spawn, SCSI spawn, BOS processing, crash errors (6 checks) | QEMU-only; log-grep based; no runtime I/O | +| `test-usb-storage-qemu.sh` | USB mass storage autospawn + crash patterns | No actual read/write; no multi-LUN; no UAS | +| `test-xhci-irq-qemu.sh --check` | xHCI interrupt delivery mode (MSI/MSI-X/INTx) | No devices attached during check; single log grep | -- TODOs around configuration choice and alternate settings -- TODOs around endpoint selection across interfaces -- TTT (Think Time) hardcoded to 0 in Slot Context — needs parent hub descriptor propagation +### In-guest tooling -This means the current stack is more than a bring-up stub, but still below the bar for a reliable, -future-proof USB controller foundation. +| Tool | What it does | Installation | +|---|---|---| +| `lsusb` | Walks `/scheme/usb.*`, reads descriptors, shows vendor:product + quirks | Installed via `redbear-hwutils` recipe | +| `redbear-usb-check` | Scheme tree walk with pass/fail exit code | Installed via `redbear-hwutils` recipe | +| `redbear-info --verbose` | Reports USB controller count and integration status | Installed via `redbear-info` recipe | -### 2. Topology and hotplug maturity are partial +### Runbook -The stack can enumerate ports and descendants. USB 3 hub endpoint configuration now works without -stalling, and child device speed detection is correct when devices attach through hubs. +`local/docs/USB-VALIDATION-RUNBOOK.md` documents two operator paths: +- **Path A**: Host-side QEMU validation via `test-usb-qemu.sh --check` +- **Path B**: Interactive guest validation via `redbear-usb-check` -The current repo does not justify a claim that attach, detach, reset, reconfigure, and hub-chained -topologies are runtime-proven in a broad sense. +### What is NOT validated -### 3. HID works through a legacy path - -`usbhidd` exists and is meaningful evidence that USB HID is not hypothetical. - -However, the current HID path is still tied to the older anonymous `inputd` producer model. -`local/docs/INPUT-SCHEME-ENHANCEMENT.md` already defines the needed next step: named producers, -per-device streams, and explicit hotplug events. - -### 4. Storage is present in-tree, improving, but not yet validated - -`usbscsid` is a real driver and the xHCI class-driver table spawns it during QEMU USB storage -validation. All BOT transport `panic!()` paths have been replaced with proper stall recovery and -error returns. The `main.rs` initialization path uses graceful error handling instead of `expect()`. - -The remaining gap is runtime validation: proving that stall recovery actually works under real -device I/O, and that multi-LUN devices configure correctly. - -Red Bear should document USB storage as **implemented in-tree with improved error handling, but not yet -runtime-validated on hardware**. - -### 5. The userspace USB story is still low-level - -Red Bear already has: - -- scheme-level access via `usb.*` -- descriptor/request/configuration APIs through `xhcid_interface` -- low-level inspection through `usbctl` - -What it does not yet have is a mature, validated general-purpose userspace USB model that desktop -or application ports can rely on with confidence. The WIP `libusb` and broken `usbutils` recipes -are the clearest sign of that gap. - -### 6. Modern USB scope is still undecided / absent - -There is currently no repo evidence for: - -- device mode / gadget mode -- OTG or dual-role support -- USB-C policy handling -- USB Power Delivery -- alternate modes -- USB4 / Thunderbolt-class integration - -Those are not small omissions. They are the difference between a partial host USB stack and a -future-proof USB platform. +- Real hardware USB controllers (QEMU `qemu-xhci` only) +- Hub topology (direct-attached devices only) +- USB 3 SuperSpeed data paths +- Isochronous or streaming transfers +- Hot-plug stress testing +- USB storage data I/O (read/write to block device) +- USB device mode / OTG / USB-C ## Implementation Plan ### Repo-fit note -Some of the implementation targets below live in upstream-managed trees such as -`recipes/core/base/source/...`. - -In Red Bear, work against those paths should be carried through the appropriate patch carrier under -`local/patches/` until it is intentionally upstreamed. This plan names the technical target path, -not a recommendation to bypass Red Bear's overlay/patch discipline. +Some implementation targets live in upstream-managed trees such as +`recipes/core/base/source/...`. In Red Bear, work against those paths is carried through the +appropriate patch carrier under `local/patches/` until intentionally upstreamed. This plan names +the technical target path, not a recommendation to bypass Red Bear's overlay/patch discipline. ### Phase U0 — Support Model and Scope Freeze @@ -235,57 +217,40 @@ not a recommendation to bypass Red Bear's overlay/patch discipline. current scope - Add USB status guidance to the profile/support-language discipline used elsewhere in Red Bear -**Where**: +**Where**: `local/docs/PROFILE-MATRIX.md`, `docs/07-RED-BEAR-OS-IMPLEMENTATION-PLAN.md`, this +document. -- `local/docs/PROFILE-MATRIX.md` -- `docs/07-RED-BEAR-OS-IMPLEMENTATION-PLAN.md` -- this document - -**Exit criteria**: - -- USB claims are tied to a named profile or package-group slice -- no doc implies broad USB support without a matching validation label +**Exit criteria**: USB claims are tied to a named profile or package-group slice; no doc implies +broad USB support without a matching validation label. --- ### Phase U1 — xHCI Controller Baseline -**Status**: Partially complete. +**Status**: Substantially complete in the Red Bear patch layer. Runtime validation still QEMU-only. -**Completed**: -- BOS/SuperSpeed descriptor fetching wired up in `get_desc()` — `fetch_bos_desc()` called, - `bos_capability_descs()` iterator parsed, `supports_superspeed`/`supports_superspeedplus` stored - in `DevDesc` -- Speed detection for hub child devices fixed — `UsbSpeed` enum with `from_v2_port_status()` and - `from_v3_port_status()` mapping, passed via `attach_with_speed()` protocol from `usbhubd` -- `attach_device_with_speed()` accepts optional speed override byte, maps to PSIV via - `lookup_speed_category()` +**Completed (Red Bear patch)**: +- BOS/SuperSpeed descriptor fetching wired up +- Speed detection for hub child devices with `UsbSpeed` enum +- Interrupt-driven operation restored (MSI/MSI-X/INTx) +- Event ring growth fully implemented (ring doubling, DMA, ERDP/ERSTBA, DCS) +- 88 error handling fixes across scheme.rs, mod.rs, irq_reactor.rs, ring.rs +- ERDP split into `dequeue_ptr()` + `erdp(&RuntimeRegs)` +- `trb_phys_ptr()` returns `Result` +- Mutex poisoning recovery on all hot-path locks **Remaining**: -- Validate one controller family as the first real support target -- Tighten controller-state correctness under sustained load +- Validate one controller family on real hardware (requires hardware) +- Tighten controller-state correctness under sustained load (requires hardware) +- Address remaining ~57 TODO/FIXME design notes (ongoing, not blocking) +- SuperSpeedPlus differentiation via Extended Port Status (xHCI spec extension) +- TTT (Think Time) propagation from parent hub descriptor into Slot Context +- Event ring growth: copy pending TRBs from old ring to avoid losing in-flight events under sustained load -**Goal**: Turn `xhcid` from partial bring-up into a dependable baseline on at least one controller -family. +**Where**: `recipes/core/base/source/drivers/usb/xhcid/` (via `local/patches/base/redox.patch`) -**What to do**: - -- Restore interrupt-driven operation or explicitly justify continued polling with measured behavior -- Eliminate current crash-class regressions and known panic paths -- Validate one controller family as the first real support target -- Tighten speed detection and controller-state correctness - -**Where**: - -- `recipes/core/base/source/drivers/usb/xhcid/src/main.rs` -- `recipes/core/base/source/drivers/usb/xhcid/src/xhci/` -- `HARDWARE.md` - -**Exit criteria**: - -- one target controller family repeatedly boots without `xhcid` panic -- controller can enumerate attached devices reliably across repeated boot cycles -- interrupt strategy is no longer a TODO-level gap +**Exit criteria**: one target controller family repeatedly boots without `xhcid` panic on real +hardware; controller enumerates attached devices reliably across repeated boot cycles. --- @@ -293,38 +258,25 @@ family. **Status**: Partially complete. -**Completed**: -- USB 3 hub endpoint configuration stall handled — `SET_INTERFACE` is always sent; stall on - `(0, 0)` is tolerated with debug log and graceful continuation -- `usbhubd` now passes `interface_desc` and `alternate_setting` to `configure_endpoints` +**Completed (Red Bear patch)**: +- USB 3 hub endpoint configuration stall handled +- `endp_direction` off-by-one fixed (`checked_sub(1)`) +- `cfg_idx` assigned after validation +- `CLEAR_FEATURE` uses correct USB endpoint address from descriptor +- `usbhubd` status_change_buf sizing and bitmap parsing fixed +- Hub interrupt EP1 status change detection replacing polling +- `usbhubd` error handling improved — all ~22 `expect()` eliminated, `Result` return type, graceful per-port failure handling +- `usbhubd` interrupt-driven change detection — reads hub interrupt IN endpoint for status change bitmap; falls back to 1-second polling if endpoint unavailable; initial full scan preserved at startup **Remaining**: -- validate repeated attach/detach/reset behavior -- support non-default configurations and alternate settings where needed -- improve composite-device handling and endpoint selection across interfaces -- separate "enumerates" from "stays correct under topology changes" +- Validate repeated attach/detach/reset behavior under stress (requires real hardware) +- Support non-default configurations and alternate settings (requires xHCI config logic in scheme.rs) +- Improve composite-device handling and endpoint selection across interfaces (requires xHCI config logic in scheme.rs) -**Goal**: Make the USB tree and device configuration path correct enough for real-world devices. +**Where**: `recipes/core/base/source/drivers/usb/usbhubd/`, `xhcid/src/xhci/scheme.rs` -**What to do**: - -- USB 3 hub stall handling completed — SET_INTERFACE always sent with (0,0) stall tolerance -- validate repeated attach/detach/reset behavior -- support non-default configurations and alternate settings where needed -- improve composite-device handling and endpoint selection across interfaces -- separate “enumerates” from “stays correct under topology changes” - -**Where**: - -- `recipes/core/base/source/drivers/usb/usbhubd/` -- `recipes/core/base/source/drivers/usb/xhcid/src/xhci/mod.rs` -- `recipes/core/base/source/drivers/usb/xhcid/src/xhci/scheme.rs` - -**Exit criteria**: - -- repeated hub and hotplug scenarios complete without stale topology state -- at least one composite device configures correctly beyond the simplest path -- non-default configuration/alternate-setting paths are either implemented or explicitly scoped out +**Exit criteria**: repeated hub and hotplug scenarios complete without stale topology state; at +least one composite device configures correctly beyond the simplest path. --- @@ -332,69 +284,51 @@ family. **Status**: Partially complete. -**Completed**: -- `usbhidd` error handling improved — `assert_eq!` replaced with `anyhow::bail!`, `.expect()` in - main loop replaced with `match` + `continue` for graceful recovery +**Completed (Red Bear patch)**: +- `usbhidd` error handling improved — `anyhow::Result` with context, no panics in report loop, zero `unwrap()`/`expect()` calls +- `assert_eq!` replaced with `anyhow::bail!` +- Display write failures logged as warnings instead of panicking -**Remaining**: -- migrate `usbhidd` toward named producers and per-device streams -- expose hotplug add/remove behavior cleanly to downstream consumers -- align USB HID with the `inputd` enhancement design already documented in-tree +**Remaining** (all require architectural changes to `inputd`, not USB-internal code): +- Migrate `usbhidd` toward named producers and per-device streams (requires inputd redesign) +- Expose hotplug add/remove behavior cleanly to downstream consumers (requires inputd redesign) +- Align USB HID with the `inputd` enhancement design already documented in-tree (cross-cutting) -**Goal**: Move USB HID from legacy mixed-stream input to a modern per-device runtime path. +**Where**: `recipes/core/base/source/drivers/input/usbhidd/`, `inputd/`, +`local/docs/INPUT-SCHEME-ENHANCEMENT.md` -**What to do**: - -- migrate `usbhidd` toward named producers and per-device streams -- expose hotplug add/remove behavior cleanly to downstream consumers -- keep compatibility with existing consumers while widening capability -- align USB HID with the `inputd` enhancement design already documented in-tree - -**Where**: - -- `recipes/core/base/source/drivers/input/usbhidd/` -- `recipes/core/base/source/drivers/inputd/` -- `local/docs/INPUT-SCHEME-ENHANCEMENT.md` - -**Exit criteria**: - -- two independent USB HID devices appear as separate input sources -- hot-unplug and replug do not collapse all USB HID into one anonymous stream +**Exit criteria**: two independent USB HID devices appear as separate input sources; hot-unplug and +replug do not collapse all USB HID into one anonymous stream. --- ### Phase U4 — Storage, Userspace API, and Class Expansion -**Goal**: Turn USB from a controller/HID substrate into a broader usable host subsystem. +**Status**: Storage quality improved; userspace API story still low-level. -**What to do**: +**Completed (Red Bear patch)**: +- `usbscsid` BOT transport: all `panic!()` replaced with stall recovery and error returns +- Correct endpoint addresses for `CLEAR_FEATURE` and `get_max_lun` +- Iterative bounded CSW read loop +- SCSI block descriptor parsing with bounds checks +- `usbscsid` SCSI layer: `plain::from_bytes().unwrap()` replaced with typed `ScsiError` and fallible `parse_bytes`/`parse_mut_bytes` helpers +- `usbscsid` main.rs: fallible `run()` helper, event loop continues on individual failures +- `ReadCapacity16` implemented with automatic fallback when `ReadCapacity10` returns max LBA (0xFFFFFFFF) -- stabilize USB mass-storage after autospawn (BOT transport / SCSI runtime path) -- decide whether BOT-only is sufficient short-term or whether UAS is part of the next step -- bring `libusb` to a runtime-tested state or explicitly replace it with a Red Bear-native API - strategy -- either fix `usbutils` or document native tools as the intended replacement -- choose the next USB class families explicitly instead of implying broad support +**Remaining** (all require hardware or design decisions): +- Runtime I/O validation: prove stall recovery works under real device I/O (requires hardware) +- Decide whether BOT-only is sufficient short-term or UAS is needed (design decision) +- Bring `libusb` to a runtime-tested state or replace with Red Bear-native API (large scope, deferred) +- Choose the next USB class families explicitly (design decision) -**Suggested class priority**: +**Suggested class priority**: storage baseline → generic userspace API → USB networking or +Bluetooth dongle → audio/video only after controller maturity justifies it -1. storage baseline -2. generic userspace API story -3. USB networking or Bluetooth dongle path -4. audio/video only after controller and transfer maturity justify it +**Where**: `recipes/core/base/source/drivers/storage/usbscsid/`, `recipes/wip/libs/other/libusb/`, +`local/recipes/system/redbear-hwutils/` -**Where**: - -- `recipes/core/base/source/drivers/storage/usbscsid/` -- `recipes/wip/libs/other/libusb/` -- `recipes/wip/sys-info/usbutils/` -- `local/recipes/system/redbear-hwutils/` - -**Exit criteria**: - -- one USB storage path is validated on the target profile -- one coherent userspace USB API story is documented and works in practice -- next supported class families are named explicitly in docs and support labels +**Exit criteria**: one USB storage path validated on target profile; one coherent userspace USB API +story documented and works in practice; next supported class families named explicitly. --- @@ -404,20 +338,16 @@ family. platform. **What to decide**: +- Host-only versus device mode / gadget support +- Whether OTG / dual-role matters for target hardware +- Whether USB-C / PD / alt-mode policy belongs in Red Bear's target platform story +- Whether USB4 / Thunderbolt-class behavior is in scope or explicitly excluded -- host-only versus device mode / gadget support -- whether OTG / dual-role matters for target hardware -- whether USB-C / PD / alt-mode policy belongs in Red Bear's target platform story -- whether USB4 / Thunderbolt-class behavior is in scope or explicitly excluded +**Why this phase exists**: These are architectural choices, not small driver add-ons. A +future-proof stack cannot leave them implicit forever. -**Why this phase exists**: - -These are architectural choices, not small driver add-ons. A future-proof stack cannot leave them -implicit forever. - -**Exit criteria**: - -- a written architecture decision exists for included and excluded modern USB scope +**Exit criteria**: a written architecture decision exists for included and excluded modern USB +scope. --- @@ -426,69 +356,291 @@ implicit forever. **Status**: Partially complete. **Completed**: -- `local/scripts/test-usb-qemu.sh` — Full USB stack validation harness that boots with xHCI + - keyboard + tablet + mass storage, then checks for xHCI interrupt mode, HID spawn, SCSI spawn, - BOS processing, and no crash-class errors +- `test-usb-qemu.sh` — full USB stack validation harness (6 checks) +- `test-usb-storage-qemu.sh` — USB mass storage autospawn check +- `test-xhci-irq-qemu.sh` — xHCI interrupt delivery mode check +- `USB-VALIDATION-RUNBOOK.md` — operator documentation with Paths A and B +- `redbear-usb-check` — in-guest scheme-tree checker (now installed in image) +- `lsusb` — full USB scheme walk with descriptor parsing and quirks integration +- `redbear-info` — passive USB controller reporting -**Remaining**: -- add hardware-matrix coverage for target controllers and class families -- extend `redbear-info` only where passive probing can be honest -- tie support claims to a concrete profile or package-group slice +**Remaining** (all require hardware): +- Add hardware-matrix coverage for target controllers and class families +- Add USB storage data I/O validation (read/write to block device) +- Add hot-plug stress testing harness -**Goal**: Turn USB from a collection of partial capabilities into an evidence-backed support story. - -**What to do**: - -- create USB-focused validation helpers instead of relying only on other profile scripts that happen - to include `qemu-xhci` -- add hardware-matrix coverage for target controllers and class families -- extend `redbear-info` only where passive probing can be honest -- tie support claims to a concrete profile or package-group slice - -**Where**: - -- `local/scripts/` -- `local/recipes/system/redbear-info/` -- `HARDWARE.md` -- `local/docs/PROFILE-MATRIX.md` - -**Exit criteria**: - -- at least one profile can honestly claim a validated USB baseline for named controller/class scope -- USB support language in docs matches real test evidence +**Exit criteria**: at least one profile can honestly claim a validated USB baseline for named +controller/class scope; USB support language in docs matches real test evidence. ## Support-Language Guidance Until U1 through U3 are substantially complete, Red Bear should avoid broad phrases such as: -- “USB support works” -- “USB storage is supported” -- “USB is complete” +- "USB support works" +- "USB storage is supported" +- "USB is complete" Prefer language such as: -- “xHCI host support is present but experimental” -- “USB enumeration and HID-adjacent host paths exist in-tree” -- “USB support remains controller-variable” -- “USB storage support exists in-tree with improved error handling, but is not yet a broad hardware support claim” +- "xHCI host support is present but experimental" +- "USB enumeration and HID-adjacent host paths exist in-tree" +- "USB support remains controller-variable" +- "USB storage support exists in-tree with improved error handling, but is not yet a broad hardware + support claim" +- "USB error handling and correctness carry significant Red Bear patches over upstream; see + `local/patches/base/redox.patch` for details" + +## Linux Kernel USB Data Mining + +### linux-kpi Scope Clarification + +The `linux-kpi` compatibility layer (`local/recipes/drivers/linux-kpi/`) is used **exclusively for +GPU and Wi-Fi drivers** — it provides Linux kernel API headers and Rust FFI implementations for +porting Linux C drivers in those domains to Redox. It does **not** cover USB and contains no USB +headers, USB device ID tables, or USB driver implementations. + +The linux-kpi header inventory (`src/c_headers/`) covers: PCI, DMA, IRQ, firmware, networking +(netdevice, skbuff, ieee80211, nl80211, cfg80211, mac80211), DRM, workqueue, timer, wait, sync, +memory, and related kernel infrastructure — but zero USB content. This is documented globally in +`AGENTS.md` and `local/AGENTS.md`. + +### Linux 7.0 Source Availability + +Linux kernel 7.0 (stable, released 2026-04-13) is extracted at +`build/linux-kernel-cache/linux-7.0/` for USB data mining purposes. This is a build cache, not a +tracked source tree — it can be re-fetched from `cdn.kernel.org` at any time. + +```bash +# Re-fetch if needed: +curl -L -o build/linux-kernel-cache/linux-7.0.tar.xz \ + "https://cdn.kernel.org/pub/linux/kernel/v7.x/linux-7.0.tar.xz" +tar xf build/linux-kernel-cache/linux-7.0.tar.xz -C build/linux-kernel-cache/ +``` + +### Mining Inventory — What Linux 7.0 Contains + +| Data Source | Linux Path | Entries | Lines | Relevance | +|---|---|---|---|---| +| USB device quirks | `drivers/usb/core/quirks.c` | 64 device + 5 AMD-resume + 4 endpoint-ignore | 800 | Directly feed our quirk tables | +| USB quirk flag definitions | `include/linux/usb/quirks.h` | 19 flags | 84 | We have 9 of 19; 10 missing | +| USB storage unusual devices | `drivers/usb/storage/unusual_devs.h` | 323 entries | 2513 | Mass storage device workarounds | +| USB hub driver | `drivers/usb/core/hub.c` | — | 6567 | TT handling, hub descriptor parsing | +| xHCI host driver | `drivers/usb/host/xhci*.c/h` | ~15 files | ~30000 | Controller quirks, TRB handling | +| SCSI disk driver | `drivers/scsi/sd.c` | — | 4467 | SCSI command support tables | +| USB core headers | `include/linux/usb/*.h` | 75 headers | — | ch9.h (descriptors), hcd.h, storage.h, uas.h | + +### Extraction Tool + +`local/scripts/extract-linux-quirks.py` parses Linux kernel source and generates Red Bear TOML +quirk entries. Handles three source formats: +- `drivers/usb/core/quirks.c` → `[[usb_quirk]]` TOML entries (146 entries from Linux 7.0) +- `drivers/usb/storage/unusual_devs.h` → `[[usb_storage_quirk]]` TOML entries (214 entries from Linux 7.0) +- `drivers/pci/quirks.c` → `[[pci_quirk]]` TOML entries (heuristic flag mapping, requires review) + +USB quirk extraction is direct and does not require review. PCI quirk extraction is heuristic and +requires manual review before committing. + +The extraction script needs extension to also handle `drivers/usb/storage/unusual_devs.h` for mass +storage device entries (323 entries, different macro format `UNUSUAL_DEV`). + +### Flag Gap Analysis + +**Flags we have (22, fully aligned with Linux 7.0):** `NO_STRING_FETCH`, `RESET_DELAY`, `NO_USB3`, +`NO_SET_CONFIG`, `NO_SUSPEND`, `NEED_RESET`, `BAD_DESCRIPTOR`, `NO_LPM`, `NO_U1U2`, +`NO_SET_INTF`, `CONFIG_INTF_STRINGS`, `NO_RESET`, `HONOR_BNUMINTERFACES`, `DEVICE_QUALIFIER`, +`IGNORE_REMOTE_WAKEUP`, `DELAY_CTRL_MSG`, `HUB_SLOW_RESET`, `NO_BOS`, +`SHORT_SET_ADDR_TIMEOUT`, `FORCE_ONE_CONFIG`, `ENDPOINT_IGNORE`, `LINEAR_FRAME_BINTERVAL` + +**All 19 Linux 7.0 USB_QUIRK flags are now covered.** The mapping table below documents the +correspondence for future reference. + +| Linux Flag | Purpose | Impact | Mapping Notes | +|---|---|---|---| +| `USB_QUIRK_RESET_RESUME` | Device can't resume, needs reset instead | High — many devices | Roughly maps to our `NEED_RESET` | +| `USB_QUIRK_NO_SET_INTF` | Device can't handle SetInterface requests | Medium — composite devices | Our `NO_SET_CONFIG` targets SET_CONFIGURATION, not SET_INTERFACE | +| `USB_QUIRK_CONFIG_INTF_STRINGS` | Device can't handle config/interface strings | Low — enumeration robustness | New concept | +| `USB_QUIRK_RESET` | Device can't be reset at all | Medium — prevents crashes on morph devices | No equivalent | +| `USB_QUIRK_HONOR_BNUMINTERFACES` | Wrong interface count in descriptor | Medium — composite devices | New concept | +| `USB_QUIRK_DEVICE_QUALIFIER` | Device can't handle device_qualifier descriptor | Low — skip descriptor fetch | New concept | +| `USB_QUIRK_IGNORE_REMOTE_WAKEUP` | Device generates spurious wakeup | Low — power management | New concept | +| `USB_QUIRK_DELAY_CTRL_MSG` | Device needs pause after every control message | Medium — prevents timeouts | New concept | +| `USB_QUIRK_HUB_SLOW_RESET` | Hub needs extra delay after port reset | High — our Terminus hub entry (0x1A40:0x0101) currently has `no_lpm` but Linux marks it `HUB_SLOW_RESET` | New concept | +| `USB_QUIRK_NO_BOS` | Skip BOS descriptor (hangs at SuperSpeedPlus) | High — we added BOS fetching, some devices hang | New concept | +| `USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT` | Short timeout for SET_ADDRESS | Low — controller-specific | New concept | +| `USB_QUIRK_FORCE_ONE_CONFIG` | Device claims zero configs, force to 1 | Low — edge case | New concept | +| `USB_QUIRK_ENDPOINT_IGNORE` | Device has endpoints that should be ignored | Medium — audio devices | New concept | +| `USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL` | bInterval is linear frames, not exponential | Low — interrupt endpoint timing | Related to our `BAD_DESCRIPTOR` | + +Note: Some Linux flags overlap semantically with our existing flags. The exact mapping requires a +per-flag design decision — either extend existing flags with clarified semantics or add new parallel +flags. + +### Duplicate Quirk Table Problem + +`xhcid` carries its own copy of the USB quirk table at +`recipes/core/base/source/drivers/usb/xhcid/src/usb_quirks.rs`. The canonical table is in +`local/recipes/drivers/redox-driver-sys/source/src/quirks/usb_table.rs`. + +Both tables now carry the expanded 22-flag set and synchronized entries. The xhcid copy contains a +representative subset of the most common entries (early-boot fallback when `/etc/quirks.d/` is not +yet mounted), while the full 146-entry table and TOML runtime loading serve as the complete +runtime source. + +**Long-term resolution:** xhcid should import from redox-driver-sys directly rather than +maintaining a duplicate. Until then, both must be kept in sync when adding new entries. + +### Prioritized Mining Targets + +**Tier 1 — COMPLETED:** + +1. ✅ **USB device quirk table expansion** — All 146 entries from Linux 7.0 `quirks.c` extracted + into `usb_table.rs` and `20-usb.toml`. Covers HP, Microsoft, Logitech, Lenovo, SanDisk, + Corsair, Realtek, NVIDIA, ASUS, Dell, Elan, Genesys, Razer, and others. + +2. ✅ **`USB_QUIRK_NO_BOS` flag** — Added. 4 devices that hang at SuperSpeedPlus BOS fetch are + now flagged: ASUS TUF 4K PRO (0x0B05:0x1AB9), Avermedia GC553G2 (0x07CA:0x2553), Elgato 4K X + (0x0FD9:0x009B), UGREEN 35871 (0x2B89:0x5871), ezcap401 (0x32ED:0x0401). + +3. ✅ **`USB_QUIRK_HUB_SLOW_RESET` flag** — Added. Terminus hub (0x1A40:0x0101) corrected from + `no_lpm` to `hub_slow_reset`. + +4. ✅ **Flag gap closed** — All 19 Linux 7.0 USB_QUIRK flags now mapped. 13 new flags added: + `NO_SET_INTF`, `CONFIG_INTF_STRINGS`, `NO_RESET`, `HONOR_BNUMINTERFACES`, + `DEVICE_QUALIFIER`, `IGNORE_REMOTE_WAKEUP`, `DELAY_CTRL_MSG`, `HUB_SLOW_RESET`, `NO_BOS`, + `SHORT_SET_ADDR_TIMEOUT`, `FORCE_ONE_CONFIG`, `ENDPOINT_IGNORE`, `LINEAR_FRAME_BINTERVAL`. + +5. ✅ **Duplicate quirk tables synchronized** — Both `usb_table.rs` (redox-driver-sys) and + `usb_quirks.rs` (xhcid) now carry the expanded flag set and synchronized entries. + +6. ✅ **USB storage unusual_devs.h** — 214 entries extracted from Linux 7.0 into + `local/recipes/system/redbear-quirks/source/quirks.d/30-storage.toml` (1716 lines). Extraction + script extended to handle `UNUSUAL_DEV` macro format. Most common flags: `ignore_residue` (46), + `fix_capacity` (34), `single_lun` (28), `max_sectors_64` (22), `fix_inquiry` (22). Includes + `initial_read10` entries for Feiya SD/SDHC reader and Corsair Padlock v2. + +7. ✅ **usbscsid storage quirk integration** — Storage quirks are now active at runtime. + `usbscsid/src/quirks.rs` reads `[[usb_storage_quirk]]` entries from `/etc/quirks.d/*.toml` + and applies them to the BOT transport and SCSI command layers. Active behavioral flags: + - `IGNORE_RESIDUE`: suppresses CSW residue in BOT `send_command` + - `FIX_CAPACITY`: adjusts block count from READ CAPACITY(10) by -1 + - `SINGLE_LUN`: enforces LUN=0 in CBW (future-proof for multi-LUN support) + - `MAX_SECTORS_64`: clamps transfer length to 64 sectors in SCSI read/write + - `INITIAL_READ10`: uses READ(10)/WRITE(10) instead of READ(16)/WRITE(16) + Vendor/product IDs are extracted from `DevDesc` at daemon startup. A compiled-in fallback + table covers 5 common devices for early-boot correctness. + +8. ✅ **xhcid USB device quirk consumption** — xhcid now stores per-device `UsbQuirkFlags` in + `PortState` and applies them during enumeration and runtime requests. Active behavioral flags: + - `NO_STRING_FETCH`: skips manufacturer/product/serial/configuration string fetches + - `BAD_DESCRIPTOR`: tolerates language/string descriptor fetch failures and continues interface parsing when malformed endpoint descriptors appear + - `RESET_DELAY`: extends first-touch post-reset settle time via early `PortId`-based lookup + - `HUB_SLOW_RESET`: uses a longer hub-oriented reset settle time via early `PortId`-based lookup + - `NO_BOS`: skips BOS descriptor fetch and leaves superspeed capability detection false + - `SHORT_SET_ADDR_TIMEOUT`: uses a shorter `Address Device` command timeout via early `PortId`-based lookup + - `FORCE_ONE_CONFIG`: limits enumeration to configuration index 0 (configuration value 1 path) + - `HONOR_BNUMINTERFACES`: stops interface parsing at `bNumInterfaces` + - `DELAY_CTRL_MSG`: inserts a short post-control-transfer delay + - `NO_SET_CONFIG`: skips `SET_CONFIGURATION` + - `NO_SET_INTF`: skips `SET_INTERFACE` + - `NEED_RESET`: issues xHC `Reset Device` automatically after transfer failures + The early-enumeration timing path now uses optional TOML `port = "[....]"` + selectors in `[[usb_quirk]]` entries for quirks that must act before vendor/product are known. + +9. ✅ **xhcid suspend/resume API skeleton** — xhcid now exposes explicit `port/suspend` and + `port/resume` endpoints plus matching `XhciClientHandle::{suspend_device,resume_device}` + helpers. `PortState` now tracks `PortPmState::{Active,Suspended}` and xhcid enforces + `NO_SUSPEND` by rejecting suspend with `EOPNOTSUPP`. While suspended, control/data/reset + activity returns `EBUSY`. + +10. ✅ **usbhubd suspend coordination slice** — `usbhubd` now tracks downstream child suspend + state and mirrors USB 2 hub-port suspend status into child xhcid devices via + `suspend_device()` / `resume_device()`. This gives us the first real cross-layer coordination + path for hub-attached devices without inventing a separate PM daemon. Remaining gap: suspend + policy/origination is still external, and USB 3 link-state-driven coordination is not yet + implemented. + +**Tier 2 — Medium-term (improves robustness):** + +5. **TT handling from hub.c** — Linux's hub driver reads `wHubDelay` and `bNbrPorts` from hub + descriptors to populate TT think time and MTT capability. Our xHCI driver hardcodes `ttt = 0` + and `mtt = false`. Mining the hub descriptor parsing logic from `hub.c` would replace these + stubs with correct values. + +6. **xHCI controller quirks from xhci-pci.c** — Linux has per-vendor controller workarounds + (Intel PCH, AMD, Etron, Fresco, VIA). Our driver has no controller-specific paths. Mining the + quirk table and applying it through our existing PCI quirk system would add real-hardware + robustness. + + 7. **SCSI command selection from sd.c** — READ(10)/WRITE(10) support is now implemented + (triggered by `INITIAL_READ10` quirk flag). Remaining: REPORT LUNS for multi-LUN devices, + SYNCHRONIZE CACHE (triggered by `NEEDS_SYNC_CACHE` flag), and START STOP UNIT for power + management. + +**Tier 3 — Future (enables new device classes):** + +8. **USB class/subclass/protocol tables from ch9.h** — Complete class code definitions for device + matching in `drivers.toml`. + +9. **USB endpoint descriptor parsing from message.c** — Extended endpoint type mapping for streams + and isochronous support. + +### Mining into the Build + +The Linux kernel source at `build/linux-kernel-cache/` is a build cache, not a tracked dependency. +Mined data must be materialized into durable locations: + +| Mined Data | Target Location | Format | +|---|---|---| +| USB device quirks | `local/recipes/system/redbear-quirks/source/quirks.d/20-usb.toml` | TOML (146 entries ✅) | +| USB compiled-in quirks | `local/recipes/drivers/redox-driver-sys/source/src/quirks/usb_table.rs` | Rust (146 entries ✅) | +| PCI controller quirks | `local/recipes/system/redbear-quirks/source/quirks.d/10-pci.toml` | TOML | +| Storage device flags | `local/recipes/system/redbear-quirks/source/quirks.d/30-storage.toml` | TOML (214 entries ✅, active at runtime ✅) | +| Flag definitions | `local/recipes/drivers/redox-driver-sys/source/src/quirks/mod.rs` | Rust bitflags (22 USB flags ✅) | + +The extraction script at `local/scripts/extract-linux-quirks.py` should be extended to also handle +`drivers/usb/storage/unusual_devs.h` for mass storage device entries. ## Summary USB in Red Bear today is not missing. It is a real userspace host-side subsystem with meaningful enumeration, runtime observability, hub/HID infrastructure, and a low-level userspace API. -Recent work has closed several specific gaps: BOS/SuperSpeed descriptor handling, hub child speed -detection, USB 3 hub configuration stalls, HID error handling, and a comprehensive QEMU validation -harness. +The Red Bear patch layer carries substantial error handling and correctness improvements over the +upstream source: 88 error handling fixes (mutex poisoning recovery, expect/panic replacement, Result +conversions), multiple correctness bug fixes, real event ring growth, +class driver error handling improvements (all three USB class daemons now use `Result` types with +zero `unwrap()`/`expect()` panics), interrupt-driven hub change detection, `ReadCapacity16` +for large disk support, and a USB quirk table expanded from 8 to 146 entries with 22 quirk flags +mined from Linux 7.0. -The remaining gaps are: +All validation is QEMU-only. No real hardware USB testing exists. -- controller interrupt maturity under sustained load -- topology and configuration correctness under attach/detach stress -- HID modernization toward named producers and per-device streams -- re-enabling and validating storage runtime stability -- defining a coherent userspace USB API strategy -- deciding how much modern USB scope Red Bear actually wants -- building broader USB validation coverage +The remaining gaps fall into three categories: -That is the correct framing for a modern, future-proof USB implementation plan in this repo. +**Still-open software work (implementable without hardware):** +- Composite-device endpoint selection across interfaces (xHCI scheme.rs — `//TODO: USE ENDPOINTS FROM ALL INTERFACES`) +- Non-default configuration and alternate-setting support (xHCI scheme.rs) +- SuperSpeedPlus differentiation via Extended Port Status +- TTT (Think Time) propagation from parent hub descriptor into Slot Context +- Event ring growth does not copy pending TRBs from old ring (may lose events under sustained load) + +**Architectural redesign (cross-cutting, not USB-internal):** +- HID producer modernization: per-device streams, hotplug add/remove (requires inputd redesign) +- Userspace USB API: `libusb` WIP, no coherent native story + +**Hardware-dependent or design decisions:** +- Real hardware validation: no controller tested outside QEMU +- Hot-plug stress testing +- Storage I/O validation (read/write to block device) +- usbhubd 1-second polling fallback (only exercisable with real hub hardware) +- Modern USB scope decision: device mode / USB-C / PD + +Software items are tracked in Phase U1 (xHCI internals) and Phase U2 (configuration/composite). +Architectural and hardware items are tracked in Phase U1 (controller hardware validation), Phase U2 +(hub polling fallback), Phase U3 (HID), Phase U4 (storage/API), Phase U5 (modern USB scope +decision), and Phase U6 (validation). + +Linux kernel USB data mining is documented in the "Linux Kernel USB Data Mining" section above. +Linux 7.0 source is available at `build/linux-kernel-cache/linux-7.0/` with 146 USB device quirks, +22 quirk flags (all 19 Linux USB_QUIRK flags covered), 214 active storage device quirks +consumed at runtime by usbscsid, and extensive xHCI/hub/SCSI reference code ready for extraction. diff --git a/local/docs/USB-STORAGE-SPEED-AND-DEVICES.md b/local/docs/USB-STORAGE-SPEED-AND-DEVICES.md new file mode 100644 index 00000000..1059b46b --- /dev/null +++ b/local/docs/USB-STORAGE-SPEED-AND-DEVICES.md @@ -0,0 +1,365 @@ +# Red Bear OS USB Storage, Speed, and Device Integration + +## Purpose + +This document covers USB subsystem areas that the main USB implementation plan +(`USB-IMPLEMENTATION-PLAN.md`) treats at a higher level: mass storage quality, filesystem +integration, device speed handling, backwards compatibility, and integrated USB device paths. + +It is a companion document, not a replacement. Read both together for the complete USB picture. + +## Current Headline + +USB mass storage is **present in the codebase but disabled**. The driver table entry for +`usbscsid` is commented out in `drivers.toml` with the note "#TODO: causes XHCI errors". HID +(keyboard/mouse) and hub handling are enabled and functional in QEMU. + +## USB Mass Storage + +### Architecture + +``` +USB device → xhcid (scheme:usb) → usbscsid → driver_block::DiskScheme → /scheme/disk.usb-* + → filesystem (redoxfs/ext4d) +``` + +| Layer | Component | Status | +|---|---|---| +| Transport | BOT (Bulk-Only Transport) | ✅ Implemented — CBW/CSW signatures validated, tag matching, stall recovery | +| Protocol | SCSI SBC | ⚠️ Partial — READ(16)/WRITE(16) only, missing READ(10)/WRITE(10) | +| Block device | driver_block::DiskScheme | ✅ Functional — registers as `/scheme/disk.usb-{scheme}+{port}-scsi` | +| Partitions | partitionlib (MBR/GPT) | ✅ Parsed on init — exposes `0p0`, `0p1`, etc. | +| Filesystems | redoxfs, ext4d | ✅ Can mount USB block devices via scheme path | + +### BOT Transport Quality + +The BOT transport in `usbscsid/src/protocol/bot.rs` is well-implemented: + +- **CBW handling**: Correct signature (`0x43425355`), per-command tag increment, direction bit, LUN field +- **CSW handling**: Signature validation, tag matching, residue tracking, short packet tolerance +- **Stall recovery**: `ClearFeature(ENDPOINT_HALT)` on both endpoints, `Bulk-Only Mass Storage Reset` + class request (0xFF) for full reset recovery, re-check for persistent stalls +- **Phase errors**: Detected and reported via `ProtocolError` + +### SCSI Command Completeness + +| Command | CDB Size | Status | Notes | +|---|---|---|---| +| INQUIRY | 6 | ✅ | Standard + vendor inquiry data | +| REQUEST SENSE | 6 | ✅ | Fixed-format sense data | +| READ CAPACITY(10) | 10 | ✅ | 32-bit LBA, used as first probe | +| READ CAPACITY(16) | 16 | ✅ | 64-bit LBA, auto-fallback from RC(10) max | +| READ(16) | 16 | ✅ | Primary read path | +| WRITE(16) | 16 | ✅ | Primary write path | +| MODE SENSE(6) | 6 | ✅ | Block descriptor fallback | +| MODE SENSE(10) | 10 | ✅ | Primary block size/count source | +| READ(10) | 10 | ❌ **Missing** | Required for older/simpler devices | +| WRITE(10) | 10 | ❌ **Missing** | Required for older/simpler devices | +| SYNCHRONIZE CACHE | 10 | ⚠️ Opcode only | Never issued | +| START STOP UNIT | 6 | ⚠️ Opcode only | Never issued | +| TEST UNIT READY | 6 | ⚠️ Opcode only | Never issued | +| REPORT LUNS | 12 | ❌ **Missing** | Needed for multi-LUN devices | +| MODE SELECT(6/10) | 6/10 | ❌ **Missing** | Needed for parameter negotiation | +| FORMAT UNIT | 6 | ❌ **Missing** | Rarely needed | + +**Critical gap**: READ(10)/WRITE(10) are not implemented. The daemon uses 16-byte CDBs exclusively. +Devices that only support 10-byte SCSI commands (some older USB flash drives, embedded firmware +devices) will fail. Adding READ(10)/WRITE(10) with automatic fallback (similar to how +READ CAPACITY(10)→(16) already works) is a concrete, bounded improvement. + +### LUN Support + +`get_max_lun()` reads the device's max LUN count via class-specific request, but the daemon +hardcodes `cbw.lun = 0` for all commands. Multi-LUN devices (card readers, multi-slot adapters) +will only expose the first LUN. Supporting multiple LUNs requires: + +1. Iterating from 0 to max_lun +2. Creating separate `UsbDisk` instances per LUN +3. Registering separate `DiskScheme` paths per LUN + +### UAS (USB Attached SCSI) + +UAS is not implemented. The protocol factory in `protocol/mod.rs` only matches protocol 0x50 (BOT). +Protocol 0x62 (UAS) is absent. UAS provides: + +- Multiple simultaneous command pipes (vs BOT's single serialize-execute-wait) +- Stream-based transfers for higher throughput +- Better error recovery semantics + +For USB 3.0 SuperSpeed devices, UAS can provide significantly higher throughput than BOT. + +### Transfer Size Limitations + +- BOT max transfer: 64KB per command (driver_interface.rs hard limit) +- Stream transfer chunk: 32KB per iteration (hardcoded in TransferStream) +- No scatter-gather: all data must fit in a single buffer (explicit TODO in scsi/mod.rs) + +### Why usbscsid is Disabled + +The comment says "#TODO: causes XHCI errors". This likely relates to: + +1. Bulk endpoint configuration issues in the xHCI driver +2. The 64KB transfer limit causing multi-block reads to fragment incorrectly +3. Missing endpoint stall handling during initial enumeration + +**Re-enabling usbscsid is a prerequisite for USB storage validation.** + +## USB Speed Handling + +### Speed Detection + +The xHCI driver detects device speed via PORTSC register bits 10–13. The `ProtocolSpeed` struct +(in `xhci/extended.rs`) classifies speeds: + +| Speed | Bitrate | Detection | Status | +|---|---|---|---| +| Low Speed | 1.5 Mbps | `is_lowspeed()` | ✅ Detected | +| Full Speed | 12 Mbps | `is_fullspeed()` | ✅ Detected | +| High Speed | 480 Mbps | `is_highspeed()` | ✅ Detected | +| SuperSpeed Gen1 x1 | 5 Gbps | `is_superspeed_gen1x1()` | ✅ Detected | +| SuperSpeedPlus Gen2 x1 | 10 Gbps | `is_superspeedplus_gen2x1()` | ✅ Detected | +| SuperSpeedPlus Gen1 x2 | 10 Gbps x2 | `is_superspeedplus_gen1x2()` | ✅ Detected | +| SuperSpeedPlus Gen2 x2 | 20 Gbps x2 | `is_superspeedplus_gen2x2()` | ✅ Detected | + +### Default Control Pipe Max Packet Size + +The driver sets the default control pipe max packet size based on speed: + +| Speed | Max Packet Size | Location | +|---|---|---| +| Low/Full Speed | 8 bytes | mod.rs:1128 | +| High Speed | 64 bytes | mod.rs:1131 | +| SuperSpeed | 512 bytes | mod.rs:1134 | + +### Transfer Type Support + +| Transfer Type | USB Role | Status | Notes | +|---|---|---|---| +| Control | Configuration, enumeration | ✅ Works | Endpoint 0 only | +| Bulk | Mass storage, network | ✅ Works | Used by usbscsid | +| Interrupt | HID, hub status | ✅ Works | Used by usbhubd, usbhidd | +| Isochronous | Audio, video | ❌ ENOSYS | `scheme.rs` explicitly returns `ENOSYS` | + +Isochronous transfers are required for USB audio devices, webcams, and streaming applications. +The driver returns `ENOSYS` (function not implemented) for all isochronous endpoint requests. + +## Backwards Compatibility + +### Transaction Translator (TT) Handling — STUBBED + +USB 1.x Low Speed and Full Speed devices connected behind USB 2.0 High Speed hubs require a +Transaction Translator (TT) to convert between USB 1.x and USB 2.0 protocols. The xHCI +specification handles TT internally in the controller, but the driver must provide correct +parent hub information in the Slot Context during device addressing. + +**Current state**: All TT-related fields are hardcoded: + +| Field | Value | Should Be | Location | +|---|---|---|---| +| `mtt` (Multi-TT) | `false` | Read from parent hub descriptor | mod.rs:1057 | +| `ttt` (TT Think Time) | `0` | Encoded from parent hub descriptor | mod.rs:1114 | +| `needs_parent_info` | `true` (forced) | Based on actual device speed topology | mod.rs:1070 | + +The TODOs at mod.rs:1066–1068 explicitly state the values need to be determined from actual +device speed and hub topology. Without correct TT information: + +- Low Speed devices (1.5 Mbps) behind USB 2.0 hubs may not enumerate correctly on real hardware +- Full Speed devices (12 Mbps) behind USB 2.0 hubs may fail during bulk transfers +- Multi-TT hubs with multiple LS/FS devices attached may have timing violations + +### USB 1.x Compatibility + +- **Low Speed (1.5 Mbps)**: Speed detection works. Default control pipe size correct (8 bytes). + TT handling stubbed — may fail on real hardware behind HS hubs. +- **Full Speed (12 Mbps)**: Speed detection works. Default control pipe size correct (8 bytes). + Same TT limitation. + +### USB 2.0 Compatibility + +- **High Speed (480 Mbps)**: Primary tested speed in QEMU. Bulk, Interrupt, Control all functional. + Max packet size 64 bytes correctly set. + +### USB 3.x Compatibility + +- **SuperSpeed (5 Gbps)**: Protocol speed detection works. BOS descriptor fetching implemented. + Max packet size 512 bytes correctly set. SuperSpeed Companion Descriptor parsed. +- **SuperSpeedPlus (10–20 Gbps)**: Protocol speed detection works. SuperSpeedPlus Isochronous + Companion Descriptor parsed. No functional testing. + +### Speed-Specific Gaps + +- No speed-specific timeout or retry tuning — all controller-level timeouts are 1-second hardcoded +- No burst transaction support for SuperSpeed bulk endpoints (burst field parsed but not used in + transfer scheduling) +- No streams support for USB 3.0 bulk endpoints (Stream ID capability parsed but not exercised) + +## Integrated USB Devices + +### Device Autospawn Flow + +``` +1. Device plugs in +2. xhcid detects port status change +3. xhcid resets port, enumerates device, reads config descriptor +4. spawn_drivers() iterates interfaces: + - For each interface with alternate_setting == 0: + - Match class code (+ optional subclass) against drivers.toml + - If match: spawn daemon with $SCHEME, $PORT, $IF_NUM/$IF_PROTO +5. Each spawned daemon opens its USB interface via xhcid_interface +6. Daemon registers its own scheme or connects to existing schemes +``` + +### Driver Table (`drivers.toml`) + +```toml +# Mass Storage — DISABLED (#TODO: causes XHCI errors) +#[[drivers]] +#name = "SCSI over USB" +#class = 8; subclass = 6 +#command = ["usbscsid", "$SCHEME", "$PORT", "$IF_PROTO"] + +[[drivers]] +name = "USB HUB"; class = 9; subclass = -1 +command = ["usbhubd", "$SCHEME", "$PORT", "$IF_NUM"] + +[[drivers]] +name = "USB HID"; class = 3; subclass = -1 +command = ["usbhidd", "$SCHEME", "$PORT", "$IF_NUM"] +``` + +### Supported Device Paths + +| Device Class | Daemon | Scheme Path | Integration | +|---|---|---|---| +| **Hub** (class 9) | `usbhubd` | Manages child ports via xhci scheme | Triggers nested device enumeration | +| **HID** (class 3) | `usbhidd` | Writes to `/scheme/input/producer` via inputd | Orbital consumes `/scheme/input` | +| **Mass Storage** (class 8) | `usbscsid` | Registers `disk.usb-{scheme}+{port}-scsi` | Filesystems mount via scheme path | + +### HID Integration Detail + +``` +USB keyboard/mouse → xhcid → usbhidd → inputd (scheme:input) → Orbital (display server) + ↑ + /scheme/input/producer (drivers write here) + /scheme/input/consumer (display server reads here) + /scheme/input/handle/{name} (per-device handles) +``` + +- `usbhidd` implements boot protocol HID (keyboard, mouse, scroll, button) +- Events: `orbclient::KeyEvent` for keyboards, `orbclient::MouseEvent`/`ButtonEvent`/`ScrollEvent` +- The `inputd` multiplexer collects from all input producers (USB HID, PS/2 via `ps2d`, etc.) + +### Storage Integration Detail + +``` +USB flash drive → xhcid → usbscsid → DiskScheme → /scheme/disk.usb-usb+1-scsi + ↓ + redoxfs/ext4d mount + ↓ + /scheme/file/{mount-point} +``` + +- `DiskScheme` from `driver-block` provides block I/O via scheme +- Partition table parsing via `partitionlib` (MBR + GPT) +- Partitions exposed as `0p0`, `0p1`, etc. under the disk scheme + +### Composite Device Handling + +Composite USB devices (e.g., keyboard+mouse combo, keyboard+trackpad) are partially supported: + +- xhcid iterates **all interfaces** in the first configuration +- Each interface matching a `drivers.toml` entry spawns its own daemon process +- Alternate settings (`alternate_setting != 0`) are explicitly skipped +- No vendor/product ID matching — class code only + +**What works**: A keyboard+mouse combo with two HID interfaces will spawn two `usbhidd` processes, +each handling one interface. Both produce input events through inputd. + +**What doesn't work**: Devices requiring alternate settings for full functionality. Devices needing +vendor-specific drivers. + +### Unsupported Device Classes + +These USB device classes have no driver in Red Bear OS: + +| Class | Name | Use Case | Blocker | +|---|---|---|---| +| 0x01 | Audio | USB headsets, speakers | Isochronous transfers not implemented (ENOSYS) | +| 0x0E | Video | Webcams | Isochronous transfers not implemented | +| 0x02 | CDC/ACM | USB serial, modems | No driver written | +| 0x0A | CDC-Data | USB networking | No driver written | +| 0x0B | Chip Card | Smart card readers | No driver written | +| 0x0D | Content Security | Conditional access | No driver written | +| 0x0F | Personal Healthcare | Medical devices | No driver written | +| 0x06 | Still Image | Cameras (PTP/MTP) | No driver written | +| 0x07 | Printer | USB printers | No driver written | +| 0x10 | Audio/Video | AV devices | Isochronous required | +| 0x11 | Billboard | USB-C alternate mode | No driver written | +| 0x12 | USB Type-C Bridge | USB-C muxes | No driver written | +| 0xDC | Diagnostic | USB debug | No driver written | +| 0xE0 | Wireless Controller | Bluetooth, Wi-Fi dongles | Separate (redbear-btusb) | +| 0xEF | Miscellaneous | Firmware update, etc. | No driver written | +| 0xFF | Vendor Specific | Custom devices | No driver written | + +## Implementation Priorities + +### Priority 1: Re-enable USB Mass Storage + +The most impactful single change. Requires diagnosing and fixing the "causes XHCI errors" issue. +Likely causes: + +1. Bulk endpoint configuration in scheme.rs — endpoint type mismatch during configuration +2. Transfer size handling — the 64KB limit may fragment BOT CBW/CSW sequences +3. Missing stall recovery during initial BOT reset + +### Priority 2: Add READ(10)/WRITE(10) + +Implement 10-byte CDB variants with automatic fallback. Pattern already exists for READ CAPACITY. +Required for device compatibility: + +```rust +// Proposed fallback pattern (matching existing RC10→RC16 pattern): +pub fn read(&mut self, lba: u64, buf: &mut [u8], protocol: &mut dyn Protocol) -> Result<()> { + if lba <= u32::MAX as u64 && buf.len() <= u32::MAX as usize { + // Try READ(10) first — wider device compatibility + let cmd = self.cmd_read10()?; + *cmd = cmds::Read10::new(lba as u32, ...); + ... + } + // Fall back to READ(16) for large addresses +} +``` + +### Priority 3: Fix Transaction Translator Handling + +Replace hardcoded TT values with actual parent hub descriptor data. This is required for real +hardware where LS/FS devices sit behind HS hubs. + +### Priority 4: Multi-LUN Support + +Iterate device LUNs and create separate disk scheme instances per LUN. Required for card readers +and multi-slot adapters. + +### Priority 5: Isochronous Transfers + +Implement the Isoch TRB path in scheme.rs to enable USB audio and video device classes. + +### Priority 6: UAS Transport + +Add USB Attached SCSI protocol support for SuperSpeed storage devices. Higher throughput than BOT +but requires stream ID support in the xHCI driver. + +## Summary + +USB mass storage exists in the codebase with a well-implemented BOT transport, proper SCSI command +set (with gaps in READ/WRITE(10)), and functional block device integration — but it is **disabled** +due to xHCI errors during device configuration. The most impactful work is diagnosing and fixing +that issue, then adding READ(10)/WRITE(10) for wider device compatibility. + +Speed handling covers the full range from Low Speed (1.5 Mbps) to SuperSpeedPlus (20 Gbps) at the +detection level, but TT handling is stubbed and isochronous transfers return ENOSYS. Backwards +compatibility for USB 1.x devices behind USB 2.0 hubs requires TT fix work. + +Device integration supports hubs and HID via autospawn. Composite devices get all interfaces +handled. No vendor/product matching exists. No audio, video, serial, or networking USB device +classes have drivers. diff --git a/local/docs/USB-VALIDATION-RUNBOOK.md b/local/docs/USB-VALIDATION-RUNBOOK.md index d085e46a..18b6a478 100644 --- a/local/docs/USB-VALIDATION-RUNBOOK.md +++ b/local/docs/USB-VALIDATION-RUNBOOK.md @@ -98,6 +98,11 @@ enumerated, ports have devices attached, and device descriptors are readable. | Script | What it tests | |--------|---------------| -| `test-usb-qemu.sh --check` | Full USB stack (xHCI + HID + SCSI + BOS) | -| `test-usb-storage-qemu.sh` | USB mass storage autospawn | -| `test-xhci-irq-qemu.sh --check` | xHCI interrupt delivery mode | +| `test-usb-qemu.sh --check` | Full USB stack (xHCI + HID + SCSI + BOS + no crashes) | +| `test-usb-storage-qemu.sh` | USB mass storage autospawn + crash pattern check | +| `test-xhci-irq-qemu.sh --check` | xHCI interrupt delivery mode (MSI/MSI-X/INTx) | + +In-guest quick checks: +- `lsusb` — walks `/scheme/usb.*`, reads descriptors, shows vendor:product + quirks +- `redbear-info --verbose` — reports USB controller count and integration status +- `redbear-usb-check` — scheme tree walk with pass/fail exit code