diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2007-08-24 15:42:24 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-12 17:55:23 -0400 |
commit | 4a00027dcb088bf90fa8fb14a7e8ba3506d78f22 (patch) | |
tree | 992b3dbda7b950b8906ac4751e43a28fd15e2e5d | |
parent | 9347d51c52afcf1a77d2104f162cf8a085624c83 (diff) |
USB: Eliminate urb->status usage!
This patch (as979) removes the last vestiges of urb->status from the
host controller drivers and the root-hub emulator. Now the field
doesn't get set until just before the URB's completion routine is
called.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: David Brownell <david-b@pacbell.net>
CC: Olav Kongas <ok@artecdesign.ee>
CC: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
CC: Tony Olech <tony.olech@elandigitalsystems.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/core/hcd.c | 22 | ||||
-rw-r--r-- | drivers/usb/core/hcd.h | 3 | ||||
-rw-r--r-- | drivers/usb/gadget/dummy_hcd.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/ehci-q.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/isp116x-hcd.c | 15 | ||||
-rw-r--r-- | drivers/usb/host/ohci-q.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/r8a66597-hcd.c | 8 | ||||
-rw-r--r-- | drivers/usb/host/sl811-hcd.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/u132-hcd.c | 36 | ||||
-rw-r--r-- | drivers/usb/host/uhci-hcd.h | 15 | ||||
-rw-r--r-- | drivers/usb/host/uhci-q.c | 12 |
11 files changed, 46 insertions, 77 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 4ac021e42cd8..1c5e5d35e08d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -532,7 +532,6 @@ error: | |||
532 | 532 | ||
533 | /* any errors get returned through the urb completion */ | 533 | /* any errors get returned through the urb completion */ |
534 | spin_lock_irq(&hcd_root_hub_lock); | 534 | spin_lock_irq(&hcd_root_hub_lock); |
535 | urb->status = status; | ||
536 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 535 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
537 | 536 | ||
538 | /* This peculiar use of spinlocks echoes what real HC drivers do. | 537 | /* This peculiar use of spinlocks echoes what real HC drivers do. |
@@ -540,7 +539,7 @@ error: | |||
540 | * RT-friendly. | 539 | * RT-friendly. |
541 | */ | 540 | */ |
542 | spin_unlock(&hcd_root_hub_lock); | 541 | spin_unlock(&hcd_root_hub_lock); |
543 | usb_hcd_giveback_urb(hcd, urb); | 542 | usb_hcd_giveback_urb(hcd, urb, status); |
544 | spin_lock(&hcd_root_hub_lock); | 543 | spin_lock(&hcd_root_hub_lock); |
545 | 544 | ||
546 | spin_unlock_irq(&hcd_root_hub_lock); | 545 | spin_unlock_irq(&hcd_root_hub_lock); |
@@ -578,13 +577,12 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd) | |||
578 | if (urb) { | 577 | if (urb) { |
579 | hcd->poll_pending = 0; | 578 | hcd->poll_pending = 0; |
580 | hcd->status_urb = NULL; | 579 | hcd->status_urb = NULL; |
581 | urb->status = 0; | ||
582 | urb->actual_length = length; | 580 | urb->actual_length = length; |
583 | memcpy(urb->transfer_buffer, buffer, length); | 581 | memcpy(urb->transfer_buffer, buffer, length); |
584 | 582 | ||
585 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 583 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
586 | spin_unlock(&hcd_root_hub_lock); | 584 | spin_unlock(&hcd_root_hub_lock); |
587 | usb_hcd_giveback_urb(hcd, urb); | 585 | usb_hcd_giveback_urb(hcd, urb, 0); |
588 | spin_lock(&hcd_root_hub_lock); | 586 | spin_lock(&hcd_root_hub_lock); |
589 | } else { | 587 | } else { |
590 | length = 0; | 588 | length = 0; |
@@ -677,7 +675,7 @@ static int usb_rh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
677 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 675 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
678 | 676 | ||
679 | spin_unlock(&hcd_root_hub_lock); | 677 | spin_unlock(&hcd_root_hub_lock); |
680 | usb_hcd_giveback_urb(hcd, urb); | 678 | usb_hcd_giveback_urb(hcd, urb, status); |
681 | spin_lock(&hcd_root_hub_lock); | 679 | spin_lock(&hcd_root_hub_lock); |
682 | } | 680 | } |
683 | } | 681 | } |
@@ -1252,6 +1250,7 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) | |||
1252 | * usb_hcd_giveback_urb - return URB from HCD to device driver | 1250 | * usb_hcd_giveback_urb - return URB from HCD to device driver |
1253 | * @hcd: host controller returning the URB | 1251 | * @hcd: host controller returning the URB |
1254 | * @urb: urb being returned to the USB device driver. | 1252 | * @urb: urb being returned to the USB device driver. |
1253 | * @status: completion status code for the URB. | ||
1255 | * Context: in_interrupt() | 1254 | * Context: in_interrupt() |
1256 | * | 1255 | * |
1257 | * This hands the URB from HCD to its USB device driver, using its | 1256 | * This hands the URB from HCD to its USB device driver, using its |
@@ -1260,25 +1259,26 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) | |||
1260 | * the device driver won't cause problems if it frees, modifies, | 1259 | * the device driver won't cause problems if it frees, modifies, |
1261 | * or resubmits this URB. | 1260 | * or resubmits this URB. |
1262 | * | 1261 | * |
1263 | * If @urb was unlinked, the value of @urb->status will be overridden by | 1262 | * If @urb was unlinked, the value of @status will be overridden by |
1264 | * @urb->unlinked. Erroneous short transfers are detected in case | 1263 | * @urb->unlinked. Erroneous short transfers are detected in case |
1265 | * the HCD hasn't checked for them. | 1264 | * the HCD hasn't checked for them. |
1266 | */ | 1265 | */ |
1267 | void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) | 1266 | void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) |
1268 | { | 1267 | { |
1269 | urb->hcpriv = NULL; | 1268 | urb->hcpriv = NULL; |
1270 | if (unlikely(urb->unlinked)) | 1269 | if (unlikely(urb->unlinked)) |
1271 | urb->status = urb->unlinked; | 1270 | status = urb->unlinked; |
1272 | else if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && | 1271 | else if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && |
1273 | urb->actual_length < urb->transfer_buffer_length && | 1272 | urb->actual_length < urb->transfer_buffer_length && |
1274 | !urb->status)) | 1273 | !status)) |
1275 | urb->status = -EREMOTEIO; | 1274 | status = -EREMOTEIO; |
1276 | 1275 | ||
1277 | unmap_urb_for_dma(hcd, urb); | 1276 | unmap_urb_for_dma(hcd, urb); |
1278 | usbmon_urb_complete(&hcd->self, urb, urb->status); | 1277 | usbmon_urb_complete(&hcd->self, urb, status); |
1279 | usb_unanchor_urb(urb); | 1278 | usb_unanchor_urb(urb); |
1280 | 1279 | ||
1281 | /* pass ownership to the completion handler */ | 1280 | /* pass ownership to the completion handler */ |
1281 | urb->status = status; | ||
1282 | urb->complete (urb); | 1282 | urb->complete (urb); |
1283 | atomic_dec (&urb->use_count); | 1283 | atomic_dec (&urb->use_count); |
1284 | if (unlikely (urb->reject)) | 1284 | if (unlikely (urb->reject)) |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 729b7a03acd8..0fc7b95259f5 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -217,7 +217,8 @@ extern void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb); | |||
217 | 217 | ||
218 | extern int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags); | 218 | extern int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags); |
219 | extern int usb_hcd_unlink_urb (struct urb *urb, int status); | 219 | extern int usb_hcd_unlink_urb (struct urb *urb, int status); |
220 | extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb); | 220 | extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, |
221 | int status); | ||
221 | extern void usb_hcd_endpoint_disable (struct usb_device *udev, | 222 | extern void usb_hcd_endpoint_disable (struct usb_device *udev, |
222 | struct usb_host_endpoint *ep); | 223 | struct usb_host_endpoint *ep); |
223 | extern int usb_hcd_get_frame_number (struct usb_device *udev); | 224 | extern int usb_hcd_get_frame_number (struct usb_device *udev); |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index c1af7bab26f0..58e4d7208805 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -1511,8 +1511,7 @@ return_urb: | |||
1511 | 1511 | ||
1512 | usb_hcd_unlink_urb_from_ep(dummy_to_hcd(dum), urb); | 1512 | usb_hcd_unlink_urb_from_ep(dummy_to_hcd(dum), urb); |
1513 | spin_unlock (&dum->lock); | 1513 | spin_unlock (&dum->lock); |
1514 | urb->status = status; | 1514 | usb_hcd_giveback_urb(dummy_to_hcd(dum), urb, status); |
1515 | usb_hcd_giveback_urb (dummy_to_hcd(dum), urb); | ||
1516 | spin_lock (&dum->lock); | 1515 | spin_lock (&dum->lock); |
1517 | 1516 | ||
1518 | goto restart; | 1517 | goto restart; |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 794d27e07807..b10f39c047e9 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -256,8 +256,7 @@ __acquires(ehci->lock) | |||
256 | /* complete() can reenter this HCD */ | 256 | /* complete() can reenter this HCD */ |
257 | usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); | 257 | usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); |
258 | spin_unlock (&ehci->lock); | 258 | spin_unlock (&ehci->lock); |
259 | urb->status = status; | 259 | usb_hcd_giveback_urb(ehci_to_hcd(ehci), urb, status); |
260 | usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb); | ||
261 | spin_lock (&ehci->lock); | 260 | spin_lock (&ehci->lock); |
262 | } | 261 | } |
263 | 262 | ||
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 35b3507ff401..c27417f5b9d8 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -277,7 +277,7 @@ static void preproc_atl_queue(struct isp116x *isp116x) | |||
277 | processed urbs. | 277 | processed urbs. |
278 | */ | 278 | */ |
279 | static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, | 279 | static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, |
280 | struct urb *urb) | 280 | struct urb *urb, int status) |
281 | __releases(isp116x->lock) __acquires(isp116x->lock) | 281 | __releases(isp116x->lock) __acquires(isp116x->lock) |
282 | { | 282 | { |
283 | unsigned i; | 283 | unsigned i; |
@@ -291,7 +291,7 @@ __releases(isp116x->lock) __acquires(isp116x->lock) | |||
291 | 291 | ||
292 | usb_hcd_unlink_urb_from_ep(isp116x_to_hcd(isp116x), urb); | 292 | usb_hcd_unlink_urb_from_ep(isp116x_to_hcd(isp116x), urb); |
293 | spin_unlock(&isp116x->lock); | 293 | spin_unlock(&isp116x->lock); |
294 | usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb); | 294 | usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb, status); |
295 | spin_lock(&isp116x->lock); | 295 | spin_lock(&isp116x->lock); |
296 | 296 | ||
297 | /* take idle endpoints out of the schedule */ | 297 | /* take idle endpoints out of the schedule */ |
@@ -453,13 +453,8 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
453 | } | 453 | } |
454 | 454 | ||
455 | done: | 455 | done: |
456 | if (status != -EINPROGRESS) { | 456 | if (status != -EINPROGRESS || urb->unlinked) |
457 | spin_lock(&urb->lock); | 457 | finish_request(isp116x, ep, urb, status); |
458 | urb->status = status; | ||
459 | spin_unlock(&urb->lock); | ||
460 | } | ||
461 | if (urb->status != -EINPROGRESS || urb->unlinked) | ||
462 | finish_request(isp116x, ep, urb); | ||
463 | } | 458 | } |
464 | } | 459 | } |
465 | 460 | ||
@@ -853,7 +848,7 @@ static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, | |||
853 | } | 848 | } |
854 | 849 | ||
855 | if (urb) | 850 | if (urb) |
856 | finish_request(isp116x, ep, urb); | 851 | finish_request(isp116x, ep, urb, status); |
857 | done: | 852 | done: |
858 | spin_unlock_irqrestore(&isp116x->lock, flags); | 853 | spin_unlock_irqrestore(&isp116x->lock, flags); |
859 | return rc; | 854 | return rc; |
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 13d31edd1a86..51817322232b 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
@@ -62,8 +62,7 @@ __acquires(ohci->lock) | |||
62 | /* urb->complete() can reenter this HCD */ | 62 | /* urb->complete() can reenter this HCD */ |
63 | usb_hcd_unlink_urb_from_ep(ohci_to_hcd(ohci), urb); | 63 | usb_hcd_unlink_urb_from_ep(ohci_to_hcd(ohci), urb); |
64 | spin_unlock (&ohci->lock); | 64 | spin_unlock (&ohci->lock); |
65 | urb->status = status; | 65 | usb_hcd_giveback_urb(ohci_to_hcd(ohci), urb, status); |
66 | usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb); | ||
67 | spin_lock (&ohci->lock); | 66 | spin_lock (&ohci->lock); |
68 | 67 | ||
69 | /* stop periodic dma if it's not needed */ | 68 | /* stop periodic dma if it's not needed */ |
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index fea6036771f6..fd00f1e33fb5 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -782,12 +782,12 @@ static void force_dequeue(struct r8a66597 *r8a66597, u16 pipenum, u16 address) | |||
782 | kfree(td); | 782 | kfree(td); |
783 | 783 | ||
784 | if (urb) { | 784 | if (urb) { |
785 | urb->status = -ENODEV; | ||
786 | usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), | 785 | usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), |
787 | urb); | 786 | urb); |
788 | 787 | ||
789 | spin_unlock(&r8a66597->lock); | 788 | spin_unlock(&r8a66597->lock); |
790 | usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb); | 789 | usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb, |
790 | -ENODEV); | ||
791 | spin_lock(&r8a66597->lock); | 791 | spin_lock(&r8a66597->lock); |
792 | } | 792 | } |
793 | break; | 793 | break; |
@@ -1134,10 +1134,8 @@ __releases(r8a66597->lock) __acquires(r8a66597->lock) | |||
1134 | urb->start_frame = r8a66597_get_frame(hcd); | 1134 | urb->start_frame = r8a66597_get_frame(hcd); |
1135 | 1135 | ||
1136 | usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb); | 1136 | usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb); |
1137 | |||
1138 | urb->status = status; | ||
1139 | spin_unlock(&r8a66597->lock); | 1137 | spin_unlock(&r8a66597->lock); |
1140 | usb_hcd_giveback_urb(hcd, urb); | 1138 | usb_hcd_giveback_urb(hcd, urb, status); |
1141 | spin_lock(&r8a66597->lock); | 1139 | spin_lock(&r8a66597->lock); |
1142 | } | 1140 | } |
1143 | 1141 | ||
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 515152809d37..94d859aa73f8 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -436,9 +436,8 @@ static void finish_request( | |||
436 | ep->nextpid = USB_PID_SETUP; | 436 | ep->nextpid = USB_PID_SETUP; |
437 | 437 | ||
438 | usb_hcd_unlink_urb_from_ep(sl811_to_hcd(sl811), urb); | 438 | usb_hcd_unlink_urb_from_ep(sl811_to_hcd(sl811), urb); |
439 | urb->status = status; | ||
440 | spin_unlock(&sl811->lock); | 439 | spin_unlock(&sl811->lock); |
441 | usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb); | 440 | usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb, status); |
442 | spin_lock(&sl811->lock); | 441 | spin_lock(&sl811->lock); |
443 | 442 | ||
444 | /* leave active endpoints in the schedule */ | 443 | /* leave active endpoints in the schedule */ |
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index db800a434b83..2b379a78d0d5 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c | |||
@@ -518,7 +518,6 @@ static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp, | |||
518 | unsigned long irqs; | 518 | unsigned long irqs; |
519 | struct usb_hcd *hcd = u132_to_hcd(u132); | 519 | struct usb_hcd *hcd = u132_to_hcd(u132); |
520 | urb->error_count = 0; | 520 | urb->error_count = 0; |
521 | urb->status = status; | ||
522 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | 521 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); |
523 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 522 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
524 | endp->queue_next += 1; | 523 | endp->queue_next += 1; |
@@ -542,7 +541,7 @@ static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp, | |||
542 | u132_ring_queue_work(u132, ring, 0); | 541 | u132_ring_queue_work(u132, ring, 0); |
543 | up(&u132->scheduler_lock); | 542 | up(&u132->scheduler_lock); |
544 | u132_endp_put_kref(u132, endp); | 543 | u132_endp_put_kref(u132, endp); |
545 | usb_hcd_giveback_urb(hcd, urb); | 544 | usb_hcd_giveback_urb(hcd, urb, status); |
546 | return; | 545 | return; |
547 | } | 546 | } |
548 | 547 | ||
@@ -558,7 +557,6 @@ static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp, | |||
558 | unsigned long irqs; | 557 | unsigned long irqs; |
559 | struct usb_hcd *hcd = u132_to_hcd(u132); | 558 | struct usb_hcd *hcd = u132_to_hcd(u132); |
560 | urb->error_count = 0; | 559 | urb->error_count = 0; |
561 | urb->status = status; | ||
562 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | 560 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); |
563 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 561 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
564 | endp->queue_next += 1; | 562 | endp->queue_next += 1; |
@@ -575,7 +573,7 @@ static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp, | |||
575 | endp->active = 0; | 573 | endp->active = 0; |
576 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 574 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
577 | kfree(urbq); | 575 | kfree(urbq); |
578 | } usb_hcd_giveback_urb(hcd, urb); | 576 | } usb_hcd_giveback_urb(hcd, urb, status); |
579 | return; | 577 | return; |
580 | } | 578 | } |
581 | 579 | ||
@@ -719,7 +717,7 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, | |||
719 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " | 717 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
720 | "unlinked=%d\n", urb, urb->unlinked); | 718 | "unlinked=%d\n", urb, urb->unlinked); |
721 | up(&u132->scheduler_lock); | 719 | up(&u132->scheduler_lock); |
722 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 720 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
723 | return; | 721 | return; |
724 | } | 722 | } |
725 | } | 723 | } |
@@ -771,7 +769,7 @@ static void u132_hcd_bulk_output_sent(void *data, struct urb *urb, u8 *buf, | |||
771 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " | 769 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
772 | "unlinked=%d\n", urb, urb->unlinked); | 770 | "unlinked=%d\n", urb, urb->unlinked); |
773 | up(&u132->scheduler_lock); | 771 | up(&u132->scheduler_lock); |
774 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 772 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
775 | return; | 773 | return; |
776 | } | 774 | } |
777 | } | 775 | } |
@@ -874,7 +872,7 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, | |||
874 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " | 872 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
875 | "unlinked=%d\n", urb, urb->unlinked); | 873 | "unlinked=%d\n", urb, urb->unlinked); |
876 | up(&u132->scheduler_lock); | 874 | up(&u132->scheduler_lock); |
877 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 875 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
878 | return; | 876 | return; |
879 | } | 877 | } |
880 | } | 878 | } |
@@ -911,7 +909,7 @@ static void u132_hcd_configure_empty_sent(void *data, struct urb *urb, u8 *buf, | |||
911 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " | 909 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
912 | "unlinked=%d\n", urb, urb->unlinked); | 910 | "unlinked=%d\n", urb, urb->unlinked); |
913 | up(&u132->scheduler_lock); | 911 | up(&u132->scheduler_lock); |
914 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 912 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
915 | return; | 913 | return; |
916 | } | 914 | } |
917 | } | 915 | } |
@@ -983,7 +981,7 @@ static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, | |||
983 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " | 981 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
984 | "unlinked=%d\n", urb, urb->unlinked); | 982 | "unlinked=%d\n", urb, urb->unlinked); |
985 | up(&u132->scheduler_lock); | 983 | up(&u132->scheduler_lock); |
986 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 984 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
987 | return; | 985 | return; |
988 | } | 986 | } |
989 | } | 987 | } |
@@ -1020,7 +1018,7 @@ static void u132_hcd_configure_empty_recv(void *data, struct urb *urb, u8 *buf, | |||
1020 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " | 1018 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1021 | "unlinked=%d\n", urb, urb->unlinked); | 1019 | "unlinked=%d\n", urb, urb->unlinked); |
1022 | up(&u132->scheduler_lock); | 1020 | up(&u132->scheduler_lock); |
1023 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1021 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1024 | return; | 1022 | return; |
1025 | } | 1023 | } |
1026 | } | 1024 | } |
@@ -1080,7 +1078,7 @@ static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1080 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " | 1078 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1081 | "unlinked=%d\n", urb, urb->unlinked); | 1079 | "unlinked=%d\n", urb, urb->unlinked); |
1082 | up(&u132->scheduler_lock); | 1080 | up(&u132->scheduler_lock); |
1083 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1081 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1084 | return; | 1082 | return; |
1085 | } | 1083 | } |
1086 | } | 1084 | } |
@@ -1121,7 +1119,7 @@ static void u132_hcd_enumeration_empty_recv(void *data, struct urb *urb, | |||
1121 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " | 1119 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1122 | "unlinked=%d\n", urb, urb->unlinked); | 1120 | "unlinked=%d\n", urb, urb->unlinked); |
1123 | up(&u132->scheduler_lock); | 1121 | up(&u132->scheduler_lock); |
1124 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1122 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1125 | return; | 1123 | return; |
1126 | } | 1124 | } |
1127 | } | 1125 | } |
@@ -1165,7 +1163,7 @@ static void u132_hcd_enumeration_address_sent(void *data, struct urb *urb, | |||
1165 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " | 1163 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1166 | "unlinked=%d\n", urb, urb->unlinked); | 1164 | "unlinked=%d\n", urb, urb->unlinked); |
1167 | up(&u132->scheduler_lock); | 1165 | up(&u132->scheduler_lock); |
1168 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1166 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1169 | return; | 1167 | return; |
1170 | } | 1168 | } |
1171 | } | 1169 | } |
@@ -1202,7 +1200,7 @@ static void u132_hcd_initial_empty_sent(void *data, struct urb *urb, u8 *buf, | |||
1202 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " | 1200 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1203 | "unlinked=%d\n", urb, urb->unlinked); | 1201 | "unlinked=%d\n", urb, urb->unlinked); |
1204 | up(&u132->scheduler_lock); | 1202 | up(&u132->scheduler_lock); |
1205 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1203 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1206 | return; | 1204 | return; |
1207 | } | 1205 | } |
1208 | } | 1206 | } |
@@ -1254,7 +1252,7 @@ static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf, | |||
1254 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " | 1252 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1255 | "unlinked=%d\n", urb, urb->unlinked); | 1253 | "unlinked=%d\n", urb, urb->unlinked); |
1256 | up(&u132->scheduler_lock); | 1254 | up(&u132->scheduler_lock); |
1257 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1255 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1258 | return; | 1256 | return; |
1259 | } | 1257 | } |
1260 | } | 1258 | } |
@@ -1299,7 +1297,7 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1299 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " | 1297 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1300 | "unlinked=%d\n", urb, urb->unlinked); | 1298 | "unlinked=%d\n", urb, urb->unlinked); |
1301 | up(&u132->scheduler_lock); | 1299 | up(&u132->scheduler_lock); |
1302 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1300 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1303 | return; | 1301 | return; |
1304 | } | 1302 | } |
1305 | } | 1303 | } |
@@ -2428,7 +2426,7 @@ static int dequeue_from_overflow_chain(struct u132 *u132, | |||
2428 | list_del(scan); | 2426 | list_del(scan); |
2429 | endp->queue_size -= 1; | 2427 | endp->queue_size -= 1; |
2430 | urb->error_count = 0; | 2428 | urb->error_count = 0; |
2431 | usb_hcd_giveback_urb(hcd, urb); | 2429 | usb_hcd_giveback_urb(hcd, urb, 0); |
2432 | return 0; | 2430 | return 0; |
2433 | } else | 2431 | } else |
2434 | continue; | 2432 | continue; |
@@ -2472,7 +2470,7 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2472 | return 0; | 2470 | return 0; |
2473 | } else { | 2471 | } else { |
2474 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 2472 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
2475 | u132_hcd_abandon_urb(u132, endp, urb, urb->status); | 2473 | u132_hcd_abandon_urb(u132, endp, urb, status); |
2476 | return 0; | 2474 | return 0; |
2477 | } | 2475 | } |
2478 | } else { | 2476 | } else { |
@@ -2513,7 +2511,7 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2513 | irqs); | 2511 | irqs); |
2514 | kfree(urbq); | 2512 | kfree(urbq); |
2515 | } urb->error_count = 0; | 2513 | } urb->error_count = 0; |
2516 | usb_hcd_giveback_urb(hcd, urb); | 2514 | usb_hcd_giveback_urb(hcd, urb, status); |
2517 | return 0; | 2515 | return 0; |
2518 | } else if (list_empty(&endp->urb_more)) { | 2516 | } else if (list_empty(&endp->urb_more)) { |
2519 | dev_err(&u132->platform_dev->dev, "urb=%p not found in " | 2517 | dev_err(&u132->platform_dev->dev, "urb=%p not found in " |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index e46d2b0203cb..340d6ed3e6e9 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -456,21 +456,6 @@ struct urb_priv { | |||
456 | }; | 456 | }; |
457 | 457 | ||
458 | 458 | ||
459 | /* | ||
460 | * Locking in uhci.c | ||
461 | * | ||
462 | * Almost everything relating to the hardware schedule and processing | ||
463 | * of URBs is protected by uhci->lock. urb->status is protected by | ||
464 | * urb->lock; that's the one exception. | ||
465 | * | ||
466 | * To prevent deadlocks, never lock uhci->lock while holding urb->lock. | ||
467 | * The safe order of locking is: | ||
468 | * | ||
469 | * #1 uhci->lock | ||
470 | * #2 urb->lock | ||
471 | */ | ||
472 | |||
473 | |||
474 | /* Some special IDs */ | 459 | /* Some special IDs */ |
475 | 460 | ||
476 | #define PCI_VENDOR_ID_GENESYS 0x17a0 | 461 | #define PCI_VENDOR_ID_GENESYS 0x17a0 |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index bab567266559..e5d60d5b105a 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -1480,7 +1480,7 @@ done: | |||
1480 | * Finish unlinking an URB and give it back | 1480 | * Finish unlinking an URB and give it back |
1481 | */ | 1481 | */ |
1482 | static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, | 1482 | static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, |
1483 | struct urb *urb) | 1483 | struct urb *urb, int status) |
1484 | __releases(uhci->lock) | 1484 | __releases(uhci->lock) |
1485 | __acquires(uhci->lock) | 1485 | __acquires(uhci->lock) |
1486 | { | 1486 | { |
@@ -1520,7 +1520,7 @@ __acquires(uhci->lock) | |||
1520 | usb_hcd_unlink_urb_from_ep(uhci_to_hcd(uhci), urb); | 1520 | usb_hcd_unlink_urb_from_ep(uhci_to_hcd(uhci), urb); |
1521 | 1521 | ||
1522 | spin_unlock(&uhci->lock); | 1522 | spin_unlock(&uhci->lock); |
1523 | usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); | 1523 | usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb, status); |
1524 | spin_lock(&uhci->lock); | 1524 | spin_lock(&uhci->lock); |
1525 | 1525 | ||
1526 | /* If the queue is now empty, we can unlink the QH and give up its | 1526 | /* If the queue is now empty, we can unlink the QH and give up its |
@@ -1556,10 +1556,6 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
1556 | if (status == -EINPROGRESS) | 1556 | if (status == -EINPROGRESS) |
1557 | break; | 1557 | break; |
1558 | 1558 | ||
1559 | spin_lock(&urb->lock); | ||
1560 | urb->status = status; | ||
1561 | spin_unlock(&urb->lock); | ||
1562 | |||
1563 | /* Dequeued but completed URBs can't be given back unless | 1559 | /* Dequeued but completed URBs can't be given back unless |
1564 | * the QH is stopped or has finished unlinking. */ | 1560 | * the QH is stopped or has finished unlinking. */ |
1565 | if (urb->unlinked) { | 1561 | if (urb->unlinked) { |
@@ -1569,7 +1565,7 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
1569 | return; | 1565 | return; |
1570 | } | 1566 | } |
1571 | 1567 | ||
1572 | uhci_giveback_urb(uhci, qh, urb); | 1568 | uhci_giveback_urb(uhci, qh, urb, status); |
1573 | if (status < 0) | 1569 | if (status < 0) |
1574 | break; | 1570 | break; |
1575 | } | 1571 | } |
@@ -1594,7 +1590,7 @@ restart: | |||
1594 | qh->is_stopped = 0; | 1590 | qh->is_stopped = 0; |
1595 | return; | 1591 | return; |
1596 | } | 1592 | } |
1597 | uhci_giveback_urb(uhci, qh, urb); | 1593 | uhci_giveback_urb(uhci, qh, urb, 0); |
1598 | goto restart; | 1594 | goto restart; |
1599 | } | 1595 | } |
1600 | } | 1596 | } |