Index: usb-devel/drivers/usb/gadget/udc/core.c =================================================================== --- usb-devel.orig/drivers/usb/gadget/udc/core.c +++ usb-devel/drivers/usb/gadget/udc/core.c @@ -1197,7 +1197,9 @@ EXPORT_SYMBOL_GPL(usb_udc_vbus_handler); void usb_gadget_udc_reset(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { + dev_info(&gadget->dev, "Reset #1, gadget %p driver %p\n", gadget, driver); driver->reset(gadget); + dev_info(&gadget->dev, "Reset #2\n"); usb_gadget_set_state(gadget, USB_STATE_DEFAULT); } EXPORT_SYMBOL_GPL(usb_gadget_udc_reset); Index: usb-devel/drivers/usb/gadget/udc/dummy_hcd.c =================================================================== --- usb-devel.orig/drivers/usb/gadget/udc/dummy_hcd.c +++ usb-devel/drivers/usb/gadget/udc/dummy_hcd.c @@ -464,7 +464,9 @@ static void set_link_state(struct dummy_ if (dum->ints_enabled && (disconnect || reset)) { stop_activity(dum); ++dum->callback_usage; + dev_info(&dum->gadget.dev, "Reset usage %d\n", dum->callback_usage); spin_unlock(&dum->lock); + udelay(1000); if (reset) usb_gadget_udc_reset(&dum->gadget, dum->driver); else @@ -906,23 +908,9 @@ static int dummy_pullup(struct usb_gadge dum_hcd = gadget_to_dummy_hcd(_gadget); spin_lock_irqsave(&dum->lock, flags); + dev_info(&_gadget->dev, "Dummy pullup %d\n", value); dum->pullup = (value != 0); set_link_state(dum_hcd); - if (value == 0) { - /* - * Emulate synchronize_irq(): wait for callbacks to finish. - * This seems to be the best place to emulate the call to - * synchronize_irq() that's in usb_gadget_remove_driver(). - * Doing it in dummy_udc_stop() would be too late since it - * is called after the unbind callback and unbind shouldn't - * be invoked until all the other callbacks are finished. - */ - while (dum->callback_usage > 0) { - spin_unlock_irqrestore(&dum->lock, flags); - usleep_range(1000, 2000); - spin_lock_irqsave(&dum->lock, flags); - } - } spin_unlock_irqrestore(&dum->lock, flags); usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum_hcd)); @@ -945,6 +933,25 @@ static void dummy_udc_async_callbacks(st spin_lock_irq(&dum->lock); dum->ints_enabled = enable; + dev_info(&_gadget->dev, "Dummy ints_enabled %d\n", enable); + if (!enable) { + /* + * Emulate synchronize_irq(): wait for callbacks to finish. + * This seems to be the best place to emulate the call to + * synchronize_irq() that's in usb_gadget_remove_driver(). + * It has to come after dum->ints_enabled is clear. But + * doing it in dummy_udc_stop() would be too late since that + * routine is called after the unbind callback, and unbind + * shouldn't be invoked until all the other callbacks are + * finished. + */ + while (dum->callback_usage > 0) { + spin_unlock_irq(&dum->lock); + usleep_range(1000, 2000); + spin_lock_irq(&dum->lock); + } + dev_info(&_gadget->dev, "Disable done\n"); + } spin_unlock_irq(&dum->lock); } @@ -1020,6 +1027,7 @@ static int dummy_udc_start(struct usb_ga spin_lock_irq(&dum->lock); dum->devstatus = 0; dum->driver = driver; + dev_info(&g->dev, "Dummy start\n"); spin_unlock_irq(&dum->lock); return 0; @@ -1034,6 +1042,7 @@ static int dummy_udc_stop(struct usb_gad dum->ints_enabled = 0; stop_activity(dum); dum->driver = NULL; + dev_info(&g->dev, "Dummy stop\n"); spin_unlock_irq(&dum->lock); return 0;