From a6c0e97546a7b2444643eb8edb6f18ae696d4e23 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 Feb 2012 09:45:52 -0800 Subject: [PATCH] 3.2-stable patches added patches: usb-don-t-fail-usb3-probe-on-missing-legacy-pci-irq.patch usb-fix-handoff-when-bios-disables-host-pci-device.patch usb-set-hub-depth-after-usb3-hub-reset.patch xhci-fix-encoding-for-hs-bulk-control-nak-rate.patch xhci-fix-oops-caused-by-more-usb2-ports-than-usb3-ports.patch --- queue-3.2/series | 5 + ...usb3-probe-on-missing-legacy-pci-irq.patch | 74 ++++++++++++++ ...f-when-bios-disables-host-pci-device.patch | 67 +++++++++++++ ...b-set-hub-depth-after-usb3-hub-reset.patch | 84 ++++++++++++++++ ...ncoding-for-hs-bulk-control-nak-rate.patch | 96 +++++++++++++++++++ ...d-by-more-usb2-ports-than-usb3-ports.patch | 36 +++++++ 6 files changed, 362 insertions(+) create mode 100644 queue-3.2/usb-don-t-fail-usb3-probe-on-missing-legacy-pci-irq.patch create mode 100644 queue-3.2/usb-fix-handoff-when-bios-disables-host-pci-device.patch create mode 100644 queue-3.2/usb-set-hub-depth-after-usb3-hub-reset.patch create mode 100644 queue-3.2/xhci-fix-encoding-for-hs-bulk-control-nak-rate.patch create mode 100644 queue-3.2/xhci-fix-oops-caused-by-more-usb2-ports-than-usb3-ports.patch diff --git a/queue-3.2/series b/queue-3.2/series index a1e4c9b7b53..45535491290 100644 --- a/queue-3.2/series +++ b/queue-3.2/series @@ -35,3 +35,8 @@ usb-added-kamstrup-vid-pids-to-cp210x-serial-driver.patch usb-option-cleanup-zte-3g-dongle-s-pid-in-option.c.patch usb-serial-ti_usb_3410_5052-add-abbot-diabetes-care-cable-id.patch usb-remove-duplicate-usb-3.0-hub-feature-defines.patch +usb-fix-handoff-when-bios-disables-host-pci-device.patch +xhci-fix-oops-caused-by-more-usb2-ports-than-usb3-ports.patch +xhci-fix-encoding-for-hs-bulk-control-nak-rate.patch +usb-don-t-fail-usb3-probe-on-missing-legacy-pci-irq.patch +usb-set-hub-depth-after-usb3-hub-reset.patch diff --git a/queue-3.2/usb-don-t-fail-usb3-probe-on-missing-legacy-pci-irq.patch b/queue-3.2/usb-don-t-fail-usb3-probe-on-missing-legacy-pci-irq.patch new file mode 100644 index 00000000000..5fd3e1d485a --- /dev/null +++ b/queue-3.2/usb-don-t-fail-usb3-probe-on-missing-legacy-pci-irq.patch @@ -0,0 +1,74 @@ +From 68d07f64b8a11a852d48d1b05b724c3e20c0d94b Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Mon, 13 Feb 2012 16:25:57 -0800 +Subject: USB: Don't fail USB3 probe on missing legacy PCI IRQ. + +From: Sarah Sharp + +commit 68d07f64b8a11a852d48d1b05b724c3e20c0d94b upstream. + +Intel has a PCI USB xhci host controller on a new platform. It doesn't +have a line IRQ definition in BIOS. The Linux driver refuses to +initialize this controller, but Windows works well because it only depends +on MSI. + +Actually, Linux also can work for MSI. This patch avoids the line IRQ +checking for USB3 HCDs in usb core PCI probe. It allows the xHCI driver +to try to enable MSI or MSI-X first. It will fail the probe if MSI +enabling failed and there's no legacy PCI IRQ. + +This patch should be backported to kernels as old as 2.6.32. + +Signed-off-by: Alex Shi +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hcd-pci.c | 5 ++++- + drivers/usb/core/hcd.c | 6 ++++-- + drivers/usb/host/xhci.c | 5 +++++ + 3 files changed, 13 insertions(+), 3 deletions(-) + +--- a/drivers/usb/core/hcd-pci.c ++++ b/drivers/usb/core/hcd-pci.c +@@ -187,7 +187,10 @@ int usb_hcd_pci_probe(struct pci_dev *de + return -ENODEV; + dev->current_state = PCI_D0; + +- if (!dev->irq) { ++ /* The xHCI driver supports MSI and MSI-X, ++ * so don't fail if the BIOS doesn't provide a legacy IRQ. ++ */ ++ if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) { + dev_err(&dev->dev, + "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", + pci_name(dev)); +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -2465,8 +2465,10 @@ int usb_add_hcd(struct usb_hcd *hcd, + && device_can_wakeup(&hcd->self.root_hub->dev)) + dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); + +- /* enable irqs just before we start the controller */ +- if (usb_hcd_is_primary_hcd(hcd)) { ++ /* enable irqs just before we start the controller, ++ * if the BIOS provides legacy PCI irqs. ++ */ ++ if (usb_hcd_is_primary_hcd(hcd) && irqnum) { + retval = usb_hcd_request_irqs(hcd, irqnum, irqflags); + if (retval) + goto err_request_irq; +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -352,6 +352,11 @@ static int xhci_try_enable_msi(struct us + /* hcd->irq is -1, we have MSI */ + return 0; + ++ if (!pdev->irq) { ++ xhci_err(xhci, "No msi-x/msi found and no IRQ in BIOS\n"); ++ return -EINVAL; ++ } ++ + /* fall back to legacy interrupt*/ + ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, + hcd->irq_descr, hcd); diff --git a/queue-3.2/usb-fix-handoff-when-bios-disables-host-pci-device.patch b/queue-3.2/usb-fix-handoff-when-bios-disables-host-pci-device.patch new file mode 100644 index 00000000000..ea888c053b4 --- /dev/null +++ b/queue-3.2/usb-fix-handoff-when-bios-disables-host-pci-device.patch @@ -0,0 +1,67 @@ +From cab928ee1f221c9cc48d6615070fefe2e444384a Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Tue, 7 Feb 2012 15:11:46 -0800 +Subject: USB: Fix handoff when BIOS disables host PCI device. + +From: Sarah Sharp + +commit cab928ee1f221c9cc48d6615070fefe2e444384a upstream. + +On some systems with an Intel Panther Point xHCI host controller, the +BIOS disables the xHCI PCI device during boot, and switches the xHCI +ports over to EHCI. This allows the BIOS to access USB devices without +having xHCI support. + +The downside is that the xHCI BIOS handoff mechanism will fail because +memory mapped I/O is not enabled for the disabled PCI device. +Jesse Barnes says this is expected behavior. The PCI core will enable +BARs before quirks run, but it will leave it in an undefined state, and +it may not have memory mapped I/O enabled. + +Make the generic USB quirk handler call pci_enable_device() to re-enable +MMIO, and call pci_disable_device() once the host-specific BIOS handoff +is finished. This will balance the ref counts in the PCI core. When +the PCI probe function is called, usb_hcd_pci_probe() will call +pci_enable_device() again. + +This should be back ported to kernels as old as 2.6.31. That was the +first kernel with xHCI support, and no one has complained about BIOS +handoffs failing due to memory mapped I/O being disabled on other hosts +(EHCI, UHCI, or OHCI). + +Signed-off-by: Sarah Sharp +Acked-by: Oliver Neukum +Cc: Jesse Barnes +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/pci-quirks.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/usb/host/pci-quirks.c ++++ b/drivers/usb/host/pci-quirks.c +@@ -872,7 +872,17 @@ static void __devinit quirk_usb_early_ha + */ + if (pdev->vendor == 0x184e) /* vendor Netlogic */ + return; ++ if (pdev->class != PCI_CLASS_SERIAL_USB_UHCI && ++ pdev->class != PCI_CLASS_SERIAL_USB_OHCI && ++ pdev->class != PCI_CLASS_SERIAL_USB_EHCI && ++ pdev->class != PCI_CLASS_SERIAL_USB_XHCI) ++ return; + ++ if (pci_enable_device(pdev) < 0) { ++ dev_warn(&pdev->dev, "Can't enable PCI device, " ++ "BIOS handoff failed.\n"); ++ return; ++ } + if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI) + quirk_usb_handoff_uhci(pdev); + else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI) +@@ -881,5 +891,6 @@ static void __devinit quirk_usb_early_ha + quirk_usb_disable_ehci(pdev); + else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI) + quirk_usb_handoff_xhci(pdev); ++ pci_disable_device(pdev); + } + DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); diff --git a/queue-3.2/usb-set-hub-depth-after-usb3-hub-reset.patch b/queue-3.2/usb-set-hub-depth-after-usb3-hub-reset.patch new file mode 100644 index 00000000000..78f62dcdea9 --- /dev/null +++ b/queue-3.2/usb-set-hub-depth-after-usb3-hub-reset.patch @@ -0,0 +1,84 @@ +From a45aa3b30583e7d54e7cf4fbcd0aa699348a6e5c Mon Sep 17 00:00:00 2001 +From: Elric Fu +Date: Sat, 18 Feb 2012 13:32:27 +0800 +Subject: USB: Set hub depth after USB3 hub reset + +From: Elric Fu + +commit a45aa3b30583e7d54e7cf4fbcd0aa699348a6e5c upstream. + +The superspeed device attached to a USB 3.0 hub(such as VIA's) +doesn't respond the address device command after resume. The +root cause is the superspeed hub will miss the Hub Depth value +that is used as an offset into the route string to locate the +bits it uses to determine the downstream port number after +reset, and all packets can't be routed to the device attached +to the superspeed hub. + +Hub driver sends a Set Hub Depth request to the superspeed hub +except for USB 3.0 root hub when the hub is initialized and +doesn't send the request again after reset due to the resume +process. So moving the code that sends the Set Hub Depth request +to the superspeed hub from hub_configure() to hub_activate() +is to cover those situations include initialization and reset. + +The patch should be backported to kernels as old as 2.6.39. + +Signed-off-by: Elric Fu +Signed-off-by: Sarah Sharp +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 30 +++++++++++++++++------------- + 1 file changed, 17 insertions(+), 13 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -705,10 +705,26 @@ static void hub_activate(struct usb_hub + if (type == HUB_INIT3) + goto init3; + +- /* After a resume, port power should still be on. ++ /* The superspeed hub except for root hub has to use Hub Depth ++ * value as an offset into the route string to locate the bits ++ * it uses to determine the downstream port number. So hub driver ++ * should send a set hub depth request to superspeed hub after ++ * the superspeed hub is set configuration in initialization or ++ * reset procedure. ++ * ++ * After a resume, port power should still be on. + * For any other type of activation, turn it on. + */ + if (type != HUB_RESUME) { ++ if (hdev->parent && hub_is_superspeed(hdev)) { ++ ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), ++ HUB_SET_DEPTH, USB_RT_HUB, ++ hdev->level - 1, 0, NULL, 0, ++ USB_CTRL_SET_TIMEOUT); ++ if (ret < 0) ++ dev_err(hub->intfdev, ++ "set hub depth failed\n"); ++ } + + /* Speed up system boot by using a delayed_work for the + * hub's initial power-up delays. This is pretty awkward +@@ -987,18 +1003,6 @@ static int hub_configure(struct usb_hub + goto fail; + } + +- if (hub_is_superspeed(hdev) && (hdev->parent != NULL)) { +- ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), +- HUB_SET_DEPTH, USB_RT_HUB, +- hdev->level - 1, 0, NULL, 0, +- USB_CTRL_SET_TIMEOUT); +- +- if (ret < 0) { +- message = "can't set hub depth"; +- goto fail; +- } +- } +- + /* Request the entire hub descriptor. + * hub->descriptor can handle USB_MAXCHILDREN ports, + * but the hub can/will return fewer bytes here. diff --git a/queue-3.2/xhci-fix-encoding-for-hs-bulk-control-nak-rate.patch b/queue-3.2/xhci-fix-encoding-for-hs-bulk-control-nak-rate.patch new file mode 100644 index 00000000000..c78240778ab --- /dev/null +++ b/queue-3.2/xhci-fix-encoding-for-hs-bulk-control-nak-rate.patch @@ -0,0 +1,96 @@ +From 340a3504fd39dad753ba908fb6f894ee81fc3ae2 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Mon, 13 Feb 2012 14:42:11 -0800 +Subject: xhci: Fix encoding for HS bulk/control NAK rate. + +From: Sarah Sharp + +commit 340a3504fd39dad753ba908fb6f894ee81fc3ae2 upstream. + +The xHCI 0.96 spec says that HS bulk and control endpoint NAK rate must +be encoded as an exponent of two number of microframes. The endpoint +descriptor has the NAK rate encoded in number of microframes. We were +just copying the value from the endpoint descriptor into the endpoint +context interval field, which was not correct. This lead to the VIA +host rejecting the add of a bulk OUT endpoint from any USB 2.0 mass +storage device. + +The fix is to use the correct encoding. Refactor the code to convert +number of frames to an exponential number of microframes, and make sure +we convert the number of microframes in HS bulk and control endpoints to +an exponent. + +This should be back ported to kernels as old as 2.6.31, that contain the +commit dfa49c4ad120a784ef1ff0717168aa79f55a483a "USB: xhci - fix math +in xhci_get_endpoint_interval" + +Signed-off-by: Sarah Sharp +Tested-by: Felipe Contreras +Suggested-by: Andiry Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-mem.c | 32 ++++++++++++++++++++++++-------- + 1 file changed, 24 insertions(+), 8 deletions(-) + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1140,26 +1140,42 @@ static unsigned int xhci_parse_exponent_ + } + + /* +- * Convert bInterval expressed in frames (in 1-255 range) to exponent of ++ * Convert bInterval expressed in microframes (in 1-255 range) to exponent of + * microframes, rounded down to nearest power of 2. + */ +-static unsigned int xhci_parse_frame_interval(struct usb_device *udev, +- struct usb_host_endpoint *ep) ++static unsigned int xhci_microframes_to_exponent(struct usb_device *udev, ++ struct usb_host_endpoint *ep, unsigned int desc_interval, ++ unsigned int min_exponent, unsigned int max_exponent) + { + unsigned int interval; + +- interval = fls(8 * ep->desc.bInterval) - 1; +- interval = clamp_val(interval, 3, 10); +- if ((1 << interval) != 8 * ep->desc.bInterval) ++ interval = fls(desc_interval) - 1; ++ interval = clamp_val(interval, min_exponent, max_exponent); ++ if ((1 << interval) != desc_interval) + dev_warn(&udev->dev, + "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n", + ep->desc.bEndpointAddress, + 1 << interval, +- 8 * ep->desc.bInterval); ++ desc_interval); + + return interval; + } + ++static unsigned int xhci_parse_microframe_interval(struct usb_device *udev, ++ struct usb_host_endpoint *ep) ++{ ++ return xhci_microframes_to_exponent(udev, ep, ++ ep->desc.bInterval, 0, 15); ++} ++ ++ ++static unsigned int xhci_parse_frame_interval(struct usb_device *udev, ++ struct usb_host_endpoint *ep) ++{ ++ return xhci_microframes_to_exponent(udev, ep, ++ ep->desc.bInterval * 8, 3, 10); ++} ++ + /* Return the polling or NAK interval. + * + * The polling interval is expressed in "microframes". If xHCI's Interval field +@@ -1178,7 +1194,7 @@ static unsigned int xhci_get_endpoint_in + /* Max NAK rate */ + if (usb_endpoint_xfer_control(&ep->desc) || + usb_endpoint_xfer_bulk(&ep->desc)) { +- interval = ep->desc.bInterval; ++ interval = xhci_parse_microframe_interval(udev, ep); + break; + } + /* Fall through - SS and HS isoc/int have same decoding */ diff --git a/queue-3.2/xhci-fix-oops-caused-by-more-usb2-ports-than-usb3-ports.patch b/queue-3.2/xhci-fix-oops-caused-by-more-usb2-ports-than-usb3-ports.patch new file mode 100644 index 00000000000..0edb3a9eb74 --- /dev/null +++ b/queue-3.2/xhci-fix-oops-caused-by-more-usb2-ports-than-usb3-ports.patch @@ -0,0 +1,36 @@ +From 3278a55a1aebe2bbd47fbb5196209e5326a88b56 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Thu, 9 Feb 2012 14:43:44 -0800 +Subject: xhci: Fix oops caused by more USB2 ports than USB3 ports. + +From: Sarah Sharp + +commit 3278a55a1aebe2bbd47fbb5196209e5326a88b56 upstream. + +The code to set the device removable bits in the USB 2.0 roothub +descriptor was accidentally looking at the USB 3.0 port registers +instead of the USB 2.0 registers. This can cause an oops if there are +more USB 2.0 registers than USB 3.0 registers. + +This should be backported to kernels as old as 2.6.39, that contain the +commit 4bbb0ace9a3de8392527e3c87926309d541d3b00 "xhci: Return a USB 3.0 +hub descriptor for USB3 roothub." + +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hub.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -95,7 +95,7 @@ static void xhci_usb2_hub_descriptor(str + */ + memset(port_removable, 0, sizeof(port_removable)); + for (i = 0; i < ports; i++) { +- portsc = xhci_readl(xhci, xhci->usb3_ports[i]); ++ portsc = xhci_readl(xhci, xhci->usb2_ports[i]); + /* If a device is removable, PORTSC reports a 0, same as in the + * hub descriptor DeviceRemovable bits. + */ -- 2.47.3