|
@@ -1283,6 +1283,33 @@ bind_fail:
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+reset_gadget(struct pxa25x_udc *dev, struct usb_gadget_driver *driver)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /* don't disconnect drivers more than once */
|
|
|
+ if (dev->gadget.speed == USB_SPEED_UNKNOWN)
|
|
|
+ driver = NULL;
|
|
|
+ dev->gadget.speed = USB_SPEED_UNKNOWN;
|
|
|
+
|
|
|
+ /* prevent new request submissions, kill any outstanding requests */
|
|
|
+ for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) {
|
|
|
+ struct pxa25x_ep *ep = &dev->ep[i];
|
|
|
+
|
|
|
+ ep->stopped = 1;
|
|
|
+ nuke(ep, -ESHUTDOWN);
|
|
|
+ }
|
|
|
+ del_timer_sync(&dev->timer);
|
|
|
+
|
|
|
+ /* report reset; the driver is already quiesced */
|
|
|
+ if (driver)
|
|
|
+ usb_gadget_udc_reset(&dev->gadget, driver);
|
|
|
+
|
|
|
+ /* re-init driver-visible data structures */
|
|
|
+ udc_reinit(dev);
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver)
|
|
|
{
|
|
@@ -1721,7 +1748,7 @@ pxa25x_udc_irq(int irq, void *_dev)
|
|
|
/* reset driver and endpoints,
|
|
|
* in case that's not yet done
|
|
|
*/
|
|
|
- stop_activity (dev, dev->driver);
|
|
|
+ reset_gadget(dev, dev->driver);
|
|
|
|
|
|
} else {
|
|
|
DBG(DBG_VERBOSE, "USB reset end\n");
|