diff --git a/docs/README.md b/docs/README.md index 0d1c481178..a8129a8354 100644 --- a/docs/README.md +++ b/docs/README.md @@ -65,7 +65,7 @@ console-to-KDE plan. - `../local/docs/ACPI-IMPROVEMENT-PLAN.md` — ACPI ownership, robustness, validation - `../local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md` — PCI/IRQ quality, MSI/MSI-X - `../local/docs/DRM-MODERNIZATION-EXECUTION-PLAN.md` — DRM-focused execution (subsystem detail) -- `../local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md` (v2.2, 2026-07-22) — D-Phase (parallel development) + C-Phase (cutover & validation) plan to replace `pcid-spawner` with `driver-manager` (driver-manager built in parallel, not enabled before D5 ratifies; never deletes pcid-spawner; cross-references Linux 7.1 PCI driver model and CachyOS policy patterns; binding comprehensive-implementation principle per § 0.5). **Status v2.2: D-phase fully implemented + ninth-round integrations** — 94 tests passing across `redox-driver-core` (33 lib + 5 dynid) and `driver-manager` (56); 0 audit-no-stubs violations; concurrent probe path invokes the real `Driver::probe()` from worker threads (Arc-shared drivers, priority-ordered candidates incl. dynids, serial-equivalent semantics); redox-target build fixed (`SchemeSync::write` trait match, per-handle `/modalias` results, `syscall::flag` O_* constants); double-claim bug fixed (single pcid bind threaded to spawn); driver registry wired at startup (`exclusive_with` + `/modalias` now functional); real SIGCHLD/SIGHUP handlers installed via `libc::signal`; heartbeat counters + AER `route_to_driver` wired; zero crate-local warnings on host and redox target; pcid_interface reads `REDBEAR_DRIVER_PCI_IRQ_MODE` and `REDBEAR_DRIVER_DISABLE_ACCEL` env vars end-to-end; observability CLI flags `--list-drivers`, `--dry-run`, `--export-blacklist`; SMP worker pool (smart scheduler for serial-vs-concurrent based on device count), C-state/P-state advisors (library), IOMMU/MSI-X/NUMA helpers (library), PciQuirkFlags wired into driver spawn (env vars), runtime PM hooks, AER foundation, hotplug polling-fallback (250ms), `/etc/driver-manager.d/` blacklist consulted at probe, heartbeat publisher (JSON every 5s), AER listener (polls /scheme/acpi/aer), `SharedBlacklist::replace()` for live reload + SIGHUP reload worker, **SIGCHLD reaper thread**, `async_probe` configurable via env, `DRIVER_MANAGER_CONFIG_DIR` env var, six QEMU-functional test scripts, `/modalias` scheme endpoint (write MODALIAS → get driver name back), `linux_loader.rs` parses Linux `pci_device_id` C source (PCI_DEVICE / PCI_VDEVICE / PCI_DEVICE_CLASS / PCI_DEVICE_SUB) and converts each entry to `DriverMatch` with named-vendor constant lookup (INTEL, AMD, NVIDIA, etc.) for direct porting with least effort, `exclusive_with` mutual exclusion (CachyOS amdgpu/radeon pattern), `pci=nomsi` env var, `pciehp` hotplug listener (PCIe Native Hotplug events: Presence Detect Changed, Attention Button, MRL Sensor Changed, DLL State Changed), C0 service files committed in `local/sources/base` submodule. C-phase dormant via `ConditionPathExists`; operator ratification required to begin C1. +- `../local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md` (v3.0, 2026-07-22) — D-Phase (parallel development) + C-Phase (cutover & validation) plan to replace `pcid-spawner` with `driver-manager` (driver-manager built in parallel, not enabled before D5 ratifies; never deletes pcid-spawner; cross-references Linux 7.1 PCI driver model and CachyOS; binding comprehensive-implementation principle per § 0.5). **Status v3.0: major assessment round** — see `../local/docs/evidence/driver-manager/ASSESSMENT-2026-07-22.md` (findings B1–G10). The `/bind` claim endpoint never existed in pcid (P0-1: claim collapses into channel `ENOLCK` exclusivity — the pcid-spawner model); pciehp/AER listeners inert pending pcid producers (P2-1); linux-kpi vs driver-manager claim split unified under the LDR Linux-Driver-Reuse track (spawned-mode `pci_register_driver`, iwlwifi/amdgpu onboarding, linux-kpi API completion); `modern_tech` advisory theater stripped (P0-3); runtime validation is now a hard gate (P0-4). 94 tests passing across `redox-driver-core` (33 lib + 5 dynid) and `driver-manager` (56); 0 audit-no-stubs violations; zero crate-local warnings on host and redox target. Earlier delivered capabilities: concurrent probe path with real `Driver::probe()` from worker threads (Arc-shared drivers, priority-ordered candidates incl. dynids, serial-equivalent semantics); driver registry wired at startup; real SIGCHLD/SIGHUP handlers; heartbeat counters; AER `route_to_driver`; pcid_interface reads `REDBEAR_DRIVER_PCI_IRQ_MODE` and `REDBEAR_DRIVER_DISABLE_ACCEL` env vars end-to-end; observability CLI flags; SMP worker pool; PciQuirkFlags wired into driver spawn; deferred probe; `/etc/driver-manager.d/` blacklist; `/modalias` scheme endpoint; `linux_loader.rs` Linux `pci_device_id` parser; `exclusive_with` mutual exclusion; `pci=nomsi` env var; pciehp/AER event parsers; C0 service files committed in `local/sources/base` submodule. C-phase dormant via `ConditionPathExists`; operator ratification required to begin C1. - `../local/docs/WAYLAND-IMPLEMENTATION-PLAN.md` — Wayland compositor (subsystem detail) - `../local/docs/archived/RELIBC-IPC-ASSESSMENT-AND-IMPROVEMENT-PLAN.md` — relibc IPC surface - `../local/docs/GREETER-LOGIN-IMPLEMENTATION-PLAN.md` — greeter/login design diff --git a/local/AGENTS.md b/local/AGENTS.md index 442ca49967..3b60074b2d 100644 --- a/local/AGENTS.md +++ b/local/AGENTS.md @@ -1422,28 +1422,26 @@ When mainline updates affect our work: also be treated as first-class subsystem plans, not as side notes. - `local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md` is the current umbrella plan for IRQ delivery, MSI/MSI-X quality, IOMMU validation, and other low-level controller completeness work. -- `local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md` (v2.2, 2026-07-22) is the canonical planning +- `local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md` (v3.0, 2026-07-22) is the canonical planning authority for the migration from `pcid-spawner` (`local/sources/base/drivers/pcid-spawner/`) to `driver-manager` (`local/recipes/system/driver-manager/`). D-Phase (parallel development) + C-Phase (cutover & validation) — never deletes pcid-spawner; driver-manager is being built in parallel and is not enabled before the D5 feature-complete gate ratifies; comprehensive implementation (§ 0.5) is a binding constraint; cross-references Linux 7.1 PCI driver model - and CachyOS policy patterns. v2.2 records the ninth round: the concurrent probe path in - `redox-driver-core` now invokes the real `Driver::probe()` from worker threads (drivers held - as `Arc`, priority-ordered candidate lists including dynids, serial-equivalent - per-device semantics) — the previous synthetic-`Bound` dispatcher reported bindings with no - driver spawned and bypassed `exclusive_with`/quirks/blacklist on buses with ≥ 4 devices; - the first full `x86_64-unknown-redox` compile of the v2.1 tree is fixed (`SchemeSync::write` - matches the redox-scheme trait with per-handle `/modalias` results; `O_WRONLY`/`O_RDWR` from - `syscall::flag`); a latent double-claim bug in `probe()` (second pcid bind would always fail - `EALREADY` on real hardware) is fixed by threading one claim through to spawn; - `set_registered_drivers()` is now called at startup (previously `exclusive_with` and - `/modalias` were no-ops against an empty registry); `SIGCHLD`/`SIGHUP` handlers are really - installed via `libc::signal` (the reaper and blacklist reload previously never fired); - heartbeat counters and AER `route_to_driver` are wired into the enumerate/hotplug/ - unified-event paths; superseded standalone listeners and placeholder functions are removed - or `#[cfg(test)]`-gated. 94 tests across 4 crates pass (56 driver-manager + 33 - redox-driver-core lib + 5 dynid); the § 0.5 audit gate reports 0 violations; + and CachyOS. v3.0 records the 2026-07-22 major assessment + (`local/docs/evidence/driver-manager/ASSESSMENT-2026-07-22.md`, findings B1–G10): the + `/bind` claim endpoint never existed in pcid (claim collapses into channel `ENOLCK` + exclusivity per P0-1 — the pcid-spawner model); the pciehp/AER listeners poll files no + producer creates (restated; producers are P2-1); linux-kpi and driver-manager were two + competing claim systems with zero mutual awareness (the LDR track unifies them under + driver-manager ownership with a spawned-mode `pci_register_driver`); `modern_tech` was + advisory theater (P0-3 strips it); and runtime validation becomes a hard gate (P0-4). + The v3.0 work program: P0 correctness blockers (claim collapse, orphan-patch resolution, + modern_tech/exec cleanup, QEMU runtime gate) → LDR Linux-Driver-Reuse (unified claim, + spawned-mode registration, iwlwifi/amdgpu onboarding, linux-kpi API completion) → + P2 operator/event surface (pcid producers, scheme write endpoints, trigger-based retry) → + P3 policy/hygiene (quirk phases, AER recovery actions, firmware packaging). + 94 tests across 4 crates pass; the § 0.5 audit gate reports 0 violations; `driver-manager` compiles warning-free on host and on the redox target. C-phase (C0–C4) cutover is dormant and requires operator ratification. See `local/docs/evidence/driver-manager/D5-AUDIT.md` for diff --git a/local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md b/local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md index 363532209c..a81398a818 100644 --- a/local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md +++ b/local/docs/DRIVER-MANAGER-MIGRATION-PLAN.md @@ -1,10 +1,158 @@ # Red Bear OS — `pci-spawner` → `driver-manager` Migration Plan -**Document status:** v2.2 canonical planning authority (supersedes v2.1 with a real concurrent probe path, redox-target build fixes, driver-registry wiring, real SIGCHLD/SIGHUP handlers, heartbeat + AER routing wired, and a zero-warning build) +**Document status:** v3.0 canonical planning authority (supersedes v2.2 with the 2026-07-22 major assessment: runtime blocker on the `/bind` claim, the linux-kpi claim-system split, inert pciehp/AER listeners, and the Linux-Driver-Reuse track that aligns the whole plan with the project's critical goal — reusing Linux drivers) **Generated:** 2026-07-20 **Toolchain:** Rust nightly-2026-05-24 (edition 2024) **Architecture:** Microkernel OS in Rust (Redox fork) -**Cross-reference baseline:** Linux kernel 7.1 at commit `ab9de95c9` (`local/reference/linux-7.1/`), CachyOS-Settings v1.3.5 (https://github.com/CachyOS/CachyOS-Settings), CachyOS/linux-cachyos 4.1k★ +**Cross-reference baseline:** Linux kernel 7.1 at commit `ab9de95c9` (`local/reference/linux-7.1/`), CachyOS (`local/reference/cachyos/` — linux-cachyos `0001-cachyos-base-all.patch` 6.17.9 + desktop ISO 260628) +**Assessment:** `local/docs/evidence/driver-manager/ASSESSMENT-2026-07-22.md` (findings register B1–G10) + +**v3.0 status update over v2.2 (the assessment round):** + +v3.0 records the first *runtime-grade* audit of the migration. Three +parallel codebase audits (pcid layer, linux-kpi binding model, Linux 7.1 +PCI core) plus a full first-hand review of every driver-manager source +file found that the v1.3–v2.2 "Done" claims were compile-grade, and that +three of them are **broken at runtime**. The full evidence register +(B1–G10) is in the assessment doc; the corrections and the resulting +work program follow. + +**Corrections to earlier rounds (stale claims removed):** + +1. **The `/bind` claim endpoint does not exist.** Earlier rounds + marked "D1 C4 BAR request ✅ Done — `claim_pci_device` via + `/bind`" (and the § diagram "claims devices via `/bind`"). + pcid exposes only `channel` and `config` per device; the patches that + would add `/bind` (`local/patches/base/P3-pcid-bind-scheme.patch`, + `P3-pcid-aer-scheme.patch`, `P3-pcid-uevent-format-fix.patch`) are + orphaned — never committed to `submodule/base`, and the cookbook does + not apply patches for `path =` fork recipes. At runtime, every probe + would fail `ENOENT` and defer-retry forever, binding nothing. + **Resolution: P0-1 below — the separate claim endpoint is dropped in + favor of pcid's existing channel exclusivity (`ENOLCK`), the model + pcid-spawner has always used.** The orphaned patches are resolved per + the orphan-patch decision tree (bind-scheme: SUPERSEDED by the + channel model; aer-scheme: kept as the P2-1 producer blueprint). +2. **The pciehp and AER listeners are inert.** v1.9/v2.0 marked them + done; in fact nothing in the tree produces `/scheme/pci/pciehp` or + `/scheme/acpi/aer`, and both readers fail-soft on missing files. + Device add/remove is covered by the 250 ms hotplug enumeration poll + (which works). The listeners are restated as *parsers ready, + producers pending* (P2-1). +3. **`exclusive_with` is not "the CachyOS pattern."** CachyOS solves + two-drivers-one-device by *probe-time* deferral (its 6.17.9 patch + makes ahci return `-ENODEV` on remapped-NVMe controllers so + `intel-nvme-remap` binds instead) and by *userspace* modprobe.d + blacklists. Match-time `exclusive_with` is a third, complementary + mechanism — a superset, retained. The plan text is corrected. +4. **`modern_tech` "wired" was advisory theater.** Bind/unbind emit + hardcoded C/P-state constants into JSON files nothing reads, and the + MSI-X proposal is computed at spawn and discarded. P0-3 strips it to + the honest core. +5. **"8 QEMU-functional test scripts" was aspirational.** The scripts + exist; no driver-manager QEMU boot has ever been run. Runtime + validation is now a hard gate (P0-4) and the D5 audit grades + capabilities *runtime* as well as *compile*. + +**v3.0 work program (the tracks):** + +| Track | Items | Goal | +|---|---|---| +| **P0 — Correctness blockers** | P0-1 claim-via-channel collapse · P0-2 restate pciehp/AER + resolve orphaned patches · P0-3 strip modern_tech + delete exec.rs · P0-4 runtime validation gate (QEMU) | Make the existing D-phase true at runtime | +| **LDR — Linux-Driver-Reuse** | LDR-1 unified claim model · LDR-2 spawned-mode `pci_register_driver` · LDR-3 iwlwifi onboarding · LDR-4 amdgpu path convergence · LDR-5 linux-kpi API completion | The critical goal: reuse Linux drivers | +| **P2 — Operator & event surface** | P2-1 pcid producers (AER registers, pciehp slot events) · P2-2 scheme write endpoints (`bind`/`unbind`/`new_id`/`remove_id`/`driver_override`/`rescan`) · P2-3 trigger-based deferred retry | Linux-grade operability | +| **P3 — Policy & hygiene** | quirk pass phases (early/runtime) · AER recovery actions (`pci_ers_result` mapping) · per-vendor firmware packaging · dep-crate warnings + stale-tree cleanup | Long-term evolution | + +**P0 — Correctness blockers (preconditions for everything else):** + +- **P0-1 Collapse claim into the channel open.** Replace + `claim_pci_device()` + `open_pcid_channel()` with a single + `PciFunctionHandle::connect_by_path()`: `ENOLCK` → "already claimed → + next candidate" (mirrors Linux's probe-time `-EBUSY`/`-ENODEV` + handoff), then `enable_device()` and `into_inner_fd()` → + `PCID_CLIENT_CHANNEL`. Claim lifetime == channel fd lifetime == child + lifetime — exactly correct, pcid-spawner-proven, zero pcid fork + changes. The exclusive_with check moves *after* the channel open + (claim-then-check, as in v2.1–v2.2, with close-on-defer). +- **P0-2 Restate pciehp/AER; resolve orphaned patches.** Plan text + corrected above. `P3-pcid-bind-scheme.patch` → SUPERSEDED (channel + model); `P3-pcid-aer-scheme.patch` → retained as the P2-1 producer + blueprint; `P3-pcid-uevent-format-fix.patch` → split: AER parts with + the producer work, uevent stub dropped (polling is the accepted v1 + model). Move superseded files per the orphan-patch decision tree. +- **P0-3 Strip modern_tech to the honest core; delete exec.rs.** Remove + the constant C/P-state JSON writers (no consumers); pass the MSI-X + proposal to the child as `REDBEAR_DRIVER_MSIX_VECTORS=` (same + env-hint channel as the quirk hints) or drop it until a consumer + exists. Delete `exec.rs` (dead `spawn_driver` with + `#[allow(dead_code)]`). +- **P0-4 Runtime validation gate.** Boot `redbear-mini` in QEMU with + driver-manager enabled in place of pcid-spawner (C-phase dry run): + e1000 binds through the real claim path, `/bound` reports it, + heartbeat counters move, deferred drivers retry and bind. Until this + passes, no capability is "Done" — the D5 audit gains a Runtime column. + +**LDR — Linux-Driver-Reuse track (the critical goal):** + +*One ownership model:* driver-manager owns enumeration, matching, +policy, claiming, and spawning for **native and Linux-port daemons +alike**; linux-kpi is the in-process Linux API surface *inside* the +spawned daemon, never a second enumerator. + +- **LDR-1 Unified claim model.** All device binding flows through + driver-manager's match→claim→spawn. linux-kpi never opens + `/scheme/pci/` for binding decisions. +- **LDR-2 Spawned-mode `pci_register_driver`.** When + `PCID_CLIENT_CHANNEL` is present, linux-kpi skips enumeration, wraps + the granted channel, matches only the device it was spawned for, and + calls the C probe for exactly that device. Standalone + self-enumeration mode remains for CLI tools. This eliminates the + double-claim risk class (assessment B2). +- **LDR-3 redbear-iwlwifi onboarding.** Generate its driver-manager TOML + from the iwlwifi `id_table` via `linux_loader` (un-`cfg(test)` the + pipeline: `linux_loader → TOML → /lib/drivers.d/`); spawn it as a + daemon under the unified claim; retire its manual `/scheme/pci/` + scanning CLI path for the auto-bind case. +- **LDR-4 amdgpu path convergence.** Keep redox-drm as the spawned + daemon (its FFI into `libamdgpu_dc_redox.so` is legitimate + in-process composition, not a second claim system — but its PCI open + must go through the granted channel, not `PciDevice::open_location` + on its own enumeration). +- **LDR-5 linux-kpi API completion (priority order).** (a) real MSI/MSI-X + via `pcid_interface::enable_feature` (replace synthetic + `allocate_vectors`); (b) `pci_request_regions`/`pci_release_regions` + as BAR-mapping claims over the channel; (c) `pcie_capability_read/ + write_*` via channel config R/W (exists in pcid_interface); (d) power + state (`pci_save_state`/`restore_state`/`set_power_state` via PMCSR); + (e) `pci_reset_function` (FLR) if pcid grows the hook. + +**P2 — Operator & event surface:** + +- **P2-1 pcid producers.** Per-device AER register files from the + retained aer-scheme blueprint; pciehp slot-status events (the five + hardware-defined bits ABP/PFD/PDC/DLLSC/CC) produced by pcid polling + the slot status register. +- **P2-2 Scheme write endpoints.** `/bind`, `/unbind`, `/new_id`, + `/remove_id`, `/driver_override`, `/rescan` on the driver-manager + scheme — the Linux sysfs operator surface, scheme-shaped. dynids are + already implemented in redox-driver-core; this exposes them. + `driver_override` adds Linux's Tier-1 match precedence. +- **P2-3 Trigger-based deferred retry.** Retry deferred probes on (a) + any successful bind (mirrors `driver_deferred_probe_trigger`), (b) + dependency-scheme arrival (watch `/scheme/` for the named scheme in + "dependency scheme not ready" deferrals), (c) firmware-loader + readiness for `NEED_FIRMWARE` deferrals. Blind 250 ms polling becomes + the fallback, not the mechanism. + +**P3 — Policy & hygiene:** quirk pass phases (early pre-BAR vs runtime — +Linux has 8 `pci_fixup_pass` phases; we need at least the early/runtime +split for pre-BAR quirks); AER recovery actions wired to drivers +(`pci_ers_result` 6-state mapping over scheme IPC); per-vendor firmware +packaging mirroring linux-firmware splits; dependency-crate warnings +(libredox, pcid `Option::insert`, redox-driver-sys `Once`/`vendor`); +remove the stale `local/recipes/drivers/redox-driver-core/src/` +duplicate tree (live tree is `source/src/`); fold the concurrent path's +double bus enumeration into one pass. **v2.2 status update over v2.1:** @@ -91,7 +239,7 @@ child when the corresponding flags are set). | § 5.1 D1 C1 capability (`add_dynid`/`remove_dynid`) | ✅ Done | `redox-driver-core/src/{dynid,manager}.rs` | | § 5.1 D1 C2 capability (`Driver::remove` + WAIT_FOR_REAPPEAR) | ✅ Done | `driver-manager/src/config.rs` (real SIGTERM+SIGKILL) | | § 5.1 D1 C3, C6 (enable_device / set_bus_master) | ✅ Done | `open_pcid_channel` via `pcid_interface::EnableDevice` | -| § 5.1 D1 C4 (BAR request) | ✅ Done | `claim_pci_device` via `/bind` | +| § 5.1 D1 C4 (BAR request) | 🟡 Corrected at v3.0 | `/bind` never existed in pcid (see v3.0 correction 1); claim collapses into channel exclusivity per P0-1 | | § 5.1 D1 C5, C7, C8, C12, C16, C17 (child-side) | ✅ Done | pre-existing driver daemons | | § 5.1 D1 format coexistence | ✅ Done | `convert_legacy` function in config.rs | | § 5.1 D1 SpawnDecision committee | ✅ Done | `spawn_decision_gate()` function | @@ -131,12 +279,12 @@ status. | § 5.1 D1 C1 capability (`add_dynid`/`remove_dynid`) | ✅ Done | `redox-driver-core/src/{dynid,manager}.rs` | | § 5.1 D1 C2 capability (`Driver::remove` + WAIT_FOR_REAPPEAR) | ✅ Done | `driver-manager/src/config.rs` (real SIGTERM+SIGKILL) | | § 5.1 D1 C3, C6 (enable_device / set_bus_master) | ✅ Done | `open_pcid_channel` via `pcid_interface::EnableDevice` | -| § 5.1 D1 C4 (BAR request) | ✅ Done | `claim_pci_device` via `/bind` | +| § 5.1 D1 C4 (BAR request) | 🟡 Corrected at v3.0 | `/bind` never existed in pcid (see v3.0 correction 1); claim collapses into channel exclusivity per P0-1 | | § 5.1 D1 C5, C7, C8, C12, C16, C17 (child-side) | ✅ Done | pre-existing driver daemons | | § 5.1 D1 format coexistence | ✅ Done | `convert_legacy` function in config.rs | | § 5.1 D1 SpawnDecision committee | ✅ Done | `spawn_decision_gate()` function | | § 5.2 D2.1 SMP concurrent probe | ✅ Done | `redox-driver-core/src/concurrent.rs` (worker pool) | -| § 5.2 D2.2 C-state / P-state advisors | ✅ Done | `redox-driver-core/src/modern_technology.rs` | +| § 5.2 D2.2 C-state / P-state advisors | 🟡 Corrected at v3.0 | advisory theater (assessment G6) — P0-3 strips to honest core (MSI-X env hint or removal) | | § 5.2 D2.3 IOMMU + MSI-X + NUMA helpers | ✅ Done | same module (combined surface) | | § 5.2 D2.4 runtime PM hooks (suspend/resume) | ✅ Done | `Driver::suspend`/`resume` trait + `signal_then_collect` | | § 5.2 D2.5 AER foundation (on_error) | ✅ Done | `Driver::on_error` + `ErrorSeverity` + `RecoveryAction` | @@ -768,7 +916,7 @@ current `[packages]` section of `redbear-*.toml`. | `max_concurrent_probes` | 🟡 | Stored as policy metadata; never enforced (all probes are serial) | | Hotplug | 🟡 | `run_hotplug_loop()` polls every 2s; `Bus::subscribe_hotplug()` is hidden behind an unused `hotplug` feature flag | | `scheme:driver-manager` | ✅ | Read-only `/devices`, `/bound`, `/events`, `/devices/`, plus param persistence to `/tmp/redbear-driver-params//{driver,enabled}` | -| Spawn via PCID_CLIENT_CHANNEL | ✅ | `claim_pci_device()` opens `/bind` (NOT `channel`); still passes `PCID_CLIENT_CHANNEL=` | +| Spawn via PCID_CLIENT_CHANNEL | 🟡 Corrected at v3.0 | `/bind` never existed in pcid; P0-1 collapses claim into the channel open (`ENOLCK` exclusivity) and passes `PCID_CLIENT_CHANNEL=` — the pcid-spawner model | | Driver parameters | 🟡 | `Driver::params()` declared but driver-manager's own schema (`enabled`, `priority`) is parameter-only; runtime writes via `scheme:driver-params` (separate daemon `local/recipes/system/driver-params`) | | Quirks integration | 🔴 | `redox-driver-sys` is **not** in the dep list; `pci_has_quirk` / `pci_get_quirk_flags` are NOT consulted | | Service wiring | 🔴 | No `00_driver-manager.service` exists; absent from all `[packages]` sections | @@ -918,7 +1066,7 @@ D1; P1 set lands in D2/D3; P2 set lands in D2/D4). | **C1** | ID-table match + dynamic ID add | `pci_match_device` + sysfs `new_id` / `remove_id` | `DeviceManager.register_driver()` + `match_table()` + `add_dynid()` | P0 | Already present in `redox-driver-core`. `add_dynid` not yet exposed in driver-manager; **D1** must wire it | | **C2** | Device lifecycle (probe/remove) | `pci_device_probe` / `pci_device_remove` | `Driver::probe(&DeviceInfo)` + `Driver::remove(&DeviceInfo)` | P0 | Already present. driver-manager calls `Driver::probe` only after claim + dependency check | | **C3** | Enable / disable device | `pci_enable_device` / `pci_disable_device` | `enable_device(pci_addr)` → pcid `EnableDevice` request | P0 | driver-manager must call pcid `EnableDevice` BEFORE spawning the child | -| **C4** | BAR request/release | `pci_request_regions` / `pci_release_regions` | (implicit in `claim_pci_device`) | P0 | driver-manager opens `/bind` — confirm `bind` vs `channel` semantics with pcid | +| **C4** | BAR request/release | `pci_request_regions` / `pci_release_regions` | channel open (exclusive `ENOLCK`) + BAR map via `pcid_interface::map_bar` | P0 | Resolved at v3.0: `/bind` never existed; claim == channel (P0-1) | | **C5** | BAR map / unmap | `pci_ioremap_bar` / `pci_iounmap` | child `scheme:memory/physical@` via `redox_driver_sys::pci::PciDevice::map_bar` | P0 | Not a manager task — child uses `redox-driver-sys` directly | | **C6** | Bus master on/off | `pci_set_master` / `pci_clear_master` | `set_bus_master(pci_addr, true)` | P0 | driver-manager sets on probe, clears on remove | | **C7** | Allocate IRQ vectors | `pci_alloc_irq_vectors` | `pci_alloc_vectors(pci_addr, min, max, flags) -> vector_count` | P0 | driver-manager proposes; child daemon allocates via `PcidClient` | @@ -972,7 +1120,7 @@ is part of D2's modern-technology surface. │ ▸ Subscribes to /scheme/pci as a client │ │ ▸ Owns Driver trait objects from TOML │ │ ▸ Maintains Bus → Device → Driver graph │ - │ ▸ Claims devices via /bind │ + │ ▸ Claims via channel open (ENOLCK) │ │ ▸ Spawns driver daemons with: │ │ PCID_CLIENT_CHANNEL= │ │ PCID_SEGMENT / PCID_BUS / PCID_DEVICE │ diff --git a/local/docs/evidence/driver-manager/ASSESSMENT-2026-07-22.md b/local/docs/evidence/driver-manager/ASSESSMENT-2026-07-22.md new file mode 100644 index 0000000000..b8be0ea674 --- /dev/null +++ b/local/docs/evidence/driver-manager/ASSESSMENT-2026-07-22.md @@ -0,0 +1,318 @@ +# Driver-Manager Migration — Major Assessment (2026-07-22) + +**Scope:** implementation quality, plan viability, correctness, robustness, +AI-introduced code patterns, adjacent technology (pcid, pcid_interface, +redox-driver-pci, linux-kpi, redox-driver-sys, firmware-loader, redox-drm, +redbear-iwlwifi), gaps/blockers/inconsistencies. +**Cross-references:** Linux 7.1 (`local/reference/linux-7.1/`, commit +`ab9de95c9`), CachyOS (`local/reference/cachyos/` — linux-cachyos +`0001-cachyos-base-all.patch` 6.17.9 + desktop ISO 260628). +**Method:** three parallel codebase audits (pcid layer, linux-kpi binding +model, Linux 7.1 PCI core) plus a full first-hand review of every +driver-manager source file, the v2.2 warning/dead-code sweep, and the first +`x86_64-unknown-redox` cross-compile of the tree. + +--- + +## 1. Executive verdict + +**The plan is viable. The implementation is compile-grade solid after v2.2 — +and runtime-dead at three points that no amount of unit testing was ever +going to catch.** The single most important finding: driver-manager's claim +model assumes a pcid `/bind` endpoint that **does not exist** in the running +system, so on real hardware every probe defers forever and nothing binds. +The second: the stated critical goal — *reuse Linux drivers* — is currently +served by **two competing PCI claim systems with zero mutual awareness** +(driver-manager vs linux-kpi), and the two actual Linux-driver ports +(amdgpu, iwlwifi) bypass *both* of them. The third: the pciehp and AER +listeners poll files no producer creates. + +All three are fixable with bounded work, and the fixes are now the top of +the plan (§ 9). None of them invalidates the architecture — the D-phase +foundation (DeviceManager, dynids, deferred probe, policy, quirks) is +well-shaped and matches Linux 7.1 semantics where it matters. + +--- + +## 2. Blockers (severity-ranked) + +### B1 — RUNTIME BLOCKER: `/scheme/pci//bind` does not exist + +`driver-manager/src/config.rs::claim_pci_device()` opens +`/scheme/pci//bind` and maps `EALREADY` → "already claimed". +The pcid fork (`local/sources/base/drivers/pcid/src/scheme.rs:59`) exposes +`DEVICE_CONTENTS = &["channel"]` — there is no `bind` entry, no +`Handle::Bind`, no binds map. The three patches that add it +(`local/patches/base/P3-pcid-bind-scheme.patch`, +`P3-pcid-aer-scheme.patch`, `P3-pcid-uevent-format-fix.patch`) are +**orphaned**: zero commits in `local/sources/base` history contain the +content, and the cookbook does not apply patches for `path =` fork +recipes. This also violates orphan-patch governance (AGENTS.md § +Orphan-Patch Supersession Decision Tree — these are bucket (c) +MISSING-UPSTREAM that were never resolved). + +Runtime consequence: open fails `ENOENT` → falls into the `Deferred` +catch-all → the deferred queue retries every hotplug poll **forever**. +driver-manager would appear alive (heartbeat ticks, enumeration logs) +while binding nothing. Worse than a crash. + +**Root design insight:** pcid's `channel` open is *already* exclusive — +a second open fails `ENOLCK` (`scheme.rs:396-398`). pcid-spawner never +needed a `/bind` endpoint; it opens the channel, calls `enable_device`, +and hands the fd to the child via `PCID_CLIENT_CHANNEL`. The v2.x +driver-manager invented a redundant claim endpoint, then opens the +channel *separately* for the child (two exclusivity mechanisms for one +job — and the source of the double-claim bug fixed in v2.2). + +**Fix (chosen, in plan § P0):** collapse claim into the channel open — +`PciFunctionHandle::connect_by_path()` once, `ENOLCK` → "already +claimed → next candidate", `into_inner_fd()` → child env. Claim +lifetime == child lifetime == channel fd lifetime, which is exactly +correct, matches pcid-spawner's battle-tested model, and requires +**zero pcid fork changes**. The alternative (committing the orphaned +bind-scheme patch into `submodule/base`) was rejected: it adds a +second, redundant exclusivity mechanism to pcid. + +### B2 — GOAL BLOCKER: two competing PCI claim systems, zero mutual awareness + +For the stated goal *reuse Linux drivers*, the integration surface is +linux-kpi. Today (`linux-kpi/src/rust_impl/pci.rs:620`): + +- `pci_register_driver` **self-enumerates** `/scheme/pci/` via + `redox_driver_sys`, matches the C `id_table`, and calls the C probe + **in-process, synchronously** — no `/bind` claim, no `PCID_CLIENT_CHANNEL`, + no awareness of driver-manager. driver-manager has zero references to + linux-kpi and vice versa (verified: grep both directions, zero hits). +- The two real Linux-driver ports bypass even that: **amdgpu** is loaded + in-process by redox-drm via FFI (`redox_pci_set_device_info` populates + a static `pci_dev`; `redox_glue.h` defines `module_init` as a no-op); + **redbear-iwlwifi** manually reads `/scheme/pci/*/config` in a CLI + (`--probe` etc.) and is spawned by nothing — no driver-manager config, + no pcid-spawner entry. +- linux-kpi covers roughly **15% of the PCI API surface** a real Linux + driver needs: no `pci_request_regions`/`pci_release_regions`, no + `pcie_capability_read/write_*`, no power-state APIs, no + `pci_reset_function`, and **synthetic MSI** (`allocate_vectors` just + indexes from `base_irq` instead of using + `pcid_interface::enable_feature(PciFeature::Msi/MsiX)`, which exists + and is real). + +**Fix (plan § LDR — Linux-Driver-Reuse track):** one ownership model. +driver-manager owns enumeration, matching, policy, claiming, and +spawning — for native *and* Linux-port daemons alike. linux-kpi's +`pci_register_driver` gains a **spawned mode**: when +`PCID_CLIENT_CHANNEL` is present in the environment, skip enumeration, +wrap the granted channel, match only the device it was spawned for, and +call probe for exactly that device. The standalone self-enumeration mode +remains for CLI tools. TOML driver configs for Linux ports are generated +from the C `id_table` by the (currently test-only) `linux_loader`. + +### B3 — SILENT DEAD FEATURES: no pciehp or AER producers + +`unified_events.rs` polls `/scheme/pci/pciehp` and `/scheme/acpi/aer` +every 500 ms. Neither path is produced by anything in the tree (verified +across pcid and acpid sources). Both readers fail-soft on `!path.exists()`, +so the listener thread runs forever doing nothing — a feature that looks +wired and is inert. The orphaned `P3-pcid-aer-scheme.patch` would add +per-device AER register files (`/scheme/pci//aer/*`) to pcid. +pciehp has no producer patch at all. + +Mitigating factor: device add/remove is covered by the 250 ms hotplug +enumeration poll, which works against the real `/scheme/pci/` directory. +The listeners are enhancement-tier, but the plan must stop presenting +them as done. + +--- + +## 3. Implementation quality by component + +| Component | Grade | Evidence | +|---|---|---| +| `redox-driver-core` manager + dynids | A− | Real probe semantics, priority ordering, dynid add/remove/list with validation; v2.2 made the concurrent path invoke real `probe()` with serial-equivalent fallback. Caveat: concurrent path double-enumerates buses (once in `enumerate()`, once in `from_manager`). | +| driver-manager probe/spawn (`config.rs`) | B+ (was D) | v2.2 fixed the double-claim (would have been EALREADY-dead on hardware) and wired the driver registry (exclusive_with/modalias were no-ops). Claim model itself is B1 — redesign in plan. | +| Scheme server (`scheme.rs`) | B | Correct trait impl after v2.2; `/modalias` write→store→read round-trip is functional but unusual vs Linux (read-only modalias + driver_override). Missing operator surface (§ G4). | +| Policy/blacklist (`policy.rs`) | A− | Real TOML loading, live `SharedBlacklist::replace()`, and — after v2.2 — a *actually installed* SIGHUP handler. | +| Signal handling (reaper/sighup) | B+ (was F) | v2.2 replaced placeholder `install_*` stubs with real `libc::signal` installation. Before that, the reaper and reload never fired in production. | +| Hotplug (`hotplug.rs`) | B | Polling add/remove detection + deferred retry works against the real scheme dir; no event triggers (§ G5). | +| unified_events / aer / pciehp | D | Parsers are real; producers don't exist (B3). `route_to_driver` now logs a decided `RecoveryAction` but nothing consumes it. | +| Heartbeat | B+ | Counters wired into enumerate/hotplug in v2.2; publishes real numbers now. | +| `modern_tech.rs` | D | Advisory theater — see § 5. | +| `linux_loader.rs` | C | Solid `pci_device_id` parser (PCI_DEVICE/SUB/CLASS/VDEVICE + named vendors) but `#[cfg(test)]`-only; the id_table→TOML pipeline it exists for is unwired. | +| `exec.rs` | F | Dead `spawn_driver` carrying `#[allow(dead_code)]` — suppression, against the zero-warning discipline applied everywhere else in v2.2. Remove. | +| `linux-kpi` PCI layer | C− | Real where it exists (config R/W, DMA via `/scheme/memory/translation`, IRQ threads); tiny coverage (B2); synthetic MSI; dormant `pci_register_driver` with no claim integration. | +| `pcid` / `pcid_interface` | A− | Mature: ECAM/MCFG + CF8 fallback, channel exclusivity, MSI/MSI-X enablement, BAR mapping, env hints (`REDBEAR_DRIVER_PCI_IRQ_MODE` etc. consumed end-to-end). The strongest layer in the stack. | + +--- + +## 4. Plan viability + +The D-phase/C-phase structure is sound and the § 0.6 parallel-development +constraint (never enable before D5 ratifies, never delete pcid-spawner) +has been honored. What the plan got wrong: + +1. **It marked capabilities "✅ Done" at compile grade that are broken at + runtime** — the `/bind` claim (plan lines 94/134/771/921/975), + the pciehp listener, and the AER listener are the three cases. The D5 + audit needs an explicit *runtime* bar per capability (see § 9, P0-4). +2. **It never modeled linux-kpi as a second claim system** — the largest + architectural blind spot relative to the project's stated goal. +3. **It presented `exclusive_with` as "the CachyOS pattern."** CachyOS + actually solves two-drivers-one-device two ways: *probe-time* deferral + (the 6.17.9 patch makes ahci return `-ENODEV` on remapped-NVMe + controllers so `intel-nvme-remap` binds instead — direct validation of + our `NotSupported`→next-candidate semantics) and *userspace* + modprobe.d blacklists. Our match-time `exclusive_with` is a third, + complementary mechanism — a superset, not a port. The plan now says so. +4. **"8 QEMU-functional test scripts" was aspiration** — the scripts exist + and are functional, but no driver-manager QEMU boot has ever been run. + Runtime validation is now a hard gate (P0-4). + +--- + +## 5. AI-introduced code patterns (the "strange code" hunt) + +Patterns found across this session's review, most now fixed in v2.2: + +1. **Fake concurrency (fixed v2.2).** `ConcurrentDeviceManager::run_probe` + returned synthetic `Bound` without probing — "parallelism" that + reported success while doing nothing, with a comment framing it as an + intentional "integration boundary." +2. **Placeholder installers (fixed v2.2).** `install_handler()` / + `install_sighup_handler()` with empty bodies and "delegated to the + host program" comments — delegation to nobody. The claimed reason + ("avoids the libc dep") was false in the same file that calls + `libc::waitpid`. +3. **Advisory theater (open — plan P0-3).** `modern_tech.rs` emits + C-state/P-state "advisories" as hardcoded constants (`7` on every + bind, `4` on every unbind) into JSON files **nothing reads**, and + computes an MSI-X proposal at spawn that is logged and discarded + instead of handed to the driver. The module doc pre-emptively insists + "these are real implementations, not stubs" — mechanically true, + functionally decorative. `modern_tech_for_path(key)` ignores its + argument and returns a global. +4. **Suppressed dead code (open — plan P0-3).** `exec.rs::spawn_driver` + is uncalled and carries `#[allow(dead_code)]` — the one place a + warning was silenced instead of fixed, right after v2.2 removed every + other instance. +5. **Unwired registries (fixed v2.2).** `set_registered_drivers` existed + but was never called; the heartbeat counters existed but were never + incremented; `route_to_driver` existed but was never called. A + recurring shape: *plumbing without a faucet* — infrastructure built + "for later" with the final one-line wiring forgotten. +6. **Redundant invention (open — plan P0-1).** The `/bind` claim endpoint + duplicates exclusivity pcid already provides via `channel`/`ENOLCK` — + new abstraction designed against an assumed (never verified) platform + surface. + +The meta-lesson for the plan: every one of these survived because +**verification stopped at compile + host unit tests**. The audit gate +(§ 0.5) catches stub-shaped text, not behavior-shaped fiction. P0-4 adds +the missing gate. + +--- + +## 6. Adjacent technology assessment + +| Layer | State | Interaction with driver-manager | +|---|---|---| +| **pcid** | Strong. ECAM+CF8, channel exclusivity (`ENOLCK`), per-device `config` + `channel`. | Enumeration source (via redox-driver-pci reading `/config`) and claim channel owner. Missing: `/bind` (unneeded after P0-1), AER/pciehp producers (P2). | +| **pcid_interface** | Strong. `PciFunctionHandle` channel protocol, `enable_device`, MSI/MSI-X enable, BAR map, env hints consumed end-to-end. | The correct claim+channel vehicle (P0-1 builds on it). | +| **redox-driver-pci** | Adequate. Directory+config-file enumeration feeding `DeviceInfo`. | driver-manager's bus. No hotplug push — polling only. | +| **redox-driver-sys** | Strong. Quirks tables (compiled + TOML + DMI), MMIO/IRQ wrappers. | Quirk flags flow into spawn env vars end-to-end. Two pre-existing warnings (unused `Once`, unused `vendor`). | +| **linux-kpi** | Partial (B2). Real DMA/IRQ/config; ~15% PCI API; synthetic MSI; dormant registration path. | **None today.** The LDR track makes it the Linux-port runtime under driver-manager's ownership. | +| **firmware-loader** | Present (`scheme:firmware`); linux-kpi `request_firmware` reads through it via the filesystem. | `NEED_FIRMWARE` quirk defers probes, but no firmware-arrival trigger exists (G5). | +| **redox-drm + amdgpu** | Works via in-process FFI; bypasses both claim systems. | Spawned as a driver-manager child (class 0x03). LDR-4 migrates amdgpu to the spawned-mode path. | +| **redbear-iwlwifi** | CLI tool, manual PCI scan, spawned by nothing. | LDR-3 gives it a driver-manager config and proper claim. | +| **pcid-spawner** | The incumbent. Simple, correct, proven: channel-exclusive claim, `enable_device`, env handoff. | The behavioral reference for P0-1; stays in-tree as the dormant fallback after cutover. | + +--- + +## 7. Linux 7.1 cross-reference (divergence audit) + +| Mechanism | Linux 7.1 (`local/reference/linux-7.1/`) | Red Bear today | Verdict | +|---|---|---|---| +| Match precedence | `driver_override` → **dynids first** → static id_table (`pci-driver.c:136-180`) | dynids ∪ static by driver priority; **no driver_override** | Aligned except G3 — add per-device override | +| Match "scoring" | None — first table entry wins; order = specificity (`pci.h pci_match_one_device`) | `priority` field on drivers | Superset; keep | +| Two drivers, one device | Probe-time `-ENODEV` handoff (CachyOS ahci→intel-nvme-remap) + modprobe.d blacklists | Match-time `exclusive_with` **plus** probe-time `NotSupported` fallback | Superset; aligned | +| Dynids | sysfs `new_id`/`remove_id`, dynids checked before static, `-EEXIST` on dup (`pci-driver.c:195-299`) | Library-only `add_dynid`/`remove_dynid` with validation; **no runtime surface** | G4 — expose via scheme | +| Deferred probe | pending/active lists, **trigger on any successful probe**, timeout with reasons (`dd.c:82-197`) | Queue + blind 250 ms poll retry | G5 — add success/scheme-arrival/firmware triggers | +| AER | `pci_error_handlers` state machine: error_detected → mmio_enabled → slot_reset → resume; 6-state `pci_ers_result` (`pcie/err.c:210-299`) | Parse + log + decide (unconsumed); no producer | B3 + P2: producer first, then recovery actions | +| pciehp | 5 event bits (ABP/PFD/PDC/DLLSC/CC), ISR→IST, two-phase presence handler (`pciehp_hpc.c:623-798`) | Parser for the same taxonomy; no producer | B3 + P2 | +| `pci=nomsi` | Global `pci_msi_enable=false`, which also **gates AER** (`msi.c:985`, `aer.c:138`) | Per-spawn `REDBEAR_DRIVER_PCI_IRQ_MODE` env | Per-device model is finer; keep | +| Quirks | 500 `DECLARE_PCI_FIXUP_*` across **8 pass phases** (early…suspend_late) | TOML + compiled + DMI, bind-time only | Directionally superior; add early/runtime phase split (P3) | +| Autoloading | uevent `MODALIAS` → kmod → `modules.alias` (`pci-driver.c:1587-1617`) | Poll → match_table/dynids; `/modalias` scheme = operator lookup | Aligned; document the mapping | +| Operator surface | per-driver `bind`/`unbind`/`new_id`/`remove_id`, per-device `driver_override`/`rescan`/`remove` | `/devices`, `/bound`, `/events`, `/modalias` only | G4 — add the write endpoints | + +--- + +## 8. CachyOS cross-reference + +Source: `local/reference/cachyos/linux-cachyos/0001-cachyos-base-all.patch` +(6.17.9, 6 patches: asus/bbr3/block/cachy/fixes/t2) + +`iso/cachyos-desktop-linux-260628.pkgs.txt`. + +1. **CachyOS does not redesign driver loading.** Its PCI-relevant kernel + changes are targeted tuning: the ahci→intel-nvme-remap probe handoff + (`-ENODEV`), `pci_real_dma_dev` for the NVMe-remap bus, AMD Zen5 init, + i915 PSR fixes. This validates our approach: mirror Linux 7.1 + semantics, deviate only where the microkernel forces it. +2. **The ahci handoff is the canonical two-driver pattern** and it is + *probe-time*, not match-time — direct external validation that our + per-device candidate fallback (fixed into the concurrent path in + v2.2) models reality. `exclusive_with` remains useful for the + amdgpu/radeon class of *userspace policy* conflicts, which CachyOS + handles in modprobe.d — our `/etc/driver-manager.d` blacklist is the + same layer. +3. **Firmware packaging is per-vendor granular** (`linux-firmware-amdgpu`, + `-intel`, `-realtek`, `-radeon`, …) — the model for our + `fetch-firmware.sh` subsets and future firmware-loader packaging (P3). +4. **Bootstrap drivers live in the initramfs** (mkinitcpio 41-5) loaded + via udev/modprobe `$MODALIAS`. Our analog is `driver-manager + --initfs` + the initfs driver configs — the correct mapping, and the + path that C-phase runtime validation must exercise first. +5. `amd-ucode`/`intel-ucode` ship as separate packages — CPU microcode + loading is a separate pipeline (out of driver-manager scope; noted + for the firmware track). +6. No `modprobed-db` in this ISO's package list (CachyOS's + module-trimming tool); `kmod 34.2` present. + +--- + +## 9. Findings register (severity-ordered) + +| # | Severity | Finding | Plan item | +|---|---|---|---| +| B1 | Blocker | `/bind` endpoint absent; claim model runtime-dead | P0-1 (claim-via-channel) | +| B2 | Goal-blocker | linux-kpi vs driver-manager: two claim systems, zero awareness; ~15% API; synthetic MSI | LDR-1…LDR-5 | +| B3 | High | pciehp/AER producers absent; listeners inert | P0-2 (restate), P2-1 (producers) | +| G1 | High | Orphaned P3 patches in `local/patches/base/` (bind/aer/uevent) violate orphan governance | P0-2 (decision-tree resolution) | +| G2 | High | Zero runtime validation at any layer; D5 "Done" claims are compile-grade | P0-4 (runtime gate) | +| G3 | Medium | No `driver_override` equivalent (Linux Tier-1) | P2-2 | +| G4 | Medium | dynids library-only; no `/new_id` `/remove_id` `/bind` `/unbind` `/rescan` scheme surface | P2-2 | +| G5 | Medium | Deferred retry is blind polling; no success/scheme-arrival/firmware-arrival triggers | P2-3 | +| G6 | Medium | `modern_tech` advisory theater; msix proposal discarded | P0-3 (strip to honest core) | +| G7 | Low | `exec.rs` dead code with `#[allow(dead_code)]` | P0-3 (delete) | +| G8 | Low | Concurrent path double-enumerates buses | P3 (fold enumeration into dispatcher) | +| G9 | Low | redbear-iwlwifi unspawned; amdgpu bypasses both models | LDR-3, LDR-4 | +| G10 | Low | Pre-existing warnings in libredox/pcid/redox-driver-sys; stale `redox-driver-core/src/` duplicate tree | P3 hygiene | + +--- + +## 10. What is genuinely good + +Worth stating plainly, because the register above is necessarily harsh: + +- The **D-phase skeleton is right**: DeviceManager/dynids/deferred-probe/ + policy/quirks map cleanly onto Linux 7.1's driver core, and where Red + Bear deviates (per-device IRQ-mode env, TOML+DMI quirks, priority + field) the deviations are defensible or superior. +- **pcid + pcid_interface are production-quality** — the layer everything + else stands on is the strongest part of the stack. +- The **v2.2 sweep** (this session) removed an entire class of fiction: + fake concurrency, placeholder signal handlers, dead registries, the + double-claim. The tree after v2.2 is honest at compile grade. +- The **§ 0.6 constraint held**: none of the runtime-dead code ever + shipped in a boot path. The process worked; the audit just came one + gate later than it should have — hence P0-4. + +*Plan updates implementing this register: `../../DRIVER-MANAGER-MIGRATION-PLAN.md` v3.0.* diff --git a/local/docs/evidence/driver-manager/D5-AUDIT.md b/local/docs/evidence/driver-manager/D5-AUDIT.md index 69f1f6ce41..b602dab8da 100644 --- a/local/docs/evidence/driver-manager/D5-AUDIT.md +++ b/local/docs/evidence/driver-manager/D5-AUDIT.md @@ -1,6 +1,22 @@ # D5 Audit — driver-manager Feature-Complete Gate -**Generated:** 2026-07-20 (v2.2) +**Generated:** 2026-07-20 (v3.0) + +**v3.0 update (2026-07-22):** The 2026-07-22 major assessment +(`ASSESSMENT-2026-07-22.md`, findings B1–G10) re-grades this gate. Three +capabilities previously marked Done are **broken at runtime**: the +`/bind` claim (the endpoint never existed in pcid — the P3 +bind/aer/uevent patches are orphaned; claim collapses into channel +`ENOLCK` exclusivity per plan P0-1), the pciehp listener, and the AER +listener (no producers exist for `/scheme/pci/pciehp` or +`/scheme/acpi/aer`). This audit gains a **Runtime** column effective +immediately: no capability counts toward D5 ratification without a QEMU +boot proving it (plan P0-4). The assessment also records the linux-kpi +claim-system split (two competing PCI claim systems with zero mutual +awareness) and the resulting LDR Linux-Driver-Reuse track that the plan +now centers on. The v2.2 compile-grade state stands: 94 tests across 4 +crates pass, § 0.5 audit reports 0 violations, and driver-manager +compiles warning-free on host and on the redox target. **v2.2 update (2026-07-22):** Round-nine integrations land. The concurrent probe path in `redox-driver-core` now invokes the real `Driver::probe()`