Message ID | 20230510075252.31023-3-quic_kriskura@quicinc.com (mailing list archive) |
---|---|
State | Accepted |
Commit | d34f9bafa78da2a561c67d9daf55fc4d1d80edf0 |
Headers | show |
Series | Handle core soft reset failure in pullup | expand |
Hello! On 5/10/23 10:52 AM, Krishna Kurapati wrote: > In the event, gadget_connect call (which invokes pullup) fails, > propagate the error to udc bind operation which inturn sends the > error to configfs. The userspace can then retry enumeartion if > it chooses to. > > Signed-off-by: Krishna Kurapati <quic_kriskura@quicinc.com> > Acked-by: Alan Stern <stern@rowland.harvard.edu> > --- > changes in v3: Rebase on top of usb-next > > drivers/usb/gadget/udc/core.c | 21 +++++++++++++++++---- > 1 file changed, 17 insertions(+), 4 deletions(-) > > diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c > index 4641153e9706..69041cca5d24 100644 > --- a/drivers/usb/gadget/udc/core.c > +++ b/drivers/usb/gadget/udc/core.c > @@ -1122,12 +1122,16 @@ EXPORT_SYMBOL_GPL(usb_gadget_set_state); > /* ------------------------------------------------------------------------- */ > > /* Acquire connect_lock before calling this function. */ > -static void usb_udc_connect_control_locked(struct usb_udc *udc) __must_hold(&udc->connect_lock) > +static int usb_udc_connect_control_locked(struct usb_udc *udc) __must_hold(&udc->connect_lock) > { > + int ret; > + > if (udc->vbus && udc->started) > - usb_gadget_connect_locked(udc->gadget); > + ret = usb_gadget_connect_locked(udc->gadget); Why not just: return usb_gadget_connect_locked(udc->gadget) > else > - usb_gadget_disconnect_locked(udc->gadget); > + ret = usb_gadget_disconnect_locked(udc->gadget); Likewise here? > + > + return ret; > } > > /** [...] MBR, Sergey
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 4641153e9706..69041cca5d24 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1122,12 +1122,16 @@ EXPORT_SYMBOL_GPL(usb_gadget_set_state); /* ------------------------------------------------------------------------- */ /* Acquire connect_lock before calling this function. */ -static void usb_udc_connect_control_locked(struct usb_udc *udc) __must_hold(&udc->connect_lock) +static int usb_udc_connect_control_locked(struct usb_udc *udc) __must_hold(&udc->connect_lock) { + int ret; + if (udc->vbus && udc->started) - usb_gadget_connect_locked(udc->gadget); + ret = usb_gadget_connect_locked(udc->gadget); else - usb_gadget_disconnect_locked(udc->gadget); + ret = usb_gadget_disconnect_locked(udc->gadget); + + return ret; } /** @@ -1583,12 +1587,21 @@ static int gadget_bind_driver(struct device *dev) goto err_start; } usb_gadget_enable_async_callbacks(udc); - usb_udc_connect_control_locked(udc); + ret = usb_udc_connect_control_locked(udc); + if (ret) + goto err_connect_control; + mutex_unlock(&udc->connect_lock); kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); return 0; + err_connect_control: + usb_gadget_disable_async_callbacks(udc); + if (gadget->irq) + synchronize_irq(gadget->irq); + usb_gadget_udc_stop_locked(udc); + err_start: driver->unbind(udc->gadget);