--- /dev/null
+From 3d584a3c85d6fe2cf878f220d4ad7145e7f89218 Mon Sep 17 00:00:00 2001
+From: Anders Roxell <anders.roxell@linaro.org>
+Date: Fri, 26 Jul 2019 13:27:05 +0200
+Subject: arm64: KVM: regmap: Fix unexpected switch fall-through
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Anders Roxell <anders.roxell@linaro.org>
+
+commit 3d584a3c85d6fe2cf878f220d4ad7145e7f89218 upstream.
+
+When fall-through warnings was enabled by default, commit d93512ef0f0e
+("Makefile: Globally enable fall-through warning"), the following
+warnings was starting to show up:
+
+In file included from ../arch/arm64/include/asm/kvm_emulate.h:19,
+ from ../arch/arm64/kvm/regmap.c:13:
+../arch/arm64/kvm/regmap.c: In function ‘vcpu_write_spsr32’:
+../arch/arm64/include/asm/kvm_hyp.h:31:3: warning: this statement may fall
+ through [-Wimplicit-fallthrough=]
+ asm volatile(ALTERNATIVE(__msr_s(r##nvh, "%x0"), \
+ ^~~
+../arch/arm64/include/asm/kvm_hyp.h:46:31: note: in expansion of macro ‘write_sysreg_elx’
+ #define write_sysreg_el1(v,r) write_sysreg_elx(v, r, _EL1, _EL12)
+ ^~~~~~~~~~~~~~~~
+../arch/arm64/kvm/regmap.c:180:3: note: in expansion of macro ‘write_sysreg_el1’
+ write_sysreg_el1(v, SYS_SPSR);
+ ^~~~~~~~~~~~~~~~
+../arch/arm64/kvm/regmap.c:181:2: note: here
+ case KVM_SPSR_ABT:
+ ^~~~
+In file included from ../arch/arm64/include/asm/cputype.h:132,
+ from ../arch/arm64/include/asm/cache.h:8,
+ from ../include/linux/cache.h:6,
+ from ../include/linux/printk.h:9,
+ from ../include/linux/kernel.h:15,
+ from ../include/asm-generic/bug.h:18,
+ from ../arch/arm64/include/asm/bug.h:26,
+ from ../include/linux/bug.h:5,
+ from ../include/linux/mmdebug.h:5,
+ from ../include/linux/mm.h:9,
+ from ../arch/arm64/kvm/regmap.c:11:
+../arch/arm64/include/asm/sysreg.h:837:2: warning: this statement may fall
+ through [-Wimplicit-fallthrough=]
+ asm volatile("msr " __stringify(r) ", %x0" \
+ ^~~
+../arch/arm64/kvm/regmap.c:182:3: note: in expansion of macro ‘write_sysreg’
+ write_sysreg(v, spsr_abt);
+ ^~~~~~~~~~~~
+../arch/arm64/kvm/regmap.c:183:2: note: here
+ case KVM_SPSR_UND:
+ ^~~~
+
+Rework to add a 'break;' in the swich-case since it didn't have that,
+leading to an interresting set of bugs.
+
+Cc: stable@vger.kernel.org # v4.17+
+Fixes: a892819560c4 ("KVM: arm64: Prepare to handle deferred save/restore of 32-bit registers")
+Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
+[maz: reworked commit message, fixed stable range]
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ arch/arm64/kvm/regmap.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm64/kvm/regmap.c
++++ b/arch/arm64/kvm/regmap.c
+@@ -178,13 +178,18 @@ void vcpu_write_spsr32(struct kvm_vcpu *
+ switch (spsr_idx) {
+ case KVM_SPSR_SVC:
+ write_sysreg_el1(v, spsr);
++ break;
+ case KVM_SPSR_ABT:
+ write_sysreg(v, spsr_abt);
++ break;
+ case KVM_SPSR_UND:
+ write_sysreg(v, spsr_und);
++ break;
+ case KVM_SPSR_IRQ:
+ write_sysreg(v, spsr_irq);
++ break;
+ case KVM_SPSR_FIQ:
+ write_sysreg(v, spsr_fiq);
++ break;
+ }
+ }
--- /dev/null
+From b9ddd5091160793ee9fac10da765cf3f53d2aaf0 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Mon, 5 Aug 2019 17:55:15 +0200
+Subject: iio: adc: max9611: Fix temperature reading in probe
+
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+
+commit b9ddd5091160793ee9fac10da765cf3f53d2aaf0 upstream.
+
+The max9611 driver reads the die temperature at probe time to validate
+the communication channel. Use the actual read value to perform the test
+instead of the read function return value, which was mistakenly used so
+far.
+
+The temperature reading test was only successful because the 0 return
+value is in the range of supported temperatures.
+
+Fixes: 69780a3bbc0b ("iio: adc: Add Maxim max9611 ADC driver")
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/max9611.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/adc/max9611.c
++++ b/drivers/iio/adc/max9611.c
+@@ -480,7 +480,7 @@ static int max9611_init(struct max9611_d
+ if (ret)
+ return ret;
+
+- regval = ret & MAX9611_TEMP_MASK;
++ regval &= MAX9611_TEMP_MASK;
+
+ if ((regval > MAX9611_TEMP_MAX_POS &&
+ regval < MAX9611_TEMP_MIN_NEG) ||
page-flags-prioritize-kasan-bits-over-last-cpuid.patch
asm-generic-fix-wtype-limits-compiler-warnings.patch
tpm-tpm_ibm_vtpm-fix-unallocated-banks.patch
+arm64-kvm-regmap-fix-unexpected-switch-fall-through.patch
+staging-comedi-dt3000-fix-signed-integer-overflow-divider-base.patch
+staging-comedi-dt3000-fix-rounding-up-of-timer-divisor.patch
+iio-adc-max9611-fix-temperature-reading-in-probe.patch
+x86-boot-save-fields-explicitly-zero-out-everything-else.patch
+usb-core-fix-races-in-character-device-registration-and-deregistraion.patch
+usb-gadget-udc-renesas_usb3-fix-sysfs-interface-of-role.patch
+usb-cdc-acm-make-sure-a-refcount-is-taken-early-enough.patch
+usb-cdc-fix-sanity-checks-in-cdc-union-parser.patch
+usb-serial-option-add-d-link-dwm-222-device-id.patch
+usb-serial-option-add-support-for-zte-mf871a.patch
+usb-serial-option-add-the-broadmobi-bm818-card.patch
+usb-serial-option-add-motorola-modem-uarts.patch
+usb-setup-authorized_default-attributes-using-usb_bus_notify.patch
--- /dev/null
+From 8e2a589a3fc36ce858d42e767c3bcd8fc62a512b Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti@mev.co.uk>
+Date: Mon, 12 Aug 2019 13:08:14 +0100
+Subject: staging: comedi: dt3000: Fix rounding up of timer divisor
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+commit 8e2a589a3fc36ce858d42e767c3bcd8fc62a512b upstream.
+
+`dt3k_ns_to_timer()` determines the prescaler and divisor to use to
+produce a desired timing period. It is influenced by a rounding mode
+and can round the divisor up, down, or to the nearest value. However,
+the code for rounding up currently does the same as rounding down! Fix
+ir by using the `DIV_ROUND_UP()` macro to calculate the divisor when
+rounding up.
+
+Also, change the types of the `divider`, `base` and `prescale` variables
+from `int` to `unsigned int` to avoid mixing signed and unsigned types
+in the calculations.
+
+Also fix a typo in a nearby comment: "improvment" => "improvement".
+
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20190812120814.21188-1-abbotti@mev.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/comedi/drivers/dt3000.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/comedi/drivers/dt3000.c
++++ b/drivers/staging/comedi/drivers/dt3000.c
+@@ -342,9 +342,9 @@ static irqreturn_t dt3k_interrupt(int ir
+ static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
+ unsigned int flags)
+ {
+- int divider, base, prescale;
++ unsigned int divider, base, prescale;
+
+- /* This function needs improvment */
++ /* This function needs improvement */
+ /* Don't know if divider==0 works. */
+
+ for (prescale = 0; prescale < 16; prescale++) {
+@@ -358,7 +358,7 @@ static int dt3k_ns_to_timer(unsigned int
+ divider = (*nanosec) / base;
+ break;
+ case CMDF_ROUND_UP:
+- divider = (*nanosec) / base;
++ divider = DIV_ROUND_UP(*nanosec, base);
+ break;
+ }
+ if (divider < 65536) {
--- /dev/null
+From b4d98bc3fc93ec3a58459948a2c0e0c9b501cd88 Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti@mev.co.uk>
+Date: Mon, 12 Aug 2019 12:15:17 +0100
+Subject: staging: comedi: dt3000: Fix signed integer overflow 'divider * base'
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+commit b4d98bc3fc93ec3a58459948a2c0e0c9b501cd88 upstream.
+
+In `dt3k_ns_to_timer()` the following lines near the end of the function
+result in a signed integer overflow:
+
+ prescale = 15;
+ base = timer_base * (1 << prescale);
+ divider = 65535;
+ *nanosec = divider * base;
+
+(`divider`, `base` and `prescale` are type `int`, `timer_base` and
+`*nanosec` are type `unsigned int`. The value of `timer_base` will be
+either 50 or 100.)
+
+The main reason for the overflow is that the calculation for `base` is
+completely wrong. It should be:
+
+ base = timer_base * (prescale + 1);
+
+which matches an earlier instance of this calculation in the same
+function.
+
+Reported-by: David Binderman <dcb314@hotmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Link: https://lore.kernel.org/r/20190812111517.26803-1-abbotti@mev.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/comedi/drivers/dt3000.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/comedi/drivers/dt3000.c
++++ b/drivers/staging/comedi/drivers/dt3000.c
+@@ -368,7 +368,7 @@ static int dt3k_ns_to_timer(unsigned int
+ }
+
+ prescale = 15;
+- base = timer_base * (1 << prescale);
++ base = timer_base * (prescale + 1);
+ divider = 65535;
+ *nanosec = divider * base;
+ return (prescale << 16) | (divider);
--- /dev/null
+From c52873e5a1ef72f845526d9f6a50704433f9c625 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Thu, 8 Aug 2019 16:21:19 +0200
+Subject: usb: cdc-acm: make sure a refcount is taken early enough
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit c52873e5a1ef72f845526d9f6a50704433f9c625 upstream.
+
+destroy() will decrement the refcount on the interface, so that
+it needs to be taken so early that it never undercounts.
+
+Fixes: 7fb57a019f94e ("USB: cdc-acm: Fix potential deadlock (lockdep warning)")
+Cc: stable <stable@vger.kernel.org>
+Reported-and-tested-by: syzbot+1b2449b7b5dc240d107a@syzkaller.appspotmail.com
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Link: https://lore.kernel.org/r/20190808142119.7998-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1301,10 +1301,6 @@ made_compressed_probe:
+ tty_port_init(&acm->port);
+ acm->port.ops = &acm_port_ops;
+
+- minor = acm_alloc_minor(acm);
+- if (minor < 0)
+- goto alloc_fail1;
+-
+ ctrlsize = usb_endpoint_maxp(epctrl);
+ readsize = usb_endpoint_maxp(epread) *
+ (quirks == SINGLE_RX_URB ? 1 : 2);
+@@ -1312,6 +1308,13 @@ made_compressed_probe:
+ acm->writesize = usb_endpoint_maxp(epwrite) * 20;
+ acm->control = control_interface;
+ acm->data = data_interface;
++
++ usb_get_intf(acm->control); /* undone in destruct() */
++
++ minor = acm_alloc_minor(acm);
++ if (minor < 0)
++ goto alloc_fail1;
++
+ acm->minor = minor;
+ acm->dev = usb_dev;
+ if (h.usb_cdc_acm_descriptor)
+@@ -1458,7 +1461,6 @@ skip_countries:
+ usb_driver_claim_interface(&acm_driver, data_interface, acm);
+ usb_set_intfdata(data_interface, acm);
+
+- usb_get_intf(control_interface);
+ tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor,
+ &control_interface->dev);
+ if (IS_ERR(tty_dev)) {
--- /dev/null
+From 54364278fb3cabdea51d6398b07c87415065b3fc Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Tue, 13 Aug 2019 11:35:41 +0200
+Subject: USB: CDC: fix sanity checks in CDC union parser
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 54364278fb3cabdea51d6398b07c87415065b3fc upstream.
+
+A few checks checked for the size of the pointer to a structure
+instead of the structure itself. Copy & paste issue presumably.
+
+Fixes: e4c6fb7794982 ("usbnet: move the CDC parser into USB core")
+Cc: stable <stable@vger.kernel.org>
+Reported-by: syzbot+45a53506b65321c1fe91@syzkaller.appspotmail.com
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Link: https://lore.kernel.org/r/20190813093541.18889-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/message.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -2218,14 +2218,14 @@ int cdc_parse_cdc_header(struct usb_cdc_
+ (struct usb_cdc_dmm_desc *)buffer;
+ break;
+ case USB_CDC_MDLM_TYPE:
+- if (elength < sizeof(struct usb_cdc_mdlm_desc *))
++ if (elength < sizeof(struct usb_cdc_mdlm_desc))
+ goto next_desc;
+ if (desc)
+ return -EINVAL;
+ desc = (struct usb_cdc_mdlm_desc *)buffer;
+ break;
+ case USB_CDC_MDLM_DETAIL_TYPE:
+- if (elength < sizeof(struct usb_cdc_mdlm_detail_desc *))
++ if (elength < sizeof(struct usb_cdc_mdlm_detail_desc))
+ goto next_desc;
+ if (detail)
+ return -EINVAL;
--- /dev/null
+From 303911cfc5b95d33687d9046133ff184cf5043ff Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Mon, 12 Aug 2019 16:11:07 -0400
+Subject: USB: core: Fix races in character device registration and deregistraion
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 303911cfc5b95d33687d9046133ff184cf5043ff upstream.
+
+The syzbot fuzzer has found two (!) races in the USB character device
+registration and deregistration routines. This patch fixes the races.
+
+The first race results from the fact that usb_deregister_dev() sets
+usb_minors[intf->minor] to NULL before calling device_destroy() on the
+class device. This leaves a window during which another thread can
+allocate the same minor number but will encounter a duplicate name
+error when it tries to register its own class device. A typical error
+message in the system log would look like:
+
+ sysfs: cannot create duplicate filename '/class/usbmisc/ldusb0'
+
+The patch fixes this race by destroying the class device first.
+
+The second race is in usb_register_dev(). When that routine runs, it
+first allocates a minor number, then drops minor_rwsem, and then
+creates the class device. If the device creation fails, the minor
+number is deallocated and the whole routine returns an error. But
+during the time while minor_rwsem was dropped, there is a window in
+which the minor number is allocated and so another thread can
+successfully open the device file. Typically this results in
+use-after-free errors or invalid accesses when the other thread closes
+its open file reference, because the kernel then tries to release
+resources that were already deallocated when usb_register_dev()
+failed. The patch fixes this race by keeping minor_rwsem locked
+throughout the entire routine.
+
+Reported-and-tested-by: syzbot+30cf45ebfe0b0c4847a1@syzkaller.appspotmail.com
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+CC: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.1908121607590.1659-100000@iolanthe.rowland.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/file.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/core/file.c
++++ b/drivers/usb/core/file.c
+@@ -193,9 +193,10 @@ int usb_register_dev(struct usb_interfac
+ intf->minor = minor;
+ break;
+ }
+- up_write(&minor_rwsem);
+- if (intf->minor < 0)
++ if (intf->minor < 0) {
++ up_write(&minor_rwsem);
+ return -EXFULL;
++ }
+
+ /* create a usb class device for this usb interface */
+ snprintf(name, sizeof(name), class_driver->name, minor - minor_base);
+@@ -203,12 +204,11 @@ int usb_register_dev(struct usb_interfac
+ MKDEV(USB_MAJOR, minor), class_driver,
+ "%s", kbasename(name));
+ if (IS_ERR(intf->usb_dev)) {
+- down_write(&minor_rwsem);
+ usb_minors[minor] = NULL;
+ intf->minor = -1;
+- up_write(&minor_rwsem);
+ retval = PTR_ERR(intf->usb_dev);
+ }
++ up_write(&minor_rwsem);
+ return retval;
+ }
+ EXPORT_SYMBOL_GPL(usb_register_dev);
+@@ -234,12 +234,12 @@ void usb_deregister_dev(struct usb_inter
+ return;
+
+ dev_dbg(&intf->dev, "removing %d minor\n", intf->minor);
++ device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
+
+ down_write(&minor_rwsem);
+ usb_minors[intf->minor] = NULL;
+ up_write(&minor_rwsem);
+
+- device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
+ intf->usb_dev = NULL;
+ intf->minor = -1;
+ destroy_usb_class();
--- /dev/null
+From 5dac665cf403967bb79a7aeb8c182a621fe617ff Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Wed, 31 Jul 2019 19:15:43 +0900
+Subject: usb: gadget: udc: renesas_usb3: Fix sysfs interface of "role"
+
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+
+commit 5dac665cf403967bb79a7aeb8c182a621fe617ff upstream.
+
+Since the role_store() uses strncmp(), it's possible to refer
+out-of-memory if the sysfs data size is smaller than strlen("host").
+This patch fixes it by using sysfs_streq() instead of strncmp().
+
+Fixes: cc995c9ec118 ("usb: gadget: udc: renesas_usb3: add support for usb role swap")
+Cc: <stable@vger.kernel.org> # v4.12+
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/udc/renesas_usb3.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/udc/renesas_usb3.c
++++ b/drivers/usb/gadget/udc/renesas_usb3.c
+@@ -19,6 +19,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/sizes.h>
+ #include <linux/slab.h>
++#include <linux/string.h>
+ #include <linux/sys_soc.h>
+ #include <linux/uaccess.h>
+ #include <linux/usb/ch9.h>
+@@ -2378,9 +2379,9 @@ static ssize_t role_store(struct device
+ if (usb3->forced_b_device)
+ return -EBUSY;
+
+- if (!strncmp(buf, "host", strlen("host")))
++ if (sysfs_streq(buf, "host"))
+ new_mode_is_host = true;
+- else if (!strncmp(buf, "peripheral", strlen("peripheral")))
++ else if (sysfs_streq(buf, "peripheral"))
+ new_mode_is_host = false;
+ else
+ return -EINVAL;
--- /dev/null
+From 552573e42aab5f75aff9bab855a9677979d9a7d5 Mon Sep 17 00:00:00 2001
+From: Rogan Dawes <rogan@dawes.za.net>
+Date: Wed, 17 Jul 2019 11:11:34 +0200
+Subject: USB: serial: option: add D-Link DWM-222 device ID
+
+From: Rogan Dawes <rogan@dawes.za.net>
+
+commit 552573e42aab5f75aff9bab855a9677979d9a7d5 upstream.
+
+Add device id for D-Link DWM-222 A2.
+
+MI_00 D-Link HS-USB Diagnostics
+MI_01 D-Link HS-USB Modem
+MI_02 D-Link HS-USB AT Port
+MI_03 D-Link HS-USB NMEA
+MI_04 D-Link HS-USB WWAN Adapter (qmi_wwan)
+MI_05 USB Mass Storage Device
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Rogan Dawes <rogan@dawes.za.net>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -1952,6 +1952,8 @@ static const struct usb_device_id option
+ .driver_info = RSVD(4) },
+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */
+ .driver_info = RSVD(4) },
++ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e3d, 0xff), /* D-Link DWM-222 A2 */
++ .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 */
--- /dev/null
+From 6caf0be40a707689e8ff8824fdb96ef77685b1ba Mon Sep 17 00:00:00 2001
+From: Tony Lindgren <tony@atomide.com>
+Date: Thu, 15 Aug 2019 01:26:02 -0700
+Subject: USB: serial: option: Add Motorola modem UARTs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Tony Lindgren <tony@atomide.com>
+
+commit 6caf0be40a707689e8ff8824fdb96ef77685b1ba upstream.
+
+On Motorola Mapphone devices such as Droid 4 there are five USB ports
+that do not use the same layout as Gobi 1K/2K/etc devices listed in
+qcserial.c. So we should use qcaux.c or option.c as noted by
+Dan Williams <dan.j.williams@intel.com>.
+
+As the Motorola USB serial ports have an interrupt endpoint as shown
+with lsusb -v, we should use option.c instead of qcaux.c as pointed out
+by Johan Hovold <johan@kernel.org>.
+
+The ff/ff/ff interfaces seem to always be UARTs on Motorola devices.
+For the other interfaces, class 0x0a (CDC Data) should not in general
+be added as they are typically part of a multi-interface function as
+noted earlier by Bjørn Mork <bjorn@mork.no>.
+
+However, looking at the Motorola mapphone kernel code, the mdm6600 0x0a
+class is only used for flashing the modem firmware, and there are no
+other interfaces. So I've added that too with more details below as it
+works just fine.
+
+The ttyUSB ports on Droid 4 are:
+
+ttyUSB0 DIAG, CQDM-capable
+ttyUSB1 MUX or NMEA, no response
+ttyUSB2 MUX or NMEA, no response
+ttyUSB3 TCMD
+ttyUSB4 AT-capable
+
+The ttyUSB0 is detected as QCDM capable by ModemManager. I think
+it's only used for debugging with ModemManager --debug for sending
+custom AT commands though. ModemManager already can manage data
+connection using the USB QMI ports that are already handled by the
+qmi_wwan.c driver.
+
+To enable the MUX or NMEA ports, it seems that something needs to be
+done additionally to enable them, maybe via the DIAG or TCMD port.
+It might be just a NVRAM setting somewhere, but I have no idea what
+NVRAM settings may need changing for that.
+
+The TCMD port seems to be a Motorola custom protocol for testing
+the modem and to configure it's NVRAM and seems to work just fine
+based on a quick test with a minimal tcmdrw tool I wrote.
+
+The voice modem AT-capable port seems to provide only partial
+support, and no PM support compared to the TS 27.010 based UART
+wired directly to the modem.
+
+The UARTs added with this change are the same product IDs as the
+Motorola Mapphone Android Linux kernel mdm6600_id_table. I don't
+have any mdm9600 based devices, so I have only tested these on
+mdm6600 based droid 4.
+
+Then for the class 0x0a (CDC Data) mode, the Motorola Mapphone Android
+Linux kernel driver moto_flashqsc.c just seems to change the
+port->bulk_out_size to 8K from the default. And is only used for
+flashing the modem firmware it seems.
+
+I've verified that flashing the modem with signed firmware works just
+fine with the option driver after manually toggling the GPIO pins, so
+I've added droid 4 modem flashing mode to the option driver. I've not
+added the other devices listed in moto_flashqsc.c in case they really
+need different port->bulk_out_size. Those can be added as they get
+tested to work for flashing the modem.
+
+After this patch the output of /sys/kernel/debug/usb/devices has
+the following for normal 22b8:2a70 mode including the related qmi_wwan
+interfaces:
+
+T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
+D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
+P: Vendor=22b8 ProdID=2a70 Rev= 0.00
+S: Manufacturer=Motorola, Incorporated
+S: Product=Flash MZ600
+C:* #Ifs= 9 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
+E: Ad=81(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
+E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
+E: Ad=83(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=03(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
+E: Ad=84(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=04(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
+E: Ad=85(I) Atr=03(Int.) MxPS= 64 Ivl=5ms
+E: Ad=86(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=05(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=fb Prot=ff Driver=qmi_wwan
+E: Ad=87(I) Atr=03(Int.) MxPS= 64 Ivl=5ms
+E: Ad=88(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=06(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 6 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=fb Prot=ff Driver=qmi_wwan
+E: Ad=89(I) Atr=03(Int.) MxPS= 64 Ivl=5ms
+E: Ad=8a(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=07(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 7 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=fb Prot=ff Driver=qmi_wwan
+E: Ad=8b(I) Atr=03(Int.) MxPS= 64 Ivl=5ms
+E: Ad=8c(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=08(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 8 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=fb Prot=ff Driver=qmi_wwan
+E: Ad=8d(I) Atr=03(Int.) MxPS= 64 Ivl=5ms
+E: Ad=8e(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=09(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+
+In 22b8:900e "qc_dload" mode the device shows up as:
+
+T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
+D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
+P: Vendor=22b8 ProdID=900e Rev= 0.00
+S: Manufacturer=Motorola, Incorporated
+S: Product=Flash MZ600
+C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
+E: Ad=81(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+
+And in 22b8:4281 "ram_downloader" mode the device shows up as:
+
+T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
+D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
+P: Vendor=22b8 ProdID=4281 Rev= 0.00
+S: Manufacturer=Motorola, Incorporated
+S: Product=Flash MZ600
+C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=fc Driver=option
+E: Ad=81(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+
+Cc: Bjørn Mork <bjorn@mork.no>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: Lars Melin <larsm17@gmail.com>
+Cc: Marcel Partap <mpartap@gmx.net>
+Cc: Merlijn Wajer <merlijn@wizzup.org>
+Cc: Michael Scott <hashcode0f@gmail.com>
+Cc: NeKit <nekit1000@gmail.com>
+Cc: Pavel Machek <pavel@ucw.cz>
+Cc: Sebastian Reichel <sre@kernel.org>
+Tested-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -968,6 +968,11 @@ static const struct usb_device_id option
+ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7B) },
+ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7C) },
+
++ /* Motorola devices */
++ { USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x2a70, 0xff, 0xff, 0xff) }, /* mdm6600 */
++ { USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x2e0a, 0xff, 0xff, 0xff) }, /* mdm9600 */
++ { USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x4281, 0x0a, 0x00, 0xfc) }, /* mdm ram dl */
++ { USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x900e, 0xff, 0xff, 0xff) }, /* mdm qc dl */
+
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) },
--- /dev/null
+From 7e7ae38bf928c5cfa6dd6e9a2cf8b42c84a27c92 Mon Sep 17 00:00:00 2001
+From: Yoshiaki Okamoto <yokamoto@allied-telesis.co.jp>
+Date: Sat, 20 Jul 2019 22:23:18 +0900
+Subject: USB: serial: option: Add support for ZTE MF871A
+
+From: Yoshiaki Okamoto <yokamoto@allied-telesis.co.jp>
+
+commit 7e7ae38bf928c5cfa6dd6e9a2cf8b42c84a27c92 upstream.
+
+This patch adds support for MF871A USB modem (aka Speed USB STICK U03)
+to option driver. This modem is manufactured by ZTE corporation, and
+sold by KDDI.
+
+Interface layout:
+0: AT
+1: MODEM
+
+usb-devices output:
+T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 9 Spd=480 MxCh= 0
+D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
+P: Vendor=19d2 ProdID=1481 Rev=52.87
+S: Manufacturer=ZTE,Incorporated
+S: Product=ZTE Technologies MSM
+S: SerialNumber=1234567890ABCDEF
+C: #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=500mA
+I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+
+Co-developed-by: Hiroyuki Yamamoto <hyamamo@allied-telesis.co.jp>
+Signed-off-by: Hiroyuki Yamamoto <hyamamo@allied-telesis.co.jp>
+Signed-off-by: Yoshiaki Okamoto <yokamoto@allied-telesis.co.jp>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -1549,6 +1549,7 @@ static const struct usb_device_id option
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G v2 */
+ .driver_info = RSVD(2) },
+ { USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x1476, 0xff) }, /* GosunCn ZTE WeLink ME3630 (ECM/NCM mode) */
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1481, 0xff, 0x00, 0x00) }, /* ZTE MF871A */
+ { 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) },
--- /dev/null
+From e5d8badf37e6b547842f2fcde10361b29e08bd36 Mon Sep 17 00:00:00 2001
+From: Bob Ham <bob.ham@puri.sm>
+Date: Wed, 24 Jul 2019 07:52:26 -0700
+Subject: USB: serial: option: add the BroadMobi BM818 card
+
+From: Bob Ham <bob.ham@puri.sm>
+
+commit e5d8badf37e6b547842f2fcde10361b29e08bd36 upstream.
+
+Add a VID:PID for the BroadMobi BM818 M.2 card
+
+T: Bus=01 Lev=03 Prnt=40 Port=03 Cnt=01 Dev#= 44 Spd=480 MxCh= 0
+D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
+P: Vendor=2020 ProdID=2060 Rev=00.00
+S: Manufacturer=Qualcomm, Incorporated
+S: Product=Qualcomm CDMA Technologies MSM
+C: #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA
+I: If#=0x0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
+I: If#=0x1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
+I: If#=0x2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
+I: If#=0x3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=fe Prot=ff Driver=(none)
+I: If#=0x4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
+
+Signed-off-by: Bob Ham <bob.ham@puri.sm>
+Signed-off-by: Angus Ainslie (Purism) <angus@akkea.ca>
+Cc: stable <stable@vger.kernel.org>
+[ johan: use USB_DEVICE_INTERFACE_CLASS() ]
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -1960,6 +1960,8 @@ static const struct usb_device_id option
+ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */
+ { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x2031, 0xff), /* Olicard 600 */
+ .driver_info = RSVD(4) },
++ { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x2060, 0xff), /* BroadMobi BM818 */
++ .driver_info = RSVD(4) },
+ { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */
+ { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) },
+ { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) },
--- /dev/null
+From 27709ae4e2fe6cf7da2ae45e718e190c5433342b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thi=C3=A9baud=20Weksteen?= <tweek@google.com>
+Date: Tue, 6 Aug 2019 13:00:50 +0200
+Subject: usb: setup authorized_default attributes using usb_bus_notify
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thiébaud Weksteen <tweek@google.com>
+
+commit 27709ae4e2fe6cf7da2ae45e718e190c5433342b upstream.
+
+Currently, the authorized_default and interface_authorized_default
+attributes for HCD are set up after the uevent has been sent to userland.
+This creates a race condition where userland may fail to access this
+file when processing the event. Move the appending of these attributes
+earlier relying on the usb_bus_notify dispatcher.
+
+Signed-off-by: Thiébaud Weksteen <tweek@google.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20190806110050.38918-1-tweek@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hcd.c | 123 -----------------------------------------------
+ drivers/usb/core/sysfs.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++
+ drivers/usb/core/usb.h | 5 +
+ 3 files changed, 126 insertions(+), 123 deletions(-)
+
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -101,11 +101,6 @@ static DEFINE_SPINLOCK(hcd_urb_unlink_lo
+ /* wait queue for synchronous unlinks */
+ DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue);
+
+-static inline int is_root_hub(struct usb_device *udev)
+-{
+- return (udev->parent == NULL);
+-}
+-
+ /*-------------------------------------------------------------------------*/
+
+ /*
+@@ -878,101 +873,6 @@ static int usb_rh_urb_dequeue(struct usb
+ }
+
+
+-
+-/*
+- * Show & store the current value of authorized_default
+- */
+-static ssize_t authorized_default_show(struct device *dev,
+- struct device_attribute *attr, char *buf)
+-{
+- struct usb_device *rh_usb_dev = to_usb_device(dev);
+- struct usb_bus *usb_bus = rh_usb_dev->bus;
+- struct usb_hcd *hcd;
+-
+- hcd = bus_to_hcd(usb_bus);
+- return snprintf(buf, PAGE_SIZE, "%u\n", hcd->dev_policy);
+-}
+-
+-static ssize_t authorized_default_store(struct device *dev,
+- struct device_attribute *attr,
+- const char *buf, size_t size)
+-{
+- ssize_t result;
+- unsigned val;
+- struct usb_device *rh_usb_dev = to_usb_device(dev);
+- struct usb_bus *usb_bus = rh_usb_dev->bus;
+- struct usb_hcd *hcd;
+-
+- hcd = bus_to_hcd(usb_bus);
+- result = sscanf(buf, "%u\n", &val);
+- if (result == 1) {
+- hcd->dev_policy = val <= USB_DEVICE_AUTHORIZE_INTERNAL ?
+- val : USB_DEVICE_AUTHORIZE_ALL;
+- result = size;
+- } else {
+- result = -EINVAL;
+- }
+- return result;
+-}
+-static DEVICE_ATTR_RW(authorized_default);
+-
+-/*
+- * interface_authorized_default_show - show default authorization status
+- * for USB interfaces
+- *
+- * note: interface_authorized_default is the default value
+- * for initializing the authorized attribute of interfaces
+- */
+-static ssize_t interface_authorized_default_show(struct device *dev,
+- struct device_attribute *attr, char *buf)
+-{
+- struct usb_device *usb_dev = to_usb_device(dev);
+- struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus);
+-
+- return sprintf(buf, "%u\n", !!HCD_INTF_AUTHORIZED(hcd));
+-}
+-
+-/*
+- * interface_authorized_default_store - store default authorization status
+- * for USB interfaces
+- *
+- * note: interface_authorized_default is the default value
+- * for initializing the authorized attribute of interfaces
+- */
+-static ssize_t interface_authorized_default_store(struct device *dev,
+- struct device_attribute *attr, const char *buf, size_t count)
+-{
+- struct usb_device *usb_dev = to_usb_device(dev);
+- struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus);
+- int rc = count;
+- bool val;
+-
+- if (strtobool(buf, &val) != 0)
+- return -EINVAL;
+-
+- if (val)
+- set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
+- else
+- clear_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
+-
+- return rc;
+-}
+-static DEVICE_ATTR_RW(interface_authorized_default);
+-
+-/* Group all the USB bus attributes */
+-static struct attribute *usb_bus_attrs[] = {
+- &dev_attr_authorized_default.attr,
+- &dev_attr_interface_authorized_default.attr,
+- NULL,
+-};
+-
+-static const struct attribute_group usb_bus_attr_group = {
+- .name = NULL, /* we want them in the same directory */
+- .attrs = usb_bus_attrs,
+-};
+-
+-
+-
+ /*-------------------------------------------------------------------------*/
+
+ /**
+@@ -2895,32 +2795,11 @@ int usb_add_hcd(struct usb_hcd *hcd,
+ if (retval != 0)
+ goto err_register_root_hub;
+
+- retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group);
+- if (retval < 0) {
+- printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n",
+- retval);
+- goto error_create_attr_group;
+- }
+ if (hcd->uses_new_polling && HCD_POLL_RH(hcd))
+ usb_hcd_poll_rh_status(hcd);
+
+ return retval;
+
+-error_create_attr_group:
+- clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
+- if (HC_IS_RUNNING(hcd->state))
+- hcd->state = HC_STATE_QUIESCING;
+- spin_lock_irq(&hcd_root_hub_lock);
+- hcd->rh_registered = 0;
+- spin_unlock_irq(&hcd_root_hub_lock);
+-
+-#ifdef CONFIG_PM
+- cancel_work_sync(&hcd->wakeup_work);
+-#endif
+- cancel_work_sync(&hcd->died_work);
+- mutex_lock(&usb_bus_idr_lock);
+- usb_disconnect(&rhdev); /* Sets rhdev to NULL */
+- mutex_unlock(&usb_bus_idr_lock);
+ err_register_root_hub:
+ hcd->rh_pollable = 0;
+ clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
+@@ -2964,8 +2843,6 @@ void usb_remove_hcd(struct usb_hcd *hcd)
+ dev_info(hcd->self.controller, "remove, state %x\n", hcd->state);
+
+ usb_get_dev(rhdev);
+- sysfs_remove_group(&rhdev->dev.kobj, &usb_bus_attr_group);
+-
+ clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
+ if (HC_IS_RUNNING (hcd->state))
+ hcd->state = HC_STATE_QUIESCING;
+--- a/drivers/usb/core/sysfs.c
++++ b/drivers/usb/core/sysfs.c
+@@ -15,6 +15,7 @@
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+ #include <linux/usb.h>
++#include <linux/usb/hcd.h>
+ #include <linux/usb/quirks.h>
+ #include <linux/of.h>
+ #include "usb.h"
+@@ -922,6 +923,116 @@ static struct bin_attribute dev_bin_attr
+ .size = 18 + 65535, /* dev descr + max-size raw descriptor */
+ };
+
++/*
++ * Show & store the current value of authorized_default
++ */
++static ssize_t authorized_default_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct usb_device *rh_usb_dev = to_usb_device(dev);
++ struct usb_bus *usb_bus = rh_usb_dev->bus;
++ struct usb_hcd *hcd;
++
++ hcd = bus_to_hcd(usb_bus);
++ return snprintf(buf, PAGE_SIZE, "%u\n", hcd->dev_policy);
++}
++
++static ssize_t authorized_default_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t size)
++{
++ ssize_t result;
++ unsigned int val;
++ struct usb_device *rh_usb_dev = to_usb_device(dev);
++ struct usb_bus *usb_bus = rh_usb_dev->bus;
++ struct usb_hcd *hcd;
++
++ hcd = bus_to_hcd(usb_bus);
++ result = sscanf(buf, "%u\n", &val);
++ if (result == 1) {
++ hcd->dev_policy = val <= USB_DEVICE_AUTHORIZE_INTERNAL ?
++ val : USB_DEVICE_AUTHORIZE_ALL;
++ result = size;
++ } else {
++ result = -EINVAL;
++ }
++ return result;
++}
++static DEVICE_ATTR_RW(authorized_default);
++
++/*
++ * interface_authorized_default_show - show default authorization status
++ * for USB interfaces
++ *
++ * note: interface_authorized_default is the default value
++ * for initializing the authorized attribute of interfaces
++ */
++static ssize_t interface_authorized_default_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct usb_device *usb_dev = to_usb_device(dev);
++ struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus);
++
++ return sprintf(buf, "%u\n", !!HCD_INTF_AUTHORIZED(hcd));
++}
++
++/*
++ * interface_authorized_default_store - store default authorization status
++ * for USB interfaces
++ *
++ * note: interface_authorized_default is the default value
++ * for initializing the authorized attribute of interfaces
++ */
++static ssize_t interface_authorized_default_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t count)
++{
++ struct usb_device *usb_dev = to_usb_device(dev);
++ struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus);
++ int rc = count;
++ bool val;
++
++ if (strtobool(buf, &val) != 0)
++ return -EINVAL;
++
++ if (val)
++ set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
++ else
++ clear_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
++
++ return rc;
++}
++static DEVICE_ATTR_RW(interface_authorized_default);
++
++/* Group all the USB bus attributes */
++static struct attribute *usb_bus_attrs[] = {
++ &dev_attr_authorized_default.attr,
++ &dev_attr_interface_authorized_default.attr,
++ NULL,
++};
++
++static const struct attribute_group usb_bus_attr_group = {
++ .name = NULL, /* we want them in the same directory */
++ .attrs = usb_bus_attrs,
++};
++
++
++static int add_default_authorized_attributes(struct device *dev)
++{
++ int rc = 0;
++
++ if (is_usb_device(dev))
++ rc = sysfs_create_group(&dev->kobj, &usb_bus_attr_group);
++
++ return rc;
++}
++
++static void remove_default_authorized_attributes(struct device *dev)
++{
++ if (is_usb_device(dev)) {
++ sysfs_remove_group(&dev->kobj, &usb_bus_attr_group);
++ }
++}
++
+ int usb_create_sysfs_dev_files(struct usb_device *udev)
+ {
+ struct device *dev = &udev->dev;
+@@ -938,7 +1049,14 @@ int usb_create_sysfs_dev_files(struct us
+ retval = add_power_attributes(dev);
+ if (retval)
+ goto error;
++
++ if (is_root_hub(udev)) {
++ retval = add_default_authorized_attributes(dev);
++ if (retval)
++ goto error;
++ }
+ return retval;
++
+ error:
+ usb_remove_sysfs_dev_files(udev);
+ return retval;
+@@ -948,6 +1066,9 @@ void usb_remove_sysfs_dev_files(struct u
+ {
+ struct device *dev = &udev->dev;
+
++ if (is_root_hub(udev))
++ remove_default_authorized_attributes(dev);
++
+ remove_power_attributes(dev);
+ remove_persist_attributes(dev);
+ device_remove_bin_file(dev, &dev_bin_attr_descriptors);
+--- a/drivers/usb/core/usb.h
++++ b/drivers/usb/core/usb.h
+@@ -153,6 +153,11 @@ static inline int is_usb_port(const stru
+ return dev->type == &usb_port_device_type;
+ }
+
++static inline int is_root_hub(struct usb_device *udev)
++{
++ return (udev->parent == NULL);
++}
++
+ /* Do the same for device drivers and interface drivers. */
+
+ static inline int is_usb_device_driver(struct device_driver *drv)
--- /dev/null
+From a90118c445cc7f07781de26a9684d4ec58bfcfd1 Mon Sep 17 00:00:00 2001
+From: John Hubbard <jhubbard@nvidia.com>
+Date: Tue, 30 Jul 2019 22:46:27 -0700
+Subject: x86/boot: Save fields explicitly, zero out everything else
+
+From: John Hubbard <jhubbard@nvidia.com>
+
+commit a90118c445cc7f07781de26a9684d4ec58bfcfd1 upstream.
+
+Recent gcc compilers (gcc 9.1) generate warnings about an out of bounds
+memset, if the memset goes accross several fields of a struct. This
+generated a couple of warnings on x86_64 builds in sanitize_boot_params().
+
+Fix this by explicitly saving the fields in struct boot_params
+that are intended to be preserved, and zeroing all the rest.
+
+[ tglx: Tagged for stable as it breaks the warning free build there as well ]
+
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Suggested-by: H. Peter Anvin <hpa@zytor.com>
+Signed-off-by: John Hubbard <jhubbard@nvidia.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20190731054627.5627-2-jhubbard@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/bootparam_utils.h | 63 +++++++++++++++++++++++++--------
+ 1 file changed, 48 insertions(+), 15 deletions(-)
+
+--- a/arch/x86/include/asm/bootparam_utils.h
++++ b/arch/x86/include/asm/bootparam_utils.h
+@@ -18,6 +18,20 @@
+ * Note: efi_info is commonly left uninitialized, but that field has a
+ * private magic, so it is better to leave it unchanged.
+ */
++
++#define sizeof_mbr(type, member) ({ sizeof(((type *)0)->member); })
++
++#define BOOT_PARAM_PRESERVE(struct_member) \
++ { \
++ .start = offsetof(struct boot_params, struct_member), \
++ .len = sizeof_mbr(struct boot_params, struct_member), \
++ }
++
++struct boot_params_to_save {
++ unsigned int start;
++ unsigned int len;
++};
++
+ static void sanitize_boot_params(struct boot_params *boot_params)
+ {
+ /*
+@@ -35,21 +49,40 @@ static void sanitize_boot_params(struct
+ * problems again.
+ */
+ if (boot_params->sentinel) {
+- /* fields in boot_params are left uninitialized, clear them */
+- boot_params->acpi_rsdp_addr = 0;
+- memset(&boot_params->ext_ramdisk_image, 0,
+- (char *)&boot_params->efi_info -
+- (char *)&boot_params->ext_ramdisk_image);
+- memset(&boot_params->kbd_status, 0,
+- (char *)&boot_params->hdr -
+- (char *)&boot_params->kbd_status);
+- memset(&boot_params->_pad7[0], 0,
+- (char *)&boot_params->edd_mbr_sig_buffer[0] -
+- (char *)&boot_params->_pad7[0]);
+- memset(&boot_params->_pad8[0], 0,
+- (char *)&boot_params->eddbuf[0] -
+- (char *)&boot_params->_pad8[0]);
+- memset(&boot_params->_pad9[0], 0, sizeof(boot_params->_pad9));
++ static struct boot_params scratch;
++ char *bp_base = (char *)boot_params;
++ char *save_base = (char *)&scratch;
++ int i;
++
++ const struct boot_params_to_save to_save[] = {
++ BOOT_PARAM_PRESERVE(screen_info),
++ BOOT_PARAM_PRESERVE(apm_bios_info),
++ BOOT_PARAM_PRESERVE(tboot_addr),
++ BOOT_PARAM_PRESERVE(ist_info),
++ BOOT_PARAM_PRESERVE(acpi_rsdp_addr),
++ BOOT_PARAM_PRESERVE(hd0_info),
++ BOOT_PARAM_PRESERVE(hd1_info),
++ BOOT_PARAM_PRESERVE(sys_desc_table),
++ BOOT_PARAM_PRESERVE(olpc_ofw_header),
++ BOOT_PARAM_PRESERVE(efi_info),
++ BOOT_PARAM_PRESERVE(alt_mem_k),
++ BOOT_PARAM_PRESERVE(scratch),
++ BOOT_PARAM_PRESERVE(e820_entries),
++ BOOT_PARAM_PRESERVE(eddbuf_entries),
++ BOOT_PARAM_PRESERVE(edd_mbr_sig_buf_entries),
++ BOOT_PARAM_PRESERVE(edd_mbr_sig_buffer),
++ BOOT_PARAM_PRESERVE(e820_table),
++ BOOT_PARAM_PRESERVE(eddbuf),
++ };
++
++ memset(&scratch, 0, sizeof(scratch));
++
++ for (i = 0; i < ARRAY_SIZE(to_save); i++) {
++ memcpy(save_base + to_save[i].start,
++ bp_base + to_save[i].start, to_save[i].len);
++ }
++
++ memcpy(boot_params, save_base, sizeof(*boot_params));
+ }
+ }
+