--- zzzz-none-000/linux-3.10.107/drivers/usb/storage/scsiglue.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/usb/storage/scsiglue.c 2021-02-04 17:41:59.000000000 +0000 @@ -241,7 +241,7 @@ /* Some USB cardreaders have trouble reading an sdcard's last * sector in a larger then 1 sector read, since the performance - * impact is negible we set this flag for all USB disks */ + * impact is negligible we set this flag for all USB disks */ sdev->last_sector_bug = 1; /* Enable last-sector hacks for single-target devices using @@ -256,6 +256,10 @@ if (us->fflags & US_FL_WRITE_CACHE) sdev->wce_default_on = 1; + /* A few buggy USB-ATA bridges don't understand FUA */ + if (us->fflags & US_FL_BROKEN_FUA) + sdev->broken_fua = 1; + } else { /* Non-disk-type devices don't need to blacklist any pages @@ -452,17 +456,13 @@ return length; } -/* we use this macro to help us write into the buffer */ -#undef SPRINTF -#define SPRINTF(args...) seq_printf(m, ## args) - static int show_info (struct seq_file *m, struct Scsi_Host *host) { struct us_data *us = host_to_us(host); const char *string; /* print the controller name */ - SPRINTF(" Host scsi%d: usb-storage\n", host->host_no); + seq_printf(m, " Host scsi%d: usb-storage\n", host->host_no); /* print product, vendor, and serial number strings */ if (us->pusb_dev->manufacturer) @@ -471,26 +471,26 @@ string = us->unusual_dev->vendorName; else string = "Unknown"; - SPRINTF(" Vendor: %s\n", string); + seq_printf(m, " Vendor: %s\n", string); if (us->pusb_dev->product) string = us->pusb_dev->product; else if (us->unusual_dev->productName) string = us->unusual_dev->productName; else string = "Unknown"; - SPRINTF(" Product: %s\n", string); + seq_printf(m, " Product: %s\n", string); if (us->pusb_dev->serial) string = us->pusb_dev->serial; else string = "None"; - SPRINTF("Serial Number: %s\n", string); + seq_printf(m, "Serial Number: %s\n", string); /* show the protocol and transport */ - SPRINTF(" Protocol: %s\n", us->protocol_name); - SPRINTF(" Transport: %s\n", us->transport_name); + seq_printf(m, " Protocol: %s\n", us->protocol_name); + seq_printf(m, " Transport: %s\n", us->transport_name); /* show the device flags */ - SPRINTF(" Quirks:"); + seq_printf(m, " Quirks:"); #define US_FLAG(name, value) \ if (us->fflags & value) seq_printf(m, " " #name); @@ -505,7 +505,7 @@ ***********************************************************************/ /* Output routine for the sysfs max_sectors file */ -static ssize_t show_max_sectors(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t max_sectors_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_device *sdev = to_scsi_device(dev); @@ -513,7 +513,7 @@ } /* Input routine for the sysfs max_sectors file */ -static ssize_t store_max_sectors(struct device *dev, struct device_attribute *attr, const char *buf, +static ssize_t max_sectors_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct scsi_device *sdev = to_scsi_device(dev); @@ -523,22 +523,49 @@ blk_queue_max_hw_sectors(sdev->request_queue, ms); return count; } - return -EINVAL; + return -EINVAL; +} +static DEVICE_ATTR_RW(max_sectors); + +#if defined (CONFIG_AVM_USB_PM) +/* Output routine for the sysfs max_spinup_ms file */ +static ssize_t max_spinup_ms_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct us_data *us = host_to_us(dev_to_shost(dev)); + + return sprintf(buf, "%u\n", us->max_spinup_ms); +} + +/* Input routine for the sysfs max_sectors file */ +static ssize_t max_spinup_ms_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + struct us_data *us = host_to_us(dev_to_shost(dev)); + unsigned int ms; + + if (sscanf(buf, "%u", &ms) > 0) { + us->max_spinup_ms = ms; + return count; + } + return -EINVAL; } -static DEVICE_ATTR(max_sectors, S_IRUGO | S_IWUSR, show_max_sectors, - store_max_sectors); +static DEVICE_ATTR_RW(max_spinup_ms); +#endif static struct device_attribute *sysfs_device_attr_list[] = { - &dev_attr_max_sectors, - NULL, - }; + &dev_attr_max_sectors, +#if defined (CONFIG_AVM_USB_PM) + &dev_attr_max_spinup_ms, +#endif + NULL, +}; /* * this defines our host template, with which we'll allocate hosts */ -struct scsi_host_template usb_stor_host_template = { +static const struct scsi_host_template usb_stor_host_template = { /* basic userland interface stuff */ .name = "usb-storage", .proc_name = "usb-storage", @@ -556,7 +583,6 @@ /* queue commands only, only one command per LUN */ .can_queue = 1, - .cmd_per_lun = 1, /* unknown initiator id */ .this_id = -1, @@ -568,8 +594,14 @@ /* lots of sg segments can be handled */ .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, +#if 1 + /* == AVM/VGJ 20160725 - Transfer speed optimization == */ + /* limit the total size of a transfer to 512 KB to reduce USB irqs */ + .max_sectors = 1024, +#else /* limit the total size of a transfer to 120 KB */ .max_sectors = 240, +#endif /* merge commands... this seems to help performance, but * periodically someone should test to see which setting is more @@ -590,6 +622,16 @@ .module = THIS_MODULE }; +void usb_stor_host_template_init(struct scsi_host_template *sht, + const char *name, struct module *owner) +{ + *sht = usb_stor_host_template; + sht->name = name; + sht->proc_name = name; + sht->module = owner; +} +EXPORT_SYMBOL_GPL(usb_stor_host_template_init); + /* To Report "Illegal Request: Invalid Field in CDB */ unsigned char usb_stor_sense_invalidCDB[18] = { [0] = 0x70, /* current error */