Commit Graph

3328 Commits

Author SHA1 Message Date
Red Bear OS 28afc1fefd drivers: complete shared-IRQ re-arm sweep (audio, net, graphics)
Continuation of 92924224 — the same conditional-ack bug class found in
six more drivers: a foreign interrupt on a shared INTx line skipped the
write-back ack, leaving the kernel-masked IRQ line dead forever.

- sb16d, ac97d: ack before the not-ours continue
- rtl8139d, rtl8168d, ixgbed: ack unconditionally, tick only when ours
  (the stale 'TODO: spurious interrupts' comments removed — the
  spurious-interrupt confusion was this bug)
- ihdgd: ack unconditionally, handle_events/tick only when ours

Verified: cargo check -Z build-std --target x86_64-unknown-redox for
sb16d, ac97d, rtl8139d, rtl8168d, ixgbed, ihdgd — clean, no new
warnings. nvmed audited: not affected (per-queue MSI pattern, no
conditional ack).
2026-07-20 18:48:30 +09:00
Red Bear OS 9292422458 drivers: always re-arm shared IRQ lines after interrupt delivery
Same bug class as the ahcid fix (ad40fffd): the kernel masks the IRQ
line when it delivers an interrupt and only re-arms it on the userspace
write-back (irq scheme write -> acknowledge() -> pic/ioapic_unmask).
When a driver acks only if the interrupt was its own, one foreign
interrupt on a shared INTx line leaves the line masked forever and all
later interrupts for the device are lost.

- e1000d: ack unconditionally; ICR is read-to-clear, so the ownership
  check doubles as the device-level status clear
- ihdad: ack before the not-ours continue
- vboxd: ack unconditionally; device-side ack and event handling stay
  conditional on host_events
- xhcid: ack unconditionally in the IRQ reactor; for INTx the ownership
  check already clears IMAN.IP (RW1C) and device interrupts are masked
  before re-arming, so no storm. MSI/MSI-X vectors are never shared, so
  behavior there is unchanged (every delivery is ours by construction)

Verified: cargo check -Z build-std --target x86_64-unknown-redox for
e1000d, ihdad, vboxd, xhcid — clean, no new warnings.
2026-07-20 18:44:53 +09:00
Red Bear OS 54e89a337a fbcond: perform the display handoff open off the console loop
fbcond blocked indefinitely in open_display_v2() while handing the console
over to the real graphics driver: boot stopped at "fbcond: Performing
handoff" and never reached the "Opened new display" that follows a
successful open.

fbcond is single-threaded and owns the console, so while it waited there it
stopped draining console writers. getty, login and the login shell all
blocked on their writes, which made the failure look like a slow or hung
shell -- the stall point just tracked whichever process next wrote to the
console. If the graphics driver was itself waiting on the console, the two
deadlocked outright and the console never came back.

The wait comes from the scheme-open handshake: inputd signals the handoff as
soon as the driver registers its path, but the driver may not be serving its
scheme yet, and O_NONBLOCK does not bound the open (it governs later reads).

Split the two halves in inputd's ConsumerHandle: display_path_v2() only does
an fpath on our own handle and returns promptly, while open_display_path_v2()
carries the blocking open. fbcond now resolves the path inline and hands the
open to a worker thread, then picks the result up from the event loop via
poll_pending_handoff(). Console output produced meanwhile is buffered in
pending_writes (already the behaviour while the display is unmapped) and
flushed once the new display is mapped.
2026-07-20 18:10:59 +09:00
Red Bear OS ad40fffd80 ahcid: always re-arm the IRQ line, even for foreign interrupts
The kernel masks an IRQ line when it delivers the interrupt to userspace
(trigger() -> pic_mask()/ioapic_mask()) and only re-enables it when the
driver writes the count back (kwrite -> acknowledge() -> pic_unmask()/
ioapic_unmask()). That write-back is therefore mandatory, not optional.

ahcid only performed it inside the `is > 0` branch. IRQ lines are shared
(on q35 the AHCI controller sits on IRQ 10 with other devices), so an
interrupt raised by a different device reaches the handler with the HBA
interrupt status register reading 0. In that case ahcid returned without
writing back, leaving the line masked permanently: every subsequent AHCI
completion was lost and all disk I/O blocked forever.

Move the write-back out of the branch so the line is re-armed whether or
not the interrupt turned out to be ours, and keep scheme.tick() gated on
`is > 0` since there is no completion to service otherwise. Device-level
status is still cleared before unmasking, so this cannot cause a storm.
2026-07-20 14:09:40 +09:00
Red Bear OS fb421083e0 fbcond: retry handoff while display driver is not ready
The handoff is one-shot: inputd signals it the moment the real display
driver registers its path, but the driver's scheme may not serve the v2
open / capability query for a few more milliseconds. Without a retry, a
transient not-ready driver leaves the framebuffer permanently blank —
the login prompt is drawn to the framebuffer VT, so the console appears
dead even though boot continues on the serial mirror (observed as the
2026-07-20 '-vga std' boot freeze at 'Performing handoff').

Retry the reopen for up to 250 x 10ms; the driver becomes ready well
within this bound in practice. On success after retries, log the retry
count at info level. If the driver is still not ready after the bound,
emit a single explicit warning instead of per-attempt warn spam (the
per-attempt message in display.rs is demoted to debug). Serial mirror
remains unaffected in the failure case.
2026-07-20 08:59:26 +09:00
Red Bear OS e4d4dfffec xhcid: promote IRQ reactor startup lines to info level
'Running IRQ reactor with IRQ file and event queue' and 'in polling
mode' were debug! since the file was created, so test-xhci-irq-qemu.sh
(which greps for the interrupt-driven line) could never see them at the
default info log level — the IRQ-driven path had zero runtime evidence.
They are one-time startup lines; promote to info so the interrupt
delivery mode is observable and the proof can detect it.
2026-07-20 00:44:11 +09:00
Red Bear OS 6694b5af9e fbcond/graphics-ipc: treat not-ready graphics driver as transient at handoff
V2GraphicsHandle::from_file() unwrapped/asserted the DumbBuffer
capability, but the display fd is O_NONBLOCK and the graphics driver
often has not finished coming up at handoff time — so from_file failed
with EAGAIN and the assert panicked fbcond. Since fbcond owns the
console and serial mirror, its death froze the whole boot right after
'Performing handoff' with no login prompt.

Return an error from graphics-ipc when the driver does not yet report
DumbBuffer, and have fbcond log-and-return so the handoff is retried
when the driver publishes its surface, instead of panicking.

(Change found as uncommitted work in the fork; committing to preserve
it and unblock the clean-fork build gate.)
2026-07-20 00:28:02 +09:00
Red Bear OS 3c9dda3253 virtio-netd: log MSI-X interrupt delivery at info level
The driver requires MSI-X (virtio-core probe errors out without it) and
binds both virtqueues to MSIX_PRIMARY_VECTOR, but only noted the
transport in a debug log — leaving zero runtime evidence of the MSI-X
path at the default level, which is why test-msix-qemu.sh found no live
MSI-X evidence. Log the delivery method at info where it is set up.
2026-07-20 00:24:54 +09:00
Red Bear OS a8e1ddc913 usb: demote diagnostic ATTACH/HUBFLOW traces to debug!
The diagnostic milestones used to root-cause the intermittent boot
'freeze' (attach_device milestones, usbhubd HUBFLOW decision points,
reactor/enumerator startup) moved from info to debug! so production
logs stay clean. One-line-per-boot startup confirmations (scheme
registered, daemon ready, reactor started, enumerator started, reactor
dispatch mode, enumerator running) remain at info as genuinely useful
low-volume startup evidence.
2026-07-19 23:01:48 +09:00
Red Bear OS 5a709b0f43 xhcid: fix build — InterruptMethod does not implement Debug
The reactor-start trace used {:?} on InterruptMethod, which has no
Debug impl. Dropped the format arg.
2026-07-19 21:48:41 +09:00
Red Bear OS a1df36a0b9 xhcid: info-level startup milestones for reactor-race diagnosis
Traces at scheme registration, daemon.ready, reactor/enumerator start,
reactor dispatch + IRQ subscribe, and enumerator run entry, to pinpoint
where xhcid stops in boots that lose the intermittent IRQ-reactor
startup race. Diagnostic; level to be revisited after root cause.
2026-07-19 21:46:50 +09:00
Red Bear OS 0e948dd2a7 usbhubd: gate port-indicator SetPortFeature on hub capability
SetPortFeature(PORT_INDICATOR) was issued unconditionally for every
connected+enabled port. QEMU's usb-hub does not advertise indicator
support and NAKs the request indefinitely; with no control-transfer
timeout the daemon hung before the post-enable debounce, so devices
behind the hub never attached. Gate on wHubCharacteristics bit 7
(HUB_CHAR_PORTIND, USB 2.0 Table 11-13), matching Linux hub_configure's
has_indicators check.
2026-07-19 19:11:36 +09:00
Red Bear OS ef34223201 usbhubd: trace SetPortReset result + wait_for_reset boundaries (diagnostic)
Log SetPortFeature(PORT_RESET) result, wait_for_reset's first fetch,
and its completion/timeout outcomes at info level to pinpoint where
hub port-reset polling stalls in QEMU.
2026-07-19 18:38:03 +09:00
Red Bear OS 5164417f56 ps2d: don't panic on transient event-queue read errors in the input loop 2026-07-19 18:02:15 +09:00
Red Bear OS bcf8ea25a7 inputd: fix misaligned-load UB on producer event writes
The producer's write buffer arrives byte-aligned from an arbitrary
scheme write; constructing a &[Event] slice directly over it is
undefined behaviour (misaligned loads, hardware faults on strict-
alignment targets). Copy the events into a properly aligned Vec<Event>
via copy_nonoverlapping and drop the trailing partial event.

