Commit Graph

379 Commits

Author SHA1 Message Date
vasilito 487d9e6410 driver-manager: F6d — C18 PM suspend ordering (system_suspend / system_resume)
Closes the C18 capability gap: manager-mediated system PM with
priority-ordered iteration.

Two new /scheme/driver-manager endpoints:
- /suspend (write): walk bound drivers in reverse priority order
  (lowest first) and SIGTERM each spawned PID. Dependency
  preservation: a high-priority driver that depends on a low-
  priority one is suspended last so the latter can keep
  servicing traffic until the former drains.
- /resume (write): walk bound drivers in priority order (highest
  first). Per-driver Driver::resume is currently a no-op (drivers
  re-probe through pcid on resume); the endpoint exists to record
  the operator-initiated event and to give future driver-side
  resume work a stable hook.

DriverConfig gains two pub helpers (cfg::spawned_pids_snapshot
and cfg::signal_all_spawned) that the system PM endpoints call.
The host-target cfg(with_manager stub) lets system_suspend /
system_resume compile on host without a real DeviceManager (the
error path is logged and the call returns cleanly).

Tests (2 new):
- spawned_pids_snapshot_returns_empty_for_unbound_driver
- signal_all_spawned_returns_zero_for_unbound_driver

134 driver-manager tests pass.
2026-07-27 13:05:47 +09:00
vasilito d41c0fd163 driver-manager: F6a — C9 Runtime PM spawn wiring
Closes the C9 capability gap: driver-manager now honours a
per-driver initial_power_state via a new TOML key. When the value
is non-default (D3hot), driver-manager emits
REDBEAR_DRIVER_INITIAL_POWER_STATE=<state> in the spawned daemon's
env so the daemon can call set_power_state on its granted channel.

Mirrors Linux's pci_power_state (include/linux/pci.h). Supported
values: D0 (default), D3hot. Unknown values default to D0 with a
WARN log so a typo never aborts config loading.

Rationale for env-var handoff (vs direct pcid call): the spawned
daemon already holds the granted channel and can call pcid
directly. Driver-manager doesn't need to extend pcid_interface for
a feature the driver can use itself. The env var is the contract;
the daemon implementation can land in its own crate.

DriverConfig gains:
- field: initial_power_state: PciPowerState (default D0)
- TOML key: initial_power_state = "D3hot"
- legacy TOML converter defaults to D0 (no migration path needed)

Tests (7 new):
- pci_power_state_from_toml_round_trips (D0 / D3hot)
- pci_power_state_from_toml_rejects_unknown_values (D1/D2/D3cold/lower-case/empty)
- pci_power_state_is_default_for_d0_only
- pci_power_state_as_str_matches_linux_pci_power_state_names
- load_all_parses_initial_power_state (D3hot from TOML)
- load_all_defaults_to_d0_when_initial_power_state_absent
- load_all_warns_and_defaults_on_invalid_initial_power_state

132 driver-manager tests pass.
2026-07-27 12:53:02 +09:00
vasilito 20ccddddf0 driver-manager: F3 — configurable deferred-retry cap
Closes the medium-severity boot-time correctness gap: hardcoded
30 retries x 500 ms = 15 s wall-clock cap that silently abandons
long-startup drivers. Linux analog (deferred_probe_timeout sysctl)
is configurable.

Adds two env vars (per Linux sysctl analogue):
- REDBEAR_DRIVER_DEFERRED_RETRY_COUNT (default 30)
- REDBEAR_DRIVER_DEFERRED_RETRY_INTERVAL_MS (default 500)

Surfaced at /scheme/driver-manager/timing via new AtomicU32
statics (DEFERRED_RETRY_COUNT, DEFERRED_RETRY_INTERVAL_MS) with
set_deferred_retry_config / deferred_retry_config accessors.
interval_ms is clamped to >= 10 ms to bound CPU use.

main.rs reads env vars via new apply_deferred_retry_env() at
startup and logs the active config. The retry loop now uses
crate::timing::deferred_retry_config() for both count and interval.

Tests (timing module):
- deferred_retry_config_default_is_30_500: statics start at defaults
- set_deferred_retry_config_round_trips: snapshot reflects writes
- set_deferred_retry_config_clamps_sub_10ms_interval: 0 -> 10 ms clamp

125 driver-manager tests pass.
2026-07-27 12:35:53 +09:00
vasilito 0bb3e6fa4d driver-manager: F2 — reaper panic visibility watchdog
Closes the medium-severity observability gap: a panic in the
SIGCHLD reaper worker is currently invisible to driver-manager.
Children silently stop being reaped, pid_to_device grows without
bound, and fork() eventually returns EAGAIN from resource
exhaustion.

Adds a watchdog thread that polls handle.is_finished() every 60s
(default) and emits ERROR-level log lines with the panic payload
on detection. Poll interval is tunable via
REDBEAR_DRIVER_REAPER_WATCHDOG_INTERVAL_MS (clamped to 100ms..=60s
to bound CPU use).

main.rs now spawns the watchdog alongside the reaper; the watchdog
owns the reaper's JoinHandle.

Tests:
- panic_payload_to_string covers &'static str / String / unknown
- watchdog_spawns_and_returns_handle: end-to-end detection of a
  finished worker (env var lowered to 100ms for test speed)
- reaper_watchdog_interval_clamps_low_values: sub-100ms values
  clamped to 100ms
- reaper_watchdog_interval_defaults_to_60s: default interval is at
  least 60s (verified by worker still alive after 200ms)

All 122 driver-manager tests pass.
2026-07-27 12:27:11 +09:00
vasilito d233190d68 driver-manager: F6b — AER 6-state mapping (Linux pci_ers_result parity)
Closes the C13 gap: 4-state -> 6-state.

Adds two new variants to redox-driver-core::RecoveryAction:
- CanRecover (=4) — PCI_ERS_RESULT_CAN_RECOVER; driver can recover
  without a slot reset
- Recovered (=5) — PCI_ERS_RESULT_RECOVERED; recovery complete

The four historical variants (Handled/ResetDevice/RescanBus/Fatal)
remain stable at discriminants 0..=3; the wire protocol is backward
compatible.

Cross-crate surfaces updated:
- linux-kpi c_headers/linux/pci.h: PCI_RECOV_CAN_RECOVER/RECOVERED
  constants added (must match redox-driver-core enum)
- linux-kpi rust_impl/error.rs: RecoveryAction enum gains the two
  variants; the sidecar IPC byte-to-action decoder now maps 4 and 5
- driver-manager scheme.rs::recovery_action_str gains mappings for
  the new variants; new tests cover both round-trips

Interlocked across 4 files — splitting would break compilation
(git-master VALID exception).

driver-manager: 6 recovery_action tests pass; redox-driver-core
recovery_action_round_trips passes.
2026-07-27 12:21:10 +09:00
vasilito 37e5107510 driver-manager: F6c — add PowerFault variant to PciehpEventKind
Closes the 5th pciehp hardware bit. The producer side at
local/sources/base/drivers/pcid/src/events.rs already emits
power_fault events; the consumer side now recognises them and
exposes them as PciehpEventKind::PowerFault with label 'power_fault'.

Adds two new parse tests (full form + alias) and extends the
label round-trip test. All 14 pciehp tests pass.
2026-07-27 12:16:50 +09:00
vasilito e65a23fd6b redbear-dbus: implement real sessiond, wifictl, notifications, statusnotifierwatcher
This commit replaces the D-Bus implementation stubs and gaps identified
during the zbus/D-Bus review round with real, tested implementations.

**redbear-sessiond: real login1 properties + PrepareForShutdown signals**

The login1.Manager interface had hardcoded stub values:
  - idle_since_hint() and idle_since_hint_monotonic() returned 0
  - inhibit_delay_max_usec() returned 0
  - handle_lid_switch() returned 'ignore'
  - handle_power_key() returned 'poweroff'
  - power_off/reboot/suspend wrote to /scheme/sys/kstop but did NOT
    emit PrepareForShutdown(before=true) / PrepareForSleep(true) first

Replace with:
- Run-time configurable atomic fields (last_activity_us,
  inhibit_delay_max_us) and RwLock<String> fields (handle_lid_switch,
  handle_power_key) on SessionRuntime, mutated by the existing control
  socket. Defaults: 5s inhibit delay, 'ignore' lid, 'poweroff' power key.
- power_off/reboot are now async, emit PrepareForShutdown(true) before
  /scheme/sys/kstop write, emit PrepareForShutdown(false) after a
  successful write, and return a D-Bus error if the kstop write fails
  (resetting preparing_for_shutdown).
- suspend emits PrepareForSleep(true)/(false) similarly.
- Bash-style dangling-Clone problem solved via manual Clone impl on
  SessionRuntime that snapshots the atomics and lock contents.

**redbear-wifictl: real NetworkManager-shaped D-Bus interface**

The dbus-nm feature was a no-op stub that just logged 'registered'
without actually doing anything. Replace with a real zbus interface:

- zbus::interface structs wrapping Arc<Mutex<NmWifiDevice>> shared state
- org.freedesktop.NetworkManager at /org/freedesktop/NetworkManager
  exposes WirelessEnabled, WirelessHardwareEnabled, State, and
  GetDevices().
- org.freedesktop.NetworkManager.Device.Wireless at
  /org/freedesktop/NetworkManager/Devices/0 exposes HwAddress,
  PermHwAddress, State, Ssid, Strength, LastScan, AccessPoints,
  GetAccessPoints(), WirelessCapabilities.
- register_nm_interface() now actually builds a blocking
  zbus::connection::Builder on the session bus, registers both
  service name + object paths, spawns a background thread to hold the
  connection alive, and returns. On session-bus connect failure it
  logs an error and returns without crashing.
- When the dbus-nm feature is disabled, behavior is unchanged (no-op).
- Type model enriched: NmWifiDevice gains last_scan, active_ssid,
  active_strength fields + Default derives; NmDeviceState gains
  Default; NmAccessPoint gains Default.

**redbear-statusnotifierwatcher: wired into redbear-full**

The recipe compiled and had 12 tests but was NOT in any config —
the binary never deployed. Add:
- [package.files] stanza to its recipe.toml so the binary is staged
- redbear-statusnotifierwatcher = {} to config/redbear-full.toml
- launch_optional_component invocation in redbear-kde-session

**redbear-notifications: 8 host unit tests**

Previously zero tests. Add a #[cfg(test)] module covering:
- monotonic notification IDs
- capabilities list (spec values present)
- server information strings
- close-id + reason recording
- action invocation payload
- ordering preserved across multiple notifications
- independence between close and action records

**zbus build-ordering marker: clean source**

The marker source lib.rs contained 'pub struct Connection;' which
is misleading. Replace with a minimal comment explaining the
build-ordering purpose. The actual zbus crate is still resolved by
Cargo at downstream build time (unchanged behavior).

**D-Bus symlink cleanup**

Remove recipes/system/dbus/dbus-root-uid.patch (orphan symlink, not
in .gitignore-relevant scope). The actual patch stays in
local/patches/dbus/. The redox.patch in the same directory is a
real file (not a symlink) and is preserved.

**Build-system bug fixes**

- build-preflight.sh: when broken recipe.toml links cannot be restored
  from git, invoke the guard-recipes.sh --fix path so untracked
  custom links are regenerated.
- verify-fork-functions.sh: skip std-trait method names (fmt, eq,
  clone, drop, etc.) when checking for dropped upstream functions —
  these are derivable or compiler-caught, so a missed refactor is
  inert, not a build blocker.
- verify-overlay-integrity.sh: add explicit 'return 0' on log helpers
  so --quiet mode does not abort on the first log call under set -e.

Verification: host cargo test passes on all four modified daemons.
redbear-sessiond: 52 tests (12 new for the properties + signals).
redbear-wifictl: 35 tests (4 new for dbus_nm) + 2 cli_transport.
redbear-notifications: 8 tests (all new).
redbear-upower/udisks/polkit: unchanged, still pass.
2026-07-27 12:10:58 +09:00
vasilito 1dd1fccbf3 docs: relocate DRIVER-MANAGER-MIGRATION-PLAN to archive + cleanup
The DRIVER-MANAGER-MIGRATION-PLAN was self-declared complete (the
driver-manager cutover happened 2026-07-23 per local/AGENTS.md). It
is now historical reference material rather than current planning
authority. Move it from local/docs/ into the established
legacy-obsolete-2026-07-25/ archive directory, updating every
inbound reference.

Also includes minor cross-doc alignment for the previous round's
relocations:

- local/AGENTS.md: update DRIVER-MANAGER-MIGRATION-PLAN to point to
  the legacy archive
- local/docs/REDBEAR-FULL-SDDM-BRINGUP.md: alignment update
- local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md: alignment update
- local/docs/archived/README.md: refresh archive contents note
- local/recipes/system/redbear-driver-policy/source/policy/README.md:
  policy doc drift alignment
- local/scripts/guard-recipes.sh: fix symlink target computation
  (relative path was being glued onto an absolute path, producing
  malformed dangling links like '../..//mnt/.../recipe.toml')
  -- this is a real bug fix discovered during this audit round.
2026-07-27 12:05:54 +09:00
vasilito 3c90858e18 daemons: replace last_err.unwrap() and unreachable!() with safe error paths
The redbear-* D-Bus daemons had two fragile patterns that would panic
on edge cases:

1. The connection-retry loop in daemon main.rs files used
   'last_err.unwrap()' after the loop exhausted. In practice the loop
   always populates last_err on the Err branch, so the unwrap is safe
   today — but the pattern is fragile: any future refactor that
   short-circuits without populating last_err would panic.

   Replace this with 'return Err(err.into())' on the final attempt
   (eliminates the panic path entirely) and keep the post-loop
   'unwrap_or_else' as a defensive fallback that produces a
   descriptive error rather than a panic.

   In redbear-sessiond, the fallback is wrapped in a typed
   ConnectionError that carries the bus address and attempt number.

2. redbear-udisks/src/inventory.rs::hex_char() used 'unreachable!'
   for an out-of-range nibble. A bug at the caller would crash the
   daemon. Replace with the safe fallback '?' character (matches
   the conventional hex encoder behavior).

Verified by host cargo check on all four daemons.
2026-07-27 11:40:04 +09:00
vasilito 27bbe13425 redbear-ftdi/redbear-acmd: propagate USB setup errors + bump base submodule
redbear-ftdi: replace four silenced 'let _ = dev.{reset,set_baud_rate,
set_flow_control,set_modem_ctrl}' calls with configure_device() that
uses ? propagation. On setup failure, logs error and aborts instead
of proceeding with a misconfigured UART.

redbear-acmd: replace two silenced 'let _ = dev.{set_line_coding,
set_control_line_state}' calls with configure_device() that uses ?
propagation. On setup failure, logs error and aborts instead of
proceeding with a half-initialized CDC-ACM device.

Bumps local/sources/base submodule pointer to include the logd/ipcd/
initfs WARNING-level fixes (kernel log loop, fcntl/read stubs, UDS
write backpressure, runtime page size detection).
2026-07-27 08:24:59 +09:00
Red Bear OS Builder 0a0402b955 d-bus: kf6-kwallet kwalletd6 build + redbear-meta static README cleanup (v3.7)
* kf6-kwallet: enable the kwalletd6 daemon binary. The recipe
  previously had -DBUILD_KWALLETD=OFF in the cmake invocation and
  omitted the KF6 dependencies that kwalletd6 needs (KF6Crash,
  KF6DBusAddons, KF6GuiAddons, KF6Notifications, KF6WidgetsAddons).
  This commit:
    - Adds the five missing KF6 dependencies to the [build] list.
    - Removes -DBUILD_KWALLETD=OFF so kwalletd6 is actually built.
    - Adds a kwalletd6-wrapper.sh generated by the build script that
      renames the Qt6 Wayland plugin so it cannot be loaded, then
      execs the real kwalletd6 binary with QT_QPA_PLATFORM=offscreen.
      This is the same approach that the kded6 recipe uses; kwalletd6
      page-faults the same way on Redox otherwise.
    - Replaces the post-install copy of /usr/bin/kwalletd6 with the
      wrapper, just like kded6.

  kwallet-query, X11, and translations remain disabled, so the
  client library + daemon are what this commit enables.

* redbear-meta: clean up the static README that the meta package
  writes to /usr/share/doc/redbear-meta/README. The previous version
  listed redbear-iwlwifi as an installed component even though
  iwlwifi is currently excluded from the dependencies list. The new
  version removes the iwlwifi line and adds a note explaining the
  current exclusion status.

* redbear-meta: update the iwlwifi-exclusion comment. The previous
  comment referenced src/linux_port.c / mac80211.h; mac80211.h
  does not exist in the source tree. The new comment lists the
  actual source files (src/linux_port.c, src/linux_mvm.c,
  src/linux_mld.c, src/mld/, src/bridge/) and notes that the
  Redox kernel-side integration is the gating item.

* DBUS-PLAN bumped to v3.7 (2026-07-26). The Implementation status
  line now describes the kf6-kwallet build (kwalletd6 daemon
  enabled with the offscreen QPA wrapper). The Phase 4 surface is
  reduced to (kf6-kauth + PolkitQt6-1, kf6-kded6 + kglobalaccel)
  since kwallet is now real.

Tested: cargo check skipped per user request (no build). 73 D-Bus
daemon unit tests already in place from prior rounds and untouched
by this commit.
2026-07-26 23:26:57 +09:00
Red Bear OS Builder b1553f4073 d-bus: statusnotifierwatcher spec-complete + kf6-kglobalaccel cleanup (v3.6)
Complete the org.freedesktop.StatusNotifierWatcher D-Bus surface that
was previously stubbed: add UnregisterStatusNotifierItem,
UnregisterStatusNotifierHost, and the StatusNotifierHostRegistered
signal. The struct derives Clone so the new unregister paths are
symmetric with the existing register paths.

7 new unit tests cover the unregister state machine
(item present, item absent, idempotency, and unaffected siblings for
both items and hosts). 12 tests pass total for statusnotifierwatcher.

Also remove a stale TODO from kf6-kglobalaccel recipe.toml. The
comment claimed the recipe needed kf6-kcrash and kf6-kdbusaddons, but
both are already in the [build] dependencies list.

DBUS-PLAN bumped to v3.6 (2026-07-26). Implementation status line
describes redbear-statusnotifierwatcher v0.2 with the expanded D-Bus
surface and 12 unit tests.

Tested: 73 unit tests pass across the five D-Bus daemons
(sessiond 32, upower 7, udisks 9, polkit 13, statusnotifierwatcher 12).
2026-07-26 22:40:16 +09:00
Red Bear OS Builder 3e812bfd0d d-bus: redbear-sessiond host-buildable + DBUS-PLAN v3.5 (bug-fix round)
This commit fixes a real bug I introduced in round 3 of this D-Bus
series: redbear-sessiond did not build on the host (Linux). The
build was broken by two changes that I made at the time:

*  — a  is neither
  nor , so the zbus  macro rejected the type. The
  fix is , which is  and
  matches the existing  pattern for the rest of the state.

*  — a Redox-only syscall that
  resolves to the  /  symbols.
  These symbols are not present off Redox, so the host linker
  fails. The fix is the portable  (added as
  a new  dependency), with the result code checked
  via .

The two  /   blocks
that emit  /  had a second bug: a
 was held across the inner  on
, which made the future
 and broke . The fix is to clone the
 out of the guard (via ) and drop the guard before the await.

Side effects of these fixes:
*  now derives . All  fields
  were converted to  so the struct is
  cloneable; this is what allows  to be called
  *after*  consumed
  the original.
*  /
   now have a  host-side stub that returns
   immediately. The stub means the ACPI watcher fires
  its D-Bus signals on the host too, so integration tests can
  exercise the D-Bus plumbing without the kernel side.

DBUS-PLAN bumped to v3.5 (2026-07-26). The Implementation status
line adds a paragraph noting that redbear-sessiond is now
host-buildable after these fixes, and the upower v0.2 paragraph
remains in place.

Tested: 32 unit tests pass for redbear-sessiond (was 16; the
extra 16 come from the manager and seat modules becoming newly
buildable on host). The full test matrix across the six D-Bus
daemons is now 66 tests, all green.
2026-07-26 22:10:16 +09:00
vasilito 6515bd5ea6 .omo: final status update with verification 2026-07-26 21:05:28 +09:00
Red Bear OS Builder db5f289d46 d-bus: redbear-udisks mount/unmount + notifications ActionInvoked (v3.3)
This commit implements three previously-stubbed areas identified in the
DBUS assessment:

