diff options
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/xhci-hub.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 19 |
2 files changed, 20 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 1e96d1f1fe6b..723f8231193d 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -761,7 +761,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
761 | memset(buf, 0, retval); | 761 | memset(buf, 0, retval); |
762 | status = 0; | 762 | status = 0; |
763 | 763 | ||
764 | mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC; | 764 | mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC; |
765 | 765 | ||
766 | spin_lock_irqsave(&xhci->lock, flags); | 766 | spin_lock_irqsave(&xhci->lock, flags); |
767 | /* For each port, did anything change? If so, set that bit in buf. */ | 767 | /* For each port, did anything change? If so, set that bit in buf. */ |
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, |