From: Greg Kroah-Hartman Date: Sun, 29 Aug 2021 07:05:57 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v4.4.283~61 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e2cb920ee77299d142139cb676a33db422065ba4;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: can-usb-esd_usb2-esd_usb2_rx_event-fix-the-interchange-of-the-can-rx-and-tx-error-counters.patch ceph-correctly-handle-releasing-an-embedded-cap-flush.patch drm-amdgpu-cancel-delayed-work-when-gfxoff-is-disabled.patch revert-btrfs-compression-don-t-try-to-compress-if-we-don-t-have-enough-pages.patch revert-usb-serial-ch341-fix-character-loss-at-high-transfer-rates.patch riscv-ensure-the-value-of-fp-registers-in-the-core-dump-file-is-up-to-date.patch scsi-core-fix-hang-of-freezing-queue-between-blocking-and-running-device.patch usb-dwc3-gadget-fix-dwc3_calc_trbs_left.patch usb-dwc3-gadget-stop-ep0-transfers-during-pullup-disable.patch usb-renesas-xhci-prefer-firmware-loading-on-unknown-rom-state.patch usb-serial-option-add-new-vid-pid-to-support-fibocom-fg150.patch --- diff --git a/queue-5.10/can-usb-esd_usb2-esd_usb2_rx_event-fix-the-interchange-of-the-can-rx-and-tx-error-counters.patch b/queue-5.10/can-usb-esd_usb2-esd_usb2_rx_event-fix-the-interchange-of-the-can-rx-and-tx-error-counters.patch new file mode 100644 index 00000000000..c0dddc1d19f --- /dev/null +++ b/queue-5.10/can-usb-esd_usb2-esd_usb2_rx_event-fix-the-interchange-of-the-can-rx-and-tx-error-counters.patch @@ -0,0 +1,40 @@ +From 044012b52029204900af9e4230263418427f4ba4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stefan=20M=C3=A4tje?= +Date: Wed, 25 Aug 2021 23:52:27 +0200 +Subject: can: usb: esd_usb2: esd_usb2_rx_event(): fix the interchange of the CAN RX and TX error counters +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Stefan Mätje + +commit 044012b52029204900af9e4230263418427f4ba4 upstream. + +This patch fixes the interchanged fetch of the CAN RX and TX error +counters from the ESD_EV_CAN_ERROR_EXT message. The RX error counter +is really in struct rx_msg::data[2] and the TX error counter is in +struct rx_msg::data[3]. + +Fixes: 96d8e90382dc ("can: Add driver for esd CAN-USB/2 device") +Link: https://lore.kernel.org/r/20210825215227.4947-2-stefan.maetje@esd.eu +Cc: stable@vger.kernel.org +Signed-off-by: Stefan Mätje +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/esd_usb2.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/can/usb/esd_usb2.c ++++ b/drivers/net/can/usb/esd_usb2.c +@@ -224,8 +224,8 @@ static void esd_usb2_rx_event(struct esd + if (id == ESD_EV_CAN_ERROR_EXT) { + u8 state = msg->msg.rx.data[0]; + u8 ecc = msg->msg.rx.data[1]; +- u8 txerr = msg->msg.rx.data[2]; +- u8 rxerr = msg->msg.rx.data[3]; ++ u8 rxerr = msg->msg.rx.data[2]; ++ u8 txerr = msg->msg.rx.data[3]; + + skb = alloc_can_err_skb(priv->netdev, &cf); + if (skb == NULL) { diff --git a/queue-5.10/ceph-correctly-handle-releasing-an-embedded-cap-flush.patch b/queue-5.10/ceph-correctly-handle-releasing-an-embedded-cap-flush.patch new file mode 100644 index 00000000000..a72ed5809bf --- /dev/null +++ b/queue-5.10/ceph-correctly-handle-releasing-an-embedded-cap-flush.patch @@ -0,0 +1,157 @@ +From b2f9fa1f3bd8846f50b355fc2168236975c4d264 Mon Sep 17 00:00:00 2001 +From: Xiubo Li +Date: Wed, 18 Aug 2021 21:38:42 +0800 +Subject: ceph: correctly handle releasing an embedded cap flush + +From: Xiubo Li + +commit b2f9fa1f3bd8846f50b355fc2168236975c4d264 upstream. + +The ceph_cap_flush structures are usually dynamically allocated, but +the ceph_cap_snap has an embedded one. + +When force umounting, the client will try to remove all the session +caps. During this, it will free them, but that should not be done +with the ones embedded in a capsnap. + +Fix this by adding a new boolean that indicates that the cap flush is +embedded in a capsnap, and skip freeing it if that's set. + +At the same time, switch to using list_del_init() when detaching the +i_list and g_list heads. It's possible for a forced umount to remove +these objects but then handle_cap_flushsnap_ack() races in and does the +list_del_init() again, corrupting memory. + +Cc: stable@vger.kernel.org +URL: https://tracker.ceph.com/issues/52283 +Signed-off-by: Xiubo Li +Reviewed-by: Jeff Layton +Signed-off-by: Ilya Dryomov +Signed-off-by: Greg Kroah-Hartman +--- + fs/ceph/caps.c | 21 +++++++++++++-------- + fs/ceph/mds_client.c | 7 ++++--- + fs/ceph/snap.c | 3 +++ + fs/ceph/super.h | 3 ++- + 4 files changed, 22 insertions(+), 12 deletions(-) + +--- a/fs/ceph/caps.c ++++ b/fs/ceph/caps.c +@@ -1752,7 +1752,11 @@ int __ceph_mark_dirty_caps(struct ceph_i + + struct ceph_cap_flush *ceph_alloc_cap_flush(void) + { +- return kmem_cache_alloc(ceph_cap_flush_cachep, GFP_KERNEL); ++ struct ceph_cap_flush *cf; ++ ++ cf = kmem_cache_alloc(ceph_cap_flush_cachep, GFP_KERNEL); ++ cf->is_capsnap = false; ++ return cf; + } + + void ceph_free_cap_flush(struct ceph_cap_flush *cf) +@@ -1787,7 +1791,7 @@ static bool __detach_cap_flush_from_mdsc + prev->wake = true; + wake = false; + } +- list_del(&cf->g_list); ++ list_del_init(&cf->g_list); + return wake; + } + +@@ -1802,7 +1806,7 @@ static bool __detach_cap_flush_from_ci(s + prev->wake = true; + wake = false; + } +- list_del(&cf->i_list); ++ list_del_init(&cf->i_list); + return wake; + } + +@@ -2422,7 +2426,7 @@ static void __kick_flushing_caps(struct + ci->i_ceph_flags &= ~CEPH_I_KICK_FLUSH; + + list_for_each_entry_reverse(cf, &ci->i_cap_flush_list, i_list) { +- if (!cf->caps) { ++ if (cf->is_capsnap) { + last_snap_flush = cf->tid; + break; + } +@@ -2441,7 +2445,7 @@ static void __kick_flushing_caps(struct + + first_tid = cf->tid + 1; + +- if (cf->caps) { ++ if (!cf->is_capsnap) { + struct cap_msg_args arg; + + dout("kick_flushing_caps %p cap %p tid %llu %s\n", +@@ -3564,7 +3568,7 @@ static void handle_cap_flush_ack(struct + cleaned = cf->caps; + + /* Is this a capsnap? */ +- if (cf->caps == 0) ++ if (cf->is_capsnap) + continue; + + if (cf->tid <= flush_tid) { +@@ -3637,8 +3641,9 @@ out: + while (!list_empty(&to_remove)) { + cf = list_first_entry(&to_remove, + struct ceph_cap_flush, i_list); +- list_del(&cf->i_list); +- ceph_free_cap_flush(cf); ++ list_del_init(&cf->i_list); ++ if (!cf->is_capsnap) ++ ceph_free_cap_flush(cf); + } + + if (wake_ci) +--- a/fs/ceph/mds_client.c ++++ b/fs/ceph/mds_client.c +@@ -1618,7 +1618,7 @@ static int remove_session_caps_cb(struct + spin_lock(&mdsc->cap_dirty_lock); + + list_for_each_entry(cf, &to_remove, i_list) +- list_del(&cf->g_list); ++ list_del_init(&cf->g_list); + + if (!list_empty(&ci->i_dirty_item)) { + pr_warn_ratelimited( +@@ -1670,8 +1670,9 @@ static int remove_session_caps_cb(struct + struct ceph_cap_flush *cf; + cf = list_first_entry(&to_remove, + struct ceph_cap_flush, i_list); +- list_del(&cf->i_list); +- ceph_free_cap_flush(cf); ++ list_del_init(&cf->i_list); ++ if (!cf->is_capsnap) ++ ceph_free_cap_flush(cf); + } + + wake_up_all(&ci->i_cap_wq); +--- a/fs/ceph/snap.c ++++ b/fs/ceph/snap.c +@@ -487,6 +487,9 @@ void ceph_queue_cap_snap(struct ceph_ino + pr_err("ENOMEM allocating ceph_cap_snap on %p\n", inode); + return; + } ++ capsnap->cap_flush.is_capsnap = true; ++ INIT_LIST_HEAD(&capsnap->cap_flush.i_list); ++ INIT_LIST_HEAD(&capsnap->cap_flush.g_list); + + spin_lock(&ci->i_ceph_lock); + used = __ceph_caps_used(ci); +--- a/fs/ceph/super.h ++++ b/fs/ceph/super.h +@@ -181,8 +181,9 @@ struct ceph_cap { + + struct ceph_cap_flush { + u64 tid; +- int caps; /* 0 means capsnap */ ++ int caps; + bool wake; /* wake up flush waiters when finish ? */ ++ bool is_capsnap; /* true means capsnap */ + struct list_head g_list; // global + struct list_head i_list; // per inode + }; diff --git a/queue-5.10/drm-amdgpu-cancel-delayed-work-when-gfxoff-is-disabled.patch b/queue-5.10/drm-amdgpu-cancel-delayed-work-when-gfxoff-is-disabled.patch new file mode 100644 index 00000000000..db04d473e52 --- /dev/null +++ b/queue-5.10/drm-amdgpu-cancel-delayed-work-when-gfxoff-is-disabled.patch @@ -0,0 +1,122 @@ +From 32bc8f8373d2d6a681c96e4b25dca60d4d1c6016 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michel=20D=C3=A4nzer?= +Date: Tue, 17 Aug 2021 10:23:25 +0200 +Subject: drm/amdgpu: Cancel delayed work when GFXOFF is disabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michel Dänzer + +commit 32bc8f8373d2d6a681c96e4b25dca60d4d1c6016 upstream. + +schedule_delayed_work does not push back the work if it was already +scheduled before, so amdgpu_device_delay_enable_gfx_off ran ~100 ms +after the first time GFXOFF was disabled and re-enabled, even if GFXOFF +was disabled and re-enabled again during those 100 ms. + +This resulted in frame drops / stutter with the upcoming mutter 41 +release on Navi 14, due to constantly enabling GFXOFF in the HW and +disabling it again (for getting the GPU clock counter). + +To fix this, call cancel_delayed_work_sync when the disable count +transitions from 0 to 1, and only schedule the delayed work on the +reverse transition, not if the disable count was already 0. This makes +sure the delayed work doesn't run at unexpected times, and allows it to +be lock-free. + +v2: +* Use cancel_delayed_work_sync & mutex_trylock instead of + mod_delayed_work. +v3: +* Make amdgpu_device_delay_enable_gfx_off lock-free (Christian König) +v4: +* Fix race condition between amdgpu_gfx_off_ctrl incrementing + adev->gfx.gfx_off_req_count and amdgpu_device_delay_enable_gfx_off + checking for it to be 0 (Evan Quan) + +Cc: stable@vger.kernel.org +Reviewed-by: Evan Quan +Reviewed-by: Lijo Lazar # v3 +Acked-by: Christian König # v3 +Signed-off-by: Michel Dänzer +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 11 +++----- + drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 38 +++++++++++++++++++---------- + 2 files changed, 31 insertions(+), 18 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -2619,12 +2619,11 @@ static void amdgpu_device_delay_enable_g + struct amdgpu_device *adev = + container_of(work, struct amdgpu_device, gfx.gfx_off_delay_work.work); + +- mutex_lock(&adev->gfx.gfx_off_mutex); +- if (!adev->gfx.gfx_off_state && !adev->gfx.gfx_off_req_count) { +- if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true)) +- adev->gfx.gfx_off_state = true; +- } +- mutex_unlock(&adev->gfx.gfx_off_mutex); ++ WARN_ON_ONCE(adev->gfx.gfx_off_state); ++ WARN_ON_ONCE(adev->gfx.gfx_off_req_count); ++ ++ if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true)) ++ adev->gfx.gfx_off_state = true; + } + + /** +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +@@ -556,24 +556,38 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_d + + mutex_lock(&adev->gfx.gfx_off_mutex); + +- if (!enable) +- adev->gfx.gfx_off_req_count++; +- else if (adev->gfx.gfx_off_req_count > 0) ++ if (enable) { ++ /* If the count is already 0, it means there's an imbalance bug somewhere. ++ * Note that the bug may be in a different caller than the one which triggers the ++ * WARN_ON_ONCE. ++ */ ++ if (WARN_ON_ONCE(adev->gfx.gfx_off_req_count == 0)) ++ goto unlock; ++ + adev->gfx.gfx_off_req_count--; + +- if (enable && !adev->gfx.gfx_off_state && !adev->gfx.gfx_off_req_count) { +- schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE); +- } else if (!enable && adev->gfx.gfx_off_state) { +- if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, false)) { +- adev->gfx.gfx_off_state = false; +- +- if (adev->gfx.funcs->init_spm_golden) { +- dev_dbg(adev->dev, "GFXOFF is disabled, re-init SPM golden settings\n"); +- amdgpu_gfx_init_spm_golden(adev); ++ if (adev->gfx.gfx_off_req_count == 0 && !adev->gfx.gfx_off_state) ++ schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE); ++ } else { ++ if (adev->gfx.gfx_off_req_count == 0) { ++ cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work); ++ ++ if (adev->gfx.gfx_off_state && ++ !amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, false)) { ++ adev->gfx.gfx_off_state = false; ++ ++ if (adev->gfx.funcs->init_spm_golden) { ++ dev_dbg(adev->dev, ++ "GFXOFF is disabled, re-init SPM golden settings\n"); ++ amdgpu_gfx_init_spm_golden(adev); ++ } + } + } ++ ++ adev->gfx.gfx_off_req_count++; + } + ++unlock: + mutex_unlock(&adev->gfx.gfx_off_mutex); + } + diff --git a/queue-5.10/revert-btrfs-compression-don-t-try-to-compress-if-we-don-t-have-enough-pages.patch b/queue-5.10/revert-btrfs-compression-don-t-try-to-compress-if-we-don-t-have-enough-pages.patch new file mode 100644 index 00000000000..c6cb516fb6c --- /dev/null +++ b/queue-5.10/revert-btrfs-compression-don-t-try-to-compress-if-we-don-t-have-enough-pages.patch @@ -0,0 +1,61 @@ +From 4e9655763b82a91e4c341835bb504a2b1590f984 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Wed, 25 Aug 2021 13:41:42 +0800 +Subject: Revert "btrfs: compression: don't try to compress if we don't have enough pages" + +From: Qu Wenruo + +commit 4e9655763b82a91e4c341835bb504a2b1590f984 upstream. + +This reverts commit f2165627319ffd33a6217275e5690b1ab5c45763. + +[BUG] +It's no longer possible to create compressed inline extent after commit +f2165627319f ("btrfs: compression: don't try to compress if we don't +have enough pages"). + +[CAUSE] +For compression code, there are several possible reasons we have a range +that needs to be compressed while it's no more than one page. + +- Compressed inline write + The data is always smaller than one sector and the test lacks the + condition to properly recognize a non-inline extent. + +- Compressed subpage write + For the incoming subpage compressed write support, we require page + alignment of the delalloc range. + And for 64K page size, we can compress just one page into smaller + sectors. + +For those reasons, the requirement for the data to be more than one page +is not correct, and is already causing regression for compressed inline +data writeback. The idea of skipping one page to avoid wasting CPU time +could be revisited in the future. + +[FIX] +Fix it by reverting the offending commit. + +Reported-by: Zygo Blaxell +Link: https://lore.kernel.org/linux-btrfs/afa2742.c084f5d6.17b6b08dffc@tnonline.net +Fixes: f2165627319f ("btrfs: compression: don't try to compress if we don't have enough pages") +CC: stable@vger.kernel.org # 4.4+ +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -547,7 +547,7 @@ again: + * inode has not been flagged as nocompress. This flag can + * change at any time if we discover bad compression ratios. + */ +- if (nr_pages > 1 && inode_need_compress(BTRFS_I(inode), start, end)) { ++ if (inode_need_compress(BTRFS_I(inode), start, end)) { + WARN_ON(pages); + pages = kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS); + if (!pages) { diff --git a/queue-5.10/revert-usb-serial-ch341-fix-character-loss-at-high-transfer-rates.patch b/queue-5.10/revert-usb-serial-ch341-fix-character-loss-at-high-transfer-rates.patch new file mode 100644 index 00000000000..9e6b8ef5828 --- /dev/null +++ b/queue-5.10/revert-usb-serial-ch341-fix-character-loss-at-high-transfer-rates.patch @@ -0,0 +1,44 @@ +From df7b16d1c00ecb3da3a30c999cdb39f273c99a2f Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 24 Aug 2021 14:19:26 +0200 +Subject: Revert "USB: serial: ch341: fix character loss at high transfer rates" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Johan Hovold + +commit df7b16d1c00ecb3da3a30c999cdb39f273c99a2f upstream. + +This reverts commit 3c18e9baee0ef97510dcda78c82285f52626764b. + +These devices do not appear to send a zero-length packet when the +transfer size is a multiple of the bulk-endpoint max-packet size. This +means that incoming data may not be processed by the driver until a +short packet is received or the receive buffer is full. + +Revert back to using endpoint-sized receive buffers to avoid stalled +reads. + +Reported-by: Paul Größel +Link: https://bugzilla.kernel.org/show_bug.cgi?id=214131 +Fixes: 3c18e9baee0e ("USB: serial: ch341: fix character loss at high transfer rates") +Cc: stable@vger.kernel.org +Cc: Willy Tarreau +Link: https://lore.kernel.org/r/20210824121926.19311-1-johan@kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/ch341.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -853,7 +853,6 @@ static struct usb_serial_driver ch341_de + .owner = THIS_MODULE, + .name = "ch341-uart", + }, +- .bulk_in_size = 512, + .id_table = id_table, + .num_ports = 1, + .open = ch341_open, diff --git a/queue-5.10/riscv-ensure-the-value-of-fp-registers-in-the-core-dump-file-is-up-to-date.patch b/queue-5.10/riscv-ensure-the-value-of-fp-registers-in-the-core-dump-file-is-up-to-date.patch new file mode 100644 index 00000000000..d110f0ae6a5 --- /dev/null +++ b/queue-5.10/riscv-ensure-the-value-of-fp-registers-in-the-core-dump-file-is-up-to-date.patch @@ -0,0 +1,48 @@ +From 379eb01c21795edb4ca8d342503bd2183a19ec3a Mon Sep 17 00:00:00 2001 +From: Vincent Chen +Date: Tue, 3 Aug 2021 17:27:51 +0800 +Subject: riscv: Ensure the value of FP registers in the core dump file is up to date + +From: Vincent Chen + +commit 379eb01c21795edb4ca8d342503bd2183a19ec3a upstream. + +The value of FP registers in the core dump file comes from the +thread.fstate. However, kernel saves the FP registers to the thread.fstate +only before scheduling out the process. If no process switch happens +during the exception handling process, kernel will not have a chance to +save the latest value of FP registers to thread.fstate. It will cause the +value of FP registers in the core dump file may be incorrect. To solve this +problem, this patch force lets kernel save the FP register into the +thread.fstate if the target task_struct equals the current. + +Signed-off-by: Vincent Chen +Reviewed-by: Jisheng Zhang +Fixes: b8c8a9590e4f ("RISC-V: Add FP register ptrace support for gdb.") +Cc: stable@vger.kernel.org +Signed-off-by: Palmer Dabbelt +Signed-off-by: Greg Kroah-Hartman +--- + arch/riscv/kernel/ptrace.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/riscv/kernel/ptrace.c ++++ b/arch/riscv/kernel/ptrace.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -56,6 +57,9 @@ static int riscv_fpr_get(struct task_str + { + struct __riscv_d_ext_state *fstate = &target->thread.fstate; + ++ if (target == current) ++ fstate_save(current, task_pt_regs(current)); ++ + membuf_write(&to, fstate, offsetof(struct __riscv_d_ext_state, fcsr)); + membuf_store(&to, fstate->fcsr); + return membuf_zero(&to, 4); // explicitly pad diff --git a/queue-5.10/scsi-core-fix-hang-of-freezing-queue-between-blocking-and-running-device.patch b/queue-5.10/scsi-core-fix-hang-of-freezing-queue-between-blocking-and-running-device.patch new file mode 100644 index 00000000000..b866e068170 --- /dev/null +++ b/queue-5.10/scsi-core-fix-hang-of-freezing-queue-between-blocking-and-running-device.patch @@ -0,0 +1,97 @@ +From 02c6dcd543f8f051973ee18bfbc4dc3bd595c558 Mon Sep 17 00:00:00 2001 +From: Li Jinlin +Date: Tue, 24 Aug 2021 10:59:21 +0800 +Subject: scsi: core: Fix hang of freezing queue between blocking and running device + +From: Li Jinlin + +commit 02c6dcd543f8f051973ee18bfbc4dc3bd595c558 upstream. + +We found a hang, the steps to reproduce are as follows: + + 1. blocking device via scsi_device_set_state() + + 2. dd if=/dev/sda of=/mnt/t.log bs=1M count=10 + + 3. echo none > /sys/block/sda/queue/scheduler + + 4. echo "running" >/sys/block/sda/device/state + +Step 3 and 4 should complete after step 4, but they hang. + + CPU#0 CPU#1 CPU#2 + --------------- ---------------- ---------------- + Step 1: blocking device + + Step 2: dd xxxx + ^^^^^^ get request + q_usage_counter++ + + Step 3: switching scheculer + elv_iosched_store + elevator_switch + blk_mq_freeze_queue + blk_freeze_queue + > blk_freeze_queue_start + ^^^^^^ mq_freeze_depth++ + + > blk_mq_run_hw_queues + ^^^^^^ can't run queue when dev blocked + + > blk_mq_freeze_queue_wait + ^^^^^^ Hang here!!! + wait q_usage_counter==0 + + Step 4: running device + store_state_field + scsi_rescan_device + scsi_attach_vpd + scsi_vpd_inquiry + __scsi_execute + blk_get_request + blk_mq_alloc_request + blk_queue_enter + ^^^^^^ Hang here!!! + wait mq_freeze_depth==0 + + blk_mq_run_hw_queues + ^^^^^^ dispatch IO, q_usage_counter will reduce to zero + + blk_mq_unfreeze_queue + ^^^^^ mq_freeze_depth-- + +To fix this, we need to run queue before rescanning device when the device +state changes to SDEV_RUNNING. + +Link: https://lore.kernel.org/r/20210824025921.3277629-1-lijinlin3@huawei.com +Fixes: f0f82e2476f6 ("scsi: core: Fix capacity set to zero after offlinining device") +Reviewed-by: Bart Van Assche +Signed-off-by: Li Jinlin +Signed-off-by: Qiu Laibin +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/scsi_sysfs.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -808,12 +808,15 @@ store_state_field(struct device *dev, st + ret = scsi_device_set_state(sdev, state); + /* + * If the device state changes to SDEV_RUNNING, we need to +- * rescan the device to revalidate it, and run the queue to +- * avoid I/O hang. ++ * run the queue to avoid I/O hang, and rescan the device ++ * to revalidate it. Running the queue first is necessary ++ * because another thread may be waiting inside ++ * blk_mq_freeze_queue_wait() and because that call may be ++ * waiting for pending I/O to finish. + */ + if (ret == 0 && state == SDEV_RUNNING) { +- scsi_rescan_device(dev); + blk_mq_run_hw_queues(sdev->request_queue, true); ++ scsi_rescan_device(dev); + } + mutex_unlock(&sdev->state_mutex); + diff --git a/queue-5.10/series b/queue-5.10/series index a0df9727968..c6d4f3cca41 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -9,3 +9,14 @@ once-fix-panic-when-module-unload.patch blk-iocost-fix-lockdep-warning-on-blkcg-lock.patch ovl-fix-uninitialized-pointer-read-in-ovl_lookup_rea.patch net-mscc-fix-non-gpl-export-of-regmap-apis.patch +can-usb-esd_usb2-esd_usb2_rx_event-fix-the-interchange-of-the-can-rx-and-tx-error-counters.patch +ceph-correctly-handle-releasing-an-embedded-cap-flush.patch +riscv-ensure-the-value-of-fp-registers-in-the-core-dump-file-is-up-to-date.patch +revert-btrfs-compression-don-t-try-to-compress-if-we-don-t-have-enough-pages.patch +drm-amdgpu-cancel-delayed-work-when-gfxoff-is-disabled.patch +revert-usb-serial-ch341-fix-character-loss-at-high-transfer-rates.patch +usb-serial-option-add-new-vid-pid-to-support-fibocom-fg150.patch +usb-renesas-xhci-prefer-firmware-loading-on-unknown-rom-state.patch +usb-dwc3-gadget-fix-dwc3_calc_trbs_left.patch +usb-dwc3-gadget-stop-ep0-transfers-during-pullup-disable.patch +scsi-core-fix-hang-of-freezing-queue-between-blocking-and-running-device.patch diff --git a/queue-5.10/usb-dwc3-gadget-fix-dwc3_calc_trbs_left.patch b/queue-5.10/usb-dwc3-gadget-fix-dwc3_calc_trbs_left.patch new file mode 100644 index 00000000000..cb8c4ebadf9 --- /dev/null +++ b/queue-5.10/usb-dwc3-gadget-fix-dwc3_calc_trbs_left.patch @@ -0,0 +1,60 @@ +From 51f1954ad853d01ba4dc2b35dee14d8490ee05a1 Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Thu, 19 Aug 2021 03:17:03 +0200 +Subject: usb: dwc3: gadget: Fix dwc3_calc_trbs_left() + +From: Thinh Nguyen + +commit 51f1954ad853d01ba4dc2b35dee14d8490ee05a1 upstream. + +We can't depend on the TRB's HWO bit to determine if the TRB ring is +"full". A TRB is only available when the driver had processed it, not +when the controller consumed and relinquished the TRB's ownership to the +driver. Otherwise, the driver may overwrite unprocessed TRBs. This can +happen when many transfer events accumulate and the system is slow to +process them and/or when there are too many small requests. + +If a request is in the started_list, that means there is one or more +unprocessed TRBs remained. Check this instead of the TRB's HWO bit +whether the TRB ring is full. + +Fixes: c4233573f6ee ("usb: dwc3: gadget: prepare TRBs on update transfers too") +Cc: +Acked-by: Felipe Balbi +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/e91e975affb0d0d02770686afc3a5b9eb84409f6.1629335416.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/gadget.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -932,19 +932,19 @@ static struct dwc3_trb *dwc3_ep_prev_trb + + static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) + { +- struct dwc3_trb *tmp; + u8 trbs_left; + + /* +- * If enqueue & dequeue are equal than it is either full or empty. +- * +- * One way to know for sure is if the TRB right before us has HWO bit +- * set or not. If it has, then we're definitely full and can't fit any +- * more transfers in our ring. ++ * If the enqueue & dequeue are equal then the TRB ring is either full ++ * or empty. It's considered full when there are DWC3_TRB_NUM-1 of TRBs ++ * pending to be processed by the driver. + */ + if (dep->trb_enqueue == dep->trb_dequeue) { +- tmp = dwc3_ep_prev_trb(dep, dep->trb_enqueue); +- if (tmp->ctrl & DWC3_TRB_CTRL_HWO) ++ /* ++ * If there is any request remained in the started_list at ++ * this point, that means there is no TRB available. ++ */ ++ if (!list_empty(&dep->started_list)) + return 0; + + return DWC3_TRB_NUM - 1; diff --git a/queue-5.10/usb-dwc3-gadget-stop-ep0-transfers-during-pullup-disable.patch b/queue-5.10/usb-dwc3-gadget-stop-ep0-transfers-during-pullup-disable.patch new file mode 100644 index 00000000000..fcc21030dcd --- /dev/null +++ b/queue-5.10/usb-dwc3-gadget-stop-ep0-transfers-during-pullup-disable.patch @@ -0,0 +1,59 @@ +From 4a1e25c0a029b97ea4a3d423a6392bfacc3b2e39 Mon Sep 17 00:00:00 2001 +From: Wesley Cheng +Date: Tue, 24 Aug 2021 21:28:55 -0700 +Subject: usb: dwc3: gadget: Stop EP0 transfers during pullup disable + +From: Wesley Cheng + +commit 4a1e25c0a029b97ea4a3d423a6392bfacc3b2e39 upstream. + +During a USB cable disconnect, or soft disconnect scenario, a pending +SETUP transaction may not be completed, leading to the following +error: + + dwc3 a600000.dwc3: timed out waiting for SETUP phase + +If this occurs, then the entire pullup disable routine is skipped and +proper cleanup and halting of the controller does not complete. + +Instead of returning an error (which is ignored from the UDC +perspective), allow the pullup disable routine to continue, which +will also handle disabling of EP0/1. This will end any active +transfers as well. Ensure to clear any delayed_status also, as the +timeout could happen within the STATUS stage. + +Fixes: bb0147364850 ("usb: dwc3: gadget: don't clear RUN/STOP when it's invalid to do so") +Cc: +Reviewed-by: Thinh Nguyen +Acked-by: Felipe Balbi +Signed-off-by: Wesley Cheng +Link: https://lore.kernel.org/r/20210825042855.7977-1-wcheng@codeaurora.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/gadget.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2125,10 +2125,8 @@ static int dwc3_gadget_pullup(struct usb + + ret = wait_for_completion_timeout(&dwc->ep0_in_setup, + msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT)); +- if (ret == 0) { +- dev_err(dwc->dev, "timed out waiting for SETUP phase\n"); +- return -ETIMEDOUT; +- } ++ if (ret == 0) ++ dev_warn(dwc->dev, "timed out waiting for SETUP phase\n"); + } + + /* +@@ -2332,6 +2330,7 @@ static int __dwc3_gadget_start(struct dw + /* begin to receive SETUP packets */ + dwc->ep0state = EP0_SETUP_PHASE; + dwc->link_state = DWC3_LINK_STATE_SS_DIS; ++ dwc->delayed_status = false; + dwc3_ep0_out_start(dwc); + + dwc3_gadget_enable_irq(dwc); diff --git a/queue-5.10/usb-renesas-xhci-prefer-firmware-loading-on-unknown-rom-state.patch b/queue-5.10/usb-renesas-xhci-prefer-firmware-loading-on-unknown-rom-state.patch new file mode 100644 index 00000000000..9ffce7012da --- /dev/null +++ b/queue-5.10/usb-renesas-xhci-prefer-firmware-loading-on-unknown-rom-state.patch @@ -0,0 +1,118 @@ +From c82cacd2f1e622a461a77d275a75d7e19e7635a3 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Thu, 26 Aug 2021 14:41:27 +0200 +Subject: usb: renesas-xhci: Prefer firmware loading on unknown ROM state + +From: Takashi Iwai + +commit c82cacd2f1e622a461a77d275a75d7e19e7635a3 upstream. + +The recent attempt to handle an unknown ROM state in the commit +d143825baf15 ("usb: renesas-xhci: Fix handling of unknown ROM state") +resulted in a regression and reverted later by the commit 44cf53602f5a +("Revert "usb: renesas-xhci: Fix handling of unknown ROM state""). +The problem of the former fix was that it treated the failure of +firmware loading as a fatal error. Since the firmware files aren't +included in the standard linux-firmware tree, most users don't have +them, hence they got the non-working system after that. The revert +fixed the regression, but also it didn't make the firmware loading +triggered even on the devices that do need it. So we need still a fix +for them. + +This is another attempt to handle the unknown ROM state. Like the +previous fix, this also tries to load the firmware when ROM shows +unknown state. In this patch, however, the failure of a firmware +loading (such as a missing firmware file) isn't handled as a fatal +error any longer when ROM has been already detected, but it falls back +to the ROM mode like before. The error is returned only when no ROM +is detected and the firmware loading failed. + +Along with it, for simplifying the code flow, the detection and the +check of ROM is factored out from renesas_fw_check_running() and done +in the caller side, renesas_xhci_check_request_fw(). It avoids the +redundant ROM checks. + +The patch was tested on Lenovo Thinkpad T14 gen (BIOS 1.34). Also it +was confirmed that no regression is seen on another Thinkpad T14 +machine that has worked without the patch, too. + +Fixes: 44cf53602f5a ("Revert "usb: renesas-xhci: Fix handling of unknown ROM state"") +Cc: stable +Signed-off-by: Takashi Iwai +BugLink: https://bugzilla.opensuse.org/show_bug.cgi?id=1189207 +Link: https://lore.kernel.org/r/20210826124127.14789-1-tiwai@suse.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-pci-renesas.c | 35 +++++++++++++++++++++++------------ + 1 file changed, 23 insertions(+), 12 deletions(-) + +--- a/drivers/usb/host/xhci-pci-renesas.c ++++ b/drivers/usb/host/xhci-pci-renesas.c +@@ -207,7 +207,8 @@ static int renesas_check_rom_state(struc + return 0; + + case RENESAS_ROM_STATUS_NO_RESULT: /* No result yet */ +- return 0; ++ dev_dbg(&pdev->dev, "Unknown ROM status ...\n"); ++ return -ENOENT; + + case RENESAS_ROM_STATUS_ERROR: /* Error State */ + default: /* All other states are marked as "Reserved states" */ +@@ -224,14 +225,6 @@ static int renesas_fw_check_running(stru + u8 fw_state; + int err; + +- /* Check if device has ROM and loaded, if so skip everything */ +- err = renesas_check_rom(pdev); +- if (err) { /* we have rom */ +- err = renesas_check_rom_state(pdev); +- if (!err) +- return err; +- } +- + /* + * Test if the device is actually needing the firmware. As most + * BIOSes will initialize the device for us. If the device is +@@ -591,21 +584,39 @@ int renesas_xhci_check_request_fw(struct + (struct xhci_driver_data *)id->driver_data; + const char *fw_name = driver_data->firmware; + const struct firmware *fw; ++ bool has_rom; + int err; + ++ /* Check if device has ROM and loaded, if so skip everything */ ++ has_rom = renesas_check_rom(pdev); ++ if (has_rom) { ++ err = renesas_check_rom_state(pdev); ++ if (!err) ++ return 0; ++ else if (err != -ENOENT) ++ has_rom = false; ++ } ++ + err = renesas_fw_check_running(pdev); + /* Continue ahead, if the firmware is already running. */ + if (err == 0) + return 0; + ++ /* no firmware interface available */ + if (err != 1) +- return err; ++ return has_rom ? 0 : err; + + pci_dev_get(pdev); +- err = request_firmware(&fw, fw_name, &pdev->dev); ++ err = firmware_request_nowarn(&fw, fw_name, &pdev->dev); + pci_dev_put(pdev); + if (err) { +- dev_err(&pdev->dev, "request_firmware failed: %d\n", err); ++ if (has_rom) { ++ dev_info(&pdev->dev, "failed to load firmware %s, fallback to ROM\n", ++ fw_name); ++ return 0; ++ } ++ dev_err(&pdev->dev, "failed to load firmware %s: %d\n", ++ fw_name, err); + return err; + } + diff --git a/queue-5.10/usb-serial-option-add-new-vid-pid-to-support-fibocom-fg150.patch b/queue-5.10/usb-serial-option-add-new-vid-pid-to-support-fibocom-fg150.patch new file mode 100644 index 00000000000..5bbe769ca81 --- /dev/null +++ b/queue-5.10/usb-serial-option-add-new-vid-pid-to-support-fibocom-fg150.patch @@ -0,0 +1,278 @@ +From 2829a4e3cf3a6ac2fa3cdb681b37574630fb9c1a Mon Sep 17 00:00:00 2001 +From: Zhengjun Zhang +Date: Mon, 9 Aug 2021 21:35:53 +0800 +Subject: USB: serial: option: add new VID/PID to support Fibocom FG150 + +From: Zhengjun Zhang + +commit 2829a4e3cf3a6ac2fa3cdb681b37574630fb9c1a upstream. + +Fibocom FG150 is a 5G module based on Qualcomm SDX55 platform, +support Sub-6G band. + +Here are the outputs of lsusb -v and usb-devices: + +> T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 2 Spd=5000 MxCh= 0 +> D: Ver= 3.20 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1 +> P: Vendor=2cb7 ProdID=010b Rev=04.14 +> S: Manufacturer=Fibocom +> S: Product=Fibocom Modem_SN:XXXXXXXX +> S: SerialNumber=XXXXXXXX +> C: #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=896mA +> I: If#=0x0 Alt= 0 #EPs= 1 Cls=ef(misc ) Sub=04 Prot=01 Driver=rndis_host +> I: If#=0x1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host +> I: If#=0x2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none) +> I: If#=0x3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=(none) +> I: If#=0x4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) + +> Bus 002 Device 002: ID 2cb7:010b Fibocom Fibocom Modem_SN:XXXXXXXX +> Device Descriptor: +> bLength 18 +> bDescriptorType 1 +> bcdUSB 3.20 +> bDeviceClass 0 +> bDeviceSubClass 0 +> bDeviceProtocol 0 +> bMaxPacketSize0 9 +> idVendor 0x2cb7 Fibocom +> idProduct 0x010b +> bcdDevice 4.14 +> iManufacturer 1 Fibocom +> iProduct 2 Fibocom Modem_SN:XXXXXXXX +> iSerial 3 XXXXXXXX +> bNumConfigurations 1 +> Configuration Descriptor: +> bLength 9 +> bDescriptorType 2 +> wTotalLength 0x00e6 +> bNumInterfaces 5 +> bConfigurationValue 1 +> iConfiguration 4 RNDIS_DUN_DIAG_ADB +> bmAttributes 0xa0 +> (Bus Powered) +> Remote Wakeup +> MaxPower 896mA +> Interface Association: +> bLength 8 +> bDescriptorType 11 +> bFirstInterface 0 +> bInterfaceCount 2 +> bFunctionClass 239 Miscellaneous Device +> bFunctionSubClass 4 +> bFunctionProtocol 1 +> iFunction 7 RNDIS +> Interface Descriptor: +> bLength 9 +> bDescriptorType 4 +> bInterfaceNumber 0 +> bAlternateSetting 0 +> bNumEndpoints 1 +> bInterfaceClass 239 Miscellaneous Device +> bInterfaceSubClass 4 +> bInterfaceProtocol 1 +> iInterface 0 +> ** UNRECOGNIZED: 05 24 00 10 01 +> ** UNRECOGNIZED: 05 24 01 00 01 +> ** UNRECOGNIZED: 04 24 02 00 +> ** UNRECOGNIZED: 05 24 06 00 01 +> Endpoint Descriptor: +> bLength 7 +> bDescriptorType 5 +> bEndpointAddress 0x81 EP 1 IN +> bmAttributes 3 +> Transfer Type Interrupt +> Synch Type None +> Usage Type Data +> wMaxPacketSize 0x0008 1x 8 bytes +> bInterval 9 +> bMaxBurst 0 +> Interface Descriptor: +> bLength 9 +> bDescriptorType 4 +> bInterfaceNumber 1 +> bAlternateSetting 0 +> bNumEndpoints 2 +> bInterfaceClass 10 CDC Data +> bInterfaceSubClass 0 +> bInterfaceProtocol 0 +> iInterface 0 +> Endpoint Descriptor: +> bLength 7 +> bDescriptorType 5 +> bEndpointAddress 0x8e EP 14 IN +> bmAttributes 2 +> Transfer Type Bulk +> Synch Type None +> Usage Type Data +> wMaxPacketSize 0x0400 1x 1024 bytes +> bInterval 0 +> bMaxBurst 6 +> Endpoint Descriptor: +> bLength 7 +> bDescriptorType 5 +> bEndpointAddress 0x0f EP 15 OUT +> bmAttributes 2 +> Transfer Type Bulk +> Synch Type None +> Usage Type Data +> wMaxPacketSize 0x0400 1x 1024 bytes +> bInterval 0 +> bMaxBurst 6 +> Interface Descriptor: +> bLength 9 +> bDescriptorType 4 +> bInterfaceNumber 2 +> bAlternateSetting 0 +> bNumEndpoints 3 +> bInterfaceClass 255 Vendor Specific Class +> bInterfaceSubClass 0 +> bInterfaceProtocol 0 +> iInterface 0 +> ** UNRECOGNIZED: 05 24 00 10 01 +> ** UNRECOGNIZED: 05 24 01 00 00 +> ** UNRECOGNIZED: 04 24 02 02 +> ** UNRECOGNIZED: 05 24 06 00 00 +> Endpoint Descriptor: +> bLength 7 +> bDescriptorType 5 +> bEndpointAddress 0x83 EP 3 IN +> bmAttributes 3 +> Transfer Type Interrupt +> Synch Type None +> Usage Type Data +> wMaxPacketSize 0x000a 1x 10 bytes +> bInterval 9 +> bMaxBurst 0 +> Endpoint Descriptor: +> bLength 7 +> bDescriptorType 5 +> bEndpointAddress 0x82 EP 2 IN +> bmAttributes 2 +> Transfer Type Bulk +> Synch Type None +> Usage Type Data +> wMaxPacketSize 0x0400 1x 1024 bytes +> bInterval 0 +> bMaxBurst 0 +> Endpoint Descriptor: +> bLength 7 +> bDescriptorType 5 +> bEndpointAddress 0x01 EP 1 OUT +> bmAttributes 2 +> Transfer Type Bulk +> Synch Type None +> Usage Type Data +> wMaxPacketSize 0x0400 1x 1024 bytes +> bInterval 0 +> bMaxBurst 0 +> Interface Descriptor: +> bLength 9 +> bDescriptorType 4 +> bInterfaceNumber 3 +> bAlternateSetting 0 +> bNumEndpoints 2 +> bInterfaceClass 255 Vendor Specific Class +> bInterfaceSubClass 255 Vendor Specific Subclass +> bInterfaceProtocol 48 +> iInterface 0 +> Endpoint Descriptor: +> bLength 7 +> bDescriptorType 5 +> bEndpointAddress 0x84 EP 4 IN +> bmAttributes 2 +> Transfer Type Bulk +> Synch Type None +> Usage Type Data +> wMaxPacketSize 0x0400 1x 1024 bytes +> bInterval 0 +> bMaxBurst 0 +> Endpoint Descriptor: +> bLength 7 +> bDescriptorType 5 +> bEndpointAddress 0x02 EP 2 OUT +> bmAttributes 2 +> Transfer Type Bulk +> Synch Type None +> Usage Type Data +> wMaxPacketSize 0x0400 1x 1024 bytes +> bInterval 0 +> bMaxBurst 0 +> Interface Descriptor: +> bLength 9 +> bDescriptorType 4 +> bInterfaceNumber 4 +> bAlternateSetting 0 +> bNumEndpoints 2 +> bInterfaceClass 255 Vendor Specific Class +> bInterfaceSubClass 66 +> bInterfaceProtocol 1 +> iInterface 0 +> Endpoint Descriptor: +> bLength 7 +> bDescriptorType 5 +> bEndpointAddress 0x03 EP 3 OUT +> bmAttributes 2 +> Transfer Type Bulk +> Synch Type None +> Usage Type Data +> wMaxPacketSize 0x0400 1x 1024 bytes +> bInterval 0 +> bMaxBurst 0 +> Endpoint Descriptor: +> bLength 7 +> bDescriptorType 5 +> bEndpointAddress 0x85 EP 5 IN +> bmAttributes 2 +> Transfer Type Bulk +> Synch Type None +> Usage Type Data +> wMaxPacketSize 0x0400 1x 1024 bytes +> bInterval 0 +> bMaxBurst 0 +> Binary Object Store Descriptor: +> bLength 5 +> bDescriptorType 15 +> wTotalLength 0x0016 +> bNumDeviceCaps 2 +> USB 2.0 Extension Device Capability: +> bLength 7 +> bDescriptorType 16 +> bDevCapabilityType 2 +> bmAttributes 0x00000006 +> BESL Link Power Management (LPM) Supported +> SuperSpeed USB Device Capability: +> bLength 10 +> bDescriptorType 16 +> bDevCapabilityType 3 +> bmAttributes 0x00 +> wSpeedsSupported 0x000f +> Device can operate at Low Speed (1Mbps) +> Device can operate at Full Speed (12Mbps) +> Device can operate at High Speed (480Mbps) +> Device can operate at SuperSpeed (5Gbps) +> bFunctionalitySupport 1 +> Lowest fully-functional device speed is Full Speed (12Mbps) +> bU1DevExitLat 1 micro seconds +> bU2DevExitLat 500 micro seconds +> Device Status: 0x0000 +> (Bus Powered) + +Signed-off-by: Zhengjun Zhang +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -2074,6 +2074,8 @@ static const struct usb_device_id option + .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ + .driver_info = RSVD(6) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) }, /* Fibocom FG150 Diag */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) }, /* Fibocom FG150 AT */ + { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ + { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */