Commit f5226f1d authored by Linus Torvalds's avatar Linus Torvalds

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

Pull USB fixes from Greg KH:
 "Here are some small USB fixes for 5.10-rc7 that resolve a number of
  reported issues, and add some new device ids.

  Nothing major here, but these solve some problems that people were
  having with the 5.10-rc tree:

   - reverts for USB storage dma settings that broke working devices

   - thunderbolt use-after-free fix

   - cdns3 driver fixes

   - gadget driver userspace copy fix

   - new device ids

  All of these except for the reverts have been in linux-next with no
  reported issues. The reverts are "clean" and were tested by Hans, as
  well as passing the 0-day tests"

* tag 'usb-5.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: gadget: f_fs: Use local copy of descriptors for userspace copy
  usb: ohci-omap: Fix descriptor conversion
  Revert "usb-storage: fix sdev->host->dma_dev"
  Revert "uas: fix sdev->host->dma_dev"
  Revert "uas: bump hw_max_sectors to 2048 blocks for SS or faster drives"
  USB: serial: kl5kusb105: fix memleak on open
  USB: serial: ch341: sort device-id entries
  USB: serial: ch341: add new Product ID for CH341A
  USB: serial: option: fix Quectel BG96 matching
  usb: cdns3: core: fix goto label for error path
  usb: cdns3: gadget: clear trb->length as zero after preparing every trb
  usb: cdns3: Fix hardware based role switch
  USB: serial: option: add support for Thales Cinterion EXS82
  USB: serial: option: add Fibocom NL668 variants
  thunderbolt: Fix use-after-free in remove_unplugged_switch()
