server udc fix
This commit is contained in:
parent
140eef5513
commit
158b9ef3ab
@ -54,6 +54,17 @@ impl UsbGadget {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait (≤ `limit_ms`) until `/sys/class/udc/<ctrl>` exists again.
|
||||||
|
fn wait_udc_present(ctrl: &str, limit_ms: u64) -> Result<()> {
|
||||||
|
for _ in 0..=limit_ms / 50 {
|
||||||
|
if Path::new(&format!("/sys/class/udc/{ctrl}")).exists() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
thread::sleep(Duration::from_millis(50));
|
||||||
|
}
|
||||||
|
Err(anyhow::anyhow!("⚠️ UDC {ctrl} did not re‑appear within {limit_ms} ms"))
|
||||||
|
}
|
||||||
|
|
||||||
/*–––– public API ––––*/
|
/*–––– public API ––––*/
|
||||||
|
|
||||||
/// Hard‑reset the gadget → identical to a physical cable re‑plug
|
/// Hard‑reset the gadget → identical to a physical cable re‑plug
|
||||||
@ -80,19 +91,21 @@ impl UsbGadget {
|
|||||||
|
|
||||||
/* 2 – unbind / bind platform driver (dwc2/dwc3) */
|
/* 2 – unbind / bind platform driver (dwc2/dwc3) */
|
||||||
Self::rebind_driver(&ctrl)?;
|
Self::rebind_driver(&ctrl)?;
|
||||||
|
Self::wait_udc_present(&ctrl, 3_000)
|
||||||
|
.context("controller did not re‑appear after bind")?;
|
||||||
|
|
||||||
/* 3 – re‑attach gadget */
|
/* 3 – re‑attach gadget */
|
||||||
info!("🔌 re‑attaching gadget to {ctrl}");
|
info!("🔌 re‑attaching gadget to {ctrl}");
|
||||||
Self::write_attr(self.udc_file, &ctrl)?;
|
Self::write_attr(self.udc_file, &ctrl)?;
|
||||||
|
|
||||||
/* 4 – toggle gadget */
|
/* 4 – assert pull‑up */
|
||||||
let sc = format!("/sys/class/udc/{ctrl}/soft_connect");
|
let sc = format!("/sys/class/udc/{ctrl}/soft_connect");
|
||||||
// toggle 0 → 1 to force the controller to assert pull‑ups
|
// toggle 0 → 1 to force the controller to assert pull‑ups
|
||||||
Self::write_attr(&sc, "0")?; // guarantee clean edge
|
Self::write_attr(&sc, "0")?; // guarantee clean edge
|
||||||
thread::sleep(Duration::from_millis(50));
|
thread::sleep(Duration::from_millis(50));
|
||||||
Self::write_attr(&sc, "1")?;
|
Self::write_attr(&sc, "1")?;
|
||||||
|
|
||||||
/* 4 – wait for gadget */
|
/* 5 – wait for host (but tolerate sleep) */
|
||||||
Self::wait_state(&ctrl, "configured", 6_000)
|
Self::wait_state(&ctrl, "configured", 6_000)
|
||||||
.or_else(|e| {
|
.or_else(|e| {
|
||||||
// If the host is physically absent (sleep / KVM paused)
|
// If the host is physically absent (sleep / KVM paused)
|
||||||
@ -123,11 +136,11 @@ impl UsbGadget {
|
|||||||
}
|
}
|
||||||
info!("🔧 unbinding UDC driver ({drv})");
|
info!("🔧 unbinding UDC driver ({drv})");
|
||||||
Self::write_attr(format!("{root}/unbind"), ctrl)?;
|
Self::write_attr(format!("{root}/unbind"), ctrl)?;
|
||||||
thread::sleep(Duration::from_millis(300));
|
thread::sleep(Duration::from_millis(500));
|
||||||
|
|
||||||
info!("🔧 binding UDC driver ({drv})");
|
info!("🔧 binding UDC driver ({drv})");
|
||||||
Self::write_attr(format!("{root}/bind"), ctrl)?;
|
Self::write_attr(format!("{root}/bind"), ctrl)?;
|
||||||
thread::sleep(Duration::from_millis(100));
|
thread::sleep(Duration::from_millis(500));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Err(anyhow::anyhow!("no dwc2/dwc3 driver nodes found"))
|
Err(anyhow::anyhow!("no dwc2/dwc3 driver nodes found"))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user