commit:     91b1e34c3593e862337560bdb21fc62c1b944189
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed May 16 10:22:34 2018 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed May 16 10:22:34 2018 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=91b1e34c

Linux patch 4.4.132

 0000_README              |    4 +
 1131_linux-4.4.132.patch | 2961 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 2965 insertions(+)

diff --git a/0000_README b/0000_README
index 863ce11..04783a3 100644
--- a/0000_README
+++ b/0000_README
@@ -567,6 +567,10 @@ Patch:  1130_linux-4.4.131.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.4.131
 
+Patch:  1131_linux-4.4.132.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.4.132
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1131_linux-4.4.132.patch b/1131_linux-4.4.132.patch
new file mode 100644
index 0000000..800f295
--- /dev/null
+++ b/1131_linux-4.4.132.patch
@@ -0,0 +1,2961 @@
+diff --git a/Makefile b/Makefile
+index 6ec65396a56d..ace4a655548a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 4
+-SUBLEVEL = 131
++SUBLEVEL = 132
+ EXTRAVERSION =
+ NAME = Blurry Fish Butt
+ 
+diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
+index b011140e6b06..5ddb1debba95 100644
+--- a/arch/s390/kvm/kvm-s390.c
++++ b/arch/s390/kvm/kvm-s390.c
+@@ -118,8 +118,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
+ 
+ /* upper facilities limit for kvm */
+ unsigned long kvm_s390_fac_list_mask[] = {
+-      0xffe6fffbfcfdfc40UL,
+-      0x005e800000000000UL,
++      0xffe6ffffffffffffUL,
++      0x005effffffffffffUL,
+ };
+ 
+ unsigned long kvm_s390_fac_list_mask_size(void)
+diff --git a/arch/x86/kernel/cpu/perf_event.c 
b/arch/x86/kernel/cpu/perf_event.c
+index b52a8d08ab36..fbf2edc3eb35 100644
+--- a/arch/x86/kernel/cpu/perf_event.c
++++ b/arch/x86/kernel/cpu/perf_event.c
+@@ -25,6 +25,7 @@
+ #include <linux/cpu.h>
+ #include <linux/bitops.h>
+ #include <linux/device.h>
++#include <linux/nospec.h>
+ 
+ #include <asm/apic.h>
+ #include <asm/stacktrace.h>
+@@ -297,17 +298,20 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct 
perf_event *event)
+ 
+       config = attr->config;
+ 
+-      cache_type = (config >>  0) & 0xff;
++      cache_type = (config >> 0) & 0xff;
+       if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
+               return -EINVAL;
++      cache_type = array_index_nospec(cache_type, PERF_COUNT_HW_CACHE_MAX);
+ 
+       cache_op = (config >>  8) & 0xff;
+       if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
+               return -EINVAL;
++      cache_op = array_index_nospec(cache_op, PERF_COUNT_HW_CACHE_OP_MAX);
+ 
+       cache_result = (config >> 16) & 0xff;
+       if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+               return -EINVAL;
++      cache_result = array_index_nospec(cache_result, 
PERF_COUNT_HW_CACHE_RESULT_MAX);
+ 
+       val = hw_cache_event_ids[cache_type][cache_op][cache_result];
+ 
+@@ -404,6 +408,8 @@ int x86_setup_perfctr(struct perf_event *event)
+       if (attr->config >= x86_pmu.max_events)
+               return -EINVAL;
+ 
++      attr->config = array_index_nospec((unsigned long)attr->config, 
x86_pmu.max_events);
++
+       /*
+        * The generic map:
+        */
+diff --git a/arch/x86/kernel/cpu/perf_event_intel_cstate.c 
b/arch/x86/kernel/cpu/perf_event_intel_cstate.c
+index 75a38b5a2e26..5b8c90935270 100644
+--- a/arch/x86/kernel/cpu/perf_event_intel_cstate.c
++++ b/arch/x86/kernel/cpu/perf_event_intel_cstate.c
+@@ -88,6 +88,7 @@
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/perf_event.h>
++#include <linux/nospec.h>
+ #include <asm/cpu_device_id.h>
+ #include "perf_event.h"
+ 
+@@ -409,6 +410,7 @@ static int cstate_pmu_event_init(struct perf_event *event)
+       } else if (event->pmu == &cstate_pkg_pmu) {
+               if (cfg >= PERF_CSTATE_PKG_EVENT_MAX)
+                       return -EINVAL;
++              cfg = array_index_nospec((unsigned long)cfg, 
PERF_CSTATE_PKG_EVENT_MAX);
+               if (!pkg_msr[cfg].attr)
+                       return -EINVAL;
+               event->hw.event_base = pkg_msr[cfg].msr;
+diff --git a/arch/x86/kernel/cpu/perf_event_msr.c 
b/arch/x86/kernel/cpu/perf_event_msr.c
+index ec863b9a9f78..067427384a63 100644
+--- a/arch/x86/kernel/cpu/perf_event_msr.c
++++ b/arch/x86/kernel/cpu/perf_event_msr.c
+@@ -1,4 +1,5 @@
+ #include <linux/perf_event.h>
++#include <linux/nospec.h>
+ 
+ enum perf_msr_id {
+       PERF_MSR_TSC                    = 0,
+@@ -115,9 +116,6 @@ static int msr_event_init(struct perf_event *event)
+       if (event->attr.type != event->pmu->type)
+               return -ENOENT;
+ 
+-      if (cfg >= PERF_MSR_EVENT_MAX)
+-              return -EINVAL;
+-
+       /* unsupported modes and filters */
+       if (event->attr.exclude_user   ||
+           event->attr.exclude_kernel ||
+@@ -128,6 +126,11 @@ static int msr_event_init(struct perf_event *event)
+           event->attr.sample_period) /* no sampling */
+               return -EINVAL;
+ 
++      if (cfg >= PERF_MSR_EVENT_MAX)
++              return -EINVAL;
++
++      cfg = array_index_nospec((unsigned long)cfg, PERF_MSR_EVENT_MAX);
++
+       if (!msr[cfg].attr)
+               return -EINVAL;
+ 
+diff --git a/crypto/af_alg.c b/crypto/af_alg.c
+index ca50eeb13097..b5953f1d1a18 100644
+--- a/crypto/af_alg.c
++++ b/crypto/af_alg.c
+@@ -157,16 +157,16 @@ static int alg_bind(struct socket *sock, struct sockaddr 
*uaddr, int addr_len)
+       void *private;
+       int err;
+ 
+-      /* If caller uses non-allowed flag, return error. */
+-      if ((sa->salg_feat & ~allowed) || (sa->salg_mask & ~allowed))
+-              return -EINVAL;
+-
+       if (sock->state == SS_CONNECTED)
+               return -EINVAL;
+ 
+       if (addr_len != sizeof(*sa))
+               return -EINVAL;
+ 
++      /* If caller uses non-allowed flag, return error. */
++      if ((sa->salg_feat & ~allowed) || (sa->salg_mask & ~allowed))
++              return -EINVAL;
++
+       sa->salg_type[sizeof(sa->salg_type) - 1] = 0;
+       sa->salg_name[sizeof(sa->salg_name) - 1] = 0;
+ 
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index 2d677ba46d77..60d6db82ce5a 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -4243,6 +4243,9 @@ static const struct ata_blacklist_entry 
ata_device_blacklist [] = {
+                                               ATA_HORKAGE_ZERO_AFTER_TRIM |
+                                               ATA_HORKAGE_NOLPM, },
+ 
++      /* Sandisk devices which are known to not handle LPM well */
++      { "SanDisk SD7UB3Q*G1001",      NULL,   ATA_HORKAGE_NOLPM, },
++
+       /* devices that don't properly handle queued TRIM commands */
+       { "Micron_M500_*",              NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
+                                               ATA_HORKAGE_ZERO_AFTER_TRIM, },
+diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
+index cecfb943762f..6eab52b92e01 100644
+--- a/drivers/atm/zatm.c
++++ b/drivers/atm/zatm.c
+@@ -23,6 +23,7 @@
+ #include <linux/bitops.h>
+ #include <linux/wait.h>
+ #include <linux/slab.h>
++#include <linux/nospec.h>
+ #include <asm/byteorder.h>
+ #include <asm/string.h>
+ #include <asm/io.h>
+@@ -1456,6 +1457,8 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int 
cmd,void __user *arg)
+                                       return -EFAULT;
+                               if (pool < 0 || pool > ZATM_LAST_POOL)
+                                       return -EINVAL;
++                              pool = array_index_nospec(pool,
++                                                        ZATM_LAST_POOL + 1);
+                               spin_lock_irqsave(&zatm_dev->lock, flags);
+                               info = zatm_dev->pool_info[pool];
+                               if (cmd == ZATM_GETPOOLZ) {
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 7fca7cfd5b09..54cef3dc0beb 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -216,6 +216,7 @@ static const struct usb_device_id blacklist_table[] = {
+       { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
++      { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
+@@ -246,7 +247,6 @@ static const struct usb_device_id blacklist_table[] = {
+       { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
+ 
+       /* QCA ROME chipset */
+-      { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_QCA_ROME },
+       { USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME },
+       { USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME },
+       { USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME },
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+index 098e562bd579..9b97f70fbb3d 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+@@ -1991,6 +1991,7 @@ void vmw_kms_helper_resource_finish(struct 
vmw_validation_ctx *ctx,
+               vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf,
+                                            out_fence, NULL);
+ 
++      vmw_dmabuf_unreference(&ctx->buf);
+       vmw_resource_unreserve(res, false, NULL, 0);
+       mutex_unlock(&res->dev_priv->cmdbuf_mutex);
+ }
+diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
+index ea3bc9bb1b7a..2b9c00faca7d 100644
+--- a/drivers/infiniband/core/ucma.c
++++ b/drivers/infiniband/core/ucma.c
+@@ -675,7 +675,7 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file,
+       if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+               return -EFAULT;
+ 
+-      if (!rdma_addr_size_in6(&cmd.src_addr) ||
++      if ((cmd.src_addr.sin6_family && !rdma_addr_size_in6(&cmd.src_addr)) ||
+           !rdma_addr_size_in6(&cmd.dst_addr))
+               return -EINVAL;
+ 
+diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
+index cfcfbb6b84d7..c5390f6f94c5 100644
+--- a/drivers/infiniband/hw/mlx5/qp.c
++++ b/drivers/infiniband/hw/mlx5/qp.c
+@@ -231,7 +231,11 @@ static int set_rq_size(struct mlx5_ib_dev *dev, struct 
ib_qp_cap *cap,
+       } else {
+               if (ucmd) {
+                       qp->rq.wqe_cnt = ucmd->rq_wqe_count;
++                      if (ucmd->rq_wqe_shift > BITS_PER_BYTE * 
sizeof(ucmd->rq_wqe_shift))
++                              return -EINVAL;
+                       qp->rq.wqe_shift = ucmd->rq_wqe_shift;
++                      if ((1 << qp->rq.wqe_shift) / sizeof(struct 
mlx5_wqe_data_seg) < qp->wq_sig)
++                              return -EINVAL;
+                       qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof(struct 
mlx5_wqe_data_seg) - qp->wq_sig;
+                       qp->rq.max_post = qp->rq.wqe_cnt;
+               } else {
+@@ -1348,18 +1352,18 @@ enum {
+ 
+ static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate)
+ {
+-      if (rate == IB_RATE_PORT_CURRENT) {
++      if (rate == IB_RATE_PORT_CURRENT)
+               return 0;
+-      } else if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_300_GBPS) {
++
++      if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_300_GBPS)
+               return -EINVAL;
+-      } else {
+-              while (rate != IB_RATE_2_5_GBPS &&
+-                     !(1 << (rate + MLX5_STAT_RATE_OFFSET) &
+-                       MLX5_CAP_GEN(dev->mdev, stat_rate_support)))
+-                      --rate;
+-      }
+ 
+-      return rate + MLX5_STAT_RATE_OFFSET;
++      while (rate != IB_RATE_PORT_CURRENT &&
++             !(1 << (rate + MLX5_STAT_RATE_OFFSET) &
++               MLX5_CAP_GEN(dev->mdev, stat_rate_support)))
++              --rate;
++
++      return rate ? rate + MLX5_STAT_RATE_OFFSET : rate;
+ }
+ 
+ static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah,
+diff --git a/drivers/input/input-leds.c b/drivers/input/input-leds.c
+index 766bf2660116..5f04b2d94635 100644
+--- a/drivers/input/input-leds.c
++++ b/drivers/input/input-leds.c
+@@ -88,6 +88,7 @@ static int input_leds_connect(struct input_handler *handler,
+                             const struct input_device_id *id)
+ {
+       struct input_leds *leds;
++      struct input_led *led;
+       unsigned int num_leds;
+       unsigned int led_code;
+       int led_no;
+@@ -119,14 +120,13 @@ static int input_leds_connect(struct input_handler 
*handler,
+ 
+       led_no = 0;
+       for_each_set_bit(led_code, dev->ledbit, LED_CNT) {
+-              struct input_led *led = &leds->leds[led_no];
++              if (!input_led_info[led_code].name)
++                      continue;
+ 
++              led = &leds->leds[led_no];
+               led->handle = &leds->handle;
+               led->code = led_code;
+ 
+-              if (!input_led_info[led_code].name)
+-                      continue;
+-
+               led->cdev.name = kasprintf(GFP_KERNEL, "%s::%s",
+                                          dev_name(&dev->dev),
+                                          input_led_info[led_code].name);
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 2d5794ec338b..88dfe3008cf4 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -2522,6 +2522,15 @@ static const struct dmi_system_id mxt_dmi_table[] = {
+               },
+               .driver_data = samus_platform_data,
+       },
++      {
++              /* Samsung Chromebook Pro */
++              .ident = "Samsung Chromebook Pro",
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "Google"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "Caroline"),
++              },
++              .driver_data = samus_platform_data,
++      },
+       {
+               /* Other Google Chromebooks */
+               .ident = "Chromebook",
+diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c 
b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+index e2a239c1f40b..40a335c6b792 100644
+--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
++++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+@@ -1032,14 +1032,87 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, 
struct nand_chip *chip,
+       /* Loop over status bytes, accumulating ECC status. */
+       status = auxiliary_virt + nfc_geo->auxiliary_status_offset;
+ 
++      read_page_swap_end(this, buf, nfc_geo->payload_size,
++                         this->payload_virt, this->payload_phys,
++                         nfc_geo->payload_size,
++                         payload_virt, payload_phys);
++
+       for (i = 0; i < nfc_geo->ecc_chunk_count; i++, status++) {
+               if ((*status == STATUS_GOOD) || (*status == STATUS_ERASED))
+                       continue;
+ 
+               if (*status == STATUS_UNCORRECTABLE) {
++                      int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len;
++                      u8 *eccbuf = this->raw_buffer;
++                      int offset, bitoffset;
++                      int eccbytes;
++                      int flips;
++
++                      /* Read ECC bytes into our internal raw_buffer */
++                      offset = nfc_geo->metadata_size * 8;
++                      offset += ((8 * nfc_geo->ecc_chunk_size) + eccbits) * 
(i + 1);
++                      offset -= eccbits;
++                      bitoffset = offset % 8;
++                      eccbytes = DIV_ROUND_UP(offset + eccbits, 8);
++                      offset /= 8;
++                      eccbytes -= offset;
++                      chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offset, -1);
++                      chip->read_buf(mtd, eccbuf, eccbytes);
++
++                      /*
++                       * ECC data are not byte aligned and we may have
++                       * in-band data in the first and last byte of
++                       * eccbuf. Set non-eccbits to one so that
++                       * nand_check_erased_ecc_chunk() does not count them
++                       * as bitflips.
++                       */
++                      if (bitoffset)
++                              eccbuf[0] |= GENMASK(bitoffset - 1, 0);
++
++                      bitoffset = (bitoffset + eccbits) % 8;
++                      if (bitoffset)
++                              eccbuf[eccbytes - 1] |= GENMASK(7, bitoffset);
++
++                      /*
++                       * The ECC hardware has an uncorrectable ECC status
++                       * code in case we have bitflips in an erased page. As
++                       * nothing was written into this subpage the ECC is
++                       * obviously wrong and we can not trust it. We assume
++                       * at this point that we are reading an erased page and
++                       * try to correct the bitflips in buffer up to
++                       * ecc_strength bitflips. If this is a page with random
++                       * data, we exceed this number of bitflips and have a
++                       * ECC failure. Otherwise we use the corrected buffer.
++                       */
++                      if (i == 0) {
++                              /* The first block includes metadata */
++                              flips = nand_check_erased_ecc_chunk(
++                                              buf + i * 
nfc_geo->ecc_chunk_size,
++                                              nfc_geo->ecc_chunk_size,
++                                              eccbuf, eccbytes,
++                                              auxiliary_virt,
++                                              nfc_geo->metadata_size,
++                                              nfc_geo->ecc_strength);
++                      } else {
++                              flips = nand_check_erased_ecc_chunk(
++                                              buf + i * 
nfc_geo->ecc_chunk_size,
++                                              nfc_geo->ecc_chunk_size,
++                                              eccbuf, eccbytes,
++                                              NULL, 0,
++                                              nfc_geo->ecc_strength);
++                      }
++
++                      if (flips > 0) {
++                              max_bitflips = max_t(unsigned int, max_bitflips,
++                                                   flips);
++                              mtd->ecc_stats.corrected += flips;
++                              continue;
++                      }
++
+                       mtd->ecc_stats.failed++;
+                       continue;
+               }
++
+               mtd->ecc_stats.corrected += *status;
+               max_bitflips = max_t(unsigned int, max_bitflips, *status);
+       }
+@@ -1062,11 +1135,6 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, 
struct nand_chip *chip,
+               chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0];
+       }
+ 
+-      read_page_swap_end(this, buf, nfc_geo->payload_size,
+-                      this->payload_virt, this->payload_phys,
+-                      nfc_geo->payload_size,
+-                      payload_virt, payload_phys);
+-
+       return max_bitflips;
+ }
+ 
+diff --git a/drivers/net/can/usb/kvaser_usb.c 
b/drivers/net/can/usb/kvaser_usb.c
+index db1855b0e08f..59f891bebcc6 100644
+--- a/drivers/net/can/usb/kvaser_usb.c
++++ b/drivers/net/can/usb/kvaser_usb.c
+@@ -1175,7 +1175,7 @@ static void kvaser_usb_rx_can_msg(const struct 
kvaser_usb *dev,
+ 
+       skb = alloc_can_skb(priv->netdev, &cf);
+       if (!skb) {
+-              stats->tx_dropped++;
++              stats->rx_dropped++;
+               return;
+       }
+ 
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index b0ea8dee5f06..a6f0a8f516d6 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -631,6 +631,7 @@ static const struct usb_device_id products[] = {
+       {QMI_FIXED_INTF(0x05c6, 0x9080, 8)},
+       {QMI_FIXED_INTF(0x05c6, 0x9083, 3)},
+       {QMI_FIXED_INTF(0x05c6, 0x9084, 4)},
++      {QMI_FIXED_INTF(0x05c6, 0x90b2, 3)},    /* ublox R410M */
+       {QMI_FIXED_INTF(0x05c6, 0x920d, 0)},
+       {QMI_FIXED_INTF(0x05c6, 0x920d, 5)},
+       {QMI_FIXED_INTF(0x0846, 0x68a2, 8)},
+diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
+index ee638cb8b48f..0c23768aa1ec 100644
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -67,6 +67,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
+                       .board_size = QCA988X_BOARD_DATA_SZ,
+                       .board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 4,
+       },
+       {
+               .id = QCA6174_HW_2_1_VERSION,
+@@ -85,6 +86,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
+                       .board_size = QCA6174_BOARD_DATA_SZ,
+                       .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 4,
+       },
+       {
+               .id = QCA6174_HW_2_1_VERSION,
+@@ -103,6 +105,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
+                       .board_size = QCA6174_BOARD_DATA_SZ,
+                       .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 4,
+       },
+       {
+               .id = QCA6174_HW_3_0_VERSION,
+@@ -121,6 +124,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
+                       .board_size = QCA6174_BOARD_DATA_SZ,
+                       .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 4,
+       },
+       {
+               .id = QCA6174_HW_3_2_VERSION,
+@@ -140,6 +144,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
+                       .board_size = QCA6174_BOARD_DATA_SZ,
+                       .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 4,
+       },
+       {
+               .id = QCA99X0_HW_2_0_DEV_VERSION,
+@@ -159,6 +164,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
+                       .board_size = QCA99X0_BOARD_DATA_SZ,
+                       .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 1,
+       },
+       {
+               .id = QCA9377_HW_1_0_DEV_VERSION,
+@@ -177,6 +183,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
+                       .board_size = QCA9377_BOARD_DATA_SZ,
+                       .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 4,
+       },
+       {
+               .id = QCA9377_HW_1_1_DEV_VERSION,
+@@ -195,6 +202,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
+                       .board_size = QCA9377_BOARD_DATA_SZ,
+                       .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
+               },
++              .decap_align_bytes = 4,
+       },
+ };
+ 
+diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
+index 858d75f49a9f..257836a0cfbc 100644
+--- a/drivers/net/wireless/ath/ath10k/core.h
++++ b/drivers/net/wireless/ath/ath10k/core.h
+@@ -670,6 +670,10 @@ struct ath10k {
+                       size_t board_size;
+                       size_t board_ext_size;
+               } fw;
++
++              /* Number of bytes used for alignment in rx_hdr_status */
++              int decap_align_bytes;
++
+       } hw_params;
+ 
+       const struct firmware *board;
+diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
+index 6060dda4e910..d26cb37b1fbd 100644
+--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
+@@ -979,7 +979,7 @@ static void ath10k_process_rx(struct ath10k *ar,
+       *status = *rx_status;
+ 
+       ath10k_dbg(ar, ATH10K_DBG_DATA,
+-                 "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx 
%u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
++                 "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx 
%u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more 
%i\n",
+                  skb,
+                  skb->len,
+                  ieee80211_get_SA(hdr),
+@@ -1076,7 +1076,21 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k 
*ar,
+       hdr = (void *)msdu->data;
+ 
+       /* Tail */
+-      skb_trim(msdu, msdu->len - ath10k_htt_rx_crypto_tail_len(ar, enctype));
++      if (status->flag & RX_FLAG_IV_STRIPPED) {
++              skb_trim(msdu, msdu->len -
++                       ath10k_htt_rx_crypto_tail_len(ar, enctype));
++      } else {
++              /* MIC */
++              if ((status->flag & RX_FLAG_MIC_STRIPPED) &&
++                  enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2)
++                      skb_trim(msdu, msdu->len - 8);
++
++              /* ICV */
++              if (status->flag & RX_FLAG_ICV_STRIPPED &&
++                  enctype != HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2)
++                      skb_trim(msdu, msdu->len -
++                               ath10k_htt_rx_crypto_tail_len(ar, enctype));
++      }
+ 
+       /* MMIC */
+       if (!ieee80211_has_morefrags(hdr->frame_control) &&
+@@ -1095,12 +1109,14 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k 
*ar,
+ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
+                                         struct sk_buff *msdu,
+                                         struct ieee80211_rx_status *status,
+-                                        const u8 first_hdr[64])
++                                        const u8 first_hdr[64],
++                                        enum htt_rx_mpdu_encrypt_type enctype)
+ {
+       struct ieee80211_hdr *hdr;
+       size_t hdr_len;
+       u8 da[ETH_ALEN];
+       u8 sa[ETH_ALEN];
++      int bytes_aligned = ar->hw_params.decap_align_bytes;
+ 
+       /* Delivered decapped frame:
+        * [nwifi 802.11 header] <-- replaced with 802.11 hdr
+@@ -1123,6 +1139,14 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k 
*ar,
+       /* push original 802.11 header */
+       hdr = (struct ieee80211_hdr *)first_hdr;
+       hdr_len = ieee80211_hdrlen(hdr->frame_control);
++
++      if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
++              memcpy(skb_push(msdu,
++                              ath10k_htt_rx_crypto_param_len(ar, enctype)),
++                     (void *)hdr + round_up(hdr_len, bytes_aligned),
++                      ath10k_htt_rx_crypto_param_len(ar, enctype));
++      }
++
+       memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
+ 
+       /* original 802.11 header has a different DA and in
+@@ -1180,6 +1204,7 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k 
*ar,
+       void *rfc1042;
+       u8 da[ETH_ALEN];
+       u8 sa[ETH_ALEN];
++      int bytes_aligned = ar->hw_params.decap_align_bytes;
+ 
+       /* Delivered decapped frame:
+        * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc
+@@ -1203,6 +1228,14 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k 
*ar,
+       /* push original 802.11 header */
+       hdr = (struct ieee80211_hdr *)first_hdr;
+       hdr_len = ieee80211_hdrlen(hdr->frame_control);
++
++      if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
++              memcpy(skb_push(msdu,
++                              ath10k_htt_rx_crypto_param_len(ar, enctype)),
++                     (void *)hdr + round_up(hdr_len, bytes_aligned),
++                      ath10k_htt_rx_crypto_param_len(ar, enctype));
++      }
++
+       memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
+ 
+       /* original 802.11 header has a different DA and in
+@@ -1216,10 +1249,12 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k 
*ar,
+ static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar,
+                                        struct sk_buff *msdu,
+                                        struct ieee80211_rx_status *status,
+-                                       const u8 first_hdr[64])
++                                       const u8 first_hdr[64],
++                                       enum htt_rx_mpdu_encrypt_type enctype)
+ {
+       struct ieee80211_hdr *hdr;
+       size_t hdr_len;
++      int bytes_aligned = ar->hw_params.decap_align_bytes;
+ 
+       /* Delivered decapped frame:
+        * [amsdu header] <-- replaced with 802.11 hdr
+@@ -1231,6 +1266,14 @@ static void ath10k_htt_rx_h_undecap_snap(struct ath10k 
*ar,
+ 
+       hdr = (struct ieee80211_hdr *)first_hdr;
+       hdr_len = ieee80211_hdrlen(hdr->frame_control);
++
++      if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
++              memcpy(skb_push(msdu,
++                              ath10k_htt_rx_crypto_param_len(ar, enctype)),
++                     (void *)hdr + round_up(hdr_len, bytes_aligned),
++                      ath10k_htt_rx_crypto_param_len(ar, enctype));
++      }
++
+       memcpy(skb_push(msdu, hdr_len), hdr, hdr_len);
+ }
+ 
+@@ -1265,13 +1308,15 @@ static void ath10k_htt_rx_h_undecap(struct ath10k *ar,
+                                           is_decrypted);
+               break;
+       case RX_MSDU_DECAP_NATIVE_WIFI:
+-              ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr);
++              ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr,
++                                            enctype);
+               break;
+       case RX_MSDU_DECAP_ETHERNET2_DIX:
+               ath10k_htt_rx_h_undecap_eth(ar, msdu, status, first_hdr, 
enctype);
+               break;
+       case RX_MSDU_DECAP_8023_SNAP_LLC:
+-              ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr);
++              ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr,
++                                           enctype);
+               break;
+       }
+ }
+@@ -1314,7 +1359,8 @@ static void ath10k_htt_rx_h_csum_offload(struct sk_buff 
*msdu)
+ 
+ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
+                                struct sk_buff_head *amsdu,
+-                               struct ieee80211_rx_status *status)
++                               struct ieee80211_rx_status *status,
++                               bool fill_crypt_header)
+ {
+       struct sk_buff *first;
+       struct sk_buff *last;
+@@ -1324,7 +1370,6 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
+       enum htt_rx_mpdu_encrypt_type enctype;
+       u8 first_hdr[64];
+       u8 *qos;
+-      size_t hdr_len;
+       bool has_fcs_err;
+       bool has_crypto_err;
+       bool has_tkip_err;
+@@ -1345,15 +1390,17 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
+        * decapped header. It'll be used for undecapping of each MSDU.
+        */
+       hdr = (void *)rxd->rx_hdr_status;
+-      hdr_len = ieee80211_hdrlen(hdr->frame_control);
+-      memcpy(first_hdr, hdr, hdr_len);
++      memcpy(first_hdr, hdr, RX_HTT_HDR_STATUS_LEN);
+ 
+       /* Each A-MSDU subframe will use the original header as the base and be
+        * reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl.
+        */
+       hdr = (void *)first_hdr;
+-      qos = ieee80211_get_qos_ctl(hdr);
+-      qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
++
++      if (ieee80211_is_data_qos(hdr->frame_control)) {
++              qos = ieee80211_get_qos_ctl(hdr);
++              qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
++      }
+ 
+       /* Some attention flags are valid only in the last MSDU. */
+       last = skb_peek_tail(amsdu);
+@@ -1387,11 +1434,17 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
+       if (has_tkip_err)
+               status->flag |= RX_FLAG_MMIC_ERROR;
+ 
+-      if (is_decrypted)
++      if (is_decrypted) {
+               status->flag |= RX_FLAG_DECRYPTED |
+-                              RX_FLAG_IV_STRIPPED |
+                               RX_FLAG_MMIC_STRIPPED;
+ 
++              if (fill_crypt_header)
++                      status->flag |= RX_FLAG_MIC_STRIPPED |
++                                      RX_FLAG_ICV_STRIPPED;
++              else
++                      status->flag |= RX_FLAG_IV_STRIPPED;
++      }
++
+       skb_queue_walk(amsdu, msdu) {
+               ath10k_htt_rx_h_csum_offload(msdu);
+               ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype,
+@@ -1404,6 +1457,9 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
+               if (!is_decrypted)
+                       continue;
+ 
++              if (fill_crypt_header)
++                      continue;
++
+               hdr = (void *)msdu->data;
+               hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+       }
+@@ -1414,6 +1470,9 @@ static void ath10k_htt_rx_h_deliver(struct ath10k *ar,
+                                   struct ieee80211_rx_status *status)
+ {
+       struct sk_buff *msdu;
++      struct sk_buff *first_subframe;
++
++      first_subframe = skb_peek(amsdu);
+ 
+       while ((msdu = __skb_dequeue(amsdu))) {
+               /* Setup per-MSDU flags */
+@@ -1422,6 +1481,13 @@ static void ath10k_htt_rx_h_deliver(struct ath10k *ar,
+               else
+                       status->flag |= RX_FLAG_AMSDU_MORE;
+ 
++              if (msdu == first_subframe) {
++                      first_subframe = NULL;
++                      status->flag &= ~RX_FLAG_ALLOW_SAME_PN;
++              } else {
++                      status->flag |= RX_FLAG_ALLOW_SAME_PN;
++              }
++
+               ath10k_process_rx(ar, status, msdu);
+       }
+ }
+@@ -1607,7 +1673,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
+               ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff);
+               ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0);
+               ath10k_htt_rx_h_filter(ar, &amsdu, rx_status);
+-              ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status);
++              ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true);
+               ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status);
+       }
+ 
+@@ -1653,7 +1719,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt 
*htt,
+ 
+       ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff);
+       ath10k_htt_rx_h_filter(ar, &amsdu, rx_status);
+-      ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status);
++      ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true);
+       ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status);
+ 
+       if (fw_desc_len > 0) {
+@@ -1952,7 +2018,7 @@ static void ath10k_htt_rx_in_ord_ind(struct ath10k *ar, 
struct sk_buff *skb)
+                        */
+                       ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id);
+                       ath10k_htt_rx_h_filter(ar, &amsdu, status);
+-                      ath10k_htt_rx_h_mpdu(ar, &amsdu, status);
++                      ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false);
+                       ath10k_htt_rx_h_deliver(ar, &amsdu, status);
+                       break;
+               case -EAGAIN:
+diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c 
b/drivers/net/wireless/ath/wcn36xx/txrx.c
+index 9bec8237231d..99c21aac68bd 100644
+--- a/drivers/net/wireless/ath/wcn36xx/txrx.c
++++ b/drivers/net/wireless/ath/wcn36xx/txrx.c
+@@ -57,7 +57,7 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
+                      RX_FLAG_MMIC_STRIPPED |
+                      RX_FLAG_DECRYPTED;
+ 
+-      wcn36xx_dbg(WCN36XX_DBG_RX, "status.flags=%x\n", status.flag);
++      wcn36xx_dbg(WCN36XX_DBG_RX, "status.flags=%llx\n", status.flag);
+ 
+       memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+ 
+diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
+index 22dcccf2d286..6a287c81a7be 100644
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -157,7 +157,9 @@ static const unsigned short full_speed_maxpacket_maxes[4] 
= {
+ 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/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
+index 0d843e0f8055..494823f21c28 100644
+--- a/drivers/usb/musb/musb_host.c
++++ b/drivers/usb/musb/musb_host.c
+@@ -1048,7 +1048,9 @@ static void musb_bulk_nak_timeout(struct musb *musb, 
struct musb_hw_ep *ep,
+                       /* 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/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 1799aa058a5b..d982c455e18e 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -236,6 +236,8 @@ static void option_instat_callback(struct urb *urb);
+ /* 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
+ 
+@@ -244,6 +246,7 @@ static void option_instat_callback(struct urb *urb);
+ #define QUECTEL_PRODUCT_EC21                  0x0121
+ #define QUECTEL_PRODUCT_EC25                  0x0125
+ #define QUECTEL_PRODUCT_BG96                  0x0296
++#define QUECTEL_PRODUCT_EP06                  0x0306
+ 
+ #define CMOTECH_VENDOR_ID                     0x16d8
+ #define CMOTECH_PRODUCT_6001                  0x6001
+@@ -550,147 +553,15 @@ static void option_instat_callback(struct urb *urb);
+ #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),
+-};
++/* Device flags */
+ 
+-static const struct option_blacklist_info net_intf2_blacklist = {
+-      .reserved = BIT(2),
+-};
++/* Interface does not support modem-control requests */
++#define NCTRL(ifnum)  ((BIT(ifnum) & 0xff) << 8)
+ 
+-static const struct option_blacklist_info net_intf3_blacklist = {
+-      .reserved = BIT(3),
+-};
++/* Interface is reserved */
++#define RSVD(ifnum)   ((BIT(ifnum) & 0xff) << 0)
+ 
+-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),
+-};
+-
+-static const struct option_blacklist_info cinterion_rmnet2_blacklist = {
+-      .reserved = BIT(4) | BIT(5),
+-};
+-
+-static const struct option_blacklist_info yuga_clm920_nc5_blacklist = {
+-      .reserved = BIT(1) | BIT(4),
+-};
+ 
+ static const struct usb_device_id option_ids[] = {
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
+@@ -724,26 +595,26 @@ static const struct usb_device_id option_ids[] = {
+       { 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) },
+@@ -1188,65 +1059,70 @@ static const struct usb_device_id option_ids[] = {
+       { 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) },
++      /* 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 = (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 = 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) },
+@@ -1254,38 +1130,38 @@ static const struct usb_device_id option_ids[] = {
+       { 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) },
+@@ -1301,58 +1177,58 @@ static const struct usb_device_id option_ids[] = {
+       { 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) },
+@@ -1377,26 +1253,26 @@ static const struct usb_device_id option_ids[] = {
+       { 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) },
+@@ -1412,50 +1288,50 @@ static const struct usb_device_id option_ids[] = {
+       { 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) },
+@@ -1572,23 +1448,23 @@ static const struct usb_device_id option_ids[] = {
+       { 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) },
+@@ -1603,7 +1479,7 @@ static const struct usb_device_id option_ids[] = {
+       { 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) },
+@@ -1639,17 +1515,17 @@ static const struct usb_device_id option_ids[] = {
+       { 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) },
+@@ -1667,8 +1543,8 @@ static const struct usb_device_id option_ids[] = {
+       { 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 */
+@@ -1679,20 +1555,20 @@ static const struct usb_device_id option_ids[] = {
+       { 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) },
+@@ -1844,19 +1720,19 @@ static const struct usb_device_id option_ids[] = {
+       { 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) },
+@@ -1876,37 +1752,34 @@ static const struct usb_device_id option_ids[] = {
+       { 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) },
+@@ -1932,14 +1805,14 @@ static const struct usb_device_id option_ids[] = {
+       { 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) },
+@@ -1949,20 +1822,20 @@ static const struct usb_device_id option_ids[] = {
+       { 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) },
+@@ -2039,9 +1912,9 @@ static const struct usb_device_id option_ids[] = {
+       { 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) */
+@@ -2052,9 +1925,9 @@ static const struct usb_device_id option_ids[] = {
+       { 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 */
+@@ -2114,7 +1987,7 @@ static int option_probe(struct usb_serial *serial,
+       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)
+@@ -2125,9 +1998,7 @@ static int option_probe(struct usb_serial *serial,
+        * 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
+@@ -2138,8 +2009,8 @@ static int option_probe(struct usb_serial *serial,
+           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;
+ }
+@@ -2147,22 +2018,21 @@ static int option_probe(struct usb_serial *serial,
+ 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/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
+index 337a0be89fcf..dbc3801b43eb 100644
+--- a/drivers/usb/serial/visor.c
++++ b/drivers/usb/serial/visor.c
+@@ -338,47 +338,48 @@ static int palm_os_3_probe(struct usb_serial *serial,
+               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);
+ 
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 98b2fc2678ff..f6ccb21f286b 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -721,7 +721,7 @@ static int __get_data_block(struct inode *inode, sector_t 
iblock,
+       if (!ret) {
+               map_bh(bh, inode->i_sb, map.m_pblk);
+               bh->b_state = (bh->b_state & ~F2FS_MAP_FLAGS) | map.m_flags;
+-              bh->b_size = map.m_len << inode->i_blkbits;
++              bh->b_size = (u64)map.m_len << inode->i_blkbits;
+       }
+       return ret;
+ }
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index 0fe667875852..cfb75dbb96f5 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -1906,7 +1906,7 @@ void wb_workfn(struct work_struct *work)
+       }
+ 
+       if (!list_empty(&wb->work_list))
+-              mod_delayed_work(bdi_wq, &wb->dwork, 0);
++              wb_wakeup(wb);
+       else if (wb_has_dirty_io(wb) && dirty_writeback_interval)
+               wb_wakeup_delayed(wb);
+ 
+diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
+index 3dd47307363f..e917aec4babe 100644
+--- a/fs/xfs/xfs_file.c
++++ b/fs/xfs/xfs_file.c
+@@ -969,22 +969,26 @@ xfs_file_fallocate(
+               if (error)
+                       goto out_unlock;
+       } else if (mode & FALLOC_FL_INSERT_RANGE) {
+-              unsigned int blksize_mask = i_blocksize(inode) - 1;
++              unsigned int    blksize_mask = i_blocksize(inode) - 1;
++              loff_t          isize = i_size_read(inode);
+ 
+-              new_size = i_size_read(inode) + len;
+               if (offset & blksize_mask || len & blksize_mask) {
+                       error = -EINVAL;
+                       goto out_unlock;
+               }
+ 
+-              /* check the new inode size does not wrap through zero */
+-              if (new_size > inode->i_sb->s_maxbytes) {
++              /*
++               * New inode size must not exceed ->s_maxbytes, accounting for
++               * possible signed overflow.
++               */
++              if (inode->i_sb->s_maxbytes - isize < len) {
+                       error = -EFBIG;
+                       goto out_unlock;
+               }
++              new_size = isize + len;
+ 
+               /* Offset should be less than i_size */
+-              if (offset >= i_size_read(inode)) {
++              if (offset >= isize) {
+                       error = -EINVAL;
+                       goto out_unlock;
+               }
+diff --git a/include/net/inet_timewait_sock.h 
b/include/net/inet_timewait_sock.h
+index c9b3eb70f340..567017b5fc9e 100644
+--- a/include/net/inet_timewait_sock.h
++++ b/include/net/inet_timewait_sock.h
+@@ -55,6 +55,7 @@ struct inet_timewait_sock {
+ #define tw_family             __tw_common.skc_family
+ #define tw_state              __tw_common.skc_state
+ #define tw_reuse              __tw_common.skc_reuse
++#define tw_reuseport          __tw_common.skc_reuseport
+ #define tw_ipv6only           __tw_common.skc_ipv6only
+ #define tw_bound_dev_if               __tw_common.skc_bound_dev_if
+ #define tw_node                       __tw_common.skc_nulls_node
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 4e51f9a5a177..7a49a31f6ddc 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -975,7 +975,7 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info 
*info)
+  * @RX_FLAG_DECRYPTED: This frame was decrypted in hardware.
+  * @RX_FLAG_MMIC_STRIPPED: the Michael MIC is stripped off this frame,
+  *    verification has been done by the hardware.
+- * @RX_FLAG_IV_STRIPPED: The IV/ICV are stripped from this frame.
++ * @RX_FLAG_IV_STRIPPED: The IV and ICV are stripped from this frame.
+  *    If this flag is set, the stack cannot do any replay detection
+  *    hence the driver or hardware will have to do that.
+  * @RX_FLAG_PN_VALIDATED: Currently only valid for CCMP/GCMP frames, this
+@@ -1013,6 +1013,8 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info 
*info)
+  *    on this subframe
+  * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC
+  *    is stored in the @ampdu_delimiter_crc field)
++ * @RX_FLAG_MIC_STRIPPED: The mic was stripped of this packet. Decryption was
++ *    done by the hardware
+  * @RX_FLAG_LDPC: LDPC was used
+  * @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
+  * @RX_FLAG_10MHZ: 10 MHz (half channel) was used
+@@ -1029,6 +1031,11 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info 
*info)
+  * @RX_FLAG_RADIOTAP_VENDOR_DATA: This frame contains vendor-specific
+  *    radiotap data in the skb->data (before the frame) as described by
+  *    the &struct ieee80211_vendor_radiotap.
++ * @RX_FLAG_ALLOW_SAME_PN: Allow the same PN as same packet before.
++ *    This is used for AMSDU subframes which can have the same PN as
++ *    the first subframe.
++ * @RX_FLAG_ICV_STRIPPED: The ICV is stripped from this frame. CRC checking 
must
++ *    be done in the hardware.
+  */
+ enum mac80211_rx_flags {
+       RX_FLAG_MMIC_ERROR              = BIT(0),
+@@ -1059,6 +1066,9 @@ enum mac80211_rx_flags {
+       RX_FLAG_5MHZ                    = BIT(29),
+       RX_FLAG_AMSDU_MORE              = BIT(30),
+       RX_FLAG_RADIOTAP_VENDOR_DATA    = BIT(31),
++      RX_FLAG_MIC_STRIPPED            = BIT_ULL(32),
++      RX_FLAG_ALLOW_SAME_PN           = BIT_ULL(33),
++      RX_FLAG_ICV_STRIPPED            = BIT_ULL(34),
+ };
+ 
+ #define RX_FLAG_STBC_SHIFT            26
+@@ -1113,7 +1123,7 @@ struct ieee80211_rx_status {
+       u64 mactime;
+       u32 device_timestamp;
+       u32 ampdu_reference;
+-      u32 flag;
++      u64 flag;
+       u16 freq;
+       u8 vht_flag;
+       u8 rate_idx;
+diff --git a/include/net/nexthop.h b/include/net/nexthop.h
+index 3334dbfa5aa4..7fc78663ec9d 100644
+--- a/include/net/nexthop.h
++++ b/include/net/nexthop.h
+@@ -6,7 +6,7 @@
+ 
+ static inline int rtnh_ok(const struct rtnexthop *rtnh, int remaining)
+ {
+-      return remaining >= sizeof(*rtnh) &&
++      return remaining >= (int)sizeof(*rtnh) &&
+              rtnh->rtnh_len >= sizeof(*rtnh) &&
+              rtnh->rtnh_len <= remaining;
+ }
+diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
+index 3608fa1aec8a..0eb11b4ac4c7 100644
+--- a/kernel/bpf/arraymap.c
++++ b/kernel/bpf/arraymap.c
+@@ -102,7 +102,7 @@ static void *array_map_lookup_elem(struct bpf_map *map, 
void *key)
+ static int array_map_get_next_key(struct bpf_map *map, void *key, void 
*next_key)
+ {
+       struct bpf_array *array = container_of(map, struct bpf_array, map);
+-      u32 index = *(u32 *)key;
++      u32 index = key ? *(u32 *)key : U32_MAX;
+       u32 *next = (u32 *)next_key;
+ 
+       if (index >= array->map.max_entries) {
+diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
+index 34777b3746fa..a35abe048239 100644
+--- a/kernel/bpf/hashtab.c
++++ b/kernel/bpf/hashtab.c
+@@ -169,12 +169,15 @@ static int htab_map_get_next_key(struct bpf_map *map, 
void *key, void *next_key)
+       struct hlist_head *head;
+       struct htab_elem *l, *next_l;
+       u32 hash, key_size;
+-      int i;
++      int i = 0;
+ 
+       WARN_ON_ONCE(!rcu_read_lock_held());
+ 
+       key_size = map->key_size;
+ 
++      if (!key)
++              goto find_first_elem;
++
+       hash = htab_map_hash(key, key_size);
+ 
+       head = select_bucket(htab, hash);
+@@ -182,10 +185,8 @@ static int htab_map_get_next_key(struct bpf_map *map, 
void *key, void *next_key)
+       /* lookup the key */
+       l = lookup_elem_raw(head, hash, key, key_size);
+ 
+-      if (!l) {
+-              i = 0;
++      if (!l)
+               goto find_first_elem;
+-      }
+ 
+       /* key was found, get next key in the same bucket */
+       next_l = 
hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(&l->hash_node)),
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index dc19b6e210e6..4b9bbfe764e8 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -390,14 +390,18 @@ static int map_get_next_key(union bpf_attr *attr)
+       if (IS_ERR(map))
+               return PTR_ERR(map);
+ 
+-      err = -ENOMEM;
+-      key = kmalloc(map->key_size, GFP_USER);
+-      if (!key)
+-              goto err_put;
+-
+-      err = -EFAULT;
+-      if (copy_from_user(key, ukey, map->key_size) != 0)
+-              goto free_key;
++      if (ukey) {
++              err = -ENOMEM;
++              key = kmalloc(map->key_size, GFP_USER);
++              if (!key)
++                      goto err_put;
++
++              err = -EFAULT;
++              if (copy_from_user(key, ukey, map->key_size) != 0)
++                      goto free_key;
++      } else {
++              key = NULL;
++      }
+ 
+       err = -ENOMEM;
+       next_key = kmalloc(map->key_size, GFP_USER);
+diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c
+index 9c418002b8c1..75f835d353db 100644
+--- a/kernel/events/callchain.c
++++ b/kernel/events/callchain.c
+@@ -107,14 +107,8 @@ int get_callchain_buffers(void)
+               goto exit;
+       }
+ 
+-      if (count > 1) {
+-              /* If the allocation failed, give up */
+-              if (!callchain_cpus_entries)
+-                      err = -ENOMEM;
+-              goto exit;
+-      }
+-
+-      err = alloc_callchain_buffers();
++      if (count == 1)
++              err = alloc_callchain_buffers();
+ exit:
+       if (err)
+               atomic_dec(&nr_callchain_events);
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 6aeb0ef4fe70..92d1f12f4407 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -229,7 +229,7 @@ int perf_cpu_time_max_percent_handler(struct ctl_table 
*table, int write,
+                               void __user *buffer, size_t *lenp,
+                               loff_t *ppos)
+ {
+-      int ret = proc_dointvec(table, write, buffer, lenp, ppos);
++      int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+ 
+       if (ret || !write)
+               return ret;
+diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
+index 014b69528194..58013ef228a1 100644
+--- a/kernel/events/ring_buffer.c
++++ b/kernel/events/ring_buffer.c
+@@ -14,6 +14,7 @@
+ #include <linux/slab.h>
+ #include <linux/circ_buf.h>
+ #include <linux/poll.h>
++#include <linux/nospec.h>
+ 
+ #include "internal.h"
+ 
+@@ -779,8 +780,10 @@ perf_mmap_to_page(struct ring_buffer *rb, unsigned long 
pgoff)
+                       return NULL;
+ 
+               /* AUX space */
+-              if (pgoff >= rb->aux_pgoff)
+-                      return virt_to_page(rb->aux_pages[pgoff - 
rb->aux_pgoff]);
++              if (pgoff >= rb->aux_pgoff) {
++                      int aux_pgoff = array_index_nospec(pgoff - 
rb->aux_pgoff, rb->aux_nr_pages);
++                      return virt_to_page(rb->aux_pages[aux_pgoff]);
++              }
+       }
+ 
+       return __perf_mmap_to_page(rb, pgoff);
+diff --git a/kernel/trace/trace_events_filter.c 
b/kernel/trace/trace_events_filter.c
+index f0e5408499b6..1ab2db6c127b 100644
+--- a/kernel/trace/trace_events_filter.c
++++ b/kernel/trace/trace_events_filter.c
+@@ -322,6 +322,9 @@ static int regex_match_full(char *str, struct regex *r, 
int len)
+ 
+ static int regex_match_front(char *str, struct regex *r, int len)
+ {
++      if (len < r->len)
++              return 0;
++
+       if (strncmp(str, r->pattern, r->len) == 0)
+               return 1;
+       return 0;
+diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
+index d2f6d0be3503..68bb89ad9d28 100644
+--- a/kernel/trace/trace_uprobe.c
++++ b/kernel/trace/trace_uprobe.c
+@@ -149,6 +149,8 @@ static void FETCH_FUNC_NAME(memory, string)(struct pt_regs 
*regs,
+               return;
+ 
+       ret = strncpy_from_user(dst, src, maxlen);
++      if (ret == maxlen)
++              dst[--ret] = '\0';
+ 
+       if (ret < 0) {  /* Failed to fetch string */
+               ((u8 *)get_rloc_data(dest))[0] = '\0';
+diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
+index ecd536de603a..eda85bbf1c2e 100644
+--- a/kernel/tracepoint.c
++++ b/kernel/tracepoint.c
+@@ -202,7 +202,7 @@ static int tracepoint_add_func(struct tracepoint *tp,
+                       lockdep_is_held(&tracepoints_mutex));
+       old = func_add(&tp_funcs, func, prio);
+       if (IS_ERR(old)) {
+-              WARN_ON_ONCE(1);
++              WARN_ON_ONCE(PTR_ERR(old) != -ENOMEM);
+               return PTR_ERR(old);
+       }
+ 
+@@ -235,7 +235,7 @@ static int tracepoint_remove_func(struct tracepoint *tp,
+                       lockdep_is_held(&tracepoints_mutex));
+       old = func_remove(&tp_funcs, func);
+       if (IS_ERR(old)) {
+-              WARN_ON_ONCE(1);
++              WARN_ON_ONCE(PTR_ERR(old) != -ENOMEM);
+               return PTR_ERR(old);
+       }
+ 
+diff --git a/mm/percpu.c b/mm/percpu.c
+index ef6353f0adbd..1c784df3bdfe 100644
+--- a/mm/percpu.c
++++ b/mm/percpu.c
+@@ -68,6 +68,7 @@
+ #include <linux/vmalloc.h>
+ #include <linux/workqueue.h>
+ #include <linux/kmemleak.h>
++#include <linux/sched.h>
+ 
+ #include <asm/cacheflush.h>
+ #include <asm/sections.h>
+diff --git a/net/atm/lec.c b/net/atm/lec.c
+index cd3b37989057..10e4066991b8 100644
+--- a/net/atm/lec.c
++++ b/net/atm/lec.c
+@@ -41,6 +41,9 @@ static unsigned char bridge_ula_lec[] = { 0x01, 0x80, 0xc2, 
0x00, 0x00 };
+ #include <linux/module.h>
+ #include <linux/init.h>
+ 
++/* Hardening for Spectre-v1 */
++#include <linux/nospec.h>
++
+ #include "lec.h"
+ #include "lec_arpc.h"
+ #include "resources.h"
+@@ -697,8 +700,10 @@ static int lec_vcc_attach(struct atm_vcc *vcc, void 
__user *arg)
+       bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc));
+       if (bytes_left != 0)
+               pr_info("copy from user failed for %d bytes\n", bytes_left);
+-      if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF ||
+-          !dev_lec[ioc_data.dev_num])
++      if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF)
++              return -EINVAL;
++      ioc_data.dev_num = array_index_nospec(ioc_data.dev_num, MAX_LEC_ITF);
++      if (!dev_lec[ioc_data.dev_num])
+               return -EINVAL;
+       vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL);
+       if (!vpriv)
+diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
+index c0548d268e1a..e3e6a3e2ca22 100644
+--- a/net/core/dev_addr_lists.c
++++ b/net/core/dev_addr_lists.c
+@@ -57,8 +57,8 @@ static int __hw_addr_add_ex(struct netdev_hw_addr_list *list,
+               return -EINVAL;
+ 
+       list_for_each_entry(ha, &list->list, list) {
+-              if (!memcmp(ha->addr, addr, addr_len) &&
+-                  ha->type == addr_type) {
++              if (ha->type == addr_type &&
++                  !memcmp(ha->addr, addr, addr_len)) {
+                       if (global) {
+                               /* check if addr is already used as global */
+                               if (ha->global_use)
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 7d3442594e0d..5668dd3f9969 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -827,6 +827,7 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, 
struct sk_buff *skb)
+       n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
+       n->cloned = 1;
+       n->nohdr = 0;
++      n->peeked = 0;
+       n->destructor = NULL;
+       C(tail);
+       C(end);
+diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
+index 6eb2bbf9873b..45fd82e61e79 100644
+--- a/net/dccp/ipv4.c
++++ b/net/dccp/ipv4.c
+@@ -618,6 +618,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff 
*skb)
+       ireq = inet_rsk(req);
+       sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr);
+       sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr);
++      ireq->ir_mark = inet_request_mark(sk, skb);
+       ireq->ireq_family = AF_INET;
+       ireq->ir_iif = sk->sk_bound_dev_if;
+ 
+diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
+index 09a9ab65f4e1..0bf41faeffc4 100644
+--- a/net/dccp/ipv6.c
++++ b/net/dccp/ipv6.c
+@@ -345,6 +345,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct 
sk_buff *skb)
+       ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr;
+       ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr;
+       ireq->ireq_family = AF_INET6;
++      ireq->ir_mark = inet_request_mark(sk, skb);
+ 
+       if (ipv6_opt_accepted(sk, skb, IP6CB(skb)) ||
+           np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
+diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
+index c67f9bd7699c..d8316869947a 100644
+--- a/net/ipv4/inet_timewait_sock.c
++++ b/net/ipv4/inet_timewait_sock.c
+@@ -182,6 +182,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct 
sock *sk,
+               tw->tw_dport        = inet->inet_dport;
+               tw->tw_family       = sk->sk_family;
+               tw->tw_reuse        = sk->sk_reuse;
++              tw->tw_reuseport    = sk->sk_reuseport;
+               tw->tw_hash         = sk->sk_hash;
+               tw->tw_ipv6only     = 0;
+               tw->tw_transparent  = inet->transparent;
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 82d2b55c953a..b531a0997664 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -2450,7 +2450,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
+       case TCP_REPAIR_QUEUE:
+               if (!tp->repair)
+                       err = -EPERM;
+-              else if (val < TCP_QUEUES_NR)
++              else if ((unsigned int)val < TCP_QUEUES_NR)
+                       tp->repair_queue = val;
+               else
+                       err = -EINVAL;
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index 33344f5a66a8..ec26a84b00e2 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -2663,8 +2663,9 @@ u64 ieee80211_calculate_rx_timestamp(struct 
ieee80211_local *local,
+ 
+       rate = cfg80211_calculate_bitrate(&ri);
+       if (WARN_ONCE(!rate,
+-                    "Invalid bitrate: flags=0x%x, idx=%d, vht_nss=%d\n",
+-                    status->flag, status->rate_idx, status->vht_nss))
++                    "Invalid bitrate: flags=0x%llx, idx=%d, vht_nss=%d\n",
++                    (unsigned long long)status->flag, status->rate_idx,
++                    status->vht_nss))
+               return 0;
+ 
+       /* rewind from end of MPDU */
+diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
+index efa3f48f1ec5..73e8f347802e 100644
+--- a/net/mac80211/wep.c
++++ b/net/mac80211/wep.c
+@@ -293,7 +293,8 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
+                       return RX_DROP_UNUSABLE;
+               ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
+               /* remove ICV */
+-              if (pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN))
++              if (!(status->flag & RX_FLAG_ICV_STRIPPED) &&
++                  pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN))
+                       return RX_DROP_UNUSABLE;
+       }
+ 
+diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
+index e19ea1c53afa..cb439e06919f 100644
+--- a/net/mac80211/wpa.c
++++ b/net/mac80211/wpa.c
+@@ -298,7 +298,8 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
+               return RX_DROP_UNUSABLE;
+ 
+       /* Trim ICV */
+-      skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN);
++      if (!(status->flag & RX_FLAG_ICV_STRIPPED))
++              skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN);
+ 
+       /* Remove IV */
+       memmove(skb->data + IEEE80211_TKIP_IV_LEN, skb->data, hdrlen);
+@@ -508,25 +509,31 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data 
*rx,
+           !ieee80211_is_robust_mgmt_frame(skb))
+               return RX_CONTINUE;
+ 
+-      data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len;
+-      if (!rx->sta || data_len < 0)
+-              return RX_DROP_UNUSABLE;
+-
+       if (status->flag & RX_FLAG_DECRYPTED) {
+               if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_CCMP_HDR_LEN))
+                       return RX_DROP_UNUSABLE;
++              if (status->flag & RX_FLAG_MIC_STRIPPED)
++                      mic_len = 0;
+       } else {
+               if (skb_linearize(rx->skb))
+                       return RX_DROP_UNUSABLE;
+       }
+ 
++      data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len;
++      if (!rx->sta || data_len < 0)
++              return RX_DROP_UNUSABLE;
++
+       if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
++              int res;
++
+               ccmp_hdr2pn(pn, skb->data + hdrlen);
+ 
+               queue = rx->security_idx;
+ 
+-              if (memcmp(pn, key->u.ccmp.rx_pn[queue],
+-                         IEEE80211_CCMP_PN_LEN) <= 0) {
++              res = memcmp(pn, key->u.ccmp.rx_pn[queue],
++                           IEEE80211_CCMP_PN_LEN);
++              if (res < 0 ||
++                  (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
+                       key->u.ccmp.replays++;
+                       return RX_DROP_UNUSABLE;
+               }
+@@ -724,8 +731,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
+       struct sk_buff *skb = rx->skb;
+       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+       u8 pn[IEEE80211_GCMP_PN_LEN];
+-      int data_len;
+-      int queue;
++      int data_len, queue, mic_len = IEEE80211_GCMP_MIC_LEN;
+ 
+       hdrlen = ieee80211_hdrlen(hdr->frame_control);
+ 
+@@ -733,26 +739,31 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data 
*rx)
+           !ieee80211_is_robust_mgmt_frame(skb))
+               return RX_CONTINUE;
+ 
+-      data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN -
+-                 IEEE80211_GCMP_MIC_LEN;
+-      if (!rx->sta || data_len < 0)
+-              return RX_DROP_UNUSABLE;
+-
+       if (status->flag & RX_FLAG_DECRYPTED) {
+               if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_GCMP_HDR_LEN))
+                       return RX_DROP_UNUSABLE;
++              if (status->flag & RX_FLAG_MIC_STRIPPED)
++                      mic_len = 0;
+       } else {
+               if (skb_linearize(rx->skb))
+                       return RX_DROP_UNUSABLE;
+       }
+ 
++      data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN - mic_len;
++      if (!rx->sta || data_len < 0)
++              return RX_DROP_UNUSABLE;
++
+       if (!(status->flag & RX_FLAG_PN_VALIDATED)) {
++              int res;
++
+               gcmp_hdr2pn(pn, skb->data + hdrlen);
+ 
+               queue = rx->security_idx;
+ 
+-              if (memcmp(pn, key->u.gcmp.rx_pn[queue],
+-                         IEEE80211_GCMP_PN_LEN) <= 0) {
++              res = memcmp(pn, key->u.gcmp.rx_pn[queue],
++                           IEEE80211_GCMP_PN_LEN);
++              if (res < 0 ||
++                  (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) {
+                       key->u.gcmp.replays++;
+                       return RX_DROP_UNUSABLE;
+               }
+@@ -776,7 +787,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx)
+       }
+ 
+       /* Remove GCMP header and MIC */
+-      if (pskb_trim(skb, skb->len - IEEE80211_GCMP_MIC_LEN))
++      if (pskb_trim(skb, skb->len - mic_len))
+               return RX_DROP_UNUSABLE;
+       memmove(skb->data + IEEE80211_GCMP_HDR_LEN, skb->data, hdrlen);
+       skb_pull(skb, IEEE80211_GCMP_HDR_LEN);
+diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
+index 2f0e4f61c40f..c0656510c4dc 100644
+--- a/net/netfilter/ipvs/ip_vs_ctl.c
++++ b/net/netfilter/ipvs/ip_vs_ctl.c
+@@ -2352,11 +2352,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user 
*user, unsigned int len)
+                       strlcpy(cfg.mcast_ifn, dm->mcast_ifn,
+                               sizeof(cfg.mcast_ifn));
+                       cfg.syncid = dm->syncid;
+-                      rtnl_lock();
+-                      mutex_lock(&ipvs->sync_mutex);
+                       ret = start_sync_thread(ipvs, &cfg, dm->state);
+-                      mutex_unlock(&ipvs->sync_mutex);
+-                      rtnl_unlock();
+               } else {
+                       mutex_lock(&ipvs->sync_mutex);
+                       ret = stop_sync_thread(ipvs, dm->state);
+@@ -3435,12 +3431,8 @@ static int ip_vs_genl_new_daemon(struct netns_ipvs 
*ipvs, struct nlattr **attrs)
+       if (ipvs->mixed_address_family_dests > 0)
+               return -EINVAL;
+ 
+-      rtnl_lock();
+-      mutex_lock(&ipvs->sync_mutex);
+       ret = start_sync_thread(ipvs, &c,
+                               nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE]));
+-      mutex_unlock(&ipvs->sync_mutex);
+-      rtnl_unlock();
+       return ret;
+ }
+ 
+diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
+index 1b07578bedf3..cec7234b7a1d 100644
+--- a/net/netfilter/ipvs/ip_vs_sync.c
++++ b/net/netfilter/ipvs/ip_vs_sync.c
+@@ -48,6 +48,7 @@
+ #include <linux/kthread.h>
+ #include <linux/wait.h>
+ #include <linux/kernel.h>
++#include <linux/sched.h>
+ 
+ #include <asm/unaligned.h>            /* Used for ntoh_seq and hton_seq */
+ 
+@@ -1356,15 +1357,9 @@ static void set_mcast_pmtudisc(struct sock *sk, int val)
+ /*
+  *      Specifiy default interface for outgoing multicasts
+  */
+-static int set_mcast_if(struct sock *sk, char *ifname)
++static int set_mcast_if(struct sock *sk, struct net_device *dev)
+ {
+-      struct net_device *dev;
+       struct inet_sock *inet = inet_sk(sk);
+-      struct net *net = sock_net(sk);
+-
+-      dev = __dev_get_by_name(net, ifname);
+-      if (!dev)
+-              return -ENODEV;
+ 
+       if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if)
+               return -EINVAL;
+@@ -1392,19 +1387,14 @@ static int set_mcast_if(struct sock *sk, char *ifname)
+  *      in the in_addr structure passed in as a parameter.
+  */
+ static int
+-join_mcast_group(struct sock *sk, struct in_addr *addr, char *ifname)
++join_mcast_group(struct sock *sk, struct in_addr *addr, struct net_device 
*dev)
+ {
+-      struct net *net = sock_net(sk);
+       struct ip_mreqn mreq;
+-      struct net_device *dev;
+       int ret;
+ 
+       memset(&mreq, 0, sizeof(mreq));
+       memcpy(&mreq.imr_multiaddr, addr, sizeof(struct in_addr));
+ 
+-      dev = __dev_get_by_name(net, ifname);
+-      if (!dev)
+-              return -ENODEV;
+       if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if)
+               return -EINVAL;
+ 
+@@ -1419,15 +1409,10 @@ join_mcast_group(struct sock *sk, struct in_addr 
*addr, char *ifname)
+ 
+ #ifdef CONFIG_IP_VS_IPV6
+ static int join_mcast_group6(struct sock *sk, struct in6_addr *addr,
+-                           char *ifname)
++                           struct net_device *dev)
+ {
+-      struct net *net = sock_net(sk);
+-      struct net_device *dev;
+       int ret;
+ 
+-      dev = __dev_get_by_name(net, ifname);
+-      if (!dev)
+-              return -ENODEV;
+       if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if)
+               return -EINVAL;
+ 
+@@ -1439,24 +1424,18 @@ static int join_mcast_group6(struct sock *sk, struct 
in6_addr *addr,
+ }
+ #endif
+ 
+-static int bind_mcastif_addr(struct socket *sock, char *ifname)
++static int bind_mcastif_addr(struct socket *sock, struct net_device *dev)
+ {
+-      struct net *net = sock_net(sock->sk);
+-      struct net_device *dev;
+       __be32 addr;
+       struct sockaddr_in sin;
+ 
+-      dev = __dev_get_by_name(net, ifname);
+-      if (!dev)
+-              return -ENODEV;
+-
+       addr = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE);
+       if (!addr)
+               pr_err("You probably need to specify IP address on "
+                      "multicast interface.\n");
+ 
+       IP_VS_DBG(7, "binding socket with (%s) %pI4\n",
+-                ifname, &addr);
++                dev->name, &addr);
+ 
+       /* Now bind the socket with the address of multicast interface */
+       sin.sin_family       = AF_INET;
+@@ -1489,7 +1468,8 @@ static void get_mcast_sockaddr(union ipvs_sockaddr *sa, 
int *salen,
+ /*
+  *      Set up sending multicast socket over UDP
+  */
+-static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id)
++static int make_send_sock(struct netns_ipvs *ipvs, int id,
++                        struct net_device *dev, struct socket **sock_ret)
+ {
+       /* multicast addr */
+       union ipvs_sockaddr mcast_addr;
+@@ -1501,9 +1481,10 @@ static struct socket *make_send_sock(struct netns_ipvs 
*ipvs, int id)
+                                 IPPROTO_UDP, &sock);
+       if (result < 0) {
+               pr_err("Error during creation of socket; terminating\n");
+-              return ERR_PTR(result);
++              goto error;
+       }
+-      result = set_mcast_if(sock->sk, ipvs->mcfg.mcast_ifn);
++      *sock_ret = sock;
++      result = set_mcast_if(sock->sk, dev);
+       if (result < 0) {
+               pr_err("Error setting outbound mcast interface\n");
+               goto error;
+@@ -1518,7 +1499,7 @@ static struct socket *make_send_sock(struct netns_ipvs 
*ipvs, int id)
+               set_sock_size(sock->sk, 1, result);
+ 
+       if (AF_INET == ipvs->mcfg.mcast_af)
+-              result = bind_mcastif_addr(sock, ipvs->mcfg.mcast_ifn);
++              result = bind_mcastif_addr(sock, dev);
+       else
+               result = 0;
+       if (result < 0) {
+@@ -1534,19 +1515,18 @@ static struct socket *make_send_sock(struct netns_ipvs 
*ipvs, int id)
+               goto error;
+       }
+ 
+-      return sock;
++      return 0;
+ 
+ error:
+-      sock_release(sock);
+-      return ERR_PTR(result);
++      return result;
+ }
+ 
+ 
+ /*
+  *      Set up receiving multicast socket over UDP
+  */
+-static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id,
+-                                      int ifindex)
++static int make_receive_sock(struct netns_ipvs *ipvs, int id,
++                           struct net_device *dev, struct socket **sock_ret)
+ {
+       /* multicast addr */
+       union ipvs_sockaddr mcast_addr;
+@@ -1558,8 +1538,9 @@ static struct socket *make_receive_sock(struct 
netns_ipvs *ipvs, int id,
+                                 IPPROTO_UDP, &sock);
+       if (result < 0) {
+               pr_err("Error during creation of socket; terminating\n");
+-              return ERR_PTR(result);
++              goto error;
+       }
++      *sock_ret = sock;
+       /* it is equivalent to the REUSEADDR option in user-space */
+       sock->sk->sk_reuse = SK_CAN_REUSE;
+       result = sysctl_sync_sock_size(ipvs);
+@@ -1567,7 +1548,7 @@ static struct socket *make_receive_sock(struct 
netns_ipvs *ipvs, int id,
+               set_sock_size(sock->sk, 0, result);
+ 
+       get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id);
+-      sock->sk->sk_bound_dev_if = ifindex;
++      sock->sk->sk_bound_dev_if = dev->ifindex;
+       result = sock->ops->bind(sock, (struct sockaddr *)&mcast_addr, salen);
+       if (result < 0) {
+               pr_err("Error binding to the multicast addr\n");
+@@ -1578,21 +1559,20 @@ static struct socket *make_receive_sock(struct 
netns_ipvs *ipvs, int id,
+ #ifdef CONFIG_IP_VS_IPV6
+       if (ipvs->bcfg.mcast_af == AF_INET6)
+               result = join_mcast_group6(sock->sk, &mcast_addr.in6.sin6_addr,
+-                                         ipvs->bcfg.mcast_ifn);
++                                         dev);
+       else
+ #endif
+               result = join_mcast_group(sock->sk, &mcast_addr.in.sin_addr,
+-                                        ipvs->bcfg.mcast_ifn);
++                                        dev);
+       if (result < 0) {
+               pr_err("Error joining to the multicast group\n");
+               goto error;
+       }
+ 
+-      return sock;
++      return 0;
+ 
+ error:
+-      sock_release(sock);
+-      return ERR_PTR(result);
++      return result;
+ }
+ 
+ 
+@@ -1777,13 +1757,12 @@ static int sync_thread_backup(void *data)
+ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
+                     int state)
+ {
+-      struct ip_vs_sync_thread_data *tinfo;
++      struct ip_vs_sync_thread_data *tinfo = NULL;
+       struct task_struct **array = NULL, *task;
+-      struct socket *sock;
+       struct net_device *dev;
+       char *name;
+       int (*threadfn)(void *data);
+-      int id, count, hlen;
++      int id = 0, count, hlen;
+       int result = -ENOMEM;
+       u16 mtu, min_mtu;
+ 
+@@ -1791,6 +1770,18 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct 
ipvs_sync_daemon_cfg *c,
+       IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %Zd bytes\n",
+                 sizeof(struct ip_vs_sync_conn_v0));
+ 
++      /* Do not hold one mutex and then to block on another */
++      for (;;) {
++              rtnl_lock();
++              if (mutex_trylock(&ipvs->sync_mutex))
++                      break;
++              rtnl_unlock();
++              mutex_lock(&ipvs->sync_mutex);
++              if (rtnl_trylock())
++                      break;
++              mutex_unlock(&ipvs->sync_mutex);
++      }
++
+       if (!ipvs->sync_state) {
+               count = clamp(sysctl_sync_ports(ipvs), 1, IPVS_SYNC_PORTS_MAX);
+               ipvs->threads_mask = count - 1;
+@@ -1809,7 +1800,8 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct 
ipvs_sync_daemon_cfg *c,
+       dev = __dev_get_by_name(ipvs->net, c->mcast_ifn);
+       if (!dev) {
+               pr_err("Unknown mcast interface: %s\n", c->mcast_ifn);
+-              return -ENODEV;
++              result = -ENODEV;
++              goto out_early;
+       }
+       hlen = (AF_INET6 == c->mcast_af) ?
+              sizeof(struct ipv6hdr) + sizeof(struct udphdr) :
+@@ -1826,26 +1818,30 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct 
ipvs_sync_daemon_cfg *c,
+               c->sync_maxlen = mtu - hlen;
+ 
+       if (state == IP_VS_STATE_MASTER) {
++              result = -EEXIST;
+               if (ipvs->ms)
+-                      return -EEXIST;
++                      goto out_early;
+ 
+               ipvs->mcfg = *c;
+               name = "ipvs-m:%d:%d";
+               threadfn = sync_thread_master;
+       } else if (state == IP_VS_STATE_BACKUP) {
++              result = -EEXIST;
+               if (ipvs->backup_threads)
+-                      return -EEXIST;
++                      goto out_early;
+ 
+               ipvs->bcfg = *c;
+               name = "ipvs-b:%d:%d";
+               threadfn = sync_thread_backup;
+       } else {
+-              return -EINVAL;
++              result = -EINVAL;
++              goto out_early;
+       }
+ 
+       if (state == IP_VS_STATE_MASTER) {
+               struct ipvs_master_sync_state *ms;
+ 
++              result = -ENOMEM;
+               ipvs->ms = kzalloc(count * sizeof(ipvs->ms[0]), GFP_KERNEL);
+               if (!ipvs->ms)
+                       goto out;
+@@ -1861,39 +1857,38 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct 
ipvs_sync_daemon_cfg *c,
+       } else {
+               array = kzalloc(count * sizeof(struct task_struct *),
+                               GFP_KERNEL);
++              result = -ENOMEM;
+               if (!array)
+                       goto out;
+       }
+ 
+-      tinfo = NULL;
+       for (id = 0; id < count; id++) {
+-              if (state == IP_VS_STATE_MASTER)
+-                      sock = make_send_sock(ipvs, id);
+-              else
+-                      sock = make_receive_sock(ipvs, id, dev->ifindex);
+-              if (IS_ERR(sock)) {
+-                      result = PTR_ERR(sock);
+-                      goto outtinfo;
+-              }
++              result = -ENOMEM;
+               tinfo = kmalloc(sizeof(*tinfo), GFP_KERNEL);
+               if (!tinfo)
+-                      goto outsocket;
++                      goto out;
+               tinfo->ipvs = ipvs;
+-              tinfo->sock = sock;
++              tinfo->sock = NULL;
+               if (state == IP_VS_STATE_BACKUP) {
+                       tinfo->buf = kmalloc(ipvs->bcfg.sync_maxlen,
+                                            GFP_KERNEL);
+                       if (!tinfo->buf)
+-                              goto outtinfo;
++                              goto out;
+               } else {
+                       tinfo->buf = NULL;
+               }
+               tinfo->id = id;
++              if (state == IP_VS_STATE_MASTER)
++                      result = make_send_sock(ipvs, id, dev, &tinfo->sock);
++              else
++                      result = make_receive_sock(ipvs, id, dev, &tinfo->sock);
++              if (result < 0)
++                      goto out;
+ 
+               task = kthread_run(threadfn, tinfo, name, ipvs->gen, id);
+               if (IS_ERR(task)) {
+                       result = PTR_ERR(task);
+-                      goto outtinfo;
++                      goto out;
+               }
+               tinfo = NULL;
+               if (state == IP_VS_STATE_MASTER)
+@@ -1910,20 +1905,20 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct 
ipvs_sync_daemon_cfg *c,
+       ipvs->sync_state |= state;
+       spin_unlock_bh(&ipvs->sync_buff_lock);
+ 
++      mutex_unlock(&ipvs->sync_mutex);
++      rtnl_unlock();
++
+       /* increase the module use count */
+       ip_vs_use_count_inc();
+ 
+       return 0;
+ 
+-outsocket:
+-      sock_release(sock);
+-
+-outtinfo:
+-      if (tinfo) {
+-              sock_release(tinfo->sock);
+-              kfree(tinfo->buf);
+-              kfree(tinfo);
+-      }
++out:
++      /* We do not need RTNL lock anymore, release it here so that
++       * sock_release below and in the kthreads can use rtnl_lock
++       * to leave the mcast group.
++       */
++      rtnl_unlock();
+       count = id;
+       while (count-- > 0) {
+               if (state == IP_VS_STATE_MASTER)
+@@ -1931,13 +1926,23 @@ outtinfo:
+               else
+                       kthread_stop(array[count]);
+       }
+-      kfree(array);
+-
+-out:
+       if (!(ipvs->sync_state & IP_VS_STATE_MASTER)) {
+               kfree(ipvs->ms);
+               ipvs->ms = NULL;
+       }
++      mutex_unlock(&ipvs->sync_mutex);
++      if (tinfo) {
++              if (tinfo->sock)
++                      sock_release(tinfo->sock);
++              kfree(tinfo->buf);
++              kfree(tinfo);
++      }
++      kfree(array);
++      return result;
++
++out_early:
++      mutex_unlock(&ipvs->sync_mutex);
++      rtnl_unlock();
+       return result;
+ }
+ 
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 98fe9691337c..818400fddc9b 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1795,6 +1795,8 @@ static int netlink_sendmsg(struct socket *sock, struct 
msghdr *msg, size_t len)
+ 
+       if (msg->msg_namelen) {
+               err = -EINVAL;
++              if (msg->msg_namelen < sizeof(struct sockaddr_nl))
++                      goto out;
+               if (addr->nl_family != AF_NETLINK)
+                       goto out;
+               dst_portid = addr->nl_pid;
+diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
+index 93127220cb54..e6e249cc651c 100644
+--- a/net/rfkill/rfkill-gpio.c
++++ b/net/rfkill/rfkill-gpio.c
+@@ -140,13 +140,18 @@ static int rfkill_gpio_probe(struct platform_device 
*pdev)
+ 
+       ret = rfkill_register(rfkill->rfkill_dev);
+       if (ret < 0)
+-              return ret;
++              goto err_destroy;
+ 
+       platform_set_drvdata(pdev, rfkill);
+ 
+       dev_info(&pdev->dev, "%s device registered.\n", rfkill->name);
+ 
+       return 0;
++
++err_destroy:
++      rfkill_destroy(rfkill->rfkill_dev);
++
++      return ret;
+ }
+ 
+ static int rfkill_gpio_remove(struct platform_device *pdev)
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+index 5d9f25cb6426..90270d7110a3 100644
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -2480,7 +2480,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh)
+ 
+ #ifdef CONFIG_COMPAT
+       if (is_compat_task())
+-              return -ENOTSUPP;
++              return -EOPNOTSUPP;
+ #endif
+ 
+       type = nlh->nlmsg_type;
+diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
+index 1f64ab0c2a95..7ae080bae15c 100644
+--- a/sound/core/pcm_compat.c
++++ b/sound/core/pcm_compat.c
+@@ -426,6 +426,8 @@ static int snd_pcm_ioctl_xfern_compat(struct 
snd_pcm_substream *substream,
+               return -ENOTTY;
+       if (substream->stream != dir)
+               return -EINVAL;
++      if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
++              return -EBADFD;
+ 
+       if ((ch = substream->runtime->channels) > 128)
+               return -EINVAL;
+diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
+index 3b126af4a026..ef494ffc1369 100644
+--- a/sound/core/seq/seq_virmidi.c
++++ b/sound/core/seq/seq_virmidi.c
+@@ -174,12 +174,12 @@ static void snd_virmidi_output_trigger(struct 
snd_rawmidi_substream *substream,
+                       }
+                       return;
+               }
++              spin_lock_irqsave(&substream->runtime->lock, flags);
+               if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
+                       if (snd_seq_kernel_client_dispatch(vmidi->client, 
&vmidi->event, in_atomic(), 0) < 0)
+-                              return;
++                              goto out;
+                       vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
+               }
+-              spin_lock_irqsave(&substream->runtime->lock, flags);
+               while (1) {
+                       count = __snd_rawmidi_transmit_peek(substream, buf, 
sizeof(buf));
+                       if (count <= 0)
+diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
+index dc91002d1e0d..847f70348d4d 100644
+--- a/sound/drivers/aloop.c
++++ b/sound/drivers/aloop.c
+@@ -296,6 +296,8 @@ static int loopback_trigger(struct snd_pcm_substream 
*substream, int cmd)
+               cable->pause |= stream;
+               loopback_timer_stop(dpcm);
+               spin_unlock(&cable->lock);
++              if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++                      loopback_active_notify(dpcm);
+               break;
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+       case SNDRV_PCM_TRIGGER_RESUME:
+@@ -304,6 +306,8 @@ static int loopback_trigger(struct snd_pcm_substream 
*substream, int cmd)
+               cable->pause &= ~stream;
+               loopback_timer_start(dpcm);
+               spin_unlock(&cable->lock);
++              if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++                      loopback_active_notify(dpcm);
+               break;
+       default:
+               return -EINVAL;
+@@ -828,9 +832,11 @@ static int loopback_rate_shift_get(struct snd_kcontrol 
*kcontrol,
+ {
+       struct loopback *loopback = snd_kcontrol_chip(kcontrol);
+       
++      mutex_lock(&loopback->cable_lock);
+       ucontrol->value.integer.value[0] =
+               loopback->setup[kcontrol->id.subdevice]
+                              [kcontrol->id.device].rate_shift;
++      mutex_unlock(&loopback->cable_lock);
+       return 0;
+ }
+ 
+@@ -862,9 +868,11 @@ static int loopback_notify_get(struct snd_kcontrol 
*kcontrol,
+ {
+       struct loopback *loopback = snd_kcontrol_chip(kcontrol);
+       
++      mutex_lock(&loopback->cable_lock);
+       ucontrol->value.integer.value[0] =
+               loopback->setup[kcontrol->id.subdevice]
+                              [kcontrol->id.device].notify;
++      mutex_unlock(&loopback->cable_lock);
+       return 0;
+ }
+ 
+@@ -876,12 +884,14 @@ static int loopback_notify_put(struct snd_kcontrol 
*kcontrol,
+       int change = 0;
+ 
+       val = ucontrol->value.integer.value[0] ? 1 : 0;
++      mutex_lock(&loopback->cable_lock);
+       if (val != loopback->setup[kcontrol->id.subdevice]
+                               [kcontrol->id.device].notify) {
+               loopback->setup[kcontrol->id.subdevice]
+                       [kcontrol->id.device].notify = val;
+               change = 1;
+       }
++      mutex_unlock(&loopback->cable_lock);
+       return change;
+ }
+ 
+@@ -889,13 +899,18 @@ static int loopback_active_get(struct snd_kcontrol 
*kcontrol,
+                              struct snd_ctl_elem_value *ucontrol)
+ {
+       struct loopback *loopback = snd_kcontrol_chip(kcontrol);
+-      struct loopback_cable *cable = loopback->cables
+-                      [kcontrol->id.subdevice][kcontrol->id.device ^ 1];
++      struct loopback_cable *cable;
++
+       unsigned int val = 0;
+ 
+-      if (cable != NULL)
+-              val = (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
+-                                                                      1 : 0;
++      mutex_lock(&loopback->cable_lock);
++      cable = loopback->cables[kcontrol->id.subdevice][kcontrol->id.device ^ 
1];
++      if (cable != NULL) {
++              unsigned int running = cable->running ^ cable->pause;
++
++              val = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? 1 : 0;
++      }
++      mutex_unlock(&loopback->cable_lock);
+       ucontrol->value.integer.value[0] = val;
+       return 0;
+ }
+@@ -938,9 +953,11 @@ static int loopback_rate_get(struct snd_kcontrol 
*kcontrol,
+ {
+       struct loopback *loopback = snd_kcontrol_chip(kcontrol);
+       
++      mutex_lock(&loopback->cable_lock);
+       ucontrol->value.integer.value[0] =
+               loopback->setup[kcontrol->id.subdevice]
+                              [kcontrol->id.device].rate;
++      mutex_unlock(&loopback->cable_lock);
+       return 0;
+ }
+ 
+@@ -960,9 +977,11 @@ static int loopback_channels_get(struct snd_kcontrol 
*kcontrol,
+ {
+       struct loopback *loopback = snd_kcontrol_chip(kcontrol);
+       
++      mutex_lock(&loopback->cable_lock);
+       ucontrol->value.integer.value[0] =
+               loopback->setup[kcontrol->id.subdevice]
+                              [kcontrol->id.device].channels;
++      mutex_unlock(&loopback->cable_lock);
+       return 0;
+ }
+ 
+diff --git a/tools/testing/selftests/firmware/fw_filesystem.sh 
b/tools/testing/selftests/firmware/fw_filesystem.sh
+index 61f9b1dbbd9b..63c310cdac09 100755
+--- a/tools/testing/selftests/firmware/fw_filesystem.sh
++++ b/tools/testing/selftests/firmware/fw_filesystem.sh
+@@ -29,9 +29,11 @@ test_finish()
+               echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout
+       fi
+       if [ "$OLD_FWPATH" = "" ]; then
+-              OLD_FWPATH=" "
++              # A zero-length write won't work; write a null byte
++              printf '\000' >/sys/module/firmware_class/parameters/path
++      else
++              echo -n "$OLD_FWPATH" 
>/sys/module/firmware_class/parameters/path
+       fi
+-      echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path
+       rm -f "$FW"
+       rmdir "$FWPATH"
+ }

Reply via email to