From: Greg Kroah-Hartman Date: Tue, 17 Apr 2012 23:59:41 +0000 (-0700) Subject: 3.3-stable patches X-Git-Tag: v3.2.16~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=715b035ee34c5ffae25a0783a50d3924a4dbd4ee;p=thirdparty%2Fkernel%2Fstable-queue.git 3.3-stable patches added patches: usb-fix-bug-of-device-descriptor-got-from-superspeed-device.patch xhci-add-xhci_reset_on_resume-quirk-for-via-xhci-host.patch xhci-correct-the-define-xhci_legacy_disable_smi.patch xhci-don-t-re-enable-ie-constantly.patch xhci-don-t-write-zeroed-pointers-to-xhc-registers.patch xhci-restore-event-ring-dequeue-pointer-on-resume.patch --- diff --git a/queue-3.3/series b/queue-3.3/series index bb8cd8e94b3..45bb5ad9fad 100644 --- a/queue-3.3/series +++ b/queue-3.3/series @@ -46,4 +46,9 @@ usb-ftdi_sio-fix-race-condition-in-tiocmiwait-and-abort-of-tiocmiwait-when-the-d usb-sierra-add-support-for-sierra-wireless-mc7710.patch usb-don-t-clear-urb-dev-in-scatter-gather-library.patch usb-don-t-ignore-suspend-errors-for-root-hubs.patch -usb-serial-metro-usb-fix-idproduct-for-uni-directional-mode.patch +xhci-don-t-re-enable-ie-constantly.patch +xhci-don-t-write-zeroed-pointers-to-xhc-registers.patch +xhci-restore-event-ring-dequeue-pointer-on-resume.patch +usb-fix-bug-of-device-descriptor-got-from-superspeed-device.patch +xhci-add-xhci_reset_on_resume-quirk-for-via-xhci-host.patch +xhci-correct-the-define-xhci_legacy_disable_smi.patch diff --git a/queue-3.3/usb-fix-bug-of-device-descriptor-got-from-superspeed-device.patch b/queue-3.3/usb-fix-bug-of-device-descriptor-got-from-superspeed-device.patch new file mode 100644 index 00000000000..018ed41ce89 --- /dev/null +++ b/queue-3.3/usb-fix-bug-of-device-descriptor-got-from-superspeed-device.patch @@ -0,0 +1,70 @@ +From d8aec3dbdfd02627e198e7956ab4aaeba2a349fa Mon Sep 17 00:00:00 2001 +From: Elric Fu +Date: Mon, 26 Mar 2012 21:16:02 +0800 +Subject: USB: fix bug of device descriptor got from superspeed device + +From: Elric Fu + +commit d8aec3dbdfd02627e198e7956ab4aaeba2a349fa upstream. + +When the Seagate Goflex USB3.0 device is attached to VIA xHCI +host, sometimes the device will downgrade mode to high speed. +By the USB analyzer, I found the device finished the link +training process and worked at superspeed mode. But the device +descriptor got from the device shows the device works at 2.1. +It is very strange and seems like the device controller of +Seagate Goflex has a little confusion. + +The first 8 bytes of device descriptor should be: +12 01 00 03 00 00 00 09 + +But the first 8 bytes of wrong device descriptor are: +12 01 10 02 00 00 00 40 + +The wrong device descriptor caused the initialization of mass +storage failed. After a while, the device would be recognized +as a high speed device and works fine. + +This patch will warm reset the device to fix the issue after +finding the bcdUSB field of device descriptor isn't 0x0300 +but the speed mode of device is superspeed. + +This patch should be backported to kernels as old as 3.2, or ones that +contain the commit 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: +refine warm reset logic". + +Signed-off-by: Elric Fu +Acked-by: Andiry Xu +Acked-by: Sergei Shtylyov +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -3071,6 +3071,22 @@ hub_port_init (struct usb_hub *hub, stru + if (retval) + goto fail; + ++ /* ++ * Some superspeed devices have finished the link training process ++ * and attached to a superspeed hub port, but the device descriptor ++ * got from those devices show they aren't superspeed devices. Warm ++ * reset the port attached by the devices can fix them. ++ */ ++ if ((udev->speed == USB_SPEED_SUPER) && ++ (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) { ++ dev_err(&udev->dev, "got a wrong device descriptor, " ++ "warm reset device\n"); ++ hub_port_reset(hub, port1, udev, ++ HUB_BH_RESET_TIME, true); ++ retval = -EINVAL; ++ goto fail; ++ } ++ + if (udev->descriptor.bMaxPacketSize0 == 0xff || + udev->speed == USB_SPEED_SUPER) + i = 512; diff --git a/queue-3.3/usb-serial-metro-usb-fix-idproduct-for-uni-directional-mode.patch b/queue-3.3/usb-serial-metro-usb-fix-idproduct-for-uni-directional-mode.patch deleted file mode 100644 index a30ed6ee0a7..00000000000 --- a/queue-3.3/usb-serial-metro-usb-fix-idproduct-for-uni-directional-mode.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 3a450850e2bb0f92cacb12da90fe98eccd105468 Mon Sep 17 00:00:00 2001 -From: Aleksey Babahin -Date: Tue, 20 Mar 2012 00:46:31 +0400 -Subject: USB: serial: metro-usb: Fix idProduct for Uni-Directional mode. - -From: Aleksey Babahin - -commit 3a450850e2bb0f92cacb12da90fe98eccd105468 upstream. - -The right idProduct for Metrologic Bar Code Scanner -in Uni-Directional Serial Emulation mode is 0x0700. - -Also rename idProduct for Bi-Directional mode to be a bit more informative. - -Signed-off-by: Aleksey Babahin -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c -index 6e1622f..08d16e8 100644 ---- a/drivers/usb/serial/metro-usb.c -+++ b/drivers/usb/serial/metro-usb.c -@@ -27,8 +27,8 @@ - - /* Product information. */ - #define FOCUS_VENDOR_ID 0x0C2E --#define FOCUS_PRODUCT_ID 0x0720 --#define FOCUS_PRODUCT_ID_UNI 0x0710 -+#define FOCUS_PRODUCT_ID_BI 0x0720 -+#define FOCUS_PRODUCT_ID_UNI 0x0700 - - #define METROUSB_SET_REQUEST_TYPE 0x40 - #define METROUSB_SET_MODEM_CTRL_REQUEST 10 -@@ -47,7 +47,7 @@ struct metrousb_private { - - /* Device table list. */ - static struct usb_device_id id_table[] = { -- { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID) }, -+ { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) }, - { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) }, - { }, /* Terminating entry. */ - }; diff --git a/queue-3.3/xhci-add-xhci_reset_on_resume-quirk-for-via-xhci-host.patch b/queue-3.3/xhci-add-xhci_reset_on_resume-quirk-for-via-xhci-host.patch new file mode 100644 index 00000000000..6ddc5189f35 --- /dev/null +++ b/queue-3.3/xhci-add-xhci_reset_on_resume-quirk-for-via-xhci-host.patch @@ -0,0 +1,41 @@ +From 457a4f61f9bfc3ae76e5b49f30f25d86bb696f67 Mon Sep 17 00:00:00 2001 +From: Elric Fu +Date: Thu, 29 Mar 2012 15:47:50 +0800 +Subject: xHCI: add XHCI_RESET_ON_RESUME quirk for VIA xHCI host + +From: Elric Fu + +commit 457a4f61f9bfc3ae76e5b49f30f25d86bb696f67 upstream. + +The suspend operation of VIA xHCI host have some issues and +hibernate operation works fine, so The XHCI_RESET_ON_RESUME +quirk is added for it. + +This patch should base on "xHCI: Don't write zeroed pointer +to xHC registers" that is released by Sarah. Otherwise, the +host system error will ocurr in the hibernate operation +process. + +This should be backported to stable kernels as old as 2.6.37, +that contain the commit c877b3b2ad5cb9d4fe523c5496185cc328ff3ae9 +"xhci: Add reset on resume quirk for asrock p67 host". + +Signed-off-by: Elric Fu +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-pci.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -95,6 +95,8 @@ static void xhci_pci_quirks(struct devic + xhci->quirks |= XHCI_RESET_ON_RESUME; + xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); + } ++ if (pdev->vendor == PCI_VENDOR_ID_VIA) ++ xhci->quirks |= XHCI_RESET_ON_RESUME; + } + + /* called during probe() after chip reset completes */ diff --git a/queue-3.3/xhci-correct-the-define-xhci_legacy_disable_smi.patch b/queue-3.3/xhci-correct-the-define-xhci_legacy_disable_smi.patch new file mode 100644 index 00000000000..6cda3045d50 --- /dev/null +++ b/queue-3.3/xhci-correct-the-define-xhci_legacy_disable_smi.patch @@ -0,0 +1,57 @@ +From 95018a53f7653e791bba1f54c8d75d9cb700d1bd Mon Sep 17 00:00:00 2001 +From: Alex He +Date: Fri, 30 Mar 2012 10:21:38 +0800 +Subject: xHCI: Correct the #define XHCI_LEGACY_DISABLE_SMI + +From: Alex He + +commit 95018a53f7653e791bba1f54c8d75d9cb700d1bd upstream. + +Re-define XHCI_LEGACY_DISABLE_SMI and used it in right way. All SMI enable +bits will be cleared to zero and flag bits 29:31 are also cleared to zero. +Other bits should be presvered as Table 146. + +This patch should be backported to kernels as old as 2.6.31. + +Signed-off-by: Alex He +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/pci-quirks.c | 10 +++++++--- + drivers/usb/host/xhci-ext-caps.h | 5 +++-- + 2 files changed, 10 insertions(+), 5 deletions(-) + +--- a/drivers/usb/host/pci-quirks.c ++++ b/drivers/usb/host/pci-quirks.c +@@ -825,9 +825,13 @@ static void __devinit quirk_usb_handoff_ + } + } + +- /* Disable any BIOS SMIs */ +- writel(XHCI_LEGACY_DISABLE_SMI, +- base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); ++ val = readl(base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); ++ /* Mask off (turn off) any enabled SMIs */ ++ val &= XHCI_LEGACY_DISABLE_SMI; ++ /* Mask all SMI events bits, RW1C */ ++ val |= XHCI_LEGACY_SMI_EVENTS; ++ /* Disable any BIOS SMIs and clear all SMI events*/ ++ writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); + + if (usb_is_intel_switchable_xhci(pdev)) + usb_enable_xhci_ports(pdev); +--- a/drivers/usb/host/xhci-ext-caps.h ++++ b/drivers/usb/host/xhci-ext-caps.h +@@ -62,8 +62,9 @@ + /* USB Legacy Support Control and Status Register - section 7.1.2 */ + /* Add this offset, plus the value of xECP in HCCPARAMS to the base address */ + #define XHCI_LEGACY_CONTROL_OFFSET (0x04) +-/* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ +-#define XHCI_LEGACY_DISABLE_SMI ((0x3 << 1) + (0xff << 5) + (0x7 << 17)) ++/* bits 1:3, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ ++#define XHCI_LEGACY_DISABLE_SMI ((0x7 << 1) + (0xff << 5) + (0x7 << 17)) ++#define XHCI_LEGACY_SMI_EVENTS (0x7 << 29) + + /* USB 2.0 xHCI 0.96 L1C capability - section 7.2.2.1.3.2 */ + #define XHCI_L1C (1 << 16) diff --git a/queue-3.3/xhci-don-t-re-enable-ie-constantly.patch b/queue-3.3/xhci-don-t-re-enable-ie-constantly.patch new file mode 100644 index 00000000000..70669b039cc --- /dev/null +++ b/queue-3.3/xhci-don-t-re-enable-ie-constantly.patch @@ -0,0 +1,54 @@ +From 4e833c0b87a30798e67f06120cecebef6ee9644c Mon Sep 17 00:00:00 2001 +From: Felipe Balbi +Date: Thu, 15 Mar 2012 16:37:08 +0200 +Subject: xhci: don't re-enable IE constantly + +From: Felipe Balbi + +commit 4e833c0b87a30798e67f06120cecebef6ee9644c upstream. + +While we're at that, define IMAN bitfield to aid readability. + +The interrupt enable bit should be set once on driver init, and we +shouldn't need to continually re-enable it. Commit c21599a3 introduced +a read of the irq_pending register, and that allows us to preserve the +state of the IE bit. Before that commit, we were blindly writing 0x3 to +the register. + +This patch should be backported to kernels as old as 2.6.36, or ones +that contain the commit c21599a36165dbc78b380846b254017a548b9de5 "USB: +xhci: Reduce reads and writes of interrupter registers". + +Signed-off-by: Felipe Balbi +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 2 +- + drivers/usb/host/xhci.h | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -2350,7 +2350,7 @@ hw_died: + u32 irq_pending; + /* Acknowledge the PCI interrupt */ + irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); +- irq_pending |= 0x3; ++ irq_pending |= IMAN_IP; + xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending); + } + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -205,6 +205,10 @@ struct xhci_op_regs { + #define CMD_PM_INDEX (1 << 11) + /* bits 12:31 are reserved (and should be preserved on writes). */ + ++/* IMAN - Interrupt Management Register */ ++#define IMAN_IP (1 << 1) ++#define IMAN_IE (1 << 0) ++ + /* USBSTS - USB status - status bitmasks */ + /* HC not running - set to 1 when run/stop bit is cleared. */ + #define STS_HALT XHCI_STS_HALT diff --git a/queue-3.3/xhci-don-t-write-zeroed-pointers-to-xhc-registers.patch b/queue-3.3/xhci-don-t-write-zeroed-pointers-to-xhc-registers.patch new file mode 100644 index 00000000000..e16aae443b8 --- /dev/null +++ b/queue-3.3/xhci-don-t-write-zeroed-pointers-to-xhc-registers.patch @@ -0,0 +1,76 @@ +From 159e1fcc9a60fc7daba23ee8fcdb99799de3fe84 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Fri, 16 Mar 2012 13:09:39 -0700 +Subject: xhci: Don't write zeroed pointers to xHC registers. + +From: Sarah Sharp + +commit 159e1fcc9a60fc7daba23ee8fcdb99799de3fe84 upstream. + +When xhci_mem_cleanup() is called, we can't be sure if the xHC is +actually halted. We can ask the xHC to halt by writing to the RUN bit +in the command register, but that might timeout due to a HW hang. + +If the host controller is still running, we should not write zeroed +values to the event ring dequeue pointers or base tables, the DCBAA +pointers, or the command ring pointers. Eric Fu reports his VIA VL800 +host accesses the event ring pointers after a failed register restore on +resume from suspend. The hypothesis is that the host never actually +halted before the register write to change the event ring pointer to +zero. + +Remove all writes of zeroed values to pointer registers in +xhci_mem_cleanup(). Instead, make all callers of the function reset the +host controller first, which will reset those registers to zero. +xhci_mem_init() is the only caller that doesn't first halt and reset the +host controller before calling xhci_mem_cleanup(). + +This should be backported to kernels as old as 2.6.32. + +Signed-off-by: Sarah Sharp +Tested-by: Elric Fu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-mem.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1690,11 +1690,6 @@ void xhci_mem_cleanup(struct xhci_hcd *x + int i; + + /* Free the Event Ring Segment Table and the actual Event Ring */ +- if (xhci->ir_set) { +- xhci_writel(xhci, 0, &xhci->ir_set->erst_size); +- xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); +- xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); +- } + size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); + if (xhci->erst.entries) + dma_free_coherent(&pdev->dev, size, +@@ -1706,7 +1701,6 @@ void xhci_mem_cleanup(struct xhci_hcd *x + xhci->event_ring = NULL; + xhci_dbg(xhci, "Freed event ring\n"); + +- xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring); + if (xhci->cmd_ring) + xhci_ring_free(xhci, xhci->cmd_ring); + xhci->cmd_ring = NULL; +@@ -1735,7 +1729,6 @@ void xhci_mem_cleanup(struct xhci_hcd *x + xhci->medium_streams_pool = NULL; + xhci_dbg(xhci, "Freed medium stream array pool\n"); + +- xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr); + if (xhci->dcbaa) + dma_free_coherent(&pdev->dev, sizeof(*xhci->dcbaa), + xhci->dcbaa, xhci->dcbaa->dma); +@@ -2344,6 +2337,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, + + fail: + xhci_warn(xhci, "Couldn't initialize memory\n"); ++ xhci_halt(xhci); ++ xhci_reset(xhci); + xhci_mem_cleanup(xhci); + return -ENOMEM; + } diff --git a/queue-3.3/xhci-restore-event-ring-dequeue-pointer-on-resume.patch b/queue-3.3/xhci-restore-event-ring-dequeue-pointer-on-resume.patch new file mode 100644 index 00000000000..a20b86a59fb --- /dev/null +++ b/queue-3.3/xhci-restore-event-ring-dequeue-pointer-on-resume.patch @@ -0,0 +1,37 @@ +From fb3d85bc7193f23c9a564502df95564c49a32c91 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Fri, 16 Mar 2012 13:27:39 -0700 +Subject: xhci: Restore event ring dequeue pointer on resume. + +From: Sarah Sharp + +commit fb3d85bc7193f23c9a564502df95564c49a32c91 upstream. + +The xhci_save_registers() function saved the event ring dequeue pointer +in the s3 register structure, but xhci_restore_registers() never +restored it. No other code in the xHCI successful resume path would +ever restore it either. Fix that. + +This should be backported to kernels as old as 2.6.37, that contain the +commit 5535b1d5f8885695c6ded783c692e3c0d0eda8ca "USB: xHCI: PCI power +management implementation". + +Signed-off-by: Sarah Sharp +Tested-by: Elric Fu +Cc: Andiry Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -681,6 +681,7 @@ static void xhci_restore_registers(struc + xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control); + xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size); + xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); ++ xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue); + } + + static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci)