--- /dev/null
+From 044012b52029204900af9e4230263418427f4ba4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Stefan=20M=C3=A4tje?= <stefan.maetje@esd.eu>
+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 <stefan.maetje@esd.eu>
+
+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 <stefan.maetje@esd.eu>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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) {
--- /dev/null
+From b2f9fa1f3bd8846f50b355fc2168236975c4d264 Mon Sep 17 00:00:00 2001
+From: Xiubo Li <xiubli@redhat.com>
+Date: Wed, 18 Aug 2021 21:38:42 +0800
+Subject: ceph: correctly handle releasing an embedded cap flush
+
+From: Xiubo Li <xiubli@redhat.com>
+
+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 <xiubli@redhat.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+ };
--- /dev/null
+From 32bc8f8373d2d6a681c96e4b25dca60d4d1c6016 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <mdaenzer@redhat.com>
+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 <mdaenzer@redhat.com>
+
+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 <evan.quan@amd.com>
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com> # v3
+Acked-by: Christian König <christian.koenig@amd.com> # v3
+Signed-off-by: Michel Dänzer <mdaenzer@redhat.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+ }
+
--- /dev/null
+From 4e9655763b82a91e4c341835bb504a2b1590f984 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+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 <wqu@suse.com>
+
+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 <ce3g8jdj@umail.furryterror.org>
+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 <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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) {
--- /dev/null
+From df7b16d1c00ecb3da3a30c999cdb39f273c99a2f Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+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 <johan@kernel.org>
+
+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 <pb.g@gmx.de>
+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 <w@1wt.eu>
+Link: https://lore.kernel.org/r/20210824121926.19311-1-johan@kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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,
--- /dev/null
+From 379eb01c21795edb4ca8d342503bd2183a19ec3a Mon Sep 17 00:00:00 2001
+From: Vincent Chen <vincent.chen@sifive.com>
+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 <vincent.chen@sifive.com>
+
+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 <vincent.chen@sifive.com>
+Reviewed-by: Jisheng Zhang <jszhang@kernel.org>
+Fixes: b8c8a9590e4f ("RISC-V: Add FP register ptrace support for gdb.")
+Cc: stable@vger.kernel.org
+Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <asm/ptrace.h>
+ #include <asm/syscall.h>
+ #include <asm/thread_info.h>
++#include <asm/switch_to.h>
+ #include <linux/audit.h>
+ #include <linux/ptrace.h>
+ #include <linux/elf.h>
+@@ -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
--- /dev/null
+From 02c6dcd543f8f051973ee18bfbc4dc3bd595c558 Mon Sep 17 00:00:00 2001
+From: Li Jinlin <lijinlin3@huawei.com>
+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 <lijinlin3@huawei.com>
+
+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 <bvanassche@acm.org>
+Signed-off-by: Li Jinlin <lijinlin3@huawei.com>
+Signed-off-by: Qiu Laibin <qiulaibin@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+
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
--- /dev/null
+From 51f1954ad853d01ba4dc2b35dee14d8490ee05a1 Mon Sep 17 00:00:00 2001
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Date: Thu, 19 Aug 2021 03:17:03 +0200
+Subject: usb: dwc3: gadget: Fix dwc3_calc_trbs_left()
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+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: <stable@vger.kernel.org>
+Acked-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/e91e975affb0d0d02770686afc3a5b9eb84409f6.1629335416.git.Thinh.Nguyen@synopsys.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
--- /dev/null
+From 4a1e25c0a029b97ea4a3d423a6392bfacc3b2e39 Mon Sep 17 00:00:00 2001
+From: Wesley Cheng <wcheng@codeaurora.org>
+Date: Tue, 24 Aug 2021 21:28:55 -0700
+Subject: usb: dwc3: gadget: Stop EP0 transfers during pullup disable
+
+From: Wesley Cheng <wcheng@codeaurora.org>
+
+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: <stable@vger.kernel.org>
+Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Acked-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
+Link: https://lore.kernel.org/r/20210825042855.7977-1-wcheng@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
--- /dev/null
+From c82cacd2f1e622a461a77d275a75d7e19e7635a3 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Thu, 26 Aug 2021 14:41:27 +0200
+Subject: usb: renesas-xhci: Prefer firmware loading on unknown ROM state
+
+From: Takashi Iwai <tiwai@suse.de>
+
+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 <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+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 <gregkh@linuxfoundation.org>
+---
+ 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;
+ }
+
--- /dev/null
+From 2829a4e3cf3a6ac2fa3cdb681b37574630fb9c1a Mon Sep 17 00:00:00 2001
+From: Zhengjun Zhang <zhangzhengjun@aicrobo.com>
+Date: Mon, 9 Aug 2021 21:35:53 +0800
+Subject: USB: serial: option: add new VID/PID to support Fibocom FG150
+
+From: Zhengjun Zhang <zhangzhengjun@aicrobo.com>
+
+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 <zhangzhengjun@aicrobo.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 */