From 4419b5ce7386569c848d4e0cb73c8f258e108e0a Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Thu, 26 Jun 2025 01:11:14 -0500 Subject: [PATCH] server udc fix --- server/src/usb_gadget.rs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/server/src/usb_gadget.rs b/server/src/usb_gadget.rs index 4030444..c11890f 100644 --- a/server/src/usb_gadget.rs +++ b/server/src/usb_gadget.rs @@ -85,7 +85,26 @@ impl UsbGadget { /* 1 – detach gadget */ info!("🔌 detaching gadget from {ctrl}"); - Self::write_attr(self.udc_file, "none")?; + // a) drop pull‑ups (if the controller offers the switch) + let sc = format!("/sys/class/udc/{ctrl}/soft_connect"); + let _ = Self::write_attr(&sc, "0"); // ignore errors – not all HW has it + + // b) clear the UDC attribute; the kernel may transiently answer EBUSY + for attempt in 1..=10 { + match Self::write_attr(self.udc_file, "") { + Ok(_) => break, + Err(err) if { + // only swallow EBUSY + err.downcast_ref::() + .and_then(|io| io.raw_os_error()) + == Some(libc::EBUSY) && attempt < 10 + } => { + trace!("⏳ UDC busy (attempt {attempt}/10) – retrying…"); + thread::sleep(Duration::from_millis(100)); + } + Err(err) => return Err(err), + } + } Self::wait_state(&ctrl, "not attached", 3_000)?; /* 2 – reset driver */ @@ -97,7 +116,6 @@ impl UsbGadget { /* 4 – re‑attach + pull‑up */ info!("🔌 re‑attaching gadget to {ctrl}"); Self::write_attr(self.udc_file, &ctrl)?; - let sc = format!("/sys/class/udc/{ctrl}/soft_connect"); if Path::new(&sc).exists() { // try to set the pull-up; ignore if the kernel rejects it match Self::write_attr(&sc, "1") { @@ -107,7 +125,7 @@ impl UsbGadget { match io.raw_os_error() { // EINVAL | EPERM | ENOENT Some(libc::EINVAL) | Some(libc::EPERM) | Some(libc::ENOENT) => { - warn!("soft_connect unsupported ({io}); continuing"); + warn!("⚠️ soft_connect unsupported ({io}); continuing"); } _ => return Err(err), // propagate all other errors }