diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-03-26 13:52:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-03-26 13:52:52 -0400 |
commit | e431e0e427799805461390df1db1e3478d4c475c (patch) | |
tree | 34d25d6824ff46638d6fc21a31a2cc48d27e2d1d | |
parent | 42234bf8320aeedaf0bff81e38a7020582c93a6f (diff) | |
parent | fd290e7096bd4441fdd61e241ee997b16e04afbd (diff) |
Merge tag 'usb-4.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB/PHY fixes from Greg KH:
"Here are a number of small USB and PHY driver fixes for 4.11-rc4.
Nothing major here, just an bunch of small fixes, and a handfull of
good fixes from Johan for devices with crazy descriptors. There are a
few new device ids in here as well.
All of these have been in linux-next with no reported issues"
* tag 'usb-4.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (26 commits)
usb: gadget: f_hid: fix: Don't access hidg->req without spinlock held
usb: gadget: udc: remove pointer dereference after free
usb: gadget: f_uvc: Sanity check wMaxPacketSize for SuperSpeed
usb: gadget: f_uvc: Fix SuperSpeed companion descriptor's wBytesPerInterval
usb: gadget: acm: fix endianness in notifications
usb: dwc3: gadget: delay unmap of bounced requests
USB: serial: qcserial: add Dell DW5811e
usb: hub: Fix crash after failure to read BOS descriptor
ACM gadget: fix endianness in notifications
USB: usbtmc: fix probe error path
USB: usbtmc: add missing endpoint sanity check
USB: serial: option: add Quectel UC15, UC20, EC21, and EC25 modems
usb: musb: fix possible spinlock deadlock
usb: musb: dsps: fix iounmap in error and exit paths
usb: musb: cppi41: don't check early-TX-interrupt for Isoch transfer
usb-core: Add LINEAR_FRAME_INTR_BINTERVAL USB quirk
uwb: i1480-dfu: fix NULL-deref at probe
uwb: hwa-rc: fix NULL-deref at probe
USB: wusbcore: fix NULL-deref at probe
USB: uss720: fix NULL-deref at probe
...
26 files changed, 141 insertions, 247 deletions
diff --git a/Documentation/devicetree/bindings/phy/brcm,nsp-usb3-phy.txt b/Documentation/devicetree/bindings/phy/brcm,nsp-usb3-phy.txt deleted file mode 100644 index e68ae5dec9c9..000000000000 --- a/Documentation/devicetree/bindings/phy/brcm,nsp-usb3-phy.txt +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | Broadcom USB3 phy binding for northstar plus SoC | ||
2 | The USB3 phy is internal to the SoC and is accessed using mdio interface. | ||
3 | |||
4 | Required mdio bus properties: | ||
5 | - reg: Should be 0x0 for SoC internal USB3 phy | ||
6 | - #address-cells: must be 1 | ||
7 | - #size-cells: must be 0 | ||
8 | |||
9 | Required USB3 PHY properties: | ||
10 | - compatible: should be "brcm,nsp-usb3-phy" | ||
11 | - reg: USB3 Phy address on SoC internal MDIO bus and it should be 0x10. | ||
12 | - usb3-ctrl-syscon: handler of syscon node defining physical address | ||
13 | of usb3 control register. | ||
14 | - #phy-cells: must be 0 | ||
15 | |||
16 | Required usb3 control properties: | ||
17 | - compatible: should be "brcm,nsp-usb3-ctrl" | ||
18 | - reg: offset and length of the control registers | ||
19 | |||
20 | Example: | ||
21 | |||
22 | mdio@0 { | ||
23 | reg = <0x0>; | ||
24 | #address-cells = <1>; | ||
25 | #size-cells = <0>; | ||
26 | |||
27 | usb3_phy: usb-phy@10 { | ||
28 | compatible = "brcm,nsp-usb3-phy"; | ||
29 | reg = <0x10>; | ||
30 | usb3-ctrl-syscon = <&usb3_ctrl>; | ||
31 | #phy-cells = <0>; | ||
32 | status = "disabled"; | ||
33 | }; | ||
34 | }; | ||
35 | |||
36 | usb3_ctrl: syscon@104408 { | ||
37 | compatible = "brcm,nsp-usb3-ctrl", "syscon"; | ||
38 | reg = <0x104408 0x3fc>; | ||
39 | }; | ||
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index dc5277ad1b5a..005cadb7a3f8 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
@@ -449,6 +449,7 @@ config PHY_QCOM_UFS | |||
449 | config PHY_QCOM_USB_HS | 449 | config PHY_QCOM_USB_HS |
450 | tristate "Qualcomm USB HS PHY module" | 450 | tristate "Qualcomm USB HS PHY module" |
451 | depends on USB_ULPI_BUS | 451 | depends on USB_ULPI_BUS |
452 | depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in | ||
452 | select GENERIC_PHY | 453 | select GENERIC_PHY |
453 | help | 454 | help |
454 | Support for the USB high-speed ULPI compliant phy on Qualcomm | 455 | Support for the USB high-speed ULPI compliant phy on Qualcomm |
@@ -510,12 +511,4 @@ config PHY_MESON8B_USB2 | |||
510 | and GXBB SoCs. | 511 | and GXBB SoCs. |
511 | If unsure, say N. | 512 | If unsure, say N. |
512 | 513 | ||
513 | config PHY_NSP_USB3 | ||
514 | tristate "Broadcom NorthStar plus USB3 PHY driver" | ||
515 | depends on OF && (ARCH_BCM_NSP || COMPILE_TEST) | ||
516 | select GENERIC_PHY | ||
517 | default ARCH_BCM_NSP | ||
518 | help | ||
519 | Enable this to support the Broadcom Northstar plus USB3 PHY. | ||
520 | If unsure, say N. | ||
521 | endmenu | 514 | endmenu |
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index e7b0feb1e125..dd8f3b5d2918 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile | |||
@@ -62,4 +62,3 @@ obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o | |||
62 | obj-$(CONFIG_ARCH_TEGRA) += tegra/ | 62 | obj-$(CONFIG_ARCH_TEGRA) += tegra/ |
63 | obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o | 63 | obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o |
64 | obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o | 64 | obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o |
65 | obj-$(CONFIG_PHY_NSP_USB3) += phy-bcm-nsp-usb3.o | ||
diff --git a/drivers/phy/phy-bcm-nsp-usb3.c b/drivers/phy/phy-bcm-nsp-usb3.c deleted file mode 100644 index 49024eaa5545..000000000000 --- a/drivers/phy/phy-bcm-nsp-usb3.c +++ /dev/null | |||
@@ -1,177 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Broadcom | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation version 2. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/mfd/syscon.h> | ||
18 | #include <linux/mdio.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_address.h> | ||
22 | #include <linux/phy/phy.h> | ||
23 | #include <linux/regmap.h> | ||
24 | |||
25 | #define NSP_USB3_RST_CTRL_OFFSET 0x3f8 | ||
26 | |||
27 | /* mdio reg access */ | ||
28 | #define NSP_USB3_PHY_BASE_ADDR_REG 0x1f | ||
29 | |||
30 | #define NSP_USB3_PHY_PLL30_BLOCK 0x8000 | ||
31 | #define NSP_USB3_PLL_CONTROL 0x01 | ||
32 | #define NSP_USB3_PLLA_CONTROL0 0x0a | ||
33 | #define NSP_USB3_PLLA_CONTROL1 0x0b | ||
34 | |||
35 | #define NSP_USB3_PHY_TX_PMD_BLOCK 0x8040 | ||
36 | #define NSP_USB3_TX_PMD_CONTROL1 0x01 | ||
37 | |||
38 | #define NSP_USB3_PHY_PIPE_BLOCK 0x8060 | ||
39 | #define NSP_USB3_LFPS_CMP 0x02 | ||
40 | #define NSP_USB3_LFPS_DEGLITCH 0x03 | ||
41 | |||
42 | struct nsp_usb3_phy { | ||
43 | struct regmap *usb3_ctrl; | ||
44 | struct phy *phy; | ||
45 | struct mdio_device *mdiodev; | ||
46 | }; | ||
47 | |||
48 | static int nsp_usb3_phy_init(struct phy *phy) | ||
49 | { | ||
50 | struct nsp_usb3_phy *iphy = phy_get_drvdata(phy); | ||
51 | struct mii_bus *bus = iphy->mdiodev->bus; | ||
52 | int addr = iphy->mdiodev->addr; | ||
53 | u32 data; | ||
54 | int rc; | ||
55 | |||
56 | rc = regmap_read(iphy->usb3_ctrl, 0, &data); | ||
57 | if (rc) | ||
58 | return rc; | ||
59 | data |= 1; | ||
60 | rc = regmap_write(iphy->usb3_ctrl, 0, data); | ||
61 | if (rc) | ||
62 | return rc; | ||
63 | |||
64 | rc = regmap_write(iphy->usb3_ctrl, NSP_USB3_RST_CTRL_OFFSET, 1); | ||
65 | if (rc) | ||
66 | return rc; | ||
67 | |||
68 | rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG, | ||
69 | NSP_USB3_PHY_PLL30_BLOCK); | ||
70 | if (rc) | ||
71 | return rc; | ||
72 | |||
73 | rc = mdiobus_write(bus, addr, NSP_USB3_PLL_CONTROL, 0x1000); | ||
74 | if (rc) | ||
75 | return rc; | ||
76 | |||
77 | rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL0, 0x6400); | ||
78 | if (rc) | ||
79 | return rc; | ||
80 | |||
81 | rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL1, 0xc000); | ||
82 | if (rc) | ||
83 | return rc; | ||
84 | |||
85 | rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL1, 0x8000); | ||
86 | if (rc) | ||
87 | return rc; | ||
88 | |||
89 | rc = regmap_write(iphy->usb3_ctrl, NSP_USB3_RST_CTRL_OFFSET, 0); | ||
90 | if (rc) | ||
91 | return rc; | ||
92 | |||
93 | rc = mdiobus_write(bus, addr, NSP_USB3_PLL_CONTROL, 0x9000); | ||
94 | if (rc) | ||
95 | return rc; | ||
96 | |||
97 | rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG, | ||
98 | NSP_USB3_PHY_PIPE_BLOCK); | ||
99 | if (rc) | ||
100 | return rc; | ||
101 | |||
102 | rc = mdiobus_write(bus, addr, NSP_USB3_LFPS_CMP, 0xf30d); | ||
103 | if (rc) | ||
104 | return rc; | ||
105 | |||
106 | rc = mdiobus_write(bus, addr, NSP_USB3_LFPS_DEGLITCH, 0x6302); | ||
107 | if (rc) | ||
108 | return rc; | ||
109 | |||
110 | rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG, | ||
111 | NSP_USB3_PHY_TX_PMD_BLOCK); | ||
112 | if (rc) | ||
113 | return rc; | ||
114 | |||
115 | rc = mdiobus_write(bus, addr, NSP_USB3_TX_PMD_CONTROL1, 0x1003); | ||
116 | |||
117 | return rc; | ||
118 | } | ||
119 | |||
120 | static struct phy_ops nsp_usb3_phy_ops = { | ||
121 | .init = nsp_usb3_phy_init, | ||
122 | .owner = THIS_MODULE, | ||
123 | }; | ||
124 | |||
125 | static int nsp_usb3_phy_probe(struct mdio_device *mdiodev) | ||
126 | { | ||
127 | struct device *dev = &mdiodev->dev; | ||
128 | struct phy_provider *provider; | ||
129 | struct nsp_usb3_phy *iphy; | ||
130 | |||
131 | iphy = devm_kzalloc(dev, sizeof(*iphy), GFP_KERNEL); | ||
132 | if (!iphy) | ||
133 | return -ENOMEM; | ||
134 | iphy->mdiodev = mdiodev; | ||
135 | |||
136 | iphy->usb3_ctrl = syscon_regmap_lookup_by_phandle(dev->of_node, | ||
137 | "usb3-ctrl-syscon"); | ||
138 | if (IS_ERR(iphy->usb3_ctrl)) | ||
139 | return PTR_ERR(iphy->usb3_ctrl); | ||
140 | |||
141 | iphy->phy = devm_phy_create(dev, dev->of_node, &nsp_usb3_phy_ops); | ||
142 | if (IS_ERR(iphy->phy)) { | ||
143 | dev_err(dev, "failed to create PHY\n"); | ||
144 | return PTR_ERR(iphy->phy); | ||
145 | } | ||
146 | |||
147 | phy_set_drvdata(iphy->phy, iphy); | ||
148 | |||
149 | provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | ||
150 | if (IS_ERR(provider)) { | ||
151 | dev_err(dev, "could not register PHY provider\n"); | ||
152 | return PTR_ERR(provider); | ||
153 | } | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static const struct of_device_id nsp_usb3_phy_of_match[] = { | ||
159 | {.compatible = "brcm,nsp-usb3-phy",}, | ||
160 | { /* sentinel */ } | ||
161 | }; | ||
162 | |||
163 | static struct mdio_driver nsp_usb3_phy_driver = { | ||
164 | .mdiodrv = { | ||
165 | .driver = { | ||
166 | .name = "nsp-usb3-phy", | ||
167 | .of_match_table = nsp_usb3_phy_of_match, | ||
168 | }, | ||
169 | }, | ||
170 | .probe = nsp_usb3_phy_probe, | ||
171 | }; | ||
172 | |||
173 | mdio_module_driver(nsp_usb3_phy_driver); | ||
174 | |||
175 | MODULE_DESCRIPTION("Broadcom NSP USB3 PHY driver"); | ||
176 | MODULE_LICENSE("GPL v2"); | ||
177 | MODULE_AUTHOR("Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com"); | ||
diff --git a/drivers/phy/phy-exynos-pcie.c b/drivers/phy/phy-exynos-pcie.c index 4f60b83641d5..60baf25d98e2 100644 --- a/drivers/phy/phy-exynos-pcie.c +++ b/drivers/phy/phy-exynos-pcie.c | |||
@@ -254,8 +254,8 @@ static int exynos_pcie_phy_probe(struct platform_device *pdev) | |||
254 | 254 | ||
255 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 255 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
256 | exynos_phy->blk_base = devm_ioremap_resource(dev, res); | 256 | exynos_phy->blk_base = devm_ioremap_resource(dev, res); |
257 | if (IS_ERR(exynos_phy->phy_base)) | 257 | if (IS_ERR(exynos_phy->blk_base)) |
258 | return PTR_ERR(exynos_phy->phy_base); | 258 | return PTR_ERR(exynos_phy->blk_base); |
259 | 259 | ||
260 | exynos_phy->drv_data = drv_data; | 260 | exynos_phy->drv_data = drv_data; |
261 | 261 | ||
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index f03692ec5520..8fb309a0ff6b 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c | |||
@@ -1381,7 +1381,7 @@ static int usbtmc_probe(struct usb_interface *intf, | |||
1381 | 1381 | ||
1382 | dev_dbg(&intf->dev, "%s called\n", __func__); | 1382 | dev_dbg(&intf->dev, "%s called\n", __func__); |
1383 | 1383 | ||
1384 | data = kmalloc(sizeof(*data), GFP_KERNEL); | 1384 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
1385 | if (!data) | 1385 | if (!data) |
1386 | return -ENOMEM; | 1386 | return -ENOMEM; |
1387 | 1387 | ||
@@ -1444,6 +1444,13 @@ static int usbtmc_probe(struct usb_interface *intf, | |||
1444 | break; | 1444 | break; |
1445 | } | 1445 | } |
1446 | } | 1446 | } |
1447 | |||
1448 | if (!data->bulk_out || !data->bulk_in) { | ||
1449 | dev_err(&intf->dev, "bulk endpoints not found\n"); | ||
1450 | retcode = -ENODEV; | ||
1451 | goto err_put; | ||
1452 | } | ||
1453 | |||
1447 | /* Find int endpoint */ | 1454 | /* Find int endpoint */ |
1448 | for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) { | 1455 | for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) { |
1449 | endpoint = &iface_desc->endpoint[n].desc; | 1456 | endpoint = &iface_desc->endpoint[n].desc; |
@@ -1469,8 +1476,10 @@ static int usbtmc_probe(struct usb_interface *intf, | |||
1469 | if (data->iin_ep_present) { | 1476 | if (data->iin_ep_present) { |
1470 | /* allocate int urb */ | 1477 | /* allocate int urb */ |
1471 | data->iin_urb = usb_alloc_urb(0, GFP_KERNEL); | 1478 | data->iin_urb = usb_alloc_urb(0, GFP_KERNEL); |
1472 | if (!data->iin_urb) | 1479 | if (!data->iin_urb) { |
1480 | retcode = -ENOMEM; | ||
1473 | goto error_register; | 1481 | goto error_register; |
1482 | } | ||
1474 | 1483 | ||
1475 | /* Protect interrupt in endpoint data until iin_urb is freed */ | 1484 | /* Protect interrupt in endpoint data until iin_urb is freed */ |
1476 | kref_get(&data->kref); | 1485 | kref_get(&data->kref); |
@@ -1478,8 +1487,10 @@ static int usbtmc_probe(struct usb_interface *intf, | |||
1478 | /* allocate buffer for interrupt in */ | 1487 | /* allocate buffer for interrupt in */ |
1479 | data->iin_buffer = kmalloc(data->iin_wMaxPacketSize, | 1488 | data->iin_buffer = kmalloc(data->iin_wMaxPacketSize, |
1480 | GFP_KERNEL); | 1489 | GFP_KERNEL); |
1481 | if (!data->iin_buffer) | 1490 | if (!data->iin_buffer) { |
1491 | retcode = -ENOMEM; | ||
1482 | goto error_register; | 1492 | goto error_register; |
1493 | } | ||
1483 | 1494 | ||
1484 | /* fill interrupt urb */ | 1495 | /* fill interrupt urb */ |
1485 | usb_fill_int_urb(data->iin_urb, data->usb_dev, | 1496 | usb_fill_int_urb(data->iin_urb, data->usb_dev, |
@@ -1512,6 +1523,7 @@ error_register: | |||
1512 | sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp); | 1523 | sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp); |
1513 | sysfs_remove_group(&intf->dev.kobj, &data_attr_grp); | 1524 | sysfs_remove_group(&intf->dev.kobj, &data_attr_grp); |
1514 | usbtmc_free_int(data); | 1525 | usbtmc_free_int(data); |
1526 | err_put: | ||
1515 | kref_put(&data->kref, usbtmc_delete); | 1527 | kref_put(&data->kref, usbtmc_delete); |
1516 | return retcode; | 1528 | return retcode; |
1517 | } | 1529 | } |
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 25dbd8c7aec7..4be52c602e9b 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -280,6 +280,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | |||
280 | 280 | ||
281 | /* | 281 | /* |
282 | * Adjust bInterval for quirked devices. | 282 | * Adjust bInterval for quirked devices. |
283 | */ | ||
284 | /* | ||
285 | * This quirk fixes bIntervals reported in ms. | ||
286 | */ | ||
287 | if (to_usb_device(ddev)->quirks & | ||
288 | USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL) { | ||
289 | n = clamp(fls(d->bInterval) + 3, i, j); | ||
290 | i = j = n; | ||
291 | } | ||
292 | /* | ||
283 | * This quirk fixes bIntervals reported in | 293 | * This quirk fixes bIntervals reported in |
284 | * linear microframes. | 294 | * linear microframes. |
285 | */ | 295 | */ |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index f0dd08198d74..5286bf67869a 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -4275,7 +4275,7 @@ static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev) | |||
4275 | struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); | 4275 | struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent); |
4276 | int connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN; | 4276 | int connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN; |
4277 | 4277 | ||
4278 | if (!udev->usb2_hw_lpm_capable) | 4278 | if (!udev->usb2_hw_lpm_capable || !udev->bos) |
4279 | return; | 4279 | return; |
4280 | 4280 | ||
4281 | if (hub) | 4281 | if (hub) |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 24f9f98968a5..96b21b0dac1e 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -170,6 +170,14 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
170 | /* M-Systems Flash Disk Pioneers */ | 170 | /* M-Systems Flash Disk Pioneers */ |
171 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, | 171 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, |
172 | 172 | ||
173 | /* Baum Vario Ultra */ | ||
174 | { USB_DEVICE(0x0904, 0x6101), .driver_info = | ||
175 | USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL }, | ||
176 | { USB_DEVICE(0x0904, 0x6102), .driver_info = | ||
177 | USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL }, | ||
178 | { USB_DEVICE(0x0904, 0x6103), .driver_info = | ||
179 | USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL }, | ||
180 | |||
173 | /* Keytouch QWERTY Panel keyboard */ | 181 | /* Keytouch QWERTY Panel keyboard */ |
174 | { USB_DEVICE(0x0926, 0x3333), .driver_info = | 182 | { USB_DEVICE(0x0926, 0x3333), .driver_info = |
175 | USB_QUIRK_CONFIG_INTF_STRINGS }, | 183 | USB_QUIRK_CONFIG_INTF_STRINGS }, |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 0d75158e43fe..79e7a3480d51 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -171,6 +171,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | |||
171 | int status) | 171 | int status) |
172 | { | 172 | { |
173 | struct dwc3 *dwc = dep->dwc; | 173 | struct dwc3 *dwc = dep->dwc; |
174 | unsigned int unmap_after_complete = false; | ||
174 | 175 | ||
175 | req->started = false; | 176 | req->started = false; |
176 | list_del(&req->list); | 177 | list_del(&req->list); |
@@ -180,11 +181,19 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | |||
180 | if (req->request.status == -EINPROGRESS) | 181 | if (req->request.status == -EINPROGRESS) |
181 | req->request.status = status; | 182 | req->request.status = status; |
182 | 183 | ||
183 | if (dwc->ep0_bounced && dep->number <= 1) | 184 | /* |
185 | * NOTICE we don't want to unmap before calling ->complete() if we're | ||
186 | * dealing with a bounced ep0 request. If we unmap it here, we would end | ||
187 | * up overwritting the contents of req->buf and this could confuse the | ||
188 | * gadget driver. | ||
189 | */ | ||
190 | if (dwc->ep0_bounced && dep->number <= 1) { | ||
184 | dwc->ep0_bounced = false; | 191 | dwc->ep0_bounced = false; |
185 | 192 | unmap_after_complete = true; | |
186 | usb_gadget_unmap_request_by_dev(dwc->sysdev, | 193 | } else { |
187 | &req->request, req->direction); | 194 | usb_gadget_unmap_request_by_dev(dwc->sysdev, |
195 | &req->request, req->direction); | ||
196 | } | ||
188 | 197 | ||
189 | trace_dwc3_gadget_giveback(req); | 198 | trace_dwc3_gadget_giveback(req); |
190 | 199 | ||
@@ -192,6 +201,10 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | |||
192 | usb_gadget_giveback_request(&dep->endpoint, &req->request); | 201 | usb_gadget_giveback_request(&dep->endpoint, &req->request); |
193 | spin_lock(&dwc->lock); | 202 | spin_lock(&dwc->lock); |
194 | 203 | ||
204 | if (unmap_after_complete) | ||
205 | usb_gadget_unmap_request_by_dev(dwc->sysdev, | ||
206 | &req->request, req->direction); | ||
207 | |||
195 | if (dep->number > 1) | 208 | if (dep->number > 1) |
196 | pm_runtime_put(dwc->dev); | 209 | pm_runtime_put(dwc->dev); |
197 | } | 210 | } |
diff --git a/drivers/usb/gadget/function/f_acm.c b/drivers/usb/gadget/function/f_acm.c index a30766ca4226..5e3828d9dac7 100644 --- a/drivers/usb/gadget/function/f_acm.c +++ b/drivers/usb/gadget/function/f_acm.c | |||
@@ -535,13 +535,15 @@ static int acm_notify_serial_state(struct f_acm *acm) | |||
535 | { | 535 | { |
536 | struct usb_composite_dev *cdev = acm->port.func.config->cdev; | 536 | struct usb_composite_dev *cdev = acm->port.func.config->cdev; |
537 | int status; | 537 | int status; |
538 | __le16 serial_state; | ||
538 | 539 | ||
539 | spin_lock(&acm->lock); | 540 | spin_lock(&acm->lock); |
540 | if (acm->notify_req) { | 541 | if (acm->notify_req) { |
541 | dev_dbg(&cdev->gadget->dev, "acm ttyGS%d serial state %04x\n", | 542 | dev_dbg(&cdev->gadget->dev, "acm ttyGS%d serial state %04x\n", |
542 | acm->port_num, acm->serial_state); | 543 | acm->port_num, acm->serial_state); |
544 | serial_state = cpu_to_le16(acm->serial_state); | ||
543 | status = acm_cdc_notify(acm, USB_CDC_NOTIFY_SERIAL_STATE, | 545 | status = acm_cdc_notify(acm, USB_CDC_NOTIFY_SERIAL_STATE, |
544 | 0, &acm->serial_state, sizeof(acm->serial_state)); | 546 | 0, &serial_state, sizeof(acm->serial_state)); |
545 | } else { | 547 | } else { |
546 | acm->pending = true; | 548 | acm->pending = true; |
547 | status = 0; | 549 | status = 0; |
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 89b48bcc377a..5eea44823ca0 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c | |||
@@ -367,7 +367,7 @@ try_again: | |||
367 | count = min_t(unsigned, count, hidg->report_length); | 367 | count = min_t(unsigned, count, hidg->report_length); |
368 | 368 | ||
369 | spin_unlock_irqrestore(&hidg->write_spinlock, flags); | 369 | spin_unlock_irqrestore(&hidg->write_spinlock, flags); |
370 | status = copy_from_user(hidg->req->buf, buffer, count); | 370 | status = copy_from_user(req->buf, buffer, count); |
371 | 371 | ||
372 | if (status != 0) { | 372 | if (status != 0) { |
373 | ERROR(hidg->func.config->cdev, | 373 | ERROR(hidg->func.config->cdev, |
@@ -378,9 +378,9 @@ try_again: | |||
378 | 378 | ||
379 | spin_lock_irqsave(&hidg->write_spinlock, flags); | 379 | spin_lock_irqsave(&hidg->write_spinlock, flags); |
380 | 380 | ||
381 | /* we our function has been disabled by host */ | 381 | /* when our function has been disabled by host */ |
382 | if (!hidg->req) { | 382 | if (!hidg->req) { |
383 | free_ep_req(hidg->in_ep, hidg->req); | 383 | free_ep_req(hidg->in_ep, req); |
384 | /* | 384 | /* |
385 | * TODO | 385 | * TODO |
386 | * Should we fail with error here? | 386 | * Should we fail with error here? |
@@ -394,7 +394,7 @@ try_again: | |||
394 | req->complete = f_hidg_req_complete; | 394 | req->complete = f_hidg_req_complete; |
395 | req->context = hidg; | 395 | req->context = hidg; |
396 | 396 | ||
397 | status = usb_ep_queue(hidg->in_ep, hidg->req, GFP_ATOMIC); | 397 | status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC); |
398 | if (status < 0) { | 398 | if (status < 0) { |
399 | ERROR(hidg->func.config->cdev, | 399 | ERROR(hidg->func.config->cdev, |
400 | "usb_ep_queue error on int endpoint %zd\n", status); | 400 | "usb_ep_queue error on int endpoint %zd\n", status); |
diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 29b41b5dee04..f8a1881609a2 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c | |||
@@ -594,6 +594,14 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) | |||
594 | opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U); | 594 | opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U); |
595 | opts->streaming_maxburst = min(opts->streaming_maxburst, 15U); | 595 | opts->streaming_maxburst = min(opts->streaming_maxburst, 15U); |
596 | 596 | ||
597 | /* For SS, wMaxPacketSize has to be 1024 if bMaxBurst is not 0 */ | ||
598 | if (opts->streaming_maxburst && | ||
599 | (opts->streaming_maxpacket % 1024) != 0) { | ||
600 | opts->streaming_maxpacket = roundup(opts->streaming_maxpacket, 1024); | ||
601 | INFO(cdev, "overriding streaming_maxpacket to %d\n", | ||
602 | opts->streaming_maxpacket); | ||
603 | } | ||
604 | |||
597 | /* Fill in the FS/HS/SS Video Streaming specific descriptors from the | 605 | /* Fill in the FS/HS/SS Video Streaming specific descriptors from the |
598 | * module parameters. | 606 | * module parameters. |
599 | * | 607 | * |
@@ -625,7 +633,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) | |||
625 | uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst; | 633 | uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst; |
626 | uvc_ss_streaming_comp.wBytesPerInterval = | 634 | uvc_ss_streaming_comp.wBytesPerInterval = |
627 | cpu_to_le16(max_packet_size * max_packet_mult * | 635 | cpu_to_le16(max_packet_size * max_packet_mult * |
628 | opts->streaming_maxburst); | 636 | (opts->streaming_maxburst + 1)); |
629 | 637 | ||
630 | /* Allocate endpoints. */ | 638 | /* Allocate endpoints. */ |
631 | ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep); | 639 | ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep); |
diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index a97da645c1b9..8a365aad66fe 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c | |||
@@ -1523,7 +1523,6 @@ static void pch_udc_free_dma_chain(struct pch_udc_dev *dev, | |||
1523 | td = phys_to_virt(addr); | 1523 | td = phys_to_virt(addr); |
1524 | addr2 = (dma_addr_t)td->next; | 1524 | addr2 = (dma_addr_t)td->next; |
1525 | pci_pool_free(dev->data_requests, td, addr); | 1525 | pci_pool_free(dev->data_requests, td, addr); |
1526 | td->next = 0x00; | ||
1527 | addr = addr2; | 1526 | addr = addr2; |
1528 | } | 1527 | } |
1529 | req->chain_len = 1; | 1528 | req->chain_len = 1; |
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index 8b9fd7534f69..502bfe30a077 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c | |||
@@ -347,6 +347,9 @@ static int idmouse_probe(struct usb_interface *interface, | |||
347 | if (iface_desc->desc.bInterfaceClass != 0x0A) | 347 | if (iface_desc->desc.bInterfaceClass != 0x0A) |
348 | return -ENODEV; | 348 | return -ENODEV; |
349 | 349 | ||
350 | if (iface_desc->desc.bNumEndpoints < 1) | ||
351 | return -ENODEV; | ||
352 | |||
350 | /* allocate memory for our device state and initialize it */ | 353 | /* allocate memory for our device state and initialize it */ |
351 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 354 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
352 | if (dev == NULL) | 355 | if (dev == NULL) |
diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c index 77176511658f..d3d124753266 100644 --- a/drivers/usb/misc/lvstest.c +++ b/drivers/usb/misc/lvstest.c | |||
@@ -366,6 +366,10 @@ static int lvs_rh_probe(struct usb_interface *intf, | |||
366 | 366 | ||
367 | hdev = interface_to_usbdev(intf); | 367 | hdev = interface_to_usbdev(intf); |
368 | desc = intf->cur_altsetting; | 368 | desc = intf->cur_altsetting; |
369 | |||
370 | if (desc->desc.bNumEndpoints < 1) | ||
371 | return -ENODEV; | ||
372 | |||
369 | endpoint = &desc->endpoint[0].desc; | 373 | endpoint = &desc->endpoint[0].desc; |
370 | 374 | ||
371 | /* valid only for SS root hub */ | 375 | /* valid only for SS root hub */ |
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index e45a3a680db8..07014cad6dbe 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c | |||
@@ -709,6 +709,11 @@ static int uss720_probe(struct usb_interface *intf, | |||
709 | 709 | ||
710 | interface = intf->cur_altsetting; | 710 | interface = intf->cur_altsetting; |
711 | 711 | ||
712 | if (interface->desc.bNumEndpoints < 3) { | ||
713 | usb_put_dev(usbdev); | ||
714 | return -ENODEV; | ||
715 | } | ||
716 | |||
712 | /* | 717 | /* |
713 | * Allocate parport interface | 718 | * Allocate parport interface |
714 | */ | 719 | */ |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index d8bae6ca8904..0c3664ab705e 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -2490,8 +2490,8 @@ static int musb_remove(struct platform_device *pdev) | |||
2490 | musb_host_cleanup(musb); | 2490 | musb_host_cleanup(musb); |
2491 | musb_gadget_cleanup(musb); | 2491 | musb_gadget_cleanup(musb); |
2492 | 2492 | ||
2493 | spin_lock_irqsave(&musb->lock, flags); | ||
2494 | musb_platform_disable(musb); | 2493 | musb_platform_disable(musb); |
2494 | spin_lock_irqsave(&musb->lock, flags); | ||
2495 | musb_disable_interrupts(musb); | 2495 | musb_disable_interrupts(musb); |
2496 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); | 2496 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); |
2497 | spin_unlock_irqrestore(&musb->lock, flags); | 2497 | spin_unlock_irqrestore(&musb->lock, flags); |
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index 00e272bfee39..355655f8a3fb 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c | |||
@@ -238,8 +238,27 @@ static void cppi41_dma_callback(void *private_data, | |||
238 | transferred < cppi41_channel->packet_sz) | 238 | transferred < cppi41_channel->packet_sz) |
239 | cppi41_channel->prog_len = 0; | 239 | cppi41_channel->prog_len = 0; |
240 | 240 | ||
241 | if (cppi41_channel->is_tx) | 241 | if (cppi41_channel->is_tx) { |
242 | empty = musb_is_tx_fifo_empty(hw_ep); | 242 | u8 type; |
243 | |||
244 | if (is_host_active(musb)) | ||
245 | type = hw_ep->out_qh->type; | ||
246 | else | ||
247 | type = hw_ep->ep_in.type; | ||
248 | |||
249 | if (type == USB_ENDPOINT_XFER_ISOC) | ||
250 | /* | ||
251 | * Don't use the early-TX-interrupt workaround below | ||
252 | * for Isoch transfter. Since Isoch are periodic | ||
253 | * transfer, by the time the next transfer is | ||
254 | * scheduled, the current one should be done already. | ||
255 | * | ||
256 | * This avoids audio playback underrun issue. | ||
257 | */ | ||
258 | empty = true; | ||
259 | else | ||
260 | empty = musb_is_tx_fifo_empty(hw_ep); | ||
261 | } | ||
243 | 262 | ||
244 | if (!cppi41_channel->is_tx || empty) { | 263 | if (!cppi41_channel->is_tx || empty) { |
245 | cppi41_trans_done(cppi41_channel); | 264 | cppi41_trans_done(cppi41_channel); |
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 7c047c4a2565..9c7ee26ef388 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
@@ -933,7 +933,7 @@ static int dsps_probe(struct platform_device *pdev) | |||
933 | if (usb_get_dr_mode(&pdev->dev) == USB_DR_MODE_PERIPHERAL) { | 933 | if (usb_get_dr_mode(&pdev->dev) == USB_DR_MODE_PERIPHERAL) { |
934 | ret = dsps_setup_optional_vbus_irq(pdev, glue); | 934 | ret = dsps_setup_optional_vbus_irq(pdev, glue); |
935 | if (ret) | 935 | if (ret) |
936 | return ret; | 936 | goto err_iounmap; |
937 | } | 937 | } |
938 | 938 | ||
939 | platform_set_drvdata(pdev, glue); | 939 | platform_set_drvdata(pdev, glue); |
@@ -946,6 +946,8 @@ static int dsps_probe(struct platform_device *pdev) | |||
946 | 946 | ||
947 | err: | 947 | err: |
948 | pm_runtime_disable(&pdev->dev); | 948 | pm_runtime_disable(&pdev->dev); |
949 | err_iounmap: | ||
950 | iounmap(glue->usbss_base); | ||
949 | return ret; | 951 | return ret; |
950 | } | 952 | } |
951 | 953 | ||
@@ -956,6 +958,7 @@ static int dsps_remove(struct platform_device *pdev) | |||
956 | platform_device_unregister(glue->musb); | 958 | platform_device_unregister(glue->musb); |
957 | 959 | ||
958 | pm_runtime_disable(&pdev->dev); | 960 | pm_runtime_disable(&pdev->dev); |
961 | iounmap(glue->usbss_base); | ||
959 | 962 | ||
960 | return 0; | 963 | return 0; |
961 | } | 964 | } |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 42cc72e54c05..af67a0de6b5d 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -233,6 +233,14 @@ static void option_instat_callback(struct urb *urb); | |||
233 | #define BANDRICH_PRODUCT_1012 0x1012 | 233 | #define BANDRICH_PRODUCT_1012 0x1012 |
234 | 234 | ||
235 | #define QUALCOMM_VENDOR_ID 0x05C6 | 235 | #define QUALCOMM_VENDOR_ID 0x05C6 |
236 | /* These Quectel products use Qualcomm's vendor ID */ | ||
237 | #define QUECTEL_PRODUCT_UC20 0x9003 | ||
238 | #define QUECTEL_PRODUCT_UC15 0x9090 | ||
239 | |||
240 | #define QUECTEL_VENDOR_ID 0x2c7c | ||
241 | /* These Quectel products use Quectel's vendor ID */ | ||
242 | #define QUECTEL_PRODUCT_EC21 0x0121 | ||
243 | #define QUECTEL_PRODUCT_EC25 0x0125 | ||
236 | 244 | ||
237 | #define CMOTECH_VENDOR_ID 0x16d8 | 245 | #define CMOTECH_VENDOR_ID 0x16d8 |
238 | #define CMOTECH_PRODUCT_6001 0x6001 | 246 | #define CMOTECH_PRODUCT_6001 0x6001 |
@@ -1161,7 +1169,14 @@ static const struct usb_device_id option_ids[] = { | |||
1161 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ | 1169 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ |
1162 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ | 1170 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ |
1163 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ | 1171 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ |
1164 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9003), /* Quectel UC20 */ | 1172 | /* Quectel products using Qualcomm vendor ID */ |
1173 | { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, | ||
1174 | { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), | ||
1175 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | ||
1176 | /* Quectel products using Quectel vendor ID */ | ||
1177 | { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21), | ||
1178 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | ||
1179 | { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC25), | ||
1165 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 1180 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
1166 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, | 1181 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, |
1167 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, | 1182 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 696458db7e3c..38b3f0d8cd58 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -169,6 +169,8 @@ static const struct usb_device_id id_table[] = { | |||
169 | {DEVICE_SWI(0x413c, 0x81a9)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */ | 169 | {DEVICE_SWI(0x413c, 0x81a9)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */ |
170 | {DEVICE_SWI(0x413c, 0x81b1)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */ | 170 | {DEVICE_SWI(0x413c, 0x81b1)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */ |
171 | {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ | 171 | {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ |
172 | {DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */ | ||
173 | {DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */ | ||
172 | 174 | ||
173 | /* Huawei devices */ | 175 | /* Huawei devices */ |
174 | {DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */ | 176 | {DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */ |
diff --git a/drivers/usb/wusbcore/wa-hc.c b/drivers/usb/wusbcore/wa-hc.c index 252c7bd9218a..d01496fd27fe 100644 --- a/drivers/usb/wusbcore/wa-hc.c +++ b/drivers/usb/wusbcore/wa-hc.c | |||
@@ -39,6 +39,9 @@ int wa_create(struct wahc *wa, struct usb_interface *iface, | |||
39 | int result; | 39 | int result; |
40 | struct device *dev = &iface->dev; | 40 | struct device *dev = &iface->dev; |
41 | 41 | ||
42 | if (iface->cur_altsetting->desc.bNumEndpoints < 3) | ||
43 | return -ENODEV; | ||
44 | |||
42 | result = wa_rpipes_create(wa); | 45 | result = wa_rpipes_create(wa); |
43 | if (result < 0) | 46 | if (result < 0) |
44 | goto error_rpipes_create; | 47 | goto error_rpipes_create; |
diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index 0aa6c3c29d17..35a1e777b449 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c | |||
@@ -823,6 +823,9 @@ static int hwarc_probe(struct usb_interface *iface, | |||
823 | struct hwarc *hwarc; | 823 | struct hwarc *hwarc; |
824 | struct device *dev = &iface->dev; | 824 | struct device *dev = &iface->dev; |
825 | 825 | ||
826 | if (iface->cur_altsetting->desc.bNumEndpoints < 1) | ||
827 | return -ENODEV; | ||
828 | |||
826 | result = -ENOMEM; | 829 | result = -ENOMEM; |
827 | uwb_rc = uwb_rc_alloc(); | 830 | uwb_rc = uwb_rc_alloc(); |
828 | if (uwb_rc == NULL) { | 831 | if (uwb_rc == NULL) { |
diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c index 2bfc846ac071..6345e85822a4 100644 --- a/drivers/uwb/i1480/dfu/usb.c +++ b/drivers/uwb/i1480/dfu/usb.c | |||
@@ -362,6 +362,9 @@ int i1480_usb_probe(struct usb_interface *iface, const struct usb_device_id *id) | |||
362 | result); | 362 | result); |
363 | } | 363 | } |
364 | 364 | ||
365 | if (iface->cur_altsetting->desc.bNumEndpoints < 1) | ||
366 | return -ENODEV; | ||
367 | |||
365 | result = -ENOMEM; | 368 | result = -ENOMEM; |
366 | i1480_usb = kzalloc(sizeof(*i1480_usb), GFP_KERNEL); | 369 | i1480_usb = kzalloc(sizeof(*i1480_usb), GFP_KERNEL); |
367 | if (i1480_usb == NULL) { | 370 | if (i1480_usb == NULL) { |
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h index 1d0043dc34e4..de2a722fe3cf 100644 --- a/include/linux/usb/quirks.h +++ b/include/linux/usb/quirks.h | |||
@@ -50,4 +50,10 @@ | |||
50 | /* device can't handle Link Power Management */ | 50 | /* device can't handle Link Power Management */ |
51 | #define USB_QUIRK_NO_LPM BIT(10) | 51 | #define USB_QUIRK_NO_LPM BIT(10) |
52 | 52 | ||
53 | /* | ||
54 | * Device reports its bInterval as linear frames instead of the | ||
55 | * USB 2.0 calculation. | ||
56 | */ | ||
57 | #define USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL BIT(11) | ||
58 | |||
53 | #endif /* __LINUX_USB_QUIRKS_H */ | 59 | #endif /* __LINUX_USB_QUIRKS_H */ |