When write UDC to empty and unbind gadget driver from gadget device, it is possible that there are many queue failures for mass storage function. The root cause is on platform like dwc3, if pull down called first, the queue operation from mass storage main thread will fail as it is belong to another thread context and always try to receive a command from host. In order to fix it, call gadget driver disconnect callback first, mass storage function driver will disable endpoints and clear running flag, so there will be no request queue to UDC. One note is when call disconnect callback first, it mean function will disable endpoints before stop UDC controller. Signed-off-by: yuan linyu <yuanlinyu@xxxxxxxxxxx> --- drivers/usb/gadget/udc/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index d59f94464b87..9c48cec89e35 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -774,15 +774,15 @@ static int usb_gadget_disconnect_locked(struct usb_gadget *gadget) goto out; } - ret = gadget->ops->pullup(gadget, 0); - if (!ret) - gadget->connected = 0; - mutex_lock(&udc_lock); if (gadget->udc->driver) gadget->udc->driver->disconnect(gadget); mutex_unlock(&udc_lock); + ret = gadget->ops->pullup(gadget, 0); + if (!ret) + gadget->connected = 0; + out: trace_usb_gadget_disconnect(gadget, ret); -- 2.25.1