]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Oct 2017 12:04:32 +0000 (14:04 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Oct 2017 12:04:32 +0000 (14:04 +0200)
added patches:
iio-adc-twl4030-disable-the-vusb3v1-rugulator-in-the-error-handling-path-of-twl4030_madc_probe.patch
iio-adc-twl4030-fix-an-error-handling-path-in-twl4030_madc_probe.patch
revert-xhci-limit-usb2-port-wake-support-for-amd-promontory-hosts.patch
usb-core-harden-cdc_parse_cdc_header.patch
usb-fix-out-of-bounds-in-usb_set_configuration.patch
usb-g_mass_storage-fix-deadlock-when-driver-is-unbound.patch
usb-increase-quirk-delay-for-usb-devices.patch
usb-uas-fix-bug-in-handling-of-alternate-settings.patch
xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch
xhci-fix-sleeping-with-spin_lock_irq-held-in-asmedia-1042a-workaround.patch
xhci-set-missing-superspeedplus-link-protocol-bit-in-roothub-descriptor.patch

12 files changed:
queue-4.9/iio-adc-twl4030-disable-the-vusb3v1-rugulator-in-the-error-handling-path-of-twl4030_madc_probe.patch [new file with mode: 0644]
queue-4.9/iio-adc-twl4030-fix-an-error-handling-path-in-twl4030_madc_probe.patch [new file with mode: 0644]
queue-4.9/revert-xhci-limit-usb2-port-wake-support-for-amd-promontory-hosts.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/usb-core-harden-cdc_parse_cdc_header.patch [new file with mode: 0644]
queue-4.9/usb-fix-out-of-bounds-in-usb_set_configuration.patch [new file with mode: 0644]
queue-4.9/usb-g_mass_storage-fix-deadlock-when-driver-is-unbound.patch [new file with mode: 0644]
queue-4.9/usb-increase-quirk-delay-for-usb-devices.patch [new file with mode: 0644]
queue-4.9/usb-uas-fix-bug-in-handling-of-alternate-settings.patch [new file with mode: 0644]
queue-4.9/xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch [new file with mode: 0644]
queue-4.9/xhci-fix-sleeping-with-spin_lock_irq-held-in-asmedia-1042a-workaround.patch [new file with mode: 0644]
queue-4.9/xhci-set-missing-superspeedplus-link-protocol-bit-in-roothub-descriptor.patch [new file with mode: 0644]

diff --git a/queue-4.9/iio-adc-twl4030-disable-the-vusb3v1-rugulator-in-the-error-handling-path-of-twl4030_madc_probe.patch b/queue-4.9/iio-adc-twl4030-disable-the-vusb3v1-rugulator-in-the-error-handling-path-of-twl4030_madc_probe.patch
new file mode 100644 (file)
index 0000000..8f0a3c7
--- /dev/null
@@ -0,0 +1,42 @@
+From 7f70be6e4025db0551e6863e7eb9cca07122695c Mon Sep 17 00:00:00 2001
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Date: Sat, 23 Sep 2017 08:06:19 +0200
+Subject: iio: adc: twl4030: Disable the vusb3v1 rugulator in the error handling path of 'twl4030_madc_probe()'
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+commit 7f70be6e4025db0551e6863e7eb9cca07122695c upstream.
+
+Commit 7cc97d77ee8a has introduced a call to 'regulator_disable()' in the
+.remove function.
+So we should also have such a call in the .probe function in case of
+error after a successful 'regulator_enable()' call.
+
+Add a new label for that and use it.
+
+Fixes: 7cc97d77ee8a ("iio: adc: twl4030: Fix ADC[3:6] readings")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/twl4030-madc.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/iio/adc/twl4030-madc.c
++++ b/drivers/iio/adc/twl4030-madc.c
+@@ -878,11 +878,13 @@ static int twl4030_madc_probe(struct pla
+       ret = iio_device_register(iio_dev);
+       if (ret) {
+               dev_err(&pdev->dev, "could not register iio device\n");
+-              goto err_i2c;
++              goto err_usb3v1;
+       }
+       return 0;
++err_usb3v1:
++      regulator_disable(madc->usb3v1);
+ err_i2c:
+       twl4030_madc_set_current_generator(madc, 0, 0);
+ err_current_generator:
diff --git a/queue-4.9/iio-adc-twl4030-fix-an-error-handling-path-in-twl4030_madc_probe.patch b/queue-4.9/iio-adc-twl4030-fix-an-error-handling-path-in-twl4030_madc_probe.patch
new file mode 100644 (file)
index 0000000..96422a2
--- /dev/null
@@ -0,0 +1,37 @@
+From 245a396a9b1a67ac5c3228737c261b3e48708a2a Mon Sep 17 00:00:00 2001
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Date: Sat, 23 Sep 2017 08:06:18 +0200
+Subject: iio: adc: twl4030: Fix an error handling path in 'twl4030_madc_probe()'
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+commit 245a396a9b1a67ac5c3228737c261b3e48708a2a upstream.
+
+If 'devm_regulator_get()' fails, we should go through the existing error
+handling path instead of returning directly, as done is all the other
+error handling paths in this function.
+
+Fixes: 7cc97d77ee8a ("iio: adc: twl4030: Fix ADC[3:6] readings")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/twl4030-madc.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/adc/twl4030-madc.c
++++ b/drivers/iio/adc/twl4030-madc.c
+@@ -866,8 +866,10 @@ static int twl4030_madc_probe(struct pla
+       /* Enable 3v1 bias regulator for MADC[3:6] */
+       madc->usb3v1 = devm_regulator_get(madc->dev, "vusb3v1");
+-      if (IS_ERR(madc->usb3v1))
+-              return -ENODEV;
++      if (IS_ERR(madc->usb3v1)) {
++              ret = -ENODEV;
++              goto err_i2c;
++      }
+       ret = regulator_enable(madc->usb3v1);
+       if (ret)
diff --git a/queue-4.9/revert-xhci-limit-usb2-port-wake-support-for-amd-promontory-hosts.patch b/queue-4.9/revert-xhci-limit-usb2-port-wake-support-for-amd-promontory-hosts.patch
new file mode 100644 (file)
index 0000000..f1acd2c
--- /dev/null
@@ -0,0 +1,81 @@
+From bcd6a7aa13800afc1418e6b29d944d882214939a Mon Sep 17 00:00:00 2001
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Date: Mon, 18 Sep 2017 17:39:19 +0300
+Subject: Revert "xhci: Limit USB2 port wake support for AMD Promontory hosts"
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+commit bcd6a7aa13800afc1418e6b29d944d882214939a upstream.
+
+This reverts commit dec08194ffeccfa1cf085906b53d301930eae18f.
+
+Commit dec08194ffec ("xhci: Limit USB2 port wake support for AMD Promontory
+hosts") makes all high speed USB ports on ASUS PRIME B350M-A cease to
+function after enabling runtime PM.
+
+All boards with this chipsets will be affected, so revert the commit.
+
+The original patch was added to stable 4.9, 4.11 and 4.12 and needs
+to reverted from there as well
+
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-hub.c |    3 ---
+ drivers/usb/host/xhci-pci.c |   12 ------------
+ drivers/usb/host/xhci.h     |    2 +-
+ 3 files changed, 1 insertion(+), 16 deletions(-)
+
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -1360,9 +1360,6 @@ int xhci_bus_suspend(struct usb_hcd *hcd
+                               t2 |= PORT_WKOC_E | PORT_WKCONN_E;
+                               t2 &= ~PORT_WKDISC_E;
+                       }
+-                      if ((xhci->quirks & XHCI_U2_DISABLE_WAKE) &&
+-                          (hcd->speed < HCD_USB3))
+-                              t2 &= ~PORT_WAKE_BITS;
+               } else
+                       t2 &= ~PORT_WAKE_BITS;
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -54,11 +54,6 @@
+ #define PCI_DEVICE_ID_INTEL_APL_XHCI                  0x5aa8
+ #define PCI_DEVICE_ID_INTEL_DNV_XHCI                  0x19d0
+-#define PCI_DEVICE_ID_AMD_PROMONTORYA_4                       0x43b9
+-#define PCI_DEVICE_ID_AMD_PROMONTORYA_3                       0x43ba
+-#define PCI_DEVICE_ID_AMD_PROMONTORYA_2                       0x43bb
+-#define PCI_DEVICE_ID_AMD_PROMONTORYA_1                       0x43bc
+-
+ #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI              0x1142
+ static const char hcd_name[] = "xhci_hcd";
+@@ -142,13 +137,6 @@ static void xhci_pci_quirks(struct devic
+       if (pdev->vendor == PCI_VENDOR_ID_AMD)
+               xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+-      if ((pdev->vendor == PCI_VENDOR_ID_AMD) &&
+-              ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) ||
+-              (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_3) ||
+-              (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2) ||
+-              (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1)))
+-              xhci->quirks |= XHCI_U2_DISABLE_WAKE;
+-
+       if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
+               xhci->quirks |= XHCI_LPM_SUPPORT;
+               xhci->quirks |= XHCI_INTEL_HOST;
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1660,7 +1660,7 @@ struct xhci_hcd {
+ /* For controller with a broken Port Disable implementation */
+ #define XHCI_BROKEN_PORT_PED  (1 << 25)
+ #define XHCI_LIMIT_ENDPOINT_INTERVAL_7        (1 << 26)
+-#define XHCI_U2_DISABLE_WAKE  (1 << 27)
++/* Reserved. It was XHCI_U2_DISABLE_WAKE */
+ #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL       (1 << 28)
+       unsigned int            num_active_eps;
index 6200f58b5b2ba16565c22c3f413a0c8f2dbf75e7..05fe3354ad61ff99b0317a5e7ce407372fa5d12b 100644 (file)
@@ -15,3 +15,14 @@ usb-dummy-hcd-fix-connection-failures-wrong-speed.patch
 usb-dummy-hcd-fix-infinite-loop-resubmission-bug.patch
 usb-dummy-hcd-fix-erroneous-synchronization-change.patch
 usb-devio-don-t-corrupt-user-memory.patch
+usb-g_mass_storage-fix-deadlock-when-driver-is-unbound.patch
+usb-uas-fix-bug-in-handling-of-alternate-settings.patch
+usb-core-harden-cdc_parse_cdc_header.patch
+usb-increase-quirk-delay-for-usb-devices.patch
+usb-fix-out-of-bounds-in-usb_set_configuration.patch
+xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch
+xhci-fix-sleeping-with-spin_lock_irq-held-in-asmedia-1042a-workaround.patch
+xhci-set-missing-superspeedplus-link-protocol-bit-in-roothub-descriptor.patch
+revert-xhci-limit-usb2-port-wake-support-for-amd-promontory-hosts.patch
+iio-adc-twl4030-fix-an-error-handling-path-in-twl4030_madc_probe.patch
+iio-adc-twl4030-disable-the-vusb3v1-rugulator-in-the-error-handling-path-of-twl4030_madc_probe.patch
diff --git a/queue-4.9/usb-core-harden-cdc_parse_cdc_header.patch b/queue-4.9/usb-core-harden-cdc_parse_cdc_header.patch
new file mode 100644 (file)
index 0000000..571dd1c
--- /dev/null
@@ -0,0 +1,39 @@
+From 2e1c42391ff2556387b3cb6308b24f6f65619feb Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Thu, 21 Sep 2017 16:58:48 +0200
+Subject: USB: core: harden cdc_parse_cdc_header
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+commit 2e1c42391ff2556387b3cb6308b24f6f65619feb upstream.
+
+Andrey Konovalov reported a possible out-of-bounds problem for the
+cdc_parse_cdc_header function.  He writes:
+       It looks like cdc_parse_cdc_header() doesn't validate buflen
+       before accessing buffer[1], buffer[2] and so on. The only check
+       present is while (buflen > 0).
+
+So fix this issue up by properly validating the buffer length matches
+what the descriptor says it is.
+
+Reported-by: Andrey Konovalov <andreyknvl@google.com>
+Tested-by: Andrey Konovalov <andreyknvl@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/message.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -2068,6 +2068,10 @@ int cdc_parse_cdc_header(struct usb_cdc_
+                       elength = 1;
+                       goto next_desc;
+               }
++              if ((buflen < elength) || (elength < 3)) {
++                      dev_err(&intf->dev, "invalid descriptor buffer length\n");
++                      break;
++              }
+               if (buffer[1] != USB_DT_CS_INTERFACE) {
+                       dev_err(&intf->dev, "skipping garbage\n");
+                       goto next_desc;
diff --git a/queue-4.9/usb-fix-out-of-bounds-in-usb_set_configuration.patch b/queue-4.9/usb-fix-out-of-bounds-in-usb_set_configuration.patch
new file mode 100644 (file)
index 0000000..6b66008
--- /dev/null
@@ -0,0 +1,67 @@
+From bd7a3fe770ebd8391d1c7d072ff88e9e76d063eb Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Tue, 19 Sep 2017 15:07:17 +0200
+Subject: USB: fix out-of-bounds in usb_set_configuration
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+commit bd7a3fe770ebd8391d1c7d072ff88e9e76d063eb upstream.
+
+Andrey Konovalov reported a possible out-of-bounds problem for a USB interface
+association descriptor.  He writes:
+       It seems there's no proper size check of a USB_DT_INTERFACE_ASSOCIATION
+       descriptor. It's only checked that the size is >= 2 in
+       usb_parse_configuration(), so find_iad() might do out-of-bounds access
+       to intf_assoc->bInterfaceCount.
+
+And he's right, we don't check for crazy descriptors of this type very well, so
+resolve this problem.  Yet another issue found by syzkaller...
+
+Reported-by: Andrey Konovalov <andreyknvl@google.com>
+Tested-by: Andrey Konovalov <andreyknvl@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/config.c    |   14 +++++++++++---
+ include/uapi/linux/usb/ch9.h |    1 +
+ 2 files changed, 12 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -638,15 +638,23 @@ static int usb_parse_configuration(struc
+               } else if (header->bDescriptorType ==
+                               USB_DT_INTERFACE_ASSOCIATION) {
++                      struct usb_interface_assoc_descriptor *d;
++
++                      d = (struct usb_interface_assoc_descriptor *)header;
++                      if (d->bLength < USB_DT_INTERFACE_ASSOCIATION_SIZE) {
++                              dev_warn(ddev,
++                                       "config %d has an invalid interface association descriptor of length %d, skipping\n",
++                                       cfgno, d->bLength);
++                              continue;
++                      }
++
+                       if (iad_num == USB_MAXIADS) {
+                               dev_warn(ddev, "found more Interface "
+                                              "Association Descriptors "
+                                              "than allocated for in "
+                                              "configuration %d\n", cfgno);
+                       } else {
+-                              config->intf_assoc[iad_num] =
+-                                      (struct usb_interface_assoc_descriptor
+-                                      *)header;
++                              config->intf_assoc[iad_num] = d;
+                               iad_num++;
+                       }
+--- a/include/uapi/linux/usb/ch9.h
++++ b/include/uapi/linux/usb/ch9.h
+@@ -759,6 +759,7 @@ struct usb_interface_assoc_descriptor {
+       __u8  iFunction;
+ } __attribute__ ((packed));
++#define USB_DT_INTERFACE_ASSOCIATION_SIZE     8
+ /*-------------------------------------------------------------------------*/
diff --git a/queue-4.9/usb-g_mass_storage-fix-deadlock-when-driver-is-unbound.patch b/queue-4.9/usb-g_mass_storage-fix-deadlock-when-driver-is-unbound.patch
new file mode 100644 (file)
index 0000000..760c4f8
--- /dev/null
@@ -0,0 +1,261 @@
+From 1fbbb78f25d1291274f320462bf6908906f538db Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Thu, 21 Sep 2017 13:22:00 -0400
+Subject: USB: g_mass_storage: Fix deadlock when driver is unbound
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 1fbbb78f25d1291274f320462bf6908906f538db upstream.
+
+As a holdover from the old g_file_storage gadget, the g_mass_storage
+legacy gadget driver attempts to unregister itself when its main
+operating thread terminates (if it hasn't been unregistered already).
+This is not strictly necessary; it was never more than an attempt to
+have the gadget fail cleanly if something went wrong and the main
+thread was killed.
+
+However, now that the UDC core manages gadget drivers independently of
+UDC drivers, this scheme doesn't work any more.  A simple test:
+
+       modprobe dummy-hcd
+       modprobe g-mass-storage file=...
+       rmmod dummy-hcd
+
+ends up in a deadlock with the following backtrace:
+
+ sysrq: SysRq : Show Blocked State
+   task                PC stack   pid father
+ file-storage    D    0  1130      2 0x00000000
+ Call Trace:
+  __schedule+0x53e/0x58c
+  schedule+0x6e/0x77
+  schedule_preempt_disabled+0xd/0xf
+  __mutex_lock.isra.1+0x129/0x224
+  ? _raw_spin_unlock_irqrestore+0x12/0x14
+  __mutex_lock_slowpath+0x12/0x14
+  mutex_lock+0x28/0x2b
+  usb_gadget_unregister_driver+0x29/0x9b [udc_core]
+  usb_composite_unregister+0x10/0x12 [libcomposite]
+  msg_cleanup+0x1d/0x20 [g_mass_storage]
+  msg_thread_exits+0xd/0xdd7 [g_mass_storage]
+  fsg_main_thread+0x1395/0x13d6 [usb_f_mass_storage]
+  ? __schedule+0x573/0x58c
+  kthread+0xd9/0xdb
+  ? do_set_interface+0x25c/0x25c [usb_f_mass_storage]
+  ? init_completion+0x1e/0x1e
+  ret_from_fork+0x19/0x24
+ rmmod           D    0  1155    683 0x00000000
+ Call Trace:
+  __schedule+0x53e/0x58c
+  schedule+0x6e/0x77
+  schedule_timeout+0x26/0xbc
+  ? __schedule+0x573/0x58c
+  do_wait_for_common+0xb3/0x128
+  ? usleep_range+0x81/0x81
+  ? wake_up_q+0x3f/0x3f
+  wait_for_common+0x2e/0x45
+  wait_for_completion+0x17/0x19
+  fsg_common_put+0x34/0x81 [usb_f_mass_storage]
+  fsg_free_inst+0x13/0x1e [usb_f_mass_storage]
+  usb_put_function_instance+0x1a/0x25 [libcomposite]
+  msg_unbind+0x2a/0x42 [g_mass_storage]
+  __composite_unbind+0x4a/0x6f [libcomposite]
+  composite_unbind+0x12/0x14 [libcomposite]
+  usb_gadget_remove_driver+0x4f/0x77 [udc_core]
+  usb_del_gadget_udc+0x52/0xcc [udc_core]
+  dummy_udc_remove+0x27/0x2c [dummy_hcd]
+  platform_drv_remove+0x1d/0x31
+  device_release_driver_internal+0xe9/0x16d
+  device_release_driver+0x11/0x13
+  bus_remove_device+0xd2/0xe2
+  device_del+0x19f/0x221
+  ? selinux_capable+0x22/0x27
+  platform_device_del+0x21/0x63
+  platform_device_unregister+0x10/0x1a
+  cleanup+0x20/0x817 [dummy_hcd]
+  SyS_delete_module+0x10c/0x197
+  ? ____fput+0xd/0xf
+  ? task_work_run+0x55/0x62
+  ? prepare_exit_to_usermode+0x65/0x75
+  do_fast_syscall_32+0x86/0xc3
+  entry_SYSENTER_32+0x4e/0x7c
+
+What happens is that removing the dummy-hcd driver causes the UDC core
+to unbind the gadget driver, which it does while holding the udc_lock
+mutex.  The unbind routine in g_mass_storage tells the main thread to
+exit and waits for it to terminate.
+
+But as mentioned above, when the main thread exits it tries to
+unregister the mass-storage function driver.  Via the composite
+framework this ends up calling usb_gadget_unregister_driver(), which
+tries to acquire the udc_lock mutex.  The result is deadlock.
+
+The simplest way to fix the problem is not to be so clever: The main
+thread doesn't have to unregister the function driver.  The side
+effects won't be so terrible; if the gadget is still attached to a USB
+host when the main thread is killed, it will appear to the host as
+though the gadget's firmware has crashed -- a reasonably accurate
+interpretation, and an all-too-common occurrence for USB mass-storage
+devices.
+
+In fact, the code to unregister the driver when the main thread exits
+is specific to g-mass-storage; it is not used when f-mass-storage is
+included as a function in a larger composite device.  Therefore the
+entire mechanism responsible for this (the fsg_operations structure
+with its ->thread_exits method, the fsg_common_set_ops() routine, and
+the msg_thread_exits() callback routine) can all be eliminated.  Even
+the msg_registered bitflag can be removed, because now the driver is
+unregistered in only one place rather than in two places.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/function/f_mass_storage.c |   29 +++++++--------------------
+ drivers/usb/gadget/function/f_mass_storage.h |   14 -------------
+ drivers/usb/gadget/legacy/mass_storage.c     |   19 +----------------
+ 3 files changed, 10 insertions(+), 52 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_mass_storage.c
++++ b/drivers/usb/gadget/function/f_mass_storage.c
+@@ -306,8 +306,6 @@ struct fsg_common {
+       struct completion       thread_notifier;
+       struct task_struct      *thread_task;
+-      /* Callback functions. */
+-      const struct fsg_operations     *ops;
+       /* Gadget's private data. */
+       void                    *private_data;
+@@ -2505,6 +2503,7 @@ static void handle_exception(struct fsg_
+ static int fsg_main_thread(void *common_)
+ {
+       struct fsg_common       *common = common_;
++      int                     i;
+       /*
+        * Allow the thread to be killed by a signal, but set the signal mask
+@@ -2566,21 +2565,16 @@ static int fsg_main_thread(void *common_
+       common->thread_task = NULL;
+       spin_unlock_irq(&common->lock);
+-      if (!common->ops || !common->ops->thread_exits
+-       || common->ops->thread_exits(common) < 0) {
+-              int i;
+-
+-              down_write(&common->filesem);
+-              for (i = 0; i < ARRAY_SIZE(common->luns); --i) {
+-                      struct fsg_lun *curlun = common->luns[i];
+-                      if (!curlun || !fsg_lun_is_open(curlun))
+-                              continue;
++      /* Eject media from all LUNs */
++      down_write(&common->filesem);
++      for (i = 0; i < ARRAY_SIZE(common->luns); i++) {
++              struct fsg_lun *curlun = common->luns[i];
++
++              if (curlun && fsg_lun_is_open(curlun))
+                       fsg_lun_close(curlun);
+-                      curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;
+-              }
+-              up_write(&common->filesem);
+       }
++      up_write(&common->filesem);
+       /* Let fsg_unbind() know the thread has exited */
+       complete_and_exit(&common->thread_notifier, 0);
+@@ -2770,13 +2764,6 @@ void fsg_common_remove_luns(struct fsg_c
+ }
+ EXPORT_SYMBOL_GPL(fsg_common_remove_luns);
+-void fsg_common_set_ops(struct fsg_common *common,
+-                      const struct fsg_operations *ops)
+-{
+-      common->ops = ops;
+-}
+-EXPORT_SYMBOL_GPL(fsg_common_set_ops);
+-
+ void fsg_common_free_buffers(struct fsg_common *common)
+ {
+       _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers);
+--- a/drivers/usb/gadget/function/f_mass_storage.h
++++ b/drivers/usb/gadget/function/f_mass_storage.h
+@@ -60,17 +60,6 @@ struct fsg_module_parameters {
+ struct fsg_common;
+ /* FSF callback functions */
+-struct fsg_operations {
+-      /*
+-       * Callback function to call when thread exits.  If no
+-       * callback is set or it returns value lower then zero MSF
+-       * will force eject all LUNs it operates on (including those
+-       * marked as non-removable or with prevent_medium_removal flag
+-       * set).
+-       */
+-      int (*thread_exits)(struct fsg_common *common);
+-};
+-
+ struct fsg_lun_opts {
+       struct config_group group;
+       struct fsg_lun *lun;
+@@ -142,9 +131,6 @@ void fsg_common_remove_lun(struct fsg_lu
+ void fsg_common_remove_luns(struct fsg_common *common);
+-void fsg_common_set_ops(struct fsg_common *common,
+-                      const struct fsg_operations *ops);
+-
+ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg,
+                         unsigned int id, const char *name,
+                         const char **name_pfx);
+--- a/drivers/usb/gadget/legacy/mass_storage.c
++++ b/drivers/usb/gadget/legacy/mass_storage.c
+@@ -107,15 +107,6 @@ static unsigned int fsg_num_buffers = CO
+ FSG_MODULE_PARAMETERS(/* no prefix */, mod_data);
+-static unsigned long msg_registered;
+-static void msg_cleanup(void);
+-
+-static int msg_thread_exits(struct fsg_common *common)
+-{
+-      msg_cleanup();
+-      return 0;
+-}
+-
+ static int msg_do_config(struct usb_configuration *c)
+ {
+       struct fsg_opts *opts;
+@@ -154,9 +145,6 @@ static struct usb_configuration msg_conf
+ static int msg_bind(struct usb_composite_dev *cdev)
+ {
+-      static const struct fsg_operations ops = {
+-              .thread_exits = msg_thread_exits,
+-      };
+       struct fsg_opts *opts;
+       struct fsg_config config;
+       int status;
+@@ -173,8 +161,6 @@ static int msg_bind(struct usb_composite
+       if (status)
+               goto fail;
+-      fsg_common_set_ops(opts->common, &ops);
+-
+       status = fsg_common_set_cdev(opts->common, cdev, config.can_stall);
+       if (status)
+               goto fail_set_cdev;
+@@ -261,9 +247,8 @@ static int __init msg_init(void)
+ }
+ module_init(msg_init);
+-static void msg_cleanup(void)
++static void __exit msg_cleanup(void)
+ {
+-      if (test_and_clear_bit(0, &msg_registered))
+-              usb_composite_unregister(&msg_driver);
++      usb_composite_unregister(&msg_driver);
+ }
+ module_exit(msg_cleanup);
diff --git a/queue-4.9/usb-increase-quirk-delay-for-usb-devices.patch b/queue-4.9/usb-increase-quirk-delay-for-usb-devices.patch
new file mode 100644 (file)
index 0000000..c0bcfe9
--- /dev/null
@@ -0,0 +1,52 @@
+From b2a542bbb3081dbd64acc8929c140d196664c406 Mon Sep 17 00:00:00 2001
+From: Dmitry Fleytman <dmitry@daynix.com>
+Date: Tue, 5 Sep 2017 11:40:56 +0300
+Subject: usb: Increase quirk delay for USB devices
+
+From: Dmitry Fleytman <dmitry@daynix.com>
+
+commit b2a542bbb3081dbd64acc8929c140d196664c406 upstream.
+
+Commit e0429362ab15
+("usb: Add device quirk for Logitech HD Pro Webcams C920 and C930e")
+introduced quirk to workaround an issue with some Logitech webcams.
+
+The workaround is introducing delay for some USB operations.
+
+According to our testing, delay introduced by original commit
+is not long enough and in rare cases we still see issues described
+by the aforementioned commit.
+
+This patch increases delays introduced by original commit.
+Having this patch applied we do not see those problems anymore.
+
+Signed-off-by: Dmitry Fleytman <dmitry@daynix.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/config.c |    2 +-
+ drivers/usb/core/hub.c    |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -847,7 +847,7 @@ int usb_get_configuration(struct usb_dev
+               }
+               if (dev->quirks & USB_QUIRK_DELAY_INIT)
+-                      msleep(100);
++                      msleep(200);
+               result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
+                   bigbuffer, length);
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -4828,7 +4828,7 @@ static void hub_port_connect(struct usb_
+                       goto loop;
+               if (udev->quirks & USB_QUIRK_DELAY_INIT)
+-                      msleep(1000);
++                      msleep(2000);
+               /* consecutive bus-powered hubs aren't reliable; they can
+                * violate the voltage drop budget.  if the new child has
diff --git a/queue-4.9/usb-uas-fix-bug-in-handling-of-alternate-settings.patch b/queue-4.9/usb-uas-fix-bug-in-handling-of-alternate-settings.patch
new file mode 100644 (file)
index 0000000..01e2b3f
--- /dev/null
@@ -0,0 +1,103 @@
+From 786de92b3cb26012d3d0f00ee37adf14527f35c4 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 22 Sep 2017 11:56:49 -0400
+Subject: USB: uas: fix bug in handling of alternate settings
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 786de92b3cb26012d3d0f00ee37adf14527f35c4 upstream.
+
+The uas driver has a subtle bug in the way it handles alternate
+settings.  The uas_find_uas_alt_setting() routine returns an
+altsetting value (the bAlternateSetting number in the descriptor), but
+uas_use_uas_driver() then treats that value as an index to the
+intf->altsetting array, which it isn't.
+
+Normally this doesn't cause any problems because the various
+alternate settings have bAlternateSetting values 0, 1, 2, ..., so the
+value is equal to the index in the array.  But this is not guaranteed,
+and Andrey Konovalov used the syzkaller fuzzer with KASAN to get a
+slab-out-of-bounds error by violating this assumption.
+
+This patch fixes the bug by making uas_find_uas_alt_setting() return a
+pointer to the altsetting entry rather than either the value or the
+index.  Pointers are less subject to misinterpretation.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-by: Andrey Konovalov <andreyknvl@google.com>
+Tested-by: Andrey Konovalov <andreyknvl@google.com>
+CC: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/uas-detect.h |   15 ++++++++-------
+ drivers/usb/storage/uas.c        |   10 +++++-----
+ 2 files changed, 13 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/storage/uas-detect.h
++++ b/drivers/usb/storage/uas-detect.h
+@@ -9,7 +9,8 @@ static int uas_is_interface(struct usb_h
+               intf->desc.bInterfaceProtocol == USB_PR_UAS);
+ }
+-static int uas_find_uas_alt_setting(struct usb_interface *intf)
++static struct usb_host_interface *uas_find_uas_alt_setting(
++              struct usb_interface *intf)
+ {
+       int i;
+@@ -17,10 +18,10 @@ static int uas_find_uas_alt_setting(stru
+               struct usb_host_interface *alt = &intf->altsetting[i];
+               if (uas_is_interface(alt))
+-                      return alt->desc.bAlternateSetting;
++                      return alt;
+       }
+-      return -ENODEV;
++      return NULL;
+ }
+ static int uas_find_endpoints(struct usb_host_interface *alt,
+@@ -58,14 +59,14 @@ static int uas_use_uas_driver(struct usb
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+       unsigned long flags = id->driver_info;
+-      int r, alt;
+-
++      struct usb_host_interface *alt;
++      int r;
+       alt = uas_find_uas_alt_setting(intf);
+-      if (alt < 0)
++      if (!alt)
+               return 0;
+-      r = uas_find_endpoints(&intf->altsetting[alt], eps);
++      r = uas_find_endpoints(alt, eps);
+       if (r < 0)
+               return 0;
+--- a/drivers/usb/storage/uas.c
++++ b/drivers/usb/storage/uas.c
+@@ -873,14 +873,14 @@ MODULE_DEVICE_TABLE(usb, uas_usb_ids);
+ static int uas_switch_interface(struct usb_device *udev,
+                               struct usb_interface *intf)
+ {
+-      int alt;
++      struct usb_host_interface *alt;
+       alt = uas_find_uas_alt_setting(intf);
+-      if (alt < 0)
+-              return alt;
++      if (!alt)
++              return -ENODEV;
+-      return usb_set_interface(udev,
+-                      intf->altsetting[0].desc.bInterfaceNumber, alt);
++      return usb_set_interface(udev, alt->desc.bInterfaceNumber,
++                      alt->desc.bAlternateSetting);
+ }
+ static int uas_configure_endpoints(struct uas_dev_info *devinfo)
diff --git a/queue-4.9/xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch b/queue-4.9/xhci-fix-finding-correct-bus_state-structure-for-usb-3.1-hosts.patch
new file mode 100644 (file)
index 0000000..e568b61
--- /dev/null
@@ -0,0 +1,34 @@
+From 5a838a13c9b4e5dd188b7a6eaeb894e9358ead0c Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Mon, 18 Sep 2017 17:39:13 +0300
+Subject: xhci: fix finding correct bus_state structure for USB 3.1 hosts
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 5a838a13c9b4e5dd188b7a6eaeb894e9358ead0c upstream.
+
+xhci driver keeps a bus_state structure for each hcd (usb2 and usb3)
+
+The structure is picked based on hcd speed, but driver only compared
+for HCD_USB3 speed, returning the wrong bus_state for HCD_USB31 hosts.
+
+This caused null pointer dereference errors in bus_resume function.
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1509,7 +1509,7 @@ struct xhci_bus_state {
+ static inline unsigned int hcd_index(struct usb_hcd *hcd)
+ {
+-      if (hcd->speed == HCD_USB3)
++      if (hcd->speed >= HCD_USB3)
+               return 0;
+       else
+               return 1;
diff --git a/queue-4.9/xhci-fix-sleeping-with-spin_lock_irq-held-in-asmedia-1042a-workaround.patch b/queue-4.9/xhci-fix-sleeping-with-spin_lock_irq-held-in-asmedia-1042a-workaround.patch
new file mode 100644 (file)
index 0000000..c7aef2a
--- /dev/null
@@ -0,0 +1,42 @@
+From 4ec1cd3eeeee7ccc35681270da028dbc29ca7bbd Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Mon, 18 Sep 2017 17:39:17 +0300
+Subject: xhci: Fix sleeping with spin_lock_irq() held in ASmedia 1042A workaround
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 4ec1cd3eeeee7ccc35681270da028dbc29ca7bbd upstream.
+
+The flow control workaround for ASM1042A xHC hosts sleeps between
+register polling. The workaround gets called in several places, among
+them with spin_lock_irq() held when xHC host is resumed or hoplug removed.
+
+This was noticed as kernel panics at resume on a Dell XPS15 9550 with
+TB16 thunderbolt dock.
+
+Avoid sleeping with spin_lock_irq() held, use udelay() instead
+
+The original workaround was added to 4.9 and 4.12 stable releases,
+this patch needs to be applied to those as well.
+
+Fixes: 9da5a1092b13 ("xhci: Bad Ethernet performance plugged in ASM1042A host")
+Reported-by: Jose Marino <marinoj@nso.edu>
+Tested-by: Jose Marino <marinoj@nso.edu>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/pci-quirks.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/pci-quirks.c
++++ b/drivers/usb/host/pci-quirks.c
+@@ -447,7 +447,7 @@ static int usb_asmedia_wait_write(struct
+               if ((value & ASMT_CONTROL_WRITE_BIT) == 0)
+                       return 0;
+-              usleep_range(40, 60);
++              udelay(50);
+       }
+       dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__);
diff --git a/queue-4.9/xhci-set-missing-superspeedplus-link-protocol-bit-in-roothub-descriptor.patch b/queue-4.9/xhci-set-missing-superspeedplus-link-protocol-bit-in-roothub-descriptor.patch
new file mode 100644 (file)
index 0000000..e153665
--- /dev/null
@@ -0,0 +1,57 @@
+From 7bea22b124d77845c85a62eaa29a85ba6cc2f899 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Mon, 18 Sep 2017 17:39:18 +0300
+Subject: xhci: set missing SuperSpeedPlus Link Protocol bit in roothub descriptor
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 7bea22b124d77845c85a62eaa29a85ba6cc2f899 upstream.
+
+A SuperSpeedPlus roothub needs to have the Link Protocol (LP) bit set in
+the bmSublinkSpeedAttr[] entry of a SuperSpeedPlus descriptor.
+
+If the xhci controller has an optional Protocol Speed ID (PSI) table then
+that will be used as a base to create the roothub SuperSpeedPlus
+descriptor.
+The PSI table does not however necessary contain the LP bit so we need
+to set it manually.
+
+Check the psi speed and set LP bit if speed is 10Gbps or higher.
+We're not setting it for 5 to 10Gbps as USB 3.1 specification always
+mention SuperSpeedPlus for 10Gbps or higher, and some SSIC USB 3.0 speeds
+can be over 5Gbps, such as SSIC-G3B-L1 at 5830 Mbps
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-hub.c |   11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -112,7 +112,7 @@ static int xhci_create_usb3_bos_desc(str
+       /* If PSI table exists, add the custom speed attributes from it */
+       if (usb3_1 && xhci->usb3_rhub.psi_count) {
+-              u32 ssp_cap_base, bm_attrib, psi;
++              u32 ssp_cap_base, bm_attrib, psi, psi_mant, psi_exp;
+               int offset;
+               ssp_cap_base = USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE;
+@@ -139,6 +139,15 @@ static int xhci_create_usb3_bos_desc(str
+               for (i = 0; i < xhci->usb3_rhub.psi_count; i++) {
+                       psi = xhci->usb3_rhub.psi[i];
+                       psi &= ~USB_SSP_SUBLINK_SPEED_RSVD;
++                      psi_exp = XHCI_EXT_PORT_PSIE(psi);
++                      psi_mant = XHCI_EXT_PORT_PSIM(psi);
++
++                      /* Shift to Gbps and set SSP Link BIT(14) if 10Gpbs */
++                      for (; psi_exp < 3; psi_exp++)
++                              psi_mant /= 1000;
++                      if (psi_mant >= 10)
++                              psi |= BIT(14);
++
+                       if ((psi & PLT_MASK) == PLT_SYM) {
+                       /* Symmetric, create SSA RX and TX from one PSI entry */
+                               put_unaligned_le32(psi, &buf[offset]);