From: Greg Kroah-Hartman Date: Tue, 16 May 2017 10:31:13 +0000 (+0200) Subject: 4.10-stable patches X-Git-Tag: v3.18.54~40 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=947977af3a10a35475c254ed976e910123ce4a37;p=thirdparty%2Fkernel%2Fstable-queue.git 4.10-stable patches added patches: iscsi-target-set-session_fall_back_to_erl0-when-forcing-reinstatement.patch staging-comedi-jr3_pci-cope-with-jiffies-wraparound.patch staging-comedi-jr3_pci-fix-possible-null-pointer-dereference.patch staging-gdm724x-gdm_mux-fix-use-after-free-on-module-unload.patch staging-vt6656-use-off-stack-for-in-buffer-usb-transfers.patch staging-vt6656-use-off-stack-for-out-buffer-usb-transfers.patch staging-wilc1000-fix-problem-with-wrong-vif-index.patch target-fileio-fix-zero-length-read-and-write-handling.patch target-fix-compare_and_write_callback-handling-for-non-good-status.patch usb-gadget-legacy-gadgets-are-optional.patch usb-host-xhci-print-correct-command-ring-address.patch usb-hub-do-not-attempt-to-autosuspend-disconnected-devices.patch usb-hub-fix-error-loop-seen-after-hub-communication-errors.patch usb-make-sure-usb-phy-of-gets-built-in.patch usb-misc-add-missing-continue-in-switch.patch usb-misc-legousbtower-fix-buffers-on-stack.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 usb-serial-ftdi_sio-add-device-id-for-microsemi-arrow-sf2plus-dev-kit.patch usb-xhci-binterval-quirk-for-ti-tusb73x0.patch --- diff --git a/queue-4.10/iscsi-target-set-session_fall_back_to_erl0-when-forcing-reinstatement.patch b/queue-4.10/iscsi-target-set-session_fall_back_to_erl0-when-forcing-reinstatement.patch new file mode 100644 index 00000000000..6fac42f957c --- /dev/null +++ b/queue-4.10/iscsi-target-set-session_fall_back_to_erl0-when-forcing-reinstatement.patch @@ -0,0 +1,75 @@ +From 197b806ae5db60c6f609d74da04ddb62ea5e1b00 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Tue, 25 Apr 2017 10:55:12 -0700 +Subject: iscsi-target: Set session_fall_back_to_erl0 when forcing reinstatement + +From: Nicholas Bellinger + +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 +Tested-by: Gary Guo +Cc: Gary Guo +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -4673,6 +4673,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 +@@ -1531,6 +1531,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 +@@ -206,6 +206,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); diff --git a/queue-4.10/series b/queue-4.10/series index ca0ac415f0b..595161487b6 100644 --- a/queue-4.10/series +++ b/queue-4.10/series @@ -1 +1,21 @@ 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-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 diff --git a/queue-4.10/staging-comedi-jr3_pci-cope-with-jiffies-wraparound.patch b/queue-4.10/staging-comedi-jr3_pci-cope-with-jiffies-wraparound.patch new file mode 100644 index 00000000000..a2837f4b136 --- /dev/null +++ b/queue-4.10/staging-comedi-jr3_pci-cope-with-jiffies-wraparound.patch @@ -0,0 +1,34 @@ +From 8ec04a491825e08068e92bed0bba7821893b6433 Mon Sep 17 00:00:00 2001 +From: Ian Abbott +Date: Fri, 17 Feb 2017 11:09:09 +0000 +Subject: staging: comedi: jr3_pci: cope with jiffies wraparound + +From: Ian Abbott + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.10/staging-comedi-jr3_pci-fix-possible-null-pointer-dereference.patch b/queue-4.10/staging-comedi-jr3_pci-fix-possible-null-pointer-dereference.patch new file mode 100644 index 00000000000..1af0cee6528 --- /dev/null +++ b/queue-4.10/staging-comedi-jr3_pci-fix-possible-null-pointer-dereference.patch @@ -0,0 +1,51 @@ +From 45292be0b3db0b7f8286683b376e2d9f949d11f9 Mon Sep 17 00:00:00 2001 +From: Ian Abbott +Date: Fri, 17 Feb 2017 11:09:08 +0000 +Subject: staging: comedi: jr3_pci: fix possible null pointer dereference + +From: Ian Abbott + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 */ diff --git a/queue-4.10/staging-gdm724x-gdm_mux-fix-use-after-free-on-module-unload.patch b/queue-4.10/staging-gdm724x-gdm_mux-fix-use-after-free-on-module-unload.patch new file mode 100644 index 00000000000..216e9474665 --- /dev/null +++ b/queue-4.10/staging-gdm724x-gdm_mux-fix-use-after-free-on-module-unload.patch @@ -0,0 +1,35 @@ +From b58f45c8fc301fe83ee28cad3e64686c19e78f1c Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 26 Apr 2017 12:23:04 +0200 +Subject: staging: gdm724x: gdm_mux: fix use-after-free on module unload + +From: Johan Hovold + +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 +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.10/staging-vt6656-use-off-stack-for-in-buffer-usb-transfers.patch b/queue-4.10/staging-vt6656-use-off-stack-for-in-buffer-usb-transfers.patch new file mode 100644 index 00000000000..8750a557422 --- /dev/null +++ b/queue-4.10/staging-vt6656-use-off-stack-for-in-buffer-usb-transfers.patch @@ -0,0 +1,54 @@ +From 05c0cf88bec588a7cb34de569acd871ceef26760 Mon Sep 17 00:00:00 2001 +From: Malcolm Priestley +Date: Sat, 22 Apr 2017 11:14:58 +0100 +Subject: staging: vt6656: use off stack for in buffer USB transfers. + +From: Malcolm Priestley + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + diff --git a/queue-4.10/staging-vt6656-use-off-stack-for-out-buffer-usb-transfers.patch b/queue-4.10/staging-vt6656-use-off-stack-for-out-buffer-usb-transfers.patch new file mode 100644 index 00000000000..614b8b31c45 --- /dev/null +++ b/queue-4.10/staging-vt6656-use-off-stack-for-out-buffer-usb-transfers.patch @@ -0,0 +1,52 @@ +From 12ecd24ef93277e4e5feaf27b0b18f2d3828bc5e Mon Sep 17 00:00:00 2001 +From: Malcolm Priestley +Date: Sat, 22 Apr 2017 11:14:57 +0100 +Subject: staging: vt6656: use off stack for out buffer USB transfers. + +From: Malcolm Priestley + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + diff --git a/queue-4.10/staging-wilc1000-fix-problem-with-wrong-vif-index.patch b/queue-4.10/staging-wilc1000-fix-problem-with-wrong-vif-index.patch new file mode 100644 index 00000000000..bd84b53d75b --- /dev/null +++ b/queue-4.10/staging-wilc1000-fix-problem-with-wrong-vif-index.patch @@ -0,0 +1,60 @@ +From 0e490657c7214cce33fbca3d88227298c5c968ae Mon Sep 17 00:00:00 2001 +From: Aditya Shankar +Date: Fri, 7 Apr 2017 17:24:58 +0530 +Subject: staging: wilc1000: Fix problem with wrong vif index + +From: Aditya Shankar + +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 +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + + { diff --git a/queue-4.10/target-fileio-fix-zero-length-read-and-write-handling.patch b/queue-4.10/target-fileio-fix-zero-length-read-and-write-handling.patch new file mode 100644 index 00000000000..4b922264a7a --- /dev/null +++ b/queue-4.10/target-fileio-fix-zero-length-read-and-write-handling.patch @@ -0,0 +1,50 @@ +From 59ac9c078141b8fd0186c0b18660a1b2c24e724e Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Thu, 4 May 2017 15:50:47 -0700 +Subject: target/fileio: Fix zero-length READ and WRITE handling + +From: Bart Van Assche + +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 + 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 +Reviewed-by: Hannes Reinecke +Reviewed-by: Christoph Hellwig +Cc: Andy Grover +Cc: David Disseldorp +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + diff --git a/queue-4.10/target-fix-compare_and_write_callback-handling-for-non-good-status.patch b/queue-4.10/target-fix-compare_and_write_callback-handling-for-non-good-status.patch new file mode 100644 index 00000000000..07c13bc5323 --- /dev/null +++ b/queue-4.10/target-fix-compare_and_write_callback-handling-for-non-good-status.patch @@ -0,0 +1,48 @@ +From a71a5dc7f833943998e97ca8fa6a4c708a0ed1a9 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Tue, 11 Apr 2017 16:24:16 -0700 +Subject: target: Fix compare_and_write_callback handling for non GOOD status + +From: Nicholas Bellinger + +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 +Cc: Bill Borsari +Tested-by: Gary Guo +Cc: Gary Guo +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + diff --git a/queue-4.10/usb-gadget-legacy-gadgets-are-optional.patch b/queue-4.10/usb-gadget-legacy-gadgets-are-optional.patch new file mode 100644 index 00000000000..f269f56555c --- /dev/null +++ b/queue-4.10/usb-gadget-legacy-gadgets-are-optional.patch @@ -0,0 +1,39 @@ +From 6e253d0fbc665b36192b8ed3cecdbb65b413a1eb Mon Sep 17 00:00:00 2001 +From: Romain Izard +Date: Fri, 10 Mar 2017 14:11:41 +0100 +Subject: usb: gadget: legacy gadgets are optional + +From: Romain Izard + +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 +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-4.10/usb-host-xhci-print-correct-command-ring-address.patch b/queue-4.10/usb-host-xhci-print-correct-command-ring-address.patch new file mode 100644 index 00000000000..6325b2693ad --- /dev/null +++ b/queue-4.10/usb-host-xhci-print-correct-command-ring-address.patch @@ -0,0 +1,30 @@ +From 6fc091fb0459ade939a795bfdcaf645385b951d4 Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Wed, 19 Apr 2017 16:55:52 +0300 +Subject: usb: host: xhci: print correct command ring address + +From: Peter Chen + +commit 6fc091fb0459ade939a795bfdcaf645385b951d4 upstream. + +Print correct command ring address using 'val_64'. + +Signed-off-by: Peter Chen +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -2485,7 +2485,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); + diff --git a/queue-4.10/usb-hub-do-not-attempt-to-autosuspend-disconnected-devices.patch b/queue-4.10/usb-hub-do-not-attempt-to-autosuspend-disconnected-devices.patch new file mode 100644 index 00000000000..edd6242f57c --- /dev/null +++ b/queue-4.10/usb-hub-do-not-attempt-to-autosuspend-disconnected-devices.patch @@ -0,0 +1,103 @@ +From f5cccf49428447dfbc9edb7a04bb8fc316269781 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Mon, 20 Mar 2017 14:30:50 -0700 +Subject: usb: hub: Do not attempt to autosuspend disconnected devices + +From: Guenter Roeck + +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: +[] autosuspend_check+0x74/0x174 +[] usb_runtime_idle+0x20/0x40 +[] __rpm_callback+0x48/0x7c +[] rpm_idle+0x1e8/0x498 +[] pm_runtime_work+0x88/0xcc +[] process_one_work+0x390/0x6b8 +[] worker_thread+0x480/0x610 +[] kthread+0x164/0x178 +[] 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 +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.10/usb-hub-fix-error-loop-seen-after-hub-communication-errors.patch b/queue-4.10/usb-hub-fix-error-loop-seen-after-hub-communication-errors.patch new file mode 100644 index 00000000000..622d819285a --- /dev/null +++ b/queue-4.10/usb-hub-fix-error-loop-seen-after-hub-communication-errors.patch @@ -0,0 +1,137 @@ +From 245b2eecee2aac6fdc77dcafaa73c33f9644c3c7 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Mon, 20 Mar 2017 11:16:11 -0700 +Subject: usb: hub: Fix error loop seen after hub communication errors + +From: Guenter Roeck + +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. + +[] hub_activate+0x368/0x7b8 +[] hub_resume+0x2c/0x3c +[] usb_resume_interface.isra.6+0x128/0x158 +[] usb_suspend_both+0x1e8/0x288 +[] usb_runtime_suspend+0x3c/0x98 +[] __rpm_callback+0x48/0x7c +[] rpm_callback+0xa8/0xd4 +[] rpm_suspend+0x84/0x758 +[] rpm_idle+0x2c8/0x498 +[] __pm_runtime_idle+0x60/0xac +[] usb_autopm_put_interface+0x6c/0x7c +[] hub_event+0x10ac/0x12ac +[] process_one_work+0x390/0x6b8 +[] worker_thread+0x480/0x610 +[] kthread+0x164/0x178 +[] 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 +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + 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: diff --git a/queue-4.10/usb-make-sure-usb-phy-of-gets-built-in.patch b/queue-4.10/usb-make-sure-usb-phy-of-gets-built-in.patch new file mode 100644 index 00000000000..ddd5668e5f7 --- /dev/null +++ b/queue-4.10/usb-make-sure-usb-phy-of-gets-built-in.patch @@ -0,0 +1,54 @@ +From 3d6159640da9c9175d1ca42f151fc1a14caded59 Mon Sep 17 00:00:00 2001 +From: Alexey Brodkin +Date: Thu, 13 Apr 2017 15:33:34 +0300 +Subject: usb: Make sure usb/phy/of gets built-in + +From: Alexey Brodkin + +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 +Cc: Greg Kroah-Hartman +Cc: Masahiro Yamada +Cc: Geert Uytterhoeven +Cc: Nicolas Pitre +Cc: Thomas Gleixner +Cc: Felipe Balbi +Cc: Felix Fietkau +Cc: Jeremy Kerr +Cc: linux-snps-arc@lists.infradead.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/Makefile | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/Makefile ++++ b/drivers/Makefile +@@ -101,6 +101,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/ diff --git a/queue-4.10/usb-misc-add-missing-continue-in-switch.patch b/queue-4.10/usb-misc-add-missing-continue-in-switch.patch new file mode 100644 index 00000000000..02bffef7335 --- /dev/null +++ b/queue-4.10/usb-misc-add-missing-continue-in-switch.patch @@ -0,0 +1,30 @@ +From 2c930e3d0aed1505e86e0928d323df5027817740 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Mon, 3 Apr 2017 22:48:40 -0500 +Subject: usb: misc: add missing continue in switch + +From: Gustavo A. R. Silva + +commit 2c930e3d0aed1505e86e0928d323df5027817740 upstream. + +Add missing continue in switch. + +Addresses-Coverity-ID: 1248733 +Signed-off-by: Gustavo A. R. Silva +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-4.10/usb-misc-legousbtower-fix-buffers-on-stack.patch b/queue-4.10/usb-misc-legousbtower-fix-buffers-on-stack.patch new file mode 100644 index 00000000000..d2ab86715e4 --- /dev/null +++ b/queue-4.10/usb-misc-legousbtower-fix-buffers-on-stack.patch @@ -0,0 +1,116 @@ +From 942a48730faf149ccbf3e12ac718aee120bb3529 Mon Sep 17 00:00:00 2001 +From: Maksim Salau +Date: Tue, 25 Apr 2017 22:49:21 +0300 +Subject: usb: misc: legousbtower: Fix buffers on stack + +From: Maksim Salau + +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 +Tested-by: Alfredo Rafael Vicente Boix ; +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-4.10/usb-proper-handling-of-race-condition-when-two-usb-class-drivers-try-to-call-init_usb_class-simultaneously.patch b/queue-4.10/usb-proper-handling-of-race-condition-when-two-usb-class-drivers-try-to-call-init_usb_class-simultaneously.patch new file mode 100644 index 00000000000..b6ab645f526 --- /dev/null +++ b/queue-4.10/usb-proper-handling-of-race-condition-when-two-usb-class-drivers-try-to-call-init_usb_class-simultaneously.patch @@ -0,0 +1,60 @@ +From 2f86a96be0ccb1302b7eee7855dbee5ce4dc5dfb Mon Sep 17 00:00:00 2001 +From: Ajay Kaher +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 + +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 +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + diff --git a/queue-4.10/usb-revert-cdc-wdm-fix-out-of-sync-due-to-missing-notifications.patch b/queue-4.10/usb-revert-cdc-wdm-fix-out-of-sync-due-to-missing-notifications.patch new file mode 100644 index 00000000000..9fd41f856f9 --- /dev/null +++ b/queue-4.10/usb-revert-cdc-wdm-fix-out-of-sync-due-to-missing-notifications.patch @@ -0,0 +1,203 @@ +From 19445816996d1a89682c37685fe95959631d9f32 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= +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 + +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 +Reported-by: Aleksander Morgado +Reported-by: Daniele Palmas +Fixes: 833415a3e781 ("cdc-wdm: fix "out-of-sync" due to missing notifications") +Signed-off-by: Bjørn Mork +Acked-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + diff --git a/queue-4.10/usb-serial-ftdi_sio-add-device-id-for-microsemi-arrow-sf2plus-dev-kit.patch b/queue-4.10/usb-serial-ftdi_sio-add-device-id-for-microsemi-arrow-sf2plus-dev-kit.patch new file mode 100644 index 00000000000..3962563329a --- /dev/null +++ b/queue-4.10/usb-serial-ftdi_sio-add-device-id-for-microsemi-arrow-sf2plus-dev-kit.patch @@ -0,0 +1,51 @@ +From 31c5d1922b90ddc1da6a6ddecef7cd31f17aa32b Mon Sep 17 00:00:00 2001 +From: Marek Vasut +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 + +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 +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-4.10/usb-xhci-binterval-quirk-for-ti-tusb73x0.patch b/queue-4.10/usb-xhci-binterval-quirk-for-ti-tusb73x0.patch new file mode 100644 index 00000000000..38db2cddb7d --- /dev/null +++ b/queue-4.10/usb-xhci-binterval-quirk-for-ti-tusb73x0.patch @@ -0,0 +1,79 @@ +From 69307ccb9ad7ccb653e332de68effdeaaab6907d Mon Sep 17 00:00:00 2001 +From: Roger Quadros +Date: Fri, 7 Apr 2017 17:57:12 +0300 +Subject: usb: xhci: bInterval quirk for TI TUSB73x0 + +From: Roger Quadros + +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 +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -1493,6 +1493,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 +@@ -1652,6 +1652,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;