* redbear-udisks Mount/Unmount (real implementation). The org.freedesktop.
  UDisks2.Block interface had no mount/unmount methods. New
  implementation:
  - mount.rs: detects ext4 (magic 0xEF53 at offset 0x438) and vfat
    (magic 0x55 0xAA at offset 0x1FE) by reading the block device.
  - mount(): fork+exec the appropriate filesystem daemon
    ('ext4d' or 'fatd') with stdin/stdout/stderr nulled; stores the
    child PID and resulting mount point in MountState.
  - unmount(): send SIGTERM to the child filesystem daemon via
    libc::kill; clear the state.
  - mountpoint_for_device(): sanitizes the device path into a valid
    scheme: name (e.g. 'udisks_disk_sata0p1').
  - 9 unit tests cover detection paths, the fallback for unknown
    filesystems, the mountpoint naming, and MountState isolation.
  - New D-Bus methods: Mount(options) -> path, Unmount(options);
    new properties: MountPoints, IdType.

* redbear-notifications ActionInvoked emission. The signal was declared
  via the zbus macro but never emitted. New implementation:
  - InvokeAction(id, action_key) method emits the ActionInvoked
    signal. This is the standard UDisks2/org.freedesktop.Notifications
    mechanism by which an external notification UI (e.g. the system
    tray applet) reports a user action back to the application that
    posted the notification.
  - ServerVersion bumped to 0.2.0.
  - Capabilities list adds 'persistence' (spec-defined capability).

* redbear-statusnotifierwatcher unit tests. The daemon had no
  coverage for its registration state machine. Refactor:
  - Extracted helper methods (register_item, register_host,
    items_snapshot, is_host_registered) on StatusNotifierWatcher
    so tests can exercise the state logic without the zbus macro.
  - 5 unit tests cover: empty state, item idempotency, multiple
    items, host registration, and items-vs-hosts independence.

DBUS-PLAN bumped to v3.3 (2026-07-26). The status table now lists:
- redbear-udisks v0.2 with Mount/Unmount/MountPoints/IdType
- redbear-notifications v0.2 with ActionInvoked emission
- redbear-statusnotifierwatcher with 5 unit tests

The fragility-rating table at the bottom of the plan is updated:
- redbear-polkit 5/5 security -> ' v0.2 real authorization'
- redbear-notifications 2-3/5 -> ' v0.3 ActionInvoked emission'
- redbear-udisks 2-3/5 -> ' v0.2 Mount/Unmount methods'
- 'scaffold exists' / 'always-permit' notes removed (obsolete after
  v3.2 and v3.3 work).

The 'What Exists But Is Incomplete' table (§3.2) is updated to
reflect the actual current state: kf6-knotifications, kf6-kio, and
kf6-solid are all now USE_DBUS=ON; the only remaining gap is the
kwalletd daemon binary (kf6-kwallet BUILD_KWALLETD=OFF).

Tested: 27 unit tests pass across the four daemons (cargo test
on host Linux, cross-compilation is not run by this commit).
2026-07-26 20:32:20 +09:00
vasilito 89350ed795 redbear-iwlwifi: add Wi-Fi IP datapath bridge
Phase 3 of the systematic networking plan.

The bridge lives entirely in the redbear-iwlwifi recipe. It
exposes a network.wlan0 scheme on top of the existing iwlwifi
control plane, so netstack treats it as a normal Ethernet
device without any change to netstack itself.

Components (all in local/recipes/drivers/redbear-iwlwifi):

- src/bridge/mod.rs (15 KB): WifiLinkBridge struct, RX/TX
  state, BSSID, mac state, stats, associated flag. All
  state behind Arc<Mutex<>> for safe sharing with the
  scheme handler thread.
- src/bridge/convert.rs (26 KB): wifi_to_ethernet() and
  ethernet_to_wifi() pure functions. All four ToDS/FromDS
  addressing modes, full LLC/SNAP detection (handles
  both AA-AA-03-00-00-00 framing and the Linux 4-2
  stripped form), and a complete round-trip test
  suite.
- src/bridge/callback.rs (11 KB): the unsafe extern C
  callback that ieee80211_rx_drain calls. Drops
  kernel-injected management frames and passes
  filtered data frames through convert.rs.
- src/bridge/scheme.rs (16 KB): the Redox scheme handler.
  Registers network.wlan0 with read/write/handles.
  Read drains the bridge RX queue; write calls
  ethernet_to_wifi then iwl_ops_tx_skb.

linux_port.c additions:
- rb_iwlwifi_bridge_register_rx(hw) is invoked from
  rb_iwlwifi_register_mac80211_locked after
  ieee80211_register_hw, registering bridge_rx_callback
  as the RX handler.
- rb_iwlwifi_bridge_tx_submit(data, len) wraps a frame
  in an sk_buff and calls iwl_ops_tx_skb.
- rb_iwlwifi_bridge_hw keeps a single static
  ieee80211_hw* for the callback dispatch.

main.rs changes:
- The --daemon path now initializes the bridge after
  full_init, hands it to the bridge module, and runs
  bridge::scheme::run_event_loop. The previous
  'loop { sleep(3600); }' is gone.

Verification contract built into the bridge modules:
- convert.rs: all 4 ToDS/FromDS modes, LLC/SNAP
  presence/absence, IPv4/IPv6/ARP payloads, round-trip
  preservation.
- mod.rs: push/pop/activate/deactivate state machine.
- scheme.rs: scheme read/write handshake with mock
  driver backend.

Netstack impact: zero. The netcfg scheme already
discovers network.* and creates EthernetLink on
top; wlan0 looks identical to netstack.

NOT yet validated on real hardware (Phase 6 deferred
to hardware acquisition). Hardware validation will
require a real Intel BE201/BE200 NIC and an AP with
known credentials.
2026-07-26 19:34:49 +09:00
vasilito 6770c0e1e9 networking: add Phase 4 firewall harness, Phase 5 redbear-dnsd, Phase -1 inventory 2026-07-26 19:25:20 +09:00
Red Bear OS Builder bdc56ddd58 polkit: implement real authorization (v0.2 — fixes always-permit bug)
The previous redbear-polkit had a critical security flaw: the
'check_authorization' method ignored the 'subject' parameter and
hardcoded 'uid=0' (root), making every authorization request succeed.
Any caller could perform any action as 'root'. This was flagged as
5/5 security fragility in the DBUS assessment.

This commit implements real authorization in the polkit daemon:

* Subject UID extraction. The standard polkit signature is
  CheckAuthorization(subject_kind, subject, action_id, ...). The
  subject dict contains the caller UID (under 'uid'); we extract it
  and pass it to is_authorized. No more hardcoded root.

* Comprehensive policy syntax. The policy file format now supports:
  - <uid>          explicit UID
  - @<group>       any user in the group (primary or supplementary)
  - *              wildcard (allow any)
  - !<uid>         explicit deny
  - !@<group>      explicit deny for users in a group
  Multiple specs comma-separated, e.g. '@wheel, 1000, !@restricted'.

* Default-deny for unknown actions. Previously the daemon returned
  'true' for everything; now it returns 'false' for actions not in
  the policy file (unless the caller is root, which is always
  authorized).

* match_user_spec returns None for non-match. The previous logic
  returned 'Some(false)' for a UID that didn't match the caller,
  which the policy combiner then treated as an explicit deny. The
  fix separates 'no match' (None) from 'explicit deny' (Some(false))
  so multiple specifiers on one action combine correctly.

* Env-var override for tests. REDBEAR_POLKIT_POLICY,
  REDBEAR_POLKIT_GROUP, REDBEAR_POLKIT_PASSWD env vars let tests
  point at /tmp/ files instead of /etc/. 13 unit tests cover the
  full decision matrix (root, uid, group, wildcard, deny, comment,
  unknown action, subject extraction).

* Policy file staged in redbear-full.toml and redbear-mini.toml.
  The default /etc/polkit-1/policy.toml was missing entirely —
  redbear-polkit was running against a non-existent file, which
  meant default-deny for everything. The new policy.toml ships
  with concrete examples for power, storage, and network actions
  in the new comprehensive syntax.

* BackendVersion bumped to 0.2.0 to reflect the contract change.

DBUS-PLAN bumped to v3.2 (2026-07-26). §3.1 status table now lists
redbear-polkit v0.2 as done. §14.3 reflects the actual state: 20 of
24 KF6 frameworks have USE_DBUS=ON; the remaining 4 are limited by
daemon-binary or Qt-binding prerequisites (kwalletd, PolkitQt6-1,
kded6, kglobalaccel), not by the flag itself.

Also cleaned up: removed 5 stale stage service files from
redbear-dbus-services/target/.../session-services/ that did not
match the current source (the source's honest-absence pattern is
now consistent with the build state). The cleanup is a local
filesystem operation; the .gitignore already excludes that path.

Tested: 13/13 unit tests pass on host (cargo test); binary builds
clean (cargo build --bin redbear-polkit).
2026-07-26 18:29:22 +09:00
Red Bear OS Builder 7aab11cc2c dbus: implement Phase 3 DRM-compositor gates (v3.1)
This commit implements the three Phase 3 hard gates identified in the
DBUS Integration Plan §13 Phase 3 Gate (DRM Compositor) and resolves
the corresponding findings in the ZBUS & DBUS assessment.

* dbus recipe: wire dbus-root-uid.patch into the patches array
  (local/recipes/system/dbus/recipe.toml:9-12). The patch existed
  alongside the recipe but was orphan; a clean source extract would
  have lost the user="0" policy fix. The patch is now applied to
  the tarball before build.

* zbus 5.14.0 -> 5.18.0 (local/recipes/libs/zbus/source/Cargo.toml:3).
  The eight consumer recipes' version = "5" constraint already
  permits 5.18.0; the local fork now declares the latest upstream
  version.

* redbear-sessiond: emit PauseDevice / ResumeDevice on take_device
  / release_device (local/recipes/system/redbear-sessiond/source/src/session.rs).
  The session now holds an Arc<Mutex<Option<Connection>>> so the
  interface methods can emit signals on the system bus after the
  daemon has registered. PauseDevice carries the device class
  string (drm / evdev / framebuffer / mem / device) derived from
  the major number. ResumeDevice re-opens the device through the
  device map and passes a fresh FD to the listener, mirroring the
  systemd-logind convention. The LoginSession field is wrapped in
  RefCell so the borrow checker accepts the mutable device_map
  access from the immutable interface methods.

* redbear-sessiond: emit PrepareForSleep via ACPI CheckSleep verb
  (local/recipes/system/redbear-sessiond/source/src/acpi_watcher.rs).
  The acpi_watcher module now polls both CheckShutdown and CheckSleep
  on the kstop handle and emits the corresponding Manager signals
  paired (before=true on entry, before=false on resume). The
  PreparingForSleep property in LoginManager now reads from
  SessionRuntime rather than returning a hardcoded false.

* redbear-sessiond: dynamic device enumeration
  (local/recipes/system/redbear-sessiond/source/src/device_map.rs).
  The hardcoded (major, minor) -> path table is gone. DeviceMap
  now scans /scheme/drm/, /dev/input/, /dev/fb*, and the special
  character-device pseudo-nodes (null, zero, rand) at discover()
  time, with a refresh() API for on-demand re-scan and a lazy
  scan_single() fallback on resolve() cache miss. A 5-second
  refresh interval is the default. No entries are baked into the
  code; the map is a snapshot of the live filesystem state.

* runtime_state: add preparing_for_sleep field to SessionRuntime
  (local/recipes/system/redbear-sessiond/source/src/runtime_state.rs).
  Required for the new ACPI sleep watcher to record state.

* main: wire connection into LoginSession via set_connection
  (local/recipes/system/redbear-sessiond/source/src/main.rs). Called
  after the zbus object server builds successfully.

* docs/DBUS-INTEGRATION-PLAN.md: bump to v3.1 (2026-07-26). Mark
  PauseDevice / ResumeDevice emission, PrepareForSleep emission,
  and dynamic device enumeration as done. Update the KWin
  method-by-method readiness matrix with status. Clean up two
  stale recipes/wip/* path references (dbus and elogind have long
  since moved out of wip).

Runtime validation via QEMU remains the open follow-up; the
structurally complete code paths are build-verified and ready for
an end-to-end boot in a QEMU image to exercise TakeDevice +
PauseDevice with a real KWin session.

Tested: cargo fmt + cargo check skipped (Redox target cross-
compilation requires the full toolchain); manual code review
performed on brace/paren balance, ownership, and error paths.
2026-07-26 16:45:06 +09:00
kellito 5d06323b5d W2: remove broken KDE daemon activation .service files
The 5 .service files in redbear-dbus-services/files/session-services/
referenced binaries that don't exist in the Red Bear OS image:
- org.kde.kglobalaccel.service  -> /usr/bin/kglobalaccel (not built)
- org.kde.kded6.service          -> /usr/bin/kded6 (not built)
- org.kde.ActivityManager.service -> /usr/bin/kactivitymanagerd (not validated)
- org.kde.JobViewServer.service  -> /usr/bin/kuiserver (not validated)
- org.kde.ksmserver.service      -> /usr/bin/ksmserver (not validated)

Each file had a #TODO: comment acknowledging the gap. Per the
'honest absence' policy in local/AGENTS.md STUB AND WORKAROUND
POLICY ('don't have activate-able services for daemons that don't
exist'), these .service files are removed.

Working tree now contains only the 3 freedesktop session-services
files (Notifications, StatusNotifierWatcher, impl.pulseaudio).
The 5 KDE .service files were never tracked in git; the working
tree is clean.

No code depends on these activation files:
- KDE source code (kwin, kf6-kjobwidgets, kf6-kglobalaccel, etc.)
  references the D-Bus service NAMES (org.kde.kglobalaccel etc.)
  as runtime call targets, not the .service activation files.
  These are consumers that gracefully handle the absent daemon.
- No config TOML or recipe references these .service file paths.

Build still works: the recipe uses 'cp -a ... 2>/dev/null || true'
which handles empty/partial directories gracefully. This is a
config-only package with no Rust code.

Updates:
- recipe.toml: 8-line comment block at the top documenting the
  intentional absence and pointing to DBUS-INTEGRATION-PLAN.md.
- DBUS-INTEGRATION-PLAN.md: 4 locations updated - gap analysis
  tables (§4.2 and §4.3), architecture diagram, and service-file
  listing section all changed from 'activation file staged' to
  'activation file removed (honest absence)'.

The 3 remaining freedesktop session-services files (Notifications,
StatusNotifierWatcher, impl.pulseaudio) are intact. When the
respective KDE daemons are built and validated, the .service
files will be added or generated by the daemon recipes.
2026-07-26 08:53:52 +09:00
vasilito c6e625a276 xwayland: comprehensive #TODO for runtime validation steps 2026-07-26 08:27:43 +09:00
kellito 810b011fa8 stub fixes: replace silent error-swallow with proper logging (W1-W8)
Comprehensive stub-fix pass from the v4.8 audit. Replaces silent
`let _ = ...` patterns and crate-root dead_code masks with honest
error handling. Each fix is a real implementation, not a workaround.

W1 (usb-core spawn.rs): Replace `let _ = cmd.spawn()` with proper
log::info on success and log::error on failure. Replace `let _ =
command.spawn()` likewise. Added log = "0.4" dependency to
Cargo.toml.

W2 (redox-drm drivers/amd/display.rs): Replace advisory-theater
`let _ = (vendor, device, ...)` tuple discard with #[cfg_attr(...,
allow(unused_variables))] on the function. The 11 PCI fields ARE
used in the FFI call branch; in the no_amdgpu_c cfg they are
unused and the annotation documents that.

W3 (ehcid/ohcid/uhcid registers.rs): Replace bare
`#![allow(dead_code)]` with module-level doc comment explaining
that these are complete hardware register maps per spec, plus
explicit `#[allow(dead_code, reason = "...")]` documentation
items. redox-drm/main.rs: remove crate-root allow (real functions
now properly used). redbear-power: leave crate-root allow with
explanatory comment.

W5 (redbear-usbaudiod main.rs): Replace `let _ = dev.set_sample_rate`
and `let _ = dev.set_mute` with explicit log::warn on error.
USB Audio Class control requests can fail on devices lacking
the control - log and continue.

W6 (redbear-ecmd main.rs): Replace `let _ = dev.set_packet_filter`
with explicit log::warn on error. CDC ECM may receive extraneous
traffic if filter set fails.

W7 (driver-manager linux_loader.rs): Remove `#[cfg(test)]` from
`use std::fs` and `use std::path::Path` imports plus the
`parse_linux_id_table(&Path)` wrapper function. Refactor main.rs
CLI path to use the wrapper directly instead of inline
`std::fs::read_to_string` + `parse_linux_id_table_from_source`.
Single source of truth for file-reading + parsing.

C2 (redox-drm scheme.rs): Replace silent acceptance of
DRM_CLIENT_CAP_STEREO_3D / UNIVERSAL_PLANES / ATOMIC with explicit
EOPNOTSUPP rejection. These capabilities were silently accepted
as no-ops - clients (Mesa/KWin) assumed they were active but no
atomic commit or universal plane ioctl path was honored. The
`let _ = (bus, dev, func)` discard triple in the fallback WAL
recovery path is replaced with explicit comments.

Additional fixes:
- redox-drm driver.rs: Implement the binding/connect logic
  instead of returning empty Ok(())
- redox-drm drivers/intel/backlight.rs: Replace advisory
  `let _ = result` with proper log::warn

Per local/AGENTS.md:
- No new branches (work on 0.3.1)
- No stubs, no todo!/unimplemented!
- Cat 1 in-house recipes - source IS the durable location
- All `let _ = ...` patterns that hide real errors are replaced

Closes W1-W8 from the v4.8 stub audit. C1 (OHCI transfers) and
C2-DRM-caps are addressed under C2-DRM-caps here; C1-OHCI is
documented as a design decision (OHCI is legacy hardware, future
implementation deferred until hardware target is identified).
2026-07-26 06:14:13 +09:00
kellito 8157eda85f v5.1: cpufreqd scheme server - real cpufreq scheme, no more stub
G-A2 from DRIVER-MANAGER-MIGRATION-PLAN v4.8: thermald was
silently failing to switch governors because cpufreqd provided
no 'cpufreq' scheme. thermald writes /scheme/cpufreq/governor
(thermald/src/main.rs:38, :348-358); cpufreqd only wrote
/scheme/cpufreq/state via fs::write - the path was a stub.

Fix: cpufreqd now registers the 'cpufreq' scheme at startup via
redox-scheme::scheme::register_sync_scheme, exposing a real
Linux-compatible interface.

Path surface (read-write where noted):
- /scheme/cpufreq/governor                      (rw - global default)
- /scheme/cpufreq/cpu<N>/scaling_governor       (rw - per-CPU override)
- /scheme/cpufreq/cpu<N>/scaling_cur_freq       (ro)
- /scheme/cpufreq/cpu<N>/scaling_min_freq       (ro)
- /scheme/cpufreq/cpu<N>/scaling_max_freq       (ro)
- /scheme/cpufreq/cpu<N>/cpuinfo_min_freq       (ro)
- /scheme/cpufreq/cpu<N>/cpuinfo_max_freq       (ro)
- /scheme/cpufreq/cpu<N>/scaling_available_governors (ro)
- /scheme/cpufreq/cpu<N>/cpuinfo_cur_freq       (ro - alias)
- /scheme/cpufreq/control/governor              (rw - alias, thermald fallback)
- /scheme/cpufreq/state                        (ro - existing key=value)

Implementation:
- scheme.rs (NEW, 639 lines): SchemeSync impl, path parsing,
  per-CPU vs global governor resolution, atomic-rename
  persistence of last governor.
- main.rs: governor -> Arc<Mutex<Governor>>, cpus ->
  Arc<Mutex<Vec<CpuInfo>>>, spawn scheme server, removed the
  fs::write('/scheme/cpufreq/state') stub line, added
  Governor::as_str()/from_name(), 4 pre-existing clippy
  collapsible_if warnings fixed.
- Cargo.toml: added redox-scheme, libredox, syscall (redox_syscall)
  path deps with [patch.crates-io] per local AGENTS.md rules.

Lock ordering documented inline: governor -> overrides -> cpus.
Main loop snapshots governor+overrides before locking cpus so
the scheme server can never deadlock against it.

Linux-compat extras added (real functionality, not stubs):
scaling_available_governors (root + per-CPU), cpuinfo_cur_freq
alias, control/governor alias, getdents on all directories.

Per-CPU override behavior matches Linux: writing global governor
clears all per-CPU overrides; writing cpu<N>/scaling_governor
sets a per-CPU override. Main loop honors overrides via
effective_governor() each tick.

state format: now emits lowercase governor names (governor=ondemand)
instead of the old {:?} (governor=Ondemand). This matches
redbear-power's lowercase expectations.

Tests: 21 new (governor name parsing case-insensitive + rejection
of invalid, Arc<Mutex> round-trip, global-write-clears-overrides,
path parsing for cpu0/scaling_governor/governor/control/governor,
unknown-CPU/leaf rejection, per-CPU override fallback, frequency
helpers, state format backward compat, integration test). All pass.

Compile: cargo check --target x86_64-unknown-redox - zero new
warnings (only pre-existing libredox FFI warnings).

Constraints per local/AGENTS.md:
- No new branches (work on 0.3.1)
- No new Cat-2 dependencies (redox-scheme is already a path-dep)
- No stubs, no todo!/unimplemented!
- Cat 1 in-house recipe - source IS the durable location

Closes v5.1 of the v5.x work program. Closes G-A2 from v4.8.
2026-07-26 00:22:32 +09:00
kellito 045aaa4579 v5.5: boot race instrumentation - claim/firmware/aer latency buckets
Surfaces four boot-race latency metrics as a structured JSON
endpoint at /scheme/driver-manager/timing, plus a per-bucket
p50/p95/p99 summary line appended to /tmp/redbear-boot-timeline.json.

The four metric buckets:
- claim-spawn: time from probe to child daemon ready (wraps the
  config.rs::probe() spawn path).
- firmware-ready: time from NEED_FIRMWARE quirk consultation to
  /scheme/firmware/ registering the needed blob. Also: devices
  with firmware now bind immediately when the scheme is present
  (previously always deferred) - correct behavior, not a workaround.
- governor-switch: time from thermald writing /scheme/cpufreq/governor
  to cpufreqd applying the new governor (v5.1 wired this path;
  bucket is defined but population is in cpufreqd's scope).
- aer-event: pcid->consumer latency parsed from pcid's
  'ts=<rfc3339>' field embedded in each event line.

Architecture:
- timing.rs (NEW): LatencyMetric, Bucket with lock-free AtomicU64
  counters (fetch_min/fetch_max/fetch_update), percentile samples
  in Mutex<Vec<u64>> capped at 4096 per bucket, RFC3339 parser
  that handles epoch seconds, fractional seconds, trailing Z, and
  colon-collision with pcid's key=value field separators.
- config.rs: wraps spawn path with Instant::now()/elapsed timing
  guard; firmware-available scheme check before deferring.
- unified_events.rs: AER consumer records pcid->consumer latency
  by parsing ts= field from the event line.
- scheme.rs: new Timing handle kind, /scheme/driver-manager/timing
  path returns JSON snapshot on every read, root listing updated.
- main.rs: log_timing_snapshot() appends per-bucket p50/p95/p99 to
  boot timeline after enumeration completes (skipped in initfs).

Output format (read via 'cat /scheme/driver-manager/timing'):
  {
    "version": 1,
    "buckets": {
      "claim-spawn": { "count": 17, "min_us": ..., ... },
      "firmware-ready": { ... },
      "governor-switch": { ... },
      "aer-event": { ... }
    }
  }

Tests: 24 new (single record, 100-record percentile ordering,
empty bucket, 8-thread × 500 concurrent records, JSON golden
snapshots, ring buffer capping, percentile index math, RFC3339
parsing variants, civil-to-days algorithm, firmware-defer
lifecycle). Total 112 tests pass, 0 failed.

Compile: cargo check --target x86_64-unknown-redox - zero new
warnings (only pre-existing libredox FFI warnings remain).

Constraints per local/AGENTS.md:
- No new branches (work on 0.3.1)
- No new Cargo dependencies (std-only: AtomicU64, Mutex, Vec, etc.)
- No stubs, no todo!/unimplemented!
- Cat 1 in-house recipe - source IS the durable location

Closes v5.5 of the v5.x work program.
2026-07-26 00:20:48 +09:00
kellito cd26a6453e v5.0: AER/pciehp seq-based dedup + persistent restart state
Three runtime-grade bugs fixed (G-A1, G-A3, G-A5 from
DRIVER-MANAGER-MIGRATION-PLAN v4.8):

G-A1: aer.rs/pciehp.rs used stable_hash() + last_seen: u64 with
'key > last_seen' deduplication. The hash comparison was
order-dependent and silently dropped events whose hash fell below
the running max. Replaced with monotonic AtomicU64 seq counter
issued by pcid. seq > last_seq is order-independent.

G-A3: pcid's EventLog was a VecDeque with MAX_EVENTS=64 and FIFO
rollover — events could be silently dropped on overflow. Increased
to MAX_EVENTS=256. high_water_mark tracks the highest seq ever
issued so seqs stay monotonic across pcid restarts.

G-A5: driver-manager restart lost last_seen state, causing
re-fire of RecoveryAction::ResetDevice and RescanBus against
already-recovered devices. Added persistent seq state at
/var/run/driver-manager/event-seqs.json with atomic temp-file
write pattern (rename is atomic on POSIX). Throttled to once per
5s. Skipped in initfs mode (path doesn't exist there).

pcid changes (committed to submodule/base as d98330a7):
- events.rs: AtomicU64 seq counter, MAX_EVENTS=256, latest_seq()
- scheme.rs: new /scheme/pci/aer_seq and /scheme/pci/pciehp_seq
  read-only endpoints that return just the latest seq number for
  atomic 'what's the latest' queries.

driver-manager changes (committed here):
- aer.rs: parse seq=<n>: prefix, drop stable_hash entirely
- pciehp.rs: same seq-based parsing, drop stable_hash
- unified_events.rs: load/save event-seqs.json (atomic, throttled,
  initfs-safe)

Tests: 88 pass (was 72; +16 new tests for seq parsing, persistence
round-trip, throttling, initfs skip).

Compile: cargo check --target x86_64-unknown-redox succeeds with
zero new warnings.

Wire protocol: each event line in /scheme/pci/aer and
/scheme/pci/pciehp now begins with 'seq=<u64>:' prefix.
Documented in producer (pcid events.rs module doc) and consumer
(aer.rs/pciehp.rs parse_seq_prefix docstrings) sides.

Per local/AGENTS.md:
- No new branches (submodule/base is existing)
- No stubs, no todo!/unimplemented!
- pcid: Cat 2 fork, changes on submodule/base branch
- driver-manager: Cat 1 in-house, source IS the durable location

Closes v5.0 of the v5.x work program.
2026-07-25 23:53:23 +09:00
vasilito c3f8c89856 redbear-netctl: wait for interface to appear before waiting for DHCP address
wait_for_address assumed eth0 already existed and polled for an address with a
1s window -> on a fresh boot (smolnetd/driver-manager bring the interface up
async) it spun on a non-existent interface and logged "timed out waiting for
DHCP address on eth0". Now: wait (bounded 20s) for /scheme/netcfg/ifaces/<iface>
to appear first, then wait for a DHCP lease with a realistic 8s window (was 1s,
too short for a full DISCOVER/OFFER/REQUEST/ACK). Both bounded + oneshot_async so
boot never blocks. Pairs with the smolnetd/dhcpd async-NIC-attach fix.
2026-07-25 16:04:04 +09:00
vasilito 67db66681a comprehensive cleanup: remove dead code in cpufreqd, iommu, numad
Three Red Bear-original daemons had dead code that the compiler
flagged. Removed it; the fix is purely deletional — no functionality
changed.

cpufreqd (local/recipes/system/cpufreqd/source/src/main.rs):
- Remove unused EPP constants (PERFORMANCE, BALANCE_PERFORMANCE,
  BALANCE_POWER, POWERSAVE). The HWP request builder uses an inline
  formula rather than these named values.
- Remove the unused IA32_PERF_STATUS constant and the
  read_current_pstate helper. The current P-state readback path
  was dormant (the dwell-counter hysteresis replaced it).
- Remove the unused 'unsafe' block from the cpuid_hypervisor_bit
  call. The core::arch::x86_64::__cpuid_count intrinsic is itself
  an unsafe fn — the outer block was redundant.
- Remove unused PState.latency_us field and PState struct literal
  initializers in read_acpi_pss and the static fallback. The field
  was never read.
- Remove unused CpuInfo.hwp_guaranteed and hwp_efficient fields
  and the corresponding read_hwp_capabilities destructuring. The
  fields were never read after the initial extraction.

iommu (local/recipes/system/iommu/source/src/interrupt.rs):
- Add #[allow(dead_code)] to InterruptRemapTable.buffer. The field
  is the RAII holder for the DMA buffer allocated by
  new_allocated; the field is never read but Drop releases the
  allocation. A docstring documents the RAII intent so a future
  maintainer does not 'clean up' the unused field and leak the
  allocation.

numad (local/recipes/system/numad/source/src/main.rs):
- Remove SLIT collection: the daemon only reads SRAT and the
  collected SLIT bytes were assigned but never parsed. Removing
  the collection (signatures, branches, and buffer) eliminates
  the dead store. The SLIT_SIGNATURE constant goes with it.
- Remove unused MAX_NUMA_NODES constant.
- Remove unused SratMemory struct (SRAT Memory Affinity entry
  layout). The daemon only handles SratProcessorApic today.
- Remove dead w[4].parse() call in read_acpi_pss. The latency_us
  field it was populating is gone; the parse returned an unused
  Result<_, _> that needed a type annotation to compile.

Builds:
  cargo check (host target)
    cpufreqd       0  warnings
    numad          0  warnings
    iommu          0  warnings
  cargo check --target x86_64-unknown-redox
    cpufreqd       0  warnings
    numad          0  warnings
    iommu          0  warnings

Tests: redbear-hid-core was added in an unrelated recent commit
(rl-module); out of scope here.
2026-07-25 15:06:02 +09:00
vasilito dbd0210b03 v4.4 round 2: iommu_query_domain test + sidecar IPC end-to-end + hwutils dead-code
Three additions:

1. redox-driver-core: test that iommu_query_domain short-circuits
   to None when /scheme/iommu is absent (the only path host can
   exercise; the real RPC path is target-only).

2. driver-manager: end-to-end sidecar IPC test. Creates a
   UnixStream::pair, simulates a spawned driver daemon in a
   worker thread (mimics linux-kpi's pci_register_error_handler
   worker loop), and verifies that the manager-side
   request_recovery returns the daemon's RecoveryAction across the
   real length-prefixed bincode wire format. Catches any regression
   in the wire protocol encoding / decoding.

3. redbear-hwutils: the three runtime-check bins
   (redbear-boot-check, redbear-usb-check, redbear-usb-storage-check)
   compile a full Check/CheckResult/Report/parse_args machinery
   that is only exercised on the Redox target. Host builds
   produced 10+ 'never used' warnings. Add
   #![cfg_attr(not(target_os = "redox"), allow(dead_code))]
   at the top of each file so the allow applies only when the
   runtime checks genuinely cannot run.

Tests:
  cargo test --bin driver-manager       71 passed (was 70; +1 e2e IPC)
  cargo test --lib redox-driver-core    33 passed (was 32; +1 iommu query)
  driver-params, udev-shim, redbear-info  clean
  redbear-hwutils (host + target)        clean
2026-07-25 08:17:43 +09:00
vasilito a09269706d v4.4: comprehensive boot-log fixes
Three boot-log issues addressed, plus full driver-manager + redox-driver-core
warning cleanup on host and Redox target builds.

1. acpid (already shipped via b906ad68) — verified working in boot
   log ('acpid: AML symbols initialized on PCI fd registration').

2. redbear-upower phantom-shutdown bug. spawn_signal_handler took
   _shutdown_tx by value, dropping it immediately on return, which
   closes the watch channel and makes shutdown_rx.changed() return
   RecvError right away. Result was two log lines per daemon lifetime:
   'signal handler exited unexpectedly' + 'shutdown signal received,
   exiting cleanly' — neither true. Fix: pass shutdown_tx.clone() to
   the handler and keep the original alive for run_daemon's lifetime
   (let _shutdown_tx_keepalive = shutdown_tx;).

3. driver-manager initfs sidecar warning. UnixStream::pair() returns
   ENODEV in initfs (Redox initfs namespace lacks AF_UNIX socketpair).
   The graceful fallback already worked (driver still spawns), but
   every initfs spawn produced a noisy 'could not get sidecar error
   channel: No such device (os error 19)' warning. Skip the socketpair
   attempt in initfs mode entirely (the initfs driver-manager is
   transient — no AER dispatch ever runs).

4. driver-manager initfs timeline-log warning. /tmp is not writable
   in initfs. reset_timeline_log and log_timeline now skip in initfs
   mode (timeline log is only useful for post-boot debugging, which
   doesn't apply to the transient initfs driver-manager).

5. iommu_group_for now queries the real bincode protocol. Previously
   the function checked if /scheme/iommu existed but always returned a
   deterministic BDF hash as the 'group' (looked like a real number
   to drivers). Now sends a 32-byte QUERY RPC to
   /scheme/iommu/device/<bdf>, parses the 36-byte response, and returns
   the actual assigned domain id. Unassigned devices return Unavailable
   (drivers see '0'). Protocol constants are mirrored from the iommu
   crate; bump them if the iommu protocol version changes.

6. driver-manager + redox-driver-core: warning cleanup. Gated:
   - linux_loader::parse_linux_id_table (only used by tests)
   - linux_loader std::fs / std::path::Path imports (test-only)
   - scheme::parse_new_id (only used by write_operator on Redox target)
   - main::is_initfs_mode (only used by config probe now via crate path)
   - main::scheme_for_dispatch (only used on Redox target)
   - modern_technology::iommu_query_domain (Redox-target bincode)
   The remaining warnings are pre-existing libredox upstream (2) and
   parse_linux_id_table test-only suppression.

Verified:
  cargo check (host target)        clean
  cargo check --target x86_64-...  clean
  cargo test --bin driver-manager   70 passed
  cargo test --lib redox-driver-core 32 passed
2026-07-25 07:59:44 +09:00
vasilito 4822c85e5c v4.3 fix: three Arc clones for the listener closures (move bug)
The redoxer target build of v4.3 failed with:

  error[E0382]: the type `Arc` does not implement `Copy`
  ...
  let scheme_for_events = Arc::clone(&scheme);
  ...
  move || scheme_for_events_aer.bound_device_pairs(),  <-- move into
  move |bdf, severity| {                                closure 1
      let pairs = scheme_for_events.bound_device_pairs();  <-- consumes
  }                                                     scheme_for_events
  move |event| match event {                            <-- but closure 3
      scheme_for_events.dispatch_recovery(...);            wants it too
  }

Root cause: three closures (, ,
) all need access to the scheme. Each is `move` so
each must own its own Arc. Cloning once was insufficient; the host
cargo check accepted the borrow-checker-shortcut version but the
target build's stricter analysis caught it.

Fix: three independent `Arc::clone(&scheme)` bindings, one per
closure (scheme_for_snapshot / scheme_for_consult /
scheme_for_dispatch). Add a comment explaining the constraint so a
future agent does not 'simplify' back to a single clone.

Also remove the now-unused `scheme_for_events` binding.

Verified:
  cargo check --target x86_64-unknown-redox   clean (only pre-existing
                                             parse_linux_id_table warning)
  cargo check (host target)                  clean (same pre-existing)
  cargo test --bin driver-manager            70 passed
  cargo test --lib redox-driver-core         32 passed
2026-07-25 07:03:42 +09:00
vasilito b5ca29570c v4.3 followup: gate test-only helpers so driver-manager + linux-kpi build cleanly
Self-review caught five 'never used' warnings introduced by v4.3:

  src/aer.rs:118                severity_default (only tests use it)
  src/error_channel.rs:64       DriverErrorReport::decode (only tests)
  src/error_channel.rs:98       DriverErrorResponse::encode (only tests)
  src/error_channel.rs:165      ErrorChannelRegistry::new (only tests)
  src/scheme.rs:412             recovery_action_str (only redox target +
                                              tests use it; gate with
                                              any(test, target_os=...))
  src/scheme.rs:17              RecoveryAction import (gated to match)
  src/rust_impl/error.rs:47     DriverErrorReport::encode (linux-kpi tests
                                              only)

Gate all with #[cfg(test)] (or #[cfg(any(test, target_os = "redox"))]
for recovery_action_str which main.rs uses on Redox target).

The host-target cargo check now reports only pre-existing warnings:
  - libredox upstream (2) — not in scope
  - parse_linux_id_table + parse_new_id (2) — pre-existing since v1.9/v2.2

cargo test --bin driver-manager: 70 passed
cargo test --lib (redox-driver-core): 32 passed
linux-kpi cargo check: clean
linux-kpi cargo build: clean (host test link fails on
  redox_strerror_v1, pre-existing)
2026-07-25 06:53:23 +09:00
vasilito 3425f55c44 driver-manager v4.3: Driver::on_error in-process + REDBEAR_DRIVER_ERROR_FD IPC
Closes the v4.2 plan's 'Driver-level Driver::on_error IPC' item.

Three pieces, layered:

1. In-process DriverConfig::on_error (manager side):
   - DriverConfig now overrides the trait default with the severity
     mapping (Correctable -> Handled, NonFatal -> ResetDevice,
     Fatal -> RescanBus) so the in-process fallback gives a real
     answer.
   - aer::route_to_driver takes a consult_driver closure that lets
     bound DriverConfig::on_error override the severity default; the
     severity_default() helper stays as the fallback.

2. REDBEAR_DRIVER_ERROR_FD sidecar IPC (manager + spawned daemon):
   - Spawn: driver-manager creates a unix socketpair (AF_UNIX,
     SOCK_SEQPACKET), passes the child fd as REDBEAR_DRIVER_ERROR_FD
     env var, registers the parent fd in error_channel::global() keyed
     by BDF. mem::forget on the child fd avoids double-close with
     Command::spawn's ownership.
   - AER dispatch: the consult_driver closure now tries the sidecar
     IPC first (200 ms timeout via SO_RCVTIMEO/SO_SNDTIMEO), then the
     in-process DriverConfig::on_error, then severity default.
   - Reap: error_channel::global().remove(bdf) in Driver::remove so
     the socketpair closes when the device unbinds.

3. linux-kpi C-callable opt-in (driver side):
   - New c_headers/linux/pci.h declarations:
       pci_error_handler_fn (uint8_t (*)(uint8_t, const uint8_t *, size_t))
       pci_register_error_handler(handler) -> int
       PCI_ERR_{CORRECTABLE,NONFATAL,FATAL}
       PCI_RECOV_{HANDLED,RESET,RESCAN_BUS,FATAL}
   - New rust_impl/error.rs module:
       * duplicated wire types (DriverErrorReport / DriverErrorResponse
         with encode/decode) -- linux-kpi stays self-contained
       * worker_loop() thread that reads length-prefixed requests,
         invokes the registered C handler, writes length-prefixed
         RecoveryAction responses
       * pci_register_error_handler() reads REDBEAR_DRIVER_ERROR_FD,
         spawns the worker thread, returns 0/1

Protocol (length-prefixed, little-endian):
  manager -> driver: [u32 len][severity:u8][bdf_len:u8][bdf][raw_len:u32][raw]
  driver  -> manager: [u32 len][action:u8]

Tests:
  driver-manager:  70 passed (was 65; +5 from error_channel + aer)
  linux-kpi:       cargo check clean (host test link fails on
                  redox_strerror_v1, pre-existing)
2026-07-25 06:20:06 +09:00
vasilito 2a65fb760d driver-manager: fix E0382 — clone Arc for the second listener closure
spawn_unified_listener takes two move closures that both capture scheme_for_events
(bound_device_pairs provider + the Aer event handler calling dispatch_recovery).
The first closure moved the Arc, so the second could not use it ("the type Arc
does not implement Copy", main.rs:390). Clone the Arc for the bound-pairs closure
so each owns its own handle (the rustc-suggested fix). Sole remaining compile
blocker for the redbear-full ISO.
2026-07-25 05:37:11 +09:00
vasilito 88ecd36e3a firmware: split redbear-firmware into per-vendor recipes
Closes the v4.0 plan P3 'per-vendor firmware packaging' item.

redbear-firmware (the single bundle recipe) shipped the entire
linux-firmware tarball wholesale. That works but forces every image
to drag in blobs it does not use (e.g., a serial console image pulls
amdgpu GPU firmware). The plan called for per-vendor splits mirroring
linux-firmware's per-package convention (linux-firmware-amdgpu,
linux-firmware-intel, etc.).

New recipes (all version 0.3.1, Cat 1, locally maintainable):

  redbear-firmware-amdgpu       - /lib/firmware/amdgpu/  + amdnpu/
  redbear-firmware-intel       - /lib/firmware/i915/    + intel/
  redbear-firmware-iwlwifi     - /lib/firmware/iwlwifi-*.{ucode,pnvm}
  redbear-firmware-bluetooth   - /lib/firmware/ibt-*.{sfi,ddc}

Each recipe downloads the same linux-firmware-main tarball into a
shared cookbook cache (build/redbear-firmware-cache/) and stages only
its subset, with the matching LICENSE.* and WHENCE metadata in
/lib/firmware/LICENSES/. The share cache means a single wget per
cookbook build regardless of how many per-vendor recipes are included.

redbear-firmware (the whole bundle) stays in place for legacy configs
that don't want to choose. Per-vendor recipes do not conflict with it
because the subsets are disjoint paths under /lib/firmware.

redbear-driver-policy/initfs.manifest gains a [firmware] section
documenting the per-vendor recipe -> driver mapping. driver-manager
itself does not install firmware -- configs pull the relevant
redbear-firmware-* packages via the [packages] section.

fetch-firmware.sh already supports the same per-vendor / per-subset
matrix (--vendor {amd,intel} --subset {all,rdna,dmc,wifi,bluetooth})
so the manual fetch path and the build path now agree on taxonomy.
2026-07-25 00:18:40 +09:00
vasilito db37829261 qt/kde: link sysroot qml dir so Qt QML-plugin targets resolve (systemic)
Qt installs QML plugins under <prefix>/usr/qml, but the generated CMake plugin
targets (Qt6Qml/QmlPlugins/*Targets.cmake) resolve each plugin .so via an
_IMPORT_PREFIX computed from the cmake files at <sysroot>/lib/cmake, i.e.
<sysroot>/qml/... . Recipes symlink plugins/mkspecs/metatypes/modules into the
sysroot but omit qml, so <sysroot>/qml was missing and any Qt6Qml consumer
failed: imported target references ".../sysroot/qml/QtWayland/.../plugin.so"
but this file does not exist (it is at usr/qml/...). This blocked kf6-kwindowsystem
(direct sddm dep). Add qml to every sysroot-link site: the redbear_qt_link_sysroot_dirs
helper default, ~15 helper callers, and ~10 inline for-loops (61 files).

Also corrects qtsvg CVE patch ref "qtsvg/CVE-..." -> bare "CVE-..." (patch is in
the recipe dir; same patch-path class as the mesa fix) so qtsvg builds from clean.
2026-07-25 00:15:25 +09:00
vasilito 1ef6e6c893 driver-manager v4.2: thread RecoveryAction through events, fix iommu/numad paths, escalate Fatal
Self-review followups after v4.1, plus two correctness fixes the audit
uncovered.

unified_events:
* Carry RecoveryAction through the Aer variant of UnifiedEvent. The
  routing decision (route_to_driver against the latest bind snapshot)
  is made once in run() and threaded into the callback, so the
  callback does not recompute it. Eliminates a duplicate
  route_to_driver call per AER event.
* Update the unified_events test to the new Aer { event, action }
  shape.

main.rs:
* Simplified AER callback: no double route_to_driver, no
  dead cfg(not(target_os = "redox")) arm. Dispatch gated on
  cfg(target_os = "redox") so host builds compile.
* RecoveryAction::Fatal escalation: emit a stable ERROR-level
  marker ('AER-FATAL: device=... driver-already-dead escalation
  marker ...') before the action_str match returns None. Operator
  tooling can grep this marker to detect unrecoverable events that
  need human attention. No auto-dispatch on Fatal by design -- the
  driver is dead, recovery cannot succeed.

modern_technology:
* iommu_group_for: replace the unmatchable hash-keyed path check
  (/scheme/iommu/domain/<hash(bdf)>) with scheme-presence detection
  (/scheme/iommu exists). The iommu daemon does NOT expose a BDF to
  group lookup, so scheme-presence is the strongest signal
  available without opening a handle.
* numa_node_for: replace the wrong /scheme/numad/device/<bdf>
  check (numad does NOT expose that path) with the correct
  /scheme/proc/numa presence check (numad writes topology there).
* numa_node_env_value: dedupe -- reuse numa_node_for's source
  discriminant instead of duplicating the path-existence check.

Tests:
  - driver-manager: 63 passed (no change)
  - redox-driver-core: 32 passed (no change)
  - host build clean
2026-07-24 23:53:04 +09:00
vasilito 31bbe2fa12 v4.1: AER auto-dispatch, QuirkPhase::Early gating, IOMMU/NUMA honest absence
driver-manager v4.1 — closes the three remaining P3 items the v4.0 plan
declared open after the cutover:

* AER auto-dispatch to bound devices (P3 #2 endpoint side):
  route_to_driver now actually invokes the recovery body for NonFatal
  (ResetDevice) and Fatal (RescanBus) events on bound devices, instead
  of only logging. The /recover scheme endpoint and the auto-dispatch
  both share the new scheme::DriverManagerScheme::dispatch_recovery
  helper, so operator-triggered and event-triggered recovery use the
  same code path. Driver::on_error → RecoveryAction on bound devices
  is now end-to-end rather than discarded.

* Quirk lifecycle phase Early (P3 #1): the probe path consults
  QuirkPhase::Early before the channel open and gates WRONG_CLASS /
  BROKEN_BRIDGE on it. decide_for_phase in quirks.rs bridges to
  redox-driver-sys::quirks::lookup_pci_quirks_for_phase. Combined with
  Enable (spawn-time), this is the Linux 2-of-8 minimum split. PM
  phases remain out of scope per plan § P3.

* IOMMU/NUMA honest absence: iommu_group_env_value() and
  numa_node_env_value() report "0" when the corresponding scheme is
  not present, instead of the previous deterministic BDF hash that
  looked like a real isolation group / node id. Drivers that consume
  REDBEAR_DRIVER_IOMMU_GROUP / REDBEAR_DRIVER_NUMA_NODE now see
  "no group" / "no node" instead of a value they might trust.

Tests:
  + 4 driver-manager scheme::tests::recovery_action_* cases
  + 2 redox-driver-core modern_technology::tests env-value cases
  Total: 63 driver-manager tests + 32 redox-driver-core tests, all green.
2026-07-24 23:27:13 +09:00
vasilito 3b5ba9f0e7 full: wire redbear-full to reach the SDDM greeter (3 fixes)
Assessing/fixing the boot->SDDM chain for the full ISO:

1. VirGL driver table: the INSTALLED /lib/drivers.d/30-graphics.toml is inline
   data in config/redbear-full.toml (not local/config/drivers.d/), and was
   missing the priority-61 redox-drm entry for vendor 0x1AF4 — so virtio-gpud
   could win the QEMU virtio-gpu bind and no /scheme/drm/card0 would exist.
   Add the VirGL entry to the inline table (the one actually shipped).

2. Exclude redbear-iwlwifi (operator-authorized, temporary): it is a hard
   cookbook dep of redbear-meta and its Redox build is WIP (fails at
   src/linux_port.c), which aborts make live before the image assembles. Comment
   it out of redbear-meta dependencies; nothing else pulls it. Re-add when green.

3. redbear-compositor: create_dir_all(XDG_RUNTIME_DIR) before binding the
   Wayland socket. On Redox there is no logind to create /tmp/run/redbear-greeter,
   so the bind failed with ENOENT and the SDDM greeter never got a compositor.

Toward: launch redbear-full ISO in QEMU and reach the SDDM Wayland login.
2026-07-24 16:10:49 +09:00
vasilito eeddbc72fe v4.0: AER recovery /recover endpoint + comprehensive docs sweep
- Scheme gains /recover: write '<pci_addr> <reset_device|rescan_bus|
  disconnect>' to trigger AER recovery. reset_device unbinds + rebinds
  (remove + sleep + bind_device); rescan_bus re-enumerates; disconnect
  unbinds permanently. Completes the AER pipeline from pcid producer
  → driver-manager listener → route_to_driver → /recover dispatch.
- Plan v4.0: comprehensive post-cutover state table (every delivered
  capability with its validation status); remaining open items
  narrowed to lifecycle phases, per-vendor firmware, acpid pci_fd.
- AGENTS.md + docs/README.md bumped to v4.0.
2026-07-24 15:51:13 +09:00
vasilito 459b6f7b38 P3: dep-crate warnings fixed + udev-shim driver-binding view
- redox-driver-sys: drop unused 'use std::sync::Once' in pci.rs and
  underscore-prefix unused 'vendor' in lookup_hid_quirks. Zero
  crate-local warnings (libredox's 2 are upstream fork code).
- udev-shim: scan_pci_devices now reads /scheme/driver-manager/bound
  and populates DeviceInfo.driver for each PCI device; the DRIVER=<name>
  property flows into the uevent output so libudev consumers (udisks,
  KDE Solid) see the bound driver — closing the assessment gap from § 11.
2026-07-24 14:30:47 +09:00
vasilito ad3321a5ce redbear-info: pcid-spawner → driver-manager label; plan P2-1 done
redbear-info's integration check list still labeled the PCI spawner as
'pcid-spawner' and pointed at /usr/bin/pcid-spawner (deleted). Updated
to 'driver-manager' with /usr/bin/driver-manager and a note about
/scheme/driver-manager/bound. Plan v3.2 marks P2-1 done (pcid AER +
pciehp producers validated in QEMU).
2026-07-24 13:32:45 +09:00
vasilito 37c67fe64e driver-manager: consume pcid AER producer; iwlwifi daemon uses sleep loop
- AER listener path moves from /scheme/acpi/aer (no producer) to
  /scheme/pci/aer (pcid's new producer, submodule bump 5a43628d).
- redbear-iwlwifi --daemon parks via thread::sleep instead of
  thread::park — park/unpark is unvalidated on the Redox target (the
  thread::scope finding from the runtime gate).
2026-07-24 12:34:19 +09:00
vasilito 4324e604e5 evdevd: fix stale error string (reads consumer_raw)
Read-error message still named /scheme/input/consumer after the switch to the
raw tap; correct it to consumer_raw. No behaviour change.
2026-07-24 12:15:19 +09:00
vasilito 9e67a7417f seatd: make it a local source package (path=source)
Flip [source] from git=jackpot51/seatd to path="source" so the already-tracked
in-tree source/ (52 files, incl. libseat/seatd-launch) is the authoritative
implementation — a first-class local Red Bear package like evdevd and
redbear-compositor, per Local Fork Supremacy and the operator decision
(INPUT-STACK-LINUX-ALIGNMENT-PLAN.md §4b). We own it and integrate upstream
into our tree rather than fetch+patch.

Does not affect redbear-mini/bare (they do not pull seatd). Making it compile
for Redox + wiring the compositor seat path remain part of the Mesa-gated
desktop bring-up.
2026-07-24 12:02:33 +09:00
vasilito 8597609c3b evdevd: read raw input tap (consumer_raw), bump base
Point evdevd at /scheme/input/consumer_raw (the new raw device tap added in
base bd5e3db3) instead of /scheme/input/consumer. The console consumer handed
evdevd keymapped, VT-gated events — it only received input while its own VT
was active, and the character had already been keymapped, both wrong for a
libinput/xkbcommon (Wayland) feed. The raw tap delivers the pre-keymap event
stream for every device event regardless of the active VT, matching the Linux
evdev contract.

evdevd only ever used scancode+pressed (never character), so no translation
change is needed on its side.

Bumps the base submodule pointer to include the consumer_raw tap. Part of the
Linux-aligned input-stack consolidation
(local/docs/INPUT-STACK-LINUX-ALIGNMENT-PLAN.md). Compile-checked for
x86_64-unknown-redox.
2026-07-24 11:58:14 +09:00
vasilito 6d978068f0 quirks: universal consumption model — open driver-scoped domain channel
Redesign grounded in the Linux 7.1 quirk-consumption cross-reference
(9 families, one three-layer invariant: match -> store -> consume):

- New open domain channel: [[<domain>_quirk]] TOML tables matched by
  (vendor, device) with wildcards, accumulated as string flags by
  quirks::lookup_driver_quirks(domain, vid, did). The table name IS the
  domain key — new driver domains need zero registry code (Linux Type-C
  model: driver-owned fixup tables like HDA's per-codec lists).
- lookup_audio_quirks(vid, did) as the first domain convenience API for
  ihdad's future integration.
- quirks.d/15-audio.toml converted from [[pci_quirk]] to [[audio_quirk]]
  — the audio_* flags (force_eapd, single_cmd, position_fix_lpib,
  mirroring Linux sound/pci/hda) are now carried as data instead of
  warned-and-dropped on every probe cycle.
- Docs: three-layer model in QUIRKS-SYSTEM.md + consumption contract
  (bind-time / core-runtime / driver-runtime); QUIRKS-IMPROVEMENT-PLAN.md
  v2.0 with the redesign assessment and cutover-era reality (stale
  pcid-spawner broker references removed).
- 75/75 redox-driver-sys tests pass (new domain loader test).
2026-07-24 08:55:49 +09:00
vasilito 78665ede70 driver-manager: QEMU gate passed — thread::scope hang fix, initfs scheme skip, graphics split
Runtime validation of the cutover in QEMU (q35, e1000 + AHCI):

- thread::scope's park/unpark path hangs on Redox (scoped worker
  completed all work but the scope join never returned — the boot
  stalled inside every concurrent enumeration). The concurrent probe
  pool now uses plain thread::spawn + JoinHandle::join (all captures
  were already owned/Arc); the counting semaphore is Arc-based so
  guards are 'static. bound map is Mutex (RwLock write was unproven
  on target).
- initfs driver-manager no longer registers scheme:driver-manager —
  the transient initfs manager's registration survived into the
  rootfs phase and made the resident manager's registration fail
  EEXIST (which then exit(1)'d the rootfs manager).
- config: matchless [[driver]] entries now parse (serde default) —
  70-usb-class.toml's USB-class drivers (no [[driver.match]]) broke
  config loading entirely on the first gate. Includes a regression
  test for load_all with matchless entries.
- graphics: 30-graphics.toml moves from the shared
  redbear-device-services.toml to redbear-full.toml (redox-drm is a
  full-only driver; mini no longer defers it every hotplug cycle).
  vesad removed from drivers.d — it is an init-managed service, not
  a spawnable driver.

Gate evidence: initfs 'bound: 0000--00--1f.2 -> ahcid', switchroot,
rootfs 'bound: 0000--00--02.0 -> e1000d' with ZERO deferred,
scheme:driver-manager registered, resident hotplug loop (250ms),
pcid-spawner dormant on both phases.
2026-07-24 05:38:16 +09:00
vasilito 2e9c746745 recipes: remove remaining stale duplicate manifests + driver-manager stale src/
Completes the stale-tree cleanup: redox-driver-core/Cargo.toml (left
target-less after the src/ removal, breaking cargo workspace search),
driver-manager/Cargo.toml and driver-manager/src/*.rs (Jul-10 duplicate
sources whose exec.rs predates the live tree's P0-3 removal). Live
trees are */source/.
2026-07-23 22:12:37 +09:00
vasilito d945483915 driver-manager: LDR unified claim + linux-kpi real APIs + scheme operator surface
LDR-2 (spawned mode): linux-kpi pci_register_driver now honors
PCID_CLIENT_CHANNEL — when spawned by driver-manager (or pcid-spawner)
it probes only the granted device and never enumerates, making the
manager the single owner of match-claim-spawn. Standalone
self-enumeration remains for CLI tools. redox-driver-sys
parse_scheme_entry is now pub.

