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.

Please merge to 2.5 and 2.4 trees.

- Dave

--- 1.13/drivers/usb/host/ehci-mem.c    Tue Jan 21 08:08:00 2003
+++ edited/drivers/usb/host/ehci-mem.c  Mon Mar 24 09:23:19 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);
--- 1.44/drivers/usb/host/ehci-q.c      Mon Feb 24 03:30:38 2003
+++ edited/drivers/usb/host/ehci-q.c    Thu Mar 27 16:40:58 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 

Reply via email to