impl UsbGadget {
    /// helper: unbind + 300 ms reset + bind
    #[cfg(coverage)]
    fn rebind_driver(ctrl: &str) -> Result<()> {
        for drv in ["dwc2", "dwc3"] {
            let root = format!("{}/bus/platform/drivers/{drv}", Self::sysfs_root());
            if !Path::new(&root).exists() {
                continue;
            }
            Self::write_attr(format!("{root}/unbind"), ctrl)?;
            Self::write_attr(format!("{root}/bind"), ctrl)?;
            return Ok(());
        }
        Err(anyhow::anyhow!("no dwc2/dwc3 driver nodes found"))
    }

    #[cfg(not(coverage))]
    fn rebind_driver(ctrl: &str) -> Result<()> {
        let cand = ["dwc2", "dwc3"];
        for drv in cand {
            let root = format!("{}/bus/platform/drivers/{drv}", Self::sysfs_root());
            if !Path::new(&root).exists() {
                continue;
            }

            /*----------- unbind ------------------------------------------------*/
            info!("🔧 unbinding UDC driver ({drv})");
            for attempt in 1..=20 {
                match Self::write_attr(format!("{root}/unbind"), ctrl) {
                    Ok(_) => break,
                    Err(err) if attempt < 20 && Self::is_still_detaching(&err) => {
                        trace!("unbind in-progress (#{attempt}) - waiting…");
                        thread::sleep(Duration::from_millis(100));
                    }
                    Err(err) => return Err(err).context("UDC unbind failed irrecoverably"),
                }
            }
            thread::sleep(Duration::from_millis(150)); // let the core quiesce

            /*----------- bind --------------------------------------------------*/
            info!("🔧 binding   UDC driver ({drv})");
            for attempt in 1..=20 {
                match Self::write_attr(format!("{root}/bind"), ctrl) {
                    Ok(_) => return Ok(()), // success 🎉
                    Err(err) if attempt < 20 && Self::is_still_detaching(&err) => {
                        trace!("bind busy (#{attempt}) - retrying…");
                        thread::sleep(Duration::from_millis(100));
                    }
                    Err(err) => return Err(err).context("UDC bind failed irrecoverably"),
                }
            }
        }
        Err(anyhow::anyhow!("no dwc2/dwc3 driver nodes found"))
    }

    fn is_still_detaching(err: &anyhow::Error) -> bool {
        err.downcast_ref::<std::io::Error>()
            .and_then(|io| io.raw_os_error())
            .is_some_and(|code| {
                matches!(code, libc::EBUSY | libc::ENOENT | libc::ENODEV)
            })
    }

}
