]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 May 2018 07:22:48 +0000 (09:22 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 May 2018 07:22:48 +0000 (09:22 +0200)
added patches:
errseq-always-report-a-writeback-error-once.patch
irqchip-qcom-fix-check-for-spurious-interrupts.patch
platform-x86-asus-wireless-fix-null-pointer-dereference.patch
tracing-fix-bad-use-of-igrab-in-trace_uprobe.c.patch
usb-accept-bulk-endpoints-with-1024-byte-maxpacket.patch
usb-dwc3-gadget-fix-list_del-corruption-in-dwc3_ep_dequeue.patch
usb-musb-host-fix-potential-null-pointer-dereference.patch
usb-musb-trace-fix-null-pointer-dereference-in-musb_g_tx.patch
usb-serial-option-adding-support-for-ublox-r410m.patch
usb-serial-option-reimplement-interface-masking.patch
usb-serial-visor-handle-potential-invalid-device-configuration.patch

12 files changed:
queue-4.14/errseq-always-report-a-writeback-error-once.patch [new file with mode: 0644]
queue-4.14/irqchip-qcom-fix-check-for-spurious-interrupts.patch [new file with mode: 0644]
queue-4.14/platform-x86-asus-wireless-fix-null-pointer-dereference.patch [new file with mode: 0644]
queue-4.14/series
queue-4.14/tracing-fix-bad-use-of-igrab-in-trace_uprobe.c.patch [new file with mode: 0644]
queue-4.14/usb-accept-bulk-endpoints-with-1024-byte-maxpacket.patch [new file with mode: 0644]
queue-4.14/usb-dwc3-gadget-fix-list_del-corruption-in-dwc3_ep_dequeue.patch [new file with mode: 0644]
queue-4.14/usb-musb-host-fix-potential-null-pointer-dereference.patch [new file with mode: 0644]
queue-4.14/usb-musb-trace-fix-null-pointer-dereference-in-musb_g_tx.patch [new file with mode: 0644]
queue-4.14/usb-serial-option-adding-support-for-ublox-r410m.patch [new file with mode: 0644]
queue-4.14/usb-serial-option-reimplement-interface-masking.patch [new file with mode: 0644]
queue-4.14/usb-serial-visor-handle-potential-invalid-device-configuration.patch [new file with mode: 0644]

diff --git a/queue-4.14/errseq-always-report-a-writeback-error-once.patch b/queue-4.14/errseq-always-report-a-writeback-error-once.patch
new file mode 100644 (file)
index 0000000..fbc49ac
--- /dev/null
@@ -0,0 +1,73 @@
+From b4678df184b314a2bd47d2329feca2c2534aa12b Mon Sep 17 00:00:00 2001
+From: Matthew Wilcox <willy@infradead.org>
+Date: Tue, 24 Apr 2018 14:02:57 -0700
+Subject: errseq: Always report a writeback error once
+
+From: Matthew Wilcox <willy@infradead.org>
+
+commit b4678df184b314a2bd47d2329feca2c2534aa12b upstream.
+
+The errseq_t infrastructure assumes that errors which occurred before
+the file descriptor was opened are of no interest to the application.
+This turns out to be a regression for some applications, notably Postgres.
+
+Before errseq_t, a writeback error would be reported exactly once (as
+long as the inode remained in memory), so Postgres could open a file,
+call fsync() and find out whether there had been a writeback error on
+that file from another process.
+
+This patch changes the errseq infrastructure to report errors to all
+file descriptors which are opened after the error occurred, but before
+it was reported to any file descriptor.  This restores the user-visible
+behaviour.
+
+Cc: stable@vger.kernel.org
+Fixes: 5660e13d2fd6 ("fs: new infrastructure for writeback error handling and reporting")
+Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ lib/errseq.c |   25 +++++++++++--------------
+ 1 file changed, 11 insertions(+), 14 deletions(-)
+
+--- a/lib/errseq.c
++++ b/lib/errseq.c
+@@ -111,25 +111,22 @@ EXPORT_SYMBOL(errseq_set);
+  * errseq_sample - grab current errseq_t value
+  * @eseq: pointer to errseq_t to be sampled
+  *
+- * This function allows callers to sample an errseq_t value, marking it as
+- * "seen" if required.
++ * This function allows callers to initialise their errseq_t variable.
++ * If the error has been "seen", new callers will not see an old error.
++ * If there is an unseen error in @eseq, the caller of this function will
++ * see it the next time it checks for an error.
++ *
++ * Context: Any context.
++ * Return: The current errseq value.
+  */
+ errseq_t errseq_sample(errseq_t *eseq)
+ {
+       errseq_t old = READ_ONCE(*eseq);
+-      errseq_t new = old;
+-      /*
+-       * For the common case of no errors ever having been set, we can skip
+-       * marking the SEEN bit. Once an error has been set, the value will
+-       * never go back to zero.
+-       */
+-      if (old != 0) {
+-              new |= ERRSEQ_SEEN;
+-              if (old != new)
+-                      cmpxchg(eseq, old, new);
+-      }
+-      return new;
++      /* If nobody has seen this error yet, then we can be the first. */
++      if (!(old & ERRSEQ_SEEN))
++              old = 0;
++      return old;
+ }
+ EXPORT_SYMBOL(errseq_sample);
diff --git a/queue-4.14/irqchip-qcom-fix-check-for-spurious-interrupts.patch b/queue-4.14/irqchip-qcom-fix-check-for-spurious-interrupts.patch
new file mode 100644 (file)
index 0000000..d1c5353
--- /dev/null
@@ -0,0 +1,49 @@
+From 1bc2463cee92ef0e2034c813d5e511adeb58b5fd Mon Sep 17 00:00:00 2001
+From: Agustin Vega-Frias <agustinv@codeaurora.org>
+Date: Tue, 1 May 2018 10:14:50 -0400
+Subject: irqchip/qcom: Fix check for spurious interrupts
+
+From: Agustin Vega-Frias <agustinv@codeaurora.org>
+
+commit 1bc2463cee92ef0e2034c813d5e511adeb58b5fd upstream.
+
+When the interrupts for a combiner span multiple registers it must be
+checked if any interrupts have been asserted on each register before
+checking for spurious interrupts.
+
+Checking each register seperately leads to false positive warnings.
+
+[ tglx: Massaged changelog ]
+
+Fixes: f20cc9b00c7b ("irqchip/qcom: Add IRQ combiner driver")
+Signed-off-by: Agustin Vega-Frias <agustinv@codeaurora.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Jason Cooper <jason@lakedaemon.net>
+Cc: Marc Zyngier <marc.zyngier@arm.com>
+Cc: timur@codeaurora.org
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/1525184090-26143-1-git-send-email-agustinv@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/irqchip/qcom-irq-combiner.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/irqchip/qcom-irq-combiner.c
++++ b/drivers/irqchip/qcom-irq-combiner.c
+@@ -1,4 +1,4 @@
+-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
++/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 and
+@@ -68,7 +68,7 @@ static void combiner_handle_irq(struct i
+               bit = readl_relaxed(combiner->regs[reg].addr);
+               status = bit & combiner->regs[reg].enabled;
+-              if (!status)
++              if (bit && !status)
+                       pr_warn_ratelimited("Unexpected IRQ on CPU%d: (%08x %08lx %p)\n",
+                                           smp_processor_id(), bit,
+                                           combiner->regs[reg].enabled,
diff --git a/queue-4.14/platform-x86-asus-wireless-fix-null-pointer-dereference.patch b/queue-4.14/platform-x86-asus-wireless-fix-null-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..dbe68db
--- /dev/null
@@ -0,0 +1,95 @@
+From 9f0a93de9139c2b0a59299cd36b61564522458f8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= <jprvita@gmail.com>
+Date: Thu, 19 Apr 2018 07:04:34 -0700
+Subject: platform/x86: asus-wireless: Fix NULL pointer dereference
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: João Paulo Rechi Vita <jprvita@gmail.com>
+
+commit 9f0a93de9139c2b0a59299cd36b61564522458f8 upstream.
+
+When the module is removed the led workqueue is destroyed in the remove
+callback, before the led device is unregistered from the led subsystem.
+
+This leads to a NULL pointer derefence when the led device is
+unregistered automatically later as part of the module removal cleanup.
+Bellow is the backtrace showing the problem.
+
+  BUG: unable to handle kernel NULL pointer dereference at           (null)
+  IP: __queue_work+0x8c/0x410
+  PGD 0 P4D 0
+  Oops: 0000 [#1] SMP NOPTI
+  Modules linked in: ccm edac_mce_amd kvm_amd kvm irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel pcbc aesni_intel aes_x86_64 joydev crypto_simd asus_nb_wmi glue_helper uvcvideo snd_hda_codec_conexant snd_hda_codec_generic snd_hda_codec_hdmi snd_hda_intel asus_wmi snd_hda_codec cryptd snd_hda_core sparse_keymap videobuf2_vmalloc arc4 videobuf2_memops snd_hwdep input_leds videobuf2_v4l2 ath9k psmouse videobuf2_core videodev ath9k_common snd_pcm ath9k_hw media fam15h_power ath k10temp snd_timer mac80211 i2c_piix4 r8169 mii mac_hid cfg80211 asus_wireless(-) snd soundcore wmi shpchp 8250_dw ip_tables x_tables amdkfd amd_iommu_v2 amdgpu radeon chash i2c_algo_bit drm_kms_helper syscopyarea serio_raw sysfillrect sysimgblt fb_sys_fops ahci ttm libahci drm video
+  CPU: 3 PID: 2177 Comm: rmmod Not tainted 4.15.0-5-generic #6+dev94.b4287e5bem1-Endless
+  Hardware name: ASUSTeK COMPUTER INC. X555DG/X555DG, BIOS 5.011 05/05/2015
+  RIP: 0010:__queue_work+0x8c/0x410
+  RSP: 0018:ffffbe8cc249fcd8 EFLAGS: 00010086
+  RAX: ffff992ac6810800 RBX: 0000000000000000 RCX: 0000000000000008
+  RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffff992ac6400e18
+  RBP: ffffbe8cc249fd18 R08: ffff992ac6400db0 R09: 0000000000000000
+  R10: 0000000000000040 R11: ffff992ac6400dd8 R12: 0000000000002000
+  R13: ffff992abd762e00 R14: ffff992abd763e38 R15: 000000000001ebe0
+  FS:  00007f318203e700(0000) GS:ffff992aced80000(0000) knlGS:0000000000000000
+  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  CR2: 0000000000000000 CR3: 00000001c720e000 CR4: 00000000001406e0
+  Call Trace:
+   queue_work_on+0x38/0x40
+   led_state_set+0x2c/0x40 [asus_wireless]
+   led_set_brightness_nopm+0x14/0x40
+   led_set_brightness+0x37/0x60
+   led_trigger_set+0xfc/0x1d0
+   led_classdev_unregister+0x32/0xd0
+   devm_led_classdev_release+0x11/0x20
+   release_nodes+0x109/0x1f0
+   devres_release_all+0x3c/0x50
+   device_release_driver_internal+0x16d/0x220
+   driver_detach+0x3f/0x80
+   bus_remove_driver+0x55/0xd0
+   driver_unregister+0x2c/0x40
+   acpi_bus_unregister_driver+0x15/0x20
+   asus_wireless_driver_exit+0x10/0xb7c [asus_wireless]
+   SyS_delete_module+0x1da/0x2b0
+   entry_SYSCALL_64_fastpath+0x24/0x87
+  RIP: 0033:0x7f3181b65fd7
+  RSP: 002b:00007ffe74bcbe18 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0
+  RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f3181b65fd7
+  RDX: 000000000000000a RSI: 0000000000000800 RDI: 0000555ea2559258
+  RBP: 0000555ea25591f0 R08: 00007ffe74bcad91 R09: 000000000000000a
+  R10: 0000000000000000 R11: 0000000000000206 R12: 0000000000000003
+  R13: 00007ffe74bcae00 R14: 0000000000000000 R15: 0000555ea25591f0
+  Code: 01 00 00 02 0f 85 7d 01 00 00 48 63 45 d4 48 c7 c6 00 f4 fa 87 49 8b 9d 08 01 00 00 48 03 1c c6 4c 89 f7 e8 87 fb ff ff 48 85 c0 <48> 8b 3b 0f 84 c5 01 00 00 48 39 f8 0f 84 bc 01 00 00 48 89 c7
+  RIP: __queue_work+0x8c/0x410 RSP: ffffbe8cc249fcd8
+  CR2: 0000000000000000
+  ---[ end trace 7aa4f4a232e9c39c ]---
+
+Unregistering the led device on the remove callback before destroying the
+workqueue avoids this problem.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=196097
+
+Reported-by: Dun Hum <bitter.taste@gmx.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: João Paulo Rechi Vita <jprvita@endlessm.com>
+Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/platform/x86/asus-wireless.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/platform/x86/asus-wireless.c
++++ b/drivers/platform/x86/asus-wireless.c
+@@ -178,8 +178,10 @@ static int asus_wireless_remove(struct a
+ {
+       struct asus_wireless_data *data = acpi_driver_data(adev);
+-      if (data->wq)
++      if (data->wq) {
++              devm_led_classdev_unregister(&adev->dev, &data->led);
+               destroy_workqueue(data->wq);
++      }
+       return 0;
+ }
index b18a41c089ac588a90b14e2436f7bc2c7fdb14cb..6d9a9e8e40bdf7fd050819a8016f1aac771f7dbf 100644 (file)
@@ -30,3 +30,14 @@ iw_cxgb4-atomically-flush-per-qp-hw-cqes.patch
 drm-vmwgfx-fix-a-buffer-object-leak.patch
 drm-bridge-vga-dac-fix-edid-memory-leak.patch
 test_firmware-fix-setting-old-custom-fw-path-back-on-exit-second-try.patch
+errseq-always-report-a-writeback-error-once.patch
+usb-serial-visor-handle-potential-invalid-device-configuration.patch
+usb-dwc3-gadget-fix-list_del-corruption-in-dwc3_ep_dequeue.patch
+usb-accept-bulk-endpoints-with-1024-byte-maxpacket.patch
+usb-serial-option-reimplement-interface-masking.patch
+usb-serial-option-adding-support-for-ublox-r410m.patch
+usb-musb-host-fix-potential-null-pointer-dereference.patch
+usb-musb-trace-fix-null-pointer-dereference-in-musb_g_tx.patch
+platform-x86-asus-wireless-fix-null-pointer-dereference.patch
+irqchip-qcom-fix-check-for-spurious-interrupts.patch
+tracing-fix-bad-use-of-igrab-in-trace_uprobe.c.patch
diff --git a/queue-4.14/tracing-fix-bad-use-of-igrab-in-trace_uprobe.c.patch b/queue-4.14/tracing-fix-bad-use-of-igrab-in-trace_uprobe.c.patch
new file mode 100644 (file)
index 0000000..335c204
--- /dev/null
@@ -0,0 +1,149 @@
+From 0c92c7a3c5d416f47b32c5f20a611dfeca5d5f2e Mon Sep 17 00:00:00 2001
+From: Song Liu <songliubraving@fb.com>
+Date: Mon, 23 Apr 2018 10:21:34 -0700
+Subject: tracing: Fix bad use of igrab in trace_uprobe.c
+
+From: Song Liu <songliubraving@fb.com>
+
+commit 0c92c7a3c5d416f47b32c5f20a611dfeca5d5f2e upstream.
+
+As Miklos reported and suggested:
+
+  This pattern repeats two times in trace_uprobe.c and in
+  kernel/events/core.c as well:
+
+      ret = kern_path(filename, LOOKUP_FOLLOW, &path);
+      if (ret)
+          goto fail_address_parse;
+
+      inode = igrab(d_inode(path.dentry));
+      path_put(&path);
+
+  And it's wrong.  You can only hold a reference to the inode if you
+  have an active ref to the superblock as well (which is normally
+  through path.mnt) or holding s_umount.
+
+  This way unmounting the containing filesystem while the tracepoint is
+  active will give you the "VFS: Busy inodes after unmount..." message
+  and a crash when the inode is finally put.
+
+  Solution: store path instead of inode.
+
+This patch fixes two instances in trace_uprobe.c. struct path is added to
+struct trace_uprobe to keep the inode and containing mount point
+referenced.
+
+Link: http://lkml.kernel.org/r/20180423172135.4050588-1-songliubraving@fb.com
+
+Fixes: f3f096cfedf8 ("tracing: Provide trace events interface for uprobes")
+Fixes: 33ea4b24277b ("perf/core: Implement the 'perf_uprobe' PMU")
+Cc: stable@vger.kernel.org
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Howard McLauchlan <hmclauchlan@fb.com>
+Cc: Josef Bacik <jbacik@fb.com>
+Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
+Acked-by: Miklos Szeredi <mszeredi@redhat.com>
+Reported-by: Miklos Szeredi <miklos@szeredi.hu>
+Signed-off-by: Song Liu <songliubraving@fb.com>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/trace_uprobe.c |   24 ++++++++++--------------
+ 1 file changed, 10 insertions(+), 14 deletions(-)
+
+--- a/kernel/trace/trace_uprobe.c
++++ b/kernel/trace/trace_uprobe.c
+@@ -55,6 +55,7 @@ struct trace_uprobe {
+       struct list_head                list;
+       struct trace_uprobe_filter      filter;
+       struct uprobe_consumer          consumer;
++      struct path                     path;
+       struct inode                    *inode;
+       char                            *filename;
+       unsigned long                   offset;
+@@ -287,7 +288,7 @@ static void free_trace_uprobe(struct tra
+       for (i = 0; i < tu->tp.nr_args; i++)
+               traceprobe_free_probe_arg(&tu->tp.args[i]);
+-      iput(tu->inode);
++      path_put(&tu->path);
+       kfree(tu->tp.call.class->system);
+       kfree(tu->tp.call.name);
+       kfree(tu->filename);
+@@ -361,7 +362,6 @@ end:
+ static int create_trace_uprobe(int argc, char **argv)
+ {
+       struct trace_uprobe *tu;
+-      struct inode *inode;
+       char *arg, *event, *group, *filename;
+       char buf[MAX_EVENT_NAME_LEN];
+       struct path path;
+@@ -369,7 +369,6 @@ static int create_trace_uprobe(int argc,
+       bool is_delete, is_return;
+       int i, ret;
+-      inode = NULL;
+       ret = 0;
+       is_delete = false;
+       is_return = false;
+@@ -435,21 +434,16 @@ static int create_trace_uprobe(int argc,
+       }
+       /* Find the last occurrence, in case the path contains ':' too. */
+       arg = strrchr(argv[1], ':');
+-      if (!arg) {
+-              ret = -EINVAL;
+-              goto fail_address_parse;
+-      }
++      if (!arg)
++              return -EINVAL;
+       *arg++ = '\0';
+       filename = argv[1];
+       ret = kern_path(filename, LOOKUP_FOLLOW, &path);
+       if (ret)
+-              goto fail_address_parse;
+-
+-      inode = igrab(d_inode(path.dentry));
+-      path_put(&path);
++              return ret;
+-      if (!inode || !S_ISREG(inode->i_mode)) {
++      if (!d_is_reg(path.dentry)) {
+               ret = -EINVAL;
+               goto fail_address_parse;
+       }
+@@ -488,7 +482,7 @@ static int create_trace_uprobe(int argc,
+               goto fail_address_parse;
+       }
+       tu->offset = offset;
+-      tu->inode = inode;
++      tu->path = path;
+       tu->filename = kstrdup(filename, GFP_KERNEL);
+       if (!tu->filename) {
+@@ -556,7 +550,7 @@ error:
+       return ret;
+ fail_address_parse:
+-      iput(inode);
++      path_put(&path);
+       pr_info("Failed to parse address or file.\n");
+@@ -935,6 +929,7 @@ probe_event_enable(struct trace_uprobe *
+               goto err_flags;
+       tu->consumer.filter = filter;
++      tu->inode = d_real_inode(tu->path.dentry);
+       ret = uprobe_register(tu->inode, tu->offset, &tu->consumer);
+       if (ret)
+               goto err_buffer;
+@@ -980,6 +975,7 @@ probe_event_disable(struct trace_uprobe
+       WARN_ON(!uprobe_filter_is_empty(&tu->filter));
+       uprobe_unregister(tu->inode, tu->offset, &tu->consumer);
++      tu->inode = NULL;
+       tu->tp.flags &= file ? ~TP_FLAG_TRACE : ~TP_FLAG_PROFILE;
+       uprobe_buffer_disable();
diff --git a/queue-4.14/usb-accept-bulk-endpoints-with-1024-byte-maxpacket.patch b/queue-4.14/usb-accept-bulk-endpoints-with-1024-byte-maxpacket.patch
new file mode 100644 (file)
index 0000000..a48a262
--- /dev/null
@@ -0,0 +1,42 @@
+From fb5ee84ea72c5f1b6cabdd1c9d6e8648995ca7c6 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Thu, 3 May 2018 11:04:48 -0400
+Subject: USB: Accept bulk endpoints with 1024-byte maxpacket
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit fb5ee84ea72c5f1b6cabdd1c9d6e8648995ca7c6 upstream.
+
+Some non-compliant high-speed USB devices have bulk endpoints with a
+1024-byte maxpacket size.  Although such endpoints don't work with
+xHCI host controllers, they do work with EHCI controllers.  We used to
+accept these invalid sizes (with a warning), but we no longer do
+because of an unintentional change introduced by commit aed9d65ac327
+("USB: validate wMaxPacketValue entries in endpoint descriptors").
+
+This patch restores the old behavior, so that people with these
+peculiar devices can use them without patching their kernels by hand.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Suggested-by: Elvinas <elvinas@veikia.lt>
+Fixes: aed9d65ac327 ("USB: validate wMaxPacketValue entries in endpoint descriptors")
+CC: <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/config.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -191,7 +191,9 @@ static const unsigned short full_speed_m
+ static const unsigned short high_speed_maxpacket_maxes[4] = {
+       [USB_ENDPOINT_XFER_CONTROL] = 64,
+       [USB_ENDPOINT_XFER_ISOC] = 1024,
+-      [USB_ENDPOINT_XFER_BULK] = 512,
++
++      /* Bulk should be 512, but some devices use 1024: we will warn below */
++      [USB_ENDPOINT_XFER_BULK] = 1024,
+       [USB_ENDPOINT_XFER_INT] = 1024,
+ };
+ static const unsigned short super_speed_maxpacket_maxes[4] = {
diff --git a/queue-4.14/usb-dwc3-gadget-fix-list_del-corruption-in-dwc3_ep_dequeue.patch b/queue-4.14/usb-dwc3-gadget-fix-list_del-corruption-in-dwc3_ep_dequeue.patch
new file mode 100644 (file)
index 0000000..05101cd
--- /dev/null
@@ -0,0 +1,44 @@
+From 96bd39df29c29d348d65311e5954c0b7d3a2a790 Mon Sep 17 00:00:00 2001
+From: Mayank Rana <mrana@codeaurora.org>
+Date: Fri, 23 Mar 2018 10:05:33 -0700
+Subject: usb: dwc3: gadget: Fix list_del corruption in dwc3_ep_dequeue
+
+From: Mayank Rana <mrana@codeaurora.org>
+
+commit 96bd39df29c29d348d65311e5954c0b7d3a2a790 upstream.
+
+dwc3_ep_dequeue() waits for completion of End Transfer command using
+wait_event_lock_irq(), which will release the dwc3->lock while waiting
+and reacquire after completion. This allows a potential race condition
+with ep_disable() which also removes all requests from started_list
+and pending_list.
+
+The check for NULL r->trb should catch this but currently it exits to
+the wrong 'out1' label which calls dwc3_gadget_giveback(). Since its
+list entry was already removed, if CONFIG_DEBUG_LIST is enabled a
+'list_del corruption' bug is thrown since its next/prev pointers are
+already LIST_POISON1/2. If r->trb is NULL it should simply exit to
+'out0'.
+
+Fixes: cf3113d893d4 ("usb: dwc3: gadget: properly increment dequeue pointer on ep_dequeue")
+Cc: stable@vger.kernel.org # v4.12+
+Signed-off-by: Mayank Rana <mrana@codeaurora.org>
+Signed-off-by: Jack Pham <jackp@codeaurora.org>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/gadget.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1444,7 +1444,7 @@ static int dwc3_gadget_ep_dequeue(struct
+                                       dwc->lock);
+                       if (!r->trb)
+-                              goto out1;
++                              goto out0;
+                       if (r->num_pending_sgs) {
+                               struct dwc3_trb *trb;
diff --git a/queue-4.14/usb-musb-host-fix-potential-null-pointer-dereference.patch b/queue-4.14/usb-musb-host-fix-potential-null-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..6fd4872
--- /dev/null
@@ -0,0 +1,38 @@
+From 2b63f1329df2cd814c1f8353fae4853ace6521d1 Mon Sep 17 00:00:00 2001
+From: Bin Liu <b-liu@ti.com>
+Date: Mon, 30 Apr 2018 11:20:53 -0500
+Subject: usb: musb: host: fix potential NULL pointer dereference
+
+From: Bin Liu <b-liu@ti.com>
+
+commit 2b63f1329df2cd814c1f8353fae4853ace6521d1 upstream.
+
+musb_start_urb() doesn't check the pass-in parameter if it is NULL.  But
+in musb_bulk_nak_timeout() the parameter passed to musb_start_urb() is
+returned from first_qh(), which could be NULL.
+
+So wrap the musb_start_urb() call here with a if condition check to
+avoid the potential NULL pointer dereference.
+
+Fixes: f283862f3b5c ("usb: musb: NAK timeout scheme on bulk TX endpoint")
+Cc: stable@vger.kernel.org # v3.7+
+Signed-off-by: Bin Liu <b-liu@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/musb/musb_host.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/musb_host.c
++++ b/drivers/usb/musb/musb_host.c
+@@ -1023,7 +1023,9 @@ static void musb_bulk_nak_timeout(struct
+                       /* set tx_reinit and schedule the next qh */
+                       ep->tx_reinit = 1;
+               }
+-              musb_start_urb(musb, is_in, next_qh);
++
++              if (next_qh)
++                      musb_start_urb(musb, is_in, next_qh);
+       }
+ }
diff --git a/queue-4.14/usb-musb-trace-fix-null-pointer-dereference-in-musb_g_tx.patch b/queue-4.14/usb-musb-trace-fix-null-pointer-dereference-in-musb_g_tx.patch
new file mode 100644 (file)
index 0000000..aef1b6c
--- /dev/null
@@ -0,0 +1,44 @@
+From 9aea9b6cc78d2b99b23d84fb2e0bc6e464c6569e Mon Sep 17 00:00:00 2001
+From: Bin Liu <b-liu@ti.com>
+Date: Mon, 30 Apr 2018 11:20:54 -0500
+Subject: usb: musb: trace: fix NULL pointer dereference in musb_g_tx()
+
+From: Bin Liu <b-liu@ti.com>
+
+commit 9aea9b6cc78d2b99b23d84fb2e0bc6e464c6569e upstream.
+
+The usb_request pointer could be NULL in musb_g_tx(), where the
+tracepoint call would trigger the NULL pointer dereference failure when
+parsing the members of the usb_request pointer.
+
+Move the tracepoint call to where the usb_request pointer is already
+checked to solve the issue.
+
+Fixes: fc78003e5345 ("usb: musb: gadget: add usb-request tracepoints")
+Cc: stable@vger.kernel.org # v4.8+
+Signed-off-by: Bin Liu <b-liu@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/musb/musb_gadget.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -442,7 +442,6 @@ void musb_g_tx(struct musb *musb, u8 epn
+       req = next_request(musb_ep);
+       request = &req->request;
+-      trace_musb_req_tx(req);
+       csr = musb_readw(epio, MUSB_TXCSR);
+       musb_dbg(musb, "<== %s, txcsr %04x", musb_ep->end_point.name, csr);
+@@ -481,6 +480,8 @@ void musb_g_tx(struct musb *musb, u8 epn
+               u8      is_dma = 0;
+               bool    short_packet = false;
++              trace_musb_req_tx(req);
++
+               if (dma && (csr & MUSB_TXCSR_DMAENAB)) {
+                       is_dma = 1;
+                       csr |= MUSB_TXCSR_P_WZC_BITS;
diff --git a/queue-4.14/usb-serial-option-adding-support-for-ublox-r410m.patch b/queue-4.14/usb-serial-option-adding-support-for-ublox-r410m.patch
new file mode 100644 (file)
index 0000000..8827d4a
--- /dev/null
@@ -0,0 +1,52 @@
+From 4205cb01f6e9ef2ae6daa7be4e8ac1edeb4c9d64 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?SZ=20Lin=20=28=E6=9E=97=E4=B8=8A=E6=99=BA=29?=
+ <sz.lin@moxa.com>
+Date: Thu, 26 Apr 2018 14:28:31 +0800
+Subject: USB: serial: option: adding support for ublox R410M
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: SZ Lin (林上智) <sz.lin@moxa.com>
+
+commit 4205cb01f6e9ef2ae6daa7be4e8ac1edeb4c9d64 upstream.
+
+This patch adds support for ublox R410M PID 0x90b2 USB modem to option
+driver, this module supports LTE Cat M1 / NB1.
+
+Interface layout:
+0: QCDM/DIAG
+1: ADB
+2: AT
+3: RMNET
+
+Signed-off-by: SZ Lin (林上智) <sz.lin@moxa.com>
+Cc: stable <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 |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -236,6 +236,8 @@ static void option_instat_callback(struc
+ /* These Quectel products use Qualcomm's vendor ID */
+ #define QUECTEL_PRODUCT_UC20                  0x9003
+ #define QUECTEL_PRODUCT_UC15                  0x9090
++/* These u-blox products use Qualcomm's vendor ID */
++#define UBLOX_PRODUCT_R410M                   0x90b2
+ /* These Yuga products use Qualcomm's vendor ID */
+ #define YUGA_PRODUCT_CLM920_NC5                       0x9625
+@@ -1068,6 +1070,9 @@ static const struct usb_device_id option
+       /* Yuga products use Qualcomm vendor ID */
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, YUGA_PRODUCT_CLM920_NC5),
+         .driver_info = RSVD(1) | RSVD(4) },
++      /* u-blox products using Qualcomm vendor ID */
++      { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R410M),
++        .driver_info = RSVD(1) | RSVD(3) },
+       /* Quectel products using Quectel vendor ID */
+       { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21),
+         .driver_info = RSVD(4) },
diff --git a/queue-4.14/usb-serial-option-reimplement-interface-masking.patch b/queue-4.14/usb-serial-option-reimplement-interface-masking.patch
new file mode 100644 (file)
index 0000000..d198945
--- /dev/null
@@ -0,0 +1,857 @@
+From c3a65808f04a8426481b63a4fbd9392f009f6330 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 7 Mar 2018 17:40:48 +0100
+Subject: USB: serial: option: reimplement interface masking
+
+From: Johan Hovold <johan@kernel.org>
+
+commit c3a65808f04a8426481b63a4fbd9392f009f6330 upstream.
+
+Reimplement interface masking using device flags stored directly in the
+device-id table. This will make it easier to add and maintain device-id
+entries by using a more compact and readable notation compared to the
+current implementation (which manages pairs of masks in separate
+blacklist structs).
+
+Two convenience macros are used to flag an interface as either reserved
+or as not supporting modem-control requests:
+
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
+         .driver_info = NCTRL(0) | RSVD(3) },
+
+For now, we limit the highest maskable interface number to seven, which
+allows for (up to 16) additional device flags to be added later should
+need arise.
+
+Note that this will likely need to be backported to stable in order to
+make future device-id backports more manageable.
+
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c |  446 ++++++++++++++------------------------------
+ 1 file changed, 152 insertions(+), 294 deletions(-)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -551,151 +551,15 @@ static void option_instat_callback(struc
+ #define WETELECOM_PRODUCT_6802                        0x6802
+ #define WETELECOM_PRODUCT_WMD300              0x6803
+-struct option_blacklist_info {
+-      /* bitmask of interface numbers blacklisted for send_setup */
+-      const unsigned long sendsetup;
+-      /* bitmask of interface numbers that are reserved */
+-      const unsigned long reserved;
+-};
+-
+-static const struct option_blacklist_info four_g_w14_blacklist = {
+-      .sendsetup = BIT(0) | BIT(1),
+-};
+-
+-static const struct option_blacklist_info four_g_w100_blacklist = {
+-      .sendsetup = BIT(1) | BIT(2),
+-      .reserved = BIT(3),
+-};
+-
+-static const struct option_blacklist_info alcatel_x200_blacklist = {
+-      .sendsetup = BIT(0) | BIT(1),
+-      .reserved = BIT(4),
+-};
+-
+-static const struct option_blacklist_info zte_0037_blacklist = {
+-      .sendsetup = BIT(0) | BIT(1),
+-};
+-
+-static const struct option_blacklist_info zte_k3765_z_blacklist = {
+-      .sendsetup = BIT(0) | BIT(1) | BIT(2),
+-      .reserved = BIT(4),
+-};
+-
+-static const struct option_blacklist_info zte_ad3812_z_blacklist = {
+-      .sendsetup = BIT(0) | BIT(1) | BIT(2),
+-};
+-
+-static const struct option_blacklist_info zte_mc2718_z_blacklist = {
+-      .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4),
+-};
+-
+-static const struct option_blacklist_info zte_mc2716_z_blacklist = {
+-      .sendsetup = BIT(1) | BIT(2) | BIT(3),
+-};
+-
+-static const struct option_blacklist_info zte_me3620_mbim_blacklist = {
+-      .reserved = BIT(2) | BIT(3) | BIT(4),
+-};
+-
+-static const struct option_blacklist_info zte_me3620_xl_blacklist = {
+-      .reserved = BIT(3) | BIT(4) | BIT(5),
+-};
+-
+-static const struct option_blacklist_info zte_zm8620_x_blacklist = {
+-      .reserved = BIT(3) | BIT(4) | BIT(5),
+-};
+-
+-static const struct option_blacklist_info huawei_cdc12_blacklist = {
+-      .reserved = BIT(1) | BIT(2),
+-};
+-
+-static const struct option_blacklist_info net_intf0_blacklist = {
+-      .reserved = BIT(0),
+-};
+-
+-static const struct option_blacklist_info net_intf1_blacklist = {
+-      .reserved = BIT(1),
+-};
+-
+-static const struct option_blacklist_info net_intf2_blacklist = {
+-      .reserved = BIT(2),
+-};
+-
+-static const struct option_blacklist_info net_intf3_blacklist = {
+-      .reserved = BIT(3),
+-};
+-
+-static const struct option_blacklist_info net_intf4_blacklist = {
+-      .reserved = BIT(4),
+-};
+-
+-static const struct option_blacklist_info net_intf5_blacklist = {
+-      .reserved = BIT(5),
+-};
+-
+-static const struct option_blacklist_info net_intf6_blacklist = {
+-      .reserved = BIT(6),
+-};
+-
+-static const struct option_blacklist_info zte_mf626_blacklist = {
+-      .sendsetup = BIT(0) | BIT(1),
+-      .reserved = BIT(4),
+-};
+-
+-static const struct option_blacklist_info zte_1255_blacklist = {
+-      .reserved = BIT(3) | BIT(4),
+-};
+-
+-static const struct option_blacklist_info simcom_sim7100e_blacklist = {
+-      .reserved = BIT(5) | BIT(6),
+-};
+-
+-static const struct option_blacklist_info telit_me910_blacklist = {
+-      .sendsetup = BIT(0),
+-      .reserved = BIT(1) | BIT(3),
+-};
+-
+-static const struct option_blacklist_info telit_me910_dual_modem_blacklist = {
+-      .sendsetup = BIT(0),
+-      .reserved = BIT(3),
+-};
+-
+-static const struct option_blacklist_info telit_le910_blacklist = {
+-      .sendsetup = BIT(0),
+-      .reserved = BIT(1) | BIT(2),
+-};
+-
+-static const struct option_blacklist_info telit_le920_blacklist = {
+-      .sendsetup = BIT(0),
+-      .reserved = BIT(1) | BIT(5),
+-};
+-
+-static const struct option_blacklist_info telit_le920a4_blacklist_1 = {
+-      .sendsetup = BIT(0),
+-      .reserved = BIT(1),
+-};
+-
+-static const struct option_blacklist_info telit_le922_blacklist_usbcfg0 = {
+-      .sendsetup = BIT(2),
+-      .reserved = BIT(0) | BIT(1) | BIT(3),
+-};
+-static const struct option_blacklist_info telit_le922_blacklist_usbcfg3 = {
+-      .sendsetup = BIT(0),
+-      .reserved = BIT(1) | BIT(2) | BIT(3),
+-};
++/* Device flags */
+-static const struct option_blacklist_info cinterion_rmnet2_blacklist = {
+-      .reserved = BIT(4) | BIT(5),
+-};
++/* Interface does not support modem-control requests */
++#define NCTRL(ifnum)  ((BIT(ifnum) & 0xff) << 8)
+-static const struct option_blacklist_info yuga_clm920_nc5_blacklist = {
+-      .reserved = BIT(1) | BIT(4),
+-};
++/* Interface is reserved */
++#define RSVD(ifnum)   ((BIT(ifnum) & 0xff) << 0)
+-static const struct option_blacklist_info quectel_ep06_blacklist = {
+-      .reserved = BIT(4) | BIT(5),
+-};
+ static const struct usb_device_id option_ids[] = {
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
+@@ -729,26 +593,26 @@ static const struct usb_device_id option
+       { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) },
+       { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) },
+       { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c1f, USB_CLASS_COMM, 0x02, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
++        .driver_info = RSVD(1) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S6, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
++        .driver_info = RSVD(1) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t) &net_intf2_blacklist },
++        .driver_info = RSVD(2) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
++        .driver_info = RSVD(1) | RSVD(2) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
++        .driver_info = RSVD(1) | RSVD(2) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x14ac, 0xff, 0xff, 0xff),    /* Huawei E1820 */
+-              .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
++        .driver_info = RSVD(1) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
++        .driver_info = RSVD(1) | RSVD(2) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x01) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x02) },
+@@ -1193,67 +1057,67 @@ static const struct usb_device_id option
+       { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
+       { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, 0x6001, 0xff, 0xff, 0xff), /* 4G LTE usb-modem U901 */
+-        .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
++        .driver_info = RSVD(3) },
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
+       /* Quectel products using Qualcomm vendor ID */
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)},
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       /* Yuga products use Qualcomm vendor ID */
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, YUGA_PRODUCT_CLM920_NC5),
+-        .driver_info = (kernel_ulong_t)&yuga_clm920_nc5_blacklist },
++        .driver_info = RSVD(1) | RSVD(4) },
+       /* Quectel products using Quectel vendor ID */
+       { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC25),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06),
+-        .driver_info = (kernel_ulong_t)&quectel_ep06_blacklist },
++        .driver_info = RSVD(4) | RSVD(5) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
+-        .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
++        .driver_info = RSVD(0) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6004) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6005) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CGU_628A) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHE_628S),
+-        .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
++        .driver_info = RSVD(0) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_301),
+-        .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
++        .driver_info = RSVD(0) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_628),
+-        .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
++        .driver_info = RSVD(0) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_628S) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU_680) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU_685A) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_720S),
+-        .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
++        .driver_info = RSVD(0) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7002),
+-        .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
++        .driver_info = RSVD(0) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_629K),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7004),
+-        .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
++        .driver_info = RSVD(3) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7005) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CGU_629),
+-        .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
++        .driver_info = RSVD(5) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_629S),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_720I),
+-        .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
++        .driver_info = RSVD(0) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7212),
+-        .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
++        .driver_info = RSVD(0) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7213),
+-        .driver_info = (kernel_ulong_t)&net_intf0_blacklist },
++        .driver_info = RSVD(0) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7251),
+-        .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
++        .driver_info = RSVD(1) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7252),
+-        .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
++        .driver_info = RSVD(1) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7253),
+-        .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
++        .driver_info = RSVD(1) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) },
+@@ -1261,38 +1125,38 @@ static const struct usb_device_id option
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0),
+-              .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 },
++        .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1),
+-              .driver_info = (kernel_ulong_t)&telit_le910_blacklist },
++        .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG2),
+-              .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
++        .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG3),
+-              .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
++        .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG5, 0xff),
+-              .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 },
++        .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
+-              .driver_info = (kernel_ulong_t)&telit_me910_blacklist },
++        .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
+-              .driver_info = (kernel_ulong_t)&telit_me910_dual_modem_blacklist },
++        .driver_info = NCTRL(0) | RSVD(3) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910),
+-              .driver_info = (kernel_ulong_t)&telit_le910_blacklist },
++        .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4),
+-              .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
++        .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
+-              .driver_info = (kernel_ulong_t)&telit_le920_blacklist },
++        .driver_info = NCTRL(0) | RSVD(1) | RSVD(5) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1207) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1208),
+-              .driver_info = (kernel_ulong_t)&telit_le920a4_blacklist_1 },
++        .driver_info = NCTRL(0) | RSVD(1) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1211),
+-              .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
++        .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1212),
+-              .driver_info = (kernel_ulong_t)&telit_le920a4_blacklist_1 },
++        .driver_info = NCTRL(0) | RSVD(1) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1213, 0xff) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1214),
+-              .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
++        .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
++        .driver_info = RSVD(1) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0004, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0005, 0xff, 0xff, 0xff) },
+@@ -1308,58 +1172,58 @@ static const struct usb_device_id option
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0010, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0011, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
++        .driver_info = RSVD(1) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
++        .driver_info = RSVD(3) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0018, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
++        .driver_info = RSVD(3) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0020, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0021, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0022, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0023, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
++        .driver_info = RSVD(1) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) },
+-      { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff,
+-        0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_mf626_blacklist },
++      { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, 0xff, 0xff),
++        .driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0034, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0037, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&zte_0037_blacklist },
++        .driver_info = NCTRL(0) | NCTRL(1) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0038, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0039, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0040, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0042, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0043, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0044, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0048, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0049, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
++        .driver_info = RSVD(5) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0050, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
++        .driver_info = RSVD(1) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0056, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0064, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0065, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) },
+@@ -1384,26 +1248,26 @@ static const struct usb_device_id option
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0096, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0097, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
++        .driver_info = RSVD(5) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
++        .driver_info = RSVD(5) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
++        .driver_info = RSVD(5) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
++        .driver_info = RSVD(5) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf6_blacklist },
++        .driver_info = RSVD(6) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
++        .driver_info = RSVD(5) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0135, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0136, 0xff, 0xff, 0xff) },
+@@ -1419,50 +1283,50 @@ static const struct usb_device_id option
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
++        .driver_info = RSVD(5) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
++        .driver_info = RSVD(3) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0164, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0189, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0191, 0xff, 0xff, 0xff), /* ZTE EuFi890 */
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0196, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0197, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0199, 0xff, 0xff, 0xff), /* ZTE MF820S */
+-        .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
++        .driver_info = RSVD(1) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0200, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0201, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0254, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0257, 0xff, 0xff, 0xff), /* ZTE MF821 */
+-        .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
++        .driver_info = RSVD(3) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0265, 0xff, 0xff, 0xff), /* ONDA MT8205 */
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0284, 0xff, 0xff, 0xff), /* ZTE MF880 */
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0317, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0330, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0395, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0412, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G */
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1018, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1021, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf2_blacklist },
++        .driver_info = RSVD(2) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) },
+@@ -1579,23 +1443,23 @@ static const struct usb_device_id option
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&zte_1255_blacklist },
++        .driver_info = RSVD(3) | RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) },
+@@ -1610,7 +1474,7 @@ static const struct usb_device_id option
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1268, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1269, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1270, 0xff, 0xff, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
++        .driver_info = RSVD(5) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1271, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1272, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1273, 0xff, 0xff, 0xff) },
+@@ -1646,17 +1510,17 @@ static const struct usb_device_id option
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1303, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1333, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf2_blacklist },
++        .driver_info = RSVD(2) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf2_blacklist },
++        .driver_info = RSVD(2) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1424, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf2_blacklist },
++        .driver_info = RSVD(2) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1425, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf2_blacklist },
++        .driver_info = RSVD(2) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff),  /* ZTE MF91 */
+-              .driver_info = (kernel_ulong_t)&net_intf2_blacklist },
++        .driver_info = RSVD(2) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff),  /* Telewell TW-LTE 4G v2 */
+-              .driver_info = (kernel_ulong_t)&net_intf2_blacklist },
++        .driver_info = RSVD(2) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1533, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) },
+@@ -1674,8 +1538,8 @@ static const struct usb_device_id option
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1596, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1598, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1600, 0xff, 0xff, 0xff) },
+-      { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff,
+-        0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist },
++      { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff),
++        .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */
+@@ -1686,20 +1550,20 @@ static const struct usb_device_id option
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
++        .driver_info = RSVD(1) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
++        .driver_info = RSVD(3) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
++        .driver_info = RSVD(5) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
++        .driver_info = RSVD(3) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
++        .driver_info = RSVD(3) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff42, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff43, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff44, 0xff, 0xff, 0xff) },
+@@ -1851,19 +1715,19 @@ static const struct usb_device_id option
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff),
+-       .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist },
++       .driver_info = NCTRL(1) | NCTRL(2) | NCTRL(3) | NCTRL(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff),
+-       .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist },
++       .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff),
+-       .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist },
++       .driver_info = NCTRL(1) | NCTRL(2) | NCTRL(3) },
+       { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_L),
+-       .driver_info = (kernel_ulong_t)&zte_me3620_xl_blacklist },
++       .driver_info = RSVD(3) | RSVD(4) | RSVD(5) },
+       { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_MBIM),
+-       .driver_info = (kernel_ulong_t)&zte_me3620_mbim_blacklist },
++       .driver_info = RSVD(2) | RSVD(3) | RSVD(4) },
+       { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_X),
+-       .driver_info = (kernel_ulong_t)&zte_me3620_xl_blacklist },
++       .driver_info = RSVD(3) | RSVD(4) | RSVD(5) },
+       { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ZM8620_X),
+-       .driver_info = (kernel_ulong_t)&zte_zm8620_x_blacklist },
++       .driver_info = RSVD(3) | RSVD(4) | RSVD(5) },
+       { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) },
+       { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) },
+       { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) },
+@@ -1883,37 +1747,34 @@ static const struct usb_device_id option
+       { USB_DEVICE(ALINK_VENDOR_ID, ALINK_PRODUCT_PH300) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
+       { USB_DEVICE(ALINK_VENDOR_ID, SIMCOM_PRODUCT_SIM7100E),
+-        .driver_info = (kernel_ulong_t)&simcom_sim7100e_blacklist },
++        .driver_info = RSVD(5) | RSVD(6) },
+       { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
+-        .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist
+-      },
++        .driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) },
+       { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D),
+-        .driver_info = (kernel_ulong_t)&net_intf6_blacklist },
++        .driver_info = RSVD(6) },
+       { USB_DEVICE(ALCATEL_VENDOR_ID, 0x0052),
+-        .driver_info = (kernel_ulong_t)&net_intf6_blacklist },
++        .driver_info = RSVD(6) },
+       { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b6),
+-        .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
++        .driver_info = RSVD(3) },
+       { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b7),
+-        .driver_info = (kernel_ulong_t)&net_intf5_blacklist },
++        .driver_info = RSVD(5) },
+       { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L100V),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L800MA),
+-        .driver_info = (kernel_ulong_t)&net_intf2_blacklist },
++        .driver_info = RSVD(2) },
+       { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
+       { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
+       { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
+-        .driver_info = (kernel_ulong_t)&four_g_w14_blacklist
+-      },
++        .driver_info = NCTRL(0) | NCTRL(1) },
+       { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W100),
+-        .driver_info = (kernel_ulong_t)&four_g_w100_blacklist
+-      },
++        .driver_info = NCTRL(1) | NCTRL(2) | RSVD(3) },
+       {USB_DEVICE(LONGCHEER_VENDOR_ID, FUJISOFT_PRODUCT_FS040U),
+-       .driver_info = (kernel_ulong_t)&net_intf3_blacklist},
++       .driver_info = RSVD(3)},
+       { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, SPEEDUP_PRODUCT_SU9800, 0xff) },
+       { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9801, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
++        .driver_info = RSVD(3) },
+       { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9803, 0xff),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) },
+       { USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) },
+       { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) },
+@@ -1939,14 +1800,14 @@ static const struct usb_device_id option
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX, 0xff) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_2RMNET, 0xff),
+-              .driver_info = (kernel_ulong_t)&cinterion_rmnet2_blacklist },
++        .driver_info = RSVD(4) | RSVD(5) },
+       { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_AUDIO, 0xff),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_2RMNET, 0xff) },
+       { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) },
+@@ -1956,20 +1817,20 @@ static const struct usb_device_id option
+       { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 enumerates with Siemens or Cinterion VID depending on FW revision */
+       { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD140),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) },
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD155),
+-              .driver_info = (kernel_ulong_t)&net_intf6_blacklist },
++        .driver_info = RSVD(6) },
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200),
+-              .driver_info = (kernel_ulong_t)&net_intf6_blacklist },
++        .driver_info = RSVD(6) },
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD160),
+-              .driver_info = (kernel_ulong_t)&net_intf6_blacklist },
++        .driver_info = RSVD(6) },
+       { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD500),
+-              .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
+       { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/
+       { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) },
+@@ -2046,9 +1907,9 @@ static const struct usb_device_id option
+       { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) },
+       { USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 0xff, 0x00, 0x00) },      /* TP-Link LTE Module */
+       { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180),
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000),                                 /* TP-Link MA260 */
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) },
+       { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d01, 0xff) },                   /* D-Link DWM-156 (variant) */
+       { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d02, 0xff) },
+@@ -2056,9 +1917,9 @@ static const struct usb_device_id option
+       { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) },                   /* D-Link DWM-158 */
+       { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d0e, 0xff) },                   /* D-Link DWM-157 C1 */
+       { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff),                     /* D-Link DWM-221 B1 */
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff),                     /* D-Link DWM-222 */
+-        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++        .driver_info = RSVD(4) },
+       { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */
+@@ -2118,7 +1979,7 @@ static int option_probe(struct usb_seria
+       struct usb_interface_descriptor *iface_desc =
+                               &serial->interface->cur_altsetting->desc;
+       struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
+-      const struct option_blacklist_info *blacklist;
++      unsigned long device_flags = id->driver_info;
+       /* Never bind to the CD-Rom emulation interface */
+       if (iface_desc->bInterfaceClass == 0x08)
+@@ -2129,9 +1990,7 @@ static int option_probe(struct usb_seria
+        * the same class/subclass/protocol as the serial interfaces.  Look at
+        * the Windows driver .INF files for reserved interface numbers.
+        */
+-      blacklist = (void *)id->driver_info;
+-      if (blacklist && test_bit(iface_desc->bInterfaceNumber,
+-                                              &blacklist->reserved))
++      if (device_flags & RSVD(iface_desc->bInterfaceNumber))
+               return -ENODEV;
+       /*
+        * Don't bind network interface on Samsung GT-B3730, it is handled by
+@@ -2142,8 +2001,8 @@ static int option_probe(struct usb_seria
+           iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
+               return -ENODEV;
+-      /* Store the blacklist info so we can use it during attach. */
+-      usb_set_serial_data(serial, (void *)blacklist);
++      /* Store the device flags so we can use them during attach. */
++      usb_set_serial_data(serial, (void *)device_flags);
+       return 0;
+ }
+@@ -2151,22 +2010,21 @@ static int option_probe(struct usb_seria
+ static int option_attach(struct usb_serial *serial)
+ {
+       struct usb_interface_descriptor *iface_desc;
+-      const struct option_blacklist_info *blacklist;
+       struct usb_wwan_intf_private *data;
++      unsigned long device_flags;
+       data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+-      /* Retrieve blacklist info stored at probe. */
+-      blacklist = usb_get_serial_data(serial);
++      /* Retrieve device flags stored at probe. */
++      device_flags = (unsigned long)usb_get_serial_data(serial);
+       iface_desc = &serial->interface->cur_altsetting->desc;
+-      if (!blacklist || !test_bit(iface_desc->bInterfaceNumber,
+-                                              &blacklist->sendsetup)) {
++      if (!(device_flags & NCTRL(iface_desc->bInterfaceNumber)))
+               data->use_send_setup = 1;
+-      }
++
+       spin_lock_init(&data->susp_lock);
+       usb_set_serial_data(serial, data);
diff --git a/queue-4.14/usb-serial-visor-handle-potential-invalid-device-configuration.patch b/queue-4.14/usb-serial-visor-handle-potential-invalid-device-configuration.patch
new file mode 100644 (file)
index 0000000..3861d58
--- /dev/null
@@ -0,0 +1,115 @@
+From 4842ed5bfcb9daf6660537d70503c18d38dbdbb8 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Sun, 29 Apr 2018 17:41:55 +0200
+Subject: USB: serial: visor: handle potential invalid device configuration
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+commit 4842ed5bfcb9daf6660537d70503c18d38dbdbb8 upstream.
+
+If we get an invalid device configuration from a palm 3 type device, we
+might incorrectly parse things, and we have the potential to crash in
+"interesting" ways.
+
+Fix this up by verifying the size of the configuration passed to us by
+the device, and only if it is correct, will we handle it.
+
+Note that this also fixes an information leak of slab data.
+
+Reported-by: Andrey Konovalov <andreyknvl@google.com>
+Reviewed-by: Andrey Konovalov <andreyknvl@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ johan: add comment about the info leak ]
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/visor.c |   69 ++++++++++++++++++++++-----------------------
+ 1 file changed, 35 insertions(+), 34 deletions(-)
+
+--- a/drivers/usb/serial/visor.c
++++ b/drivers/usb/serial/visor.c
+@@ -338,47 +338,48 @@ static int palm_os_3_probe(struct usb_se
+               goto exit;
+       }
+-      if (retval == sizeof(*connection_info)) {
+-                      connection_info = (struct visor_connection_info *)
+-                                                      transfer_buffer;
+-
+-              num_ports = le16_to_cpu(connection_info->num_ports);
+-              for (i = 0; i < num_ports; ++i) {
+-                      switch (
+-                         connection_info->connections[i].port_function_id) {
+-                      case VISOR_FUNCTION_GENERIC:
+-                              string = "Generic";
+-                              break;
+-                      case VISOR_FUNCTION_DEBUGGER:
+-                              string = "Debugger";
+-                              break;
+-                      case VISOR_FUNCTION_HOTSYNC:
+-                              string = "HotSync";
+-                              break;
+-                      case VISOR_FUNCTION_CONSOLE:
+-                              string = "Console";
+-                              break;
+-                      case VISOR_FUNCTION_REMOTE_FILE_SYS:
+-                              string = "Remote File System";
+-                              break;
+-                      default:
+-                              string = "unknown";
+-                              break;
+-                      }
+-                      dev_info(dev, "%s: port %d, is for %s use\n",
+-                              serial->type->description,
+-                              connection_info->connections[i].port, string);
+-              }
++      if (retval != sizeof(*connection_info)) {
++              dev_err(dev, "Invalid connection information received from device\n");
++              retval = -ENODEV;
++              goto exit;
+       }
+-      /*
+-      * Handle devices that report invalid stuff here.
+-      */
++
++      connection_info = (struct visor_connection_info *)transfer_buffer;
++
++      num_ports = le16_to_cpu(connection_info->num_ports);
++
++      /* Handle devices that report invalid stuff here. */
+       if (num_ports == 0 || num_ports > 2) {
+               dev_warn(dev, "%s: No valid connect info available\n",
+                       serial->type->description);
+               num_ports = 2;
+       }
++      for (i = 0; i < num_ports; ++i) {
++              switch (connection_info->connections[i].port_function_id) {
++              case VISOR_FUNCTION_GENERIC:
++                      string = "Generic";
++                      break;
++              case VISOR_FUNCTION_DEBUGGER:
++                      string = "Debugger";
++                      break;
++              case VISOR_FUNCTION_HOTSYNC:
++                      string = "HotSync";
++                      break;
++              case VISOR_FUNCTION_CONSOLE:
++                      string = "Console";
++                      break;
++              case VISOR_FUNCTION_REMOTE_FILE_SYS:
++                      string = "Remote File System";
++                      break;
++              default:
++                      string = "unknown";
++                      break;
++              }
++              dev_info(dev, "%s: port %d, is for %s use\n",
++                      serial->type->description,
++                      connection_info->connections[i].port, string);
++      }
+       dev_info(dev, "%s: Number of ports: %d\n", serial->type->description,
+               num_ports);