USB fixes for 4.6-rc4

Here are some small USB fixes for 4.6-rc4.
 
 Mostly xhci fixes for reported issues, a UAS bug that has hit a number
 of people, including stable tree users, and a few other minor things.
 
 All have been in linux-next for a while with no reported issues.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iEYEABECAAYFAlcS3ngACgkQMUfUDdst+ykPlgCeJ2UJu7dYz3ICVnxQ4zLkNG6A
 yI0AoKa37VYqNkqRadj97g9E5S6KcsXi
 =KmX3
 -----END PGP SIGNATURE-----

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

Pull USB driver fixes from Greg KH:
 "Here are some small USB fixes for 4.6-rc4.

  Mostly xhci fixes for reported issues, a UAS bug that has hit a number
  of people, including stable tree users, and a few other minor things.

  All have been in linux-next for a while with no reported issues"

* tag 'usb-4.6-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: hcd: out of bounds access in for_each_companion
  USB: uas: Add a new NO_REPORT_LUNS quirk
  USB: uas: Limit qdepth at the scsi-host level
  doc: usb: Fix typo in gadget_multi documentation
  usb: host: xhci-plat: Make enum xhci_plat_type start at a non zero value
  xhci: fix 10 second timeout on removal of PCI hotpluggable xhci controllers
  usb: xhci: fix wild pointers in xhci_mem_cleanup
  usb: host: xhci-plat: fix cannot work if R-Car Gen2/3 run on above 4GB phys
  usb: host: xhci: add a new quirk XHCI_NO_64BIT_SUPPORT
  xhci: resume USB 3 roothub first
  usb: xhci: applying XHCI_PME_STUCK_QUIRK to Intel BXT B0 host
  cdc-acm: fix crash if flushed with nothing buffered
This commit is contained in:
Linus Torvalds 2016-04-16 20:48:14 -07:00
commit b62dabfb4b
15 changed files with 94 additions and 13 deletions

View File

@ -4077,6 +4077,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
sector if the number is odd); sector if the number is odd);
i = IGNORE_DEVICE (don't bind to this i = IGNORE_DEVICE (don't bind to this
device); device);
j = NO_REPORT_LUNS (don't use report luns
command, uas only);
l = NOT_LOCKABLE (don't try to lock and l = NOT_LOCKABLE (don't try to lock and
unlock ejectable media); unlock ejectable media);
m = MAX_SECTORS_64 (don't transfer more m = MAX_SECTORS_64 (don't transfer more

View File

@ -43,7 +43,7 @@ For the gadget two work under Windows two conditions have to be met:
First of all, Windows need to detect the gadget as an USB composite First of all, Windows need to detect the gadget as an USB composite
gadget which on its own have some conditions[4]. If they are met, gadget which on its own have some conditions[4]. If they are met,
Windows lets USB Generic Parent Driver[5] handle the device which then Windows lets USB Generic Parent Driver[5] handle the device which then
tries to much drivers for each individual interface (sort of, don't tries to match drivers for each individual interface (sort of, don't
get into too many details). get into too many details).
The good news is: you do not have to worry about most of the The good news is: you do not have to worry about most of the

View File

@ -744,11 +744,15 @@ static void acm_tty_flush_chars(struct tty_struct *tty)
int err; int err;
unsigned long flags; unsigned long flags;
if (!cur) /* nothing to do */
return;
acm->putbuffer = NULL; acm->putbuffer = NULL;
err = usb_autopm_get_interface_async(acm->control); err = usb_autopm_get_interface_async(acm->control);
spin_lock_irqsave(&acm->write_lock, flags); spin_lock_irqsave(&acm->write_lock, flags);
if (err < 0) { if (err < 0) {
cur->use = 0; cur->use = 0;
acm->putbuffer = cur;
goto out; goto out;
} }

View File

@ -73,6 +73,15 @@ static void for_each_companion(struct pci_dev *pdev, struct usb_hcd *hcd,
if (companion->bus != pdev->bus || if (companion->bus != pdev->bus ||
PCI_SLOT(companion->devfn) != slot) PCI_SLOT(companion->devfn) != slot)
continue; continue;
/*
* Companion device should be either UHCI,OHCI or EHCI host
* controller, otherwise skip.
*/
if (companion->class != CL_UHCI && companion->class != CL_OHCI &&
companion->class != CL_EHCI)
continue;
companion_hcd = pci_get_drvdata(companion); companion_hcd = pci_get_drvdata(companion);
if (!companion_hcd || !companion_hcd->self.root_hub) if (!companion_hcd || !companion_hcd->self.root_hub)
continue; continue;

View File

@ -1861,6 +1861,12 @@ no_bw:
kfree(xhci->rh_bw); kfree(xhci->rh_bw);
kfree(xhci->ext_caps); kfree(xhci->ext_caps);
xhci->usb2_ports = NULL;
xhci->usb3_ports = NULL;
xhci->port_array = NULL;
xhci->rh_bw = NULL;
xhci->ext_caps = NULL;
xhci->page_size = 0; xhci->page_size = 0;
xhci->page_shift = 0; xhci->page_shift = 0;
xhci->bus_state[0].bus_suspended = 0; xhci->bus_state[0].bus_suspended = 0;

View File

@ -48,6 +48,7 @@
#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f
#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f
#define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI 0x0aa8 #define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI 0x0aa8
#define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI 0x1aa8
static const char hcd_name[] = "xhci_hcd"; static const char hcd_name[] = "xhci_hcd";
@ -155,7 +156,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
(pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI || (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI)) { pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI)) {
xhci->quirks |= XHCI_PME_STUCK_QUIRK; xhci->quirks |= XHCI_PME_STUCK_QUIRK;
} }
if (pdev->vendor == PCI_VENDOR_ID_INTEL && if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
@ -302,6 +304,7 @@ static void xhci_pci_remove(struct pci_dev *dev)
struct xhci_hcd *xhci; struct xhci_hcd *xhci;
xhci = hcd_to_xhci(pci_get_drvdata(dev)); xhci = hcd_to_xhci(pci_get_drvdata(dev));
xhci->xhc_state |= XHCI_STATE_REMOVING;
if (xhci->shared_hcd) { if (xhci->shared_hcd) {
usb_remove_hcd(xhci->shared_hcd); usb_remove_hcd(xhci->shared_hcd);
usb_put_hcd(xhci->shared_hcd); usb_put_hcd(xhci->shared_hcd);

View File

@ -39,12 +39,25 @@ static const struct xhci_driver_overrides xhci_plat_overrides __initconst = {
static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
{ {
struct usb_hcd *hcd = xhci_to_hcd(xhci);
/* /*
* As of now platform drivers don't provide MSI support so we ensure * As of now platform drivers don't provide MSI support so we ensure
* here that the generic code does not try to make a pci_dev from our * here that the generic code does not try to make a pci_dev from our
* dev struct in order to setup MSI * dev struct in order to setup MSI
*/ */
xhci->quirks |= XHCI_PLAT; xhci->quirks |= XHCI_PLAT;
/*
* On R-Car Gen2 and Gen3, the AC64 bit (bit 0) of HCCPARAMS1 is set
* to 1. However, these SoCs don't support 64-bit address memory
* pointers. So, this driver clears the AC64 bit of xhci->hcc_params
* to call dma_set_coherent_mask(dev, DMA_BIT_MASK(32)) in
* xhci_gen_setup().
*/
if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2) ||
xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN3))
xhci->quirks |= XHCI_NO_64BIT_SUPPORT;
} }
/* called during probe() after chip reset completes */ /* called during probe() after chip reset completes */

View File

@ -14,7 +14,7 @@
#include "xhci.h" /* for hcd_to_xhci() */ #include "xhci.h" /* for hcd_to_xhci() */
enum xhci_plat_type { enum xhci_plat_type {
XHCI_PLAT_TYPE_MARVELL_ARMADA, XHCI_PLAT_TYPE_MARVELL_ARMADA = 1,
XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2,
XHCI_PLAT_TYPE_RENESAS_RCAR_GEN3, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN3,
}; };

View File

@ -4004,7 +4004,8 @@ static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd,
int reserved_trbs = xhci->cmd_ring_reserved_trbs; int reserved_trbs = xhci->cmd_ring_reserved_trbs;
int ret; int ret;
if (xhci->xhc_state) { if ((xhci->xhc_state & XHCI_STATE_DYING) ||
(xhci->xhc_state & XHCI_STATE_HALTED)) {
xhci_dbg(xhci, "xHCI dying or halted, can't queue_command\n"); xhci_dbg(xhci, "xHCI dying or halted, can't queue_command\n");
return -ESHUTDOWN; return -ESHUTDOWN;
} }

View File

@ -147,7 +147,8 @@ static int xhci_start(struct xhci_hcd *xhci)
"waited %u microseconds.\n", "waited %u microseconds.\n",
XHCI_MAX_HALT_USEC); XHCI_MAX_HALT_USEC);
if (!ret) if (!ret)
xhci->xhc_state &= ~(XHCI_STATE_HALTED | XHCI_STATE_DYING); /* clear state flags. Including dying, halted or removing */
xhci->xhc_state = 0;
return ret; return ret;
} }
@ -1108,8 +1109,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
/* Resume root hubs only when have pending events. */ /* Resume root hubs only when have pending events. */
status = readl(&xhci->op_regs->status); status = readl(&xhci->op_regs->status);
if (status & STS_EINT) { if (status & STS_EINT) {
usb_hcd_resume_root_hub(hcd);
usb_hcd_resume_root_hub(xhci->shared_hcd); usb_hcd_resume_root_hub(xhci->shared_hcd);
usb_hcd_resume_root_hub(hcd);
} }
} }
@ -1124,10 +1125,10 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
/* Re-enable port polling. */ /* Re-enable port polling. */
xhci_dbg(xhci, "%s: starting port polling.\n", __func__); xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
usb_hcd_poll_rh_status(hcd);
set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
usb_hcd_poll_rh_status(xhci->shared_hcd); usb_hcd_poll_rh_status(xhci->shared_hcd);
set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
usb_hcd_poll_rh_status(hcd);
return retval; return retval;
} }
@ -2773,7 +2774,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
if (ret <= 0) if (ret <= 0)
return ret; return ret;
xhci = hcd_to_xhci(hcd); xhci = hcd_to_xhci(hcd);
if (xhci->xhc_state & XHCI_STATE_DYING) if ((xhci->xhc_state & XHCI_STATE_DYING) ||
(xhci->xhc_state & XHCI_STATE_REMOVING))
return -ENODEV; return -ENODEV;
xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
@ -3820,7 +3822,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
mutex_lock(&xhci->mutex); mutex_lock(&xhci->mutex);
if (xhci->xhc_state) /* dying or halted */ if (xhci->xhc_state) /* dying, removing or halted */
goto out; goto out;
if (!udev->slot_id) { if (!udev->slot_id) {
@ -4948,6 +4950,16 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
return retval; return retval;
xhci_dbg(xhci, "Reset complete\n"); xhci_dbg(xhci, "Reset complete\n");
/*
* On some xHCI controllers (e.g. R-Car SoCs), the AC64 bit (bit 0)
* of HCCPARAMS1 is set to 1. However, the xHCs don't support 64-bit
* address memory pointers actually. So, this driver clears the AC64
* bit of xhci->hcc_params to call dma_set_coherent_mask(dev,
* DMA_BIT_MASK(32)) in this xhci_gen_setup().
*/
if (xhci->quirks & XHCI_NO_64BIT_SUPPORT)
xhci->hcc_params &= ~BIT(0);
/* Set dma_mask and coherent_dma_mask to 64-bits, /* Set dma_mask and coherent_dma_mask to 64-bits,
* if xHC supports 64-bit addressing */ * if xHC supports 64-bit addressing */
if (HCC_64BIT_ADDR(xhci->hcc_params) && if (HCC_64BIT_ADDR(xhci->hcc_params) &&

View File

@ -1605,6 +1605,7 @@ struct xhci_hcd {
*/ */
#define XHCI_STATE_DYING (1 << 0) #define XHCI_STATE_DYING (1 << 0)
#define XHCI_STATE_HALTED (1 << 1) #define XHCI_STATE_HALTED (1 << 1)
#define XHCI_STATE_REMOVING (1 << 2)
/* Statistics */ /* Statistics */
int error_bitmask; int error_bitmask;
unsigned int quirks; unsigned int quirks;
@ -1641,6 +1642,7 @@ struct xhci_hcd {
#define XHCI_PME_STUCK_QUIRK (1 << 20) #define XHCI_PME_STUCK_QUIRK (1 << 20)
#define XHCI_MTK_HOST (1 << 21) #define XHCI_MTK_HOST (1 << 21)
#define XHCI_SSIC_PORT_UNUSED (1 << 22) #define XHCI_SSIC_PORT_UNUSED (1 << 22)
#define XHCI_NO_64BIT_SUPPORT (1 << 23)
unsigned int num_active_eps; unsigned int num_active_eps;
unsigned int limit_active_eps; unsigned int limit_active_eps;
/* There are two roothubs to keep track of bus suspend info for */ /* There are two roothubs to keep track of bus suspend info for */

View File

@ -2,7 +2,7 @@
* USB Attached SCSI * USB Attached SCSI
* Note that this is not the same as the USB Mass Storage driver * Note that this is not the same as the USB Mass Storage driver
* *
* Copyright Hans de Goede <hdegoede@redhat.com> for Red Hat, Inc. 2013 - 2014 * Copyright Hans de Goede <hdegoede@redhat.com> for Red Hat, Inc. 2013 - 2016
* Copyright Matthew Wilcox for Intel Corp, 2010 * Copyright Matthew Wilcox for Intel Corp, 2010
* Copyright Sarah Sharp for Intel Corp, 2010 * Copyright Sarah Sharp for Intel Corp, 2010
* *
@ -781,6 +781,17 @@ static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd)
return SUCCESS; return SUCCESS;
} }
static int uas_target_alloc(struct scsi_target *starget)
{
struct uas_dev_info *devinfo = (struct uas_dev_info *)
dev_to_shost(starget->dev.parent)->hostdata;
if (devinfo->flags & US_FL_NO_REPORT_LUNS)
starget->no_report_luns = 1;
return 0;
}
static int uas_slave_alloc(struct scsi_device *sdev) static int uas_slave_alloc(struct scsi_device *sdev)
{ {
struct uas_dev_info *devinfo = struct uas_dev_info *devinfo =
@ -824,7 +835,6 @@ static int uas_slave_configure(struct scsi_device *sdev)
if (devinfo->flags & US_FL_BROKEN_FUA) if (devinfo->flags & US_FL_BROKEN_FUA)
sdev->broken_fua = 1; sdev->broken_fua = 1;
scsi_change_queue_depth(sdev, devinfo->qdepth - 2);
return 0; return 0;
} }
@ -832,6 +842,7 @@ static struct scsi_host_template uas_host_template = {
.module = THIS_MODULE, .module = THIS_MODULE,
.name = "uas", .name = "uas",
.queuecommand = uas_queuecommand, .queuecommand = uas_queuecommand,
.target_alloc = uas_target_alloc,
.slave_alloc = uas_slave_alloc, .slave_alloc = uas_slave_alloc,
.slave_configure = uas_slave_configure, .slave_configure = uas_slave_configure,
.eh_abort_handler = uas_eh_abort_handler, .eh_abort_handler = uas_eh_abort_handler,
@ -956,6 +967,12 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (result) if (result)
goto set_alt0; goto set_alt0;
/*
* 1 tag is reserved for untagged commands +
* 1 tag to avoid off by one errors in some bridge firmwares
*/
shost->can_queue = devinfo->qdepth - 2;
usb_set_intfdata(intf, shost); usb_set_intfdata(intf, shost);
result = scsi_add_host(shost, &intf->dev); result = scsi_add_host(shost, &intf->dev);
if (result) if (result)

View File

@ -64,6 +64,13 @@ UNUSUAL_DEV(0x0bc2, 0x3312, 0x0000, 0x9999,
USB_SC_DEVICE, USB_PR_DEVICE, NULL, USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_NO_ATA_1X), US_FL_NO_ATA_1X),
/* Reported-by: David Webb <djw@noc.ac.uk> */
UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x9999,
"Seagate",
"Expansion Desk",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_NO_REPORT_LUNS),
/* Reported-by: Hans de Goede <hdegoede@redhat.com> */ /* Reported-by: Hans de Goede <hdegoede@redhat.com> */
UNUSUAL_DEV(0x0bc2, 0x3320, 0x0000, 0x9999, UNUSUAL_DEV(0x0bc2, 0x3320, 0x0000, 0x9999,
"Seagate", "Seagate",

View File

@ -482,7 +482,7 @@ void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags)
US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16 | US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16 |
US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE | US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE |
US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES | US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES |
US_FL_MAX_SECTORS_240); US_FL_MAX_SECTORS_240 | US_FL_NO_REPORT_LUNS);
p = quirks; p = quirks;
while (*p) { while (*p) {
@ -532,6 +532,9 @@ void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags)
case 'i': case 'i':
f |= US_FL_IGNORE_DEVICE; f |= US_FL_IGNORE_DEVICE;
break; break;
case 'j':
f |= US_FL_NO_REPORT_LUNS;
break;
case 'l': case 'l':
f |= US_FL_NOT_LOCKABLE; f |= US_FL_NOT_LOCKABLE;
break; break;

View File

@ -79,6 +79,8 @@
/* Cannot handle MI_REPORT_SUPPORTED_OPERATION_CODES */ \ /* Cannot handle MI_REPORT_SUPPORTED_OPERATION_CODES */ \
US_FLAG(MAX_SECTORS_240, 0x08000000) \ US_FLAG(MAX_SECTORS_240, 0x08000000) \
/* Sets max_sectors to 240 */ \ /* Sets max_sectors to 240 */ \
US_FLAG(NO_REPORT_LUNS, 0x10000000) \
/* Cannot handle REPORT_LUNS */ \
#define US_FLAG(name, value) US_FL_##name = value , #define US_FLAG(name, value) US_FL_##name = value ,
enum { US_DO_ALL_FLAGS }; enum { US_DO_ALL_FLAGS };