aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2014-07-25 16:01:18 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-08-01 18:49:34 -0400
commit8f873c1ff4ca034626093d03b254e7cb8bb782dd (patch)
tree438cfeb38fcbee6c7c203c29d0a9ae5ec43cbab5 /drivers/usb/host
parente2875c33787ebda21aeecc1a9d3ff52b3aa413ec (diff)
xhci: Blacklist using streams on the Etron EJ168 controller
Streams on the EJ168 do not work as they should. I've spend 2 days trying to get them to work, but without success. The first problem is that when ever you ring the stream-ring doorbell, the controller starts executing trbs at the beginning of the first ring segment, event if it ended somewhere else previously. This can be worked around by allowing enqueing only one td (not a problem with how streams are typically used) and then resetting our copies of the enqueueing en dequeueing pointers on a td completion to match what the controller seems to be doing. This way things seem to start working with uas and instead of being able to complete only the very first scsi command, the scsi core can probe the disk. But then things break later on when td-s get enqueued with more then one trb. The controller does seem to increase its dequeue pointer while executing a stream-ring (data transfer events I inserted for debugging do trigger). However execution seems to stop at the final normal trb of a multi trb td, even if there is a data transfer event inserted after the final trb. The first problem alone is a serious deviation from the spec, and esp. dealing with cancellation would have been very tricky if not outright impossible, but the second problem simply is a deal breaker altogether, so this patch simply disables streams. Note this will cause the usb-storage + uas driver pair to automatically switch to using usb-storage instead of uas on these devices, essentially reverting to the 3.14 and earlier behavior when uas was marked CONFIG_BROKEN. https://bugzilla.redhat.com/show_bug.cgi?id=1121288 https://bugzilla.kernel.org/show_bug.cgi?id=80101 Cc: stable@vger.kernel.org # 3.15 Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/xhci-pci.c4
-rw-r--r--drivers/usb/host/xhci.c3
-rw-r--r--drivers/usb/host/xhci.h2
3 files changed, 7 insertions, 2 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index e20520f42753..464049f638c0 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -143,6 +143,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
143 pdev->device == PCI_DEVICE_ID_ASROCK_P67) { 143 pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
144 xhci->quirks |= XHCI_RESET_ON_RESUME; 144 xhci->quirks |= XHCI_RESET_ON_RESUME;
145 xhci->quirks |= XHCI_TRUST_TX_LENGTH; 145 xhci->quirks |= XHCI_TRUST_TX_LENGTH;
146 xhci->quirks |= XHCI_BROKEN_STREAMS;
146 } 147 }
147 if (pdev->vendor == PCI_VENDOR_ID_RENESAS && 148 if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
148 pdev->device == 0x0015) 149 pdev->device == 0x0015)
@@ -230,7 +231,8 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
230 goto put_usb3_hcd; 231 goto put_usb3_hcd;
231 /* Roothub already marked as USB 3.0 speed */ 232 /* Roothub already marked as USB 3.0 speed */
232 233
233 if (HCC_MAX_PSA(xhci->hcc_params) >= 4) 234 if (!(xhci->quirks & XHCI_BROKEN_STREAMS) &&
235 HCC_MAX_PSA(xhci->hcc_params) >= 4)
234 xhci->shared_hcd->can_do_streams = 1; 236 xhci->shared_hcd->can_do_streams = 1;
235 237
236 /* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */ 238 /* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 0342d9b63977..a0772d362e70 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3148,7 +3148,8 @@ int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev,
3148 num_streams); 3148 num_streams);
3149 3149
3150 /* MaxPSASize value 0 (2 streams) means streams are not supported */ 3150 /* MaxPSASize value 0 (2 streams) means streams are not supported */
3151 if (HCC_MAX_PSA(xhci->hcc_params) < 4) { 3151 if ((xhci->quirks & XHCI_BROKEN_STREAMS) ||
3152 HCC_MAX_PSA(xhci->hcc_params) < 4) {
3152 xhci_dbg(xhci, "xHCI controller does not support streams.\n"); 3153 xhci_dbg(xhci, "xHCI controller does not support streams.\n");
3153 return -ENOSYS; 3154 return -ENOSYS;
3154 } 3155 }
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 9ffecd56600d..dace5152e179 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1558,6 +1558,8 @@ struct xhci_hcd {
1558#define XHCI_PLAT (1 << 16) 1558#define XHCI_PLAT (1 << 16)
1559#define XHCI_SLOW_SUSPEND (1 << 17) 1559#define XHCI_SLOW_SUSPEND (1 << 17)
1560#define XHCI_SPURIOUS_WAKEUP (1 << 18) 1560#define XHCI_SPURIOUS_WAKEUP (1 << 18)
1561/* For controllers with a broken beyond repair streams implementation */
1562#define XHCI_BROKEN_STREAMS (1 << 19)
1561 unsigned int num_active_eps; 1563 unsigned int num_active_eps;
1562 unsigned int limit_active_eps; 1564 unsigned int limit_active_eps;
1563 /* There are two roothubs to keep track of bus suspend info for */ 1565 /* There are two roothubs to keep track of bus suspend info for */