diff options
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index d1498c03c4cb..56f6c584c651 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -2061,6 +2061,16 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2061 | if (!event_seg) { | 2061 | if (!event_seg) { |
2062 | if (!ep->skip || | 2062 | if (!ep->skip || |
2063 | !usb_endpoint_xfer_isoc(&td->urb->ep->desc)) { | 2063 | !usb_endpoint_xfer_isoc(&td->urb->ep->desc)) { |
2064 | /* Some host controllers give a spurious | ||
2065 | * successful event after a short transfer. | ||
2066 | * Ignore it. | ||
2067 | */ | ||
2068 | if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) && | ||
2069 | ep_ring->last_td_was_short) { | ||
2070 | ep_ring->last_td_was_short = false; | ||
2071 | ret = 0; | ||
2072 | goto cleanup; | ||
2073 | } | ||
2064 | /* HC is busted, give up! */ | 2074 | /* HC is busted, give up! */ |
2065 | xhci_err(xhci, | 2075 | xhci_err(xhci, |
2066 | "ERROR Transfer event TRB DMA ptr not " | 2076 | "ERROR Transfer event TRB DMA ptr not " |
@@ -2071,6 +2081,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2071 | ret = skip_isoc_td(xhci, td, event, ep, &status); | 2081 | ret = skip_isoc_td(xhci, td, event, ep, &status); |
2072 | goto cleanup; | 2082 | goto cleanup; |
2073 | } | 2083 | } |
2084 | if (trb_comp_code == COMP_SHORT_TX) | ||
2085 | ep_ring->last_td_was_short = true; | ||
2086 | else | ||
2087 | ep_ring->last_td_was_short = false; | ||
2074 | 2088 | ||
2075 | if (ep->skip) { | 2089 | if (ep->skip) { |
2076 | xhci_dbg(xhci, "Found td. Clear skip flag.\n"); | 2090 | xhci_dbg(xhci, "Found td. Clear skip flag.\n"); |