]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 May 2018 07:23:40 +0000 (09:23 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 May 2018 07:23:40 +0000 (09:23 +0200)
added patches:
platform-x86-asus-wireless-fix-null-pointer-dereference.patch
s390-facilites-use-stfle_fac_list-array-size-for-max_facility_bit.patch
usb-accept-bulk-endpoints-with-1024-byte-maxpacket.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

queue-4.9/platform-x86-asus-wireless-fix-null-pointer-dereference.patch [new file with mode: 0644]
queue-4.9/s390-facilites-use-stfle_fac_list-array-size-for-max_facility_bit.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/usb-accept-bulk-endpoints-with-1024-byte-maxpacket.patch [new file with mode: 0644]
queue-4.9/usb-musb-host-fix-potential-null-pointer-dereference.patch [new file with mode: 0644]
queue-4.9/usb-musb-trace-fix-null-pointer-dereference-in-musb_g_tx.patch [new file with mode: 0644]
queue-4.9/usb-serial-option-adding-support-for-ublox-r410m.patch [new file with mode: 0644]
queue-4.9/usb-serial-option-reimplement-interface-masking.patch [new file with mode: 0644]
queue-4.9/usb-serial-visor-handle-potential-invalid-device-configuration.patch [new file with mode: 0644]

diff --git a/queue-4.9/platform-x86-asus-wireless-fix-null-pointer-dereference.patch b/queue-4.9/platform-x86-asus-wireless-fix-null-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..6c7c258
--- /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
+@@ -145,8 +145,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;
+ }
diff --git a/queue-4.9/s390-facilites-use-stfle_fac_list-array-size-for-max_facility_bit.patch b/queue-4.9/s390-facilites-use-stfle_fac_list-array-size-for-max_facility_bit.patch
new file mode 100644 (file)
index 0000000..cefe9a3
--- /dev/null
@@ -0,0 +1,33 @@
+From 6f5165e864d240d15675cc2fb5a369d57e1f60d0 Mon Sep 17 00:00:00 2001
+From: Heiko Carstens <heiko.carstens@de.ibm.com>
+Date: Mon, 20 Mar 2017 14:29:50 +0100
+Subject: s390/facilites: use stfle_fac_list array size for MAX_FACILITY_BIT
+
+From: Heiko Carstens <heiko.carstens@de.ibm.com>
+
+commit 6f5165e864d240d15675cc2fb5a369d57e1f60d0 upstream.
+
+Use the actual size of the facility list array within the lowcore
+structure for the MAX_FACILITY_BIT define instead of a comment which
+states what this is good for. This makes it a bit harder to break
+things.
+
+Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/include/asm/facility.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/s390/include/asm/facility.h
++++ b/arch/s390/include/asm/facility.h
+@@ -15,7 +15,7 @@
+ #include <linux/preempt.h>
+ #include <asm/lowcore.h>
+-#define MAX_FACILITY_BIT (256*8)      /* stfle_fac_list has 256 bytes */
++#define MAX_FACILITY_BIT (sizeof(((struct lowcore *)0)->stfle_fac_list) * 8)
+ static inline void __set_facility(unsigned long nr, void *facilities)
+ {
index c1006ae84d31ddd5f589824d32ce85afd1b61d68..8b10f2efa653ff5b475fa132f29cec8e30e2ee67 100644 (file)
@@ -22,3 +22,11 @@ ib-hfi1-fix-null-pointer-dereference-when-invalid-num_vls-is-used.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
+usb-serial-visor-handle-potential-invalid-device-configuration.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
+s390-facilites-use-stfle_fac_list-array-size-for-max_facility_bit.patch
diff --git a/queue-4.9/usb-accept-bulk-endpoints-with-1024-byte-maxpacket.patch b/queue-4.9/usb-accept-bulk-endpoints-with-1024-byte-maxpacket.patch
new file mode 100644 (file)
index 0000000..ff5f204
--- /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
+@@ -186,7 +186,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.9/usb-musb-host-fix-potential-null-pointer-dereference.patch b/queue-4.9/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.9/usb-musb-trace-fix-null-pointer-dereference-in-musb_g_tx.patch b/queue-4.9/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.9/usb-serial-option-adding-support-for-ublox-r410m.patch b/queue-4.9/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.9/usb-serial-option-reimplement-interface-masking.patch b/queue-4.9/usb-serial-option-reimplement-interface-masking.patch
new file mode 100644 (file)
index 0000000..2f4ea70
--- /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_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x02, 0x01) },    /* D-Link DWM-156 (variant) */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x00, 0x00) },    /* D-Link DWM-156 (variant) */
+@@ -2059,9 +1920,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 */
+@@ -2121,7 +1982,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)
+@@ -2132,9 +1993,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
+@@ -2145,8 +2004,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;
+ }
+@@ -2154,22 +2013,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.9/usb-serial-visor-handle-potential-invalid-device-configuration.patch b/queue-4.9/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);