aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-q.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-q.c')
-rw-r--r--drivers/usb/host/ehci-q.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 9a1384747f3..7673554fa64 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -375,12 +375,11 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
375 */ 375 */
376 if ((token & QTD_STS_XACT) && 376 if ((token & QTD_STS_XACT) &&
377 QTD_CERR(token) == 0 && 377 QTD_CERR(token) == 0 &&
378 --qh->xacterrs > 0 && 378 ++qh->xacterrs < QH_XACTERR_MAX &&
379 !urb->unlinked) { 379 !urb->unlinked) {
380 ehci_dbg(ehci, 380 ehci_dbg(ehci,
381 "detected XactErr len %zu/%zu retry %d\n", 381 "detected XactErr len %zu/%zu retry %d\n",
382 qtd->length - QTD_LENGTH(token), qtd->length, 382 qtd->length - QTD_LENGTH(token), qtd->length, qh->xacterrs);
383 QH_XACTERR_MAX - qh->xacterrs);
384 383
385 /* reset the token in the qtd and the 384 /* reset the token in the qtd and the
386 * qh overlay (which still contains 385 * qh overlay (which still contains
@@ -494,7 +493,7 @@ halt:
494 last = qtd; 493 last = qtd;
495 494
496 /* reinit the xacterr counter for the next qtd */ 495 /* reinit the xacterr counter for the next qtd */
497 qh->xacterrs = QH_XACTERR_MAX; 496 qh->xacterrs = 0;
498 } 497 }
499 498
500 /* last urb's completion might still need calling */ 499 /* last urb's completion might still need calling */
@@ -940,7 +939,8 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
940 head->qh_next.qh = qh; 939 head->qh_next.qh = qh;
941 head->hw_next = dma; 940 head->hw_next = dma;
942 941
943 qh->xacterrs = QH_XACTERR_MAX; 942 qh_get(qh);
943 qh->xacterrs = 0;
944 qh->qh_state = QH_STATE_LINKED; 944 qh->qh_state = QH_STATE_LINKED;
945 /* qtd completions reported later by interrupt */ 945 /* qtd completions reported later by interrupt */
946} 946}
@@ -1080,7 +1080,7 @@ submit_async (
1080 * the HC and TT handle it when the TT has a buffer ready. 1080 * the HC and TT handle it when the TT has a buffer ready.
1081 */ 1081 */
1082 if (likely (qh->qh_state == QH_STATE_IDLE)) 1082 if (likely (qh->qh_state == QH_STATE_IDLE))
1083 qh_link_async (ehci, qh_get (qh)); 1083 qh_link_async(ehci, qh);
1084 done: 1084 done:
1085 spin_unlock_irqrestore (&ehci->lock, flags); 1085 spin_unlock_irqrestore (&ehci->lock, flags);
1086 if (unlikely (qh == NULL)) 1086 if (unlikely (qh == NULL))
@@ -1115,8 +1115,6 @@ static void end_unlink_async (struct ehci_hcd *ehci)
1115 && HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) 1115 && HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
1116 qh_link_async (ehci, qh); 1116 qh_link_async (ehci, qh);
1117 else { 1117 else {
1118 qh_put (qh); // refcount from async list
1119
1120 /* it's not free to turn the async schedule on/off; leave it 1118 /* it's not free to turn the async schedule on/off; leave it
1121 * active but idle for a while once it empties. 1119 * active but idle for a while once it empties.
1122 */ 1120 */
@@ -1124,6 +1122,7 @@ static void end_unlink_async (struct ehci_hcd *ehci)
1124 && ehci->async->qh_next.qh == NULL) 1122 && ehci->async->qh_next.qh == NULL)
1125 timer_action (ehci, TIMER_ASYNC_OFF); 1123 timer_action (ehci, TIMER_ASYNC_OFF);
1126 } 1124 }
1125 qh_put(qh); /* refcount from async list */
1127 1126
1128 if (next) { 1127 if (next) {
1129 ehci->reclaim = NULL; 1128 ehci->reclaim = NULL;