]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Apr 2012 17:28:40 +0000 (10:28 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Apr 2012 17:28:40 +0000 (10:28 -0700)
added patches:
ehci-always-clear-the-sts_flr-status-bit.patch
ehci-fix-criterion-for-resuming-the-root-hub.patch
usb-fix-deadlock-in-bconfigurationvalue-attribute-method.patch
usb-sierra-avoid-qmi-wwan-interface-on-mc77xx.patch

queue-3.3/ehci-always-clear-the-sts_flr-status-bit.patch [new file with mode: 0644]
queue-3.3/ehci-fix-criterion-for-resuming-the-root-hub.patch [new file with mode: 0644]
queue-3.3/series
queue-3.3/usb-fix-deadlock-in-bconfigurationvalue-attribute-method.patch [new file with mode: 0644]
queue-3.3/usb-sierra-avoid-qmi-wwan-interface-on-mc77xx.patch [new file with mode: 0644]

diff --git a/queue-3.3/ehci-always-clear-the-sts_flr-status-bit.patch b/queue-3.3/ehci-always-clear-the-sts_flr-status-bit.patch
new file mode 100644 (file)
index 0000000..3aaa7ab
--- /dev/null
@@ -0,0 +1,43 @@
+From 2fbe2bf1fd37f9d99950bd8d8093623cf22cf08b Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 18 Apr 2012 11:33:00 -0400
+Subject: EHCI: always clear the STS_FLR status bit
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 2fbe2bf1fd37f9d99950bd8d8093623cf22cf08b upstream.
+
+This patch (as1544) fixes a problem affecting some EHCI controllers.
+They can generate interrupts whenever the STS_FLR status bit is turned
+on, even though that bit is masked out in the Interrupt Enable
+register.
+
+Since the driver doesn't use STS_FLR anyway, the patch changes the
+interrupt routine to clear that bit whenever it is set, rather than
+leaving it alone.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-and-tested-by: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ehci-hcd.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -857,8 +857,13 @@ static irqreturn_t ehci_irq (struct usb_
+               goto dead;
+       }
++      /*
++       * We don't use STS_FLR, but some controllers don't like it to
++       * remain on, so mask it out along with the other status bits.
++       */
++      masked_status = status & (INTR_MASK | STS_FLR);
++
+       /* Shared IRQ? */
+-      masked_status = status & INTR_MASK;
+       if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {
+               spin_unlock(&ehci->lock);
+               return IRQ_NONE;
diff --git a/queue-3.3/ehci-fix-criterion-for-resuming-the-root-hub.patch b/queue-3.3/ehci-fix-criterion-for-resuming-the-root-hub.patch
new file mode 100644 (file)
index 0000000..e598572
--- /dev/null
@@ -0,0 +1,45 @@
+From dc75ce9d929aabeb0843a6b1a4ab320e58ba1597 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 17 Apr 2012 15:24:15 -0400
+Subject: EHCI: fix criterion for resuming the root hub
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit dc75ce9d929aabeb0843a6b1a4ab320e58ba1597 upstream.
+
+This patch (as1542) changes the criterion ehci-hcd uses to tell when
+it needs to resume the controller's root hub.  A resume is needed when
+a port status change is detected, obviously, but only if the root hub
+is currently suspended.
+
+Right now the driver tests whether the root hub is running, and that
+is not the correct test.  In particular, if the controller has died
+then the root hub should not be restarted.  In addition, some buggy
+hardware occasionally requires the root hub to be running and
+sending out SOF packets even while it is nominally supposed to be
+suspended.
+
+In the end, the test needs to be changed.  Rather than checking whether
+the root hub is currently running, the driver will now check whether
+the root hub is currently suspended.  This will yield the correct
+behavior in all cases.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+CC: Peter Chen <B29397@freescale.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ehci-hcd.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -909,7 +909,7 @@ static irqreturn_t ehci_irq (struct usb_
+               pcd_status = status;
+               /* resume root hub? */
+-              if (!(cmd & CMD_RUN))
++              if (ehci->rh_state == EHCI_RH_SUSPENDED)
+                       usb_hcd_resume_root_hub(hcd);
+               /* get per-port change detect bits */
index bf9120a1b2abd0013b36c60483edc4772f2755d0..0b4e01af79b6825748111871da58679789a96d8a 100644 (file)
@@ -35,3 +35,7 @@ jbd2-use-gfp_nofs-for-blkdev_issue_flush.patch
 usb-serial-cp210x-fixed-usb_control_msg-timeout-values.patch
 pch_uart-fix-dma-channel-unallocated-issue.patch
 drivers-tty-amiserial.c-add-missing-tty_unlock.patch
+usb-sierra-avoid-qmi-wwan-interface-on-mc77xx.patch
+ehci-fix-criterion-for-resuming-the-root-hub.patch
+ehci-always-clear-the-sts_flr-status-bit.patch
+usb-fix-deadlock-in-bconfigurationvalue-attribute-method.patch
diff --git a/queue-3.3/usb-fix-deadlock-in-bconfigurationvalue-attribute-method.patch b/queue-3.3/usb-fix-deadlock-in-bconfigurationvalue-attribute-method.patch
new file mode 100644 (file)
index 0000000..3542edb
--- /dev/null
@@ -0,0 +1,110 @@
+From 8963c487a80b4688c9e68dcc504a90074aacc145 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 17 Apr 2012 15:22:39 -0400
+Subject: USB: fix deadlock in bConfigurationValue attribute method
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 8963c487a80b4688c9e68dcc504a90074aacc145 upstream.
+
+This patch (as154) fixes a self-deadlock that occurs when userspace
+writes to the bConfigurationValue sysfs attribute for a hub with
+children.  The task tries to lock the bandwidth_mutex at a time when
+it already owns the lock:
+
+       The attribute's method calls usb_set_configuration(),
+       which calls usb_disable_device() with the bandwidth_mutex
+       held.
+
+       usb_disable_device() unregisters the existing interfaces,
+       which causes the hub driver to be unbound.
+
+       The hub_disconnect() routine calls hub_quiesce(), which
+       calls usb_disconnect() for each of the hub's children.
+
+       usb_disconnect() attempts to acquire the bandwidth_mutex
+       around a call to usb_disable_device().
+
+The solution is to make usb_disable_device() acquire the mutex for
+itself instead of requiring the caller to hold it.  Then the mutex can
+cover only the bandwidth deallocation operation and not the region
+where the interfaces are unregistered.
+
+This has the potential to change system behavior slightly when a
+config change races with another config or altsetting change.  Some of
+the bandwidth released from the old config might get claimed by the
+other config or altsetting, make it impossible to restore the old
+config in case of a failure.  But since we don't try to recover from
+config-change failures anyway, this doesn't matter.
+
+[This should be marked for stable kernels that contain the commit
+fccf4e86200b8f5edd9a65da26f150e32ba79808 "USB: Free bandwidth when
+usb_disable_device is called."
+That commit was marked for stable kernels as old as 2.6.32.]
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c     |    3 ---
+ drivers/usb/core/message.c |    6 +++---
+ 2 files changed, 3 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1643,7 +1643,6 @@ void usb_disconnect(struct usb_device **
+ {
+       struct usb_device       *udev = *pdev;
+       int                     i;
+-      struct usb_hcd          *hcd = bus_to_hcd(udev->bus);
+       /* mark the device as inactive, so any further urb submissions for
+        * this device (and any of its children) will fail immediately.
+@@ -1666,9 +1665,7 @@ void usb_disconnect(struct usb_device **
+        * so that the hardware is now fully quiesced.
+        */
+       dev_dbg (&udev->dev, "unregistering device\n");
+-      mutex_lock(hcd->bandwidth_mutex);
+       usb_disable_device(udev, 0);
+-      mutex_unlock(hcd->bandwidth_mutex);
+       usb_hcd_synchronize_unlinks(udev);
+       usb_remove_ep_devs(&udev->ep0);
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -1136,8 +1136,6 @@ void usb_disable_interface(struct usb_de
+  * Deallocates hcd/hardware state for the endpoints (nuking all or most
+  * pending urbs) and usbcore state for the interfaces, so that usbcore
+  * must usb_set_configuration() before any interfaces could be used.
+- *
+- * Must be called with hcd->bandwidth_mutex held.
+  */
+ void usb_disable_device(struct usb_device *dev, int skip_ep0)
+ {
+@@ -1190,7 +1188,9 @@ void usb_disable_device(struct usb_devic
+                       usb_disable_endpoint(dev, i + USB_DIR_IN, false);
+               }
+               /* Remove endpoints from the host controller internal state */
++              mutex_lock(hcd->bandwidth_mutex);
+               usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
++              mutex_unlock(hcd->bandwidth_mutex);
+               /* Second pass: remove endpoint pointers */
+       }
+       for (i = skip_ep0; i < 16; ++i) {
+@@ -1750,7 +1750,6 @@ free_interfaces:
+       /* if it's already configured, clear out old state first.
+        * getting rid of old interfaces means unbinding their drivers.
+        */
+-      mutex_lock(hcd->bandwidth_mutex);
+       if (dev->state != USB_STATE_ADDRESS)
+               usb_disable_device(dev, 1);     /* Skip ep0 */
+@@ -1763,6 +1762,7 @@ free_interfaces:
+        * host controller will not allow submissions to dropped endpoints.  If
+        * this call fails, the device state is unchanged.
+        */
++      mutex_lock(hcd->bandwidth_mutex);
+       ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
+       if (ret < 0) {
+               mutex_unlock(hcd->bandwidth_mutex);
diff --git a/queue-3.3/usb-sierra-avoid-qmi-wwan-interface-on-mc77xx.patch b/queue-3.3/usb-sierra-avoid-qmi-wwan-interface-on-mc77xx.patch
new file mode 100644 (file)
index 0000000..a74b03f
--- /dev/null
@@ -0,0 +1,57 @@
+From 749541d19e70905e3971f2a08335a206a98e4d0c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+Date: Tue, 17 Apr 2012 21:37:29 +0200
+Subject: USB: sierra: avoid QMI/wwan interface on MC77xx
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Bjørn Mork <bjorn@mork.no>
+
+commit 749541d19e70905e3971f2a08335a206a98e4d0c upstream.
+
+These devices have a number of non serial interfaces as well.  Use
+the existing "Direct IP" blacklist to prevent binding to interfaces
+which are handled by other drivers.
+
+We also extend the "Direct IP" blacklist with with interfaces only
+seen in "QMI" mode, assuming that these devices use the same
+interface numbers for serial interfaces both in "Direct IP" and in
+"QMI" mode.
+
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/sierra.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/serial/sierra.c
++++ b/drivers/usb/serial/sierra.c
+@@ -221,7 +221,7 @@ static const struct sierra_iface_info ty
+ };
+ /* 'blacklist' of interfaces not served by this driver */
+-static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 };
++static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 };
+ static const struct sierra_iface_info direct_ip_interface_blacklist = {
+       .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces),
+       .ifaceinfo = direct_ip_non_serial_ifaces,
+@@ -289,7 +289,6 @@ static const struct usb_device_id id_tab
+       { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */
+       { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */
+       { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
+-      { USB_DEVICE(0x1199, 0x68A2) }, /* Sierra Wireless MC7710 */
+       /* Sierra Wireless C885 */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
+       /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */
+@@ -299,6 +298,9 @@ static const struct usb_device_id id_tab
+       /* Sierra Wireless HSPA Non-Composite Device */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
+       { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */
++      { USB_DEVICE(0x1199, 0x68A2),   /* Sierra Wireless MC77xx in QMI mode */
++        .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
++      },
+       { USB_DEVICE(0x1199, 0x68A3),   /* Sierra Wireless Direct IP modems */
+         .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
+       },