diff options
author | David Vrabel <david.vrabel@csr.com> | 2009-06-24 13:26:40 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-23 09:46:21 -0400 |
commit | 831baa4915de465357b25c471bbb9b36472024df (patch) | |
tree | b28e8365e77defb84ba1437993b64be753274ead /drivers/usb/host/whci/hcd.c | |
parent | 586dfc8cafc25cf785332fdfe9530f392e26f30d (diff) |
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 e019a5058ab8..687b622a1612 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, | |||
192 | struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); | 192 | struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); |
193 | struct whc *whc = wusbhc_to_whc(wusbhc); | 193 | struct whc *whc = wusbhc_to_whc(wusbhc); |
194 | struct whc_qset *qset; | 194 | struct whc_qset *qset; |
195 | unsigned long flags; | ||
196 | |||
197 | spin_lock_irqsave(&whc->lock, flags); | ||
195 | 198 | ||
196 | qset = ep->hcpriv; | 199 | qset = ep->hcpriv; |
197 | if (qset) { | 200 | if (qset) { |
198 | qset->remove = 1; | 201 | qset->remove = 1; |
202 | qset->reset = 1; | ||
199 | 203 | ||
200 | if (usb_endpoint_xfer_bulk(&ep->desc) | 204 | if (usb_endpoint_xfer_bulk(&ep->desc) |
201 | || usb_endpoint_xfer_control(&ep->desc)) | 205 | || usb_endpoint_xfer_control(&ep->desc)) |
202 | queue_work(whc->workqueue, &whc->async_work); | 206 | queue_work(whc->workqueue, &whc->async_work); |
203 | else | 207 | else |
204 | queue_work(whc->workqueue, &whc->periodic_work); | 208 | queue_work(whc->workqueue, &whc->periodic_work); |
205 | |||
206 | qset_reset(whc, qset); | ||
207 | } | 209 | } |
210 | |||
211 | spin_unlock_irqrestore(&whc->lock, flags); | ||
208 | } | 212 | } |
209 | 213 | ||
210 | 214 | ||