ChangeSet 1.994.1.4, 2003/03/28 14:16:39-08:00, david-b@pacbell.net [PATCH] USB: ehci-hcd, minor hardware tweaks This tweaks the hardware in two minor ways, being more forgiving of what are either hardware bugs or hard-to-see driver bugs. - Some silicon seems to mis-handle dummy qtds on occasion, writing them into the qh and thus stopping progress unless something times it out and cancels it (scsi-eh etc). This initializes such qtds slightly differently, so some such cases will make the driver automatically recover, and so all such errors will fail in the same way. - In case of dodgy behavior with respect to unlinking, don't modify a field. Silicon that's (wrongly) reading this will have a chance to read the old value while it's still valid. Also minor diagnostic tweaks for better uniformity/usability. drivers/usb/host/ehci-mem.c | 1 + drivers/usb/host/ehci-q.c | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff -Nru a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c --- a/drivers/usb/host/ehci-mem.c Mon Apr 7 15:15:21 2003 +++ b/drivers/usb/host/ehci-mem.c Mon Apr 7 15:15:21 2003 @@ -62,6 +62,7 @@ { memset (qtd, 0, sizeof *qtd); qtd->qtd_dma = dma; + qtd->hw_token = cpu_to_le32 (QTD_STS_HALT); qtd->hw_next = EHCI_LIST_END; qtd->hw_alt_next = EHCI_LIST_END; INIT_LIST_HEAD (&qtd->qtd_list); diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c --- a/drivers/usb/host/ehci-q.c Mon Apr 7 15:15:21 2003 +++ b/drivers/usb/host/ehci-q.c Mon Apr 7 15:15:21 2003 @@ -137,7 +137,10 @@ if (QTD_CERR (token)) urb->status = -EPIPE; else { - dbg ("3strikes"); + ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n", + urb->dev->devpath, + usb_pipeendpoint (urb->pipe), + usb_pipein (urb->pipe) ? "in" : "out"); urb->status = -EPROTO; } /* CERR nonzero + no errors + halt --> stall */ @@ -213,7 +216,6 @@ /* complete() can reenter this HCD */ spin_unlock (&ehci->lock); usb_hcd_giveback_urb (&ehci->hcd, urb, regs); - spin_lock (&ehci->lock); } @@ -827,7 +829,7 @@ * HC is allowed to fetch the old dummy (4.10.2). */ token = qtd->hw_token; - qtd->hw_token = 0; + qtd->hw_token = cpu_to_le32 (QTD_STS_HALT); wmb (); dummy = qh->dummy; @@ -879,8 +881,7 @@ if (usb_pipein (urb->pipe) && !usb_pipecontrol (urb->pipe)) epnum |= 0x10; - vdbg ("%s: submit_async urb %p len %d ep %d-%s qtd %p [qh %p]", - hcd_to_bus (&ehci->hcd)->bus_name, + ehci_vdbg (ehci, "submit_async urb %p len %d ep%d%s qtd %p [qh %p]\n", urb, urb->transfer_buffer_length, epnum & 0x0f, (epnum & 0x10) ? "in" : "out", qtd, dev ? dev->ep [epnum] : (void *)~0); @@ -916,7 +917,7 @@ del_timer (&ehci->watchdog); - qh->hw_next = cpu_to_le32 (qh->qh_dma); + // qh->hw_next = cpu_to_le32 (qh->qh_dma); qh->qh_state = QH_STATE_IDLE; qh->qh_next.qh = 0; qh_put (ehci, qh); // refcount from reclaim