Skip to content

Commit 0181553

Browse files
committed
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
2 parents dd5ae68 + fd7cd06 commit 0181553

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

drivers/usb/host/xhci-pci.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
147147
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
148148
pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {
149149
xhci->quirks |= XHCI_SPURIOUS_REBOOT;
150+
xhci->quirks |= XHCI_SPURIOUS_WAKEUP;
150151
}
151152
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
152153
(pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||

drivers/usb/host/xhci-ring.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2191,6 +2191,10 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
21912191
}
21922192
/* Fast path - was this the last TRB in the TD for this URB? */
21932193
} 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+
21942198
if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
21952199
td->urb->actual_length =
21962200
td->urb->transfer_buffer_length -
@@ -2242,6 +2246,12 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
22422246
td->urb->actual_length +=
22432247
TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) -
22442248
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+
}
22452255
}
22462256

22472257
return finish_td(xhci, td, event_trb, event, ep, status, false);
@@ -2274,6 +2284,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
22742284
u32 trb_comp_code;
22752285
int ret = 0;
22762286
int td_num = 0;
2287+
bool handling_skipped_tds = false;
22772288

22782289
slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
22792290
xdev = xhci->devs[slot_id];
@@ -2410,6 +2421,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
24102421
ep->skip = true;
24112422
xhci_dbg(xhci, "Miss service interval error, set skip flag\n");
24122423
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;
24132428
default:
24142429
if (xhci_is_vendor_info_code(xhci, trb_comp_code)) {
24152430
status = 0;
@@ -2546,13 +2561,18 @@ static int handle_tx_event(struct xhci_hcd *xhci,
25462561
ep, &status);
25472562

25482563
cleanup:
2564+
2565+
2566+
handling_skipped_tds = ep->skip &&
2567+
trb_comp_code != COMP_MISSED_INT &&
2568+
trb_comp_code != COMP_PING_ERR;
2569+
25492570
/*
2550-
* Do not update event ring dequeue pointer if ep->skip is set.
2551-
* Will roll back to continue process missed tds.
2571+
* Do not update event ring dequeue pointer if we're in a loop
2572+
* processing missed tds.
25522573
*/
2553-
if (trb_comp_code == COMP_MISSED_INT || !ep->skip) {
2574+
if (!handling_skipped_tds)
25542575
inc_deq(xhci, xhci->event_ring);
2555-
}
25562576

25572577
if (ret) {
25582578
urb = td->urb;
@@ -2587,7 +2607,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
25872607
* Process them as short transfer until reach the td pointed by
25882608
* the event.
25892609
*/
2590-
} while (ep->skip && trb_comp_code != COMP_MISSED_INT);
2610+
} while (handling_skipped_tds);
25912611

25922612
return 0;
25932613
}

0 commit comments

Comments
 (0)