]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 16 Aug 2013 22:59:38 +0000 (15:59 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 16 Aug 2013 22:59:38 +0000 (15:59 -0700)
added patches:
pm-qos-fix-workqueue-deadlock-when-using-pm_qos_update_request_timeout.patch
usb-add-two-quirky-touchscreen.patch
usb-ehci-accept-very-late-isochronous-urbs.patch
usb-keyspan-fix-null-deref-at-disconnect-and-release.patch
usb-mos7720-fix-broken-control-requests.patch
usb-mos7840-fix-big-endian-probe.patch
usb-serial-fix-error-handling-of-usb_wwan.patch
usb-ti_usb_3410_5052-fix-big-endian-firmware-handling.patch
wusbcore-fix-kernel-panic-when-disconnecting-a-wireless-usb-serial-device.patch

queue-3.10/pm-qos-fix-workqueue-deadlock-when-using-pm_qos_update_request_timeout.patch [new file with mode: 0644]
queue-3.10/series
queue-3.10/usb-add-two-quirky-touchscreen.patch [new file with mode: 0644]
queue-3.10/usb-ehci-accept-very-late-isochronous-urbs.patch [new file with mode: 0644]
queue-3.10/usb-keyspan-fix-null-deref-at-disconnect-and-release.patch [new file with mode: 0644]
queue-3.10/usb-mos7720-fix-broken-control-requests.patch [new file with mode: 0644]
queue-3.10/usb-mos7840-fix-big-endian-probe.patch [new file with mode: 0644]
queue-3.10/usb-serial-fix-error-handling-of-usb_wwan.patch [new file with mode: 0644]
queue-3.10/usb-ti_usb_3410_5052-fix-big-endian-firmware-handling.patch [new file with mode: 0644]
queue-3.10/wusbcore-fix-kernel-panic-when-disconnecting-a-wireless-usb-serial-device.patch [new file with mode: 0644]

diff --git a/queue-3.10/pm-qos-fix-workqueue-deadlock-when-using-pm_qos_update_request_timeout.patch b/queue-3.10/pm-qos-fix-workqueue-deadlock-when-using-pm_qos_update_request_timeout.patch
new file mode 100644 (file)
index 0000000..2b8b051
--- /dev/null
@@ -0,0 +1,69 @@
+From 40fea92ffb5fa0ef26d10ae0fe5688bc8e61c791 Mon Sep 17 00:00:00 2001
+From: Stephen Boyd <sboyd@codeaurora.org>
+Date: Tue, 13 Aug 2013 14:12:40 -0700
+Subject: PM / QoS: Fix workqueue deadlock when using pm_qos_update_request_timeout()
+
+From: Stephen Boyd <sboyd@codeaurora.org>
+
+commit 40fea92ffb5fa0ef26d10ae0fe5688bc8e61c791 upstream.
+
+pm_qos_update_request_timeout() updates a qos and then schedules
+a delayed work item to bring the qos back down to the default
+after the timeout. When the work item runs, pm_qos_work_fn() will
+call pm_qos_update_request() and deadlock because it tries to
+cancel itself via cancel_delayed_work_sync(). Future callers of
+that qos will also hang waiting to cancel the work that is
+canceling itself. Let's extract the little bit of code that does
+the real work of pm_qos_update_request() and call it from the
+work function so that we don't deadlock.
+
+Before ed1ac6e (PM: don't use [delayed_]work_pending()) this didn't
+happen because the work function wouldn't try to cancel itself.
+
+[backport to 3.10 - gregkh]
+
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+Reviewed-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/power/qos.c |   13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/kernel/power/qos.c
++++ b/kernel/power/qos.c
+@@ -293,6 +293,15 @@ int pm_qos_request_active(struct pm_qos_
+ }
+ EXPORT_SYMBOL_GPL(pm_qos_request_active);
++static void __pm_qos_update_request(struct pm_qos_request *req,
++                         s32 new_value)
++{
++      if (new_value != req->node.prio)
++              pm_qos_update_target(
++                      pm_qos_array[req->pm_qos_class]->constraints,
++                      &req->node, PM_QOS_UPDATE_REQ, new_value);
++}
++
+ /**
+  * pm_qos_work_fn - the timeout handler of pm_qos_update_request_timeout
+  * @work: work struct for the delayed work (timeout)
+@@ -305,7 +314,7 @@ static void pm_qos_work_fn(struct work_s
+                                                 struct pm_qos_request,
+                                                 work);
+-      pm_qos_update_request(req, PM_QOS_DEFAULT_VALUE);
++      __pm_qos_update_request(req, PM_QOS_DEFAULT_VALUE);
+ }
+ /**
+@@ -365,6 +374,8 @@ void pm_qos_update_request(struct pm_qos
+               pm_qos_update_target(
+                       pm_qos_array[req->pm_qos_class]->constraints,
+                       &req->node, PM_QOS_UPDATE_REQ, new_value);
++
++      __pm_qos_update_request(req, new_value);
+ }
+ EXPORT_SYMBOL_GPL(pm_qos_update_request);
index 811748c1566a492abeef402f7e814bddbb5faa42..e15a39c0b24f12b03406318489c72afed0bb97d6 100644 (file)
@@ -27,3 +27,12 @@ alsa-hda-fix-missing-mute-controls-for-cx5051.patch
 alsa-hda-add-pinfix-for-lg-lw25-laptop.patch
 alsa-hda-add-a-fixup-for-gateway-lt27.patch
 nl80211-fix-another-nl80211_fam.attrbuf-race.patch
+usb-add-two-quirky-touchscreen.patch
+usb-ti_usb_3410_5052-fix-big-endian-firmware-handling.patch
+usb-mos7840-fix-big-endian-probe.patch
+usb-mos7720-fix-broken-control-requests.patch
+usb-keyspan-fix-null-deref-at-disconnect-and-release.patch
+usb-ehci-accept-very-late-isochronous-urbs.patch
+usb-serial-fix-error-handling-of-usb_wwan.patch
+pm-qos-fix-workqueue-deadlock-when-using-pm_qos_update_request_timeout.patch
+wusbcore-fix-kernel-panic-when-disconnecting-a-wireless-usb-serial-device.patch
diff --git a/queue-3.10/usb-add-two-quirky-touchscreen.patch b/queue-3.10/usb-add-two-quirky-touchscreen.patch
new file mode 100644 (file)
index 0000000..b3bcd4e
--- /dev/null
@@ -0,0 +1,33 @@
+From 304ab4ab079a8ed03ce39f1d274964a532db036b Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.de>
+Date: Wed, 14 Aug 2013 11:01:46 +0200
+Subject: usb: add two quirky touchscreen
+
+From: Oliver Neukum <oneukum@suse.de>
+
+commit 304ab4ab079a8ed03ce39f1d274964a532db036b upstream.
+
+These devices tend to become unresponsive after S3
+
+Signed-off-by: Oliver Neukum <oneukum@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -78,6 +78,12 @@ static const struct usb_device_id usb_qu
+       { USB_DEVICE(0x04d8, 0x000c), .driver_info =
+                       USB_QUIRK_CONFIG_INTF_STRINGS },
++      /* CarrolTouch 4000U */
++      { USB_DEVICE(0x04e7, 0x0009), .driver_info = USB_QUIRK_RESET_RESUME },
++
++      /* CarrolTouch 4500U */
++      { USB_DEVICE(0x04e7, 0x0030), .driver_info = USB_QUIRK_RESET_RESUME },
++
+       /* Samsung Android phone modem - ID conflict with SPH-I500 */
+       { USB_DEVICE(0x04e8, 0x6601), .driver_info =
+                       USB_QUIRK_CONFIG_INTF_STRINGS },
diff --git a/queue-3.10/usb-ehci-accept-very-late-isochronous-urbs.patch b/queue-3.10/usb-ehci-accept-very-late-isochronous-urbs.patch
new file mode 100644 (file)
index 0000000..527f8cb
--- /dev/null
@@ -0,0 +1,73 @@
+From 24f531371de17010f2b1b57d90e42240032e7733 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 7 Aug 2013 10:58:05 -0400
+Subject: USB: EHCI: accept very late isochronous URBs
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 24f531371de17010f2b1b57d90e42240032e7733 upstream.
+
+Since commits 4005ad4390bf (EHCI: implement new semantics for
+URB_ISO_ASAP) and c75c5ab575af (ALSA: USB: adjust for changed 3.8 USB
+API) became widely distributed, people have been experiencing problems
+with audio transfers.  The slightest underrun causes complete failure,
+requiring the audio stream to be restarted.
+
+It turns out that the current isochronous API doesn't handle underruns
+in the best way.  The ALSA developers would much rather have transfers
+that are submitted too late be accepted and complete in the normal
+fashion, rather than being refused outright.
+
+This patch implements the requested approach.  When an isochronous URB
+submission is so late that all its scheduled slots have already
+expired, a debugging message will be printed in the log and the URB
+will be accepted as usual.  Assuming it was submitted by a completion
+handler (which is normally the case), it will complete shortly
+thereafter with all the usb_iso_packet_descriptor status fields marked
+-EXDEV.
+
+This fixes (for ehci-hcd)
+
+       https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1191603
+
+It should be applied to all kernels that include commit 4005ad4390bf.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Tested-by: Maksim Boyko <maksboyko@yandex.ru>
+CC: Clemens Ladisch <clemens@ladisch.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ehci-sched.c |   13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/host/ehci-sched.c
++++ b/drivers/usb/host/ehci-sched.c
+@@ -1391,21 +1391,20 @@ iso_stream_schedule (
+               /* Behind the scheduling threshold? */
+               if (unlikely(start < next)) {
++                      unsigned now2 = (now - base) & (mod - 1);
+                       /* USB_ISO_ASAP: Round up to the first available slot */
+                       if (urb->transfer_flags & URB_ISO_ASAP)
+                               start += (next - start + period - 1) & -period;
+                       /*
+-                       * Not ASAP: Use the next slot in the stream.  If
+-                       * the entire URB falls before the threshold, fail.
++                       * Not ASAP: Use the next slot in the stream,
++                       * no matter what.
+                        */
+-                      else if (start + span - period < next) {
+-                              ehci_dbg(ehci, "iso urb late %p (%u+%u < %u)\n",
++                      else if (start + span - period < now2) {
++                              ehci_dbg(ehci, "iso underrun %p (%u+%u < %u)\n",
+                                               urb, start + base,
+-                                              span - period, next + base);
+-                              status = -EXDEV;
+-                              goto fail;
++                                              span - period, now2 + base);
+                       }
+               }
diff --git a/queue-3.10/usb-keyspan-fix-null-deref-at-disconnect-and-release.patch b/queue-3.10/usb-keyspan-fix-null-deref-at-disconnect-and-release.patch
new file mode 100644 (file)
index 0000000..2ecb9d2
--- /dev/null
@@ -0,0 +1,31 @@
+From ff8a43c10f1440f07a5faca0c1556921259f7f76 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 13 Aug 2013 13:27:35 +0200
+Subject: USB: keyspan: fix null-deref at disconnect and release
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit ff8a43c10f1440f07a5faca0c1556921259f7f76 upstream.
+
+Make sure to fail properly if the device is not accepted during attach
+in order to avoid null-pointer derefs (of missing interface private
+data) at disconnect or release.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/keyspan.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/serial/keyspan.c
++++ b/drivers/usb/serial/keyspan.c
+@@ -2315,7 +2315,7 @@ static int keyspan_startup(struct usb_se
+       if (d_details == NULL) {
+               dev_err(&serial->dev->dev, "%s - unknown product id %x\n",
+                   __func__, le16_to_cpu(serial->dev->descriptor.idProduct));
+-              return 1;
++              return -ENODEV;
+       }
+       /* Setup private data for serial driver */
diff --git a/queue-3.10/usb-mos7720-fix-broken-control-requests.patch b/queue-3.10/usb-mos7720-fix-broken-control-requests.patch
new file mode 100644 (file)
index 0000000..2fe1fcc
--- /dev/null
@@ -0,0 +1,74 @@
+From ef6c8c1d733e244f0499035be0dabe1f4ed98c6f Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 13 Aug 2013 13:27:34 +0200
+Subject: USB: mos7720: fix broken control requests
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit ef6c8c1d733e244f0499035be0dabe1f4ed98c6f upstream.
+
+The parallel-port code of the drivers used a stack allocated
+control-request buffer for asynchronous (and possibly deferred) control
+requests. This not only violates the no-DMA-from-stack requirement but
+could also lead to corrupt control requests being submitted.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7720.c |   21 ++++++++++++++-------
+ 1 file changed, 14 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/serial/mos7720.c
++++ b/drivers/usb/serial/mos7720.c
+@@ -90,6 +90,7 @@ struct urbtracker {
+       struct list_head        urblist_entry;
+       struct kref             ref_count;
+       struct urb              *urb;
++      struct usb_ctrlrequest  *setup;
+ };
+ enum mos7715_pp_modes {
+@@ -271,6 +272,7 @@ static void destroy_urbtracker(struct kr
+       struct mos7715_parport *mos_parport = urbtrack->mos_parport;
+       usb_free_urb(urbtrack->urb);
++      kfree(urbtrack->setup);
+       kfree(urbtrack);
+       kref_put(&mos_parport->ref_count, destroy_mos_parport);
+ }
+@@ -355,7 +357,6 @@ static int write_parport_reg_nonblock(st
+       struct urbtracker *urbtrack;
+       int ret_val;
+       unsigned long flags;
+-      struct usb_ctrlrequest setup;
+       struct usb_serial *serial = mos_parport->serial;
+       struct usb_device *usbdev = serial->dev;
+@@ -373,14 +374,20 @@ static int write_parport_reg_nonblock(st
+               kfree(urbtrack);
+               return -ENOMEM;
+       }
+-      setup.bRequestType = (__u8)0x40;
+-      setup.bRequest = (__u8)0x0e;
+-      setup.wValue = get_reg_value(reg, dummy);
+-      setup.wIndex = get_reg_index(reg);
+-      setup.wLength = 0;
++      urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL);
++      if (!urbtrack->setup) {
++              usb_free_urb(urbtrack->urb);
++              kfree(urbtrack);
++              return -ENOMEM;
++      }
++      urbtrack->setup->bRequestType = (__u8)0x40;
++      urbtrack->setup->bRequest = (__u8)0x0e;
++      urbtrack->setup->wValue = get_reg_value(reg, dummy);
++      urbtrack->setup->wIndex = get_reg_index(reg);
++      urbtrack->setup->wLength = 0;
+       usb_fill_control_urb(urbtrack->urb, usbdev,
+                            usb_sndctrlpipe(usbdev, 0),
+-                           (unsigned char *)&setup,
++                           (unsigned char *)urbtrack->setup,
+                            NULL, 0, async_complete, urbtrack);
+       kref_init(&urbtrack->ref_count);
+       INIT_LIST_HEAD(&urbtrack->urblist_entry);
diff --git a/queue-3.10/usb-mos7840-fix-big-endian-probe.patch b/queue-3.10/usb-mos7840-fix-big-endian-probe.patch
new file mode 100644 (file)
index 0000000..b48c93d
--- /dev/null
@@ -0,0 +1,32 @@
+From d551ec9b690f3de65b0091a2e767f1382adc792d Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Sun, 11 Aug 2013 16:49:20 +0200
+Subject: USB: mos7840: fix big-endian probe
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit d551ec9b690f3de65b0091a2e767f1382adc792d upstream.
+
+Fix bug in device-type detection on big-endian machines originally
+introduced by commit 0eafe4de ("USB: serial: mos7840: add support for
+MCS7810 devices") which always matched on little-endian product ids.
+
+Reported-by: kbuild test robot <fengguang.wu@intel.com>
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7840.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -2208,7 +2208,7 @@ static int mos7810_check(struct usb_seri
+ static int mos7840_probe(struct usb_serial *serial,
+                               const struct usb_device_id *id)
+ {
+-      u16 product = serial->dev->descriptor.idProduct;
++      u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
+       u8 *buf;
+       int device_type;
diff --git a/queue-3.10/usb-serial-fix-error-handling-of-usb_wwan.patch b/queue-3.10/usb-serial-fix-error-handling-of-usb_wwan.patch
new file mode 100644 (file)
index 0000000..2b968f8
--- /dev/null
@@ -0,0 +1,53 @@
+From 6c1ee66a0b2bdbd64c078fba684d640cf2fd38a9 Mon Sep 17 00:00:00 2001
+From: Matt Burtch <matt@grid-net.com>
+Date: Mon, 12 Aug 2013 10:11:39 -0700
+Subject: USB-Serial: Fix error handling of usb_wwan
+
+From: Matt Burtch <matt@grid-net.com>
+
+commit 6c1ee66a0b2bdbd64c078fba684d640cf2fd38a9 upstream.
+
+This fixes an issue where the bulk-in urb used for incoming data transfer
+is not resubmitted if the packet recieved contains an error status.  This
+results in the driver locking until the port is closed and re-opened.
+
+Tested on a custom board with a Cinterion GSM module.
+
+Signed-off-by: Matt Burtch <matt@grid-net.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/usb_wwan.c |   20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+--- a/drivers/usb/serial/usb_wwan.c
++++ b/drivers/usb/serial/usb_wwan.c
+@@ -291,18 +291,18 @@ static void usb_wwan_indat_callback(stru
+                       tty_flip_buffer_push(&port->port);
+               } else
+                       dev_dbg(dev, "%s: empty read urb received\n", __func__);
+-
+-              /* Resubmit urb so we continue receiving */
+-              err = usb_submit_urb(urb, GFP_ATOMIC);
+-              if (err) {
+-                      if (err != -EPERM) {
+-                              dev_err(dev, "%s: resubmit read urb failed. (%d)\n", __func__, err);
+-                              /* busy also in error unless we are killed */
+-                              usb_mark_last_busy(port->serial->dev);
+-                      }
+-              } else {
++      }
++      /* Resubmit urb so we continue receiving */
++      err = usb_submit_urb(urb, GFP_ATOMIC);
++      if (err) {
++              if (err != -EPERM) {
++                      dev_err(dev, "%s: resubmit read urb failed. (%d)\n",
++                              __func__, err);
++                      /* busy also in error unless we are killed */
+                       usb_mark_last_busy(port->serial->dev);
+               }
++      } else {
++              usb_mark_last_busy(port->serial->dev);
+       }
+ }
diff --git a/queue-3.10/usb-ti_usb_3410_5052-fix-big-endian-firmware-handling.patch b/queue-3.10/usb-ti_usb_3410_5052-fix-big-endian-firmware-handling.patch
new file mode 100644 (file)
index 0000000..4a787f2
--- /dev/null
@@ -0,0 +1,43 @@
+From e877dd2f2581628b7119df707d4cf03d940cff49 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Sun, 11 Aug 2013 16:49:23 +0200
+Subject: USB: ti_usb_3410_5052: fix big-endian firmware handling
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit e877dd2f2581628b7119df707d4cf03d940cff49 upstream.
+
+Fix endianess bugs in firmware handling introduced by commits cb7a7c6a
+("ti_usb_3410_5052: add Multi-Tech modem support") and 05a3d905
+("ti_usb_3410_5052: support alternate firmware") which made the driver
+use the wrong firmware for certain devices on big-endian machines.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ti_usb_3410_5052.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/serial/ti_usb_3410_5052.c
++++ b/drivers/usb/serial/ti_usb_3410_5052.c
+@@ -1536,14 +1536,15 @@ static int ti_download_firmware(struct t
+       char buf[32];
+       /* try ID specific firmware first, then try generic firmware */
+-      sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor,
+-          dev->descriptor.idProduct);
++      sprintf(buf, "ti_usb-v%04x-p%04x.fw",
++                      le16_to_cpu(dev->descriptor.idVendor),
++                      le16_to_cpu(dev->descriptor.idProduct));
+       status = request_firmware(&fw_p, buf, &dev->dev);
+       if (status != 0) {
+               buf[0] = '\0';
+-              if (dev->descriptor.idVendor == MTS_VENDOR_ID) {
+-                      switch (dev->descriptor.idProduct) {
++              if (le16_to_cpu(dev->descriptor.idVendor) == MTS_VENDOR_ID) {
++                      switch (le16_to_cpu(dev->descriptor.idProduct)) {
+                       case MTS_CDMA_PRODUCT_ID:
+                               strcpy(buf, "mts_cdma.fw");
+                               break;
diff --git a/queue-3.10/wusbcore-fix-kernel-panic-when-disconnecting-a-wireless-usb-serial-device.patch b/queue-3.10/wusbcore-fix-kernel-panic-when-disconnecting-a-wireless-usb-serial-device.patch
new file mode 100644 (file)
index 0000000..ad415ee
--- /dev/null
@@ -0,0 +1,53 @@
+From ec58fad1feb76c323ef47efff1d1e8660ed4644c Mon Sep 17 00:00:00 2001
+From: Thomas Pugliese <thomas.pugliese@gmail.com>
+Date: Fri, 9 Aug 2013 09:52:13 -0500
+Subject: wusbcore: fix kernel panic when disconnecting a wireless USB->serial device
+
+From: Thomas Pugliese <thomas.pugliese@gmail.com>
+
+commit ec58fad1feb76c323ef47efff1d1e8660ed4644c upstream.
+
+This patch fixes a kernel panic that can occur when disconnecting a
+wireless USB->serial device.  When the serial device disconnects, the
+device cleanup procedure ends up calling usb_hcd_disable_endpoint on the
+serial device's endpoints.  The wusbcore uses the ABORT_RPIPE command to
+abort all transfers on the given endpoint but it does not properly give
+back the URBs when the transfer results return from the HWA.  This patch
+prevents the transfer result processing code from bailing out when it sees
+a WA_XFER_STATUS_ABORTED result code so that these urbs are flushed
+properly by usb_hcd_disable_endpoint.  It also updates wa_urb_dequeue to
+handle the case where the endpoint has already been cleaned up when
+usb_kill_urb is called which is where the panic originally occurred.
+
+Signed-off-by: Thomas Pugliese <thomas.pugliese@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/wusbcore/wa-xfer.c |    9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/wusbcore/wa-xfer.c
++++ b/drivers/usb/wusbcore/wa-xfer.c
+@@ -1110,6 +1110,12 @@ int wa_urb_dequeue(struct wahc *wa, stru
+       }
+       spin_lock_irqsave(&xfer->lock, flags);
+       rpipe = xfer->ep->hcpriv;
++      if (rpipe == NULL) {
++              pr_debug("%s: xfer id 0x%08X has no RPIPE.  %s",
++                      __func__, wa_xfer_id(xfer),
++                      "Probably already aborted.\n" );
++              goto out_unlock;
++      }
+       /* Check the delayed list -> if there, release and complete */
+       spin_lock_irqsave(&wa->xfer_list_lock, flags2);
+       if (!list_empty(&xfer->list_node) && xfer->seg == NULL)
+@@ -1493,8 +1499,7 @@ static void wa_xfer_result_cb(struct urb
+                       break;
+               }
+               usb_status = xfer_result->bTransferStatus & 0x3f;
+-              if (usb_status == WA_XFER_STATUS_ABORTED
+-                  || usb_status == WA_XFER_STATUS_NOT_FOUND)
++              if (usb_status == WA_XFER_STATUS_NOT_FOUND)
+                       /* taken care of already */
+                       break;
+               xfer_id = xfer_result->dwTransferID;