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

Changed files
+26 -5
drivers
+1
drivers/usb/host/xhci-pci.c
··· 147 147 if (pdev->vendor == PCI_VENDOR_ID_INTEL && 148 148 pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) { 149 149 xhci->quirks |= XHCI_SPURIOUS_REBOOT; 150 + xhci->quirks |= XHCI_SPURIOUS_WAKEUP; 150 151 } 151 152 if (pdev->vendor == PCI_VENDOR_ID_INTEL && 152 153 (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||
+25 -5
drivers/usb/host/xhci-ring.c
··· 2191 2191 } 2192 2192 /* Fast path - was this the last TRB in the TD for this URB? */ 2193 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 2198 if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { 2195 2199 td->urb->actual_length = 2196 2200 td->urb->transfer_buffer_length - ··· 2246 2242 td->urb->actual_length += 2247 2243 TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - 2248 2244 EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); 2245 + 2246 + if (trb_comp_code == COMP_SHORT_TX) { 2247 + xhci_dbg(xhci, "mid bulk/intr SP, wait for last TRB event\n"); 2248 + td->urb_length_set = true; 2249 + return 0; 2250 + } 2249 2251 } 2250 2252 2251 2253 return finish_td(xhci, td, event_trb, event, ep, status, false); ··· 2284 2274 u32 trb_comp_code; 2285 2275 int ret = 0; 2286 2276 int td_num = 0; 2277 + bool handling_skipped_tds = false; 2287 2278 2288 2279 slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags)); 2289 2280 xdev = xhci->devs[slot_id]; ··· 2420 2409 */ 2421 2410 ep->skip = true; 2422 2411 xhci_dbg(xhci, "Miss service interval error, set skip flag\n"); 2412 + goto cleanup; 2413 + case COMP_PING_ERR: 2414 + ep->skip = true; 2415 + xhci_dbg(xhci, "No Ping response error, Skip one Isoc TD\n"); 2423 2416 goto cleanup; 2424 2417 default: 2425 2418 if (xhci_is_vendor_info_code(xhci, trb_comp_code)) { ··· 2561 2546 ep, &status); 2562 2547 2563 2548 cleanup: 2549 + 2550 + 2551 + handling_skipped_tds = ep->skip && 2552 + trb_comp_code != COMP_MISSED_INT && 2553 + trb_comp_code != COMP_PING_ERR; 2554 + 2564 2555 /* 2565 - * Do not update event ring dequeue pointer if ep->skip is set. 2566 - * Will roll back to continue process missed tds. 2556 + * Do not update event ring dequeue pointer if we're in a loop 2557 + * processing missed tds. 2567 2558 */ 2568 - if (trb_comp_code == COMP_MISSED_INT || !ep->skip) { 2559 + if (!handling_skipped_tds) 2569 2560 inc_deq(xhci, xhci->event_ring); 2570 - } 2571 2561 2572 2562 if (ret) { 2573 2563 urb = td->urb; ··· 2607 2587 * Process them as short transfer until reach the td pointed by 2608 2588 * the event. 2609 2589 */ 2610 - } while (ep->skip && trb_comp_code != COMP_MISSED_INT); 2590 + } while (handling_skipped_tds); 2611 2591 2612 2592 return 0; 2613 2593 }