From f58a7b3c069cfe4537fbddf0a0af85a9113b2f1b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 24 Apr 2012 10:28:40 -0700 Subject: [PATCH] 3.3-stable patches 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 --- ...-always-clear-the-sts_flr-status-bit.patch | 43 +++++++ ...-criterion-for-resuming-the-root-hub.patch | 45 +++++++ queue-3.3/series | 4 + ...bconfigurationvalue-attribute-method.patch | 110 ++++++++++++++++++ ...a-avoid-qmi-wwan-interface-on-mc77xx.patch | 57 +++++++++ 5 files changed, 259 insertions(+) create mode 100644 queue-3.3/ehci-always-clear-the-sts_flr-status-bit.patch create mode 100644 queue-3.3/ehci-fix-criterion-for-resuming-the-root-hub.patch create mode 100644 queue-3.3/usb-fix-deadlock-in-bconfigurationvalue-attribute-method.patch create mode 100644 queue-3.3/usb-sierra-avoid-qmi-wwan-interface-on-mc77xx.patch 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 index 00000000000..3aaa7ab7277 --- /dev/null +++ b/queue-3.3/ehci-always-clear-the-sts_flr-status-bit.patch @@ -0,0 +1,43 @@ +From 2fbe2bf1fd37f9d99950bd8d8093623cf22cf08b Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Wed, 18 Apr 2012 11:33:00 -0400 +Subject: EHCI: always clear the STS_FLR status bit + +From: Alan Stern + +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 +Reported-and-tested-by: Tomoya MORINAGA +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e598572d761 --- /dev/null +++ b/queue-3.3/ehci-fix-criterion-for-resuming-the-root-hub.patch @@ -0,0 +1,45 @@ +From dc75ce9d929aabeb0843a6b1a4ab320e58ba1597 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 17 Apr 2012 15:24:15 -0400 +Subject: EHCI: fix criterion for resuming the root hub + +From: Alan Stern + +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 +CC: Peter Chen +Signed-off-by: Greg Kroah-Hartman + +--- + 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 */ diff --git a/queue-3.3/series b/queue-3.3/series index bf9120a1b2a..0b4e01af79b 100644 --- a/queue-3.3/series +++ b/queue-3.3/series @@ -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 index 00000000000..3542edb2a44 --- /dev/null +++ b/queue-3.3/usb-fix-deadlock-in-bconfigurationvalue-attribute-method.patch @@ -0,0 +1,110 @@ +From 8963c487a80b4688c9e68dcc504a90074aacc145 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Tue, 17 Apr 2012 15:22:39 -0400 +Subject: USB: fix deadlock in bConfigurationValue attribute method + +From: Alan Stern + +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 +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a74b03fe811 --- /dev/null +++ b/queue-3.3/usb-sierra-avoid-qmi-wwan-interface-on-mc77xx.patch @@ -0,0 +1,57 @@ +From 749541d19e70905e3971f2a08335a206a98e4d0c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= +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 + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + }, -- 2.47.3