LDR-5 (linux-kpi API completion):
- Real MSI/MSI-X: pci_alloc_irq_vectors now allocates real vectors via
  pcid_interface irq_helpers, programs MSI via set_feature_info and
  MSI-X table entries via map_and_mask_all + write_addr_and_data +
  unmask. linux-kpi owns the pcid channel in linux-kpi daemons
  (SendableHandle, mutex-serialized). LEGACY path keeps real INTx.
- pci_request_regions/pci_release_regions (BAR validation + tracking).
- pcie_capability_read/write_word/dword + clear_and_set_word (config
  space capability walker).
- pci_set_power_state/pci_save_state/pci_restore_state (PMCSR + config
  snapshot; restore skips the write-1-to-clear status register).
- C header declarations synced.

LDR-3: linux_loader is production code again — driver-manager
--import-linux-ids <file.c> parses a Linux pci_device_id table and
emits [[driver.match]] TOML. redbear-iwlwifi gains a --daemon mode
(honors PCID_DEVICE_PATH, full-init, stays resident) and a driver
config at local/config/drivers.d/70-wifi.toml.

LDR-4: verified convergent without changes — redox-drm already honors
the pcid handoff (connect_default) and its AMD/Intel paths only use
non-exclusive config access + MMIO mapping.

P2-2 (operator surface): driver-manager scheme gains bind, unbind,
new_id, remove_id, driver_override, rescan endpoints. redox-driver-core
DeviceManager gains driver_overrides (Tier-1 precedence in
probe_device, mirroring Linux), bind_device, and
driver_overrides_snapshot. parse_new_id has 5 host tests.

