aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/xhci-pci.c4
-rw-r--r--drivers/usb/host/xhci-ring.c14
-rw-r--r--drivers/usb/host/xhci.h2
3 files changed, 20 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index faf039ac6573..eafd17fae949 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -118,6 +118,10 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
118 /* AMD PLL quirk */ 118 /* AMD PLL quirk */
119 if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) 119 if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info())
120 xhci->quirks |= XHCI_AMD_PLL_FIX; 120 xhci->quirks |= XHCI_AMD_PLL_FIX;
121 if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
122 pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI) {
123 xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
124 }
121 125
122 /* Make sure the HC is halted. */ 126 /* Make sure the HC is halted. */
123 retval = xhci_halt(xhci); 127 retval = xhci_halt(xhci);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index d1498c03c4cb..56f6c584c651 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2061,6 +2061,16 @@ static int handle_tx_event(struct xhci_hcd *xhci,
2061 if (!event_seg) { 2061 if (!event_seg) {
2062 if (!ep->skip || 2062 if (!ep->skip ||
2063 !usb_endpoint_xfer_isoc(&td->urb->ep->desc)) { 2063 !usb_endpoint_xfer_isoc(&td->urb->ep->desc)) {
2064 /* Some host controllers give a spurious
2065 * successful event after a short transfer.
2066 * Ignore it.
2067 */
2068 if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) &&
2069 ep_ring->last_td_was_short) {
2070 ep_ring->last_td_was_short = false;
2071 ret = 0;
2072 goto cleanup;
2073 }
2064 /* HC is busted, give up! */ 2074 /* HC is busted, give up! */
2065 xhci_err(xhci, 2075 xhci_err(xhci,
2066 "ERROR Transfer event TRB DMA ptr not " 2076 "ERROR Transfer event TRB DMA ptr not "
@@ -2071,6 +2081,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
2071 ret = skip_isoc_td(xhci, td, event, ep, &status); 2081 ret = skip_isoc_td(xhci, td, event, ep, &status);
2072 goto cleanup; 2082 goto cleanup;
2073 } 2083 }
2084 if (trb_comp_code == COMP_SHORT_TX)
2085 ep_ring->last_td_was_short = true;
2086 else
2087 ep_ring->last_td_was_short = false;
2074 2088
2075 if (ep->skip) { 2089 if (ep->skip) {
2076 xhci_dbg(xhci, "Found td. Clear skip flag.\n"); 2090 xhci_dbg(xhci, "Found td. Clear skip flag.\n");
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 0772a8cfea23..5cfeb8614b87 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1123,6 +1123,7 @@ struct xhci_ring {
1123 */ 1123 */
1124 u32 cycle_state; 1124 u32 cycle_state;
1125 unsigned int stream_id; 1125 unsigned int stream_id;
1126 bool last_td_was_short;
1126}; 1127};
1127 1128
1128struct xhci_erst_entry { 1129struct xhci_erst_entry {
@@ -1290,6 +1291,7 @@ struct xhci_hcd {
1290#define XHCI_RESET_EP_QUIRK (1 << 1) 1291#define XHCI_RESET_EP_QUIRK (1 << 1)
1291#define XHCI_NEC_HOST (1 << 2) 1292#define XHCI_NEC_HOST (1 << 2)
1292#define XHCI_AMD_PLL_FIX (1 << 3) 1293#define XHCI_AMD_PLL_FIX (1 << 3)
1294#define XHCI_SPURIOUS_SUCCESS (1 << 4)
1293 /* There are two roothubs to keep track of bus suspend info for */ 1295 /* There are two roothubs to keep track of bus suspend info for */
1294 struct xhci_bus_state bus_state[2]; 1296 struct xhci_bus_state bus_state[2];
1295 /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ 1297 /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */