When unplug USB device, another USB device access failed

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I have the following problem.  My machine's chipset is 
ICH5. I plugged in a USB flash drive and a DVD drive. I 
start to access USB flash drive by a CP command and while 
it's running, unplugged a dvd drive. CP command running is 
failed.

I got advice about this problem from Alan-san, Matthew-san 
and David-san on anther thread.
 http://markmail.org/message/k2drtwwkul6dawp2#query:koichiro%20saito%20usb%20linux+page:1+mid:wn27qdeqbqwgoaes+state:results
I obtained information that this problem occur by Alain's 
system (Intel 82845GE motherboard with ICH4 chipset). The 
cause of this error is a common hardware bug among EHCI 
controllers. This error occur by XactErr.

I examined how Windows work around with this problem. 
Windows corrected with a following HOTFIX. But the content 
of the symptom is different.
 http://support.microsoft.com/KB/908673 
When I install this HOTFIX in my windows machine, I 
confirmed this problem is resolved. The description of 
HOTFIX said that When XactErr occurred, ehci host driver of 
Windows run soft retrying. 

>From the aforementioned process, I try to modified 
ehci-driver to retry when XactErr occurred. 
Could you give me any advice whether this soft retrying is 
valid and correct? 


diff -urN linux-2.6.28-git10.org/drivers/usb/host/ehci-q.c linux-2.6.28-git10/drivers/usb/host/ehci-q.c
--- linux-2.6.28-git10.org/drivers/usb/host/ehci-q.c    2008-12-25 08:26:37.000000000 +0900
+++ linux-2.6.28-git10/drivers/usb/host/ehci-q.c    2009-01-09 06:46:05.000000000 +0900
@@ -341,6 +341,35 @@
            if ((token & QTD_STS_HALT) != 0) {
                stopped = 1;
 
+               /* judge transaction error
+                * "three strikes and you're out" policy
+                * is applied to retrying */
+               if (token & QTD_STS_XACT &&
+                   !QTD_CERR (token) &&
+                   --qh->xacterrs > 0) {
+                   ehci_dbg (ehci, "@@@ detected XactErr len %d/%d retry %d\n",
+                   qtd->length - QTD_LENGTH(token), qtd->length,
+                   QH_XACTERR_MAX - qh->xacterrs);
+                   /* stop flag off*/
+                   stopped = 0;
+
+                   /* token clear error status for tranxaction error retry*/
+                   /* clear token status */
+                   token &= 0xffffff00;                    /* status -> off */
+                   token |= QTD_STS_ACTIVE;                /* Active -> on */
+                   token |= (EHCI_TUNE_CERR << 10);        /* clear CERR */
+                   /* update qtd token */
+                   qtd->hw_token = cpu_to_hc32(ehci, token);
+                   wmb ();
+
+                   /* update qh */
+                   qh->qh_state = QH_STATE_IDLE;
+                   qh_update(ehci, qh, qtd);
+
+                   break;
+               }
+
+
            /* magic dummy for some short reads; qh won't advance.
             * that silicon quirk can kick in with this dummy too.
             *
@@ -949,6 +978,8 @@
 
            urb->hcpriv = qh_get (qh);
        }
+       /* set transaction error retry counter */
+       qh->xacterrs = QH_XACTERR_MAX;
    }
    return qh;
 }
diff -urN linux-2.6.28-git10.org/drivers/usb/host/ehci.h linux-2.6.28-git10/drivers/usb/host/ehci.h
--- linux-2.6.28-git10.org/drivers/usb/host/ehci.h  2009-01-09 05:55:34.000000000 +0900
+++ linux-2.6.28-git10/drivers/usb/host/ehci.h  2009-01-09 06:46:05.000000000 +0900
@@ -379,6 +379,13 @@
    unsigned short      start;      /* where polling starts */
 #define NO_FRAME ((unsigned short)~0)          /* pick new start */
    struct usb_device   *dev;       /* access to TT */
+   u8                      xacterrs;   /* XactErr retry counter */
+#define QH_XACTERR_MAX     3       /* XactErr retry limit
+                        * "three strikes and
+                        * you're out" policy
+                        * is applied to retrying
+                        */
+
 } __attribute__ ((aligned (32)));
 
 /*-------------------------------------------------------------------------*/


best regards
   Koichiro Saito

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux