aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-08-24 15:42:24 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-10-12 17:55:23 -0400
commit4a00027dcb088bf90fa8fb14a7e8ba3506d78f22 (patch)
tree992b3dbda7b950b8906ac4751e43a28fd15e2e5d /drivers/usb/host
parent9347d51c52afcf1a77d2104f162cf8a085624c83 (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>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ehci-q.c3
-rw-r--r--drivers/usb/host/isp116x-hcd.c15
-rw-r--r--drivers/usb/host/ohci-q.c3
-rw-r--r--drivers/usb/host/r8a66597-hcd.c8
-rw-r--r--drivers/usb/host/sl811-hcd.c3
-rw-r--r--drivers/usb/host/u132-hcd.c36
-rw-r--r--drivers/usb/host/uhci-hcd.h15
-rw-r--r--drivers/usb/host/uhci-q.c12
8 files changed, 32 insertions, 63 deletions
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*/
279static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, 279static 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 */
1482static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, 1482static 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 }