USB/PHY fixes for 4.11-rc4
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. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCWNefwQ8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ykewwCg1P1HEZV2wLJSalsPxduIKIRLcmkAnRcE0H31 2egrp1seSGQumYcGQUJ/ =2fH+ -----END PGP SIGNATURE----- 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 ...
This commit is contained in:
Коммит
e431e0e427
|
@ -1,39 +0,0 @@
|
|||
Broadcom USB3 phy binding for northstar plus SoC
|
||||
The USB3 phy is internal to the SoC and is accessed using mdio interface.
|
||||
|
||||
Required mdio bus properties:
|
||||
- reg: Should be 0x0 for SoC internal USB3 phy
|
||||
- #address-cells: must be 1
|
||||
- #size-cells: must be 0
|
||||
|
||||
Required USB3 PHY properties:
|
||||
- compatible: should be "brcm,nsp-usb3-phy"
|
||||
- reg: USB3 Phy address on SoC internal MDIO bus and it should be 0x10.
|
||||
- usb3-ctrl-syscon: handler of syscon node defining physical address
|
||||
of usb3 control register.
|
||||
- #phy-cells: must be 0
|
||||
|
||||
Required usb3 control properties:
|
||||
- compatible: should be "brcm,nsp-usb3-ctrl"
|
||||
- reg: offset and length of the control registers
|
||||
|
||||
Example:
|
||||
|
||||
mdio@0 {
|
||||
reg = <0x0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
usb3_phy: usb-phy@10 {
|
||||
compatible = "brcm,nsp-usb3-phy";
|
||||
reg = <0x10>;
|
||||
usb3-ctrl-syscon = <&usb3_ctrl>;
|
||||
#phy-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
usb3_ctrl: syscon@104408 {
|
||||
compatible = "brcm,nsp-usb3-ctrl", "syscon";
|
||||
reg = <0x104408 0x3fc>;
|
||||
};
|
|
@ -449,6 +449,7 @@ config PHY_QCOM_UFS
|
|||
config PHY_QCOM_USB_HS
|
||||
tristate "Qualcomm USB HS PHY module"
|
||||
depends on USB_ULPI_BUS
|
||||
depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Support for the USB high-speed ULPI compliant phy on Qualcomm
|
||||
|
@ -510,12 +511,4 @@ config PHY_MESON8B_USB2
|
|||
and GXBB SoCs.
|
||||
If unsure, say N.
|
||||
|
||||
config PHY_NSP_USB3
|
||||
tristate "Broadcom NorthStar plus USB3 PHY driver"
|
||||
depends on OF && (ARCH_BCM_NSP || COMPILE_TEST)
|
||||
select GENERIC_PHY
|
||||
default ARCH_BCM_NSP
|
||||
help
|
||||
Enable this to support the Broadcom Northstar plus USB3 PHY.
|
||||
If unsure, say N.
|
||||
endmenu
|
||||
|
|
|
@ -62,4 +62,3 @@ obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o
|
|||
obj-$(CONFIG_ARCH_TEGRA) += tegra/
|
||||
obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o
|
||||
obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o
|
||||
obj-$(CONFIG_PHY_NSP_USB3) += phy-bcm-nsp-usb3.o
|
||||
|
|
|
@ -1,177 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Broadcom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation version 2.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether express or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/mdio.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define NSP_USB3_RST_CTRL_OFFSET 0x3f8
|
||||
|
||||
/* mdio reg access */
|
||||
#define NSP_USB3_PHY_BASE_ADDR_REG 0x1f
|
||||
|
||||
#define NSP_USB3_PHY_PLL30_BLOCK 0x8000
|
||||
#define NSP_USB3_PLL_CONTROL 0x01
|
||||
#define NSP_USB3_PLLA_CONTROL0 0x0a
|
||||
#define NSP_USB3_PLLA_CONTROL1 0x0b
|
||||
|
||||
#define NSP_USB3_PHY_TX_PMD_BLOCK 0x8040
|
||||
#define NSP_USB3_TX_PMD_CONTROL1 0x01
|
||||
|
||||
#define NSP_USB3_PHY_PIPE_BLOCK 0x8060
|
||||
#define NSP_USB3_LFPS_CMP 0x02
|
||||
#define NSP_USB3_LFPS_DEGLITCH 0x03
|
||||
|
||||
struct nsp_usb3_phy {
|
||||
struct regmap *usb3_ctrl;
|
||||
struct phy *phy;
|
||||
struct mdio_device *mdiodev;
|
||||
};
|
||||
|
||||
static int nsp_usb3_phy_init(struct phy *phy)
|
||||
{
|
||||
struct nsp_usb3_phy *iphy = phy_get_drvdata(phy);
|
||||
struct mii_bus *bus = iphy->mdiodev->bus;
|
||||
int addr = iphy->mdiodev->addr;
|
||||
u32 data;
|
||||
int rc;
|
||||
|
||||
rc = regmap_read(iphy->usb3_ctrl, 0, &data);
|
||||
if (rc)
|
||||
return rc;
|
||||
data |= 1;
|
||||
rc = regmap_write(iphy->usb3_ctrl, 0, data);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = regmap_write(iphy->usb3_ctrl, NSP_USB3_RST_CTRL_OFFSET, 1);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG,
|
||||
NSP_USB3_PHY_PLL30_BLOCK);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = mdiobus_write(bus, addr, NSP_USB3_PLL_CONTROL, 0x1000);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL0, 0x6400);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL1, 0xc000);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL1, 0x8000);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = regmap_write(iphy->usb3_ctrl, NSP_USB3_RST_CTRL_OFFSET, 0);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = mdiobus_write(bus, addr, NSP_USB3_PLL_CONTROL, 0x9000);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG,
|
||||
NSP_USB3_PHY_PIPE_BLOCK);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = mdiobus_write(bus, addr, NSP_USB3_LFPS_CMP, 0xf30d);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = mdiobus_write(bus, addr, NSP_USB3_LFPS_DEGLITCH, 0x6302);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG,
|
||||
NSP_USB3_PHY_TX_PMD_BLOCK);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = mdiobus_write(bus, addr, NSP_USB3_TX_PMD_CONTROL1, 0x1003);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct phy_ops nsp_usb3_phy_ops = {
|
||||
.init = nsp_usb3_phy_init,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int nsp_usb3_phy_probe(struct mdio_device *mdiodev)
|
||||
{
|
||||
struct device *dev = &mdiodev->dev;
|
||||
struct phy_provider *provider;
|
||||
struct nsp_usb3_phy *iphy;
|
||||
|
||||
iphy = devm_kzalloc(dev, sizeof(*iphy), GFP_KERNEL);
|
||||
if (!iphy)
|
||||
return -ENOMEM;
|
||||
iphy->mdiodev = mdiodev;
|
||||
|
||||
iphy->usb3_ctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
|
||||
"usb3-ctrl-syscon");
|
||||
if (IS_ERR(iphy->usb3_ctrl))
|
||||
return PTR_ERR(iphy->usb3_ctrl);
|
||||
|
||||
iphy->phy = devm_phy_create(dev, dev->of_node, &nsp_usb3_phy_ops);
|
||||
if (IS_ERR(iphy->phy)) {
|
||||
dev_err(dev, "failed to create PHY\n");
|
||||
return PTR_ERR(iphy->phy);
|
||||
}
|
||||
|
||||
phy_set_drvdata(iphy->phy, iphy);
|
||||
|
||||
provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
if (IS_ERR(provider)) {
|
||||
dev_err(dev, "could not register PHY provider\n");
|
||||
return PTR_ERR(provider);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id nsp_usb3_phy_of_match[] = {
|
||||
{.compatible = "brcm,nsp-usb3-phy",},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct mdio_driver nsp_usb3_phy_driver = {
|
||||
.mdiodrv = {
|
||||
.driver = {
|
||||
.name = "nsp-usb3-phy",
|
||||
.of_match_table = nsp_usb3_phy_of_match,
|
||||
},
|
||||
},
|
||||
.probe = nsp_usb3_phy_probe,
|
||||
};
|
||||
|
||||
mdio_module_driver(nsp_usb3_phy_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Broadcom NSP USB3 PHY driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com");
|
|
@ -254,8 +254,8 @@ static int exynos_pcie_phy_probe(struct platform_device *pdev)
|
|||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
exynos_phy->blk_base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(exynos_phy->phy_base))
|
||||
return PTR_ERR(exynos_phy->phy_base);
|
||||
if (IS_ERR(exynos_phy->blk_base))
|
||||
return PTR_ERR(exynos_phy->blk_base);
|
||||
|
||||
exynos_phy->drv_data = drv_data;
|
||||
|
||||
|
|
|
@ -1381,7 +1381,7 @@ static int usbtmc_probe(struct usb_interface *intf,
|
|||
|
||||
dev_dbg(&intf->dev, "%s called\n", __func__);
|
||||
|
||||
data = kmalloc(sizeof(*data), GFP_KERNEL);
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1444,6 +1444,13 @@ static int usbtmc_probe(struct usb_interface *intf,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!data->bulk_out || !data->bulk_in) {
|
||||
dev_err(&intf->dev, "bulk endpoints not found\n");
|
||||
retcode = -ENODEV;
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
/* Find int endpoint */
|
||||
for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) {
|
||||
endpoint = &iface_desc->endpoint[n].desc;
|
||||
|
@ -1469,8 +1476,10 @@ static int usbtmc_probe(struct usb_interface *intf,
|
|||
if (data->iin_ep_present) {
|
||||
/* allocate int urb */
|
||||
data->iin_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!data->iin_urb)
|
||||
if (!data->iin_urb) {
|
||||
retcode = -ENOMEM;
|
||||
goto error_register;
|
||||
}
|
||||
|
||||
/* Protect interrupt in endpoint data until iin_urb is freed */
|
||||
kref_get(&data->kref);
|
||||
|
@ -1478,8 +1487,10 @@ static int usbtmc_probe(struct usb_interface *intf,
|
|||
/* allocate buffer for interrupt in */
|
||||
data->iin_buffer = kmalloc(data->iin_wMaxPacketSize,
|
||||
GFP_KERNEL);
|
||||
if (!data->iin_buffer)
|
||||
if (!data->iin_buffer) {
|
||||
retcode = -ENOMEM;
|
||||
goto error_register;
|
||||
}
|
||||
|
||||
/* fill interrupt urb */
|
||||
usb_fill_int_urb(data->iin_urb, data->usb_dev,
|
||||
|
@ -1512,6 +1523,7 @@ error_register:
|
|||
sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp);
|
||||
sysfs_remove_group(&intf->dev.kobj, &data_attr_grp);
|
||||
usbtmc_free_int(data);
|
||||
err_put:
|
||||
kref_put(&data->kref, usbtmc_delete);
|
||||
return retcode;
|
||||
}
|
||||
|
|
|
@ -280,6 +280,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
|
|||
|
||||
/*
|
||||
* Adjust bInterval for quirked devices.
|
||||
*/
|
||||
/*
|
||||
* This quirk fixes bIntervals reported in ms.
|
||||
*/
|
||||
if (to_usb_device(ddev)->quirks &
|
||||
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL) {
|
||||
n = clamp(fls(d->bInterval) + 3, i, j);
|
||||
i = j = n;
|
||||
}
|
||||
/*
|
||||
* This quirk fixes bIntervals reported in
|
||||
* linear microframes.
|
||||
*/
|
||||
|
|
|
@ -4275,7 +4275,7 @@ static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev)
|
|||
struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
|
||||
int connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN;
|
||||
|
||||
if (!udev->usb2_hw_lpm_capable)
|
||||
if (!udev->usb2_hw_lpm_capable || !udev->bos)
|
||||
return;
|
||||
|
||||
if (hub)
|
||||
|
|
|
@ -170,6 +170,14 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||
/* M-Systems Flash Disk Pioneers */
|
||||
{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Baum Vario Ultra */
|
||||
{ USB_DEVICE(0x0904, 0x6101), .driver_info =
|
||||
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
|
||||
{ USB_DEVICE(0x0904, 0x6102), .driver_info =
|
||||
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
|
||||
{ USB_DEVICE(0x0904, 0x6103), .driver_info =
|
||||
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
|
||||
|
||||
/* Keytouch QWERTY Panel keyboard */
|
||||
{ USB_DEVICE(0x0926, 0x3333), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
|
|
@ -171,6 +171,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
|||
int status)
|
||||
{
|
||||
struct dwc3 *dwc = dep->dwc;
|
||||
unsigned int unmap_after_complete = false;
|
||||
|
||||
req->started = false;
|
||||
list_del(&req->list);
|
||||
|
@ -180,11 +181,19 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
|||
if (req->request.status == -EINPROGRESS)
|
||||
req->request.status = status;
|
||||
|
||||
if (dwc->ep0_bounced && dep->number <= 1)
|
||||
/*
|
||||
* NOTICE we don't want to unmap before calling ->complete() if we're
|
||||
* dealing with a bounced ep0 request. If we unmap it here, we would end
|
||||
* up overwritting the contents of req->buf and this could confuse the
|
||||
* gadget driver.
|
||||
*/
|
||||
if (dwc->ep0_bounced && dep->number <= 1) {
|
||||
dwc->ep0_bounced = false;
|
||||
|
||||
usb_gadget_unmap_request_by_dev(dwc->sysdev,
|
||||
&req->request, req->direction);
|
||||
unmap_after_complete = true;
|
||||
} else {
|
||||
usb_gadget_unmap_request_by_dev(dwc->sysdev,
|
||||
&req->request, req->direction);
|
||||
}
|
||||
|
||||
trace_dwc3_gadget_giveback(req);
|
||||
|
||||
|
@ -192,6 +201,10 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
|||
usb_gadget_giveback_request(&dep->endpoint, &req->request);
|
||||
spin_lock(&dwc->lock);
|
||||
|
||||
if (unmap_after_complete)
|
||||
usb_gadget_unmap_request_by_dev(dwc->sysdev,
|
||||
&req->request, req->direction);
|
||||
|
||||
if (dep->number > 1)
|
||||
pm_runtime_put(dwc->dev);
|
||||
}
|
||||
|
|
|
@ -535,13 +535,15 @@ static int acm_notify_serial_state(struct f_acm *acm)
|
|||
{
|
||||
struct usb_composite_dev *cdev = acm->port.func.config->cdev;
|
||||
int status;
|
||||
__le16 serial_state;
|
||||
|
||||
spin_lock(&acm->lock);
|
||||
if (acm->notify_req) {
|
||||
dev_dbg(&cdev->gadget->dev, "acm ttyGS%d serial state %04x\n",
|
||||
acm->port_num, acm->serial_state);
|
||||
serial_state = cpu_to_le16(acm->serial_state);
|
||||
status = acm_cdc_notify(acm, USB_CDC_NOTIFY_SERIAL_STATE,
|
||||
0, &acm->serial_state, sizeof(acm->serial_state));
|
||||
0, &serial_state, sizeof(acm->serial_state));
|
||||
} else {
|
||||
acm->pending = true;
|
||||
status = 0;
|
||||
|
|
|
@ -367,7 +367,7 @@ try_again:
|
|||
count = min_t(unsigned, count, hidg->report_length);
|
||||
|
||||
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
||||
status = copy_from_user(hidg->req->buf, buffer, count);
|
||||
status = copy_from_user(req->buf, buffer, count);
|
||||
|
||||
if (status != 0) {
|
||||
ERROR(hidg->func.config->cdev,
|
||||
|
@ -378,9 +378,9 @@ try_again:
|
|||
|
||||
spin_lock_irqsave(&hidg->write_spinlock, flags);
|
||||
|
||||
/* we our function has been disabled by host */
|
||||
/* when our function has been disabled by host */
|
||||
if (!hidg->req) {
|
||||
free_ep_req(hidg->in_ep, hidg->req);
|
||||
free_ep_req(hidg->in_ep, req);
|
||||
/*
|
||||
* TODO
|
||||
* Should we fail with error here?
|
||||
|
@ -394,7 +394,7 @@ try_again:
|
|||
req->complete = f_hidg_req_complete;
|
||||
req->context = hidg;
|
||||
|
||||
status = usb_ep_queue(hidg->in_ep, hidg->req, GFP_ATOMIC);
|
||||
status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC);
|
||||
if (status < 0) {
|
||||
ERROR(hidg->func.config->cdev,
|
||||
"usb_ep_queue error on int endpoint %zd\n", status);
|
||||
|
|
|
@ -594,6 +594,14 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
|
|||
opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U);
|
||||
opts->streaming_maxburst = min(opts->streaming_maxburst, 15U);
|
||||
|
||||
/* For SS, wMaxPacketSize has to be 1024 if bMaxBurst is not 0 */
|
||||
if (opts->streaming_maxburst &&
|
||||
(opts->streaming_maxpacket % 1024) != 0) {
|
||||
opts->streaming_maxpacket = roundup(opts->streaming_maxpacket, 1024);
|
||||
INFO(cdev, "overriding streaming_maxpacket to %d\n",
|
||||
opts->streaming_maxpacket);
|
||||
}
|
||||
|
||||
/* Fill in the FS/HS/SS Video Streaming specific descriptors from the
|
||||
* module parameters.
|
||||
*
|
||||
|
@ -625,7 +633,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
|
|||
uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst;
|
||||
uvc_ss_streaming_comp.wBytesPerInterval =
|
||||
cpu_to_le16(max_packet_size * max_packet_mult *
|
||||
opts->streaming_maxburst);
|
||||
(opts->streaming_maxburst + 1));
|
||||
|
||||
/* Allocate endpoints. */
|
||||
ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep);
|
||||
|
|
|
@ -1523,7 +1523,6 @@ static void pch_udc_free_dma_chain(struct pch_udc_dev *dev,
|
|||
td = phys_to_virt(addr);
|
||||
addr2 = (dma_addr_t)td->next;
|
||||
pci_pool_free(dev->data_requests, td, addr);
|
||||
td->next = 0x00;
|
||||
addr = addr2;
|
||||
}
|
||||
req->chain_len = 1;
|
||||
|
|
|
@ -347,6 +347,9 @@ static int idmouse_probe(struct usb_interface *interface,
|
|||
if (iface_desc->desc.bInterfaceClass != 0x0A)
|
||||
return -ENODEV;
|
||||
|
||||
if (iface_desc->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
/* allocate memory for our device state and initialize it */
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (dev == NULL)
|
||||
|
|
|
@ -366,6 +366,10 @@ static int lvs_rh_probe(struct usb_interface *intf,
|
|||
|
||||
hdev = interface_to_usbdev(intf);
|
||||
desc = intf->cur_altsetting;
|
||||
|
||||
if (desc->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
endpoint = &desc->endpoint[0].desc;
|
||||
|
||||
/* valid only for SS root hub */
|
||||
|
|
|
@ -709,6 +709,11 @@ static int uss720_probe(struct usb_interface *intf,
|
|||
|
||||
interface = intf->cur_altsetting;
|
||||
|
||||
if (interface->desc.bNumEndpoints < 3) {
|
||||
usb_put_dev(usbdev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate parport interface
|
||||
*/
|
||||
|
|
|
@ -2490,8 +2490,8 @@ static int musb_remove(struct platform_device *pdev)
|
|||
musb_host_cleanup(musb);
|
||||
musb_gadget_cleanup(musb);
|
||||
|
||||
spin_lock_irqsave(&musb->lock, flags);
|
||||
musb_platform_disable(musb);
|
||||
spin_lock_irqsave(&musb->lock, flags);
|
||||
musb_disable_interrupts(musb);
|
||||
musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
|
||||
spin_unlock_irqrestore(&musb->lock, flags);
|
||||
|
|
|
@ -238,8 +238,27 @@ static void cppi41_dma_callback(void *private_data,
|
|||
transferred < cppi41_channel->packet_sz)
|
||||
cppi41_channel->prog_len = 0;
|
||||
|
||||
if (cppi41_channel->is_tx)
|
||||
empty = musb_is_tx_fifo_empty(hw_ep);
|
||||
if (cppi41_channel->is_tx) {
|
||||
u8 type;
|
||||
|
||||
if (is_host_active(musb))
|
||||
type = hw_ep->out_qh->type;
|
||||
else
|
||||
type = hw_ep->ep_in.type;
|
||||
|
||||
if (type == USB_ENDPOINT_XFER_ISOC)
|
||||
/*
|
||||
* Don't use the early-TX-interrupt workaround below
|
||||
* for Isoch transfter. Since Isoch are periodic
|
||||
* transfer, by the time the next transfer is
|
||||
* scheduled, the current one should be done already.
|
||||
*
|
||||
* This avoids audio playback underrun issue.
|
||||
*/
|
||||
empty = true;
|
||||
else
|
||||
empty = musb_is_tx_fifo_empty(hw_ep);
|
||||
}
|
||||
|
||||
if (!cppi41_channel->is_tx || empty) {
|
||||
cppi41_trans_done(cppi41_channel);
|
||||
|
|
|
@ -933,7 +933,7 @@ static int dsps_probe(struct platform_device *pdev)
|
|||
if (usb_get_dr_mode(&pdev->dev) == USB_DR_MODE_PERIPHERAL) {
|
||||
ret = dsps_setup_optional_vbus_irq(pdev, glue);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, glue);
|
||||
|
@ -946,6 +946,8 @@ static int dsps_probe(struct platform_device *pdev)
|
|||
|
||||
err:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
err_iounmap:
|
||||
iounmap(glue->usbss_base);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -956,6 +958,7 @@ static int dsps_remove(struct platform_device *pdev)
|
|||
platform_device_unregister(glue->musb);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
iounmap(glue->usbss_base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -233,6 +233,14 @@ static void option_instat_callback(struct urb *urb);
|
|||
#define BANDRICH_PRODUCT_1012 0x1012
|
||||
|
||||
#define QUALCOMM_VENDOR_ID 0x05C6
|
||||
/* These Quectel products use Qualcomm's vendor ID */
|
||||
#define QUECTEL_PRODUCT_UC20 0x9003
|
||||
#define QUECTEL_PRODUCT_UC15 0x9090
|
||||
|
||||
#define QUECTEL_VENDOR_ID 0x2c7c
|
||||
/* These Quectel products use Quectel's vendor ID */
|
||||
#define QUECTEL_PRODUCT_EC21 0x0121
|
||||
#define QUECTEL_PRODUCT_EC25 0x0125
|
||||
|
||||
#define CMOTECH_VENDOR_ID 0x16d8
|
||||
#define CMOTECH_PRODUCT_6001 0x6001
|
||||
|
@ -1161,7 +1169,14 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ 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 */
|
||||
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9003), /* Quectel UC20 */
|
||||
/* 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 },
|
||||
/* Quectel products using Quectel vendor ID */
|
||||
{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC25),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
|
||||
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
|
||||
|
|
|
@ -169,6 +169,8 @@ static const struct usb_device_id id_table[] = {
|
|||
{DEVICE_SWI(0x413c, 0x81a9)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
|
||||
{DEVICE_SWI(0x413c, 0x81b1)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */
|
||||
{DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
|
||||
{DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */
|
||||
{DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */
|
||||
|
||||
/* Huawei devices */
|
||||
{DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */
|
||||
|
|
|
@ -39,6 +39,9 @@ int wa_create(struct wahc *wa, struct usb_interface *iface,
|
|||
int result;
|
||||
struct device *dev = &iface->dev;
|
||||
|
||||
if (iface->cur_altsetting->desc.bNumEndpoints < 3)
|
||||
return -ENODEV;
|
||||
|
||||
result = wa_rpipes_create(wa);
|
||||
if (result < 0)
|
||||
goto error_rpipes_create;
|
||||
|
|
|
@ -823,6 +823,9 @@ static int hwarc_probe(struct usb_interface *iface,
|
|||
struct hwarc *hwarc;
|
||||
struct device *dev = &iface->dev;
|
||||
|
||||
if (iface->cur_altsetting->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
result = -ENOMEM;
|
||||
uwb_rc = uwb_rc_alloc();
|
||||
if (uwb_rc == NULL) {
|
||||
|
|
|
@ -362,6 +362,9 @@ int i1480_usb_probe(struct usb_interface *iface, const struct usb_device_id *id)
|
|||
result);
|
||||
}
|
||||
|
||||
if (iface->cur_altsetting->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
result = -ENOMEM;
|
||||
i1480_usb = kzalloc(sizeof(*i1480_usb), GFP_KERNEL);
|
||||
if (i1480_usb == NULL) {
|
||||
|
|
|
@ -50,4 +50,10 @@
|
|||
/* device can't handle Link Power Management */
|
||||
#define USB_QUIRK_NO_LPM BIT(10)
|
||||
|
||||
/*
|
||||
* Device reports its bInterval as linear frames instead of the
|
||||
* USB 2.0 calculation.
|
||||
*/
|
||||
#define USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL BIT(11)
|
||||
|
||||
#endif /* __LINUX_USB_QUIRKS_H */
|
||||
|
|
Загрузка…
Ссылка в новой задаче