diff options
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 3d9422f16a20..23b4aefd1036 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -1377,6 +1377,7 @@ static void handle_port_status(struct xhci_hcd *xhci, | |||
1377 | xhci_dbg(xhci, "resume HS port %d\n", port_id); | 1377 | xhci_dbg(xhci, "resume HS port %d\n", port_id); |
1378 | bus_state->resume_done[faked_port_index] = jiffies + | 1378 | bus_state->resume_done[faked_port_index] = jiffies + |
1379 | msecs_to_jiffies(20); | 1379 | msecs_to_jiffies(20); |
1380 | set_bit(faked_port_index, &bus_state->resuming_ports); | ||
1380 | mod_timer(&hcd->rh_timer, | 1381 | mod_timer(&hcd->rh_timer, |
1381 | bus_state->resume_done[faked_port_index]); | 1382 | bus_state->resume_done[faked_port_index]); |
1382 | /* Do the rest in GetPortStatus */ | 1383 | /* Do the rest in GetPortStatus */ |
@@ -1786,8 +1787,12 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1786 | /* handle completion code */ | 1787 | /* handle completion code */ |
1787 | switch (trb_comp_code) { | 1788 | switch (trb_comp_code) { |
1788 | case COMP_SUCCESS: | 1789 | case COMP_SUCCESS: |
1789 | frame->status = 0; | 1790 | if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) { |
1790 | break; | 1791 | frame->status = 0; |
1792 | break; | ||
1793 | } | ||
1794 | if ((xhci->quirks & XHCI_TRUST_TX_LENGTH)) | ||
1795 | trb_comp_code = COMP_SHORT_TX; | ||
1791 | case COMP_SHORT_TX: | 1796 | case COMP_SHORT_TX: |
1792 | frame->status = td->urb->transfer_flags & URB_SHORT_NOT_OK ? | 1797 | frame->status = td->urb->transfer_flags & URB_SHORT_NOT_OK ? |
1793 | -EREMOTEIO : 0; | 1798 | -EREMOTEIO : 0; |
@@ -1803,6 +1808,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1803 | break; | 1808 | break; |
1804 | case COMP_DEV_ERR: | 1809 | case COMP_DEV_ERR: |
1805 | case COMP_STALL: | 1810 | case COMP_STALL: |
1811 | case COMP_TX_ERR: | ||
1806 | frame->status = -EPROTO; | 1812 | frame->status = -EPROTO; |
1807 | skip_td = true; | 1813 | skip_td = true; |
1808 | break; | 1814 | break; |
@@ -1883,13 +1889,16 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1883 | switch (trb_comp_code) { | 1889 | switch (trb_comp_code) { |
1884 | case COMP_SUCCESS: | 1890 | case COMP_SUCCESS: |
1885 | /* Double check that the HW transferred everything. */ | 1891 | /* Double check that the HW transferred everything. */ |
1886 | if (event_trb != td->last_trb) { | 1892 | if (event_trb != td->last_trb || |
1893 | TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { | ||
1887 | xhci_warn(xhci, "WARN Successful completion " | 1894 | xhci_warn(xhci, "WARN Successful completion " |
1888 | "on short TX\n"); | 1895 | "on short TX\n"); |
1889 | if (td->urb->transfer_flags & URB_SHORT_NOT_OK) | 1896 | if (td->urb->transfer_flags & URB_SHORT_NOT_OK) |
1890 | *status = -EREMOTEIO; | 1897 | *status = -EREMOTEIO; |
1891 | else | 1898 | else |
1892 | *status = 0; | 1899 | *status = 0; |
1900 | if ((xhci->quirks & XHCI_TRUST_TX_LENGTH)) | ||
1901 | trb_comp_code = COMP_SHORT_TX; | ||
1893 | } else { | 1902 | } else { |
1894 | *status = 0; | 1903 | *status = 0; |
1895 | } | 1904 | } |
@@ -2048,6 +2057,13 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2048 | * transfer type | 2057 | * transfer type |
2049 | */ | 2058 | */ |
2050 | case COMP_SUCCESS: | 2059 | case COMP_SUCCESS: |
2060 | if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) | ||
2061 | break; | ||
2062 | if (xhci->quirks & XHCI_TRUST_TX_LENGTH) | ||
2063 | trb_comp_code = COMP_SHORT_TX; | ||
2064 | else | ||
2065 | xhci_warn(xhci, "WARN Successful completion on short TX: " | ||
2066 | "needs XHCI_TRUST_TX_LENGTH quirk?\n"); | ||
2051 | case COMP_SHORT_TX: | 2067 | case COMP_SHORT_TX: |
2052 | break; | 2068 | break; |
2053 | case COMP_STOP: | 2069 | case COMP_STOP: |
@@ -2270,7 +2286,7 @@ cleanup: | |||
2270 | (status != 0 && | 2286 | (status != 0 && |
2271 | !usb_endpoint_xfer_isoc(&urb->ep->desc))) | 2287 | !usb_endpoint_xfer_isoc(&urb->ep->desc))) |
2272 | xhci_dbg(xhci, "Giveback URB %p, len = %d, " | 2288 | xhci_dbg(xhci, "Giveback URB %p, len = %d, " |
2273 | "expected = %x, status = %d\n", | 2289 | "expected = %d, status = %d\n", |
2274 | urb, urb->actual_length, | 2290 | urb, urb->actual_length, |
2275 | urb->transfer_buffer_length, | 2291 | urb->transfer_buffer_length, |
2276 | status); | 2292 | status); |
@@ -3593,12 +3609,12 @@ int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | |||
3593 | 3609 | ||
3594 | /* Queue an evaluate context command TRB */ | 3610 | /* Queue an evaluate context command TRB */ |
3595 | int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | 3611 | int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, |
3596 | u32 slot_id) | 3612 | u32 slot_id, bool command_must_succeed) |
3597 | { | 3613 | { |
3598 | return queue_command(xhci, lower_32_bits(in_ctx_ptr), | 3614 | return queue_command(xhci, lower_32_bits(in_ctx_ptr), |
3599 | upper_32_bits(in_ctx_ptr), 0, | 3615 | upper_32_bits(in_ctx_ptr), 0, |
3600 | TRB_TYPE(TRB_EVAL_CONTEXT) | SLOT_ID_FOR_TRB(slot_id), | 3616 | TRB_TYPE(TRB_EVAL_CONTEXT) | SLOT_ID_FOR_TRB(slot_id), |
3601 | false); | 3617 | command_must_succeed); |
3602 | } | 3618 | } |
3603 | 3619 | ||
3604 | /* | 3620 | /* |