diff options
Diffstat (limited to 'drivers/usb/host/ehci-q.c')
-rw-r--r-- | drivers/usb/host/ehci-q.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 9a1384747f3b..7673554fa64d 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; |