diff options
| author | Greg Kroah-Hartman <gregkh@google.com> | 2020-09-23 10:39:26 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@google.com> | 2020-09-23 10:39:26 +0200 |
| commit | 78515aabd6418c4a8d60ddd56c6905fbc2be0b5a (patch) | |
| tree | 0b6e352182d21a9bc3369958e8083514a4a71a16 /drivers/usb | |
| parent | 5fd2d19eeb9767339e1338eb6789495d1812065b (diff) | |
| parent | 38779362ed7ce5c24c9ac88c45afaf93116fc459 (diff) | |
Merge 4.4.237 into android-4.4-p
Changes in 4.4.237
ARM: dts: socfpga: fix register entry for timer3 on Arria10
scsi: libsas: Set data_dir as DMA_NONE if libata marks qc as NODATA
drivers/net/wan/lapbether: Added needed_tailroom
firestream: Fix memleak in fs_open
drivers/net/wan/lapbether: Set network_header before transmitting
xfs: initialize the shortform attr header padding entry
drivers/net/wan/hdlc_cisco: Add hard_header_len
ALSA: hda: fix a runtime pm issue in SOF when integrated GPU is disabled
gcov: Disable gcov build with GCC 10
iio: adc: mcp3422: fix locking scope
iio: adc: mcp3422: fix locking on error path
iio:light:ltr501 Fix timestamp alignment issue.
iio:accel:bmc150-accel: Fix timestamp alignment and prevent data leak.
iio:accel:mma8452: Fix timestamp alignment and prevent data leak.
USB: core: add helpers to retrieve endpoints
staging: wlan-ng: fix out of bounds read in prism2sta_probe_usb()
btrfs: fix wrong address when faulting in pages in the search ioctl
scsi: target: iscsi: Fix hang in iscsit_access_np() when getting tpg->np_login_sem
rbd: require global CAP_SYS_ADMIN for mapping and unmapping
fbcon: remove soft scrollback code
fbcon: remove now unusued 'softback_lines' cursor() argument
vgacon: remove software scrollback support
KVM: VMX: Don't freeze guest when event delivery causes an APIC-access exit
video: fbdev: fix OOB read in vga_8planes_imageblit()
USB: serial: ftdi_sio: add IDs for Xsens Mti USB converter
USB: serial: option: add support for SIM7070/SIM7080/SIM7090 modules
usb: Fix out of sync data toggle if a configured device is reconfigured
gcov: add support for GCC 10.1
NFSv4.1 handle ERR_DELAY error reclaiming locking state on delegation recall
scsi: pm8001: Fix memleak in pm8001_exec_internal_task_abort
scsi: lpfc: Fix FLOGI/PLOGI receive race condition in pt2pt discovery
SUNRPC: stop printk reading past end of string
rapidio: Replace 'select' DMAENGINES 'with depends on'
i2c: algo: pca: Reapply i2c bus settings after reset
MIPS: SNI: Fix MIPS_L1_CACHE_SHIFT
perf test: Free formats for perf pmu parse test
fbcon: Fix user font detection test at fbcon_resize().
MIPS: SNI: Fix spurious interrupts
USB: quirks: Add USB_QUIRK_IGNORE_REMOTE_WAKEUP quirk for BYD zhaoxin notebook
USB: UAS: fix disconnect by unplugging a hub
usblp: fix race between disconnect() and read()
Input: i8042 - add Entroware Proteus EL07R4 to nomux and reset lists
serial: 8250_pci: Add Realtek 816a and 816b
ehci-hcd: Move include to keep CRC stable
powerpc/dma: Fix dma_map_ops::get_required_mask
x86/defconfig: Enable CONFIG_USB_XHCI_HCD=y
Linux 4.4.237
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: If3f7701823084090849a6866ba1e52a0276c9621
Diffstat (limited to 'drivers/usb')
| -rw-r--r-- | drivers/usb/class/usblp.c | 5 | ||||
| -rw-r--r-- | drivers/usb/core/message.c | 91 | ||||
| -rw-r--r-- | drivers/usb/core/quirks.c | 4 | ||||
| -rw-r--r-- | drivers/usb/core/usb.c | 83 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-hcd.c | 1 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-hub.c | 1 | ||||
| -rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 1 | ||||
| -rw-r--r-- | drivers/usb/serial/ftdi_sio_ids.h | 1 | ||||
| -rw-r--r-- | drivers/usb/serial/option.c | 2 | ||||
| -rw-r--r-- | drivers/usb/storage/uas.c | 14 |
10 files changed, 151 insertions, 52 deletions
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index c578d64edc15..71c2ae4b8106 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -840,6 +840,11 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t len, lo if (rv < 0) return rv; + if (!usblp->present) { + count = -ENODEV; + goto done; + } + if ((avail = usblp->rstatus) < 0) { printk(KERN_ERR "usblp%d: error %d reading from printer\n", usblp->minor, (int)avail); diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f083ecfddd1b..e568325cb6e1 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1141,6 +1141,34 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, } } +/* + * usb_disable_device_endpoints -- Disable all endpoints for a device + * @dev: the device whose endpoints are being disabled + * @skip_ep0: 0 to disable endpoint 0, 1 to skip it. + */ +static void usb_disable_device_endpoints(struct usb_device *dev, int skip_ep0) +{ + struct usb_hcd *hcd = bus_to_hcd(dev->bus); + int i; + + if (hcd->driver->check_bandwidth) { + /* First pass: Cancel URBs, leave endpoint pointers intact. */ + for (i = skip_ep0; i < 16; ++i) { + usb_disable_endpoint(dev, i, false); + usb_disable_endpoint(dev, i + USB_DIR_IN, false); + } + /* Remove endpoints from the host controller internal state */ + mutex_lock(hcd->bandwidth_mutex); + usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); + mutex_unlock(hcd->bandwidth_mutex); + } + /* Second pass: remove endpoint pointers */ + for (i = skip_ep0; i < 16; ++i) { + usb_disable_endpoint(dev, i, true); + usb_disable_endpoint(dev, i + USB_DIR_IN, true); + } +} + /** * usb_disable_device - Disable all the endpoints for a USB device * @dev: the device whose endpoints are being disabled @@ -1154,7 +1182,6 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, void usb_disable_device(struct usb_device *dev, int skip_ep0) { int i; - struct usb_hcd *hcd = bus_to_hcd(dev->bus); /* getting rid of interfaces will disconnect * any drivers bound to them (a key side effect) @@ -1200,22 +1227,8 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, skip_ep0 ? "non-ep0" : "all"); - if (hcd->driver->check_bandwidth) { - /* First pass: Cancel URBs, leave endpoint pointers intact. */ - for (i = skip_ep0; i < 16; ++i) { - usb_disable_endpoint(dev, i, false); - usb_disable_endpoint(dev, i + USB_DIR_IN, false); - } - /* Remove endpoints from the host controller internal state */ - mutex_lock(hcd->bandwidth_mutex); - usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); - mutex_unlock(hcd->bandwidth_mutex); - /* Second pass: remove endpoint pointers */ - } - for (i = skip_ep0; i < 16; ++i) { - usb_disable_endpoint(dev, i, true); - usb_disable_endpoint(dev, i + USB_DIR_IN, true); - } + + usb_disable_device_endpoints(dev, skip_ep0); } /** @@ -1458,6 +1471,9 @@ EXPORT_SYMBOL_GPL(usb_set_interface); * The caller must own the device lock. * * Return: Zero on success, else a negative error code. + * + * If this routine fails the device will probably be in an unusable state + * with endpoints disabled, and interfaces only partially enabled. */ int usb_reset_configuration(struct usb_device *dev) { @@ -1473,10 +1489,7 @@ int usb_reset_configuration(struct usb_device *dev) * calls during probe() are fine */ - for (i = 1; i < 16; ++i) { - usb_disable_endpoint(dev, i, true); - usb_disable_endpoint(dev, i + USB_DIR_IN, true); - } + usb_disable_device_endpoints(dev, 1); /* skip ep0*/ config = dev->actconfig; retval = 0; @@ -1489,34 +1502,10 @@ int usb_reset_configuration(struct usb_device *dev) mutex_unlock(hcd->bandwidth_mutex); return -ENOMEM; } - /* Make sure we have enough bandwidth for each alternate setting 0 */ - for (i = 0; i < config->desc.bNumInterfaces; i++) { - struct usb_interface *intf = config->interface[i]; - struct usb_host_interface *alt; - alt = usb_altnum_to_altsetting(intf, 0); - if (!alt) - alt = &intf->altsetting[0]; - if (alt != intf->cur_altsetting) - retval = usb_hcd_alloc_bandwidth(dev, NULL, - intf->cur_altsetting, alt); - if (retval < 0) - break; - } - /* If not, reinstate the old alternate settings */ + /* xHCI adds all endpoints in usb_hcd_alloc_bandwidth */ + retval = usb_hcd_alloc_bandwidth(dev, config, NULL, NULL); if (retval < 0) { -reset_old_alts: - for (i--; i >= 0; i--) { - struct usb_interface *intf = config->interface[i]; - struct usb_host_interface *alt; - - alt = usb_altnum_to_altsetting(intf, 0); - if (!alt) - alt = &intf->altsetting[0]; - if (alt != intf->cur_altsetting) - usb_hcd_alloc_bandwidth(dev, NULL, - alt, intf->cur_altsetting); - } usb_enable_lpm(dev); mutex_unlock(hcd->bandwidth_mutex); return retval; @@ -1525,8 +1514,12 @@ reset_old_alts: USB_REQ_SET_CONFIGURATION, 0, config->desc.bConfigurationValue, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); - if (retval < 0) - goto reset_old_alts; + if (retval < 0) { + usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); + usb_enable_lpm(dev); + mutex_unlock(hcd->bandwidth_mutex); + return retval; + } mutex_unlock(hcd->bandwidth_mutex); /* re-init hc/hcd interface/endpoint state */ diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index eed7c8d8e3d4..dd72e85f2e17 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -236,6 +236,10 @@ static const struct usb_device_id usb_quirk_list[] = { /* Generic RTL8153 based ethernet adapters */ { USB_DEVICE(0x0bda, 0x8153), .driver_info = USB_QUIRK_NO_LPM }, + /* SONiX USB DEVICE Touchpad */ + { USB_DEVICE(0x0c45, 0x7056), .driver_info = + USB_QUIRK_IGNORE_REMOTE_WAKEUP }, + /* Action Semiconductor flash disk */ { USB_DEVICE(0x10d6, 0x2200), .driver_info = USB_QUIRK_STRING_FETCH_255 }, diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 36e5098e4e6f..415e9cf407ba 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -77,6 +77,89 @@ MODULE_PARM_DESC(autosuspend, "default autosuspend delay"); /** + * usb_find_common_endpoints() -- look up common endpoint descriptors + * @alt: alternate setting to search + * @bulk_in: pointer to descriptor pointer, or NULL + * @bulk_out: pointer to descriptor pointer, or NULL + * @int_in: pointer to descriptor pointer, or NULL + * @int_out: pointer to descriptor pointer, or NULL + * + * Search the alternate setting's endpoint descriptors for the first bulk-in, + * bulk-out, interrupt-in and interrupt-out endpoints and return them in the + * provided pointers (unless they are NULL). + * + * If a requested endpoint is not found, the corresponding pointer is set to + * NULL. + * + * Return: Zero if all requested descriptors were found, or -ENXIO otherwise. + */ +int usb_find_common_endpoints(struct usb_host_interface *alt, + struct usb_endpoint_descriptor **bulk_in, + struct usb_endpoint_descriptor **bulk_out, + struct usb_endpoint_descriptor **int_in, + struct usb_endpoint_descriptor **int_out) +{ + struct usb_endpoint_descriptor *epd; + int i; + + if (bulk_in) + *bulk_in = NULL; + if (bulk_out) + *bulk_out = NULL; + if (int_in) + *int_in = NULL; + if (int_out) + *int_out = NULL; + + for (i = 0; i < alt->desc.bNumEndpoints; ++i) { + epd = &alt->endpoint[i].desc; + + switch (usb_endpoint_type(epd)) { + case USB_ENDPOINT_XFER_BULK: + if (usb_endpoint_dir_in(epd)) { + if (bulk_in && !*bulk_in) { + *bulk_in = epd; + break; + } + } else { + if (bulk_out && !*bulk_out) { + *bulk_out = epd; + break; + } + } + + continue; + case USB_ENDPOINT_XFER_INT: + if (usb_endpoint_dir_in(epd)) { + if (int_in && !*int_in) { + *int_in = epd; + break; + } + } else { + if (int_out && !*int_out) { + *int_out = epd; + break; + } + } + + continue; + default: + continue; + } + + if ((!bulk_in || *bulk_in) && + (!bulk_out || *bulk_out) && + (!int_in || *int_in) && + (!int_out || *int_out)) { + return 0; + } + } + + return -ENXIO; +} +EXPORT_SYMBOL_GPL(usb_find_common_endpoints); + +/** * usb_find_alt_setting() - Given a configuration, find the alternate setting * for the given interface. * @config: the configuration to search (not necessarily the current config). diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f7661d9750fd..330e05acf5f7 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -35,6 +35,7 @@ #include <linux/interrupt.h> #include <linux/usb.h> #include <linux/usb/hcd.h> +#include <linux/usb/otg.h> #include <linux/moduleparam.h> #include <linux/dma-mapping.h> #include <linux/debugfs.h> diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 086a7115d263..4dc93547e927 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -27,7 +27,6 @@ */ /*-------------------------------------------------------------------------*/ -#include <linux/usb/otg.h> #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 0afea511eb37..25e76d4c1505 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -708,6 +708,7 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(XSENS_VID, XSENS_AWINDA_STATION_PID) }, { USB_DEVICE(XSENS_VID, XSENS_CONVERTER_PID) }, { USB_DEVICE(XSENS_VID, XSENS_MTDEVBOARD_PID) }, + { USB_DEVICE(XSENS_VID, XSENS_MTIUSBCONVERTER_PID) }, { USB_DEVICE(XSENS_VID, XSENS_MTW_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) }, { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 32a40ab9a385..c33e06752b5f 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -159,6 +159,7 @@ #define XSENS_AWINDA_DONGLE_PID 0x0102 #define XSENS_MTW_PID 0x0200 /* Xsens MTw */ #define XSENS_MTDEVBOARD_PID 0x0300 /* Motion Tracker Development Board */ +#define XSENS_MTIUSBCONVERTER_PID 0x0301 /* MTi USB converter */ #define XSENS_CONVERTER_PID 0xD00D /* Xsens USB-serial converter */ /* Xsens devices using FTDI VID */ diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 52b1092ed57e..8cff50ef4fd1 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1808,6 +1808,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9003, 0xff) }, /* Simcom SIM7500/SIM7600 MBIM mode */ { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9011, 0xff), /* Simcom SIM7500/SIM7600 RNDIS mode */ .driver_info = RSVD(7) }, + { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9205, 0xff) }, /* Simcom SIM7070/SIM7080/SIM7090 AT+ECM mode */ + { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9206, 0xff) }, /* Simcom SIM7070/SIM7080/SIM7090 AT-only mode */ { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), .driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D), diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 698ba127b635..34dcd2e1b4fe 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -646,8 +646,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, if (devinfo->resetting) { cmnd->result = DID_ERROR << 16; cmnd->scsi_done(cmnd); - spin_unlock_irqrestore(&devinfo->lock, flags); - return 0; + goto zombie; } /* Find a free uas-tag */ @@ -682,6 +681,16 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB); err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC); + /* + * in case of fatal errors the SCSI layer is peculiar + * a command that has finished is a success for the purpose + * of queueing, no matter how fatal the error + */ + if (err == -ENODEV) { + cmnd->result = DID_ERROR << 16; + cmnd->scsi_done(cmnd); + goto zombie; + } if (err) { /* If we did nothing, give up now */ if (cmdinfo->state & SUBMIT_STATUS_URB) { @@ -692,6 +701,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, } devinfo->cmnd[idx] = cmnd; +zombie: spin_unlock_irqrestore(&devinfo->lock, flags); return 0; } |
