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