From 4a00027dcb088bf90fa8fb14a7e8ba3506d78f22 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 24 Aug 2007 15:42:24 -0400 Subject: 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 CC: David Brownell CC: Olav Kongas CC: Yoshihiro Shimoda CC: Tony Olech Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-q.c | 3 +-- drivers/usb/host/isp116x-hcd.c | 15 +++++---------- drivers/usb/host/ohci-q.c | 3 +-- drivers/usb/host/r8a66597-hcd.c | 8 +++----- drivers/usb/host/sl811-hcd.c | 3 +-- drivers/usb/host/u132-hcd.c | 36 +++++++++++++++++------------------- drivers/usb/host/uhci-hcd.h | 15 --------------- drivers/usb/host/uhci-q.c | 12 ++++-------- 8 files changed, 32 insertions(+), 63 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 794d27e0780..b10f39c047e 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -256,8 +256,7 @@ __acquires(ehci->lock) /* complete() can reenter this HCD */ usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); spin_unlock (&ehci->lock); - urb->status = status; - usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb); + usb_hcd_giveback_urb(ehci_to_hcd(ehci), urb, status); spin_lock (&ehci->lock); } diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 35b3507ff40..c27417f5b9d 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) processed urbs. */ static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, - struct urb *urb) + struct urb *urb, int status) __releases(isp116x->lock) __acquires(isp116x->lock) { unsigned i; @@ -291,7 +291,7 @@ __releases(isp116x->lock) __acquires(isp116x->lock) usb_hcd_unlink_urb_from_ep(isp116x_to_hcd(isp116x), urb); spin_unlock(&isp116x->lock); - usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb); + usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb, status); spin_lock(&isp116x->lock); /* take idle endpoints out of the schedule */ @@ -453,13 +453,8 @@ static void postproc_atl_queue(struct isp116x *isp116x) } done: - if (status != -EINPROGRESS) { - spin_lock(&urb->lock); - urb->status = status; - spin_unlock(&urb->lock); - } - if (urb->status != -EINPROGRESS || urb->unlinked) - finish_request(isp116x, ep, urb); + if (status != -EINPROGRESS || urb->unlinked) + finish_request(isp116x, ep, urb, status); } } @@ -853,7 +848,7 @@ static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, } if (urb) - finish_request(isp116x, ep, urb); + finish_request(isp116x, ep, urb, status); done: spin_unlock_irqrestore(&isp116x->lock, flags); return rc; diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 13d31edd1a8..51817322232 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -62,8 +62,7 @@ __acquires(ohci->lock) /* urb->complete() can reenter this HCD */ usb_hcd_unlink_urb_from_ep(ohci_to_hcd(ohci), urb); spin_unlock (&ohci->lock); - urb->status = status; - usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb); + usb_hcd_giveback_urb(ohci_to_hcd(ohci), urb, status); spin_lock (&ohci->lock); /* 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 fea6036771f..fd00f1e33fb 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) kfree(td); if (urb) { - urb->status = -ENODEV; usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb); spin_unlock(&r8a66597->lock); - usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb); + usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb, + -ENODEV); spin_lock(&r8a66597->lock); } break; @@ -1134,10 +1134,8 @@ __releases(r8a66597->lock) __acquires(r8a66597->lock) urb->start_frame = r8a66597_get_frame(hcd); usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb); - - urb->status = status; spin_unlock(&r8a66597->lock); - usb_hcd_giveback_urb(hcd, urb); + usb_hcd_giveback_urb(hcd, urb, status); spin_lock(&r8a66597->lock); } diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 515152809d3..94d859aa73f 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -436,9 +436,8 @@ static void finish_request( ep->nextpid = USB_PID_SETUP; usb_hcd_unlink_urb_from_ep(sl811_to_hcd(sl811), urb); - urb->status = status; spin_unlock(&sl811->lock); - usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb); + usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb, status); spin_lock(&sl811->lock); /* leave active endpoints in the schedule */ diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index db800a434b8..2b379a78d0d 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, unsigned long irqs; struct usb_hcd *hcd = u132_to_hcd(u132); urb->error_count = 0; - urb->status = status; spin_lock_irqsave(&endp->queue_lock.slock, irqs); usb_hcd_unlink_urb_from_ep(hcd, urb); endp->queue_next += 1; @@ -542,7 +541,7 @@ static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp, u132_ring_queue_work(u132, ring, 0); up(&u132->scheduler_lock); u132_endp_put_kref(u132, endp); - usb_hcd_giveback_urb(hcd, urb); + usb_hcd_giveback_urb(hcd, urb, status); return; } @@ -558,7 +557,6 @@ static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp, unsigned long irqs; struct usb_hcd *hcd = u132_to_hcd(u132); urb->error_count = 0; - urb->status = status; spin_lock_irqsave(&endp->queue_lock.slock, irqs); usb_hcd_unlink_urb_from_ep(hcd, urb); endp->queue_next += 1; @@ -575,7 +573,7 @@ static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp, endp->active = 0; spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); kfree(urbq); - } usb_hcd_giveback_urb(hcd, urb); + } usb_hcd_giveback_urb(hcd, urb, status); return; } @@ -719,7 +717,7 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, urb->status); + u132_hcd_giveback_urb(u132, endp, urb, 0); return; } } @@ -771,7 +769,7 @@ static void u132_hcd_bulk_output_sent(void *data, struct urb *urb, u8 *buf, dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, urb->status); + u132_hcd_giveback_urb(u132, endp, urb, 0); return; } } @@ -874,7 +872,7 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, urb->status); + u132_hcd_giveback_urb(u132, endp, urb, 0); return; } } @@ -911,7 +909,7 @@ static void u132_hcd_configure_empty_sent(void *data, struct urb *urb, u8 *buf, dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, urb->status); + u132_hcd_giveback_urb(u132, endp, urb, 0); return; } } @@ -983,7 +981,7 @@ static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, urb->status); + u132_hcd_giveback_urb(u132, endp, urb, 0); return; } } @@ -1020,7 +1018,7 @@ static void u132_hcd_configure_empty_recv(void *data, struct urb *urb, u8 *buf, dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, urb->status); + u132_hcd_giveback_urb(u132, endp, urb, 0); return; } } @@ -1080,7 +1078,7 @@ static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf, dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, urb->status); + u132_hcd_giveback_urb(u132, endp, urb, 0); return; } } @@ -1121,7 +1119,7 @@ static void u132_hcd_enumeration_empty_recv(void *data, struct urb *urb, dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, urb->status); + u132_hcd_giveback_urb(u132, endp, urb, 0); return; } } @@ -1165,7 +1163,7 @@ static void u132_hcd_enumeration_address_sent(void *data, struct urb *urb, dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, urb->status); + u132_hcd_giveback_urb(u132, endp, urb, 0); return; } } @@ -1202,7 +1200,7 @@ static void u132_hcd_initial_empty_sent(void *data, struct urb *urb, u8 *buf, dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, urb->status); + u132_hcd_giveback_urb(u132, endp, urb, 0); return; } } @@ -1254,7 +1252,7 @@ static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf, dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, urb->status); + u132_hcd_giveback_urb(u132, endp, urb, 0); return; } } @@ -1299,7 +1297,7 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " "unlinked=%d\n", urb, urb->unlinked); up(&u132->scheduler_lock); - u132_hcd_giveback_urb(u132, endp, urb, urb->status); + u132_hcd_giveback_urb(u132, endp, urb, 0); return; } } @@ -2428,7 +2426,7 @@ static int dequeue_from_overflow_chain(struct u132 *u132, list_del(scan); endp->queue_size -= 1; urb->error_count = 0; - usb_hcd_giveback_urb(hcd, urb); + usb_hcd_giveback_urb(hcd, urb, 0); return 0; } else continue; @@ -2472,7 +2470,7 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, return 0; } else { spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); - u132_hcd_abandon_urb(u132, endp, urb, urb->status); + u132_hcd_abandon_urb(u132, endp, urb, status); return 0; } } else { @@ -2513,7 +2511,7 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, irqs); kfree(urbq); } urb->error_count = 0; - usb_hcd_giveback_urb(hcd, urb); + usb_hcd_giveback_urb(hcd, urb, status); return 0; } else if (list_empty(&endp->urb_more)) { 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 e46d2b0203c..340d6ed3e6e 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h @@ -456,21 +456,6 @@ struct urb_priv { }; -/* - * Locking in uhci.c - * - * Almost everything relating to the hardware schedule and processing - * of URBs is protected by uhci->lock. urb->status is protected by - * urb->lock; that's the one exception. - * - * To prevent deadlocks, never lock uhci->lock while holding urb->lock. - * The safe order of locking is: - * - * #1 uhci->lock - * #2 urb->lock - */ - - /* Some special IDs */ #define PCI_VENDOR_ID_GENESYS 0x17a0 diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index bab56726655..e5d60d5b105 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -1480,7 +1480,7 @@ done: * Finish unlinking an URB and give it back */ static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, - struct urb *urb) + struct urb *urb, int status) __releases(uhci->lock) __acquires(uhci->lock) { @@ -1520,7 +1520,7 @@ __acquires(uhci->lock) usb_hcd_unlink_urb_from_ep(uhci_to_hcd(uhci), urb); spin_unlock(&uhci->lock); - usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); + usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb, status); spin_lock(&uhci->lock); /* 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) if (status == -EINPROGRESS) break; - spin_lock(&urb->lock); - urb->status = status; - spin_unlock(&urb->lock); - /* Dequeued but completed URBs can't be given back unless * the QH is stopped or has finished unlinking. */ if (urb->unlinked) { @@ -1569,7 +1565,7 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) return; } - uhci_giveback_urb(uhci, qh, urb); + uhci_giveback_urb(uhci, qh, urb, status); if (status < 0) break; } @@ -1594,7 +1590,7 @@ restart: qh->is_stopped = 0; return; } - uhci_giveback_urb(uhci, qh, urb); + uhci_giveback_urb(uhci, qh, urb, 0); goto restart; } } -- cgit v1.2.3