summaryrefslogtreecommitdiffstats
path: root/rsnix/src/usb.rs
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-11-01 17:09:59 +0100
committersalmonik <salmonik@tuta.io>2026-11-01 17:09:59 +0100
commitd99906b48698c1bd722a1fa5f2270b76317ec661 (patch)
tree780a2b7bcf09733b7f6fedde9cf802c6b6e3abfb /rsnix/src/usb.rs
parentehci: diagnostics + hardening for the port-not-enabled case (diff)
downloadrs-dos-d99906b48698c1bd722a1fa5f2270b76317ec661.tar.gz
rs-dos-d99906b48698c1bd722a1fa5f2270b76317ec661.zip
ehci: bound all init waits; stop auto-rescanning; wider boot watchdogqemu
Hardware run 3 showed the same PED=0 SETUP halt and then never reached the prompt. Two boot-time hazards explain the death: - reset_port polled PED with a 2,000,000-iteration MMIO loop (seconds on real silicon) and the reset retry ran it twice per port, so the port scan alone exceeded the boot watchdog window (task 0 in one frame for 7.5 s panics). - while no HID was found the cursor task re-ran the whole EHCI scan, port resets included, every second -- a rate-matching hub never settles. Changes: - every EHCI wait is wall-clock bounded: halt/reset/run 500 ms, PED 200 ms - control-transfer timeout 5 s -> 500 ms - per-controller 3 s port-scan budget; no automatic re-scan (explicit `usb rescan` only) - 300 ms power-up settle before the reset walk (RMH bring-up) - boot-phase watchdog 750 -> 2000 ticks (20 s), room for hub bring-up - xHCI gets the same persistent bottom-row port/device summary
Diffstat (limited to '')
-rw-r--r--rsnix/src/usb.rs20
1 files changed, 19 insertions, 1 deletions
diff --git a/rsnix/src/usb.rs b/rsnix/src/usb.rs
index 5a4136f..aa41b0e 100644
--- a/rsnix/src/usb.rs
+++ b/rsnix/src/usb.rs
@@ -699,6 +699,7 @@ fn enumerate(port: u32, speed: u32) -> bool {
699 } 699 }
700 NXDEV.fetch_add(1, Ordering::Relaxed); 700 NXDEV.fetch_add(1, Ordering::Relaxed);
701 queue_report(idx); 701 queue_report(idx);
702 show_summary();
702 crate::serial_println!( 703 crate::serial_println!(
703 "usb: HID {} armed (slot {} mps {} interval {})", 704 "usb: HID {} armed (slot {} mps {} interval {})",
704 if kind == Kind::Mouse { "mouse" } else { "keyboard" }, 705 if kind == Kind::Mouse { "mouse" } else { "keyboard" },
@@ -968,10 +969,12 @@ pub fn init() -> bool {
968 } 969 }
969 } 970 }
970 INITOK.store(true, Ordering::Relaxed); 971 INITOK.store(true, Ordering::Relaxed);
972 let ports = unsafe { MAXPORTS };
971 crate::serial_println!( 973 crate::serial_println!(
972 "usb: controller up ({} ports) — HID discovery deferred to polling", 974 "usb: controller up ({} ports) — HID discovery deferred to polling",
973 unsafe { MAXPORTS } 975 ports
974 ); 976 );
977 show_summary();
975 true 978 true
976} 979}
977 980
@@ -1008,6 +1011,21 @@ fn maybe_discover() {
1008 } 1011 }
1009} 1012}
1010 1013
1014/// Persistent bottom-row summary for hardware runs without serial.
1015fn show_summary() {
1016 let (np, nd) = unsafe { (MAXPORTS, NXDEV.load(Ordering::Relaxed)) };
1017 let mut line = alloc::format!("xhci ports={} devs={}:", np, nd);
1018 unsafe {
1019 for p in 0..np.min(8) {
1020 let v = rd(op(OP_PORTSC) + (p as usize) * PORT_STRIDE);
1021 if v & PORT_CONNECT != 0 {
1022 line.push_str(&alloc::format!(" p{}={:04x}", p, v & 0xffff));
1023 }
1024 }
1025 }
1026 crate::gop::boot_marker_at(&line, crate::gop::bottom_row(3));
1027}
1028
1011fn has_kind(kind: Kind) -> bool { 1029fn has_kind(kind: Kind) -> bool {
1012 let n = NXDEV.load(Ordering::Relaxed) as usize; 1030 let n = NXDEV.load(Ordering::Relaxed) as usize;
1013 for i in 0..n { 1031 for i in 0..n {