(Change found as uncommitted work in the fork; committing to preserve
it and unblock the clean-fork build gate.)
2026-07-19 12:27:50 +09:00
Red Bear OS 0683c020a5 ptyd: harden against transient scan/event-queue errors
Replace two panics (initial scan_requests expect, event-queue read
expect) and a socket-event break with error logging + continuation. A
transient error reading the event queue or scanning requests must not
kill ptyd and take the whole pty subsystem down with it.

(Change found as uncommitted work in the fork; committing to preserve
it and unblock the clean-fork build gate.)
2026-07-19 12:25:21 +09:00
Red Bear OS 5f78ad843a usbhubd: info-level HUBFLOW traces at attach decision points (diagnostic)
Post-debounce state, pre-attach state, and attach() result logged at
info level to pinpoint where hub-child enumeration stalls in QEMU.
Diagnostic; level to be revisited.
2026-07-19 12:00:45 +09:00
Red Bear OS 5803f4c6f2 xhcid: info-level attach_device milestone traces (diagnostic)
Temporary info-level ATTACH milestones in attach_device (begin, slot,
addressed, desc8, desc-full, drivers spawned) to trace hub-child
enumeration in QEMU — the kbd behind a hub reaches port-enable but
produces no visible outcome at the default log level. Level to be
revisited after the hub-child attach path is diagnosed.
2026-07-19 11:39:44 +09:00
Red Bear OS b16e6ca399 usbhubd: judge debounce stability on connection state, not change bit
The debounce's inner clear of C_PORT_CONNECTION could hang or be
ignored by the hub, and our control transfers have no timeout — so a
literal port of Linux's clear-inside-the-loop design deadlocked hub
enumeration: the debounce never converged and the reset/attach path was
never reached (observed on QEMU as usbhubd logging the port's first
status with connection_changed=true and then going silent forever).

Judge the 100ms stable window on the connection STATE alone (the same
stability property hub_port_debounce_be_connected protects): a stuck or
hung change bit can no longer deadlock enumeration — it only
re-triggers a poll, and is cleared once, best-effort, after a
successful attach (matching Linux port_event's C_PORT_CONNECTION
clear). New regression test debounce_stuck_change_bit_still_converges
locks the deadlock scenario; 15/15 tests pass.
2026-07-19 10:59:35 +09:00
Red Bear OS 217935ec95 ipcd: fix RefCell double-borrow panic on getsockopt(SO_PEERCRED)
UdsStreamScheme::getsockopt held an outer socket_rc.borrow() across the
whole option match. The SO_PEERCRED branch calls get_connected_peer(id),
which itself does borrow_mut() on the same socket — a RefCell
double-borrow that panicked ipcd and took the UDS scheme down (observed
in QEMU boot logs as ipcd crash at uds/stream.rs plus tokio
UnixStream::pair / 'failed to create UnixStream' failures from clients
calling getsockopt(SO_PEERCRED)).

Borrow only inside the branches that read socket fields (SNDBUF/RCVBUF);
the SO_PEERCRED branch now runs without an outer borrow held.

(Change found as uncommitted work in the fork; committing to unblock the
clean-fork build gate and to preserve the fix.)
2026-07-19 10:17:23 +09:00
Red Bear OS 8cd2f71ddd usbhubd: bound EP1 wait via worker thread + recv_timeout poll fallback
Root cause of hub-child enumeration stalling: after a synchronous
action (power-on, reset) the port's state changes WITHOUT a new
interrupt ever being generated, and the loop's next step was a blocking
EP1 transfer_read with no timeout — the daemon never woke to observe
the state it had just caused, so devices behind a hub sat
enabled-but-never-attached forever.

