Advance USB implementation plan and validation docs

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-04-17 13:32:43 +01:00
parent 6f93b6ed43
commit 9bda932ed4
3 changed files with 862 additions and 340 deletions
+489 -337
View File
@@ -3,9 +3,10 @@
## Purpose ## Purpose
This document defines the current state, completeness, and implementation path for USB in Red Bear 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 actually usable**, and **what still needs to be implemented** before Red Bear can honestly claim a
modern, future-proof USB stack. 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**. 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 ## Current Repo State
### Summary ### Summary
USB in Red Bear OS is **present and improving**. 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 The Red Bear USB stack consists of:
daemon, hub and HID class spawning, native USB observability (`lsusb`, `usbctl`, `redbear-info`),
and a low-level userspace client API through `xhcid_interface`.
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 ### Red Bear xHCI Patch Layer
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<u8>`) 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
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<u64>` 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 - HID is still wired through the legacy mixed-stream `inputd` path
- SuperSpeedPlus differentiation requires Extended Port Status (not yet implemented) - SuperSpeedPlus differentiation requires Extended Port Status (not yet implemented)
- TTT (Think Time) in Slot Context hardcoded to 0 — needs parent hub descriptor propagation - 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`) - Composite devices and non-default alternate settings use first-match only
- `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 (`//TODO: USE ENDPOINTS FROM ALL INTERFACES`)
- `usbhubd` startup uses `unwrap_or_else` with graceful exit (not panics), but per-child-port handle creation now skips failed ports with error logging - `grow_event_ring()` swaps to a new ring but does not copy pending TRBs from the old one; under
- there is no evidence of validated support for broader USB classes or modern USB-C / dual-role sustained event-ring-full conditions this may lose in-flight events
scope - ~57 TODO/FIXME comments remain across xHCI driver files
- usbhubd: interrupt-driven change detection implemented; 1-second polling retained as fallback
### Identified Correctness Issues (from audit) - usbscsid: `ReadCapacity16` now implemented with automatic fallback from `ReadCapacity10`
- No real hardware USB validation — all testing is QEMU-only
A comprehensive audit of the xHCI driver identified these correctness issues. Fixes are being - No hot-plug stress testing
applied through `local/patches/base/redox.patch`: - 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
- **ERDP read pointer bug** (`event.rs`): `erdp()` returns the software producer pointer from the - USB quirk flags expanded from 9 to 22 (13 new flags from Linux 7.0 including NO_BOS, HUB_SLOW_RESET)
ring state instead of reading the actual hardware dequeue pointer from the ERDP runtime register. - Terminus hub (0x1A40:0x0101) corrected from `no_lpm` to `hub_slow_reset` per Linux semantics
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.
### Current Status Matrix ### Current Status Matrix
| Area | State | Notes | | Area | State | Notes |
|---|---|---| |---|---|---|
| Host mode | **usable / experimental** | Real host-side stack exists, interrupt-driven, not broadly validated on hardware | | Host mode | **builds / QEMU-validated** | Real host-side stack, interrupt-driven, QEMU-validated only |
| 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 | | 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 / improving** | `usbhubd` uses interrupt EP1, change bits cleared, USB 3 speed-aware attach | | Hub handling | **builds / good quality** | `usbhubd`: all `expect()` eliminated, interrupt-driven change detection with polling fallback, graceful per-port error handling |
| HID | **builds / usable in narrow path** | `usbhidd` handles keyboard/mouse/button/scroll via legacy input path, no panics in report loop | | 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 / 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 | | 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 | | 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()` | | 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` **Upstream state** — 91 `unwrap()`, 25 `expect()`, 7 `panic!()`, ~57 TODO/FIXME across ~6000
- `recipes/core/base/source/drivers/usb/xhcid/config.toml` autoloads `xhcid` by PCI class match lines of Rust.
- `recipes/core/base/source/drivers/usb/xhcid/drivers.toml` enables hub and HID subdrivers by
default
### 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` Key files and their sizes:
- `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
### 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 ### Class drivers
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
## Current Gaps and Limits | Daemon | Lines | Error Handling Quality | Remaining unwrap/expect | Key Gaps |
|---|---|---|---|---|
| `usbhubd` | ~430 | **Good**`Result<(), Box<dyn Error>>`, 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 ### In-guest tooling
- TODOs around endpoint selection across interfaces
- TTT (Think Time) hardcoded to 0 in Slot Context — needs parent hub descriptor propagation
This means the current stack is more than a bring-up stub, but still below the bar for a reliable, | Tool | What it does | Installation |
future-proof USB controller foundation. |---|---|---|
| `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 `local/docs/USB-VALIDATION-RUNBOOK.md` documents two operator paths:
stalling, and child device speed detection is correct when devices attach through hubs. - **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 ### What is NOT validated
topologies are runtime-proven in a broad sense.
### 3. HID works through a legacy path - Real hardware USB controllers (QEMU `qemu-xhci` only)
- Hub topology (direct-attached devices only)
`usbhidd` exists and is meaningful evidence that USB HID is not hypothetical. - USB 3 SuperSpeed data paths
- Isochronous or streaming transfers
However, the current HID path is still tied to the older anonymous `inputd` producer model. - Hot-plug stress testing
`local/docs/INPUT-SCHEME-ENHANCEMENT.md` already defines the needed next step: named producers, - USB storage data I/O (read/write to block device)
per-device streams, and explicit hotplug events. - USB device mode / OTG / USB-C
### 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.
## Implementation Plan ## Implementation Plan
### Repo-fit note ### Repo-fit note
Some of the implementation targets below live in upstream-managed trees such as Some implementation targets live in upstream-managed trees such as
`recipes/core/base/source/...`. `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
In Red Bear, work against those paths should be carried through the appropriate patch carrier under the technical target path, not a recommendation to bypass Red Bear's overlay/patch discipline.
`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.
### Phase U0 — Support Model and Scope Freeze ### Phase U0 — Support Model and Scope Freeze
@@ -235,57 +217,40 @@ not a recommendation to bypass Red Bear's overlay/patch discipline.
current scope current scope
- Add USB status guidance to the profile/support-language discipline used elsewhere in Red Bear - 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` **Exit criteria**: USB claims are tied to a named profile or package-group slice; no doc implies
- `docs/07-RED-BEAR-OS-IMPLEMENTATION-PLAN.md` broad USB support without a matching validation label.
- 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
--- ---
### Phase U1 — xHCI Controller Baseline ### Phase U1 — xHCI Controller Baseline
**Status**: Partially complete. **Status**: Substantially complete in the Red Bear patch layer. Runtime validation still QEMU-only.
**Completed**: **Completed (Red Bear patch)**:
- BOS/SuperSpeed descriptor fetching wired up in `get_desc()``fetch_bos_desc()` called, - BOS/SuperSpeed descriptor fetching wired up
`bos_capability_descs()` iterator parsed, `supports_superspeed`/`supports_superspeedplus` stored - Speed detection for hub child devices with `UsbSpeed` enum
in `DevDesc` - Interrupt-driven operation restored (MSI/MSI-X/INTx)
- Speed detection for hub child devices fixed — `UsbSpeed` enum with `from_v2_port_status()` and - Event ring growth fully implemented (ring doubling, DMA, ERDP/ERSTBA, DCS)
`from_v3_port_status()` mapping, passed via `attach_with_speed()` protocol from `usbhubd` - 88 error handling fixes across scheme.rs, mod.rs, irq_reactor.rs, ring.rs
- `attach_device_with_speed()` accepts optional speed override byte, maps to PSIV via - ERDP split into `dequeue_ptr()` + `erdp(&RuntimeRegs)`
`lookup_speed_category()` - `trb_phys_ptr()` returns `Result<u64>`
- Mutex poisoning recovery on all hot-path locks
**Remaining**: **Remaining**:
- Validate one controller family as the first real support target - Validate one controller family on real hardware (requires hardware)
- Tighten controller-state correctness under sustained load - 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 **Where**: `recipes/core/base/source/drivers/usb/xhcid/` (via `local/patches/base/redox.patch`)
family.
**What to do**: **Exit criteria**: one target controller family repeatedly boots without `xhcid` panic on real
hardware; controller enumerates attached devices reliably across repeated boot cycles.
- 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
--- ---
@@ -293,38 +258,25 @@ family.
**Status**: Partially complete. **Status**: Partially complete.
**Completed**: **Completed (Red Bear patch)**:
- USB 3 hub endpoint configuration stall handled`SET_INTERFACE` is always sent; stall on - USB 3 hub endpoint configuration stall handled
`(0, 0)` is tolerated with debug log and graceful continuation - `endp_direction` off-by-one fixed (`checked_sub(1)`)
- `usbhubd` now passes `interface_desc` and `alternate_setting` to `configure_endpoints` - `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**: **Remaining**:
- validate repeated attach/detach/reset behavior - Validate repeated attach/detach/reset behavior under stress (requires real hardware)
- support non-default configurations and alternate settings where needed - Support non-default configurations and alternate settings (requires xHCI config logic in scheme.rs)
- improve composite-device handling and endpoint selection across interfaces - Improve composite-device handling and endpoint selection across interfaces (requires xHCI config logic in scheme.rs)
- separate "enumerates" from "stays correct under topology changes"
**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**: **Exit criteria**: repeated hub and hotplug scenarios complete without stale topology state; at
least one composite device configures correctly beyond the simplest path.
- 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
--- ---
@@ -332,69 +284,51 @@ family.
**Status**: Partially complete. **Status**: Partially complete.
**Completed**: **Completed (Red Bear patch)**:
- `usbhidd` error handling improved — `assert_eq!` replaced with `anyhow::bail!`, `.expect()` in - `usbhidd` error handling improved — `anyhow::Result` with context, no panics in report loop, zero `unwrap()`/`expect()` calls
main loop replaced with `match` + `continue` for graceful recovery - `assert_eq!` replaced with `anyhow::bail!`
- Display write failures logged as warnings instead of panicking
**Remaining**: **Remaining** (all require architectural changes to `inputd`, not USB-internal code):
- migrate `usbhidd` toward named producers and per-device streams - Migrate `usbhidd` toward named producers and per-device streams (requires inputd redesign)
- expose hotplug add/remove behavior cleanly to downstream consumers - Expose hotplug add/remove behavior cleanly to downstream consumers (requires inputd redesign)
- align USB HID with the `inputd` enhancement design already documented in-tree - 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**: **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.
- 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
--- ---
### Phase U4 — Storage, Userspace API, and Class Expansion ### 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) **Remaining** (all require hardware or design decisions):
- decide whether BOT-only is sufficient short-term or whether UAS is part of the next step - Runtime I/O validation: prove stall recovery works under real device I/O (requires hardware)
- bring `libusb` to a runtime-tested state or explicitly replace it with a Red Bear-native API - Decide whether BOT-only is sufficient short-term or UAS is needed (design decision)
strategy - Bring `libusb` to a runtime-tested state or replace with Red Bear-native API (large scope, deferred)
- either fix `usbutils` or document native tools as the intended replacement - Choose the next USB class families explicitly (design decision)
- choose the next USB class families explicitly instead of implying broad support
**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 **Where**: `recipes/core/base/source/drivers/storage/usbscsid/`, `recipes/wip/libs/other/libusb/`,
2. generic userspace API story `local/recipes/system/redbear-hwutils/`
3. USB networking or Bluetooth dongle path
4. audio/video only after controller and transfer maturity justify it
**Where**: **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.
- `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
--- ---
@@ -404,20 +338,16 @@ family.
platform. platform.
**What to decide**: **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 **Why this phase exists**: These are architectural choices, not small driver add-ons. A
- whether OTG / dual-role matters for target hardware future-proof stack cannot leave them implicit forever.
- 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**: **Exit criteria**: a written architecture decision exists for included and excluded modern USB
scope.
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
--- ---
@@ -426,69 +356,291 @@ implicit forever.
**Status**: Partially complete. **Status**: Partially complete.
**Completed**: **Completed**:
- `local/scripts/test-usb-qemu.sh`Full USB stack validation harness that boots with xHCI + - `test-usb-qemu.sh`full USB stack validation harness (6 checks)
keyboard + tablet + mass storage, then checks for xHCI interrupt mode, HID spawn, SCSI spawn, - `test-usb-storage-qemu.sh` — USB mass storage autospawn check
BOS processing, and no crash-class errors - `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**: **Remaining** (all require hardware):
- add hardware-matrix coverage for target controllers and class families - Add hardware-matrix coverage for target controllers and class families
- extend `redbear-info` only where passive probing can be honest - Add USB storage data I/O validation (read/write to block device)
- tie support claims to a concrete profile or package-group slice - Add hot-plug stress testing harness
**Goal**: Turn USB from a collection of partial capabilities into an evidence-backed support story. **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.
**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
## Support-Language Guidance ## Support-Language Guidance
Until U1 through U3 are substantially complete, Red Bear should avoid broad phrases such as: Until U1 through U3 are substantially complete, Red Bear should avoid broad phrases such as:
- USB support works - "USB support works"
- USB storage is supported - "USB storage is supported"
- USB is complete - "USB is complete"
Prefer language such as: Prefer language such as:
- xHCI host support is present but experimental - "xHCI host support is present but experimental"
- USB enumeration and HID-adjacent host paths exist in-tree - "USB enumeration and HID-adjacent host paths exist in-tree"
- USB support remains controller-variable - "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 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 = "<root>[.<route>...]"`
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<n>/suspend` and
`port<n>/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 ## Summary
USB in Red Bear today is not missing. It is a real userspace host-side subsystem with meaningful 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. 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 The Red Bear patch layer carries substantial error handling and correctness improvements over the
detection, USB 3 hub configuration stalls, HID error handling, and a comprehensive QEMU validation upstream source: 88 error handling fixes (mutex poisoning recovery, expect/panic replacement, Result
harness. 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 The remaining gaps fall into three categories:
- 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
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.
+365
View File
@@ -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 1013. 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:10661068 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 (1020 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.
+8 -3
View File
@@ -98,6 +98,11 @@ enumerated, ports have devices attached, and device descriptors are readable.
| Script | What it tests | | Script | What it tests |
|--------|---------------| |--------|---------------|
| `test-usb-qemu.sh --check` | Full USB stack (xHCI + HID + SCSI + BOS) | | `test-usb-qemu.sh --check` | Full USB stack (xHCI + HID + SCSI + BOS + no crashes) |
| `test-usb-storage-qemu.sh` | USB mass storage autospawn | | `test-usb-storage-qemu.sh` | USB mass storage autospawn + crash pattern check |
| `test-xhci-irq-qemu.sh --check` | xHCI interrupt delivery mode | | `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