diff options
author | David Vrabel <david.vrabel@csr.com> | 2009-06-24 17:26:40 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-23 13:46:21 (GMT) |
commit | 831baa4915de465357b25c471bbb9b36472024df (patch) | |
tree | b28e8365e77defb84ba1437993b64be753274ead /drivers/usb/host/whci/hcd.c | |
parent | 586dfc8cafc25cf785332fdfe9530f392e26f30d (diff) | |
download | linux-831baa4915de465357b25c471bbb9b36472024df.tar.xz |
USB: whci-hcd: make endpoint_reset method async
usb_hcd_endpoint_reset() may be called in atomic context and must not
sleep. So make whci-hcd's endpoint_reset() asynchronous. URBs
submitted while the reset is in progress will be queued (on the std
list) and transfers will resume once the reset is complete.
Signed-off-by: David Vrabel <david.vrabel@csr.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/whci/hcd.c')
-rw-r--r-- | drivers/usb/host/whci/hcd.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c index e019a50..687b622 100644 --- a/drivers/usb/host/whci/hcd.c +++ b/drivers/usb/host/whci/hcd.c @@ -192,19 +192,23 @@ static void whc_endpoint_reset(struct usb_hcd *usb_hcd, struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); struct whc *whc = wusbhc_to_whc(wusbhc); struct whc_qset *qset; + unsigned long flags; + + spin_lock_irqsave(&whc->lock, flags); qset = ep->hcpriv; if (qset) { qset->remove = 1; + qset->reset = 1; if (usb_endpoint_xfer_bulk(&ep->desc) || usb_endpoint_xfer_control(&ep->desc)) queue_work(whc->workqueue, &whc->async_work); else queue_work(whc->workqueue, &whc->periodic_work); - - qset_reset(whc, qset); } + + spin_unlock_irqrestore(&whc->lock, flags); } |