Move the blocking transfer_read onto a worker thread that forwards each
interrupt bitmap as a u64 mask over an mpsc channel. The main loop
waits with recv_timeout(POLL_FALLBACK_MS): a real bitmap processes only
the changed ports (interrupt fast path), while timeout/disconnect/error
falls back to an all-ports poll (progress guarantee). Matches the Linux
model where hub_irq is the accelerator but port status reads are always
authoritative.
2026-07-19 10:11:38 +09:00
Red Bear OS 9317d4874b usbhubd: fix status-bitmap off-by-one + add initial full port scan
Two latent bugs exposed by test-usb-hub-qemu.sh against a real hub
topology (QEMU usb-hub with usb-kbd behind it):

1. Status-change bitmap was indexed off by one: the loop checked
   bit (port - 1), but USB 2.0 spec 11.12.4 defines bit 0 = hub status
   change and bit N = port N status change (Linux hub_irq uses bit i
   for port i). Every change was processed on the wrong port — a device
   on port N was never enumerated (its bit was read as port N+1).

2. The event loop's first action was a blocking EP1 interrupt read;
   when the hub delivers no immediate status-change interrupt the
   daemon hung before ever scanning a port. Linux hub_activate()
   performs a full port scan before arming the status-change endpoint;
   the first iteration now forces an all-ports mask with the same
   semantics. Also widened the fallback all-ports mask to bits 1..=ports
   (bit 0 = hub, skipped).
2026-07-19 09:46:05 +09:00
Red Bear OS d7f31916bc xhcid: open hub-child port dirs before enumeration (scheme bootstrap)
open_handle_port required a PortState for every port<N> directory open,
but hub child ports have no PortState until the hub daemon triggers
attach_device via port<N>/attach — an endpoint that itself is
state-free (open_handle_attach_device). This made XhciClientHandle::new
fail with ENOENT for unenumerated hub children, deadlocking the attach
flow: usbhubd could never start enumeration for a device behind a
non-root hub (panic at startup, caught by test-usb-hub-qemu.sh).

Open the directory with the static listing when no PortState exists
yet; state-dependent subpaths (descriptors, state, configure) still
gate on the PortState being present.
2026-07-19 09:15:33 +09:00
Red Bear OS 9bbdc2cafa Merge upstream/main (59cf8189) into submodule/base
Sync the base fork with 13 upstream commits (xhci event-processing
dedup + IRQ race fix, randd permission simplification, nvmed TimeSpec
fix, /dev/ptmx, fpath legacy-path cleanup, dynamically-linked init
fix, and more). Brings process_one_event into the tree, satisfying the
verify-fork-functions gate for base.

Conflicts resolved (3 of 8 overlapping files; 5 auto-merged):

- drivers/usb/xhcid/src/xhci/irq_reactor.rs: took upstream's
  process_one_event/EventProcessResult refactor (b2ed85ea) including
  the a01d3ce6 race fix (process events between NoEvent and
  unmasking), and re-applied the Red Bear SPURIOUS_REBOOT quirk on the
  NoEvent warning (downgrade to debug when quirked).

- randd/src/main.rs: took upstream's permission-handling
  simplification (e26db606); re-applied the RB fcntl improvement
  (F_GETFL/F_GETFD/F_SETFL/F_SETFD handling, Linux random_fops xref)
  and the is_cpu_feature_detected early-return cleanup. Dropped
  test_scheme_perms (deleted by upstream's simplification).

- Makefile: kept upstream's new /dev symlink block (dev/null, ptmx,
  random, urandom, zero, tty, stdin/stdout/stderr).

Verified: cargo check clean; 57/57 tests pass (xhcid 35, usbhubd 14,
xhci trb 8); verify-fork-functions.sh --no-fetch base reports all
upstream functions present.
2026-07-19 05:47:27 +09:00
Red Bear OS bd379e0771 usbhubd: full Linux 7.1 hub enumeration state machine (P3-A)
Port the Linux 7.1 hub.c port state machine into usbhubd, replacing the
minimal connect/reset handling:

New module port_ops.rs (pure logic, side effects injected, 14 unit
tests):
- debounce_until_connected: hub_port_debounce_be_connected() port
  (hub.c:4696-4737) — 25ms polls, connection stable for 100ms, 2s
  budget, connection-change bit cleared in-loop.
- wait_for_reset: hub_port_wait_reset() port (hub.c:2953-3047) — 10ms
  polls until RESET clears with CONNECTION set, escalate to 200ms after
  two short waits, 800ms budget; then 50ms TRSTRCY recovery (hub.c:3159)
  and C_PORT_RESET clear. Replaces the previous bare sleep(10ms).
