From 7efb6dbd0d825899955fd4035504823bb5c1124c Mon Sep 17 00:00:00 2001 From: Sarah Sharp 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 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