usb-usb_wwan-fix-urb-leak-at-shutdown.patch
usb-usb_wwan-fix-potential-null-deref-at-resume.patch
usb-usb_wwan-fix-potential-blocked-i-o-after-resume.patch
+usb-sierra-fix-aa-deadlock-in-open-error-path.patch
+usb-sierra-fix-use-after-free-at-suspend-resume.patch
+usb-sierra-fix-urb-and-memory-leak-in-resume-error-path.patch
+usb-sierra-fix-urb-and-memory-leak-on-disconnect.patch
+usb-sierra-fix-remote-wakeup.patch
--- /dev/null
+From 353fe198602e8b4d1c7bdcceb8e60955087201b1 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Mon, 26 May 2014 19:22:50 +0200
+Subject: USB: sierra: fix AA deadlock in open error path
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 353fe198602e8b4d1c7bdcceb8e60955087201b1 upstream.
+
+Fix AA deadlock in open error path that would call close() and try to
+grab the already held disc_mutex.
+
+Fixes: b9a44bc19f48 ("sierra: driver urb handling improvements")
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/sierra.c | 21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/serial/sierra.c
++++ b/drivers/usb/serial/sierra.c
+@@ -816,14 +816,9 @@ static int sierra_open(struct tty_struct
+ usb_sndbulkpipe(serial->dev, endpoint) | USB_DIR_IN);
+
+ err = sierra_submit_rx_urbs(port, GFP_KERNEL);
+- if (err) {
+- /* get rid of everything as in close */
+- sierra_close(port);
+- /* restore balance for autopm */
+- if (!serial->disconnected)
+- usb_autopm_put_interface(serial->interface);
+- return err;
+- }
++ if (err)
++ goto err_submit;
++
+ sierra_send_setup(port);
+
+ serial->interface->needs_remote_wakeup = 1;
+@@ -833,6 +828,16 @@ static int sierra_open(struct tty_struct
+ usb_autopm_put_interface(serial->interface);
+
+ return 0;
++
++err_submit:
++ sierra_stop_rx_urbs(port);
++
++ for (i = 0; i < portdata->num_in_urbs; i++) {
++ sierra_release_urb(portdata->in_urbs[i]);
++ portdata->in_urbs[i] = NULL;
++ }
++
++ return err;
+ }
+
+
--- /dev/null
+From 80cc0fcbdaeaf10d04ba27779a2d7ceb73d2717a Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Mon, 26 May 2014 19:22:54 +0200
+Subject: USB: sierra: fix remote wakeup
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 80cc0fcbdaeaf10d04ba27779a2d7ceb73d2717a upstream.
+
+Make sure that needs_remote_wake up is always set when there are open
+ports.
+
+Currently close() would unconditionally set needs_remote_wakeup to 0
+even though there might still be open ports. This could lead to blocked
+input and possibly dropped data on devices that do not support remote
+wakeup (and which must therefore not be runtime suspended while open).
+
+Add an open_ports counter (protected by the susp_lock) and only clear
+needs_remote_wakeup when the last port is closed.
+
+Fixes: e6929a9020ac ("USB: support for autosuspend in sierra while
+online")
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/sierra.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/serial/sierra.c
++++ b/drivers/usb/serial/sierra.c
+@@ -58,6 +58,7 @@ struct sierra_intf_private {
+ spinlock_t susp_lock;
+ unsigned int suspended:1;
+ int in_flight;
++ unsigned int open_ports;
+ };
+
+ static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
+@@ -768,7 +769,6 @@ static void sierra_close(struct usb_seri
+
+ mutex_lock(&serial->disc_mutex);
+ if (!serial->disconnected) {
+- serial->interface->needs_remote_wakeup = 0;
+ /* odd error handling due to pm counters */
+ if (!usb_autopm_get_interface(serial->interface))
+ sierra_send_setup(port);
+@@ -779,6 +779,8 @@ static void sierra_close(struct usb_seri
+ mutex_unlock(&serial->disc_mutex);
+ spin_lock_irq(&intfdata->susp_lock);
+ portdata->opened = 0;
++ if (--intfdata->open_ports == 0)
++ serial->interface->needs_remote_wakeup = 0;
+ spin_unlock_irq(&intfdata->susp_lock);
+
+ for (;;) {
+@@ -834,9 +836,10 @@ static int sierra_open(struct tty_struct
+
+ sierra_send_setup(port);
+
+- serial->interface->needs_remote_wakeup = 1;
+ spin_lock_irq(&intfdata->susp_lock);
+ portdata->opened = 1;
++ if (++intfdata->open_ports == 1)
++ serial->interface->needs_remote_wakeup = 1;
+ spin_unlock_irq(&intfdata->susp_lock);
+ usb_autopm_put_interface(serial->interface);
+
--- /dev/null
+From 7fdd26a01eb7b6cb6855ff8f69ef4a720720dfcb Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Mon, 26 May 2014 19:22:52 +0200
+Subject: USB: sierra: fix urb and memory leak in resume error path
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 7fdd26a01eb7b6cb6855ff8f69ef4a720720dfcb upstream.
+
+Neither the transfer buffer or the urb itself were released in the
+resume error path for delayed writes. Also on errors, the remainder of
+the queue was not even processed, which leads to further urb and buffer
+leaks.
+
+The same error path also failed to balance the outstanding-urb counter,
+something which results in degraded throughput or completely blocked
+writes.
+
+Fix this by releasing urb and buffer and balancing counters on errors,
+and by always processing the whole queue even when submission of one urb
+fails.
+
+Fixes: e6929a9020ac ("USB: support for autosuspend in sierra while
+online")
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/sierra.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/serial/sierra.c
++++ b/drivers/usb/serial/sierra.c
+@@ -1004,8 +1004,12 @@ static int sierra_resume(struct usb_seri
+ if (err < 0) {
+ intfdata->in_flight--;
+ usb_unanchor_urb(urb);
+- usb_scuttle_anchored_urbs(&portdata->delayed);
+- break;
++ kfree(urb->transfer_buffer);
++ usb_free_urb(urb);
++ spin_lock(&portdata->lock);
++ portdata->outstanding_urbs--;
++ spin_unlock(&portdata->lock);
++ continue;
+ }
+ }
+
--- /dev/null
+From 014333f77c0b71123d6ef7d31a9724e0699c9548 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Mon, 26 May 2014 19:22:53 +0200
+Subject: USB: sierra: fix urb and memory leak on disconnect
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 014333f77c0b71123d6ef7d31a9724e0699c9548 upstream.
+
+The delayed-write queue was never emptied on disconnect, something which
+would lead to leaked urbs and transfer buffers if the device is
+disconnected before being runtime resumed due to a write.
+
+Fixes: e6929a9020ac ("USB: support for autosuspend in sierra while
+online")
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/sierra.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/usb/serial/sierra.c
++++ b/drivers/usb/serial/sierra.c
+@@ -759,6 +759,7 @@ static void sierra_close(struct usb_seri
+ struct usb_serial *serial = port->serial;
+ struct sierra_port_private *portdata;
+ struct sierra_intf_private *intfdata = port->serial->private;
++ struct urb *urb;
+
+ portdata = usb_get_serial_port_data(port);
+
+@@ -780,6 +781,18 @@ static void sierra_close(struct usb_seri
+ portdata->opened = 0;
+ spin_unlock_irq(&intfdata->susp_lock);
+
++ for (;;) {
++ urb = usb_get_from_anchor(&portdata->delayed);
++ if (!urb)
++ break;
++ kfree(urb->transfer_buffer);
++ usb_free_urb(urb);
++ usb_autopm_put_interface_async(serial->interface);
++ spin_lock(&portdata->lock);
++ portdata->outstanding_urbs--;
++ spin_unlock(&portdata->lock);
++ }
++
+ sierra_stop_rx_urbs(port);
+ for (i = 0; i < portdata->num_in_urbs; i++) {
+ sierra_release_urb(portdata->in_urbs[i]);
--- /dev/null
+From 8452727de70f6ad850cd6d0aaa18b5d9050aa63b Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Mon, 26 May 2014 19:22:51 +0200
+Subject: USB: sierra: fix use after free at suspend/resume
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 8452727de70f6ad850cd6d0aaa18b5d9050aa63b upstream.
+
+Fix use after free or NULL-pointer dereference during suspend and
+resume.
+
+The port data may never have been allocated (port probe failed)
+or may already have been released by port_remove (e.g. driver is
+unloaded) when suspend and resume are called.
+
+Fixes: e6929a9020ac ("USB: support for autosuspend in sierra while
+online")
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/sierra.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/serial/sierra.c
++++ b/drivers/usb/serial/sierra.c
+@@ -933,6 +933,7 @@ static int sierra_port_remove(struct usb
+ struct sierra_port_private *portdata;
+
+ portdata = usb_get_serial_port_data(port);
++ usb_set_serial_port_data(port, NULL);
+ kfree(portdata);
+
+ return 0;
+@@ -949,6 +950,8 @@ static void stop_read_write_urbs(struct
+ for (i = 0; i < serial->num_ports; ++i) {
+ port = serial->port[i];
+ portdata = usb_get_serial_port_data(port);
++ if (!portdata)
++ continue;
+ sierra_stop_rx_urbs(port);
+ usb_kill_anchored_urbs(&portdata->active);
+ }
+@@ -991,6 +994,9 @@ static int sierra_resume(struct usb_seri
+ port = serial->port[i];
+ portdata = usb_get_serial_port_data(port);
+
++ if (!portdata)
++ continue;
++
+ while ((urb = usb_get_from_anchor(&portdata->delayed))) {
+ usb_anchor_urb(urb, &portdata->active);
+ intfdata->in_flight++;