aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-ring.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r--drivers/usb/host/xhci-ring.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 54139a2f06ce..952e2ded61af 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1934,8 +1934,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
1934 int status = -EINPROGRESS; 1934 int status = -EINPROGRESS;
1935 struct urb_priv *urb_priv; 1935 struct urb_priv *urb_priv;
1936 struct xhci_ep_ctx *ep_ctx; 1936 struct xhci_ep_ctx *ep_ctx;
1937 struct list_head *tmp;
1937 u32 trb_comp_code; 1938 u32 trb_comp_code;
1938 int ret = 0; 1939 int ret = 0;
1940 int td_num = 0;
1939 1941
1940 slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags)); 1942 slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
1941 xdev = xhci->devs[slot_id]; 1943 xdev = xhci->devs[slot_id];
@@ -1957,6 +1959,12 @@ static int handle_tx_event(struct xhci_hcd *xhci,
1957 return -ENODEV; 1959 return -ENODEV;
1958 } 1960 }
1959 1961
1962 /* Count current td numbers if ep->skip is set */
1963 if (ep->skip) {
1964 list_for_each(tmp, &ep_ring->td_list)
1965 td_num++;
1966 }
1967
1960 event_dma = le64_to_cpu(event->buffer); 1968 event_dma = le64_to_cpu(event->buffer);
1961 trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len)); 1969 trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len));
1962 /* Look for common error cases */ 1970 /* Look for common error cases */
@@ -2068,7 +2076,18 @@ static int handle_tx_event(struct xhci_hcd *xhci,
2068 goto cleanup; 2076 goto cleanup;
2069 } 2077 }
2070 2078
2079 /* We've skipped all the TDs on the ep ring when ep->skip set */
2080 if (ep->skip && td_num == 0) {
2081 ep->skip = false;
2082 xhci_dbg(xhci, "All tds on the ep_ring skipped. "
2083 "Clear skip flag.\n");
2084 ret = 0;
2085 goto cleanup;
2086 }
2087
2071 td = list_entry(ep_ring->td_list.next, struct xhci_td, td_list); 2088 td = list_entry(ep_ring->td_list.next, struct xhci_td, td_list);
2089 if (ep->skip)
2090 td_num--;
2072 2091
2073 /* Is this a TRB in the currently executing TD? */ 2092 /* Is this a TRB in the currently executing TD? */
2074 event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue, 2093 event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue,