Commit 359334ca authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-5.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are number of small USB fixes for 5.3-rc5.

  Syzbot has been on a tear recently now that it has some good USB
  debugging hooks integrated, so there's a number of fixes in here found
  by those tools for some _very_ old bugs. Also a handful of gadget
  driver fixes for reported issues, some hopefully-final dma fixes for
  host controller drivers, and some new USB serial gadget driver ids.

  All of these have been in linux-next this week with no reported issues
  (the usb-serial ones were in linux-next in its own branch, but merged
  into mine on Friday)"

* tag 'usb-5.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: add a hcd_uses_dma helper
  usb: don't create dma pools for HCDs with a localmem_pool
  usb: chipidea: imx: fix EPROBE_DEFER support during driver probe
  usb: host: fotg2: restart hcd after port reset
  USB: CDC: fix sanity checks in CDC union parser
  usb: cdc-acm: make sure a refcount is taken early enough
  USB: serial: option: add the BroadMobi BM818 card
  USB: serial: option: Add Motorola modem UARTs
  USB: core: Fix races in character device registration and deregistraion
  usb: gadget: mass_storage: Fix races between fsg_disable and fsg_set_alt
  usb: gadget: composite: Clear "suspended" on reset/disconnect
  usb: gadget: udc: renesas_usb3: Fix sysfs interface of "role"
  USB: serial: option: add D-Link DWM-222 device ID
  USB: serial: option: Add support for ZTE MF871A
