From dafebacdfd306c924827aeab48b3e5519fa0bc89 Mon Sep 17 00:00:00 2001 From: Siyuan Date: Wed, 5 Nov 2025 15:43:10 +0000 Subject: [PATCH] feat: reset USB gadget if needed --- internal/usbgadget/config.go | 38 ++++++++++++++++++++++++------------ jsonrpc.go | 10 +++++----- usb_mass_storage.go | 2 +- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/internal/usbgadget/config.go b/internal/usbgadget/config.go index 6d1bd391..8cbdf081 100644 --- a/internal/usbgadget/config.go +++ b/internal/usbgadget/config.go @@ -177,7 +177,7 @@ func (u *UsbGadget) Init() error { u.udc = udcs[0] - err := u.configureUsbGadget(false) + err := u.configureUsbGadget(false, true) if err != nil { return u.logError("unable to initialize USB stack", err) } @@ -185,13 +185,13 @@ func (u *UsbGadget) Init() error { return nil } -func (u *UsbGadget) UpdateGadgetConfig() error { +func (u *UsbGadget) UpdateGadgetConfig(resetUsbIfNeeded bool) error { u.configLock.Lock() defer u.configLock.Unlock() u.loadGadgetConfig() - err := u.configureUsbGadget(true) + err := u.configureUsbGadget(true, resetUsbIfNeeded) if err != nil { return u.logError("unable to update gadget config", err) } @@ -199,14 +199,28 @@ func (u *UsbGadget) UpdateGadgetConfig() error { return nil } -func (u *UsbGadget) configureUsbGadget(resetUsb bool) error { - return u.WithTransaction(func() error { - u.tx.MountConfigFS() - u.tx.CreateConfigPath() - u.tx.WriteGadgetConfig() - if resetUsb { - u.tx.RebindUsb(true) +func (u *UsbGadget) configureUsbGadget(resetUsb bool, resetUsbIfNeeded bool) error { + f := func(resetUsbBefore bool, resetUsbAfter bool) func() error { + return func() error { + if resetUsbBefore { + u.tx.RebindUsb(true) + } + u.tx.MountConfigFS() + u.tx.CreateConfigPath() + u.tx.WriteGadgetConfig() + if resetUsbAfter { + u.tx.RebindUsb(true) + } + return nil } - return nil - }) + } + + // initial attempt to configure the gadget + err := u.WithTransaction(f(false, resetUsb)) + if err != nil && !resetUsbIfNeeded { + return err + } + + // if the initial attempt failed, try to configure the gadget again with the resetUsb flag + return u.WithTransaction(f(true, resetUsb)) } diff --git a/jsonrpc.go b/jsonrpc.go index 5ed90a7a..4d8695c2 100644 --- a/jsonrpc.go +++ b/jsonrpc.go @@ -678,7 +678,7 @@ func rpcSetUsbConfig(usbConfig usbgadget.Config) error { LoadConfig() config.UsbConfig = &usbConfig gadget.SetGadgetConfig(config.UsbConfig) - return updateUsbRelatedConfig() + return updateUsbRelatedConfig(false) } func rpcGetWakeOnLanDevices() ([]WakeOnLanDevice, error) { @@ -890,8 +890,8 @@ func rpcGetUsbDevices() (usbgadget.Devices, error) { return *config.UsbDevices, nil } -func updateUsbRelatedConfig() error { - if err := gadget.UpdateGadgetConfig(); err != nil { +func updateUsbRelatedConfig(resetUsbIfNeeded bool) error { + if err := gadget.UpdateGadgetConfig(resetUsbIfNeeded); err != nil { return fmt.Errorf("failed to write gadget config: %w", err) } if err := SaveConfig(); err != nil { @@ -903,7 +903,7 @@ func updateUsbRelatedConfig() error { func rpcSetUsbDevices(usbDevices usbgadget.Devices) error { config.UsbDevices = &usbDevices gadget.SetGadgetDevices(config.UsbDevices) - return updateUsbRelatedConfig() + return updateUsbRelatedConfig(false) } func rpcSetUsbDeviceState(device string, enabled bool) error { @@ -920,7 +920,7 @@ func rpcSetUsbDeviceState(device string, enabled bool) error { return fmt.Errorf("invalid device: %s", device) } gadget.SetGadgetDevices(config.UsbDevices) - return updateUsbRelatedConfig() + return updateUsbRelatedConfig(false) } func rpcSetCloudUrl(apiUrl string, appUrl string) error { diff --git a/usb_mass_storage.go b/usb_mass_storage.go index 0f1f4b93..9a112e3a 100644 --- a/usb_mass_storage.go +++ b/usb_mass_storage.go @@ -66,7 +66,7 @@ func setMassStorageMode(cdrom bool) error { return nil } - return gadget.UpdateGadgetConfig() + return gadget.UpdateGadgetConfig(true) } func mountImage(imagePath string) error {