@@ -24,6 +24,14 @@ type gadgetConfigItemWithKey struct {
2424
2525type orderedGadgetConfigItems []gadgetConfigItemWithKey
2626
27+ type UsbResetMode uint8
28+
29+ const (
30+ UsbResetNever UsbResetMode = 0 // never reset the usb gadget
31+ UsbResetAlways UsbResetMode = 1 // always reset the usb gadget
32+ UsbResetOnDemand UsbResetMode = 2 // reset the usb gadget when needed
33+ )
34+
2735var defaultGadgetConfig = map [string ]gadgetConfigItem {
2836 "base" : {
2937 order : 0 ,
@@ -177,34 +185,31 @@ func (u *UsbGadget) Init() error {
177185
178186 u .udc = udcs [0 ]
179187
180- err := u .configureUsbGadget (false , true )
188+ err := u .configureUsbGadget (UsbResetAlways )
181189 if err != nil {
182190 return u .logError ("unable to initialize USB stack" , err )
183191 }
184192
185193 return nil
186194}
187195
188- func (u * UsbGadget ) UpdateGadgetConfig (resetUsbIfNeeded bool ) error {
196+ func (u * UsbGadget ) UpdateGadgetConfig (resetUsbMode UsbResetMode ) error {
189197 u .configLock .Lock ()
190198 defer u .configLock .Unlock ()
191199
192200 u .loadGadgetConfig ()
193201
194- err := u .configureUsbGadget (true , resetUsbIfNeeded )
202+ err := u .configureUsbGadget (resetUsbMode )
195203 if err != nil {
196204 return u .logError ("unable to update gadget config" , err )
197205 }
198206
199207 return nil
200208}
201209
202- func (u * UsbGadget ) configureUsbGadget (resetUsb bool , resetUsbIfNeeded bool ) error {
203- f := func (resetUsbBefore bool , resetUsbAfter bool ) func () error {
210+ func (u * UsbGadget ) configureUsbGadget (resetUsbMode UsbResetMode ) error {
211+ f := func (resetUsbAfter bool ) func () error {
204212 return func () error {
205- if resetUsbBefore {
206- u .tx .RebindUsb (true )
207- }
208213 u .tx .MountConfigFS ()
209214 u .tx .CreateConfigPath ()
210215 u .tx .WriteGadgetConfig ()
@@ -216,11 +221,21 @@ func (u *UsbGadget) configureUsbGadget(resetUsb bool, resetUsbIfNeeded bool) err
216221 }
217222
218223 // initial attempt to configure the gadget
219- err := u .WithTransaction (f (false , resetUsb ))
220- if err != nil && ! resetUsbIfNeeded {
221- return err
224+ err := u .WithTransaction (f (resetUsbMode == UsbResetAlways ))
225+ if err == nil {
226+ return nil
222227 }
223228
224229 // if the initial attempt failed, try to configure the gadget again with the resetUsb flag
225- return u .WithTransaction (f (true , resetUsb ))
230+ if resetUsbMode == UsbResetOnDemand {
231+ u .log .Warn ().Err (err ).Msg ("initial attempt to configure the gadget failed, resetting USB gadget then trying again" )
232+ // NOTES: do not use the RebindUsb method here because it will block the transaction
233+ if err := u .rebindUsb (true ); err != nil {
234+ u .log .Warn ().Err (err ).Msg ("failed to reset USB gadget, skipping second attempt" )
235+ return err
236+ }
237+ return u .WithTransaction (f (true ))
238+ }
239+
240+ return err
226241}
0 commit comments