+1
drivers/usb/host/xhci-pci.c
+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
+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
}