87 lines
3.1 KiB
Diff
87 lines
3.1 KiB
Diff
From 7efb6dbd0d825899955fd4035504823bb5c1124c Mon Sep 17 00:00:00 2001
|
|
From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
|
|
Date: Tue, 04 Mar 2014 22:28:16 +0000
|
|
Subject: Revert "xhci 1.0: Limit arbitrarily-aligned scatter gather."
|
|
|
|
This reverts commit 247bf557273dd775505fb9240d2d152f4f20d304, since it
|
|
causes USB 3.0 mass storage devices to fail on xHCI 1.0 hosts.
|
|
|
|
The block layer may submit scatter-gather lists with entries that
|
|
are multiples of 512-byte blocks. That's fine for USB 2.0 devices,
|
|
where the bulk endpoint max packet size is 512 bytes. But USB 3.0
|
|
devices have bulk endpoints with a 1024 byte max packet size.
|
|
|
|
That means when the block layer submits a scatter-gather list with one
|
|
entry that includes, say, three 512-byte blocks, this code will reject
|
|
the URB if it's submitted to a USB 3.0 bulk endpoint:
|
|
|
|
int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
|
|
{
|
|
...
|
|
max = usb_endpoint_maxp(&ep->desc);
|
|
...
|
|
} else if (urb->num_sgs && !urb->dev->bus->no_sg_constraint &&
|
|
dev->speed != USB_SPEED_WIRELESS) {
|
|
struct scatterlist *sg;
|
|
int i;
|
|
|
|
for_each_sg(urb->sg, sg, urb->num_sgs - 1, i)
|
|
if (sg->length % max)
|
|
return -EINVAL;
|
|
}
|
|
|
|
This results in failures with USB 3.0 drives. For me, a failure to
|
|
auto-mount the device. For others, a read or write SCSI command
|
|
failure.
|
|
|
|
This commit was put in place so that we could get scatter-gather support
|
|
for the ASIX USB ethernet adapter on non-1.0 hosts. It was a quick fix
|
|
until we implemented TD fragments properly in the driver. Since it
|
|
breaks USB 3.0 mass storage, we need to revert it, and revert
|
|
scatter-gather support for the ASIX devices.
|
|
|
|
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
|
|
Cc: stable@vger.kernel.org # 3.12
|
|
---
|
|
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
|
|
index 652be21..8fe4e12 100644
|
|
--- a/drivers/usb/host/xhci.c
|
|
+++ b/drivers/usb/host/xhci.c
|
|
@@ -4762,6 +4762,9 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
|
|
/* Accept arbitrarily long scatter-gather lists */
|
|
hcd->self.sg_tablesize = ~0;
|
|
|
|
+ /* support to build packet from discontinuous buffers */
|
|
+ hcd->self.no_sg_constraint = 1;
|
|
+
|
|
/* XHCI controllers don't stop the ep queue on short packets :| */
|
|
hcd->self.no_stop_on_short = 1;
|
|
|
|
@@ -4786,14 +4789,6 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
|
|
/* xHCI private pointer was set in xhci_pci_probe for the second
|
|
* registered roothub.
|
|
*/
|
|
- xhci = hcd_to_xhci(hcd);
|
|
- /*
|
|
- * Support arbitrarily aligned sg-list entries on hosts without
|
|
- * TD fragment rules (which are currently unsupported).
|
|
- */
|
|
- if (xhci->hci_version < 0x100)
|
|
- hcd->self.no_sg_constraint = 1;
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
@@ -4822,9 +4817,6 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
|
|
if (xhci->hci_version > 0x96)
|
|
xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
|
|
|
|
- if (xhci->hci_version < 0x100)
|
|
- hcd->self.no_sg_constraint = 1;
|
|
-
|
|
/* Make sure the HC is halted. */
|
|
retval = xhci_halt(xhci);
|
|
if (retval)
|
|
--
|
|
cgit v0.9.2
|