diff options
Diffstat (limited to 'drivers/usb/host/ohci-hcd.c')
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 32 |
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 | */ |
118 | static int ohci_urb_enqueue ( | 118 | static 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 | ||
241 | fail0: | ||
242 | spin_unlock (&urb->lock); | ||
243 | fail: | 235 | fail: |
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 | */ |
256 | static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | 248 | static 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 | /*-------------------------------------------------------------------------*/ |