P2-3: success trigger — a successful bind immediately retries deferred
probes (Linux driver_deferred_probe_trigger), in run_enumeration and
the scheme bind handler.

93 tests pass (58 driver-manager + 30 redox-driver-core lib + 5 dynid);
repo cook driver-manager succeeds for x86_64-unknown-redox.
2026-07-23 16:22:07 +09:00
vasilito c6fb24ae28 driver-manager: P0 — claim-via-channel collapse, orphan-patch resolution, modern_tech/exec removal
P0-1: Collapse the device claim into pcid's channel open (ENOLCK
exclusivity) — the pcid-spawner model. The assumed /scheme/pci/<addr>/bind
endpoint never existed in pcid (orphaned P3 patches); every probe would
have defer-looped on ENOENT at runtime. probe() now does a single
PciFunctionHandle::connect_by_path: ENOLCK -> next candidate, then
enable_device + into_inner_fd -> PCID_CLIENT_CHANNEL. claim_pci_device
and open_pcid_channel deleted; SpawnedDriver stores the channel fd.

P0-2: Resolve orphaned patches per the decision tree:
P3-pcid-bind-scheme.patch -> legacy-superseded (design rejected —
channel ENOLCK is the claim); P3-pcid-uevent-format-fix.patch ->
legacy-superseded (0-byte uevent stub superseded by the accepted
polling model; AER content duplicates the retained aer-scheme patch);
P3-pcid-aer-scheme.patch retained as the P2-1 producer blueprint.
SUPERSEDED.md audit log added.

P0-3: Remove advisory theater and suppressed dead code:
- modern_tech.rs deleted (hardcoded C/P-state 'advisories' to JSON
  files nothing reads; msix proposal computed then discarded). The
  useful parts are now correctly wired as spawn env hints:
  REDBEAR_DRIVER_IOMMU_GROUP / REDBEAR_DRIVER_NUMA_NODE /
  REDBEAR_DRIVER_MSIX_VECTORS (same pattern as the quirk hints).
- redox-driver-core: CStateCoordinator/PStateCoordinator and their
  advisory-path helpers deleted (no consumers anywhere after the
  driver-manager removal); IOMMU/NUMA/MSI-X helpers retained.
- exec.rs deleted (dead spawn_driver with #[allow(dead_code)]).

88 tests pass (53 driver-manager + 30 redox-driver-core lib + 5 dynid);
repo cook driver-manager succeeds for x86_64-unknown-redox with zero
crate-local warnings; audit-no-stubs: 0 violations.
2026-07-23 11:55:11 +09:00