--- /dev/null
+From a553add0846f355a28ed4e81134012e4a1e280c2 Mon Sep 17 00:00:00 2001
+From: Randy Dunlap <rdunlap@infradead.org>
+Date: Mon, 16 Sep 2019 16:12:23 -0700
+Subject: serial: uartlite: fix exit path null pointer
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+commit a553add0846f355a28ed4e81134012e4a1e280c2 upstream.
+
+Call uart_unregister_driver() conditionally instead of
+unconditionally, only if it has been previously registered.
+
+This uses driver.state, just as the sh-sci.c driver does.
+
+Fixes this null pointer dereference in tty_unregister_driver(),
+since the 'driver' argument is null:
+
+ general protection fault: 0000 [#1] PREEMPT SMP KASAN PTI
+ RIP: 0010:tty_unregister_driver+0x25/0x1d0
+
+Fixes: 238b8721a554 ("[PATCH] serial uartlite driver")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: stable <stable@vger.kernel.org>
+Cc: Peter Korsgaard <jacmet@sunsite.dk>
+Link: https://lore.kernel.org/r/9c8e6581-6fcc-a595-0897-4d90f5d710df@infradead.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/uartlite.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/uartlite.c
++++ b/drivers/tty/serial/uartlite.c
+@@ -746,7 +746,8 @@ err_uart:
+ static void __exit ulite_exit(void)
+ {
+ platform_driver_unregister(&ulite_platform_driver);
+- uart_unregister_driver(&ulite_uart_driver);
++ if (ulite_uart_driver.state)
++ uart_unregister_driver(&ulite_uart_driver);
+ }
+
+ module_init(ulite_init);
usb-rio500-remove-rio-500-kernel-driver.patch
usb-yurex-don-t-retry-on-unexpected-errors.patch
usb-yurex-fix-null-derefs-on-disconnect.patch
+usb-usb-skeleton-fix-runtime-pm-after-driver-unbind.patch
+usb-usb-skeleton-fix-null-deref-on-disconnect.patch
+xhci-fix-false-warning-message-about-wrong-bounce-buffer-write-length.patch
+xhci-prevent-device-initiated-u1-u2-link-pm-if-exit-latency-is-too-long.patch
+xhci-check-all-endpoints-for-lpm-timeout.patch
+usb-xhci-wait-for-cnr-controller-not-ready-bit-in-xhci-resume.patch
+xhci-increase-sts_save-timeout-in-xhci_suspend.patch
+usb-adutux-remove-redundant-variable-minor.patch
+usb-adutux-fix-use-after-free-on-disconnect.patch
+usb-adutux-fix-null-derefs-on-disconnect.patch
+usb-adutux-fix-use-after-free-on-release.patch
+usb-iowarrior-fix-use-after-free-on-disconnect.patch
+usb-iowarrior-fix-use-after-free-on-release.patch
+usb-iowarrior-fix-use-after-free-after-driver-unbind.patch
+usb-usblp-fix-runtime-pm-after-driver-unbind.patch
+usb-chaoskey-fix-use-after-free-on-release.patch
+usb-ldusb-fix-null-derefs-on-driver-unbind.patch
+serial-uartlite-fix-exit-path-null-pointer.patch
+usb-serial-keyspan-fix-null-derefs-on-open-and-write.patch
+usb-serial-ftdi_sio-add-device-ids-for-sienna-and-echelon-pl-20.patch
+usb-serial-option-add-telit-fn980-compositions.patch
+usb-serial-option-add-support-for-cinterion-cls8-devices.patch
+usb-serial-fix-runtime-pm-after-driver-unbind.patch
+usb-usblcd-fix-i-o-after-disconnect.patch
+usb-microtek-fix-info-leak-at-probe.patch
+usb-dummy-hcd-fix-power-budget-for-superspeed-mode.patch
+usb-renesas_usbhs-gadget-do-not-discard-queues-in-usb_ep_set_-halt-wedge.patch
+usb-renesas_usbhs-gadget-fix-usb_ep_set_-halt-wedge-behavior.patch
+usb-legousbtower-fix-slab-info-leak-at-probe.patch
+usb-legousbtower-fix-deadlock-on-disconnect.patch
+usb-legousbtower-fix-potential-null-deref-on-disconnect.patch
+usb-legousbtower-fix-open-after-failed-reset-request.patch
+usb-legousbtower-fix-use-after-free-on-release.patch
--- /dev/null
+From b2fa7baee744fde746c17bc1860b9c6f5c2eebb7 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 25 Sep 2019 11:29:13 +0200
+Subject: USB: adutux: fix NULL-derefs on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit b2fa7baee744fde746c17bc1860b9c6f5c2eebb7 upstream.
+
+The driver was using its struct usb_device pointer as an inverted
+disconnected flag, but was setting it to NULL before making sure all
+completion handlers had run. This could lead to a NULL-pointer
+dereference in a number of dev_dbg statements in the completion handlers
+which relies on said pointer.
+
+The pointer was also dereferenced unconditionally in a dev_dbg statement
+release() something which would lead to a NULL-deref whenever a device
+was disconnected before the final character-device close if debugging
+was enabled.
+
+Fix this by unconditionally stopping all I/O and preventing
+resubmissions by poisoning the interrupt URBs at disconnect and using a
+dedicated disconnected flag.
+
+This also makes sure that all I/O has completed by the time the
+disconnect callback returns.
+
+Fixes: 1ef37c6047fe ("USB: adutux: remove custom debug macro and module parameter")
+Fixes: 66d4bc30d128 ("USB: adutux: remove custom debug macro")
+Cc: stable <stable@vger.kernel.org> # 3.12
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20190925092913.8608-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/adutux.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/misc/adutux.c
++++ b/drivers/usb/misc/adutux.c
+@@ -79,6 +79,7 @@ struct adu_device {
+ char serial_number[8];
+
+ int open_count; /* number of times this port has been opened */
++ unsigned long disconnected:1;
+
+ char *read_buffer_primary;
+ int read_buffer_length;
+@@ -120,7 +121,7 @@ static void adu_abort_transfers(struct a
+ {
+ unsigned long flags;
+
+- if (dev->udev == NULL)
++ if (dev->disconnected)
+ return;
+
+ /* shutdown transfer */
+@@ -243,7 +244,7 @@ static int adu_open(struct inode *inode,
+ }
+
+ dev = usb_get_intfdata(interface);
+- if (!dev || !dev->udev) {
++ if (!dev) {
+ retval = -ENODEV;
+ goto exit_no_device;
+ }
+@@ -326,7 +327,7 @@ static int adu_release(struct inode *ino
+ }
+
+ adu_release_internal(dev);
+- if (dev->udev == NULL) {
++ if (dev->disconnected) {
+ /* the device was unplugged before the file was released */
+ if (!dev->open_count) /* ... and we're the last user */
+ adu_delete(dev);
+@@ -355,7 +356,7 @@ static ssize_t adu_read(struct file *fil
+ return -ERESTARTSYS;
+
+ /* verify that the device wasn't unplugged */
+- if (dev->udev == NULL) {
++ if (dev->disconnected) {
+ retval = -ENODEV;
+ pr_err("No device or device unplugged %d\n", retval);
+ goto exit;
+@@ -520,7 +521,7 @@ static ssize_t adu_write(struct file *fi
+ goto exit_nolock;
+
+ /* verify that the device wasn't unplugged */
+- if (dev->udev == NULL) {
++ if (dev->disconnected) {
+ retval = -ENODEV;
+ pr_err("No device or device unplugged %d\n", retval);
+ goto exit;
+@@ -766,11 +767,14 @@ static void adu_disconnect(struct usb_in
+
+ usb_deregister_dev(interface, &adu_class);
+
++ usb_poison_urb(dev->interrupt_in_urb);
++ usb_poison_urb(dev->interrupt_out_urb);
++
+ mutex_lock(&adutux_mutex);
+ usb_set_intfdata(interface, NULL);
+
+ mutex_lock(&dev->mtx); /* not interruptible */
+- dev->udev = NULL; /* poison */
++ dev->disconnected = 1;
+ mutex_unlock(&dev->mtx);
+
+ /* if the device is not opened, then we clean up right now */
--- /dev/null
+From 44efc269db7929f6275a1fa927ef082e533ecde0 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 25 Sep 2019 11:29:12 +0200
+Subject: USB: adutux: fix use-after-free on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 44efc269db7929f6275a1fa927ef082e533ecde0 upstream.
+
+The driver was clearing its struct usb_device pointer, which it used as
+an inverted disconnected flag, before deregistering the character device
+and without serialising against racing release().
+
+This could lead to a use-after-free if a racing release() callback
+observes the cleared pointer and frees the driver data before
+disconnect() is finished with it.
+
+This could also lead to NULL-pointer dereferences in a racing open().
+
+Fixes: f08812d5eb8f ("USB: FIx locks and urb->status in adutux (updated)")
+Cc: stable <stable@vger.kernel.org> # 2.6.24
+Reported-by: syzbot+0243cb250a51eeefb8cc@syzkaller.appspotmail.com
+Tested-by: syzbot+0243cb250a51eeefb8cc@syzkaller.appspotmail.com
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20190925092913.8608-1-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/adutux.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/misc/adutux.c
++++ b/drivers/usb/misc/adutux.c
+@@ -764,14 +764,15 @@ static void adu_disconnect(struct usb_in
+
+ dev = usb_get_intfdata(interface);
+
+- mutex_lock(&dev->mtx); /* not interruptible */
+- dev->udev = NULL; /* poison */
+ usb_deregister_dev(interface, &adu_class);
+- mutex_unlock(&dev->mtx);
+
+ mutex_lock(&adutux_mutex);
+ usb_set_intfdata(interface, NULL);
+
++ mutex_lock(&dev->mtx); /* not interruptible */
++ dev->udev = NULL; /* poison */
++ mutex_unlock(&dev->mtx);
++
+ /* if the device is not opened, then we clean up right now */
+ if (!dev->open_count)
+ adu_delete(dev);
--- /dev/null
+From 123a0f125fa3d2104043697baa62899d9e549272 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 17:38:44 +0200
+Subject: USB: adutux: fix use-after-free on release
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 123a0f125fa3d2104043697baa62899d9e549272 upstream.
+
+The driver was accessing its struct usb_device in its release()
+callback without holding a reference. This would lead to a
+use-after-free whenever the device was disconnected while the character
+device was still open.
+
+Fixes: 66d4bc30d128 ("USB: adutux: remove custom debug macro")
+Cc: stable <stable@vger.kernel.org> # 3.12
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009153848.8664-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/adutux.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/adutux.c
++++ b/drivers/usb/misc/adutux.c
+@@ -151,6 +151,7 @@ static void adu_delete(struct adu_device
+ kfree(dev->read_buffer_secondary);
+ kfree(dev->interrupt_in_buffer);
+ kfree(dev->interrupt_out_buffer);
++ usb_put_dev(dev->udev);
+ kfree(dev);
+ }
+
+@@ -666,7 +667,7 @@ static int adu_probe(struct usb_interfac
+
+ mutex_init(&dev->mtx);
+ spin_lock_init(&dev->buflock);
+- dev->udev = udev;
++ dev->udev = usb_get_dev(udev);
+ init_waitqueue_head(&dev->read_wait);
+ init_waitqueue_head(&dev->write_wait);
+
--- /dev/null
+From 8444efc4a052332d643ed5c8aebcca148c7de032 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Tue, 7 Nov 2017 11:45:27 +0000
+Subject: USB: adutux: remove redundant variable minor
+
+From: Colin Ian King <colin.king@canonical.com>
+
+commit 8444efc4a052332d643ed5c8aebcca148c7de032 upstream.
+
+Variable minor is being assigned but never read, hence it is redundant
+and can be removed. Cleans up clang warning:
+
+drivers/usb/misc/adutux.c:770:2: warning: Value stored to 'minor' is
+never read
+
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/adutux.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/usb/misc/adutux.c
++++ b/drivers/usb/misc/adutux.c
+@@ -761,13 +761,11 @@ error:
+ static void adu_disconnect(struct usb_interface *interface)
+ {
+ struct adu_device *dev;
+- int minor;
+
+ dev = usb_get_intfdata(interface);
+
+ mutex_lock(&dev->mtx); /* not interruptible */
+ dev->udev = NULL; /* poison */
+- minor = dev->minor;
+ usb_deregister_dev(interface, &adu_class);
+ mutex_unlock(&dev->mtx);
+
--- /dev/null
+From 93ddb1f56ae102f14f9e46a9a9c8017faa970003 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 17:38:45 +0200
+Subject: USB: chaoskey: fix use-after-free on release
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 93ddb1f56ae102f14f9e46a9a9c8017faa970003 upstream.
+
+The driver was accessing its struct usb_interface in its release()
+callback without holding a reference. This would lead to a
+use-after-free whenever the device was disconnected while the character
+device was still open.
+
+Fixes: 66e3e591891d ("usb: Add driver for Altus Metrum ChaosKey device (v2)")
+Cc: stable <stable@vger.kernel.org> # 4.1
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009153848.8664-3-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/chaoskey.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/misc/chaoskey.c
++++ b/drivers/usb/misc/chaoskey.c
+@@ -106,6 +106,7 @@ static void chaoskey_free(struct chaoske
+ usb_free_urb(dev->urb);
+ kfree(dev->name);
+ kfree(dev->buf);
++ usb_put_intf(dev->interface);
+ kfree(dev);
+ }
+ }
+@@ -153,6 +154,8 @@ static int chaoskey_probe(struct usb_int
+ if (dev == NULL)
+ goto out;
+
++ dev->interface = usb_get_intf(interface);
++
+ dev->buf = kmalloc(size, GFP_KERNEL);
+
+ if (dev->buf == NULL)
+@@ -186,8 +189,6 @@ static int chaoskey_probe(struct usb_int
+ strcat(dev->name, udev->serial);
+ }
+
+- dev->interface = interface;
+-
+ dev->in_ep = in_ep;
+
+ if (le16_to_cpu(udev->descriptor.idVendor) != ALEA_VENDOR_ID)
--- /dev/null
+From 2636d49b64671d3d90ecc4daf971b58df3956519 Mon Sep 17 00:00:00 2001
+From: "Jacky.Cao@sony.com" <Jacky.Cao@sony.com>
+Date: Thu, 5 Sep 2019 04:11:57 +0000
+Subject: USB: dummy-hcd: fix power budget for SuperSpeed mode
+
+From: Jacky.Cao@sony.com <Jacky.Cao@sony.com>
+
+commit 2636d49b64671d3d90ecc4daf971b58df3956519 upstream.
+
+The power budget for SuperSpeed mode should be 900 mA
+according to USB specification, so set the power budget
+to 900mA for dummy_start_ss which is only used for
+SuperSpeed mode.
+
+If the max power consumption of SuperSpeed device is
+larger than 500 mA, insufficient available bus power
+error happens in usb_choose_configuration function
+when the device connects to dummy hcd.
+
+Signed-off-by: Jacky Cao <Jacky.Cao@sony.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/16EA1F625E922C43B00B9D82250220500871CDE5@APYOKXMS108.ap.sony.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/udc/dummy_hcd.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/udc/dummy_hcd.c
++++ b/drivers/usb/gadget/udc/dummy_hcd.c
+@@ -50,6 +50,7 @@
+ #define DRIVER_VERSION "02 May 2005"
+
+ #define POWER_BUDGET 500 /* in mA; use 8 for low-power port testing */
++#define POWER_BUDGET_3 900 /* in mA */
+
+ static const char driver_name[] = "dummy_hcd";
+ static const char driver_desc[] = "USB Host+Gadget Emulator";
+@@ -2439,7 +2440,7 @@ static int dummy_start_ss(struct dummy_h
+ dum_hcd->rh_state = DUMMY_RH_RUNNING;
+ dum_hcd->stream_en_ep = 0;
+ INIT_LIST_HEAD(&dum_hcd->urbp_list);
+- dummy_hcd_to_hcd(dum_hcd)->power_budget = POWER_BUDGET;
++ dummy_hcd_to_hcd(dum_hcd)->power_budget = POWER_BUDGET_3;
+ dummy_hcd_to_hcd(dum_hcd)->state = HC_STATE_RUNNING;
+ dummy_hcd_to_hcd(dum_hcd)->uses_new_polling = 1;
+ #ifdef CONFIG_USB_OTG
--- /dev/null
+From b5f8d46867ca233d773408ffbe691a8062ed718f Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 12:48:43 +0200
+Subject: USB: iowarrior: fix use-after-free after driver unbind
+
+From: Johan Hovold <johan@kernel.org>
+
+commit b5f8d46867ca233d773408ffbe691a8062ed718f upstream.
+
+Make sure to stop also the asynchronous write URBs on disconnect() to
+avoid use-after-free in the completion handler after driver unbind.
+
+Fixes: 946b960d13c1 ("USB: add driver for iowarrior devices.")
+Cc: stable <stable@vger.kernel.org> # 2.6.21: 51a2f077c44e ("USB: introduce usb_anchor")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009104846.5925-4-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/iowarrior.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/misc/iowarrior.c
++++ b/drivers/usb/misc/iowarrior.c
+@@ -87,6 +87,7 @@ struct iowarrior {
+ char chip_serial[9]; /* the serial number string of the chip connected */
+ int report_size; /* number of bytes in a report */
+ u16 product_id;
++ struct usb_anchor submitted;
+ };
+
+ /*--------------*/
+@@ -428,11 +429,13 @@ static ssize_t iowarrior_write(struct fi
+ retval = -EFAULT;
+ goto error;
+ }
++ usb_anchor_urb(int_out_urb, &dev->submitted);
+ retval = usb_submit_urb(int_out_urb, GFP_KERNEL);
+ if (retval) {
+ dev_dbg(&dev->interface->dev,
+ "submit error %d for urb nr.%d\n",
+ retval, atomic_read(&dev->write_busy));
++ usb_unanchor_urb(int_out_urb);
+ goto error;
+ }
+ /* submit was ok */
+@@ -774,6 +777,8 @@ static int iowarrior_probe(struct usb_in
+ iface_desc = interface->cur_altsetting;
+ dev->product_id = le16_to_cpu(udev->descriptor.idProduct);
+
++ init_usb_anchor(&dev->submitted);
++
+ res = usb_find_last_int_in_endpoint(iface_desc, &dev->int_in_endpoint);
+ if (res) {
+ dev_err(&interface->dev, "no interrupt-in endpoint found\n");
+@@ -889,6 +894,7 @@ static void iowarrior_disconnect(struct
+ Deleting the device is postponed until close() was called.
+ */
+ usb_kill_urb(dev->int_in_urb);
++ usb_kill_anchored_urbs(&dev->submitted);
+ wake_up_interruptible(&dev->read_wait);
+ wake_up_interruptible(&dev->write_wait);
+ mutex_unlock(&dev->mutex);
--- /dev/null
+From edc4746f253d907d048de680a621e121517f484b Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 12:48:41 +0200
+Subject: USB: iowarrior: fix use-after-free on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit edc4746f253d907d048de680a621e121517f484b upstream.
+
+A recent fix addressing a deadlock on disconnect introduced a new bug
+by moving the present flag out of the critical section protected by the
+driver-data mutex. This could lead to a racing release() freeing the
+driver data before disconnect() is done with it.
+
+Due to insufficient locking a related use-after-free could be triggered
+also before the above mentioned commit. Specifically, the driver needs
+to hold the driver-data mutex also while checking the opened flag at
+disconnect().
+
+Fixes: c468a8aa790e ("usb: iowarrior: fix deadlock on disconnect")
+Fixes: 946b960d13c1 ("USB: add driver for iowarrior devices.")
+Cc: stable <stable@vger.kernel.org> # 2.6.21
+Reported-by: syzbot+0761012cebf7bdb38137@syzkaller.appspotmail.com
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009104846.5925-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/iowarrior.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/misc/iowarrior.c
++++ b/drivers/usb/misc/iowarrior.c
+@@ -870,8 +870,6 @@ static void iowarrior_disconnect(struct
+ dev = usb_get_intfdata(interface);
+ mutex_lock(&iowarrior_open_disc_lock);
+ usb_set_intfdata(interface, NULL);
+- /* prevent device read, write and ioctl */
+- dev->present = 0;
+
+ minor = dev->minor;
+ mutex_unlock(&iowarrior_open_disc_lock);
+@@ -882,8 +880,7 @@ static void iowarrior_disconnect(struct
+ mutex_lock(&dev->mutex);
+
+ /* prevent device read, write and ioctl */
+-
+- mutex_unlock(&dev->mutex);
++ dev->present = 0;
+
+ if (dev->opened) {
+ /* There is a process that holds a filedescriptor to the device ,
+@@ -893,8 +890,10 @@ static void iowarrior_disconnect(struct
+ usb_kill_urb(dev->int_in_urb);
+ wake_up_interruptible(&dev->read_wait);
+ wake_up_interruptible(&dev->write_wait);
++ mutex_unlock(&dev->mutex);
+ } else {
+ /* no process is using the device, cleanup now */
++ mutex_unlock(&dev->mutex);
+ iowarrior_delete(dev);
+ }
+
--- /dev/null
+From 80cd5479b525093a56ef768553045741af61b250 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 12:48:42 +0200
+Subject: USB: iowarrior: fix use-after-free on release
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 80cd5479b525093a56ef768553045741af61b250 upstream.
+
+The driver was accessing its struct usb_interface from its release()
+callback without holding a reference. This would lead to a
+use-after-free whenever debugging was enabled and the device was
+disconnected while its character device was open.
+
+Fixes: 549e83500b80 ("USB: iowarrior: Convert local dbg macro to dev_dbg")
+Cc: stable <stable@vger.kernel.org> # 3.16
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009104846.5925-3-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/iowarrior.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/iowarrior.c
++++ b/drivers/usb/misc/iowarrior.c
+@@ -246,6 +246,7 @@ static inline void iowarrior_delete(stru
+ kfree(dev->int_in_buffer);
+ usb_free_urb(dev->int_in_urb);
+ kfree(dev->read_queue);
++ usb_put_intf(dev->interface);
+ kfree(dev);
+ }
+
+@@ -768,7 +769,7 @@ static int iowarrior_probe(struct usb_in
+ init_waitqueue_head(&dev->write_wait);
+
+ dev->udev = udev;
+- dev->interface = interface;
++ dev->interface = usb_get_intf(interface);
+
+ iface_desc = interface->cur_altsetting;
+ dev->product_id = le16_to_cpu(udev->descriptor.idProduct);
--- /dev/null
+From 58ecf131e74620305175a7aa103f81350bb37570 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 17:38:46 +0200
+Subject: USB: ldusb: fix NULL-derefs on driver unbind
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 58ecf131e74620305175a7aa103f81350bb37570 upstream.
+
+The driver was using its struct usb_interface pointer as an inverted
+disconnected flag, but was setting it to NULL before making sure all
+completion handlers had run. This could lead to a NULL-pointer
+dereference in a number of dev_dbg, dev_warn and dev_err statements in
+the completion handlers which relies on said pointer.
+
+Fix this by unconditionally stopping all I/O and preventing
+resubmissions by poisoning the interrupt URBs at disconnect and using a
+dedicated disconnected flag.
+
+This also makes sure that all I/O has completed by the time the
+disconnect callback returns.
+
+Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver")
+Cc: stable <stable@vger.kernel.org> # 2.6.13
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009153848.8664-4-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/ldusb.c | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/misc/ldusb.c
++++ b/drivers/usb/misc/ldusb.c
+@@ -157,6 +157,7 @@ MODULE_PARM_DESC(min_interrupt_out_inter
+ struct ld_usb {
+ struct mutex mutex; /* locks this structure */
+ struct usb_interface *intf; /* save off the usb interface pointer */
++ unsigned long disconnected:1;
+
+ int open_count; /* number of times this port has been opened */
+
+@@ -196,12 +197,10 @@ static void ld_usb_abort_transfers(struc
+ /* shutdown transfer */
+ if (dev->interrupt_in_running) {
+ dev->interrupt_in_running = 0;
+- if (dev->intf)
+- usb_kill_urb(dev->interrupt_in_urb);
++ usb_kill_urb(dev->interrupt_in_urb);
+ }
+ if (dev->interrupt_out_busy)
+- if (dev->intf)
+- usb_kill_urb(dev->interrupt_out_urb);
++ usb_kill_urb(dev->interrupt_out_urb);
+ }
+
+ /**
+@@ -209,8 +208,6 @@ static void ld_usb_abort_transfers(struc
+ */
+ static void ld_usb_delete(struct ld_usb *dev)
+ {
+- ld_usb_abort_transfers(dev);
+-
+ /* free data structures */
+ usb_free_urb(dev->interrupt_in_urb);
+ usb_free_urb(dev->interrupt_out_urb);
+@@ -266,7 +263,7 @@ static void ld_usb_interrupt_in_callback
+
+ resubmit:
+ /* resubmit if we're still running */
+- if (dev->interrupt_in_running && !dev->buffer_overflow && dev->intf) {
++ if (dev->interrupt_in_running && !dev->buffer_overflow) {
+ retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
+ if (retval) {
+ dev_err(&dev->intf->dev,
+@@ -395,7 +392,7 @@ static int ld_usb_release(struct inode *
+ retval = -ENODEV;
+ goto unlock_exit;
+ }
+- if (dev->intf == NULL) {
++ if (dev->disconnected) {
+ /* the device was unplugged before the file was released */
+ mutex_unlock(&dev->mutex);
+ /* unlock here as ld_usb_delete frees dev */
+@@ -426,7 +423,7 @@ static unsigned int ld_usb_poll(struct f
+
+ dev = file->private_data;
+
+- if (!dev->intf)
++ if (dev->disconnected)
+ return POLLERR | POLLHUP;
+
+ poll_wait(file, &dev->read_wait, wait);
+@@ -465,7 +462,7 @@ static ssize_t ld_usb_read(struct file *
+ }
+
+ /* verify that the device wasn't unplugged */
+- if (dev->intf == NULL) {
++ if (dev->disconnected) {
+ retval = -ENODEV;
+ printk(KERN_ERR "ldusb: No device or device unplugged %d\n", retval);
+ goto unlock_exit;
+@@ -545,7 +542,7 @@ static ssize_t ld_usb_write(struct file
+ }
+
+ /* verify that the device wasn't unplugged */
+- if (dev->intf == NULL) {
++ if (dev->disconnected) {
+ retval = -ENODEV;
+ printk(KERN_ERR "ldusb: No device or device unplugged %d\n", retval);
+ goto unlock_exit;
+@@ -762,6 +759,9 @@ static void ld_usb_disconnect(struct usb
+ /* give back our minor */
+ usb_deregister_dev(intf, &ld_usb_class);
+
++ usb_poison_urb(dev->interrupt_in_urb);
++ usb_poison_urb(dev->interrupt_out_urb);
++
+ mutex_lock(&dev->mutex);
+
+ /* if the device is not opened, then we clean up right now */
+@@ -769,7 +769,7 @@ static void ld_usb_disconnect(struct usb
+ mutex_unlock(&dev->mutex);
+ ld_usb_delete(dev);
+ } else {
+- dev->intf = NULL;
++ dev->disconnected = 1;
+ /* wake up pollers */
+ wake_up_interruptible_all(&dev->read_wait);
+ wake_up_interruptible_all(&dev->write_wait);
--- /dev/null
+From 33a7813219f208f4952ece60ee255fd983272dec Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 19 Sep 2019 10:30:37 +0200
+Subject: USB: legousbtower: fix deadlock on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 33a7813219f208f4952ece60ee255fd983272dec upstream.
+
+Fix a potential deadlock if disconnect races with open.
+
+Since commit d4ead16f50f9 ("USB: prevent char device open/deregister
+race") core holds an rw-semaphore while open is called and when
+releasing the minor number during deregistration. This can lead to an
+ABBA deadlock if a driver takes a lock in open which it also holds
+during deregistration.
+
+This effectively reverts commit 78663ecc344b ("USB: disconnect open race
+in legousbtower") which needlessly introduced this issue after a generic
+fix for this race had been added to core by commit d4ead16f50f9 ("USB:
+prevent char device open/deregister race").
+
+Fixes: 78663ecc344b ("USB: disconnect open race in legousbtower")
+Cc: stable <stable@vger.kernel.org> # 2.6.24
+Reported-by: syzbot+f9549f5ee8a5416f0b95@syzkaller.appspotmail.com
+Tested-by: syzbot+f9549f5ee8a5416f0b95@syzkaller.appspotmail.com
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20190919083039.30898-3-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/legousbtower.c | 19 ++-----------------
+ 1 file changed, 2 insertions(+), 17 deletions(-)
+
+--- a/drivers/usb/misc/legousbtower.c
++++ b/drivers/usb/misc/legousbtower.c
+@@ -183,7 +183,6 @@ static const struct usb_device_id tower_
+ };
+
+ MODULE_DEVICE_TABLE (usb, tower_table);
+-static DEFINE_MUTEX(open_disc_mutex);
+
+ #define LEGO_USB_TOWER_MINOR_BASE 160
+
+@@ -336,18 +335,14 @@ static int tower_open (struct inode *ino
+ goto exit;
+ }
+
+- mutex_lock(&open_disc_mutex);
+ dev = usb_get_intfdata(interface);
+-
+ if (!dev) {
+- mutex_unlock(&open_disc_mutex);
+ retval = -ENODEV;
+ goto exit;
+ }
+
+ /* lock this device */
+ if (mutex_lock_interruptible(&dev->lock)) {
+- mutex_unlock(&open_disc_mutex);
+ retval = -ERESTARTSYS;
+ goto exit;
+ }
+@@ -355,12 +350,10 @@ static int tower_open (struct inode *ino
+
+ /* allow opening only once */
+ if (dev->open_count) {
+- mutex_unlock(&open_disc_mutex);
+ retval = -EBUSY;
+ goto unlock_exit;
+ }
+ dev->open_count = 1;
+- mutex_unlock(&open_disc_mutex);
+
+ /* reset the tower */
+ result = usb_control_msg (dev->udev,
+@@ -427,10 +420,9 @@ static int tower_release (struct inode *
+
+ if (dev == NULL) {
+ retval = -ENODEV;
+- goto exit_nolock;
++ goto exit;
+ }
+
+- mutex_lock(&open_disc_mutex);
+ if (mutex_lock_interruptible(&dev->lock)) {
+ retval = -ERESTARTSYS;
+ goto exit;
+@@ -460,10 +452,7 @@ static int tower_release (struct inode *
+
+ unlock_exit:
+ mutex_unlock(&dev->lock);
+-
+ exit:
+- mutex_unlock(&open_disc_mutex);
+-exit_nolock:
+ return retval;
+ }
+
+@@ -915,7 +904,6 @@ static int tower_probe (struct usb_inter
+ if (retval) {
+ /* something prevented us from registering this driver */
+ dev_err(idev, "Not able to get a minor for this device.\n");
+- usb_set_intfdata (interface, NULL);
+ goto error;
+ }
+ dev->minor = interface->minor;
+@@ -947,16 +935,13 @@ static void tower_disconnect (struct usb
+ int minor;
+
+ dev = usb_get_intfdata (interface);
+- mutex_lock(&open_disc_mutex);
+- usb_set_intfdata (interface, NULL);
+
+ minor = dev->minor;
+
+- /* give back our minor */
++ /* give back our minor and prevent further open() */
+ usb_deregister_dev (interface, &tower_class);
+
+ mutex_lock(&dev->lock);
+- mutex_unlock(&open_disc_mutex);
+
+ /* if the device is not opened, then we clean up right now */
+ if (!dev->open_count) {
--- /dev/null
+From 0b074f6986751361ff442bc1127c1648567aa8d6 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 19 Sep 2019 10:30:39 +0200
+Subject: USB: legousbtower: fix open after failed reset request
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 0b074f6986751361ff442bc1127c1648567aa8d6 upstream.
+
+The driver would return with a nonzero open count in case the reset
+control request failed. This would prevent any further attempts to open
+the char dev until the device was disconnected.
+
+Fix this by incrementing the open count only on successful open.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20190919083039.30898-5-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/legousbtower.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/misc/legousbtower.c
++++ b/drivers/usb/misc/legousbtower.c
+@@ -352,7 +352,6 @@ static int tower_open (struct inode *ino
+ retval = -EBUSY;
+ goto unlock_exit;
+ }
+- dev->open_count = 1;
+
+ /* reset the tower */
+ result = usb_control_msg (dev->udev,
+@@ -392,13 +391,14 @@ static int tower_open (struct inode *ino
+ dev_err(&dev->udev->dev,
+ "Couldn't submit interrupt_in_urb %d\n", retval);
+ dev->interrupt_in_running = 0;
+- dev->open_count = 0;
+ goto unlock_exit;
+ }
+
+ /* save device in the file's private structure */
+ file->private_data = dev;
+
++ dev->open_count = 1;
++
+ unlock_exit:
+ mutex_unlock(&dev->lock);
+
--- /dev/null
+From cd81e6fa8e033e7bcd59415b4a65672b4780030b Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 19 Sep 2019 10:30:38 +0200
+Subject: USB: legousbtower: fix potential NULL-deref on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit cd81e6fa8e033e7bcd59415b4a65672b4780030b upstream.
+
+The driver is using its struct usb_device pointer as an inverted
+disconnected flag, but was setting it to NULL before making sure all
+completion handlers had run. This could lead to a NULL-pointer
+dereference in a number of dev_dbg and dev_err statements in the
+completion handlers which relies on said pointer.
+
+Fix this by unconditionally stopping all I/O and preventing
+resubmissions by poisoning the interrupt URBs at disconnect and using a
+dedicated disconnected flag.
+
+This also makes sure that all I/O has completed by the time the
+disconnect callback returns.
+
+Fixes: 9d974b2a06e3 ("USB: legousbtower.c: remove err() usage")
+Fixes: fef526cae700 ("USB: legousbtower: remove custom debug macro")
+Fixes: 4dae99638097 ("USB: legotower: remove custom debug macro and module parameter")
+Cc: stable <stable@vger.kernel.org> # 3.5
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20190919083039.30898-4-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/legousbtower.c | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+--- a/drivers/usb/misc/legousbtower.c
++++ b/drivers/usb/misc/legousbtower.c
+@@ -194,6 +194,7 @@ struct lego_usb_tower {
+ unsigned char minor; /* the starting minor number for this device */
+
+ int open_count; /* number of times this port has been opened */
++ unsigned long disconnected:1;
+
+ char* read_buffer;
+ size_t read_buffer_length; /* this much came in */
+@@ -293,8 +294,6 @@ static inline void lego_usb_tower_debug_
+ */
+ static inline void tower_delete (struct lego_usb_tower *dev)
+ {
+- tower_abort_transfers (dev);
+-
+ /* free data structures */
+ usb_free_urb(dev->interrupt_in_urb);
+ usb_free_urb(dev->interrupt_out_urb);
+@@ -434,7 +433,8 @@ static int tower_release (struct inode *
+ retval = -ENODEV;
+ goto unlock_exit;
+ }
+- if (dev->udev == NULL) {
++
++ if (dev->disconnected) {
+ /* the device was unplugged before the file was released */
+
+ /* unlock here as tower_delete frees dev */
+@@ -470,10 +470,9 @@ static void tower_abort_transfers (struc
+ if (dev->interrupt_in_running) {
+ dev->interrupt_in_running = 0;
+ mb();
+- if (dev->udev)
+- usb_kill_urb (dev->interrupt_in_urb);
++ usb_kill_urb(dev->interrupt_in_urb);
+ }
+- if (dev->interrupt_out_busy && dev->udev)
++ if (dev->interrupt_out_busy)
+ usb_kill_urb(dev->interrupt_out_urb);
+ }
+
+@@ -509,7 +508,7 @@ static unsigned int tower_poll (struct f
+
+ dev = file->private_data;
+
+- if (!dev->udev)
++ if (dev->disconnected)
+ return POLLERR | POLLHUP;
+
+ poll_wait(file, &dev->read_wait, wait);
+@@ -556,7 +555,7 @@ static ssize_t tower_read (struct file *
+ }
+
+ /* verify that the device wasn't unplugged */
+- if (dev->udev == NULL) {
++ if (dev->disconnected) {
+ retval = -ENODEV;
+ pr_err("No device or device unplugged %d\n", retval);
+ goto unlock_exit;
+@@ -642,7 +641,7 @@ static ssize_t tower_write (struct file
+ }
+
+ /* verify that the device wasn't unplugged */
+- if (dev->udev == NULL) {
++ if (dev->disconnected) {
+ retval = -ENODEV;
+ pr_err("No device or device unplugged %d\n", retval);
+ goto unlock_exit;
+@@ -751,7 +750,7 @@ static void tower_interrupt_in_callback
+
+ resubmit:
+ /* resubmit if we're still running */
+- if (dev->interrupt_in_running && dev->udev) {
++ if (dev->interrupt_in_running) {
+ retval = usb_submit_urb (dev->interrupt_in_urb, GFP_ATOMIC);
+ if (retval)
+ dev_err(&dev->udev->dev,
+@@ -816,6 +815,7 @@ static int tower_probe (struct usb_inter
+
+ dev->udev = udev;
+ dev->open_count = 0;
++ dev->disconnected = 0;
+
+ dev->read_buffer = NULL;
+ dev->read_buffer_length = 0;
+@@ -941,6 +941,10 @@ static void tower_disconnect (struct usb
+ /* give back our minor and prevent further open() */
+ usb_deregister_dev (interface, &tower_class);
+
++ /* stop I/O */
++ usb_poison_urb(dev->interrupt_in_urb);
++ usb_poison_urb(dev->interrupt_out_urb);
++
+ mutex_lock(&dev->lock);
+
+ /* if the device is not opened, then we clean up right now */
+@@ -948,7 +952,7 @@ static void tower_disconnect (struct usb
+ mutex_unlock(&dev->lock);
+ tower_delete (dev);
+ } else {
+- dev->udev = NULL;
++ dev->disconnected = 1;
+ /* wake up pollers */
+ wake_up_interruptible_all(&dev->read_wait);
+ wake_up_interruptible_all(&dev->write_wait);
--- /dev/null
+From 1d427be4a39defadda6dd8f4659bc17f7591740f Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 19 Sep 2019 10:30:36 +0200
+Subject: USB: legousbtower: fix slab info leak at probe
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 1d427be4a39defadda6dd8f4659bc17f7591740f upstream.
+
+Make sure to check for short transfers when retrieving the version
+information at probe to avoid leaking uninitialised slab data when
+logging it.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20190919083039.30898-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/legousbtower.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/misc/legousbtower.c
++++ b/drivers/usb/misc/legousbtower.c
+@@ -894,8 +894,10 @@ static int tower_probe (struct usb_inter
+ get_version_reply,
+ sizeof(*get_version_reply),
+ 1000);
+- if (result < 0) {
+- dev_err(idev, "LEGO USB Tower get version control request failed\n");
++ if (result < sizeof(*get_version_reply)) {
++ if (result >= 0)
++ result = -EIO;
++ dev_err(idev, "get version request failed: %d\n", result);
+ retval = result;
+ goto error;
+ }
--- /dev/null
+From 726b55d0e22ca72c69c947af87785c830289ddbc Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 17:38:47 +0200
+Subject: USB: legousbtower: fix use-after-free on release
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 726b55d0e22ca72c69c947af87785c830289ddbc upstream.
+
+The driver was accessing its struct usb_device in its release()
+callback without holding a reference. This would lead to a
+use-after-free whenever the device was disconnected while the character
+device was still open.
+
+Fixes: fef526cae700 ("USB: legousbtower: remove custom debug macro")
+Cc: stable <stable@vger.kernel.org> # 3.12
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009153848.8664-5-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/legousbtower.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/legousbtower.c
++++ b/drivers/usb/misc/legousbtower.c
+@@ -300,6 +300,7 @@ static inline void tower_delete (struct
+ kfree (dev->read_buffer);
+ kfree (dev->interrupt_in_buffer);
+ kfree (dev->interrupt_out_buffer);
++ usb_put_dev(dev->udev);
+ kfree (dev);
+ }
+
+@@ -813,7 +814,7 @@ static int tower_probe (struct usb_inter
+
+ mutex_init(&dev->lock);
+
+- dev->udev = udev;
++ dev->udev = usb_get_dev(udev);
+ dev->open_count = 0;
+ dev->disconnected = 0;
+
--- /dev/null
+From 177238c3d47d54b2ed8f0da7a4290db492f4a057 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 3 Oct 2019 09:09:31 +0200
+Subject: USB: microtek: fix info-leak at probe
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 177238c3d47d54b2ed8f0da7a4290db492f4a057 upstream.
+
+Add missing bulk-in endpoint sanity check to prevent uninitialised stack
+data from being reported to the system log and used as endpoint
+addresses.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable <stable@vger.kernel.org>
+Reported-by: syzbot+5630ca7c3b2be5c9da5e@syzkaller.appspotmail.com
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Acked-by: Oliver Neukum <oneukum@suse.com>
+Link: https://lore.kernel.org/r/20191003070931.17009-1-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/image/microtek.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/usb/image/microtek.c
++++ b/drivers/usb/image/microtek.c
+@@ -720,6 +720,10 @@ static int mts_usb_probe(struct usb_inte
+
+ }
+
++ if (ep_in_current != &ep_in_set[2]) {
++ MTS_WARNING("couldn't find two input bulk endpoints. Bailing out.\n");
++ return -ENODEV;
++ }
+
+ if ( ep_out == -1 ) {
+ MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" );
--- /dev/null
+From 1aae1394294cb71c6aa0bc904a94a7f2f1e75936 Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Tue, 1 Oct 2019 19:10:32 +0900
+Subject: usb: renesas_usbhs: gadget: Do not discard queues in usb_ep_set_{halt,wedge}()
+
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+
+commit 1aae1394294cb71c6aa0bc904a94a7f2f1e75936 upstream.
+
+The commit 97664a207bc2 ("usb: renesas_usbhs: shrink spin lock area")
+had added a usbhsg_pipe_disable() calling into
+__usbhsg_ep_set_halt_wedge() accidentally. But, this driver should
+not call the usbhsg_pipe_disable() because the function discards
+all queues. So, this patch removes it.
+
+Fixes: 97664a207bc2 ("usb: renesas_usbhs: shrink spin lock area")
+Cc: <stable@vger.kernel.org> # v3.1+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Link: https://lore.kernel.org/r/1569924633-322-2-git-send-email-yoshihiro.shimoda.uh@renesas.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/renesas_usbhs/mod_gadget.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/usb/renesas_usbhs/mod_gadget.c
++++ b/drivers/usb/renesas_usbhs/mod_gadget.c
+@@ -730,8 +730,6 @@ static int __usbhsg_ep_set_halt_wedge(st
+ struct device *dev = usbhsg_gpriv_to_dev(gpriv);
+ unsigned long flags;
+
+- usbhsg_pipe_disable(uep);
+-
+ dev_dbg(dev, "set halt %d (pipe %d)\n",
+ halt, usbhs_pipe_number(pipe));
+
--- /dev/null
+From 4d599cd3a097a85a5c68a2c82b9a48cddf9953ec Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Tue, 1 Oct 2019 19:10:33 +0900
+Subject: usb: renesas_usbhs: gadget: Fix usb_ep_set_{halt,wedge}() behavior
+
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+
+commit 4d599cd3a097a85a5c68a2c82b9a48cddf9953ec upstream.
+
+According to usb_ep_set_halt()'s description,
+__usbhsg_ep_set_halt_wedge() should return -EAGAIN if the IN endpoint
+has any queue or data. Otherwise, this driver is possible to cause
+just STALL without sending a short packet data on g_mass_storage driver,
+and then a few resetting a device happens on a host side during
+a usb enumaration.
+
+Fixes: 2f98382dcdfe ("usb: renesas_usbhs: Add Renesas USBHS Gadget")
+Cc: <stable@vger.kernel.org> # v3.0+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Link: https://lore.kernel.org/r/1569924633-322-3-git-send-email-yoshihiro.shimoda.uh@renesas.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/renesas_usbhs/common.h | 1 +
+ drivers/usb/renesas_usbhs/fifo.c | 2 +-
+ drivers/usb/renesas_usbhs/fifo.h | 1 +
+ drivers/usb/renesas_usbhs/mod_gadget.c | 16 +++++++++++++++-
+ drivers/usb/renesas_usbhs/pipe.c | 15 +++++++++++++++
+ drivers/usb/renesas_usbhs/pipe.h | 1 +
+ 6 files changed, 34 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/renesas_usbhs/common.h
++++ b/drivers/usb/renesas_usbhs/common.h
+@@ -213,6 +213,7 @@ struct usbhs_priv;
+ /* DCPCTR */
+ #define BSTS (1 << 15) /* Buffer Status */
+ #define SUREQ (1 << 14) /* Sending SETUP Token */
++#define INBUFM (1 << 14) /* (PIPEnCTR) Transfer Buffer Monitor */
+ #define CSSTS (1 << 12) /* CSSTS Status */
+ #define ACLRM (1 << 9) /* Buffer Auto-Clear Mode */
+ #define SQCLR (1 << 8) /* Toggle Bit Clear */
+--- a/drivers/usb/renesas_usbhs/fifo.c
++++ b/drivers/usb/renesas_usbhs/fifo.c
+@@ -98,7 +98,7 @@ static void __usbhsf_pkt_del(struct usbh
+ list_del_init(&pkt->node);
+ }
+
+-static struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe)
++struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe)
+ {
+ return list_first_entry_or_null(&pipe->list, struct usbhs_pkt, node);
+ }
+--- a/drivers/usb/renesas_usbhs/fifo.h
++++ b/drivers/usb/renesas_usbhs/fifo.h
+@@ -106,5 +106,6 @@ void usbhs_pkt_push(struct usbhs_pipe *p
+ void *buf, int len, int zero, int sequence);
+ struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt);
+ void usbhs_pkt_start(struct usbhs_pipe *pipe);
++struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe);
+
+ #endif /* RENESAS_USB_FIFO_H */
+--- a/drivers/usb/renesas_usbhs/mod_gadget.c
++++ b/drivers/usb/renesas_usbhs/mod_gadget.c
+@@ -729,6 +729,7 @@ static int __usbhsg_ep_set_halt_wedge(st
+ struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
+ struct device *dev = usbhsg_gpriv_to_dev(gpriv);
+ unsigned long flags;
++ int ret = 0;
+
+ dev_dbg(dev, "set halt %d (pipe %d)\n",
+ halt, usbhs_pipe_number(pipe));
+@@ -736,6 +737,18 @@ static int __usbhsg_ep_set_halt_wedge(st
+ /******************** spin lock ********************/
+ usbhs_lock(priv, flags);
+
++ /*
++ * According to usb_ep_set_halt()'s description, this function should
++ * return -EAGAIN if the IN endpoint has any queue or data. Note
++ * that the usbhs_pipe_is_dir_in() returns false if the pipe is an
++ * IN endpoint in the gadget mode.
++ */
++ if (!usbhs_pipe_is_dir_in(pipe) && (__usbhsf_pkt_get(pipe) ||
++ usbhs_pipe_contains_transmittable_data(pipe))) {
++ ret = -EAGAIN;
++ goto out;
++ }
++
+ if (halt)
+ usbhs_pipe_stall(pipe);
+ else
+@@ -746,10 +759,11 @@ static int __usbhsg_ep_set_halt_wedge(st
+ else
+ usbhsg_status_clr(gpriv, USBHSG_STATUS_WEDGE);
+
++out:
+ usbhs_unlock(priv, flags);
+ /******************** spin unlock ******************/
+
+- return 0;
++ return ret;
+ }
+
+ static int usbhsg_ep_set_halt(struct usb_ep *ep, int value)
+--- a/drivers/usb/renesas_usbhs/pipe.c
++++ b/drivers/usb/renesas_usbhs/pipe.c
+@@ -286,6 +286,21 @@ int usbhs_pipe_is_accessible(struct usbh
+ return -EBUSY;
+ }
+
++bool usbhs_pipe_contains_transmittable_data(struct usbhs_pipe *pipe)
++{
++ u16 val;
++
++ /* Do not support for DCP pipe */
++ if (usbhs_pipe_is_dcp(pipe))
++ return false;
++
++ val = usbhsp_pipectrl_get(pipe);
++ if (val & INBUFM)
++ return true;
++
++ return false;
++}
++
+ /*
+ * PID ctrl
+ */
+--- a/drivers/usb/renesas_usbhs/pipe.h
++++ b/drivers/usb/renesas_usbhs/pipe.h
+@@ -90,6 +90,7 @@ void usbhs_pipe_init(struct usbhs_priv *
+ int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe);
+ void usbhs_pipe_clear(struct usbhs_pipe *pipe);
+ int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe);
++bool usbhs_pipe_contains_transmittable_data(struct usbhs_pipe *pipe);
+ void usbhs_pipe_enable(struct usbhs_pipe *pipe);
+ void usbhs_pipe_disable(struct usbhs_pipe *pipe);
+ void usbhs_pipe_stall(struct usbhs_pipe *pipe);
--- /dev/null
+From d51bdb93ca7e71d7fb30a572c7b47ed0194bf3fe Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 1 Oct 2019 10:49:07 +0200
+Subject: USB: serial: fix runtime PM after driver unbind
+
+From: Johan Hovold <johan@kernel.org>
+
+commit d51bdb93ca7e71d7fb30a572c7b47ed0194bf3fe upstream.
+
+Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate
+interface PM usage counter") USB drivers must always balance their
+runtime PM gets and puts, including when the driver has already been
+unbound from the interface.
+
+Leaving the interface with a positive PM usage counter would prevent a
+later bound driver from suspending the device.
+
+Fixes: c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191001084908.2003-4-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/usb-serial.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -314,10 +314,7 @@ static void serial_cleanup(struct tty_st
+ serial = port->serial;
+ owner = serial->type->driver.owner;
+
+- mutex_lock(&serial->disc_mutex);
+- if (!serial->disconnected)
+- usb_autopm_put_interface(serial->interface);
+- mutex_unlock(&serial->disc_mutex);
++ usb_autopm_put_interface(serial->interface);
+
+ usb_serial_put(serial);
+ module_put(owner);
--- /dev/null
+From 357f16d9e0194cdbc36531ff88b453481560b76a Mon Sep 17 00:00:00 2001
+From: Beni Mahler <beni.mahler@gmx.net>
+Date: Thu, 5 Sep 2019 00:26:20 +0200
+Subject: USB: serial: ftdi_sio: add device IDs for Sienna and Echelon PL-20
+
+From: Beni Mahler <beni.mahler@gmx.net>
+
+commit 357f16d9e0194cdbc36531ff88b453481560b76a upstream.
+
+Both devices added here have a FTDI chip inside. The device from Echelon
+is called 'Network Interface' it is actually a LON network gateway.
+
+ ID 0403:8348 Future Technology Devices International, Ltd
+ https://www.eltako.com/fileadmin/downloads/de/datenblatt/Datenblatt_PL-SW-PROF.pdf
+
+ ID 0920:7500 Network Interface
+ https://www.echelon.com/products/u20-usb-network-interface
+
+Signed-off-by: Beni Mahler <beni.mahler@gmx.net>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ftdi_sio.c | 3 +++
+ drivers/usb/serial/ftdi_sio_ids.h | 9 +++++++++
+ 2 files changed, 12 insertions(+)
+
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -1025,6 +1025,9 @@ static const struct usb_device_id id_tab
+ /* EZPrototypes devices */
+ { USB_DEVICE(EZPROTOTYPES_VID, HJELMSLUND_USB485_ISO_PID) },
+ { USB_DEVICE_INTERFACE_NUMBER(UNJO_VID, UNJO_ISODEBUG_V1_PID, 1) },
++ /* Sienna devices */
++ { USB_DEVICE(FTDI_VID, FTDI_SIENNA_PID) },
++ { USB_DEVICE(ECHELON_VID, ECHELON_U20_PID) },
+ { } /* Terminating entry */
+ };
+
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -39,6 +39,9 @@
+
+ #define FTDI_LUMEL_PD12_PID 0x6002
+
++/* Sienna Serial Interface by Secyourit GmbH */
++#define FTDI_SIENNA_PID 0x8348
++
+ /* Cyber Cortex AV by Fabulous Silicon (http://fabuloussilicon.com) */
+ #define CYBER_CORTEX_AV_PID 0x8698
+
+@@ -689,6 +692,12 @@
+ #define BANDB_ZZ_PROG1_USB_PID 0xBA02
+
+ /*
++ * Echelon USB Serial Interface
++ */
++#define ECHELON_VID 0x0920
++#define ECHELON_U20_PID 0x7500
++
++/*
+ * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI
+ */
+ #define INTREPID_VID 0x093C
--- /dev/null
+From 7d7e21fafdbc7fcf0854b877bd0975b487ed2717 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 3 Oct 2019 15:49:58 +0200
+Subject: USB: serial: keyspan: fix NULL-derefs on open() and write()
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 7d7e21fafdbc7fcf0854b877bd0975b487ed2717 upstream.
+
+Fix NULL-pointer dereferences on open() and write() which can be
+triggered by a malicious USB device.
+
+The current URB allocation helper would fail to initialise the newly
+allocated URB if the device has unexpected endpoint descriptors,
+something which could lead NULL-pointer dereferences in a number of
+open() and write() paths when accessing the URB. For example:
+
+ BUG: kernel NULL pointer dereference, address: 0000000000000000
+ ...
+ RIP: 0010:usb_clear_halt+0x11/0xc0
+ ...
+ Call Trace:
+ ? tty_port_open+0x4d/0xd0
+ keyspan_open+0x70/0x160 [keyspan]
+ serial_port_activate+0x5b/0x80 [usbserial]
+ tty_port_open+0x7b/0xd0
+ ? check_tty_count+0x43/0xa0
+ tty_open+0xf1/0x490
+
+ BUG: kernel NULL pointer dereference, address: 0000000000000000
+ ...
+ RIP: 0010:keyspan_write+0x14e/0x1f3 [keyspan]
+ ...
+ Call Trace:
+ serial_write+0x43/0xa0 [usbserial]
+ n_tty_write+0x1af/0x4f0
+ ? do_wait_intr_irq+0x80/0x80
+ ? process_echoes+0x60/0x60
+ tty_write+0x13f/0x2f0
+
+ BUG: kernel NULL pointer dereference, address: 0000000000000000
+ ...
+ RIP: 0010:keyspan_usa26_send_setup+0x298/0x305 [keyspan]
+ ...
+ Call Trace:
+ keyspan_open+0x10f/0x160 [keyspan]
+ serial_port_activate+0x5b/0x80 [usbserial]
+ tty_port_open+0x7b/0xd0
+ ? check_tty_count+0x43/0xa0
+ tty_open+0xf1/0x490
+
+Fixes: fdcba53e2d58 ("fix for bugzilla #7544 (keyspan USB-to-serial converter)")
+Cc: stable <stable@vger.kernel.org> # 2.6.21
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/keyspan.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/serial/keyspan.c
++++ b/drivers/usb/serial/keyspan.c
+@@ -1745,8 +1745,8 @@ static struct urb *keyspan_setup_urb(str
+
+ ep_desc = find_ep(serial, endpoint);
+ if (!ep_desc) {
+- /* leak the urb, something's wrong and the callers don't care */
+- return urb;
++ usb_free_urb(urb);
++ return NULL;
+ }
+ if (usb_endpoint_xfer_int(ep_desc)) {
+ ep_type_name = "INT";
--- /dev/null
+From dfbac2f4da6a0c4a8f6b4d715a4077a7b8df53ad Mon Sep 17 00:00:00 2001
+From: Reinhard Speyerer <rspmn@arcor.de>
+Date: Thu, 3 Oct 2019 18:53:21 +0200
+Subject: USB: serial: option: add support for Cinterion CLS8 devices
+
+From: Reinhard Speyerer <rspmn@arcor.de>
+
+commit dfbac2f4da6a0c4a8f6b4d715a4077a7b8df53ad upstream.
+
+Add support for the serial ports of Cinterion CLS8 devices.
+
+T: Bus=01 Lev=03 Prnt=05 Port=01 Cnt=02 Dev#= 25 Spd=480 MxCh= 0
+D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
+P: Vendor=1e2d ProdID=00b0 Rev= 3.18
+S: Manufacturer=GEMALTO
+S: Product=USB Modem
+C:* #Ifs= 5 Cfg#= 1 Atr=80 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none)
+E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
+E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
+E: Ad=89(I) Atr=03(Int.) MxPS= 8 Ivl=32ms
+E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+
+Signed-off-by: Reinhard Speyerer <rspmn@arcor.de>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -422,6 +422,7 @@ static void option_instat_callback(struc
+ #define CINTERION_PRODUCT_PH8_AUDIO 0x0083
+ #define CINTERION_PRODUCT_AHXX_2RMNET 0x0084
+ #define CINTERION_PRODUCT_AHXX_AUDIO 0x0085
++#define CINTERION_PRODUCT_CLS8 0x00b0
+
+ /* Olivetti products */
+ #define OLIVETTI_VENDOR_ID 0x0b3c
+@@ -1858,6 +1859,8 @@ static const struct usb_device_id option
+ .driver_info = RSVD(4) },
+ { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_2RMNET, 0xff) },
+ { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) },
++ { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_CLS8, 0xff),
++ .driver_info = RSVD(0) | RSVD(4) },
+ { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) },
+ { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
+ { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
--- /dev/null
+From 5eb3f4b87a0e7e949c976f32f296176a06d1a93b Mon Sep 17 00:00:00 2001
+From: Daniele Palmas <dnlplm@gmail.com>
+Date: Mon, 23 Sep 2019 12:23:28 +0200
+Subject: USB: serial: option: add Telit FN980 compositions
+
+From: Daniele Palmas <dnlplm@gmail.com>
+
+commit 5eb3f4b87a0e7e949c976f32f296176a06d1a93b upstream.
+
+This patch adds the following Telit FN980 compositions:
+
+0x1050: tty, adb, rmnet, tty, tty, tty, tty
+0x1051: tty, adb, mbim, tty, tty, tty, tty
+0x1052: rndis, tty, adb, tty, tty, tty, tty
+0x1053: tty, adb, ecm, tty, tty, tty, tty
+
+Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -1157,6 +1157,14 @@ static const struct usb_device_id option
+ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) },
+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG5, 0xff),
+ .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) },
++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1050, 0xff), /* Telit FN980 (rmnet) */
++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1051, 0xff), /* Telit FN980 (MBIM) */
++ .driver_info = NCTRL(0) | RSVD(1) },
++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1052, 0xff), /* Telit FN980 (RNDIS) */
++ .driver_info = NCTRL(2) | RSVD(3) },
++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1053, 0xff), /* Telit FN980 (ECM) */
++ .driver_info = NCTRL(0) | RSVD(1) },
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
+ .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
--- /dev/null
+From bed5ef230943863b9abf5eae226a20fad9a8ff71 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 9 Oct 2019 19:09:42 +0200
+Subject: USB: usb-skeleton: fix NULL-deref on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit bed5ef230943863b9abf5eae226a20fad9a8ff71 upstream.
+
+The driver was using its struct usb_interface pointer as an inverted
+disconnected flag and was setting it to NULL before making sure all
+completion handlers had run. This could lead to NULL-pointer
+dereferences in the dev_err() statements in the completion handlers
+which relies on said pointer.
+
+Fix this by using a dedicated disconnected flag.
+
+Note that this is also addresses a NULL-pointer dereference at release()
+and a struct usb_interface reference leak introduced by a recent runtime
+PM fix, which depends on and should have been submitted together with
+this patch.
+
+Fixes: 4212cd74ca6f ("USB: usb-skeleton.c: remove err() usage")
+Fixes: 5c290a5e42c3 ("USB: usb-skeleton: fix runtime PM after driver unbind")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191009170944.30057-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usb-skeleton.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/usb-skeleton.c
++++ b/drivers/usb/usb-skeleton.c
+@@ -63,6 +63,7 @@ struct usb_skel {
+ spinlock_t err_lock; /* lock for errors */
+ struct kref kref;
+ struct mutex io_mutex; /* synchronize I/O with disconnect */
++ unsigned long disconnected:1;
+ wait_queue_head_t bulk_in_wait; /* to wait for an ongoing read */
+ };
+ #define to_skel_dev(d) container_of(d, struct usb_skel, kref)
+@@ -239,7 +240,7 @@ static ssize_t skel_read(struct file *fi
+ if (rv < 0)
+ return rv;
+
+- if (!dev->interface) { /* disconnect() was called */
++ if (dev->disconnected) { /* disconnect() was called */
+ rv = -ENODEV;
+ goto exit;
+ }
+@@ -420,7 +421,7 @@ static ssize_t skel_write(struct file *f
+
+ /* this lock makes sure we don't submit URBs to gone devices */
+ mutex_lock(&dev->io_mutex);
+- if (!dev->interface) { /* disconnect() was called */
++ if (dev->disconnected) { /* disconnect() was called */
+ mutex_unlock(&dev->io_mutex);
+ retval = -ENODEV;
+ goto error;
+@@ -571,7 +572,7 @@ static void skel_disconnect(struct usb_i
+
+ /* prevent more I/O from starting */
+ mutex_lock(&dev->io_mutex);
+- dev->interface = NULL;
++ dev->disconnected = 1;
+ mutex_unlock(&dev->io_mutex);
+
+ usb_kill_anchored_urbs(&dev->submitted);
--- /dev/null
+From 5c290a5e42c3387e82de86965784d30e6c5270fd Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 1 Oct 2019 10:49:05 +0200
+Subject: USB: usb-skeleton: fix runtime PM after driver unbind
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 5c290a5e42c3387e82de86965784d30e6c5270fd upstream.
+
+Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate
+interface PM usage counter") USB drivers must always balance their
+runtime PM gets and puts, including when the driver has already been
+unbound from the interface.
+
+Leaving the interface with a positive PM usage counter would prevent a
+later bound driver from suspending the device.
+
+Fixes: c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191001084908.2003-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/usb-skeleton.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/usb-skeleton.c
++++ b/drivers/usb/usb-skeleton.c
+@@ -75,6 +75,7 @@ static void skel_delete(struct kref *kre
+ struct usb_skel *dev = to_skel_dev(kref);
+
+ usb_free_urb(dev->bulk_in_urb);
++ usb_put_intf(dev->interface);
+ usb_put_dev(dev->udev);
+ kfree(dev->bulk_in_buffer);
+ kfree(dev);
+@@ -126,10 +127,7 @@ static int skel_release(struct inode *in
+ return -ENODEV;
+
+ /* allow the device to be autosuspended */
+- mutex_lock(&dev->io_mutex);
+- if (dev->interface)
+- usb_autopm_put_interface(dev->interface);
+- mutex_unlock(&dev->io_mutex);
++ usb_autopm_put_interface(dev->interface);
+
+ /* decrement the count on our device */
+ kref_put(&dev->kref, skel_delete);
+@@ -507,7 +505,7 @@ static int skel_probe(struct usb_interfa
+ init_waitqueue_head(&dev->bulk_in_wait);
+
+ dev->udev = usb_get_dev(interface_to_usbdev(interface));
+- dev->interface = interface;
++ dev->interface = usb_get_intf(interface);
+
+ /* set up the endpoint information */
+ /* use only the first bulk-in and bulk-out endpoints */
--- /dev/null
+From eb7f5a490c5edfe8126f64bc58b9ba2edef0a425 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 26 Sep 2019 11:12:25 +0200
+Subject: USB: usblcd: fix I/O after disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit eb7f5a490c5edfe8126f64bc58b9ba2edef0a425 upstream.
+
+Make sure to stop all I/O on disconnect by adding a disconnected flag
+which is used to prevent new I/O from being started and by stopping all
+ongoing I/O before returning.
+
+This also fixes a potential use-after-free on driver unbind in case the
+driver data is freed before the completion handler has run.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable <stable@vger.kernel.org> # 7bbe990c989e
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20190926091228.24634-7-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/usblcd.c | 33 +++++++++++++++++++++++++++++++--
+ 1 file changed, 31 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/misc/usblcd.c
++++ b/drivers/usb/misc/usblcd.c
+@@ -17,6 +17,7 @@
+ #include <linux/slab.h>
+ #include <linux/errno.h>
+ #include <linux/mutex.h>
++#include <linux/rwsem.h>
+ #include <linux/uaccess.h>
+ #include <linux/usb.h>
+
+@@ -56,6 +57,8 @@ struct usb_lcd {
+ using up all RAM */
+ struct usb_anchor submitted; /* URBs to wait for
+ before suspend */
++ struct rw_semaphore io_rwsem;
++ unsigned long disconnected:1;
+ };
+ #define to_lcd_dev(d) container_of(d, struct usb_lcd, kref)
+
+@@ -141,6 +144,13 @@ static ssize_t lcd_read(struct file *fil
+
+ dev = file->private_data;
+
++ down_read(&dev->io_rwsem);
++
++ if (dev->disconnected) {
++ retval = -ENODEV;
++ goto out_up_io;
++ }
++
+ /* do a blocking bulk read to get data from the device */
+ retval = usb_bulk_msg(dev->udev,
+ usb_rcvbulkpipe(dev->udev,
+@@ -157,6 +167,9 @@ static ssize_t lcd_read(struct file *fil
+ retval = bytes_read;
+ }
+
++out_up_io:
++ up_read(&dev->io_rwsem);
++
+ return retval;
+ }
+
+@@ -236,11 +249,18 @@ static ssize_t lcd_write(struct file *fi
+ if (r < 0)
+ return -EINTR;
+
++ down_read(&dev->io_rwsem);
++
++ if (dev->disconnected) {
++ retval = -ENODEV;
++ goto err_up_io;
++ }
++
+ /* create a urb, and a buffer for it, and copy the data to the urb */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ retval = -ENOMEM;
+- goto err_no_buf;
++ goto err_up_io;
+ }
+
+ buf = usb_alloc_coherent(dev->udev, count, GFP_KERNEL,
+@@ -277,6 +297,7 @@ static ssize_t lcd_write(struct file *fi
+ the USB core will eventually free it entirely */
+ usb_free_urb(urb);
+
++ up_read(&dev->io_rwsem);
+ exit:
+ return count;
+ error_unanchor:
+@@ -284,7 +305,8 @@ error_unanchor:
+ error:
+ usb_free_coherent(dev->udev, count, buf, urb->transfer_dma);
+ usb_free_urb(urb);
+-err_no_buf:
++err_up_io:
++ up_read(&dev->io_rwsem);
+ up(&dev->limit_sem);
+ return retval;
+ }
+@@ -324,6 +346,7 @@ static int lcd_probe(struct usb_interfac
+
+ kref_init(&dev->kref);
+ sema_init(&dev->limit_sem, USB_LCD_CONCURRENT_WRITES);
++ init_rwsem(&dev->io_rwsem);
+ init_usb_anchor(&dev->submitted);
+
+ dev->udev = usb_get_dev(interface_to_usbdev(interface));
+@@ -421,6 +444,12 @@ static void lcd_disconnect(struct usb_in
+ /* give back our minor */
+ usb_deregister_dev(interface, &lcd_class);
+
++ down_write(&dev->io_rwsem);
++ dev->disconnected = 1;
++ up_write(&dev->io_rwsem);
++
++ usb_kill_anchored_urbs(&dev->submitted);
++
+ /* decrement our usage count */
+ kref_put(&dev->kref, lcd_delete);
+
--- /dev/null
+From 9a31535859bfd8d1c3ed391f5e9247cd87bb7909 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 1 Oct 2019 10:49:06 +0200
+Subject: USB: usblp: fix runtime PM after driver unbind
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 9a31535859bfd8d1c3ed391f5e9247cd87bb7909 upstream.
+
+Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate
+interface PM usage counter") USB drivers must always balance their
+runtime PM gets and puts, including when the driver has already been
+unbound from the interface.
+
+Leaving the interface with a positive PM usage counter would prevent a
+later bound driver from suspending the device.
+
+Fixes: c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191001084908.2003-3-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/usblp.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/class/usblp.c
++++ b/drivers/usb/class/usblp.c
+@@ -474,10 +474,12 @@ static int usblp_release(struct inode *i
+
+ mutex_lock(&usblp_mutex);
+ usblp->used = 0;
+- if (usblp->present) {
++ if (usblp->present)
+ usblp_unlink_urbs(usblp);
+- usb_autopm_put_interface(usblp->intf);
+- } else /* finish cleanup from disconnect */
++
++ usb_autopm_put_interface(usblp->intf);
++
++ if (!usblp->present) /* finish cleanup from disconnect */
+ usblp_cleanup(usblp);
+ mutex_unlock(&usblp_mutex);
+ return 0;
--- /dev/null
+From a70bcbc322837eda1ab5994d12db941dc9733a7d Mon Sep 17 00:00:00 2001
+From: Rick Tseng <rtseng@nvidia.com>
+Date: Fri, 4 Oct 2019 14:59:30 +0300
+Subject: usb: xhci: wait for CNR controller not ready bit in xhci resume
+
+From: Rick Tseng <rtseng@nvidia.com>
+
+commit a70bcbc322837eda1ab5994d12db941dc9733a7d upstream.
+
+NVIDIA 3.1 xHCI card would lose power when moving power state into D3Cold.
+Thus we need to wait for CNR bit to clear in xhci resume, just as in
+xhci init.
+
+[Minor changes to comment and commit message -Mathias]
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Rick Tseng <rtseng@nvidia.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/1570190373-30684-6-git-send-email-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -1044,6 +1044,18 @@ int xhci_resume(struct xhci_hcd *xhci, b
+ hibernated = true;
+
+ if (!hibernated) {
++ /*
++ * Some controllers might lose power during suspend, so wait
++ * for controller not ready bit to clear, just as in xHC init.
++ */
++ retval = xhci_handshake(&xhci->op_regs->status,
++ STS_CNR, 0, 10 * 1000 * 1000);
++ if (retval) {
++ xhci_warn(xhci, "Controller not ready at resume %d\n",
++ retval);
++ spin_unlock_irq(&xhci->lock);
++ return retval;
++ }
+ /* step 1: restore register */
+ xhci_restore_registers(xhci);
+ /* step 2: initialize command ring buffer */
--- /dev/null
+From d500c63f80f2ea08ee300e57da5f2af1c13875f5 Mon Sep 17 00:00:00 2001
+From: Jan Schmidt <jan@centricular.com>
+Date: Fri, 4 Oct 2019 14:59:28 +0300
+Subject: xhci: Check all endpoints for LPM timeout
+
+From: Jan Schmidt <jan@centricular.com>
+
+commit d500c63f80f2ea08ee300e57da5f2af1c13875f5 upstream.
+
+If an endpoint is encountered that returns USB3_LPM_DEVICE_INITIATED, keep
+checking further endpoints, as there might be periodic endpoints later
+that return USB3_LPM_DISABLED due to shorter service intervals.
+
+Without this, the code can set too high a maximum-exit-latency and
+prevent the use of multiple USB3 cameras that should be able to work.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Jan Schmidt <jan@centricular.com>
+Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/1570190373-30684-4-git-send-email-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -4491,12 +4491,12 @@ static int xhci_update_timeout_for_endpo
+ alt_timeout = xhci_call_host_update_timeout_for_endpoint(xhci, udev,
+ desc, state, timeout);
+
+- /* If we found we can't enable hub-initiated LPM, or
++ /* If we found we can't enable hub-initiated LPM, and
+ * the U1 or U2 exit latency was too high to allow
+- * device-initiated LPM as well, just stop searching.
++ * device-initiated LPM as well, then we will disable LPM
++ * for this device, so stop searching any further.
+ */
+- if (alt_timeout == USB3_LPM_DISABLED ||
+- alt_timeout == USB3_LPM_DEVICE_INITIATED) {
++ if (alt_timeout == USB3_LPM_DISABLED) {
+ *timeout = alt_timeout;
+ return -E2BIG;
+ }
--- /dev/null
+From c03101ff4f74bb30679c1a03d551ecbef1024bf6 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Fri, 4 Oct 2019 14:59:26 +0300
+Subject: xhci: Fix false warning message about wrong bounce buffer write length
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit c03101ff4f74bb30679c1a03d551ecbef1024bf6 upstream.
+
+The check printing out the "WARN Wrong bounce buffer write length:"
+uses incorrect values when comparing bytes written from scatterlist
+to bounce buffer. Actual copied lengths are fine.
+
+The used seg->bounce_len will be set to equal new_buf_len a few lines later
+in the code, but is incorrect when doing the comparison.
+
+The patch which added this false warning was backported to 4.8+ kernels
+so this should be backported as far as well.
+
+Cc: <stable@vger.kernel.org> # v4.8+
+Fixes: 597c56e372da ("xhci: update bounce buffer with correct sg num")
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/1570190373-30684-2-git-send-email-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -3223,10 +3223,10 @@ static int xhci_align_td(struct xhci_hcd
+ if (usb_urb_dir_out(urb)) {
+ len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs,
+ seg->bounce_buf, new_buff_len, enqd_len);
+- if (len != seg->bounce_len)
++ if (len != new_buff_len)
+ xhci_warn(xhci,
+ "WARN Wrong bounce buffer write length: %zu != %d\n",
+- len, seg->bounce_len);
++ len, new_buff_len);
+ seg->bounce_dma = dma_map_single(dev, seg->bounce_buf,
+ max_pkt, DMA_TO_DEVICE);
+ } else {
--- /dev/null
+From ac343366846a445bb81f0a0e8f16abb8bd5d5d88 Mon Sep 17 00:00:00 2001
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Date: Fri, 4 Oct 2019 14:59:32 +0300
+Subject: xhci: Increase STS_SAVE timeout in xhci_suspend()
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+commit ac343366846a445bb81f0a0e8f16abb8bd5d5d88 upstream.
+
+After commit f7fac17ca925 ("xhci: Convert xhci_handshake() to use
+readl_poll_timeout_atomic()"), ASMedia xHCI may fail to suspend.
+
+Although the algorithms are essentially the same, the old max timeout is
+(usec + usec * time of doing readl()), and the new max timeout is just
+usec, which is much less than the old one.
+
+Increase the timeout to make ASMedia xHCI able to suspend again.
+
+BugLink: https://bugs.launchpad.net/bugs/1844021
+Fixes: f7fac17ca925 ("xhci: Convert xhci_handshake() to use readl_poll_timeout_atomic()")
+Cc: <stable@vger.kernel.org> # v5.2+
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/1570190373-30684-8-git-send-email-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -968,7 +968,7 @@ int xhci_suspend(struct xhci_hcd *xhci,
+ writel(command, &xhci->op_regs->command);
+ xhci->broken_suspend = 0;
+ if (xhci_handshake(&xhci->op_regs->status,
+- STS_SAVE, 0, 10 * 1000)) {
++ STS_SAVE, 0, 20 * 1000)) {
+ /*
+ * AMD SNPS xHC 3.0 occasionally does not clear the
+ * SSS bit of USBSTS and when driver tries to poll
--- /dev/null
+From cd9d9491e835a845c1a98b8471f88d26285e0bb9 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Fri, 4 Oct 2019 14:59:27 +0300
+Subject: xhci: Prevent device initiated U1/U2 link pm if exit latency is too long
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit cd9d9491e835a845c1a98b8471f88d26285e0bb9 upstream.
+
+If host/hub initiated link pm is prevented by a driver flag we still must
+ensure that periodic endpoints have longer service intervals than link pm
+exit latency before allowing device initiated link pm.
+
+Fix this by continue walking and checking endpoint service interval if
+xhci_get_timeout_no_hub_lpm() returns anything else than USB3_LPM_DISABLED
+
+While at it fix the split line error message
+
+Tested-by: Jan Schmidt <jan@centricular.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/1570190373-30684-3-git-send-email-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -4607,10 +4607,12 @@ static u16 xhci_calculate_lpm_timeout(st
+ if (intf->dev.driver) {
+ driver = to_usb_driver(intf->dev.driver);
+ if (driver && driver->disable_hub_initiated_lpm) {
+- dev_dbg(&udev->dev, "Hub-initiated %s disabled "
+- "at request of driver %s\n",
+- state_name, driver->name);
+- return xhci_get_timeout_no_hub_lpm(udev, state);
++ dev_dbg(&udev->dev, "Hub-initiated %s disabled at request of driver %s\n",
++ state_name, driver->name);
++ timeout = xhci_get_timeout_no_hub_lpm(udev,
++ state);
++ if (timeout == USB3_LPM_DISABLED)
++ return timeout;
+ }
+ }
+