aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/whci/hcd.c
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@csr.com>2009-06-24 13:26:40 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 09:46:21 -0400
commit831baa4915de465357b25c471bbb9b36472024df (patch)
treeb28e8365e77defb84ba1437993b64be753274ead /drivers/usb/host/whci/hcd.c
parent586dfc8cafc25cf785332fdfe9530f392e26f30d (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.c8
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