- wait_for_u0: USB 3.0 polling→U0 wait after port power-on — 36ms steps,
  400ms ceiling (tPollingLFPSTimeout = 360ms; Linux hub.c:1226 debounce
  path).
- accumulate_hub_delay_ns: wHubDelay chain rule (hub.c:1507-1519:
  wHubDelay + parent->hub_delay + 40ns, cap 65535ns).

main.rs wiring:
- Port status normalized to PortStatusSnapshot (decouples the state
  machine from the V2/V3 wire formats; V3 link state extracted from
  bits 8:5).
- Debounce on connection-change before attach; C_PORT_ENABLE cleared
  once handled (Linux port_event semantics).
- Reset path uses wait_for_reset instead of sleep(10ms).
- USB 3 power-on path waits for U0 before proceeding.
- wHubDelay: ancestor-chain walk fetching USB 3 ancestor hub
  descriptors, accumulated per Linux; delivered to newly attached
  SuperSpeed children via SET_ISOCH_DELAY (USB 3.0 9.4.11; Linux
  message.c:1142 — hubs and non-SS skipped, children inherit the hub's
  accumulated delay verbatim per hub.c:5128-5129).
- attach/detach failure logs now identify the port.

hub.rs (xhcid usb module):
- HubDescriptorV3 extended with device_removable: u16 — the SS hub
  descriptor is 12 bytes (spec Table 10-15); the old struct under-read
  by 2 bytes. Stale TODO corrected: SS descriptors have no
  PortPwrCtrlMask (that is USB 2.0-only, still unparsed).

Verified: cargo check clean (0 usbhubd warnings), 14/14 usbhubd tests,
xhcid unaffected (43/43 tests).
2026-07-19 00:27:49 +09:00
Red Bear OS 260003331e xhcid: fix restart_endpoint deadlock, doorbell ordering, NoOp priming (P2-C)
Three bugs in the xHCI endpoint-restart path used by all error recovery
(stall hard reset, transaction-error soft retry, resource retry,
split/babble hard reset):

1. Latent deadlock: restart_endpoint held the port_states write guard
   across set_tr_deque_ptr(), which internally re-acquires a read guard
   on the same key (std RwLock read-while-write on one thread).
   Unobserved because error injection is not yet exercised at runtime
   (P8-C). Fixed by scoping phase-1 ring priming so the guard drops
   before the async command.

2. Doorbell ordering violated xHCI spec 4.6.8/4.6.10: after Reset
   Endpoint the TR Dequeue Pointer is undefined, so Set TR Dequeue
   Pointer must complete BEFORE the doorbell transitions the endpoint
   Stopped->Running. The old order (doorbell first) ran the endpoint
   with an undefined dequeue pointer — undefined xHC behavior on real
   hardware. Linux rings the doorbell from the Set TR Dequeue command
   completion path (xhci_handle_cmd_set_deq, ring.c:1416-1554); xhcid
   now issues Set TR Dequeue, awaits completion, then rings.

3. Priming NoOp never executed: ring.register() was captured after
   ring.next() advanced the enqueue index, so the dequeue pointed past
   the NoOp (dead TRB). Now captured before next(), priming the
   hardware dequeue AT the NoOp so the xHC executes it on restart —
   same semantics as Linux xhci_move_dequeue_past_td pointing at the
   first valid TRB.

Verified: cargo check clean (138 warnings, unchanged), 43/43 tests pass.
2026-07-18 23:14:14 +09:00
Red Bear OS 75229a5789 ptyd: remove temporary line-discipline diagnostics 2026-07-18 23:07:59 +09:00
Red Bear OS d20557f726 xhcid: gate xHCI 1.1+ features on HCCPARAMS2 + protocol-caps bits (P2-B)
Gate xHCI 1.1+ features on their capability bits, cross-referenced with
Linux 7.1 xhci driver behavior:

LEC (HCC2_LEC, scheme.rs):
- lec now uses Linux xhci-mem.c:1350 exact condition:
  hci_version > 0x100 && hcc_params2 & HCC2_LEC (HCCPARAMS2 register
  space is reserved on 1.0 controllers).
- Max ESIT Payload Hi zeroed when LEC=0 (spec Table 6-8 RsvdZ).

U3C (HCC2_U3C, mod.rs suspend_port):
- Refuse SuperSpeed U3 entry with ENOSYS when hci_ver >= 0x110 and
  HCC2_U3C=0 (spec 4.15.1). USB2 suspend unaffected. Linux 7.1 defines
  but never gates this bit; xhcid follows the spec.

CIC (HCC2_CIC): CIE gate pre-existing (set_cie from cic()); added the
hci_ver > 0x100 version guard. HCC2 capability log block similarly
guarded.

HW LPM (extended.rs, mod.rs, port.rs):
- New SupportedProtoCap::{l1_capable,hw_lpm_capable,besl_lpm_capable}
  reading protocol-defined bits (Linux xhci-ext-caps.h:62-66 L1C/HLC/BLC).
- Xhci::hw_lpm_support computed per Linux xhci-mem.c:2137:
  hci_ver >= 0x100 && !HW_LPM_DISABLE && any USB2 protocol cap has HLC.
- attach_device(): defensive LPM clear on USB 2.0 protocol ports
  (rev_major() != 3) when hw_lpm_support is false — Linux xhci.c:4725
  disable path; USB3 excluded because PORTPMSC L1DS aliases U2 timeout.
- Port::enable_lpm/disable_lpm register targets fixed: HLE/HIRD/RWE/
  L1DS belong in PORTPMSC (offset 0x04), not PORTHLPMC (0x0C, bit 16
  RsvdZ) — spec Tables 5-21/5-23, Linux xhci-port.h:135-158. Helpers
  rewritten to Linux xhci.c:4686-4737 two-register sequence.
- Per-device L1 enablement (BESL, MEL Evaluate Context) defers to P3.

Bug fix: removed bogus CapabilityRegs::hlc() + HCC_PARAMS1_HLC_BIT —
they read xECP pointer bits 16-31 of HCCPARAMS1 (spec Table 5-13), not
HLC. HLC lives in the Supported Protocol capability port_info DWORD.

Verification: cargo check clean (138 warnings, -2 vs baseline: the new
disable_lpm call site also revived PORT_HLE/PORT_HIRD_MASK), 43/43
tests pass.
2026-07-18 22:33:38 +09:00
Red Bear OS 9fc1947d53 xhcid: converge xHCI quirks to canonical redox-driver-sys path
Replace xhcid's self-contained 294-line xhci/quirks.rs (7-flag bitflags
type + ~30-entry quirk table) with a thin re-export shim that delegates
to redox-driver-sys::quirks, which now carries all 51 Linux 7.1 quirk
flags and the full ~85-entry canonical controller table.

Changes:
- Cargo.toml: add redox-driver-sys path dependency
- xhci/quirks.rs: replace table with pub use XhciControllerQuirkFlags
  as XhciQuirks + delegating lookup_quirks(vendor, device, revision,
  hci_version)
- main.rs: read real HCIVERSION from MMIO offset 0x04 via
  cap.hci_ver.read() instead of hardcoded 0x100 — matches Linux 7.1
  xhci_gen_setup() at xhci.c:5455. Two table entries depend on the
  value: AMD_0x96_HOST (xhci-pci.c:308) and >= 0x120 spec rule
  (xhci-pci.c:511).
- main.rs: resolve quirks BEFORE get_int_method() so BROKEN_MSI skips
  MSI/MSI-X probing entirely (matching Linux xhci_try_enable_msi at
  xhci-pci.c:143-209). Previously the quirk only overrode the method
  label while irq_file still held the MSI handle — a mismatch causing
  silent interrupt-delivery failures on BROKEN_MSI controllers.
- get_int_method (both cfg variants): accept quirks parameter
2026-07-18 21:52:05 +09:00
Red Bear OS ad4bedd46d xhcid: expand xHCI completion-code error recovery to all 36 codes
maybe_recover_transfer_error previously handled only the first-tier
codes (UsbTransaction, Resource, Stall, BabbleDetected, DataBuffer,
Trb, SplitTransaction) and silently returned Ok(false) for every
other completion code via a catch-all arm.

Cross-referenced Linux 7.1 drivers/usb/host/xhci-ring.c
handle_tx_event() (line 2608+) and handle_transferless_tx_event()
(line 2561+) to add explicit recovery for the remaining ~29 codes:

- Stopped/StoppedLengthInvalid/StoppedShortPacket: restart endpoint
  + retry (up to MAX_SOFT_RETRY), then hard-reset
- InvalidStreamType/InvalidStreamId: soft reset + retry, then
  hard-reset
- IncompatibleDevice: disable slot (device must re-enumerate)
- MissedService/NoPingResponse: log informational, surface to caller
- ContextState/Parameter: hard-reset to resync driver/xHC state
- Bandwidth/BandwidthOverrun/SecondaryBandwidth: log, no transfer
  recovery (config must change)
