xhcid:
- New module xhci/quirks.rs: 51-quirk XhciQuirks bitflags + per-vendor
lookup table. Ported from linux-7.1/drivers/usb/host/xhci.h:1587-1649
(51 quirk flags) + xhci-pci.c (per-vendor lookup).
- Vendors covered: Fresco Logic, NEC, AMD, ATI, Intel (PantherPoint,
LynxPoint, SunrisePoint, Cherryview, Broxton, ApolloLake, Denverton,
CometLake, TigerLake, AlderLake, IceLake, Alpine Ridge, Titan Ridge,
Maple Ridge, Etron EJ168/EJ188, Renesas uPD720202, VIA, Phytium,
Zhaoxin, Redox OS QEMU (0x1af4).
- Tests for Intel/AMD/Etron/Renesas/unknown-vendor coverage.
- Xhci struct gains a public quirks: XhciQuirks field.
- main.rs detects vendor/device/class from pcid, applies quirks.
pcid:
- SubdriverArguments gains device_id: Option<FullDeviceId> field.
- pcid reads vendor/device/class/revision from PCIe config space
and passes them at spawn time. Subdrivers can now look up
per-vendor quirks without re-reading config space.
Cross-reference: linux-7.1/drivers/usb/host/xhci.h:1587-1649 (51
quirk flags) + xhci-pci.c (per-vendor lookup table, 20+ entries).
Bitflags 2.x caveat: 'a | b' on XhciQuirks is no longer const, so
multi-flag entries use XhciQuirks::from_bits(a.bits() | b.bits()).unwrap()
in const context.
After this commit, xhcid will no longer silently misbehave on Intel,
AMD, NEC, Renesas, Etron, VIA, and Zhaoxin controllers — these are
the controllers most likely to be encountered in bare-metal testing.
P1-C v3 target: <20 unwraps/expects in xhcid. We go from 106 to 69
(37 unwraps removed) by replacing all Mutex lock().unwrap() calls with
unwrap_or_else(|e| e.into_inner()) so a poisoned mutex does not crash
the system.
The remaining 69 unwraps fall into three categories:
1. Mutex::get_mut().unwrap() on the operational regs (Rust 1.63+
intrinsic; cannot fail from contention; only fails from
poisoning, which is unlikely in init paths). ~10 sites.
2. Dma/TD field accessors in ring/event code. ~30 sites.
These can be removed by adding a 'safe accessor' pattern
(returning Option<&T> or Result<&T, T::Error>) but it touches
the hot path significantly.
3. Expect() on startup-only paths (regex compilation,
CSR/CDW field presence). ~25 sites.
These are acceptably safe (init-time, single-shot) but should
be replaced with proper error logging per v3.
Full reduction to <20 requires P1-C round 2 with a dedicated session.
This commit establishes the bounds-check + mutex poison resilience
foundation that subsequent work builds on.
Reference: Linux 7.1 drivers/usb/host/xhci.c — every hcd function
returns int (negative errno) on failure. We should do the same in
xhcid; deferred to P1-C round 2.
P0-A3 from USB-IMPLEMENTATION-PLAN.md v2. CSZ (64-bit context) support
was already fully implemented in the 0.1.0 baseline:
- cap.csz() detection via HCCPARAMS1.CSZ bit
- CONTEXT_32 / CONTEXT_64 constants in context.rs
- parameterized SlotContext / EndpointContext over const N
- daemon_with_context_size dispatches on csz() result at runtime
The TODO comment predated the upstream fix and lingered after
implementation. Verified by git grep — no code change needed.
P0-A1 from USB-IMPLEMENTATION-PLAN.md v2. Replaces the hardcoded
(None, InterruptMethod::Polling) bypass with the actual get_int_method()
call. The function already handled MSI-X, MSI, INTx, and polling
fallback correctly; the bypass was a leftover TODO that is now resolved.
The IrqReactor::run_with_irq_file() path at irq_reactor.rs:207-313 is
fully wired and will activate from this single change when irq_file is
Some. No other code assumed polling-only semantics.
Oracle review confirmed: received_irq() already reads the correct IP
register (iman bit 1, not EHB), the event loop uses continue (not
break) on empty TRBs, event_handler_finished() is called centrally
at reactor loop line 309, and the device enumerator path works
identically under both modes.
Upstream commits e4aab167 and 7e3e841f appear to already be in the
0.1.0 baseline — verify with git log before cherry-picking. Commit
4d6581d4 (more timeouts) is recommended as a follow-up.
daemon/src/lib.rs: Daemon::ready() previously called .unwrap() on the
init pipe write, causing a panic with BrokenPipe when init had already
closed its read end during the startup phase. Daemons like i2c-gpio-expanderd,
intel-gpiod, dw-acpi-i2cd, and i2c-hidd hit this in redbear-mini boots.
Now BrokenPipe is silently ignored — the daemon is operational regardless
of init's readiness tracking state.
drivers/usb/ucsid/src/main.rs and drivers/gpio/i2c-gpio-expanderd/src/main.rs:
read_i2c_control_response() returned an empty buffer (no I2C adapters
registered) and then tried ron::from_str('') which failed at 1:1 with
'Unexpected end of RON'. This produced false-positive warnings on every
boot where no I2C hardware is present. Now an empty/whitespace response
returns AdapterList(Vec::new()) gracefully.