|
@@ -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 */
|
|
|
}
|