- IsochBuffer: hard-reset endpoint
- MaxExitLatencyTooLarge: log, surface
- EventLost/Undefined: hard-reset (event ring may be corrupted)
- SlotNotEnabled/EndpointNotEnabled/NoSlotsAvailable: log driver
  state mismatch
- CommandRingStopped/CommandAborted: log xHC state confusion
- Reserved/vendor: default arm logs explicitly

Added completion_code_to_errno() mapping transfer completion codes
to POSIX errnos matching Linux 7.1 semantics:
  Stall -> EPIPE
  BabbleDetected -> EOVERFLOW
  UsbTransaction/SplitTransaction/IncompatibleDevice -> EPROTO
  Trb -> EILSEQ
  DataBuffer -> ENOSR
  SlotNotEnabled/EndpointNotEnabled/NoSlotsAvailable -> ENODEV
  default -> EIO

Rewrote handle_transfer_event_trb() to use the new errno mapping
instead of always returning EIO.

Added 14 unit tests covering all errno mappings and transfer
event handling paths. Full suite (41 tests) passes.
2026-07-18 20:55:41 +09:00
Jacob Lorentzon 59cf818933 Merge branch 'fix_dylink_init' into 'main'
Fix support for dynamically linked init

See merge request redox-os/base!309
2026-07-18 11:05:46 +02:00
bjorn3 01018feece Fix support for dynamically linked init 2026-07-18 10:54:07 +02:00
Red Bear OS 4fdb81fa30 DIAG(ptyd): log pty.input line-discipline (icanon/vmin -> cooked/mosi) + slave read mosi state 2026-07-18 17:29:33 +09:00
Red Bear OS 8b605179eb fbcond: translate CR to LF on keyboard input
The keyboard input path pushed the raw character bytes, so the Enter key
(a bare CR on the keymap) never produced an LF. Line-oriented readers on
the console (e.g. a shell's read_line) then never saw a completed line and
appeared to hang. Convert CR->LF here, matching the serial input path
(push_input_bytes).
2026-07-18 12:02:45 +09:00
Jeremy Soller ba31f13cb1 Merge branch 'timed-out' into 'main'
nvmed: Use correct TimeSpec for timeout

See merge request redox-os/base!308
2026-07-17 19:54:51 -06:00
Red Bear OS ebf0cad69d init: do not chdir into initfs prefix after switch_root
The restored switch_root chdir set init's CWD to /scheme/initfs on the
live image. login later restricts its namespace to DEFAULT_SCHEMES (no
'initfs' scheme) via mkns/setns; the inherited /scheme/initfs CWD fd then
becomes unresolvable. Because relibc resolves paths through the CWD fd
(AT_REDOX_CWD_FD), every subsequent file op in login hangs -- notably
Command::spawn() loading the login shell binary never returns, so the
shell never starts. Leaving the CWD inherited (as before the chdir was
added) keeps spawn working across the login namespace switch; getcwd() in
/usr binaries works without the chdir. Reverts the CWD half of 521c6ffe;
the init-diag cleanup from that commit is retained.
2026-07-18 10:43:05 +09:00
Red Bear OS 37289beee0 Revert 'common/logger: quiet console output to Warn'
The Warn console level correlated with a deterministic login-auth
regression in the mini image (login reads the username but never reaches
MOTD/spawn_shell; 0/3 boots authenticated vs 1/1 with Info). Restore
Info-level console output while the interaction is re-verified; console
spam will be reduced later via a safer mechanism (routing daemon output,
not lowering the shared log level).
2026-07-18 09:47:24 +09:00
Red Bear OS c739f32aa2 common/logger: quiet console output to Warn (keep Info in files)
Daemons log via OutputBuilder::stderr() at output_level, which shares the
interactive console/login VT. At Info they spam routine chatter (cpufreqd,
thermald, i2c-hidd, ...) over the login prompt as boot continues in
parallel with getty. Drop the console filter to Warn; full Info logs are
still written to per-daemon log files (file_level), and a bootloader env
var can raise it for debugging.
2026-07-18 08:54:57 +09:00
Red Bear OS 521c6ffe5b init: restore switch_root chdir + remove temporary spawn diagnostics
Commit 99e08650 temporarily removed the post-switch_root chdir (which
points init's working directory at a valid dir in the new root) to test a
spawn hang, and added init-diag SPAWNING/SPAWNED/WAITING eprintlns. The
chdir was never restored: init and every daemon/getty/login/shell it
spawns inherit an invalid CWD (AT_REDOX_CWD_FD), so getcwd() fails in
/usr binaries and interactive shells (zsh/brush) hang instead of reading
input. Restore the chdir and drop the diagnostic eprintlns (which also
spammed the login console).
2026-07-18 08:24:09 +09:00
Red Bear OS e9342b78e9 feat(fbcond): bidirectional serial console mirror for headless login
fbcond now mirrors all framebuffer-console output to the kernel debug (serial)
scheme AND feeds serial input back into the active VT's input queue. Previously,
once fbcond took over the console after display handoff the serial line went
silent (headless operators saw the boot stop at 'Performing handoff' and never
saw the getty login prompt, which draws only to the framebuffer VT). Now the
same console — boot log, login prompt, and shell — is fully usable over serial,
reusing the working framebuffer getty for both surfaces.
2026-07-18 07:23:22 +09:00
Red Bear OS 0120017484 fix(net): silence benign no-network warnings; add e1000e (82574) support
- smolnetd: an empty ip_router (DHCP-managed or deliberately network-less like
  the bare target) is a valid 'no default gateway' state, not a malformed config
  -> no warning.
- router: a limited/directed IPv4 broadcast (DHCP DISCOVER to 255.255.255.255
  before any lease/route exists) legitimately has no routing-table entry; don't
  warn 'No route found' for broadcast destinations.
- e1000d: add the 82574L (0x10d3, QEMU '-device e1000e') to the E1000 match
  list; it keeps the legacy descriptor/register interface this driver uses.
  I219 is intentionally excluded (integrated MDIO PHY, different init).
2026-07-18 00:49:44 +09:00
Red Bear OS 1769b083ab fix(boot): clean up bare/mini boot warnings and errors
- init: add condition_path_exists so optional-daemon units (dbus, seatd,
  thermald, evdevd) are silently skipped when their binary is absent in a
  minimal image, instead of emitting [FAILED] 'No such file or directory' on
  the bare target. Boot-critical units omit the field and still hard-fail.
- ahcid: an empty ATAPI/optical drive (QEMU's default DVD-ROM, most bare-metal
  optical bays) failed READ CAPACITY and logged 4 ERROR lines every boot;
  register it with a zero block count as a normal no-media state and drop the
  HBA register dump to debug level.
- netstack: a machine with no NIC (bare, or an unsupported NIC) logged an ERROR
  and exited non-zero; treat 'no network adapter' as a normal idle state
  (info + clean exit).
- dhcpd: cut the socket timeout 30s -> 8s so the network stage fails fast when
  no DHCP server answers instead of stalling boot.
2026-07-18 00:29:43 +09:00
Wildan M 4abaae000b nvmed: Use correct TimeSpec for timeout 2026-07-17 03:31:40 +07:00
Jeremy Soller d77b425552 Merge branch 'fpath_remove_legacy_path' into 'main'
Stop using the legacy path format in fpath

See merge request redox-os/base!307
2026-07-16 12:19:08 -06:00
bjorn3 5c6f460bbb Stop using the legacy path format in fpath
For fbbootlog, fbcon and the disk drivers there is no load bearing use
of the fpath output. And for chan relibc already handles both the legacy
and new format.
2026-07-16 20:16:44 +02:00
Jeremy Soller 6238bb653d Merge branch 'dev_ptmx' into 'main'
Add /dev/ptmx symlink

See merge request redox-os/base!306
2026-07-16 12:03:43 -06:00
bjorn3 add972864e Add /dev/ptmx symlink
This is the standard location for ptmx across unixes though POSIX
doesn't strictly mandate it to exist. It only mandates posix_openpt() to
work.
2026-07-16 20:01:02 +02:00
Jeremy Soller 3cca6d13cc Merge branch 'simplify_randd' into 'main'
randd: Significantly simplify file permission handling

See merge request redox-os/base!305
2026-07-16 10:27:43 -06:00
bjorn3 e26db606d1 randd: Significantly simplify file permission handling
There isn't really a need to support chown/chmod of the rand scheme. It
adds a fair bit of complexity without adding any security over
unconditionally allowing reads by anyone and writes by root. If we want
to restore support for chown/chmod, we should probably do so in a
generic way that covers all device schemes.
2026-07-16 18:19:44 +02:00
Red Bear OS 324172abaf fbcond: restore console scrollback (lost P4-fbcond-scrollback)
Re-adds the archived-but-unapplied scrollback support: a 1000-line ring
buffer in TextScreen capturing all output (incl. pre-handoff boot log), a
Handle::Scrollback variant opened via /scheme/fbcon/<vt>/scrollback, and a
read path returning the retained buffer. Adapted to the current single-step
openat scheme protocol.
2026-07-16 21:59:18 +09:00