aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ohci-hcd.c')
-rw-r--r--drivers/usb/host/ohci-hcd.c32
1 files changed, 14 insertions, 18 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index d673cb9c36b1..6b06ab69938f 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -117,7 +117,6 @@ MODULE_PARM_DESC (no_handshake, "true (not default) disables BIOS handshake");
117 */ 117 */
118static int ohci_urb_enqueue ( 118static int ohci_urb_enqueue (
119 struct usb_hcd *hcd, 119 struct usb_hcd *hcd,
120 struct usb_host_endpoint *ep,
121 struct urb *urb, 120 struct urb *urb,
122 gfp_t mem_flags 121 gfp_t mem_flags
123) { 122) {
@@ -134,7 +133,7 @@ static int ohci_urb_enqueue (
134#endif 133#endif
135 134
136 /* every endpoint has a ed, locate and maybe (re)initialize it */ 135 /* every endpoint has a ed, locate and maybe (re)initialize it */
137 if (! (ed = ed_get (ohci, ep, urb->dev, pipe, urb->interval))) 136 if (! (ed = ed_get (ohci, urb->ep, urb->dev, pipe, urb->interval)))
138 return -ENOMEM; 137 return -ENOMEM;
139 138
140 /* for the private part of the URB we need the number of TDs (size) */ 139 /* for the private part of the URB we need the number of TDs (size) */
@@ -199,22 +198,17 @@ static int ohci_urb_enqueue (
199 retval = -ENODEV; 198 retval = -ENODEV;
200 goto fail; 199 goto fail;
201 } 200 }
202 201 retval = usb_hcd_link_urb_to_ep(hcd, urb);
203 /* in case of unlink-during-submit */ 202 if (retval)
204 spin_lock (&urb->lock);
205 if (urb->status != -EINPROGRESS) {
206 spin_unlock (&urb->lock);
207 urb->hcpriv = urb_priv;
208 finish_urb (ohci, urb);
209 retval = 0;
210 goto fail; 203 goto fail;
211 }
212 204
213 /* schedule the ed if needed */ 205 /* schedule the ed if needed */
214 if (ed->state == ED_IDLE) { 206 if (ed->state == ED_IDLE) {
215 retval = ed_schedule (ohci, ed); 207 retval = ed_schedule (ohci, ed);
216 if (retval < 0) 208 if (retval < 0) {
217 goto fail0; 209 usb_hcd_unlink_urb_from_ep(hcd, urb);
210 goto fail;
211 }
218 if (ed->type == PIPE_ISOCHRONOUS) { 212 if (ed->type == PIPE_ISOCHRONOUS) {
219 u16 frame = ohci_frame_no(ohci); 213 u16 frame = ohci_frame_no(ohci);
220 214
@@ -238,8 +232,6 @@ static int ohci_urb_enqueue (
238 urb->hcpriv = urb_priv; 232 urb->hcpriv = urb_priv;
239 td_submit_urb (ohci, urb); 233 td_submit_urb (ohci, urb);
240 234
241fail0:
242 spin_unlock (&urb->lock);
243fail: 235fail:
244 if (retval) 236 if (retval)
245 urb_free_priv (ohci, urb_priv); 237 urb_free_priv (ohci, urb_priv);
@@ -253,17 +245,21 @@ fail:
253 * asynchronously, and we might be dealing with an urb that's 245 * asynchronously, and we might be dealing with an urb that's
254 * partially transferred, or an ED with other urbs being unlinked. 246 * partially transferred, or an ED with other urbs being unlinked.
255 */ 247 */
256static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) 248static int ohci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
257{ 249{
258 struct ohci_hcd *ohci = hcd_to_ohci (hcd); 250 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
259 unsigned long flags; 251 unsigned long flags;
252 int rc;
260 253
261#ifdef OHCI_VERBOSE_DEBUG 254#ifdef OHCI_VERBOSE_DEBUG
262 urb_print (urb, "UNLINK", 1); 255 urb_print (urb, "UNLINK", 1);
263#endif 256#endif
264 257
265 spin_lock_irqsave (&ohci->lock, flags); 258 spin_lock_irqsave (&ohci->lock, flags);
266 if (HC_IS_RUNNING(hcd->state)) { 259 rc = usb_hcd_check_unlink_urb(hcd, urb, status);
260 if (rc) {
261 ; /* Do nothing */
262 } else if (HC_IS_RUNNING(hcd->state)) {
267 urb_priv_t *urb_priv; 263 urb_priv_t *urb_priv;
268 264
269 /* Unless an IRQ completed the unlink while it was being 265 /* Unless an IRQ completed the unlink while it was being
@@ -284,7 +280,7 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
284 finish_urb (ohci, urb); 280 finish_urb (ohci, urb);
285 } 281 }
286 spin_unlock_irqrestore (&ohci->lock, flags); 282 spin_unlock_irqrestore (&ohci->lock, flags);
287 return 0; 283 return rc;
288} 284}
289 285
290/*-------------------------------------------------------------------------*/ 286/*-------------------------------------------------------------------------*/