diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-10-23 18:52:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-10-23 18:52:59 -0400 |
commit | 018155365dccecd9ea9f26e1b26fb0f960c1ee32 (patch) | |
tree | 6fbfd8f2fe22966118823845a45b8cc26076def8 | |
parent | dd5ae6818ccd4ab0aa6f7d84e88f60a48af0fb52 (diff) | |
parent | fd7cd061adcf5f7503515ba52b6a724642a839c8 (diff) |
Merge tag 'usb-4.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH:
"Here are three xhci driver fixes for reported issues for 4.3-rc7
All have been in linux-next for a while with no problems"
* tag 'usb-4.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
xhci: Add spurious wakeup quirk for LynxPoint-LP controllers
xhci: handle no ping response error properly
xhci: don't finish a TD if we get a short transfer event mid TD
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 30 |
2 files changed, 26 insertions, 5 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index c79d33676672..c47d3e480586 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -147,6 +147,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
147 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && | 147 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && |
148 | pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) { | 148 | pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) { |
149 | xhci->quirks |= XHCI_SPURIOUS_REBOOT; | 149 | xhci->quirks |= XHCI_SPURIOUS_REBOOT; |
150 | xhci->quirks |= XHCI_SPURIOUS_WAKEUP; | ||
150 | } | 151 | } |
151 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && | 152 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && |
152 | (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI || | 153 | (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI || |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 43291f93afeb..97ffe3997273 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -2191,6 +2191,10 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
2191 | } | 2191 | } |
2192 | /* Fast path - was this the last TRB in the TD for this URB? */ | 2192 | /* Fast path - was this the last TRB in the TD for this URB? */ |
2193 | } else if (event_trb == td->last_trb) { | 2193 | } else if (event_trb == td->last_trb) { |
2194 | if (td->urb_length_set && trb_comp_code == COMP_SHORT_TX) | ||
2195 | return finish_td(xhci, td, event_trb, event, ep, | ||
2196 | status, false); | ||
2197 | |||
2194 | if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { | 2198 | if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { |
2195 | td->urb->actual_length = | 2199 | td->urb->actual_length = |
2196 | td->urb->transfer_buffer_length - | 2200 | td->urb->transfer_buffer_length - |
@@ -2242,6 +2246,12 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
2242 | td->urb->actual_length += | 2246 | td->urb->actual_length += |
2243 | TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - | 2247 | TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - |
2244 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); | 2248 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
2249 | |||
2250 | if (trb_comp_code == COMP_SHORT_TX) { | ||
2251 | xhci_dbg(xhci, "mid bulk/intr SP, wait for last TRB event\n"); | ||
2252 | td->urb_length_set = true; | ||
2253 | return 0; | ||
2254 | } | ||
2245 | } | 2255 | } |
2246 | 2256 | ||
2247 | return finish_td(xhci, td, event_trb, event, ep, status, false); | 2257 | return finish_td(xhci, td, event_trb, event, ep, status, false); |
@@ -2274,6 +2284,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2274 | u32 trb_comp_code; | 2284 | u32 trb_comp_code; |
2275 | int ret = 0; | 2285 | int ret = 0; |
2276 | int td_num = 0; | 2286 | int td_num = 0; |
2287 | bool handling_skipped_tds = false; | ||
2277 | 2288 | ||
2278 | slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags)); | 2289 | slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags)); |
2279 | xdev = xhci->devs[slot_id]; | 2290 | xdev = xhci->devs[slot_id]; |
@@ -2410,6 +2421,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2410 | ep->skip = true; | 2421 | ep->skip = true; |
2411 | xhci_dbg(xhci, "Miss service interval error, set skip flag\n"); | 2422 | xhci_dbg(xhci, "Miss service interval error, set skip flag\n"); |
2412 | goto cleanup; | 2423 | goto cleanup; |
2424 | case COMP_PING_ERR: | ||
2425 | ep->skip = true; | ||
2426 | xhci_dbg(xhci, "No Ping response error, Skip one Isoc TD\n"); | ||
2427 | goto cleanup; | ||
2413 | default: | 2428 | default: |
2414 | if (xhci_is_vendor_info_code(xhci, trb_comp_code)) { | 2429 | if (xhci_is_vendor_info_code(xhci, trb_comp_code)) { |
2415 | status = 0; | 2430 | status = 0; |
@@ -2546,13 +2561,18 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2546 | ep, &status); | 2561 | ep, &status); |
2547 | 2562 | ||
2548 | cleanup: | 2563 | cleanup: |
2564 | |||
2565 | |||
2566 | handling_skipped_tds = ep->skip && | ||
2567 | trb_comp_code != COMP_MISSED_INT && | ||
2568 | trb_comp_code != COMP_PING_ERR; | ||
2569 | |||
2549 | /* | 2570 | /* |
2550 | * Do not update event ring dequeue pointer if ep->skip is set. | 2571 | * Do not update event ring dequeue pointer if we're in a loop |
2551 | * Will roll back to continue process missed tds. | 2572 | * processing missed tds. |
2552 | */ | 2573 | */ |
2553 | if (trb_comp_code == COMP_MISSED_INT || !ep->skip) { | 2574 | if (!handling_skipped_tds) |
2554 | inc_deq(xhci, xhci->event_ring); | 2575 | inc_deq(xhci, xhci->event_ring); |
2555 | } | ||
2556 | 2576 | ||
2557 | if (ret) { | 2577 | if (ret) { |
2558 | urb = td->urb; | 2578 | urb = td->urb; |
@@ -2587,7 +2607,7 @@ cleanup: | |||
2587 | * Process them as short transfer until reach the td pointed by | 2607 | * Process them as short transfer until reach the td pointed by |
2588 | * the event. | 2608 | * the event. |
2589 | */ | 2609 | */ |
2590 | } while (ep->skip && trb_comp_code != COMP_MISSED_INT); | 2610 | } while (handling_skipped_tds); |
2591 | 2611 | ||
2592 | return 0; | 2612 | return 0; |
2593 | } | 2613 | } |