parents 8100a580 a4b98a75
...@@ -288,7 +288,7 @@ static struct gpiod_lookup_table osk_usb_gpio_table = { ...@@ -288,7 +288,7 @@ static struct gpiod_lookup_table osk_usb_gpio_table = {
.dev_id = "ohci", .dev_id = "ohci",
.table = { .table = {
/* Power GPIO on the I2C-attached TPS65010 */ /* Power GPIO on the I2C-attached TPS65010 */
GPIO_LOOKUP("i2c-tps65010", 1, "power", GPIO_ACTIVE_HIGH), GPIO_LOOKUP("tps65010", 0, "power", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP(OMAP_GPIO_LABEL, 9, "overcurrent", GPIO_LOOKUP(OMAP_GPIO_LABEL, 9, "overcurrent",
GPIO_ACTIVE_HIGH), GPIO_ACTIVE_HIGH),
}, },
......
...@@ -1976,7 +1976,9 @@ static int complete_rpm(struct device *dev, void *data) ...@@ -1976,7 +1976,9 @@ static int complete_rpm(struct device *dev, void *data)
static void remove_unplugged_switch(struct tb_switch *sw) static void remove_unplugged_switch(struct tb_switch *sw)
{ {
pm_runtime_get_sync(sw->dev.parent); struct device *parent = get_device(sw->dev.parent);
pm_runtime_get_sync(parent);
/* /*
* Signal this and switches below for rpm_complete because * Signal this and switches below for rpm_complete because
...@@ -1987,8 +1989,10 @@ static void remove_unplugged_switch(struct tb_switch *sw) ...@@ -1987,8 +1989,10 @@ static void remove_unplugged_switch(struct tb_switch *sw)
bus_for_each_dev(&tb_bus_type, &sw->dev, NULL, complete_rpm); bus_for_each_dev(&tb_bus_type, &sw->dev, NULL, complete_rpm);
tb_switch_remove(sw); tb_switch_remove(sw);
pm_runtime_mark_last_busy(sw->dev.parent); pm_runtime_mark_last_busy(parent);
pm_runtime_put_autosuspend(sw->dev.parent); pm_runtime_put_autosuspend(parent);
put_device(parent);
} }
static void icm_free_unplugged_children(struct tb_switch *sw) static void icm_free_unplugged_children(struct tb_switch *sw)
......
...@@ -427,7 +427,6 @@ static irqreturn_t cdns3_wakeup_irq(int irq, void *data) ...@@ -427,7 +427,6 @@ static irqreturn_t cdns3_wakeup_irq(int irq, void *data)
*/ */
static int cdns3_probe(struct platform_device *pdev) static int cdns3_probe(struct platform_device *pdev)
{ {
struct usb_role_switch_desc sw_desc = { };
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct resource *res; struct resource *res;
struct cdns3 *cdns; struct cdns3 *cdns;
...@@ -529,18 +528,21 @@ static int cdns3_probe(struct platform_device *pdev) ...@@ -529,18 +528,21 @@ static int cdns3_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err2; goto err2;
sw_desc.set = cdns3_role_set; if (device_property_read_bool(dev, "usb-role-switch")) {
sw_desc.get = cdns3_role_get; struct usb_role_switch_desc sw_desc = { };
sw_desc.allow_userspace_control = true;
sw_desc.driver_data = cdns; sw_desc.set = cdns3_role_set;
if (device_property_read_bool(dev, "usb-role-switch")) sw_desc.get = cdns3_role_get;
sw_desc.allow_userspace_control = true;
sw_desc.driver_data = cdns;
sw_desc.fwnode = dev->fwnode; sw_desc.fwnode = dev->fwnode;
cdns->role_sw = usb_role_switch_register(dev, &sw_desc); cdns->role_sw = usb_role_switch_register(dev, &sw_desc);
if (IS_ERR(cdns->role_sw)) { if (IS_ERR(cdns->role_sw)) {
ret = PTR_ERR(cdns->role_sw); ret = PTR_ERR(cdns->role_sw);
dev_warn(dev, "Unable to register Role Switch\n"); dev_warn(dev, "Unable to register Role Switch\n");
goto err3; goto err3;
}
} }
if (cdns->wakeup_irq) { if (cdns->wakeup_irq) {
...@@ -551,7 +553,7 @@ static int cdns3_probe(struct platform_device *pdev) ...@@ -551,7 +553,7 @@ static int cdns3_probe(struct platform_device *pdev)
if (ret) { if (ret) {
dev_err(cdns->dev, "couldn't register wakeup irq handler\n"); dev_err(cdns->dev, "couldn't register wakeup irq handler\n");
goto err3; goto err4;
} }
} }
...@@ -582,7 +584,8 @@ static int cdns3_probe(struct platform_device *pdev) ...@@ -582,7 +584,8 @@ static int cdns3_probe(struct platform_device *pdev)
return 0; return 0;
err4: err4:
cdns3_drd_exit(cdns); cdns3_drd_exit(cdns);
usb_role_switch_unregister(cdns->role_sw); if (cdns->role_sw)
usb_role_switch_unregister(cdns->role_sw);
err3: err3:
set_phy_power_off(cdns); set_phy_power_off(cdns);
err2: err2:
......
...@@ -1260,6 +1260,7 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, ...@@ -1260,6 +1260,7 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
priv_req->end_trb = priv_ep->enqueue; priv_req->end_trb = priv_ep->enqueue;
cdns3_ep_inc_enq(priv_ep); cdns3_ep_inc_enq(priv_ep);
trb = priv_ep->trb_pool + priv_ep->enqueue; trb = priv_ep->trb_pool + priv_ep->enqueue;
trb->length = 0;
} while (sg_iter < num_trb); } while (sg_iter < num_trb);
trb = priv_req->trb; trb = priv_req->trb;
......
...@@ -1324,7 +1324,7 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, ...@@ -1324,7 +1324,7 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
case FUNCTIONFS_ENDPOINT_DESC: case FUNCTIONFS_ENDPOINT_DESC:
{ {
int desc_idx; int desc_idx;
struct usb_endpoint_descriptor *desc; struct usb_endpoint_descriptor desc1, *desc;
switch (epfile->ffs->gadget->speed) { switch (epfile->ffs->gadget->speed) {
case USB_SPEED_SUPER: case USB_SPEED_SUPER:
...@@ -1336,10 +1336,12 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, ...@@ -1336,10 +1336,12 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
default: default:
desc_idx = 0; desc_idx = 0;
} }
desc = epfile->ep->descs[desc_idx]; desc = epfile->ep->descs[desc_idx];
memcpy(&desc1, desc, desc->bLength);
spin_unlock_irq(&epfile->ffs->eps_lock); spin_unlock_irq(&epfile->ffs->eps_lock);
ret = copy_to_user((void __user *)value, desc, desc->bLength); ret = copy_to_user((void __user *)value, &desc1, desc1.bLength);
if (ret) if (ret)
ret = -EFAULT; ret = -EFAULT;
return ret; return ret;
......
...@@ -91,14 +91,14 @@ static int omap_ohci_transceiver_power(struct ohci_omap_priv *priv, int on) ...@@ -91,14 +91,14 @@ static int omap_ohci_transceiver_power(struct ohci_omap_priv *priv, int on)
| ((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), | ((1 << 5/*usb1*/) | (1 << 3/*usb2*/)),
INNOVATOR_FPGA_CAM_USB_CONTROL); INNOVATOR_FPGA_CAM_USB_CONTROL);
else if (priv->power) else if (priv->power)
gpiod_set_value(priv->power, 0); gpiod_set_value_cansleep(priv->power, 0);
} else { } else {
if (machine_is_omap_innovator() && cpu_is_omap1510()) if (machine_is_omap_innovator() && cpu_is_omap1510())
__raw_writeb(__raw_readb(INNOVATOR_FPGA_CAM_USB_CONTROL) __raw_writeb(__raw_readb(INNOVATOR_FPGA_CAM_USB_CONTROL)
& ~((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), & ~((1 << 5/*usb1*/) | (1 << 3/*usb2*/)),
INNOVATOR_FPGA_CAM_USB_CONTROL); INNOVATOR_FPGA_CAM_USB_CONTROL);
else if (priv->power) else if (priv->power)
gpiod_set_value(priv->power, 1); gpiod_set_value_cansleep(priv->power, 1);
} }
return 0; return 0;
......
...@@ -81,10 +81,11 @@ ...@@ -81,10 +81,11 @@
#define CH341_QUIRK_SIMULATE_BREAK BIT(1) #define CH341_QUIRK_SIMULATE_BREAK BIT(1)
static const struct usb_device_id id_table[] = { static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x4348, 0x5523) }, { USB_DEVICE(0x1a86, 0x5512) },
{ USB_DEVICE(0x1a86, 0x5523) },
{ USB_DEVICE(0x1a86, 0x7522) }, { USB_DEVICE(0x1a86, 0x7522) },
{ USB_DEVICE(0x1a86, 0x7523) }, { USB_DEVICE(0x1a86, 0x7523) },
{ USB_DEVICE(0x1a86, 0x5523) }, { USB_DEVICE(0x4348, 0x5523) },
{ }, { },
}; };
MODULE_DEVICE_TABLE(usb, id_table); MODULE_DEVICE_TABLE(usb, id_table);
......
...@@ -276,12 +276,12 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -276,12 +276,12 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
priv->cfg.unknown2 = cfg->unknown2; priv->cfg.unknown2 = cfg->unknown2;
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
kfree(cfg);
/* READ_ON and urb submission */ /* READ_ON and urb submission */
rc = usb_serial_generic_open(tty, port); rc = usb_serial_generic_open(tty, port);
if (rc) { if (rc)
retval = rc; return rc;
goto err_free_cfg;
}
rc = usb_control_msg(port->serial->dev, rc = usb_control_msg(port->serial->dev,
usb_sndctrlpipe(port->serial->dev, 0), usb_sndctrlpipe(port->serial->dev, 0),
...@@ -324,8 +324,6 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -324,8 +324,6 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
KLSI_TIMEOUT); KLSI_TIMEOUT);
err_generic_close: err_generic_close:
usb_serial_generic_close(port); usb_serial_generic_close(port);
err_free_cfg:
kfree(cfg);
return retval; return retval;
} }
......
...@@ -419,6 +419,7 @@ static void option_instat_callback(struct urb *urb); ...@@ -419,6 +419,7 @@ static void option_instat_callback(struct urb *urb);
#define CINTERION_PRODUCT_PH8 0x0053 #define CINTERION_PRODUCT_PH8 0x0053
#define CINTERION_PRODUCT_AHXX 0x0055 #define CINTERION_PRODUCT_AHXX 0x0055
#define CINTERION_PRODUCT_PLXX 0x0060 #define CINTERION_PRODUCT_PLXX 0x0060
#define CINTERION_PRODUCT_EXS82 0x006c
#define CINTERION_PRODUCT_PH8_2RMNET 0x0082 #define CINTERION_PRODUCT_PH8_2RMNET 0x0082
#define CINTERION_PRODUCT_PH8_AUDIO 0x0083 #define CINTERION_PRODUCT_PH8_AUDIO 0x0083
#define CINTERION_PRODUCT_AHXX_2RMNET 0x0084 #define CINTERION_PRODUCT_AHXX_2RMNET 0x0084
...@@ -1105,9 +1106,8 @@ static const struct usb_device_id option_ids[] = { ...@@ -1105,9 +1106,8 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0xff, 0xff), { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0xff, 0xff),
.driver_info = NUMEP2 }, .driver_info = NUMEP2 },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96, 0xff, 0xff, 0xff), { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
.driver_info = NUMEP2 }, .driver_info = RSVD(4) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff), { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff),
.driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) },
...@@ -1902,6 +1902,7 @@ static const struct usb_device_id option_ids[] = { ...@@ -1902,6 +1902,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) }, { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) },
{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_CLS8, 0xff), { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_CLS8, 0xff),
.driver_info = RSVD(0) | RSVD(4) }, .driver_info = RSVD(0) | RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EXS82, 0xff) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) },
{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
...@@ -2046,12 +2047,13 @@ static const struct usb_device_id option_ids[] = { ...@@ -2046,12 +2047,13 @@ static const struct usb_device_id option_ids[] = {
.driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, .driver_info = RSVD(0) | RSVD(1) | RSVD(6) },
{ USB_DEVICE(0x0489, 0xe0b5), /* Foxconn T77W968 ESIM */ { USB_DEVICE(0x0489, 0xe0b5), /* Foxconn T77W968 ESIM */
.driver_info = RSVD(0) | RSVD(1) | RSVD(6) }, .driver_info = RSVD(0) | RSVD(1) | RSVD(6) },
{ USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 */ { USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */
.driver_info = RSVD(4) | RSVD(5) | RSVD(6) }, .driver_info = RSVD(4) | RSVD(5) | RSVD(6) },
{ USB_DEVICE(0x2cb7, 0x0104), /* Fibocom NL678 series */ { USB_DEVICE(0x2cb7, 0x0104), /* Fibocom NL678 series */
.driver_info = RSVD(4) | RSVD(5) }, .driver_info = RSVD(4) | RSVD(5) },
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */
.driver_info = RSVD(6) }, .driver_info = RSVD(6) },
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */
......
...@@ -92,7 +92,7 @@ static int slave_alloc (struct scsi_device *sdev) ...@@ -92,7 +92,7 @@ static int slave_alloc (struct scsi_device *sdev)
static int slave_configure(struct scsi_device *sdev) static int slave_configure(struct scsi_device *sdev)
{ {
struct us_data *us = host_to_us(sdev->host); struct us_data *us = host_to_us(sdev->host);
struct device *dev = sdev->host->dma_dev; struct device *dev = us->pusb_dev->bus->sysdev;
/* /*
* Many devices have trouble transferring more than 32KB at a time, * Many devices have trouble transferring more than 32KB at a time,
......
...@@ -837,24 +837,17 @@ static int uas_slave_alloc(struct scsi_device *sdev) ...@@ -837,24 +837,17 @@ static int uas_slave_alloc(struct scsi_device *sdev)
*/ */
blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1)); blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1));
if (devinfo->flags & US_FL_MAX_SECTORS_64)
blk_queue_max_hw_sectors(sdev->request_queue, 64);
else if (devinfo->flags & US_FL_MAX_SECTORS_240)
blk_queue_max_hw_sectors(sdev->request_queue, 240);
return 0; return 0;
} }
static int uas_slave_configure(struct scsi_device *sdev) static int uas_slave_configure(struct scsi_device *sdev)
{ {
struct uas_dev_info *devinfo = sdev->hostdata; struct uas_dev_info *devinfo = sdev->hostdata;
struct device *dev = sdev->host->dma_dev;
if (devinfo->flags & US_FL_MAX_SECTORS_64)
blk_queue_max_hw_sectors(sdev->request_queue, 64);
else if (devinfo->flags & US_FL_MAX_SECTORS_240)
blk_queue_max_hw_sectors(sdev->request_queue, 240);
else if (devinfo->udev->speed >= USB_SPEED_SUPER)
blk_queue_max_hw_sectors(sdev->request_queue, 2048);
blk_queue_max_hw_sectors(sdev->request_queue,
min_t(size_t, queue_max_hw_sectors(sdev->request_queue),
dma_max_mapping_size(dev) >> SECTOR_SHIFT));
if (devinfo->flags & US_FL_NO_REPORT_OPCODES) if (devinfo->flags & US_FL_NO_REPORT_OPCODES)
sdev->no_report_opcodes = 1; sdev->no_report_opcodes = 1;
...@@ -1040,7 +1033,7 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -1040,7 +1033,7 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
shost->can_queue = devinfo->qdepth - 2; shost->can_queue = devinfo->qdepth - 2;
usb_set_intfdata(intf, shost); usb_set_intfdata(intf, shost);
result = scsi_add_host_with_dma(shost, &intf->dev, udev->bus->sysdev); result = scsi_add_host(shost, &intf->dev);
if (result) if (result)
goto free_streams; goto free_streams;
......
...@@ -1049,9 +1049,8 @@ int usb_stor_probe2(struct us_data *us) ...@@ -1049,9 +1049,8 @@ int usb_stor_probe2(struct us_data *us)
goto BadDevice; goto BadDevice;
usb_autopm_get_interface_no_resume(us->pusb_intf); usb_autopm_get_interface_no_resume(us->pusb_intf);
snprintf(us->scsi_name, sizeof(us->scsi_name), "usb-storage %s", snprintf(us->scsi_name, sizeof(us->scsi_name), "usb-storage %s",
dev_name(dev)); dev_name(&us->pusb_intf->dev));
result = scsi_add_host_with_dma(us_to_host(us), dev, result = scsi_add_host(us_to_host(us), dev);
us->pusb_dev->bus->sysdev);
if (result) { if (result) {
dev_warn(dev, dev_warn(dev,
"Unable to add the scsi host\n"); "Unable to add the scsi host\n");
......
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