b5205e162d
Replace v1 (now archived/USB-IMPLEMENTATION-PLAN-v1-2026-04.md) with a comprehensive v2 that re-audits every daemon against local/sources/base/ HEAD, aligns with Redox 0.x USB HEAD (Jan-Jul 2026), and reorganizes phases around bare-metal correctness gaps. Key v1→v2 corrections: - xHCI interrupts are *not* restored in production (main.rs:141 hardcodes Polling). This was the biggest v1 overstatement. P0-A1 now fixes it. - uhcid/ohcid are 35-line stubs, not "ownership-grade". P0-B2 gives them real enumeration over usb-core. - ehcid does not auto-spawn class drivers. P0-B1 adds that. - The base fork carries only one USB commit. The 88-fix claim lived in patch carriers that path-sourced recipes don't apply. v2 records this honestly and recommends per-feature commits on submodule/base. Also: - USB-VALIDATION-RUNBOOK.md restored from archived/ (operationally current). - local/AGENTS.md: operator override allowing agents to create submodules when really necessary (2026-07-07), with a 4-point necessity test. - archived/README.md supersession table updated with v1 plan and XHCID plan.
470 lines
30 KiB
Markdown
470 lines
30 KiB
Markdown
# Red Bear OS USB Implementation Plan — v2
|
||
|
||
> **Status:** Canonical. Replaces `archived/USB-IMPLEMENTATION-PLAN-v1-2026-04.md`.
|
||
> **Date:** 2026-07-07.
|
||
> **Supersession reason:** v1 (Apr 2026) overstated several capabilities relative to the
|
||
> then-current source. v2 re-audits every daemon against `local/sources/base/` HEAD,
|
||
> aligns with Redox 0.x USB HEAD (Jan 2025 – Jun 2026), and reorganizes phases around the
|
||
> actual bare-metal correctness gaps. Validation labels are now source-anchored rather than
|
||
> patch-anchored.
|
||
>
|
||
> **Sibling docs:**
|
||
> `USB-VALIDATION-RUNBOOK.md` (operator path — restored from `archived/`); the older
|
||
> `archived/USB-BOOT-INPUT-PLAN.md` and `archived/XHCID-DEVICE-IMPROVEMENT-PLAN.md` are
|
||
> kept as historical reference but are not the planning authority.
|
||
|
||
---
|
||
|
||
## 0. Purpose and scope
|
||
|
||
This plan is the **single planning authority** for the USB subsystem in Red Bear OS. It
|
||
answers four questions honestly:
|
||
|
||
1. **What is built?** — every host controller, class driver, scheme, and observability tool
|
||
that actually exists in `local/sources/base/` and `local/recipes/drivers/`. Status is
|
||
derived from the current source tree, not from prior memory or from patch carriers.
|
||
2. **What was patched?** — every durable Red Bear modification, with file paths
|
||
(`local/patches/base/P*.patch` for the base module, dedicated local recipes or forks
|
||
otherwise).
|
||
3. **What is actually usable?** — explicitly distinguishes **builds**, **enumerates**,
|
||
**usable (narrow path)**, **validated (QEMU)**, **validated (real hardware)**, and
|
||
**experimental**. A label is only ever **validated** if the matching proof has run
|
||
on the matching artifact under the matching config.
|
||
4. **What is missing?** — the real bare-metal-blockers, the upstream-comparable gaps, the
|
||
architectural decisions still deferred, and the durability problems that this plan owns.
|
||
|
||
### Validation labels (canonical, do not redefine elsewhere)
|
||
|
||
- **builds** — code is in tree and compiles. Not a usability claim.
|
||
- **enumerates** — runtime surfaces can discover controllers, ports, descriptors.
|
||
- **usable (narrow path)** — one controller family / one class family works in a bounded,
|
||
repeatable scenario; other paths are likely broken.
|
||
- **validated (QEMU)** — a documented QEMU script passed on the matching recipe, config, and
|
||
commit. Reproducible on a Linux x86_64 host.
|
||
- **validated (real hardware)** — a named physical controller + class, with a captured log,
|
||
on real bare metal. This is what an end user can expect.
|
||
- **experimental** — present for bring-up but not in any support-promised path.
|
||
|
||
**Honesty rule.** `builds` is **not** equivalent to `usable`. `validated (QEMU)` is **not**
|
||
equivalent to `validated (real hardware)`. The plan never mixes these categories. Where
|
||
prior text conflated them, this v2 corrects.
|
||
|
||
### Plan structure
|
||
|
||
| Section | Authority | Updates cadence |
|
||
|---|---|---|
|
||
| §1 Source audit (controllers, class drivers, schemes, tooling) | ground truth | on every source-tree bump |
|
||
| §2 Patch carriers | every durable Red Bear diff | on every patch add/rebase |
|
||
| §3 Status matrix (one row per component) | single source of truth for "is it working" | on every status change |
|
||
| §4 Upstream divergence: what Redox 0.x USB HEAD has that we have not | required adoption list | on every upstream bump |
|
||
| §5 Bare-metal input correctness (boot-time USB keyboard) | the bare-metal failure modes | on every controller or class change |
|
||
| §6 Phase P0–P5 (execution order) | who does what next | reviewed monthly |
|
||
| §7 Validation inventory and bounded proofs | the proof surfaces | on every script add/break |
|
||
| §8 Durability posture | local fork health, patch carriers, archival policy | on every base fork bump |
|
||
| §9 Support language | how the rest of Red Bear should describe USB | on every phase change |
|
||
|
||
---
|
||
|
||
## 1. Source audit — what is actually in the tree
|
||
|
||
Red Bear follows the upstream Redox model: **all USB logic is in userspace** (`drivers/usb/`
|
||
plus `local/recipes/drivers/usb-core/`). The kernel exposes `irq:`, `memory:`, `pcid:`,
|
||
`event:`, and `scheme:` surfaces that userspace USB daemons consume. There is no kernel USB
|
||
host stack, and the v1 phase plan's mention of "kernel MSI/MSI-X plumbing" was a reference
|
||
to that surface, not a kernel change.
|
||
|
||
### 1.1 Host controllers
|
||
|
||
| Daemon | Source | Lines | Reality today | Scheme registered |
|
||
|---|---|---|---|---|
|
||
| **xhcid** | `local/sources/base/drivers/usb/xhcid/` | ~6000 LoC across 25 files | Builds. Real ring/TRB/context/transfer engine. Polling in production (see §1.6). | `usb.<pci_name>_xhci` |
|
||
| **ehcid** | `local/recipes/drivers/ehcid/source/src/` | ~1550 LoC (3 files) | Builds. Real MMIO init, frame list, QH/TD, port reset. **No class-driver auto-spawn.** | `usb` |
|
||
| **uhcid** | `local/recipes/drivers/uhcid/source/src/main.rs` | 35 LoC | Builds. **Real stub.** Reads PCI BAR4, sleeps forever. No scheme. | — |
|
||
| **ohcid** | `local/recipes/drivers/ohcid/source/src/main.rs` | 35 LoC | Builds. **Real stub.** Identical pattern to uhcid. | — |
|
||
|
||
**Honesty corrections vs v1:**
|
||
|
||
- v1 said *"EHCI/UHCI/OHCI — ownership, port handling, and logging exist, but they are not
|
||
yet full runtime enumeration paths"*. For **uhcid** and **ohcid** this is too generous —
|
||
they are 35-line stubs that **only read PCI BAR4 and sleep**. They are not even
|
||
ownership-grade; the controller is never probed, no port state is published, no error
|
||
is logged past init.
|
||
- v1 said *"xHCI interrupt-driven operation restored"*. The current source at
|
||
`xhcid/src/main.rs:141` hardcodes polling:
|
||
```rust
|
||
let (irq_file, interrupt_method) = (None, InterruptMethod::Polling); //get_int_method(&mut pcid_handle);
|
||
//TODO: Fix interrupts.
|
||
```
|
||
The `get_int_method` function exists, MSI-X/MSI/INTx branches are written, but the
|
||
function is bypassed at runtime. §4 captures the upstream commits that help finish this.
|
||
|
||
### 1.2 Class drivers
|
||
|
||
| Daemon | Source | LoC | Reality | Notes |
|
||
|---|---|---|---|---|
|
||
| **usbhubd** | `local/sources/base/drivers/usb/usbhubd/` | 249 | Builds; runs. | Polls port status (1s fallback retained from v1). |
|
||
| **usbhidd** | `local/sources/base/drivers/input/usbhidd/` | 576 | Builds; runs. | Named-producer input (`usb-{port}-if{n}`) + legacy VT fallback. |
|
||
| **usbscsid** | `local/sources/base/drivers/storage/usbscsid/` | ~1800 | Builds; runs. | BOT/SCSI, `ReadCapacity16`, 3 storage quirk flags active. |
|
||
| **usbctl** | `local/sources/base/drivers/usb/usbctl/` | 54 | Builds. CLI only. | Minimal — port/endpoint status query. |
|
||
| **ucsid** | `local/sources/base/drivers/usb/ucsid/` | 839 | Builds. | USB-C UCSI topology over ACPI + I2C; `/scheme/ucsi`. |
|
||
| **redbear-usbaudiod** | `local/recipes/system/redbear-usbaudiod/` | (small) | Builds; wired in `redbear-mini.toml`. | USB Audio Class 1. |
|
||
| **redbear-acmd** | `local/recipes/system/redbear-acmd/` | (small) | Builds; wired via `drivers.d/70-usb-class.toml`. | USB CDC ACM serial. |
|
||
| **redbear-ecmd** | `local/recipes/system/redbear-ecmd/` | (small) | Builds; wired via `drivers.d/70-usb-class.toml`. | USB CDC ECM/NCM ethernet. |
|
||
| **redbear-btusb** | `local/recipes/drivers/redbear-btusb/` | (small) | Builds. | Bluetooth USB transport — see BLUETOOTH-IMPLEMENTATION-PLAN. |
|
||
|
||
### 1.3 USB core library
|
||
|
||
| Crate | Source | Notes |
|
||
|---|---|---|
|
||
| **usb-core** | `local/recipes/drivers/usb-core/source/src/` | 6 files (lib.rs, dma.rs, scheme.rs, spawn.rs, transfer.rs, types.rs). Provides `UsbHostController` trait, `SetupPacket`, `PortStatus`, `TransferDirection`, `DmaBuffer`, descriptor parsers, `control_transfer`, `spawn_usb_driver`. Used by ehcid. **Currently not used by xhcid, uhcid, or ohcid.** |
|
||
|
||
This trait is the most important "infrastructure that already exists" item in this plan:
|
||
it is the natural target for uhcid/ohcid runtime enumeration (§6 P0-B2) and for any
|
||
future host port — including the xhcid → USB-core path that future xHCI cleanup will allow.
|
||
|
||
### 1.4 Tooling and observability
|
||
|
||
| Tool | Source | Reality |
|
||
|---|---|---|
|
||
| `lsusb` | `local/recipes/system/redbear-hwutils/source/src/bin/lsusb.rs` | Walks `/scheme/usb.*`, reads descriptors. |
|
||
| `redbear-usb-check` | `local/recipes/system/redbear-hwutils/source/src/bin/redbear-usb-check.rs` | In-guest scheme tree validator. |
|
||
| `redbear-usb-storage-check` | `local/recipes/system/redbear-hwutils/source/src/bin/redbear-usb-storage-check.rs` | Mass-storage round-trip validator. |
|
||
| `usbctl` | `local/sources/base/drivers/usb/usbctl/` | CLI for port/endpoint status. |
|
||
|
||
### 1.5 Patch carriers on `local/patches/base/`
|
||
|
||
The **durable** Red Bear USB modifications are carried as `local/patches/base/P*.patch`
|
||
files. These are applied atomically by the cookbook against the recipe source tree during
|
||
fetch+cook.
|
||
|
||
| Patch | Size | Purpose |
|
||
|---|---|---|
|
||
| `P1-xhcid-device-lifecycle.patch` | 2351 lines | Attach publication, transactional configure, bounded detach. |
|
||
| `P1-xhcid-port-pm-read-fix.patch` | 942 lines | Port PM state read. |
|
||
| `P1-xhcid-uevent-logging.patch` | 20 lines | Uevent audit trail. |
|
||
| `P2-usb-pm-and-drivers.patch` | 158 lines | USB PM (suspend/resume/quirk integration). |
|
||
| `P3-xhci-device-hardening.patch` | 1193 lines | Endp direction, cfg_idx ordering, interrupt-EP, hub feature clearing. |
|
||
| `P3-usbhidd-hardening.patch` | 725 lines | HID panic removal, named producer wiring. |
|
||
| `P4-initfs-usb-drm-services.patch` | 22 lines | DRM/USB service ordering in init. |
|
||
| (sibling) `P0-inputd-named-producers.patch`, `P0-inputd-per-device-consumers.patch`, `P2-inputd.patch`, `P3-inputd-keymap-bridge.patch` | (varying) | Input multiplexer wiring (ps2d + usbhidd consumers). |
|
||
|
||
**Durability rule:** any source-tree edit must be mirrored into one of these patches (or
|
||
into the local `base` fork's `submodule/base` branch on `RedBear-OS`) before the session
|
||
ends. This rule is also enforced by `local/AGENTS.md` and the cookbook's atomic patch
|
||
applier. **The current local fork at `local/sources/base/` is a single mega-commit** —
|
||
see §8 for the durability problem and remediation.
|
||
|
||
### 1.6 The interrupt-vs-polling contradiction
|
||
|
||
`local/sources/base/drivers/usb/xhcid/src/main.rs:101–115` defines a complete
|
||
`get_int_method()` that returns MSI-X, MSI, INTx, or Polling based on PCI capabilities.
|
||
`main.rs:141` then **disables it**:
|
||
|
||
```rust
|
||
let (irq_file, interrupt_method) = (None, InterruptMethod::Polling); //get_int_method(&mut pcid_handle);
|
||
//TODO: Fix interrupts.
|
||
```
|
||
|
||
`xhci::start_irq_reactor(&hci, irq_file);` is called with `irq_file = None`, which makes
|
||
the reactor a **bounded polling loop that wakes every 1 second** (see the `mod.rs` reactor
|
||
fallback). This is functionally "polling in production."
|
||
|
||
The v1 plan called this "interrupt-driven operation restored" — that is incorrect relative
|
||
to the live code. v2 makes the gap explicit: **interrupts remain to be re-enabled** as P0-A1.
|
||
|
||
---
|
||
|
||
## 2. Status matrix (single source of truth)
|
||
|
||
Reorganized around the *honest* state of the tree.
|
||
|
||
| Component | State today | Maturity | Open correctness gap |
|
||
|---|---|---|---|
|
||
| Host mode (any controller) | builds / QEMU-validated narrow path | `usable (narrow path)` | see §4 |
|
||
| **xhcid** runtime | builds / polling / QEMU-validated | `usable (narrow path)` | interrupts hardcoded off; missing CSZ; missing real-hardware reset fix; missing USB 3.x packet-size + hub fixes |
|
||
| **ehcid** runtime | builds / no auto-spawn | `builds` | no class driver dispatch; no full bot pipeline through `/scheme/usb`; ~no peer review |
|
||
| **uhcid** runtime | builds / does nothing | `builds` | stub (35 lines) |
|
||
| **ohcid** runtime | builds / does nothing | `builds` | stub (35 lines) |
|
||
| Hub | builds / good quality | `usable (narrow path)` | polling fallback retained |
|
||
| HID class | builds / QEMU-validated narrow path | `usable (narrow path)` | named producer wiring complete; legacy VT fallback preserved |
|
||
| Mass storage | builds / QEMU-validated narrow path | `usable (narrow path)` | no guest-side write proof; no multi-LUN; no UAS |
|
||
| Audio class (USB) | builds | `builds` | not exercised in any proof |
|
||
| CDC ACM/ECM | builds | `builds` | not exercised in any proof |
|
||
| Bluetooth USB transport | builds (transport only) | `builds` | Bluetooth host path remains gappy (see BLUETOOTH-IMPLEMENTATION-PLAN) |
|
||
| USB-C / UCSI | builds | `builds` | topology surfaced, no PD/alt-mode |
|
||
| Native tooling (`lsusb`, `usbctl`, `redbear-info`, `redbear-usb-check`) | builds | `usable (narrow path)` | no bounded proof scheme validation |
|
||
| Quirk table (compiled + TOML) | builds | `validated (QEMU)` — quirk-bypass-only | 146 USB + 214 storage entries, 22 flags |
|
||
| Validation harnesses | 5 QEMU scripts | `validated (QEMU)` | no real-hardware matrix |
|
||
|
||
If a row says `builds`, **Red Bear does not promise that the component is reachable from a
|
||
typed-key-in-the-inputd-pipe to a shell prompt.** That promise is restricted to
|
||
`usable (narrow path)` and above, and only for the documented scenario.
|
||
|
||
---
|
||
|
||
## 3. Upstream divergence — what Redox 0.x USB HEAD has that Red Bear does not
|
||
|
||
This section is required reading before any USB change. It is the input to every phase in
|
||
§6. The Redox merge window for USB change runs roughly Jan 2025 – Jun 2026 with two
|
||
concentrated bursts (March 2025, Sep–Oct 2025). Red Bear's fork is currently pinned at the
|
||
v1 baseline (0.1.0 base snapshot).
|
||
|
||
### 3.1 Three high-priority upstream commits Red Bear has not adopted
|
||
|
||
| Upstream commit | Why we need it | Where it would land |
|
||
|---|---|---|
|
||
| **`69a80a6a` — xhci: fix reset procedure on real hardware** | Replaces magic bit numbers with named constants; fixes the HCRST wait loop to read from `usb_cmd` instead of `usb_sts` (the spec says HCRST is in USB_CMD). Without this, `xhcid` can spin or wedge on real controllers. | New patch `local/patches/base/P3-xhci-real-hw-reset.patch` against `xhcid/src/xhci/mod.rs`. |
|
||
| **`19570db4` — xhci: support 64-bit contexts (CSZ)** | Makes `Xhci` generic over context size (`Xhci<CONTEXT_32>` / `Xhci<CONTEXT_64>`) with runtime detection via `HCCPARAMS1.CSZ`. Required by modern xHCI controllers (Alder Lake, Raptor Lake, Ryzen 7000+). The local source already has `daemon_with_context_size<const N: usize>` and a `//TODO: cleanup CSZ support` comment at the call site — the upstream fix is the natural completion. | New patch `local/patches/base/P3-xhci-csz-64-bit.patch` against `xhcid/src/main.rs` and the downstream context types. |
|
||
| **`12e601b3` — xhci: improvements based on real hardware testing** | Adds `USB_CMD_INTE`, corrects port RWC handling, fixes address_device speed passthrough. Companion to `69a80a6a`. | New patch `local/patches/base/P3-xhci-real-hw-impl.patch`. |
|
||
|
||
### 3.2 Medium-priority upstream commits
|
||
|
||
| Upstream commit | Note |
|
||
|---|---|
|
||
| `8dcd85b5`, `ba0ca4ce` — Fix packet size for USB 3.0 and USB 1 | Required for SuperSpeed device enumeration. Adopt in same patch as CSZ. |
|
||
| `cbbcbc9e`, `f58625b0` — `usbhubd`/`xhcid` fix reading descriptor / port status on USB 3 hubs | Round out the USB 3 hub story. |
|
||
| `8f278dcb`, `34b37410` — Bounds check on `root_hub_port_index()` | Stop a panic that we already pay down via patch but have not tested in tree. |
|
||
| `4d6581d4` — xhcid: add more timeouts | Prevents infinite hangs on unresponsive controllers. |
|
||
| `7e3e841f` — xhci: fix reading EHB flag in received_irq | Companion for interrupt-driven paths. |
|
||
| `e3a13a0c` — `xhcid` and friends: use newtype `PortId` to ensure route string | Type-safety win. |
|
||
| `6ac41ee` — daemon: tolerate BrokenPipe on ready() | Already in our base fork. |
|
||
| `258ea4e6`, `865ca866` — `usbscsid`: use the unified disk scheme implementation | `usbscsid` revision; lower priority, code organization. |
|
||
| `e4aab167`, `24c1f0a3` — xhcid: don't exit the event loop when using irqs | Required for stable interrupt-driven operation (pairs with the §1.6 fix). |
|
||
|
||
### 3.3 Lower-priority upstream commits to record, not blindly adopt
|
||
|
||
| Commit | Note |
|
||
|---|---|
|
||
| `a5f87735` — ignore alternate settings | Conflicts with our composite-device fix (P3-xhci-device-hardening retains explicit alternate handling). Validate whether dropping this is sound given our active `PortState.active_ifaces` map. |
|
||
| `7c980137` — language ID for string descriptors | Likely a clean drop-in. |
|
||
| `374e5fbf` — xhci: use redox-scheme v2 | We are on `redox-scheme 0.11`; a v2 migration is not in scope for 0.2.x. |
|
||
| `30fb1e7a` — drivers merged into base (Nov 2025) | Mirrors what Red Bear already does (our `local/sources/base/`). No action. |
|
||
| USB SCSI driver disabled upstream (Dec 2025) | Red Bear keeps it on with the BOUNDED storage test. Re-evaluate after P2-B1. |
|
||
| `bjorn3` enabled xHCI by default in QEMU x86-64 (Mar 2026) | Aligns with our `redbear-mini` boot script. No action. |
|
||
| `bjorn3` moved xHCI config to runtime (Apr 2026) | Lower priority — compile-time config is fine for our release model. |
|
||
| Antoine Reversat — simplified xhci (May 2026) | Subject to per-line review. |
|
||
|
||
### 3.4 Things upstream still does NOT have
|
||
|
||
These are explicit non-features from upstream that Red Bear should not silently inherit as
|
||
a todo:
|
||
|
||
- **USB Type-C / USB-PD / alt-modes.** No policy engine, no protocol stack.
|
||
- **USB4 / Thunderbolt.** Listed as "not supported" in upstream `COMMUNITY-HW.md`.
|
||
- **xHCI debug capability (DbC).** Not implemented.
|
||
- **USB device mode (gadget) / OTG.** No dual-role support.
|
||
- **USB isochronous transfers.** `xhcid` returns `ENOSYS` for isoch endpoints.
|
||
|
||
These belong to §6 P5 (architectural decision gate), not to "fix the missing patch."
|
||
|
||
---
|
||
|
||
## 4. Bare-metal-input correctness (the actual boot-time failure modes)
|
||
|
||
The bare-metal USB keyboard problem is not "xhcid doesn't work." xhcid does work in QEMU
|
||
and on some real hardware. The failure modes are the **paths that do not reach xhcid**:
|
||
|
||
1. **EHCI-attached USB keyboard** — xHCI now owns every USB-3 controller, but
|
||
EHCI/companion controllers (UHCI/OHCI) still own low/full-speed devices on chipsets
|
||
that firmware routes through them. **ehcid does not auto-spawn class drivers**, so even
|
||
though ehcid publishes `/scheme/usb/port<n>/...`, no `usbhidd` is started for any
|
||
device on that scheme. The keyboard is reachable by userland but the input pipeline
|
||
never builds.
|
||
|
||
2. **UHCI/OHCI-attached devices** — uhcid and ohcid are 35-line stubs. The companion
|
||
controller is owned (by `pcid`) but no USB traffic flows. There is no port state, no
|
||
transfer completion, no scheme.
|
||
|
||
3. **xHCI interrupt-driven operation is offline** — line 141 hardcodes polling. On real
|
||
hardware with no reliable polling timer, this can produce slow enumeration or input
|
||
lag, and on some chips it can wedge the controller (see upstream `69a80a6a`).
|
||
|
||
4. **No real-hardware validation matrix** — there is no `hardware-validation.md` table
|
||
enumerating which physical controller families have been exercised on bare metal.
|
||
QEMU `qemu-xhci` is one fixed emulation target; it is not representative.
|
||
|
||
5. **USB HID and ACPI I2C-HID are not the same** — internal laptop keyboards are
|
||
I2C-HID (`i2c-hidd`, `intel-thc-hidd`), not USB. These are real but separate. The
|
||
I2C-HID plan and the USB HID plan cannot assume one is a substitute for the other.
|
||
|
||
6. **Strict-boot mode exists but is not bound** — `uhcid`/`ohcid`/`ehcid` accept
|
||
`--strict-boot`, but no initfs entry enables it; the policy lives in operator
|
||
knowledge, not in the artifact.
|
||
|
||
7. **LED state is a weak health signal** — `usbhidd` keyboard LEDs are bounded,
|
||
per-device, best-effort; they are not a system-global lock-state authority. A dead
|
||
`Caps Lock` indicator does not prove keyboard transport is broken; a working indicator
|
||
does not prove the external USB keyboard fallback works. Treat LED state as cosmetic
|
||
debug, not as a proof of input health.
|
||
|
||
8. **External keyboard bare-metal proof remains unpinned** — the bounded QEMU lifecycle
|
||
proof is not the same as a bare-metal proof. We need a captured log per controller
|
||
family before claiming a fallback works on hardware.
|
||
|
||
These eight items are the inputs to phases P0-A (xHCI runtime) and P0-B (legacy host
|
||
controllers).
|
||
|
||
---
|
||
|
||
## 5. Phases — execution order
|
||
|
||
Phases are ordered by *what unblocks bare-metal correctness and what has unambiguous
|
||
upstream-comparable patches we can adopt without inventing semantics*.
|
||
|
||
| Phase | Goal | Exit |
|
||
|---|---|---|
|
||
| **P0-A1** | Re-enable xHCI MSI/MSI-X/INTx at runtime; bound to the modern CSZ stack. | Real-hardware bring-up on one Intel + one AMD controller + bounded QEMU proof |
|
||
| **P0-A2** | Adopt upstream xHCI reset-procedure fix + hardware hardening (`69a80a6a`, `12e601b3`). | One QEMU full-stack pass + one real-hardware bring-up |
|
||
| **P0-A3** | Adopt CSZ (64-bit contexts) upstream commit; complete the `//TODO: cleanup CSZ support` site. | Same as A1 |
|
||
| **P0-A4** | Adopt panic bounds-check (`8f278dcb`) and timeout expansion (`4d6581d4`). | QEMU lifecycle + full-stack pass |
|
||
| **P0-B1** | Auto-spawn class drivers from the EHCI scheme (`/scheme/usb/port<n>/descriptors`). Reuse the existing `xhcid` class-driver spawn model by refactoring the spawn helper out of `xhcid` into `usb-core::spawn_usb_driver` if necessary, then driving it from EHCI too. | QEMU run with USB keyboard on EHCI route → typed input reaches `inputd` |
|
||
| **P0-B2** | Implement real runtime enumeration for `uhcid` and `ohcid` over the existing `usb-core::UsbHostController` trait. Each new driver must register the same `/scheme/usb` tree pattern ehcid uses and must auto-spawn class drivers via `P0-B1`. | QEMU run with low/full-speed USB keyboard on legacy controller route → typed input reaches `inputd` |
|
||
| **P1** | USB 3.x hub correctness upstream commits (`cbbcbc9e`, `f58625b0`, `8dcd85b5`, `ba0ca4ce`); review alt-setting handling (`a5f87735`) against our `active_ifaces`. | One USB 3 hub brought up in QEMU with descriptor walk end-to-end |
|
||
| **P2-A** | Storage data path: in-guest write verification on the `disk.usb-*` scheme; multi-LUN if it is tractable. | `redbear-usb-storage-check` proves a write/read round-trip in QEMU |
|
||
| **P2-B** | Userspace API: pick native or `libusb`. Native: bake `usb-core` consumers first. `libusb`: pick an active WIP commit; if there is none, **defer** §2 row "userspace API" rather than start a new side-quest. | Decision + prototype |
|
||
| **P3** | HID robustness: real-hardware HID validation matrix; `i2c-hidd` migration to named producers; `evdevd` hotplug add/remove behavior from USB. | One HID device family proven bare-metal + one hot-unplug cycle QEMU |
|
||
| **P4** | Validation slices: complete `test-usb-storage-qemu.sh` write proof, hardware matrix in `HARDWARE-VALIDATION-MATRIX.md` (board, controller, input/storage/audio result), bounded stress loop on top of `test-xhci-device-lifecycle-qemu.sh`. | matrix has one row per controller family |
|
||
| **P5** | Architectural decision gate: host-only vs device mode; USB-C/PD/alt-mode scope; USB4/Thunderbolt exclusion; whether UCSI grows into a real PD surface. Recorded as an ADR in `local/docs/`. | Decision recorded |
|
||
|
||
Phases are not equal in size. P0-A1 and P0-B2 are bounded, well-understood work. P2-B
|
||
(libusb vs native) is a fork in the road; it is correct that it has *no* time estimate.
|
||
P5 is a decision moment, not an implementation.
|
||
|
||
---
|
||
|
||
## 6. Validation inventory and bounded proofs
|
||
|
||
Five scripts exist today. They are honest about their scope (QEMU) but should be paired
|
||
with a real-hardware matrix per phase exit.
|
||
|
||
| Script | What it actually proves | Limits |
|
||
|---|---|---|
|
||
| `local/scripts/test-usb-qemu.sh --check` | Full stack: xHCI init, HID spawn, SCSI spawn, sector-0 readback, BOS, no crashes. | QEMU `qemu-xhci` only; one emulator config; no real hardware. |
|
||
| `local/scripts/test-xhci-device-lifecycle-qemu.sh --check` | Bounded hotplug attach/detach for HID + storage. | QEMU only; monitor-driven hotplug; not a stress test. |
|
||
| `local/scripts/test-usb-storage-qemu.sh` | Mass storage autospawn + sector-0 readback. | No write proof; no multi-LUN; no UAS. |
|
||
| `local/scripts/test-xhci-irq-qemu.sh --check` | xHCI is brought up; only validates init lines today. **Should not be trusted as a proof of interrupt-driven operation** until P0-A1 lands. | Today this checks "the binary runs", not "interrupts fire." |
|
||
| `local/scripts/test-usb-maturity-qemu.sh` | Sequential wrapper. | Composes the others; inherits their limits. |
|
||
|
||
**Required proofs after P0-A1 lands:**
|
||
|
||
1. `test-xhci-irq-qemu.sh --check` must transition from "binary runs" to "interrupts fire
|
||
and complete." Add a bounded probe that confirms a hotplug event triggers an IRQ in
|
||
guest time, not a sleep timer.
|
||
2. Add `test-xhci-regression-qemu.sh` for the upstream reset-procedure fix.
|
||
3. Add `test-uhci-runtime-qemu.sh` and `test-ohci-runtime-qemu.sh` after P0-B2 — same
|
||
shape as the xHCI lifecycle test.
|
||
4. Add `test-ehci-class-autospawn-qemu.sh` after P0-B1.
|
||
|
||
Proofs must:
|
||
|
||
- run on `redbear-mini` from a clean `make clean` build;
|
||
- keep the boot log under `local/docs/boot-logs/` with a `REDBEAR-...-RESULTS.md`;
|
||
- be citeable from phase status (§3 matrix) and from `USB-VALIDATION-RUNBOOK.md`.
|
||
|
||
---
|
||
|
||
## 7. Durability posture (the local-fork problem, honestly)
|
||
|
||
The base fork at `local/sources/base/` currently carries **one USB-related commit**:
|
||
|
||
```
|
||
$ git -C local/sources/base log -- drivers/usb/
|
||
6ac41ee daemon: tolerate BrokenPipe on ready(); i2cd: handle empty RON response
|
||
dd08b76 Red Bear OS base baseline from 0.1.0 pre-patched archive
|
||
```
|
||
|
||
Everything else that v1 described as "88 error handling fixes across xhcid" lives in
|
||
**`local/patches/base/P*.patch`** files. That is acceptable as long as:
|
||
|
||
1. The base *recipe* (`recipes/core/base/recipe.toml`) actually applies those patches on
|
||
`repo cook`. Verify by running `repo validate-patches base` after every edit and by
|
||
checking that `recipes/core/base/source/drivers/usb/xhcid/...` contains the Red Bear
|
||
state, not the upstream state.
|
||
2. No "live-edit" of `recipes/core/base/source/...` ever escapes into the next build
|
||
without an immediate patch mirror. `local/AGENTS.md` enforces this; the rule stands.
|
||
3. The next base-fork bump (rebase onto a newer Redox base tag) preserves every USB patch
|
||
in the same order and lands them as commits on the `submodule/base` branch — not as a
|
||
new mega-patch.
|
||
|
||
**Durability remediation work that does not block USB phases:**
|
||
|
||
- After P0-A1, the xHCI interrupt-re-enable change is a natural candidate to land as
|
||
the **first USB-focused commit on `submodule/base`** since `dd08b76`. That reopens
|
||
per-feature commit history and makes future rebases reviewable.
|
||
- The base fork's `Cargo.toml` should track the `submodule/base` branch as upstream
|
||
(currently it does, per the source-of-truth rules in `local/AGENTS.md`).
|
||
|
||
---
|
||
|
||
## 8. Support language — how Red Bear describes USB
|
||
|
||
Until P0-A and P0-B exit, Red Bear should NOT use any of:
|
||
|
||
- "USB support works."
|
||
- "USB is functional."
|
||
- "USB keyboard works on bare metal."
|
||
- "USB storage is supported."
|
||
|
||
It SHOULD use language such as:
|
||
|
||
- "xHCI host support is present but experimental; bare-metal proof requires the real-hardware
|
||
matrix in §6 P4."
|
||
- "EHCI ownership and USB 2 register init exist; class-driver auto-spawn is pending P0-B1."
|
||
- "UHCI and OHCI are userspace stubs in this build; legacy host controllers are not yet
|
||
the boot-input fallback."
|
||
- "USB storage autospawn and bounded sector-0 readback are QEMU-validated; write proof is
|
||
pending P2-A."
|
||
- "USB error handling and correctness carry significant Red Bear patches over upstream; see
|
||
`local/patches/base/P[1-3]-xhci*.patch` and `local/patches/base/P3-xhci-device-hardening.patch`."
|
||
- "USB-C topology (UCSI) is exposed but does not negotiate PD or alternate modes."
|
||
|
||
The README status table and the desktop-path plans should adopt this language consistently
|
||
the next time they are touched. The `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` already
|
||
treats USB as a first-class subsystem; this plan agrees and refines the wording.
|
||
|
||
---
|
||
|
||
## 9. Open questions and follow-up
|
||
|
||
1. **Rebase cadence** — when `submodule/base` upstream lands the
|
||
`simplify xHCI` commit (May 2026), do we adopt it before or after P0-A1 lands? Per the
|
||
upstream-first rule, after — but the diff requires per-line review because our local
|
||
patches (`P1-xhcid-*.patch`, `P3-xhci-device-hardening.patch`) overlap on the same code
|
||
regions.
|
||
2. **Cross-process class driver spawn** — the class spawn path is currently xhcid-driven
|
||
(via the scheme). Should the spawn helper live in `usb-core` and be reused by
|
||
`ehcid`/`uhcid`/`ohcid`? Yes (P0-B1, P0-B2) — and that requires `usb-core` to grow
|
||
`spawn_class_driver`, which it does not yet have. The migration is the natural unit
|
||
of P0-B1.
|
||
3. **Strict-boot mode** — should `pcid-spawner` always pass `--strict-boot` to USB host
|
||
daemons? Operators can set `REDBEAR_STRICT_USB_BOOT=1` today; the default is off.
|
||
Recommend leaving the default off but documenting the env var in
|
||
`USB-VALIDATION-RUNBOOK.md` (P0-A4 documentation step).
|
||
4. **Whether to keep `usbscsid` enabled after upstream disabled it** — adopt the upside
|
||
(bounded in-guest write proof) and the downside (occasional stalls). Defer to P2-A
|
||
evaluation.
|
||
5. **Hardware validation entries** — the matrix in `local/docs/HARDWARE-VALIDATION-MATRIX.md`
|
||
is currently tiny. P4 explicitly grows it; if it does not, the matrix block of P4 exit
|
||
blocks the phase.
|
||
|
||
---
|
||
|
||
## 10. See also
|
||
|
||
- `local/docs/USB-VALIDATION-RUNBOOK.md` — operator runbook for the bounded proofs above.
|
||
- `local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md` — the canonical desktop-path plan; treats
|
||
USB as a first-class runtime subsystem.
|
||
- `local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md` — MSI/MSI-X quality
|
||
surface that P0-A1 actually exercises.
|
||
- `local/docs/BLUETOOTH-IMPLEMENTATION-PLAN.md` — `redbear-btusb` consumes the USB class
|
||
driver dispatch path that P0-B1 makes available to all host controllers.
|
||
- `local/docs/WIFI-IMPLEMENTATION-PLAN.md` — Wi-Fi native control plane; not USB-coupled.
|
||
- `local/docs/QUIRKS-SYSTEM.md` — TOML + DMI + compiled-in quirk tables, source of USB
|
||
device workarounds.
|
||
- `local/AGENTS.md` — fork model, durability policy, single-repo rule, branch policy.
|
||
- `local/docs/archived/USB-IMPLEMENTATION-PLAN-v1-2026-04.md` — superseded v1.
|
||
- `local/docs/archived/USB-BOOT-INPUT-PLAN.md` — preserved for the boot-input
|
||
historical context; not the planning authority.
|
||
- `local/docs/archived/XHCID-DEVICE-IMPROVEMENT-PLAN.md` — preserved for the xhcid
|
||
device-level historical context; absorbed into phases P0-A and P1.
|