parents 8fde2832 6a5f43d1
...@@ -454,9 +454,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) ...@@ -454,9 +454,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
imx_disable_unprepare_clks(dev); imx_disable_unprepare_clks(dev);
disable_hsic_regulator: disable_hsic_regulator:
if (data->hsic_pad_regulator) if (data->hsic_pad_regulator)
ret = regulator_disable(data->hsic_pad_regulator); /* don't overwrite original ret (cf. EPROBE_DEFER) */
regulator_disable(data->hsic_pad_regulator);
if (pdata.flags & CI_HDRC_PMQOS) if (pdata.flags & CI_HDRC_PMQOS)
pm_qos_remove_request(&data->pm_qos_req); pm_qos_remove_request(&data->pm_qos_req);
data->ci_pdev = NULL;
return ret; return ret;
} }
...@@ -469,14 +471,17 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev) ...@@ -469,14 +471,17 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev); pm_runtime_put_noidle(&pdev->dev);
} }
if (data->ci_pdev)
ci_hdrc_remove_device(data->ci_pdev); ci_hdrc_remove_device(data->ci_pdev);
if (data->override_phy_control) if (data->override_phy_control)
usb_phy_shutdown(data->phy); usb_phy_shutdown(data->phy);
if (data->ci_pdev) {
imx_disable_unprepare_clks(&pdev->dev); imx_disable_unprepare_clks(&pdev->dev);
if (data->plat_data->flags & CI_HDRC_PMQOS) if (data->plat_data->flags & CI_HDRC_PMQOS)
pm_qos_remove_request(&data->pm_qos_req); pm_qos_remove_request(&data->pm_qos_req);
if (data->hsic_pad_regulator) if (data->hsic_pad_regulator)
regulator_disable(data->hsic_pad_regulator); regulator_disable(data->hsic_pad_regulator);
}
return 0; return 0;
} }
......
...@@ -1301,10 +1301,6 @@ static int acm_probe(struct usb_interface *intf, ...@@ -1301,10 +1301,6 @@ static int acm_probe(struct usb_interface *intf,
tty_port_init(&acm->port); tty_port_init(&acm->port);
acm->port.ops = &acm_port_ops; acm->port.ops = &acm_port_ops;
minor = acm_alloc_minor(acm);
if (minor < 0)
goto alloc_fail1;
ctrlsize = usb_endpoint_maxp(epctrl); ctrlsize = usb_endpoint_maxp(epctrl);
readsize = usb_endpoint_maxp(epread) * readsize = usb_endpoint_maxp(epread) *
(quirks == SINGLE_RX_URB ? 1 : 2); (quirks == SINGLE_RX_URB ? 1 : 2);
...@@ -1312,6 +1308,13 @@ static int acm_probe(struct usb_interface *intf, ...@@ -1312,6 +1308,13 @@ static int acm_probe(struct usb_interface *intf,
acm->writesize = usb_endpoint_maxp(epwrite) * 20; acm->writesize = usb_endpoint_maxp(epwrite) * 20;
acm->control = control_interface; acm->control = control_interface;
acm->data = data_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->minor = minor;
acm->dev = usb_dev; acm->dev = usb_dev;
if (h.usb_cdc_acm_descriptor) if (h.usb_cdc_acm_descriptor)
...@@ -1458,7 +1461,6 @@ static int acm_probe(struct usb_interface *intf, ...@@ -1458,7 +1461,6 @@ static int acm_probe(struct usb_interface *intf,
usb_driver_claim_interface(&acm_driver, data_interface, acm); usb_driver_claim_interface(&acm_driver, data_interface, acm);
usb_set_intfdata(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, tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor,
&control_interface->dev); &control_interface->dev);
if (IS_ERR(tty_dev)) { if (IS_ERR(tty_dev)) {
......
...@@ -66,9 +66,7 @@ int hcd_buffer_create(struct usb_hcd *hcd) ...@@ -66,9 +66,7 @@ int hcd_buffer_create(struct usb_hcd *hcd)
char name[16]; char name[16];
int i, size; int i, size;
if (!IS_ENABLED(CONFIG_HAS_DMA) || if (hcd->localmem_pool || !hcd_uses_dma(hcd))
(!is_device_dma_capable(hcd->self.sysdev) &&
!hcd->localmem_pool))
return 0; return 0;
for (i = 0; i < HCD_BUFFER_POOLS; i++) { for (i = 0; i < HCD_BUFFER_POOLS; i++) {
...@@ -129,8 +127,7 @@ void *hcd_buffer_alloc( ...@@ -129,8 +127,7 @@ void *hcd_buffer_alloc(
return gen_pool_dma_alloc(hcd->localmem_pool, size, dma); return gen_pool_dma_alloc(hcd->localmem_pool, size, dma);
/* some USB hosts just use PIO */ /* some USB hosts just use PIO */
if (!IS_ENABLED(CONFIG_HAS_DMA) || if (!hcd_uses_dma(hcd)) {
!is_device_dma_capable(bus->sysdev)) {
*dma = ~(dma_addr_t) 0; *dma = ~(dma_addr_t) 0;
return kmalloc(size, mem_flags); return kmalloc(size, mem_flags);
} }
...@@ -160,8 +157,7 @@ void hcd_buffer_free( ...@@ -160,8 +157,7 @@ void hcd_buffer_free(
return; return;
} }
if (!IS_ENABLED(CONFIG_HAS_DMA) || if (!hcd_uses_dma(hcd)) {
!is_device_dma_capable(bus->sysdev)) {
kfree(addr); kfree(addr);
return; return;
} }
......
...@@ -193,9 +193,10 @@ int usb_register_dev(struct usb_interface *intf, ...@@ -193,9 +193,10 @@ int usb_register_dev(struct usb_interface *intf,
intf->minor = minor; intf->minor = minor;
break; break;
} }
if (intf->minor < 0) {
up_write(&minor_rwsem); up_write(&minor_rwsem);
if (intf->minor < 0)
return -EXFULL; return -EXFULL;
}
/* create a usb class device for this usb interface */ /* create a usb class device for this usb interface */
snprintf(name, sizeof(name), class_driver->name, minor - minor_base); snprintf(name, sizeof(name), class_driver->name, minor - minor_base);
...@@ -203,12 +204,11 @@ int usb_register_dev(struct usb_interface *intf, ...@@ -203,12 +204,11 @@ int usb_register_dev(struct usb_interface *intf,
MKDEV(USB_MAJOR, minor), class_driver, MKDEV(USB_MAJOR, minor), class_driver,
"%s", kbasename(name)); "%s", kbasename(name));
if (IS_ERR(intf->usb_dev)) { if (IS_ERR(intf->usb_dev)) {
down_write(&minor_rwsem);
usb_minors[minor] = NULL; usb_minors[minor] = NULL;
intf->minor = -1; intf->minor = -1;
up_write(&minor_rwsem);
retval = PTR_ERR(intf->usb_dev); retval = PTR_ERR(intf->usb_dev);
} }
up_write(&minor_rwsem);
return retval; return retval;
} }
EXPORT_SYMBOL_GPL(usb_register_dev); EXPORT_SYMBOL_GPL(usb_register_dev);
...@@ -234,12 +234,12 @@ void usb_deregister_dev(struct usb_interface *intf, ...@@ -234,12 +234,12 @@ void usb_deregister_dev(struct usb_interface *intf,
return; return;
dev_dbg(&intf->dev, "removing %d minor\n", intf->minor); dev_dbg(&intf->dev, "removing %d minor\n", intf->minor);
device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
down_write(&minor_rwsem); down_write(&minor_rwsem);
usb_minors[intf->minor] = NULL; usb_minors[intf->minor] = NULL;
up_write(&minor_rwsem); up_write(&minor_rwsem);
device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
intf->usb_dev = NULL; intf->usb_dev = NULL;
intf->minor = -1; intf->minor = -1;
destroy_usb_class(); destroy_usb_class();
......
...@@ -1412,7 +1412,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, ...@@ -1412,7 +1412,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
if (usb_endpoint_xfer_control(&urb->ep->desc)) { if (usb_endpoint_xfer_control(&urb->ep->desc)) {
if (hcd->self.uses_pio_for_control) if (hcd->self.uses_pio_for_control)
return ret; return ret;
if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) { if (hcd_uses_dma(hcd)) {
if (is_vmalloc_addr(urb->setup_packet)) { if (is_vmalloc_addr(urb->setup_packet)) {
WARN_ONCE(1, "setup packet is not dma capable\n"); WARN_ONCE(1, "setup packet is not dma capable\n");
return -EAGAIN; return -EAGAIN;
...@@ -1446,7 +1446,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, ...@@ -1446,7 +1446,7 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
if (urb->transfer_buffer_length != 0 if (urb->transfer_buffer_length != 0
&& !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) { if (hcd_uses_dma(hcd)) {
if (urb->num_sgs) { if (urb->num_sgs) {
int n; int n;
......
...@@ -2218,14 +2218,14 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, ...@@ -2218,14 +2218,14 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr,
(struct usb_cdc_dmm_desc *)buffer; (struct usb_cdc_dmm_desc *)buffer;
break; break;
case USB_CDC_MDLM_TYPE: case USB_CDC_MDLM_TYPE:
if (elength < sizeof(struct usb_cdc_mdlm_desc *)) if (elength < sizeof(struct usb_cdc_mdlm_desc))
goto next_desc; goto next_desc;
if (desc) if (desc)
return -EINVAL; return -EINVAL;
desc = (struct usb_cdc_mdlm_desc *)buffer; desc = (struct usb_cdc_mdlm_desc *)buffer;
break; break;
case USB_CDC_MDLM_DETAIL_TYPE: 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; goto next_desc;
if (detail) if (detail)
return -EINVAL; return -EINVAL;
......
...@@ -4608,7 +4608,7 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, ...@@ -4608,7 +4608,7 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
buf = urb->transfer_buffer; buf = urb->transfer_buffer;
if (hcd->self.uses_dma) { if (hcd_uses_dma(hcd)) {
if (!buf && (urb->transfer_dma & 3)) { if (!buf && (urb->transfer_dma & 3)) {
dev_err(hsotg->dev, dev_err(hsotg->dev,
"%s: unaligned transfer with no transfer_buffer", "%s: unaligned transfer with no transfer_buffer",
......
...@@ -1976,6 +1976,7 @@ void composite_disconnect(struct usb_gadget *gadget) ...@@ -1976,6 +1976,7 @@ void composite_disconnect(struct usb_gadget *gadget)
* disconnect callbacks? * disconnect callbacks?
*/ */
spin_lock_irqsave(&cdev->lock, flags); spin_lock_irqsave(&cdev->lock, flags);
cdev->suspended = 0;
if (cdev->config) if (cdev->config)
reset_config(cdev); reset_config(cdev);
if (cdev->driver->disconnect) if (cdev->driver->disconnect)
......
...@@ -261,7 +261,7 @@ struct fsg_common; ...@@ -261,7 +261,7 @@ struct fsg_common;
struct fsg_common { struct fsg_common {
struct usb_gadget *gadget; struct usb_gadget *gadget;
struct usb_composite_dev *cdev; struct usb_composite_dev *cdev;
struct fsg_dev *fsg, *new_fsg; struct fsg_dev *fsg;
wait_queue_head_t io_wait; wait_queue_head_t io_wait;
wait_queue_head_t fsg_wait; wait_queue_head_t fsg_wait;
...@@ -290,6 +290,7 @@ struct fsg_common { ...@@ -290,6 +290,7 @@ struct fsg_common {
unsigned int bulk_out_maxpacket; unsigned int bulk_out_maxpacket;
enum fsg_state state; /* For exception handling */ enum fsg_state state; /* For exception handling */
unsigned int exception_req_tag; unsigned int exception_req_tag;
void *exception_arg;
enum data_direction data_dir; enum data_direction data_dir;
u32 data_size; u32 data_size;
...@@ -391,7 +392,8 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) ...@@ -391,7 +392,8 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
/* These routines may be called in process context or in_irq */ /* These routines may be called in process context or in_irq */
static void raise_exception(struct fsg_common *common, enum fsg_state new_state) static void __raise_exception(struct fsg_common *common, enum fsg_state new_state,
void *arg)
{ {
unsigned long flags; unsigned long flags;
...@@ -404,6 +406,7 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state) ...@@ -404,6 +406,7 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
if (common->state <= new_state) { if (common->state <= new_state) {
common->exception_req_tag = common->ep0_req_tag; common->exception_req_tag = common->ep0_req_tag;
common->state = new_state; common->state = new_state;
common->exception_arg = arg;
if (common->thread_task) if (common->thread_task)
send_sig_info(SIGUSR1, SEND_SIG_PRIV, send_sig_info(SIGUSR1, SEND_SIG_PRIV,
common->thread_task); common->thread_task);
...@@ -411,6 +414,10 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state) ...@@ -411,6 +414,10 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
spin_unlock_irqrestore(&common->lock, flags); spin_unlock_irqrestore(&common->lock, flags);
} }
static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
{
__raise_exception(common, new_state, NULL);
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -2285,16 +2292,16 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg) ...@@ -2285,16 +2292,16 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg)
static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
{ {
struct fsg_dev *fsg = fsg_from_func(f); struct fsg_dev *fsg = fsg_from_func(f);
fsg->common->new_fsg = fsg;
raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, fsg);
return USB_GADGET_DELAYED_STATUS; return USB_GADGET_DELAYED_STATUS;
} }
static void fsg_disable(struct usb_function *f) static void fsg_disable(struct usb_function *f)
{ {
struct fsg_dev *fsg = fsg_from_func(f); struct fsg_dev *fsg = fsg_from_func(f);
fsg->common->new_fsg = NULL;
raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL);
} }
...@@ -2307,6 +2314,7 @@ static void handle_exception(struct fsg_common *common) ...@@ -2307,6 +2314,7 @@ static void handle_exception(struct fsg_common *common)
enum fsg_state old_state; enum fsg_state old_state;
struct fsg_lun *curlun; struct fsg_lun *curlun;
unsigned int exception_req_tag; unsigned int exception_req_tag;
struct fsg_dev *new_fsg;
/* /*
* Clear the existing signals. Anything but SIGUSR1 is converted * Clear the existing signals. Anything but SIGUSR1 is converted
...@@ -2360,6 +2368,7 @@ static void handle_exception(struct fsg_common *common) ...@@ -2360,6 +2368,7 @@ static void handle_exception(struct fsg_common *common)
common->next_buffhd_to_fill = &common->buffhds[0]; common->next_buffhd_to_fill = &common->buffhds[0];
common->next_buffhd_to_drain = &common->buffhds[0]; common->next_buffhd_to_drain = &common->buffhds[0];
exception_req_tag = common->exception_req_tag; exception_req_tag = common->exception_req_tag;
new_fsg = common->exception_arg;
old_state = common->state; old_state = common->state;
common->state = FSG_STATE_NORMAL; common->state = FSG_STATE_NORMAL;
...@@ -2413,8 +2422,8 @@ static void handle_exception(struct fsg_common *common) ...@@ -2413,8 +2422,8 @@ static void handle_exception(struct fsg_common *common)
break; break;
case FSG_STATE_CONFIG_CHANGE: case FSG_STATE_CONFIG_CHANGE:
do_set_interface(common, common->new_fsg); do_set_interface(common, new_fsg);
if (common->new_fsg) if (new_fsg)
usb_composite_setup_continue(common->cdev); usb_composite_setup_continue(common->cdev);
break; break;
...@@ -2989,8 +2998,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) ...@@ -2989,8 +2998,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
DBG(fsg, "unbind\n"); DBG(fsg, "unbind\n");
if (fsg->common->fsg == fsg) { if (fsg->common->fsg == fsg) {
fsg->common->new_fsg = NULL; __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL);
raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
/* FIXME: make interruptible or killable somehow? */ /* FIXME: make interruptible or killable somehow? */
wait_event(common->fsg_wait, common->fsg != fsg); wait_event(common->fsg_wait, common->fsg != fsg);
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/sizes.h> #include <linux/sizes.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h>
#include <linux/sys_soc.h> #include <linux/sys_soc.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/usb/ch9.h> #include <linux/usb/ch9.h>
...@@ -2450,9 +2451,9 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr, ...@@ -2450,9 +2451,9 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
if (usb3->forced_b_device) if (usb3->forced_b_device)
return -EBUSY; return -EBUSY;
if (!strncmp(buf, "host", strlen("host"))) if (sysfs_streq(buf, "host"))
new_mode_is_host = true; new_mode_is_host = true;
else if (!strncmp(buf, "peripheral", strlen("peripheral"))) else if (sysfs_streq(buf, "peripheral"))
new_mode_is_host = false; new_mode_is_host = false;
else else
return -EINVAL; return -EINVAL;
......
...@@ -1629,6 +1629,10 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -1629,6 +1629,10 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
/* see what we found out */ /* see what we found out */
temp = check_reset_complete(fotg210, wIndex, status_reg, temp = check_reset_complete(fotg210, wIndex, status_reg,
fotg210_readl(fotg210, status_reg)); fotg210_readl(fotg210, status_reg));
/* restart schedule */
fotg210->command |= CMD_RUN;
fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
} }
if (!(temp & (PORT_RESUME|PORT_RESET))) { if (!(temp & (PORT_RESUME|PORT_RESET))) {
......
...@@ -968,6 +968,11 @@ static const struct usb_device_id option_ids[] = { ...@@ -968,6 +968,11 @@ static const struct usb_device_id option_ids[] = {
{ USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7B) }, { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7B) },
{ USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7C) }, { 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_V640) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) },
...@@ -1549,6 +1554,7 @@ static const struct usb_device_id option_ids[] = { ...@@ -1549,6 +1554,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G v2 */ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G v2 */
.driver_info = RSVD(2) }, .driver_info = RSVD(2) },
{ USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x1476, 0xff) }, /* GosunCn ZTE WeLink ME3630 (ECM/NCM mode) */ { 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, 0x1533, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 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) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) },
...@@ -1952,11 +1958,15 @@ static const struct usb_device_id option_ids[] = { ...@@ -1952,11 +1958,15 @@ static const struct usb_device_id option_ids[] = {
.driver_info = RSVD(4) }, .driver_info = RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */
.driver_info = RSVD(4) }, .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, 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, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */
{ USB_DEVICE_INTERFACE_CLASS(0x2020, 0x2031, 0xff), /* Olicard 600 */ { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x2031, 0xff), /* Olicard 600 */
.driver_info = RSVD(4) }, .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_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */
{ USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) },
{ USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) }, { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) },
......
...@@ -1457,7 +1457,7 @@ typedef void (*usb_complete_t)(struct urb *); ...@@ -1457,7 +1457,7 @@ typedef void (*usb_complete_t)(struct urb *);
* field rather than determining a dma address themselves. * field rather than determining a dma address themselves.
* *
* Note that transfer_buffer must still be set if the controller * Note that transfer_buffer must still be set if the controller
* does not support DMA (as indicated by bus.uses_dma) and when talking * does not support DMA (as indicated by hcd_uses_dma()) and when talking
* to root hub. If you have to trasfer between highmem zone and the device * to root hub. If you have to trasfer between highmem zone and the device
* on such controller, create a bounce buffer or bail out with an error. * on such controller, create a bounce buffer or bail out with an error.
* If transfer_buffer cannot be set (is in highmem) and the controller is DMA * If transfer_buffer cannot be set (is in highmem) and the controller is DMA
......
...@@ -422,6 +422,9 @@ static inline bool hcd_periodic_completion_in_progress(struct usb_hcd *hcd, ...@@ -422,6 +422,9 @@ static inline bool hcd_periodic_completion_in_progress(struct usb_hcd *hcd,
return hcd->high_prio_bh.completing_ep == ep; return hcd->high_prio_bh.completing_ep == ep;
} }
#define hcd_uses_dma(hcd) \
(IS_ENABLED(CONFIG_HAS_DMA) && (hcd)->self.uses_dma)
extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,
int status); int status);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment