diff options
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 821b7b4709d..184e8b6f30b 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -306,7 +306,7 @@ static void ring_ep_doorbell(struct xhci_hcd *xhci, | |||
306 | /* Don't ring the doorbell for this endpoint if there are pending | 306 | /* Don't ring the doorbell for this endpoint if there are pending |
307 | * cancellations because the we don't want to interrupt processing. | 307 | * cancellations because the we don't want to interrupt processing. |
308 | */ | 308 | */ |
309 | if (!ep->cancels_pending && !(ep_state & SET_DEQ_PENDING) | 309 | if (!(ep_state & EP_HALT_PENDING) && !(ep_state & SET_DEQ_PENDING) |
310 | && !(ep_state & EP_HALTED)) { | 310 | && !(ep_state & EP_HALTED)) { |
311 | field = xhci_readl(xhci, db_addr) & DB_MASK; | 311 | field = xhci_readl(xhci, db_addr) & DB_MASK; |
312 | xhci_writel(xhci, field | EPI_TO_DB(ep_index), db_addr); | 312 | xhci_writel(xhci, field | EPI_TO_DB(ep_index), db_addr); |
@@ -507,8 +507,11 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, | |||
507 | ep = &xhci->devs[slot_id]->eps[ep_index]; | 507 | ep = &xhci->devs[slot_id]->eps[ep_index]; |
508 | ep_ring = ep->ring; | 508 | ep_ring = ep->ring; |
509 | 509 | ||
510 | if (list_empty(&ep->cancelled_td_list)) | 510 | if (list_empty(&ep->cancelled_td_list)) { |
511 | ep->ep_state &= ~EP_HALT_PENDING; | ||
512 | ring_ep_doorbell(xhci, slot_id, ep_index); | ||
511 | return; | 513 | return; |
514 | } | ||
512 | 515 | ||
513 | /* Fix up the ep ring first, so HW stops executing cancelled TDs. | 516 | /* Fix up the ep ring first, so HW stops executing cancelled TDs. |
514 | * We have the xHCI lock, so nothing can modify this list until we drop | 517 | * We have the xHCI lock, so nothing can modify this list until we drop |
@@ -535,9 +538,9 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, | |||
535 | * the cancelled TD list for URB completion later. | 538 | * the cancelled TD list for URB completion later. |
536 | */ | 539 | */ |
537 | list_del(&cur_td->td_list); | 540 | list_del(&cur_td->td_list); |
538 | ep->cancels_pending--; | ||
539 | } | 541 | } |
540 | last_unlinked_td = cur_td; | 542 | last_unlinked_td = cur_td; |
543 | ep->ep_state &= ~EP_HALT_PENDING; | ||
541 | 544 | ||
542 | /* If necessary, queue a Set Transfer Ring Dequeue Pointer command */ | 545 | /* If necessary, queue a Set Transfer Ring Dequeue Pointer command */ |
543 | if (deq_state.new_deq_ptr && deq_state.new_deq_seg) { | 546 | if (deq_state.new_deq_ptr && deq_state.new_deq_seg) { |
@@ -1249,10 +1252,9 @@ td_cleanup: | |||
1249 | } | 1252 | } |
1250 | list_del(&td->td_list); | 1253 | list_del(&td->td_list); |
1251 | /* Was this TD slated to be cancelled but completed anyway? */ | 1254 | /* Was this TD slated to be cancelled but completed anyway? */ |
1252 | if (!list_empty(&td->cancelled_td_list)) { | 1255 | if (!list_empty(&td->cancelled_td_list)) |
1253 | list_del(&td->cancelled_td_list); | 1256 | list_del(&td->cancelled_td_list); |
1254 | ep->cancels_pending--; | 1257 | |
1255 | } | ||
1256 | /* Leave the TD around for the reset endpoint function to use | 1258 | /* Leave the TD around for the reset endpoint function to use |
1257 | * (but only if it's not a control endpoint, since we already | 1259 | * (but only if it's not a control endpoint, since we already |
1258 | * queued the Set TR dequeue pointer command for stalled | 1260 | * queued the Set TR dequeue pointer command for stalled |