--- zzzz-none-000/linux-3.10.107/drivers/usb/storage/usb.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/usb/storage/usb.c 2021-02-04 17:41:59.000000000 +0000 @@ -53,7 +53,6 @@ #include #include #include -#include #include #include #include @@ -73,12 +72,24 @@ #include "sierra_ms.h" #include "option_ms.h" +#if IS_ENABLED(CONFIG_USB_UAS) +#include "uas-detect.h" +#endif + +#define DRV_NAME "usb-storage" + /* Some informational data */ MODULE_AUTHOR("Matthew Dharm "); MODULE_DESCRIPTION("USB Mass Storage driver for Linux"); MODULE_LICENSE("GPL"); +/* == 20160222 AVM/VGJ need delay for UMTS modeswitch ==*/ +#if defined (CONFIG_USB_SERIAL_OPTION) || defined (CONFIG_USB_SERIAL_OPTION_MODULE) +static unsigned int delay_use = 5; +#else static unsigned int delay_use = 1; +#endif + module_param(delay_use, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); @@ -95,7 +106,7 @@ /* The vendor name should be kept at eight characters or less, and * the product name should be kept at 16 characters or less. If a device * has the US_FL_FIX_INQUIRY flag, then the vendor and product names - * normally generated by a device thorugh the INQUIRY response will be + * normally generated by a device through the INQUIRY response will be * taken from this list, and this is the reason for the above size * restriction. However, if the flag is not present, then you * are free to use as many characters as you like. @@ -344,14 +355,16 @@ */ else if (us->srb->device->id && !(us->fflags & US_FL_SCM_MULT_TARG)) { - usb_stor_dbg(us, "Bad target number (%d:%d)\n", - us->srb->device->id, us->srb->device->lun); + usb_stor_dbg(us, "Bad target number (%d:%llu)\n", + us->srb->device->id, + us->srb->device->lun); us->srb->result = DID_BAD_TARGET << 16; } else if (us->srb->device->lun > us->max_lun) { - usb_stor_dbg(us, "Bad LUN (%d:%d)\n", - us->srb->device->id, us->srb->device->lun); + usb_stor_dbg(us, "Bad LUN (%d:%llu)\n", + us->srb->device->id, + us->srb->device->lun); us->srb->result = DID_BAD_TARGET << 16; } @@ -460,20 +473,22 @@ #define TOLOWER(x) ((x) | 0x20) /* Adjust device flags based on the "quirks=" module parameter */ -static void adjust_quirks(struct us_data *us) +void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags) { char *p; - u16 vid = le16_to_cpu(us->pusb_dev->descriptor.idVendor); - u16 pid = le16_to_cpu(us->pusb_dev->descriptor.idProduct); + u16 vid = le16_to_cpu(udev->descriptor.idVendor); + u16 pid = le16_to_cpu(udev->descriptor.idProduct); unsigned f = 0; unsigned int mask = (US_FL_SANE_SENSE | US_FL_BAD_SENSE | - US_FL_FIX_CAPACITY | + US_FL_FIX_CAPACITY | US_FL_IGNORE_UAS | US_FL_CAPACITY_HEURISTICS | US_FL_IGNORE_DEVICE | US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 | US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE | US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT | 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_MAX_SECTORS_240 | US_FL_NO_REPORT_LUNS); p = quirks; while (*p) { @@ -511,12 +526,21 @@ case 'e': f |= US_FL_NO_READ_CAPACITY_16; break; + case 'f': + f |= US_FL_NO_REPORT_OPCODES; + break; + case 'g': + f |= US_FL_MAX_SECTORS_240; + break; case 'h': f |= US_FL_CAPACITY_HEURISTICS; break; case 'i': f |= US_FL_IGNORE_DEVICE; break; + case 'j': + f |= US_FL_NO_REPORT_LUNS; + break; case 'l': f |= US_FL_NOT_LOCKABLE; break; @@ -538,14 +562,21 @@ case 's': f |= US_FL_SINGLE_LUN; break; + case 't': + f |= US_FL_NO_ATA_1X; + break; + case 'u': + f |= US_FL_IGNORE_UAS; + break; case 'w': f |= US_FL_NO_WP_DETECT; break; /* Ignore unrecognized flag characters */ } } - us->fflags = (us->fflags & ~mask) | f; + *fflags = (*fflags & ~mask) | f; } +EXPORT_SYMBOL_GPL(usb_stor_adjust_quirks); /* Get the unusual_devs entries and the string descriptors */ static int get_device_info(struct us_data *us, const struct usb_device_id *id, @@ -565,7 +596,7 @@ idesc->bInterfaceProtocol : unusual_dev->useTransport; us->fflags = id->driver_info; - adjust_quirks(us); + usb_stor_adjust_quirks(us->pusb_dev, &us->fflags); if (us->fflags & US_FL_IGNORE_DEVICE) { dev_info(pdev, "device ignored\n"); @@ -868,9 +899,17 @@ dev_dbg(dev, "starting scan\n"); /* For bulk-only devices, determine the max LUN value */ - if (us->protocol == USB_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN)) { + if (us->protocol == USB_PR_BULK && + !(us->fflags & US_FL_SINGLE_LUN) && + !(us->fflags & US_FL_SCM_MULT_TARG)) { mutex_lock(&us->dev_mutex); us->max_lun = usb_stor_Bulk_max_lun(us); + /* + * Allow proper scanning of devices that present more than 8 LUNs + * While not affecting other devices that may need the previous behavior + */ + if (us->max_lun >= 8) + us_to_host(us)->max_lun = us->max_lun+1; mutex_unlock(&us->dev_mutex); } scsi_scan_host(us_to_host(us)); @@ -896,7 +935,8 @@ int usb_stor_probe1(struct us_data **pus, struct usb_interface *intf, const struct usb_device_id *id, - struct us_unusual_dev *unusual_dev) + struct us_unusual_dev *unusual_dev, + struct scsi_host_template *sht) { struct Scsi_Host *host; struct us_data *us; @@ -908,7 +948,7 @@ * Ask the SCSI layer to allocate a host structure, with extra * space at the end for our private us_data structure. */ - host = scsi_host_alloc(&usb_stor_host_template, sizeof(*us)); + host = scsi_host_alloc(sht, sizeof(*us)); if (!host) { dev_warn(&intf->dev, "Unable to allocate the scsi host\n"); return -ENOMEM; @@ -967,13 +1007,31 @@ usb_stor_dbg(us, "Transport: %s\n", us->transport_name); usb_stor_dbg(us, "Protocol: %s\n", us->protocol_name); + if (us->fflags & US_FL_SCM_MULT_TARG) { + /* + * SCM eUSCSI bridge devices can have different numbers + * of LUNs on different targets; allow all to be probed. + */ + us->max_lun = 7; + /* The eUSCSI itself has ID 7, so avoid scanning that */ + us_to_host(us)->this_id = 7; + /* max_id is 8 initially, so no need to set it here */ + } else { + /* In the normal case there is only a single target */ + us_to_host(us)->max_id = 1; + /* + * Like Windows, we won't store the LUN bits in CDB[1] for + * SCSI-2 devices using the Bulk-Only transport (even though + * this violates the SCSI spec). + */ + if (us->transport == usb_stor_Bulk_transport) + us_to_host(us)->no_scsi2_lun_in_cdb = 1; + } + /* fix for single-lun devices */ if (us->fflags & US_FL_SINGLE_LUN) us->max_lun = 0; - if (!(us->fflags & US_FL_SCM_MULT_TARG)) - us_to_host(us)->max_id = 1; - /* Find the endpoints and calculate pipe values */ result = get_pipes(us); if (result) @@ -1001,6 +1059,10 @@ /* Submit the delayed_work for SCSI-device scanning */ usb_autopm_get_interface_no_resume(us->pusb_intf); +#ifdef CONFIG_AVM_USB_PM + /* == 20170929 AVM/VGJ - the scsi child must be ignored for the device to suspend ==*/ + pm_suspend_ignore_children(&us->pusb_intf->dev, true); +#endif set_bit(US_FLIDX_SCAN_PENDING, &us->dflags); if (delay_use > 0) @@ -1027,6 +1089,8 @@ } EXPORT_SYMBOL_GPL(usb_stor_disconnect); +static struct scsi_host_template usb_stor_host_template; + /* The main probe routine for standard devices */ static int storage_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -1036,6 +1100,29 @@ int result; int size; +#if 1 + /* == 20170809 AVM/VGJ - CHANGESET: STICK_AND_SURF == + * Filter out all AVM (057C) mass storage devices... + */ + { + struct usb_device *udev; + #define AVM_VENDOR_ID 0x057C + udev = interface_to_usbdev(intf); + if (le16_to_cpu(udev->descriptor.idVendor) == AVM_VENDOR_ID) { + printk (KERN_INFO "USB Mass Storage device (%04x:%04x) ignored!\n", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct)); + return -ENODEV; + } + } +#endif + + /* If uas is enabled and this device can do uas then ignore it. */ +#if IS_ENABLED(CONFIG_USB_UAS) + if (uas_use_uas_driver(intf, id, NULL)) + return -ENXIO; +#endif + /* * If the device isn't standard (is handled by a subdriver * module) then don't accept it. @@ -1061,7 +1148,8 @@ id->idVendor, id->idProduct); } - result = usb_stor_probe1(&us, intf, id, unusual_dev); + result = usb_stor_probe1(&us, intf, id, unusual_dev, + &usb_stor_host_template); if (result) return result; @@ -1072,7 +1160,7 @@ } static struct usb_driver usb_storage_driver = { - .name = "usb-storage", + .name = DRV_NAME, .probe = storage_probe, .disconnect = usb_stor_disconnect, .suspend = usb_stor_suspend, @@ -1085,4 +1173,4 @@ .soft_unbind = 1, }; -module_usb_driver(usb_storage_driver); +module_usb_stor_driver(usb_storage_driver, usb_stor_host_template, DRV_NAME);