server udc fix

This commit is contained in:
Brad Stein 2025-06-26 01:11:14 -05:00
parent 9ce834264e
commit 4419b5ce73

View File

@ -85,7 +85,26 @@ impl UsbGadget {
/* 1 detach gadget */
info!("🔌 detaching gadget from {ctrl}");
Self::write_attr(self.udc_file, "none")?;
// a) drop pullups (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::<std::io::Error>()
.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 reattach + pullup */
info!("🔌 reattaching 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
}