--- /dev/null
+From 197b806ae5db60c6f609d74da04ddb62ea5e1b00 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Tue, 25 Apr 2017 10:55:12 -0700
+Subject: iscsi-target: Set session_fall_back_to_erl0 when forcing reinstatement
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit 197b806ae5db60c6f609d74da04ddb62ea5e1b00 upstream.
+
+While testing modification of per se_node_acl queue_depth forcing
+session reinstatement via lio_target_nacl_cmdsn_depth_store() ->
+core_tpg_set_initiator_node_queue_depth(), a hung task bug triggered
+when changing cmdsn_depth invoked session reinstatement while an iscsi
+login was already waiting for session reinstatement to complete.
+
+This can happen when an outstanding se_cmd descriptor is taking a
+long time to complete, and session reinstatement from iscsi login
+or cmdsn_depth change occurs concurrently.
+
+To address this bug, explicitly set session_fall_back_to_erl0 = 1
+when forcing session reinstatement, so session reinstatement is
+not attempted if an active session is already being shutdown.
+
+This patch has been tested with two scenarios. The first when
+iscsi login is blocked waiting for iscsi session reinstatement
+to complete followed by queue_depth change via configfs, and
+second when queue_depth change via configfs us blocked followed
+by a iscsi login driven session reinstatement.
+
+Note this patch depends on commit d36ad77f702 to handle multiple
+sessions per se_node_acl when changing cmdsn_depth, and for
+pre v4.5 kernels will need to be included for stable as well.
+
+Reported-by: Gary Guo <ghg@datera.io>
+Tested-by: Gary Guo <ghg@datera.io>
+Cc: Gary Guo <ghg@datera.io>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/iscsi/iscsi_target.c | 1 +
+ drivers/target/iscsi/iscsi_target_configfs.c | 1 +
+ drivers/target/iscsi/iscsi_target_login.c | 1 +
+ 3 files changed, 3 insertions(+)
+
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -4683,6 +4683,7 @@ int iscsit_release_sessions_for_tpg(stru
+ continue;
+ }
+ atomic_set(&sess->session_reinstatement, 1);
++ atomic_set(&sess->session_fall_back_to_erl0, 1);
+ spin_unlock(&sess->conn_lock);
+
+ list_move_tail(&se_sess->sess_list, &free_list);
+--- a/drivers/target/iscsi/iscsi_target_configfs.c
++++ b/drivers/target/iscsi/iscsi_target_configfs.c
+@@ -1528,6 +1528,7 @@ static void lio_tpg_close_session(struct
+ return;
+ }
+ atomic_set(&sess->session_reinstatement, 1);
++ atomic_set(&sess->session_fall_back_to_erl0, 1);
+ spin_unlock(&sess->conn_lock);
+
+ iscsit_stop_time2retain_timer(sess);
+--- a/drivers/target/iscsi/iscsi_target_login.c
++++ b/drivers/target/iscsi/iscsi_target_login.c
+@@ -208,6 +208,7 @@ int iscsi_check_for_session_reinstatemen
+ initiatorname_param->value) &&
+ (sess_p->sess_ops->SessionType == sessiontype))) {
+ atomic_set(&sess_p->session_reinstatement, 1);
++ atomic_set(&sess_p->session_fall_back_to_erl0, 1);
+ spin_unlock(&sess_p->conn_lock);
+ iscsit_inc_session_usage_count(sess_p);
+ iscsit_stop_time2retain_timer(sess_p);
xen-adjust-early-dom0-p2m-handling-to-xen-hypervisor-behavior.patch
+target-fix-compare_and_write_callback-handling-for-non-good-status.patch
+target-fileio-fix-zero-length-read-and-write-handling.patch
+iscsi-target-set-session_fall_back_to_erl0-when-forcing-reinstatement.patch
+usb-xhci-binterval-quirk-for-ti-tusb73x0.patch
+usb-host-xhci-print-correct-command-ring-address.patch
+usb-serial-ftdi_sio-add-device-id-for-microsemi-arrow-sf2plus-dev-kit.patch
+usb-proper-handling-of-race-condition-when-two-usb-class-drivers-try-to-call-init_usb_class-simultaneously.patch
+usb-revert-cdc-wdm-fix-out-of-sync-due-to-missing-notifications.patch
+staging-vt6656-use-off-stack-for-in-buffer-usb-transfers.patch
+staging-vt6656-use-off-stack-for-out-buffer-usb-transfers.patch
+staging-gdm724x-gdm_mux-fix-use-after-free-on-module-unload.patch
+staging-wilc1000-fix-problem-with-wrong-vif-index.patch
+staging-sir-fill-in-missing-fields-and-fix-probe.patch
+staging-comedi-jr3_pci-fix-possible-null-pointer-dereference.patch
+staging-comedi-jr3_pci-cope-with-jiffies-wraparound.patch
+usb-misc-add-missing-continue-in-switch.patch
+usb-gadget-legacy-gadgets-are-optional.patch
+usb-make-sure-usb-phy-of-gets-built-in.patch
+usb-hub-fix-error-loop-seen-after-hub-communication-errors.patch
+usb-hub-do-not-attempt-to-autosuspend-disconnected-devices.patch
+usb-misc-legousbtower-fix-buffers-on-stack.patch
--- /dev/null
+From 8ec04a491825e08068e92bed0bba7821893b6433 Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti@mev.co.uk>
+Date: Fri, 17 Feb 2017 11:09:09 +0000
+Subject: staging: comedi: jr3_pci: cope with jiffies wraparound
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+commit 8ec04a491825e08068e92bed0bba7821893b6433 upstream.
+
+The timer expiry routine `jr3_pci_poll_dev()` checks for expiry by
+checking whether the absolute value of `jiffies` (stored in local
+variable `now`) is greater than the expected expiry time in jiffy units.
+This will fail when `jiffies` wraps around. Also, it seems to make
+sense to handle the expiry one jiffy earlier than the current test. Use
+`time_after_eq()` to check for expiry.
+
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/comedi/drivers/jr3_pci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/comedi/drivers/jr3_pci.c
++++ b/drivers/staging/comedi/drivers/jr3_pci.c
+@@ -611,7 +611,7 @@ static void jr3_pci_poll_dev(unsigned lo
+ s = &dev->subdevices[i];
+ spriv = s->private;
+
+- if (now > spriv->next_time_min) {
++ if (time_after_eq(now, spriv->next_time_min)) {
+ struct jr3_pci_poll_delay sub_delay;
+
+ sub_delay = jr3_pci_poll_subdevice(s);
--- /dev/null
+From 45292be0b3db0b7f8286683b376e2d9f949d11f9 Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti@mev.co.uk>
+Date: Fri, 17 Feb 2017 11:09:08 +0000
+Subject: staging: comedi: jr3_pci: fix possible null pointer dereference
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+commit 45292be0b3db0b7f8286683b376e2d9f949d11f9 upstream.
+
+For some reason, the driver does not consider allocation of the
+subdevice private data to be a fatal error when attaching the COMEDI
+device. It tests the subdevice private data pointer for validity at
+certain points, but omits some crucial tests. In particular,
+`jr3_pci_auto_attach()` calls `jr3_pci_alloc_spriv()` to allocate and
+initialize the subdevice private data, but the same function
+subsequently dereferences the pointer to access the `next_time_min` and
+`next_time_max` members without checking it first. The other missing
+test is in the timer expiry routine `jr3_pci_poll_dev()`, but it will
+crash before it gets that far.
+
+Fix the bug by returning `-ENOMEM` from `jr3_pci_auto_attach()` as soon
+as one of the calls to `jr3_pci_alloc_spriv()` returns `NULL`. The
+COMEDI core will subsequently call `jr3_pci_detach()` to clean up.
+
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/comedi/drivers/jr3_pci.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/staging/comedi/drivers/jr3_pci.c
++++ b/drivers/staging/comedi/drivers/jr3_pci.c
+@@ -727,11 +727,12 @@ static int jr3_pci_auto_attach(struct co
+ s->insn_read = jr3_pci_ai_insn_read;
+
+ spriv = jr3_pci_alloc_spriv(dev, s);
+- if (spriv) {
+- /* Channel specific range and maxdata */
+- s->range_table_list = spriv->range_table_list;
+- s->maxdata_list = spriv->maxdata_list;
+- }
++ if (!spriv)
++ return -ENOMEM;
++
++ /* Channel specific range and maxdata */
++ s->range_table_list = spriv->range_table_list;
++ s->maxdata_list = spriv->maxdata_list;
+ }
+
+ /* Reset DSP card */
--- /dev/null
+From b58f45c8fc301fe83ee28cad3e64686c19e78f1c Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 26 Apr 2017 12:23:04 +0200
+Subject: staging: gdm724x: gdm_mux: fix use-after-free on module unload
+
+From: Johan Hovold <johan@kernel.org>
+
+commit b58f45c8fc301fe83ee28cad3e64686c19e78f1c upstream.
+
+Make sure to deregister the USB driver before releasing the tty driver
+to avoid use-after-free in the USB disconnect callback where the tty
+devices are deregistered.
+
+Fixes: 61e121047645 ("staging: gdm7240: adding LTE USB driver")
+Cc: Won Kang <wkang77@gmail.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/gdm724x/gdm_mux.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/staging/gdm724x/gdm_mux.c
++++ b/drivers/staging/gdm724x/gdm_mux.c
+@@ -664,9 +664,8 @@ static int __init gdm_usb_mux_init(void)
+
+ static void __exit gdm_usb_mux_exit(void)
+ {
+- unregister_lte_tty_driver();
+-
+ usb_deregister(&gdm_mux_driver);
++ unregister_lte_tty_driver();
+ }
+
+ module_init(gdm_usb_mux_init);
--- /dev/null
+From cf9ed9aa5b0c196b796d2728218e3c06b0f42d90 Mon Sep 17 00:00:00 2001
+From: Sean Young <sean@mess.org>
+Date: Sat, 25 Mar 2017 07:31:57 -0300
+Subject: [media] staging: sir: fill in missing fields and fix probe
+
+From: Sean Young <sean@mess.org>
+
+commit cf9ed9aa5b0c196b796d2728218e3c06b0f42d90 upstream.
+
+Some fields are left blank.
+
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/media/lirc/lirc_sir.c | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+--- a/drivers/staging/media/lirc/lirc_sir.c
++++ b/drivers/staging/media/lirc/lirc_sir.c
+@@ -227,6 +227,7 @@ static int init_chrdev(void)
+ if (!rcdev)
+ return -ENOMEM;
+
++ rcdev->input_name = "SIR IrDA port";
+ rcdev->input_phys = KBUILD_MODNAME "/input0";
+ rcdev->input_id.bustype = BUS_HOST;
+ rcdev->input_id.vendor = 0x0001;
+@@ -234,6 +235,7 @@ static int init_chrdev(void)
+ rcdev->input_id.version = 0x0100;
+ rcdev->tx_ir = sir_tx_ir;
+ rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
++ rcdev->driver_name = KBUILD_MODNAME;
+ rcdev->map_name = RC_MAP_RC6_MCE;
+ rcdev->timeout = IR_DEFAULT_TIMEOUT;
+ rcdev->dev.parent = &sir_ir_dev->dev;
+@@ -740,7 +742,13 @@ static int init_sir_ir(void)
+
+ static int sir_ir_probe(struct platform_device *dev)
+ {
+- return 0;
++ int retval;
++
++ retval = init_chrdev();
++ if (retval < 0)
++ return retval;
++
++ return init_sir_ir();
+ }
+
+ static int sir_ir_remove(struct platform_device *dev)
+@@ -780,18 +788,8 @@ static int __init sir_ir_init(void)
+ goto pdev_add_fail;
+ }
+
+- retval = init_chrdev();
+- if (retval < 0)
+- goto fail;
+-
+- retval = init_sir_ir();
+- if (retval)
+- goto fail;
+-
+ return 0;
+
+-fail:
+- platform_device_del(sir_ir_dev);
+ pdev_add_fail:
+ platform_device_put(sir_ir_dev);
+ pdev_alloc_fail:
--- /dev/null
+From 05c0cf88bec588a7cb34de569acd871ceef26760 Mon Sep 17 00:00:00 2001
+From: Malcolm Priestley <tvboxspy@gmail.com>
+Date: Sat, 22 Apr 2017 11:14:58 +0100
+Subject: staging: vt6656: use off stack for in buffer USB transfers.
+
+From: Malcolm Priestley <tvboxspy@gmail.com>
+
+commit 05c0cf88bec588a7cb34de569acd871ceef26760 upstream.
+
+Since 4.9 mandated USB buffers to be heap allocated. This causes
+the driver to fail.
+
+Create buffer for USB transfers.
+
+Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/vt6656/usbpipe.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/vt6656/usbpipe.c
++++ b/drivers/staging/vt6656/usbpipe.c
+@@ -75,15 +75,28 @@ int vnt_control_in(struct vnt_private *p
+ u16 index, u16 length, u8 *buffer)
+ {
+ int status;
++ u8 *usb_buffer;
+
+ if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags))
+ return STATUS_FAILURE;
+
+ mutex_lock(&priv->usb_lock);
+
++ usb_buffer = kmalloc(length, GFP_KERNEL);
++ if (!usb_buffer) {
++ mutex_unlock(&priv->usb_lock);
++ return -ENOMEM;
++ }
++
+ status = usb_control_msg(priv->usb,
+- usb_rcvctrlpipe(priv->usb, 0), request, 0xc0, value,
+- index, buffer, length, USB_CTL_WAIT);
++ usb_rcvctrlpipe(priv->usb, 0),
++ request, 0xc0, value,
++ index, usb_buffer, length, USB_CTL_WAIT);
++
++ if (status == length)
++ memcpy(buffer, usb_buffer, length);
++
++ kfree(usb_buffer);
+
+ mutex_unlock(&priv->usb_lock);
+
--- /dev/null
+From 12ecd24ef93277e4e5feaf27b0b18f2d3828bc5e Mon Sep 17 00:00:00 2001
+From: Malcolm Priestley <tvboxspy@gmail.com>
+Date: Sat, 22 Apr 2017 11:14:57 +0100
+Subject: staging: vt6656: use off stack for out buffer USB transfers.
+
+From: Malcolm Priestley <tvboxspy@gmail.com>
+
+commit 12ecd24ef93277e4e5feaf27b0b18f2d3828bc5e upstream.
+
+Since 4.9 mandated USB buffers be heap allocated this causes the driver
+to fail.
+
+Since there is a wide range of buffer sizes use kmemdup to create
+allocated buffer.
+
+Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/vt6656/usbpipe.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/vt6656/usbpipe.c
++++ b/drivers/staging/vt6656/usbpipe.c
+@@ -47,15 +47,25 @@ int vnt_control_out(struct vnt_private *
+ u16 index, u16 length, u8 *buffer)
+ {
+ int status = 0;
++ u8 *usb_buffer;
+
+ if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags))
+ return STATUS_FAILURE;
+
+ mutex_lock(&priv->usb_lock);
+
++ usb_buffer = kmemdup(buffer, length, GFP_KERNEL);
++ if (!usb_buffer) {
++ mutex_unlock(&priv->usb_lock);
++ return -ENOMEM;
++ }
++
+ status = usb_control_msg(priv->usb,
+- usb_sndctrlpipe(priv->usb, 0), request, 0x40, value,
+- index, buffer, length, USB_CTL_WAIT);
++ usb_sndctrlpipe(priv->usb, 0),
++ request, 0x40, value,
++ index, usb_buffer, length, USB_CTL_WAIT);
++
++ kfree(usb_buffer);
+
+ mutex_unlock(&priv->usb_lock);
+
--- /dev/null
+From 0e490657c7214cce33fbca3d88227298c5c968ae Mon Sep 17 00:00:00 2001
+From: Aditya Shankar <aditya.shankar@microchip.com>
+Date: Fri, 7 Apr 2017 17:24:58 +0530
+Subject: staging: wilc1000: Fix problem with wrong vif index
+
+From: Aditya Shankar <aditya.shankar@microchip.com>
+
+commit 0e490657c7214cce33fbca3d88227298c5c968ae upstream.
+
+The vif->idx value is always 0 for two interfaces.
+
+wl->vif_num = 0;
+
+loop {
+ ...
+
+ vif->idx = wl->vif_num;
+ ...
+ wl->vif_num = i;
+ ....
+ i++;
+ ...
+}
+
+At present, vif->idx is assigned the value of wl->vif_num
+at the beginning of this block and device is initialized
+based on this index value.
+In the next iteration, wl->vif_num is still 0 as it is only updated
+later but gets assigned to vif->idx in the beginning. This causes problems
+later when we try to reference a particular interface and also while
+configuring the firmware.
+
+This patch moves the assignment to vif->idx from the beginning
+of the block to after wl->vif_num is updated with latest value of i.
+
+Fixes: commit 735bb39ca3be ("staging: wilc1000: simplify vif[i]->ndev accesses")
+Signed-off-by: Aditya Shankar <aditya.shankar@microchip.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/wilc1000/linux_wlan.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/wilc1000/linux_wlan.c
++++ b/drivers/staging/wilc1000/linux_wlan.c
+@@ -1251,11 +1251,12 @@ int wilc_netdev_init(struct wilc **wilc,
+ else
+ strcpy(ndev->name, "p2p%d");
+
+- vif->idx = wl->vif_num;
+ vif->wilc = *wilc;
+ vif->ndev = ndev;
+ wl->vif[i] = vif;
+ wl->vif_num = i;
++ vif->idx = wl->vif_num;
++
+ ndev->netdev_ops = &wilc_netdev_ops;
+
+ {
--- /dev/null
+From 59ac9c078141b8fd0186c0b18660a1b2c24e724e Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Thu, 4 May 2017 15:50:47 -0700
+Subject: target/fileio: Fix zero-length READ and WRITE handling
+
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+
+commit 59ac9c078141b8fd0186c0b18660a1b2c24e724e upstream.
+
+This patch fixes zero-length READ and WRITE handling in target/FILEIO,
+which was broken a long time back by:
+
+Since:
+
+ commit d81cb44726f050d7cf1be4afd9cb45d153b52066
+ Author: Paolo Bonzini <pbonzini@redhat.com>
+ Date: Mon Sep 17 16:36:11 2012 -0700
+
+ target: go through normal processing for all zero-length commands
+
+which moved zero-length READ and WRITE completion out of target-core,
+to doing submission into backend driver code.
+
+To address this, go ahead and invoke target_complete_cmd() for any
+non negative return value in fd_do_rw().
+
+Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Cc: Andy Grover <agrover@redhat.com>
+Cc: David Disseldorp <ddiss@suse.de>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_file.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/target/target_core_file.c
++++ b/drivers/target/target_core_file.c
+@@ -595,8 +595,7 @@ fd_execute_rw(struct se_cmd *cmd, struct
+ if (ret < 0)
+ return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+
+- if (ret)
+- target_complete_cmd(cmd, SAM_STAT_GOOD);
++ target_complete_cmd(cmd, SAM_STAT_GOOD);
+ return 0;
+ }
+
--- /dev/null
+From a71a5dc7f833943998e97ca8fa6a4c708a0ed1a9 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Tue, 11 Apr 2017 16:24:16 -0700
+Subject: target: Fix compare_and_write_callback handling for non GOOD status
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit a71a5dc7f833943998e97ca8fa6a4c708a0ed1a9 upstream.
+
+Following the bugfix for handling non SAM_STAT_GOOD COMPARE_AND_WRITE
+status during COMMIT phase in commit 9b2792c3da1, the same bug exists
+for the READ phase as well.
+
+This would manifest first as a lost SCSI response, and eventual
+hung task during fabric driver logout or re-login, as existing
+shutdown logic waited for the COMPARE_AND_WRITE se_cmd->cmd_kref
+to reach zero.
+
+To address this bug, compare_and_write_callback() has been changed
+to set post_ret = 1 and return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE
+as necessary to signal failure status.
+
+Reported-by: Bill Borsari <wgb@datera.io>
+Cc: Bill Borsari <wgb@datera.io>
+Tested-by: Gary Guo <ghg@datera.io>
+Cc: Gary Guo <ghg@datera.io>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_sbc.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/target/target_core_sbc.c
++++ b/drivers/target/target_core_sbc.c
+@@ -507,8 +507,11 @@ static sense_reason_t compare_and_write_
+ * been failed with a non-zero SCSI status.
+ */
+ if (cmd->scsi_status) {
+- pr_err("compare_and_write_callback: non zero scsi_status:"
++ pr_debug("compare_and_write_callback: non zero scsi_status:"
+ " 0x%02x\n", cmd->scsi_status);
++ *post_ret = 1;
++ if (cmd->scsi_status == SAM_STAT_CHECK_CONDITION)
++ ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+ goto out;
+ }
+
--- /dev/null
+From 6e253d0fbc665b36192b8ed3cecdbb65b413a1eb Mon Sep 17 00:00:00 2001
+From: Romain Izard <romain.izard.pro@gmail.com>
+Date: Fri, 10 Mar 2017 14:11:41 +0100
+Subject: usb: gadget: legacy gadgets are optional
+
+From: Romain Izard <romain.izard.pro@gmail.com>
+
+commit 6e253d0fbc665b36192b8ed3cecdbb65b413a1eb upstream.
+
+With commit bc49d1d17dcf ("usb: gadget: don't couple configfs to legacy
+gadgets"),it is possible to build a modular kernel with both built-in
+configfs support and modular legacy gadget drivers.
+
+But when building a kernel without modules, it is also necessary to be
+able to build with configfs but without any legacy gadget driver. This
+was a possible configuration when the USB_CONFIGFS was a part of the
+choice options, but not anymore.
+
+Mark the choice for legacy gadget drivers as optional restores this.
+
+Fixes: bc49d1d17dcf ("usb: gadget: don't couple configfs to legacy gadgets")
+Signed-off-by: Romain Izard <romain.izard.pro@gmail.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -460,6 +460,7 @@ config USB_CONFIGFS_F_TCM
+ choice
+ tristate "USB Gadget Drivers"
+ default USB_ETH
++ optional
+ help
+ A Linux "Gadget Driver" talks to the USB Peripheral Controller
+ driver through the abstract "gadget" API. Some other operating
--- /dev/null
+From 6fc091fb0459ade939a795bfdcaf645385b951d4 Mon Sep 17 00:00:00 2001
+From: Peter Chen <peter.chen@nxp.com>
+Date: Wed, 19 Apr 2017 16:55:52 +0300
+Subject: usb: host: xhci: print correct command ring address
+
+From: Peter Chen <peter.chen@nxp.com>
+
+commit 6fc091fb0459ade939a795bfdcaf645385b951d4 upstream.
+
+Print correct command ring address using 'val_64'.
+
+Signed-off-by: Peter Chen <peter.chen@nxp.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-mem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -2491,7 +2491,7 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+ (xhci->cmd_ring->first_seg->dma & (u64) ~CMD_RING_RSVD_BITS) |
+ xhci->cmd_ring->cycle_state;
+ xhci_dbg_trace(xhci, trace_xhci_dbg_init,
+- "// Setting command ring address to 0x%x", val);
++ "// Setting command ring address to 0x%016llx", val_64);
+ xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring);
+ xhci_dbg_cmd_ptrs(xhci);
+
--- /dev/null
+From f5cccf49428447dfbc9edb7a04bb8fc316269781 Mon Sep 17 00:00:00 2001
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Mon, 20 Mar 2017 14:30:50 -0700
+Subject: usb: hub: Do not attempt to autosuspend disconnected devices
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+commit f5cccf49428447dfbc9edb7a04bb8fc316269781 upstream.
+
+While running a bind/unbind stress test with the dwc3 usb driver on rk3399,
+the following crash was observed.
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000218
+pgd = ffffffc00165f000
+[00000218] *pgd=000000000174f003, *pud=000000000174f003,
+ *pmd=0000000001750003, *pte=00e8000001751713
+Internal error: Oops: 96000005 [#1] PREEMPT SMP
+Modules linked in: uinput uvcvideo videobuf2_vmalloc cmac
+ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat rfcomm
+xt_mark fuse bridge stp llc zram btusb btrtl btbcm btintel bluetooth
+ip6table_filter mwifiex_pcie mwifiex cfg80211 cdc_ether usbnet r8152 mii joydev
+snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device ppp_async
+ppp_generic slhc tun
+CPU: 1 PID: 29814 Comm: kworker/1:1 Not tainted 4.4.52 #507
+Hardware name: Google Kevin (DT)
+Workqueue: pm pm_runtime_work
+task: ffffffc0ac540000 ti: ffffffc0af4d4000 task.ti: ffffffc0af4d4000
+PC is at autosuspend_check+0x74/0x174
+LR is at autosuspend_check+0x70/0x174
+...
+Call trace:
+[<ffffffc00080dcc0>] autosuspend_check+0x74/0x174
+[<ffffffc000810500>] usb_runtime_idle+0x20/0x40
+[<ffffffc000785ae0>] __rpm_callback+0x48/0x7c
+[<ffffffc000786af0>] rpm_idle+0x1e8/0x498
+[<ffffffc000787cdc>] pm_runtime_work+0x88/0xcc
+[<ffffffc000249bb8>] process_one_work+0x390/0x6b8
+[<ffffffc00024abcc>] worker_thread+0x480/0x610
+[<ffffffc000251a80>] kthread+0x164/0x178
+[<ffffffc0002045d0>] ret_from_fork+0x10/0x40
+
+Source:
+
+(gdb) l *0xffffffc00080dcc0
+0xffffffc00080dcc0 is in autosuspend_check
+(drivers/usb/core/driver.c:1778).
+1773 /* We don't need to check interfaces that are
+1774 * disabled for runtime PM. Either they are unbound
+1775 * or else their drivers don't support autosuspend
+1776 * and so they are permanently active.
+1777 */
+1778 if (intf->dev.power.disable_depth)
+1779 continue;
+1780 if (atomic_read(&intf->dev.power.usage_count) > 0)
+1781 return -EBUSY;
+1782 w |= intf->needs_remote_wakeup;
+
+Code analysis shows that intf is set to NULL in usb_disable_device() prior
+to setting actconfig to NULL. At the same time, usb_runtime_idle() does not
+lock the usb device, and neither does any of the functions in the
+traceback. This means that there is no protection against a race condition
+where usb_disable_device() is removing dev->actconfig->interface[] pointers
+while those are being accessed from autosuspend_check().
+
+To solve the problem, synchronize and validate device state between
+autosuspend_check() and usb_disconnect().
+
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/driver.c | 3 +++
+ drivers/usb/core/hub.c | 6 ++++++
+ 2 files changed, 9 insertions(+)
+
+--- a/drivers/usb/core/driver.c
++++ b/drivers/usb/core/driver.c
+@@ -1781,6 +1781,9 @@ static int autosuspend_check(struct usb_
+ int w, i;
+ struct usb_interface *intf;
+
++ if (udev->state == USB_STATE_NOTATTACHED)
++ return -ENODEV;
++
+ /* Fail if autosuspend is disabled, or any interfaces are in use, or
+ * any interface drivers require remote wakeup but it isn't available.
+ */
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2087,6 +2087,12 @@ void usb_disconnect(struct usb_device **
+ dev_info(&udev->dev, "USB disconnect, device number %d\n",
+ udev->devnum);
+
++ /*
++ * Ensure that the pm runtime code knows that the USB device
++ * is in the process of being disconnected.
++ */
++ pm_runtime_barrier(&udev->dev);
++
+ usb_lock_device(udev);
+
+ hub_disconnect_children(udev);
--- /dev/null
+From 245b2eecee2aac6fdc77dcafaa73c33f9644c3c7 Mon Sep 17 00:00:00 2001
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Mon, 20 Mar 2017 11:16:11 -0700
+Subject: usb: hub: Fix error loop seen after hub communication errors
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+commit 245b2eecee2aac6fdc77dcafaa73c33f9644c3c7 upstream.
+
+While stress testing a usb controller using a bind/unbind looop, the
+following error loop was observed.
+
+usb 7-1.2: new low-speed USB device number 3 using xhci-hcd
+usb 7-1.2: hub failed to enable device, error -108
+usb 7-1-port2: cannot disable (err = -22)
+usb 7-1-port2: couldn't allocate usb_device
+usb 7-1-port2: cannot disable (err = -22)
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: activate --> -22
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: activate --> -22
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: activate --> -22
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: activate --> -22
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: activate --> -22
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: activate --> -22
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: activate --> -22
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: activate --> -22
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+** 57 printk messages dropped ** hub 7-1:1.0: activate --> -22
+** 82 printk messages dropped ** hub 7-1:1.0: hub_ext_port_status failed (err = -22)
+
+This continues forever. After adding tracebacks into the code,
+the call sequence leading to this is found to be as follows.
+
+[<ffffffc0007fc8e0>] hub_activate+0x368/0x7b8
+[<ffffffc0007fceb4>] hub_resume+0x2c/0x3c
+[<ffffffc00080b3b8>] usb_resume_interface.isra.6+0x128/0x158
+[<ffffffc00080b5d0>] usb_suspend_both+0x1e8/0x288
+[<ffffffc00080c9c4>] usb_runtime_suspend+0x3c/0x98
+[<ffffffc0007820a0>] __rpm_callback+0x48/0x7c
+[<ffffffc00078217c>] rpm_callback+0xa8/0xd4
+[<ffffffc000786234>] rpm_suspend+0x84/0x758
+[<ffffffc000786ca4>] rpm_idle+0x2c8/0x498
+[<ffffffc000786ed4>] __pm_runtime_idle+0x60/0xac
+[<ffffffc00080eba8>] usb_autopm_put_interface+0x6c/0x7c
+[<ffffffc000803798>] hub_event+0x10ac/0x12ac
+[<ffffffc000249bb8>] process_one_work+0x390/0x6b8
+[<ffffffc00024abcc>] worker_thread+0x480/0x610
+[<ffffffc000251a80>] kthread+0x164/0x178
+[<ffffffc0002045d0>] ret_from_fork+0x10/0x40
+
+kick_hub_wq() is called from hub_activate() even after failures to
+communicate with the hub. This results in an endless sequence of
+hub event -> hub activate -> wq trigger -> hub event -> ...
+
+Provide two solutions for the problem.
+
+- Only trigger the hub event queue if communication with the hub
+ is successful.
+- After a suspend failure, only resume already suspended interfaces
+ if the communication with the device is still possible.
+
+Each of the changes fixes the observed problem. Use both to improve
+robustness.
+
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/driver.c | 18 ++++++++++++++++++
+ drivers/usb/core/hub.c | 5 ++++-
+ 2 files changed, 22 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/core/driver.c
++++ b/drivers/usb/core/driver.c
+@@ -1331,6 +1331,24 @@ static int usb_suspend_both(struct usb_d
+ */
+ if (udev->parent && !PMSG_IS_AUTO(msg))
+ status = 0;
++
++ /*
++ * If the device is inaccessible, don't try to resume
++ * suspended interfaces and just return the error.
++ */
++ if (status && status != -EBUSY) {
++ int err;
++ u16 devstat;
++
++ err = usb_get_status(udev, USB_RECIP_DEVICE, 0,
++ &devstat);
++ if (err) {
++ dev_err(&udev->dev,
++ "Failed to suspend device, error %d\n",
++ status);
++ goto done;
++ }
++ }
+ }
+
+ /* If the suspend failed, resume interfaces that did get suspended */
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1066,6 +1066,9 @@ static void hub_activate(struct usb_hub
+
+ portstatus = portchange = 0;
+ status = hub_port_status(hub, port1, &portstatus, &portchange);
++ if (status)
++ goto abort;
++
+ if (udev || (portstatus & USB_PORT_STAT_CONNECTION))
+ dev_dbg(&port_dev->dev, "status %04x change %04x\n",
+ portstatus, portchange);
+@@ -1198,7 +1201,7 @@ static void hub_activate(struct usb_hub
+
+ /* Scan all ports that need attention */
+ kick_hub_wq(hub);
+-
++ abort:
+ if (type == HUB_INIT2 || type == HUB_INIT3) {
+ /* Allow autosuspend if it was suppressed */
+ disconnected:
--- /dev/null
+From 3d6159640da9c9175d1ca42f151fc1a14caded59 Mon Sep 17 00:00:00 2001
+From: Alexey Brodkin <Alexey.Brodkin@synopsys.com>
+Date: Thu, 13 Apr 2017 15:33:34 +0300
+Subject: usb: Make sure usb/phy/of gets built-in
+
+From: Alexey Brodkin <Alexey.Brodkin@synopsys.com>
+
+commit 3d6159640da9c9175d1ca42f151fc1a14caded59 upstream.
+
+DWC3 driver uses of_usb_get_phy_mode() which is
+implemented in drivers/usb/phy/of.c and in bare minimal
+configuration it might not be pulled in kernel binary.
+
+In case of ARC or ARM this could be easily reproduced with
+"allnodefconfig" +CONFIG_USB=m +CONFIG_USB_DWC3=m.
+
+On building all ends-up with:
+---------------------->8------------------
+ Kernel: arch/arm/boot/Image is ready
+ Kernel: arch/arm/boot/zImage is ready
+ Building modules, stage 2.
+ MODPOST 5 modules
+ERROR: "of_usb_get_phy_mode" [drivers/usb/dwc3/dwc3.ko] undefined!
+make[1]: *** [__modpost] Error 1
+make: *** [modules] Error 2
+---------------------->8------------------
+
+Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
+Cc: Geert Uytterhoeven <geert+renesas@glider.be>
+Cc: Nicolas Pitre <nicolas.pitre@linaro.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Felipe Balbi <balbi@kernel.org>
+Cc: Felix Fietkau <nbd@nbd.name>
+Cc: Jeremy Kerr <jk@ozlabs.org>
+Cc: linux-snps-arc@lists.infradead.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -104,6 +104,7 @@ obj-$(CONFIG_USB_PHY) += usb/
+ obj-$(CONFIG_USB) += usb/
+ obj-$(CONFIG_PCI) += usb/
+ obj-$(CONFIG_USB_GADGET) += usb/
++obj-$(CONFIG_OF) += usb/
+ obj-$(CONFIG_SERIO) += input/serio/
+ obj-$(CONFIG_GAMEPORT) += input/gameport/
+ obj-$(CONFIG_INPUT) += input/
--- /dev/null
+From 2c930e3d0aed1505e86e0928d323df5027817740 Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <garsilva@embeddedor.com>
+Date: Mon, 3 Apr 2017 22:48:40 -0500
+Subject: usb: misc: add missing continue in switch
+
+From: Gustavo A. R. Silva <garsilva@embeddedor.com>
+
+commit 2c930e3d0aed1505e86e0928d323df5027817740 upstream.
+
+Add missing continue in switch.
+
+Addresses-Coverity-ID: 1248733
+Signed-off-by: Gustavo A. R. Silva <garsilva@embeddedor.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/usbtest.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/misc/usbtest.c
++++ b/drivers/usb/misc/usbtest.c
+@@ -159,6 +159,7 @@ get_endpoints(struct usbtest_dev *dev, s
+ case USB_ENDPOINT_XFER_INT:
+ if (dev->info->intr)
+ goto try_intr;
++ continue;
+ case USB_ENDPOINT_XFER_ISOC:
+ if (dev->info->iso)
+ goto try_iso;
--- /dev/null
+From 942a48730faf149ccbf3e12ac718aee120bb3529 Mon Sep 17 00:00:00 2001
+From: Maksim Salau <maksim.salau@gmail.com>
+Date: Tue, 25 Apr 2017 22:49:21 +0300
+Subject: usb: misc: legousbtower: Fix buffers on stack
+
+From: Maksim Salau <maksim.salau@gmail.com>
+
+commit 942a48730faf149ccbf3e12ac718aee120bb3529 upstream.
+
+Allocate buffers on HEAP instead of STACK for local structures
+that are to be received using usb_control_msg().
+
+Signed-off-by: Maksim Salau <maksim.salau@gmail.com>
+Tested-by: Alfredo Rafael Vicente Boix <alviboi@gmail.com>;
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/legousbtower.c | 37 +++++++++++++++++++++++++++----------
+ 1 file changed, 27 insertions(+), 10 deletions(-)
+
+--- a/drivers/usb/misc/legousbtower.c
++++ b/drivers/usb/misc/legousbtower.c
+@@ -317,9 +317,16 @@ static int tower_open (struct inode *ino
+ int subminor;
+ int retval = 0;
+ struct usb_interface *interface;
+- struct tower_reset_reply reset_reply;
++ struct tower_reset_reply *reset_reply;
+ int result;
+
++ reset_reply = kmalloc(sizeof(*reset_reply), GFP_KERNEL);
++
++ if (!reset_reply) {
++ retval = -ENOMEM;
++ goto exit;
++ }
++
+ nonseekable_open(inode, file);
+ subminor = iminor(inode);
+
+@@ -364,8 +371,8 @@ static int tower_open (struct inode *ino
+ USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
+ 0,
+ 0,
+- &reset_reply,
+- sizeof(reset_reply),
++ reset_reply,
++ sizeof(*reset_reply),
+ 1000);
+ if (result < 0) {
+ dev_err(&dev->udev->dev,
+@@ -406,6 +413,7 @@ unlock_exit:
+ mutex_unlock(&dev->lock);
+
+ exit:
++ kfree(reset_reply);
+ return retval;
+ }
+
+@@ -808,7 +816,7 @@ static int tower_probe (struct usb_inter
+ struct lego_usb_tower *dev = NULL;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor* endpoint;
+- struct tower_get_version_reply get_version_reply;
++ struct tower_get_version_reply *get_version_reply = NULL;
+ int i;
+ int retval = -ENOMEM;
+ int result;
+@@ -886,6 +894,13 @@ static int tower_probe (struct usb_inter
+ dev->interrupt_in_interval = interrupt_in_interval ? interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
+ dev->interrupt_out_interval = interrupt_out_interval ? interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;
+
++ get_version_reply = kmalloc(sizeof(*get_version_reply), GFP_KERNEL);
++
++ if (!get_version_reply) {
++ retval = -ENOMEM;
++ goto error;
++ }
++
+ /* get the firmware version and log it */
+ result = usb_control_msg (udev,
+ usb_rcvctrlpipe(udev, 0),
+@@ -893,18 +908,19 @@ static int tower_probe (struct usb_inter
+ USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
+ 0,
+ 0,
+- &get_version_reply,
+- sizeof(get_version_reply),
++ get_version_reply,
++ sizeof(*get_version_reply),
+ 1000);
+ if (result < 0) {
+ dev_err(idev, "LEGO USB Tower get version control request failed\n");
+ retval = result;
+ goto error;
+ }
+- dev_info(&interface->dev, "LEGO USB Tower firmware version is %d.%d "
+- "build %d\n", get_version_reply.major,
+- get_version_reply.minor,
+- le16_to_cpu(get_version_reply.build_no));
++ dev_info(&interface->dev,
++ "LEGO USB Tower firmware version is %d.%d build %d\n",
++ get_version_reply->major,
++ get_version_reply->minor,
++ le16_to_cpu(get_version_reply->build_no));
+
+ /* we can register the device now, as it is ready */
+ usb_set_intfdata (interface, dev);
+@@ -928,6 +944,7 @@ exit:
+ return retval;
+
+ error:
++ kfree(get_version_reply);
+ tower_delete(dev);
+ return retval;
+ }
--- /dev/null
+From 2f86a96be0ccb1302b7eee7855dbee5ce4dc5dfb Mon Sep 17 00:00:00 2001
+From: Ajay Kaher <ajay.kaher@samsung.com>
+Date: Tue, 28 Mar 2017 08:09:32 -0400
+Subject: USB: Proper handling of Race Condition when two USB class drivers try to call init_usb_class simultaneously
+
+From: Ajay Kaher <ajay.kaher@samsung.com>
+
+commit 2f86a96be0ccb1302b7eee7855dbee5ce4dc5dfb upstream.
+
+There is race condition when two USB class drivers try to call
+init_usb_class at the same time and leads to crash.
+code path: probe->usb_register_dev->init_usb_class
+
+To solve this, mutex locking has been added in init_usb_class() and
+destroy_usb_class().
+
+As pointed by Alan, removed "if (usb_class)" test from destroy_usb_class()
+because usb_class can never be NULL there.
+
+Signed-off-by: Ajay Kaher <ajay.kaher@samsung.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/file.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/file.c
++++ b/drivers/usb/core/file.c
+@@ -29,6 +29,7 @@
+ #define MAX_USB_MINORS 256
+ static const struct file_operations *usb_minors[MAX_USB_MINORS];
+ static DECLARE_RWSEM(minor_rwsem);
++static DEFINE_MUTEX(init_usb_class_mutex);
+
+ static int usb_open(struct inode *inode, struct file *file)
+ {
+@@ -111,8 +112,9 @@ static void release_usb_class(struct kre
+
+ static void destroy_usb_class(void)
+ {
+- if (usb_class)
+- kref_put(&usb_class->kref, release_usb_class);
++ mutex_lock(&init_usb_class_mutex);
++ kref_put(&usb_class->kref, release_usb_class);
++ mutex_unlock(&init_usb_class_mutex);
+ }
+
+ int usb_major_init(void)
+@@ -173,7 +175,10 @@ int usb_register_dev(struct usb_interfac
+ if (intf->minor >= 0)
+ return -EADDRINUSE;
+
++ mutex_lock(&init_usb_class_mutex);
+ retval = init_usb_class();
++ mutex_unlock(&init_usb_class_mutex);
++
+ if (retval)
+ return retval;
+
--- /dev/null
+From 19445816996d1a89682c37685fe95959631d9f32 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+Date: Fri, 21 Apr 2017 10:01:29 +0200
+Subject: USB: Revert "cdc-wdm: fix "out-of-sync" due to missing notifications"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Bjørn Mork <bjorn@mork.no>
+
+commit 19445816996d1a89682c37685fe95959631d9f32 upstream.
+
+This reverts commit 833415a3e781 ("cdc-wdm: fix "out-of-sync" due to
+missing notifications")
+
+There have been several reports of wdm_read returning unexpected EIO
+errors with QMI devices using the qmi_wwan driver. The reporters
+confirm that reverting prevents these errors. I have been unable to
+reproduce the bug myself, and have no explanation to offer either. But
+reverting is the safe choice here, given that the commit was an
+attempt to work around a firmware problem. Living with a firmware
+problem is still better than adding driver bugs.
+
+Reported-by: Kasper Holtze <kasper@holtze.dk>
+Reported-by: Aleksander Morgado <aleksander@aleksander.es>
+Reported-by: Daniele Palmas <dnlplm@gmail.com>
+Fixes: 833415a3e781 ("cdc-wdm: fix "out-of-sync" due to missing notifications")
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Acked-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-wdm.c | 103 +-------------------------------------------
+ 1 file changed, 4 insertions(+), 99 deletions(-)
+
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -58,7 +58,6 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
+ #define WDM_SUSPENDING 8
+ #define WDM_RESETTING 9
+ #define WDM_OVERFLOW 10
+-#define WDM_DRAIN_ON_OPEN 11
+
+ #define WDM_MAX 16
+
+@@ -182,7 +181,7 @@ static void wdm_in_callback(struct urb *
+ "nonzero urb status received: -ESHUTDOWN\n");
+ goto skip_error;
+ case -EPIPE:
+- dev_dbg(&desc->intf->dev,
++ dev_err(&desc->intf->dev,
+ "nonzero urb status received: -EPIPE\n");
+ break;
+ default:
+@@ -210,25 +209,6 @@ static void wdm_in_callback(struct urb *
+ desc->reslength = length;
+ }
+ }
+-
+- /*
+- * Handling devices with the WDM_DRAIN_ON_OPEN flag set:
+- * If desc->resp_count is unset, then the urb was submitted
+- * without a prior notification. If the device returned any
+- * data, then this implies that it had messages queued without
+- * notifying us. Continue reading until that queue is flushed.
+- */
+- if (!desc->resp_count) {
+- if (!length) {
+- /* do not propagate the expected -EPIPE */
+- desc->rerr = 0;
+- goto unlock;
+- }
+- dev_dbg(&desc->intf->dev, "got %d bytes without notification\n", length);
+- set_bit(WDM_RESPONDING, &desc->flags);
+- usb_submit_urb(desc->response, GFP_ATOMIC);
+- }
+-
+ skip_error:
+ set_bit(WDM_READ, &desc->flags);
+ wake_up(&desc->wait);
+@@ -243,7 +223,6 @@ skip_error:
+ service_outstanding_interrupt(desc);
+ }
+
+-unlock:
+ spin_unlock(&desc->iuspin);
+ }
+
+@@ -686,17 +665,6 @@ static int wdm_open(struct inode *inode,
+ dev_err(&desc->intf->dev,
+ "Error submitting int urb - %d\n", rv);
+ rv = usb_translate_errors(rv);
+- } else if (test_bit(WDM_DRAIN_ON_OPEN, &desc->flags)) {
+- /*
+- * Some devices keep pending messages queued
+- * without resending notifications. We must
+- * flush the message queue before we can
+- * assume a one-to-one relationship between
+- * notifications and messages in the queue
+- */
+- dev_dbg(&desc->intf->dev, "draining queued data\n");
+- set_bit(WDM_RESPONDING, &desc->flags);
+- rv = usb_submit_urb(desc->response, GFP_KERNEL);
+ }
+ } else {
+ rv = 0;
+@@ -803,8 +771,7 @@ static void wdm_rxwork(struct work_struc
+ /* --- hotplug --- */
+
+ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor *ep,
+- u16 bufsize, int (*manage_power)(struct usb_interface *, int),
+- bool drain_on_open)
++ u16 bufsize, int (*manage_power)(struct usb_interface *, int))
+ {
+ int rv = -ENOMEM;
+ struct wdm_device *desc;
+@@ -891,68 +858,6 @@ static int wdm_create(struct usb_interfa
+
+ desc->manage_power = manage_power;
+
+- /*
+- * "drain_on_open" enables a hack to work around a firmware
+- * issue observed on network functions, in particular MBIM
+- * functions.
+- *
+- * Quoting section 7 of the CDC-WMC r1.1 specification:
+- *
+- * "The firmware shall interpret GetEncapsulatedResponse as a
+- * request to read response bytes. The firmware shall send
+- * the next wLength bytes from the response. The firmware
+- * shall allow the host to retrieve data using any number of
+- * GetEncapsulatedResponse requests. The firmware shall
+- * return a zero- length reply if there are no data bytes
+- * available.
+- *
+- * The firmware shall send ResponseAvailable notifications
+- * periodically, using any appropriate algorithm, to inform
+- * the host that there is data available in the reply
+- * buffer. The firmware is allowed to send ResponseAvailable
+- * notifications even if there is no data available, but
+- * this will obviously reduce overall performance."
+- *
+- * These requirements, although they make equally sense, are
+- * often not implemented by network functions. Some firmwares
+- * will queue data indefinitely, without ever resending a
+- * notification. The result is that the driver and firmware
+- * loses "syncronization" if the driver ever fails to respond
+- * to a single notification, something which easily can happen
+- * on release(). When this happens, the driver will appear to
+- * never receive notifications for the most current data. Each
+- * notification will only cause a single read, which returns
+- * the oldest data in the firmware's queue.
+- *
+- * The "drain_on_open" hack resolves the situation by draining
+- * data from the firmware until none is returned, without a
+- * prior notification.
+- *
+- * This will inevitably race with the firmware, risking that
+- * we read data from the device before handling the associated
+- * notification. To make things worse, some of the devices
+- * needing the hack do not implement the "return zero if no
+- * data is available" requirement either. Instead they return
+- * an error on the subsequent read in this case. This means
+- * that "winning" the race can cause an unexpected EIO to
+- * userspace.
+- *
+- * "winning" the race is more likely on resume() than on
+- * open(), and the unexpected error is more harmful in the
+- * middle of an open session. The hack is therefore only
+- * applied on open(), and not on resume() where it logically
+- * would be equally necessary. So we define open() as the only
+- * driver <-> device "syncronization point". Should we happen
+- * to lose a notification after open(), then syncronization
+- * will be lost until release()
+- *
+- * The hack should not be enabled for CDC WDM devices
+- * conforming to the CDC-WMC r1.1 specification. This is
+- * ensured by setting drain_on_open to false in wdm_probe().
+- */
+- if (drain_on_open)
+- set_bit(WDM_DRAIN_ON_OPEN, &desc->flags);
+-
+ spin_lock(&wdm_device_list_lock);
+ list_add(&desc->device_list, &wdm_device_list);
+ spin_unlock(&wdm_device_list_lock);
+@@ -1006,7 +911,7 @@ static int wdm_probe(struct usb_interfac
+ goto err;
+ ep = &iface->endpoint[0].desc;
+
+- rv = wdm_create(intf, ep, maxcom, &wdm_manage_power, false);
++ rv = wdm_create(intf, ep, maxcom, &wdm_manage_power);
+
+ err:
+ return rv;
+@@ -1038,7 +943,7 @@ struct usb_driver *usb_cdc_wdm_register(
+ {
+ int rv = -EINVAL;
+
+- rv = wdm_create(intf, ep, bufsize, manage_power, true);
++ rv = wdm_create(intf, ep, bufsize, manage_power);
+ if (rv < 0)
+ goto err;
+
--- /dev/null
+From 31c5d1922b90ddc1da6a6ddecef7cd31f17aa32b Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Tue, 18 Apr 2017 20:07:56 +0200
+Subject: USB: serial: ftdi_sio: add device ID for Microsemi/Arrow SF2PLUS Dev Kit
+
+From: Marek Vasut <marex@denx.de>
+
+commit 31c5d1922b90ddc1da6a6ddecef7cd31f17aa32b upstream.
+
+This development kit has an FT4232 on it with a custom USB VID/PID.
+The FT4232 provides four UARTs, but only two are used. The UART 0
+is used by the FlashPro5 programmer and UART 2 is connected to the
+SmartFusion2 CortexM3 SoC UART port.
+
+Note that the USB VID is registered to Actel according to Linux USB
+VID database, but that was acquired by Microsemi.
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ftdi_sio.c | 1 +
+ drivers/usb/serial/ftdi_sio_ids.h | 6 ++++++
+ 2 files changed, 7 insertions(+)
+
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -873,6 +873,7 @@ static const struct usb_device_id id_tab
+ { USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID,
+ USB_CLASS_VENDOR_SPEC,
+ USB_SUBCLASS_VENDOR_SPEC, 0x00) },
++ { USB_DEVICE_INTERFACE_NUMBER(ACTEL_VID, MICROSEMI_ARROW_SF2PLUS_BOARD_PID, 2) },
+ { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
+ { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -873,6 +873,12 @@
+ #define FIC_VID 0x1457
+ #define FIC_NEO1973_DEBUG_PID 0x5118
+
++/*
++ * Actel / Microsemi
++ */
++#define ACTEL_VID 0x1514
++#define MICROSEMI_ARROW_SF2PLUS_BOARD_PID 0x2008
++
+ /* Olimex */
+ #define OLIMEX_VID 0x15BA
+ #define OLIMEX_ARM_USB_OCD_PID 0x0003
--- /dev/null
+From 69307ccb9ad7ccb653e332de68effdeaaab6907d Mon Sep 17 00:00:00 2001
+From: Roger Quadros <rogerq@ti.com>
+Date: Fri, 7 Apr 2017 17:57:12 +0300
+Subject: usb: xhci: bInterval quirk for TI TUSB73x0
+
+From: Roger Quadros <rogerq@ti.com>
+
+commit 69307ccb9ad7ccb653e332de68effdeaaab6907d upstream.
+
+As per [1] issue #4,
+"The periodic EP scheduler always tries to schedule the EPs
+that have large intervals (interval equal to or greater than
+128 microframes) into different microframes. So it maintains
+an internal counter and increments for each large interval
+EP added. When the counter is greater than 128, the scheduler
+rejects the new EP. So when the hub re-enumerated 128 times,
+it triggers this condition."
+
+This results in Bandwidth error when devices with periodic
+endpoints (ISO/INT) having bInterval > 7 are plugged and
+unplugged several times on a TUSB73x0 XHCI host.
+
+Workaround this issue by limiting the bInterval to 7
+(i.e. interval to 6) for High-speed or faster periodic endpoints.
+
+[1] - http://www.ti.com/lit/er/sllz076/sllz076.pdf
+
+Signed-off-by: Roger Quadros <rogerq@ti.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-mem.c | 11 +++++++++++
+ drivers/usb/host/xhci-pci.c | 3 +++
+ drivers/usb/host/xhci.h | 1 +
+ 3 files changed, 15 insertions(+)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -1502,6 +1502,17 @@ int xhci_endpoint_init(struct xhci_hcd *
+ */
+ max_esit_payload = xhci_get_max_esit_payload(udev, ep);
+ interval = xhci_get_endpoint_interval(udev, ep);
++
++ /* Periodic endpoint bInterval limit quirk */
++ if (usb_endpoint_xfer_int(&ep->desc) ||
++ usb_endpoint_xfer_isoc(&ep->desc)) {
++ if ((xhci->quirks & XHCI_LIMIT_ENDPOINT_INTERVAL_7) &&
++ udev->speed >= USB_SPEED_HIGH &&
++ interval >= 7) {
++ interval = 6;
++ }
++ }
++
+ mult = xhci_get_endpoint_mult(udev, ep);
+ max_packet = usb_endpoint_maxp(&ep->desc);
+ max_burst = xhci_get_endpoint_max_burst(udev, ep);
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -199,6 +199,9 @@ static void xhci_pci_quirks(struct devic
+ pdev->device == 0x1042)
+ xhci->quirks |= XHCI_BROKEN_STREAMS;
+
++ if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241)
++ xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7;
++
+ if (xhci->quirks & XHCI_RESET_ON_RESUME)
+ xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
+ "QUIRK: Resetting on resume");
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1818,6 +1818,7 @@ struct xhci_hcd {
+ #define XHCI_MISSING_CAS (1 << 24)
+ /* For controller with a broken Port Disable implementation */
+ #define XHCI_BROKEN_PORT_PED (1 << 25)
++#define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26)
+
+ unsigned int num_active_eps;
+ unsigned int limit_active_eps;