From 140eef551396947ef44978feadf056df39ddf0b1 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Wed, 25 Jun 2025 23:27:51 -0500 Subject: [PATCH] server udc fix --- server/src/main.rs | 2 +- server/src/usb_gadget.rs | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/server/src/main.rs b/server/src/main.rs index a4020ee..b40d6dc 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -51,7 +51,7 @@ fn init_tracing() -> anyhow::Result { } async fn open_with_retry(path: &str) -> anyhow::Result { - const MAX_ATTEMPTS: usize = 40; // ≈ 2 s (@50 ms) + const MAX_ATTEMPTS: usize = 200; // ≈ 10 s (@50 ms) for attempt in 1..=MAX_ATTEMPTS { match OpenOptions::new() .write(true) diff --git a/server/src/usb_gadget.rs b/server/src/usb_gadget.rs index dec0dd9..7188838 100644 --- a/server/src/usb_gadget.rs +++ b/server/src/usb_gadget.rs @@ -84,7 +84,30 @@ impl UsbGadget { /* 3 – re‑attach gadget */ info!("🔌 re‑attaching gadget to {ctrl}"); Self::write_attr(self.udc_file, &ctrl)?; - Self::wait_state(&ctrl, "configured", 6_000)?; + + /* 4 – toggle gadget */ + let sc = format!("/sys/class/udc/{ctrl}/soft_connect"); + // toggle 0 → 1 to force the controller to assert pull‑ups + Self::write_attr(&sc, "0")?; // guarantee clean edge + thread::sleep(Duration::from_millis(50)); + Self::write_attr(&sc, "1")?; + + /* 4 – wait for gadget */ + Self::wait_state(&ctrl, "configured", 6_000) + .or_else(|e| { + // If the host is physically absent (sleep / KVM paused) + // we allow 'not attached' and continue – we can still + // accept keyboard/mouse data and the host will enumerate + // later without another reset. + let last = fs::read_to_string(format!("/sys/class/udc/{ctrl}/state")) + .unwrap_or_default(); + if last.trim() == "not attached" { + warn!("⚠️ host did not enumerate within 6 s – continuing (state = {last:?})"); + Ok(()) + } else { + Err(e) + } + })?; info!("✅ USB‑gadget cycle complete"); Ok(())