disable usbip; patch to 2.6.28.10
[kernel-power] / usbhost / usb / host / ehci-q.c
index 3712b92..01132ac 100644 (file)
@@ -333,12 +333,40 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
                token = hc32_to_cpu(ehci, qtd->hw_token);
 
                /* always clean up qtds the hc de-activated */
+ retry_xacterr:
                if ((token & QTD_STS_ACTIVE) == 0) {
 
                        /* on STALL, error, and short reads this urb must
                         * complete and all its qtds must be recycled.
                         */
                        if ((token & QTD_STS_HALT) != 0) {
+
+                               /* retry transaction errors until we
+                                * reach the software xacterr limit
+                                */
+                               if ((token & QTD_STS_XACT) &&
+                                               QTD_CERR(token) == 0 &&
+                                               --qh->xacterrs > 0 &&
+                                               !urb->unlinked) {
+                                       ehci_dbg(ehci,
+       "detected XactErr len %d/%d retry %d\n",
+       qtd->length - QTD_LENGTH(token), qtd->length,
+       QH_XACTERR_MAX - qh->xacterrs);
+
+                                       /* reset the token in the qtd and the
+                                        * qh overlay (which still contains
+                                        * the qtd) so that we pick up from
+                                        * where we left off
+                                        */
+                                       token &= ~QTD_STS_HALT;
+                                       token |= QTD_STS_ACTIVE |
+                                                       (EHCI_TUNE_CERR << 10);
+                                       qtd->hw_token = cpu_to_hc32(ehci,
+                                                       token);
+                                       wmb();
+                                       qh->hw_token = cpu_to_hc32(ehci, token);
+                                       goto retry_xacterr;
+                               }
                                stopped = 1;
 
                        /* magic dummy for some short reads; qh won't advance.
@@ -421,6 +449,9 @@ halt:
                /* remove qtd; it's recycled after possible urb completion */
                list_del (&qtd->qtd_list);
                last = qtd;
+
+               /* reinit the xacterr counter for the next qtd */
+               qh->xacterrs = QH_XACTERR_MAX;
        }
 
        /* last urb's completion might still need calling */
@@ -862,6 +893,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
        head->qh_next.qh = qh;
        head->hw_next = dma;
 
+       qh->xacterrs = QH_XACTERR_MAX;
        qh->qh_state = QH_STATE_LINKED;
        /* qtd completions reported later by interrupt */
 }
@@ -1095,7 +1127,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
        prev->qh_next = qh->qh_next;
        wmb ();
 
-       if (unlikely (ehci_to_hcd(ehci)->state == HC_STATE_HALT)) {
+       /* If the controller isn't running, we don't have to wait for it */
+       if (unlikely(!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))) {
                /* if (unlikely (qh->reclaim != 0))
                 *      this will recurse, probably not much
                 */