--- /dev/null
+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:
--- /dev/null
+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)
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
+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
--- /dev/null
+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/net/usb/usbnet.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -1990,6 +1990,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;
--- /dev/null
+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
+@@ -609,15 +609,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
+@@ -717,6 +717,7 @@ struct usb_interface_assoc_descriptor {
+ __u8 iFunction;
+ } __attribute__ ((packed));
+
++#define USB_DT_INTERFACE_ASSOCIATION_SIZE 8
+
+ /*-------------------------------------------------------------------------*/
+
--- /dev/null
+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;
+
+@@ -2504,6 +2502,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
+@@ -2565,21 +2564,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);
+@@ -2785,13 +2779,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;
+@@ -141,9 +130,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);
--- /dev/null
+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
+@@ -818,7 +818,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
+@@ -4761,7 +4761,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
--- /dev/null
+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
+@@ -849,14 +849,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)
--- /dev/null
+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
+@@ -1490,7 +1490,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;