USB fixes for 4.2-rc1

Here are a number of small USB fixes for 4.2-rc2.  They revert one
 problem patch, fix some minor things, and add some new quirks for
 "broken" devices.
 
 All have been in linux-next successfully.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iEYEABECAAYFAlVCMNMACgkQMUfUDdst+ylQJwCgsGHQVK4YgrIOCpIkXoc+riy1
 VWkAnip86mUGKRej4jrrRvTGvm3maeTj
 =/oWf
 -----END PGP SIGNATURE-----

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

Pull USB fixes from Greg KH:
 "Here are a number of small USB fixes for 4.2-rc2.  They revert one
  problem patch, fix some minor things, and add some new quirks for
  "broken" devices.

  All have been in linux-next successfully"

* tag 'usb-4.1-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  cdc-acm: prevent infinite loop when parsing CDC headers.
  Revert "usb: host: ehci-msm: Use devm_ioremap_resource instead of devm_ioremap"
  usb: chipidea: otg: remove mutex unlock and lock while stop and start role
  uas: Set max_sectors_240 quirk for ASM1053 devices
  uas: Add US_FL_MAX_SECTORS_240 flag
  uas: Allow uas_use_uas_driver to return usb-storage flags
This commit is contained in:
Linus Torvalds 2015-04-30 09:08:53 -07:00
commit dcca8de0aa
8 changed files with 47 additions and 16 deletions

View File

@ -3787,6 +3787,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
READ_CAPACITY_16 command); READ_CAPACITY_16 command);
f = NO_REPORT_OPCODES (don't use report opcodes f = NO_REPORT_OPCODES (don't use report opcodes
command, uas only); command, uas only);
g = MAX_SECTORS_240 (don't transfer more than
240 sectors at a time, uas only);
h = CAPACITY_HEURISTICS (decrease the h = CAPACITY_HEURISTICS (decrease the
reported device capacity by one reported device capacity by one
sector if the number is odd); sector if the number is odd);

View File

@ -520,7 +520,6 @@ static int ci_otg_start_host(struct otg_fsm *fsm, int on)
{ {
struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm); struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
mutex_unlock(&fsm->lock);
if (on) { if (on) {
ci_role_stop(ci); ci_role_stop(ci);
ci_role_start(ci, CI_ROLE_HOST); ci_role_start(ci, CI_ROLE_HOST);
@ -529,7 +528,6 @@ static int ci_otg_start_host(struct otg_fsm *fsm, int on)
hw_device_reset(ci); hw_device_reset(ci);
ci_role_start(ci, CI_ROLE_GADGET); ci_role_start(ci, CI_ROLE_GADGET);
} }
mutex_lock(&fsm->lock);
return 0; return 0;
} }
@ -537,12 +535,10 @@ static int ci_otg_start_gadget(struct otg_fsm *fsm, int on)
{ {
struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm); struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
mutex_unlock(&fsm->lock);
if (on) if (on)
usb_gadget_vbus_connect(&ci->gadget); usb_gadget_vbus_connect(&ci->gadget);
else else
usb_gadget_vbus_disconnect(&ci->gadget); usb_gadget_vbus_disconnect(&ci->gadget);
mutex_lock(&fsm->lock);
return 0; return 0;
} }

View File

@ -1142,11 +1142,16 @@ static int acm_probe(struct usb_interface *intf,
} }
while (buflen > 0) { while (buflen > 0) {
elength = buffer[0];
if (!elength) {
dev_err(&intf->dev, "skipping garbage byte\n");
elength = 1;
goto next_desc;
}
if (buffer[1] != USB_DT_CS_INTERFACE) { if (buffer[1] != USB_DT_CS_INTERFACE) {
dev_err(&intf->dev, "skipping garbage\n"); dev_err(&intf->dev, "skipping garbage\n");
goto next_desc; goto next_desc;
} }
elength = buffer[0];
switch (buffer[2]) { switch (buffer[2]) {
case USB_CDC_UNION_TYPE: /* we've found it */ case USB_CDC_UNION_TYPE: /* we've found it */

View File

@ -88,13 +88,20 @@ static int ehci_msm_probe(struct platform_device *pdev)
} }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (!res) {
if (IS_ERR(hcd->regs)) { dev_err(&pdev->dev, "Unable to get memory resource\n");
ret = PTR_ERR(hcd->regs); ret = -ENODEV;
goto put_hcd; goto put_hcd;
} }
hcd->rsrc_start = res->start; hcd->rsrc_start = res->start;
hcd->rsrc_len = resource_size(res); hcd->rsrc_len = resource_size(res);
hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len);
if (!hcd->regs) {
dev_err(&pdev->dev, "ioremap failed\n");
ret = -ENOMEM;
goto put_hcd;
}
/* /*
* OTG driver takes care of PHY initialization, clock management, * OTG driver takes care of PHY initialization, clock management,

View File

@ -51,7 +51,8 @@ static int uas_find_endpoints(struct usb_host_interface *alt,
} }
static int uas_use_uas_driver(struct usb_interface *intf, static int uas_use_uas_driver(struct usb_interface *intf,
const struct usb_device_id *id) const struct usb_device_id *id,
unsigned long *flags_ret)
{ {
struct usb_host_endpoint *eps[4] = { }; struct usb_host_endpoint *eps[4] = { };
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
@ -73,7 +74,7 @@ static int uas_use_uas_driver(struct usb_interface *intf,
* this writing the following versions exist: * this writing the following versions exist:
* ASM1051 - no uas support version * ASM1051 - no uas support version
* ASM1051 - with broken (*) uas support * ASM1051 - with broken (*) uas support
* ASM1053 - with working uas support * ASM1053 - with working uas support, but problems with large xfers
* ASM1153 - with working uas support * ASM1153 - with working uas support
* *
* Devices with these chips re-use a number of device-ids over the * Devices with these chips re-use a number of device-ids over the
@ -103,6 +104,9 @@ static int uas_use_uas_driver(struct usb_interface *intf,
} else if (usb_ss_max_streams(&eps[1]->ss_ep_comp) == 32) { } else if (usb_ss_max_streams(&eps[1]->ss_ep_comp) == 32) {
/* Possibly an ASM1051, disable uas */ /* Possibly an ASM1051, disable uas */
flags |= US_FL_IGNORE_UAS; flags |= US_FL_IGNORE_UAS;
} else {
/* ASM1053, these have issues with large transfers */
flags |= US_FL_MAX_SECTORS_240;
} }
} }
@ -132,5 +136,8 @@ static int uas_use_uas_driver(struct usb_interface *intf,
return 0; return 0;
} }
if (flags_ret)
*flags_ret = flags;
return 1; return 1;
} }

View File

@ -759,7 +759,10 @@ static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd)
static int uas_slave_alloc(struct scsi_device *sdev) static int uas_slave_alloc(struct scsi_device *sdev)
{ {
sdev->hostdata = (void *)sdev->host->hostdata; struct uas_dev_info *devinfo =
(struct uas_dev_info *)sdev->host->hostdata;
sdev->hostdata = devinfo;
/* USB has unusual DMA-alignment requirements: Although the /* USB has unusual DMA-alignment requirements: Although the
* starting address of each scatter-gather element doesn't matter, * starting address of each scatter-gather element doesn't matter,
@ -778,6 +781,11 @@ 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;
} }
@ -887,8 +895,9 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
struct Scsi_Host *shost = NULL; struct Scsi_Host *shost = NULL;
struct uas_dev_info *devinfo; struct uas_dev_info *devinfo;
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
unsigned long dev_flags;
if (!uas_use_uas_driver(intf, id)) if (!uas_use_uas_driver(intf, id, &dev_flags))
return -ENODEV; return -ENODEV;
if (uas_switch_interface(udev, intf)) if (uas_switch_interface(udev, intf))
@ -910,8 +919,7 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
devinfo->udev = udev; devinfo->udev = udev;
devinfo->resetting = 0; devinfo->resetting = 0;
devinfo->shutdown = 0; devinfo->shutdown = 0;
devinfo->flags = id->driver_info; devinfo->flags = dev_flags;
usb_stor_adjust_quirks(udev, &devinfo->flags);
init_usb_anchor(&devinfo->cmd_urbs); init_usb_anchor(&devinfo->cmd_urbs);
init_usb_anchor(&devinfo->sense_urbs); init_usb_anchor(&devinfo->sense_urbs);
init_usb_anchor(&devinfo->data_urbs); init_usb_anchor(&devinfo->data_urbs);

View File

@ -479,7 +479,8 @@ void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags)
US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT | US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT |
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);
p = quirks; p = quirks;
while (*p) { while (*p) {
@ -520,6 +521,9 @@ void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags)
case 'f': case 'f':
f |= US_FL_NO_REPORT_OPCODES; f |= US_FL_NO_REPORT_OPCODES;
break; break;
case 'g':
f |= US_FL_MAX_SECTORS_240;
break;
case 'h': case 'h':
f |= US_FL_CAPACITY_HEURISTICS; f |= US_FL_CAPACITY_HEURISTICS;
break; break;
@ -1080,7 +1084,7 @@ static int storage_probe(struct usb_interface *intf,
/* If uas is enabled and this device can do uas then ignore it. */ /* If uas is enabled and this device can do uas then ignore it. */
#if IS_ENABLED(CONFIG_USB_UAS) #if IS_ENABLED(CONFIG_USB_UAS)
if (uas_use_uas_driver(intf, id)) if (uas_use_uas_driver(intf, id, NULL))
return -ENXIO; return -ENXIO;
#endif #endif

View File

@ -77,6 +77,8 @@
/* Cannot handle ATA_12 or ATA_16 CDBs */ \ /* Cannot handle ATA_12 or ATA_16 CDBs */ \
US_FLAG(NO_REPORT_OPCODES, 0x04000000) \ US_FLAG(NO_REPORT_OPCODES, 0x04000000) \
/* Cannot handle MI_REPORT_SUPPORTED_OPERATION_CODES */ \ /* Cannot handle MI_REPORT_SUPPORTED_OPERATION_CODES */ \
US_FLAG(MAX_SECTORS_240, 0x08000000) \
/* Sets max_sectors to 240 */ \
#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 };