ChangeSet 1.1722.97.71, 2004/06/14 10:33:05-07:00, mdharm-usb@one-eyed-alien.net [PATCH] USB Storage: INQUIRY fixup, mode-sense options, Genesys devices This patch does a few things (all in the same section of code). It started life as patches as226b, as280, and as275. Later it was merged into as226e and I added significantly to it. First, this patch introduces a new config option to allow people to enable write-protect detection for their USB devices. With some luck, we've finally got it right and can eventually remove this option in favor of enabling this behavior all the time. Next, we change how we force some flags on -- it turns out that there are some 'generic' entries in the SCSI devinfo which was overriding us when we didn't want it. Finally, we add a safety check to the workaround for GeneSys Logic devices -- if the max_sectors parameter has already been turned down, we won't turn it up. Signed-off-by: Greg Kroah-Hartman drivers/usb/storage/Kconfig | 22 +++++++++++++++++ drivers/usb/storage/scsiglue.c | 52 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 68 insertions(+), 6 deletions(-) diff -Nru a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig --- a/drivers/usb/storage/Kconfig Fri Jun 18 10:54:22 2004 +++ b/drivers/usb/storage/Kconfig Fri Jun 18 10:54:22 2004 @@ -23,6 +23,28 @@ Say Y here in order to have the USB Mass Storage code generate verbose debugging messages. +config USB_STORAGE_RW_DETECT + bool "USB Mass Storage Write-Protected Media Detection (EXPERIMENTAL)" + depends on USB_STORAGE && EXPERIMENTAL + help + Say Y here in order to have the USB Mass Storage code indicate to + the SCSI layer that using MODE SENSE(6) and MODE SENSE(10) to + determine if the media is write-protected is a good thing to do. + + Many devices have historically had trouble with these commands, + hence the default 2.6.x behavior has been to suppress their use. + 2.4.x used these commands with (at best) mixed results, often + crashing the firmware of the device. However, the SCSI layer now + issues these commands in a manner more consistent with other + "popular" OSes, in an attempt to improve compatibility. + + Saying Y here allows these commands to be sent to a USB device. + If you find a device this doesn't work for, switch to N and let + us know at usb-storage@lists.one-eyed-alien.net + + If you say N here, the kernel will assume that all disk-like USB + devices are write-enabled. + config USB_STORAGE_DATAFAB bool "Datafab Compact Flash Reader support (EXPERIMENTAL)" depends on USB_STORAGE && EXPERIMENTAL diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c --- a/drivers/usb/storage/scsiglue.c Fri Jun 18 10:54:22 2004 +++ b/drivers/usb/storage/scsiglue.c Fri Jun 18 10:54:22 2004 @@ -48,13 +48,13 @@ #include "usb.h" #include "debug.h" #include "transport.h" +#include "protocol.h" #include #include #include #include - /*********************************************************************** * Host functions ***********************************************************************/ @@ -68,10 +68,13 @@ { /* * Set default bflags. These can be overridden for individual - * models and vendors via the scsi devinfo mechanism. + * models and vendors via the scsi devinfo mechanism. The only + * flag we need is to force 36-byte INQUIRYs; we don't use any + * of the extra data and many devices choke if asked for more or + * less than 36 bytes. */ - sdev->sdev_bflags = (BLIST_MS_SKIP_PAGE_08 | BLIST_MS_SKIP_PAGE_3F | - BLIST_USE_10_BYTE_MS); + sdev->sdev_bflags = BLIST_INQUIRY_36; + return 0; } @@ -95,11 +98,48 @@ * reduce the maximum transfer size to 64 KB = 128 sectors. */ #define USB_VENDOR_ID_GENESYS 0x05e3 // Needs a standard location + if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS && - us->pusb_dev->speed == USB_SPEED_HIGH) + us->pusb_dev->speed == USB_SPEED_HIGH && + sdev->request_queue->max_sectors > 128) blk_queue_max_sectors(sdev->request_queue, 128); - /* this is to satisify the compiler, tho I don't think the + /* We can't put these settings in slave_alloc() because that gets + * called before the device type is known. Consequently these + * settings can't be overridden via the scsi devinfo mechanism. */ + if (sdev->type == TYPE_DISK) { + + /* Disk-type devices use MODE SENSE(6) if the protocol + * (SubClass) is Transparent SCSI, otherwise they use + * MODE SENSE(10). */ + if (us->subclass != US_SC_SCSI) + sdev->use_10_for_ms = 1; + + /* Many disks only accept MODE SENSE transfer lengths of + * 192 bytes (that's what Windows uses). */ + sdev->use_192_bytes_for_3f = 1; + + /* A number of devices have problems with MODE SENSE for + * page x08, so we will skip it. */ + sdev->skip_ms_page_8 = 1; + +#ifndef CONFIG_USB_STORAGE_RW_DETECT + /* Some devices may not like MODE SENSE with page=0x3f. + * Now that we're using 192-byte transfers this may no + * longer be a problem. So this will be a configuration + * option. */ + sdev->skip_ms_page_3f = 1; +#endif + + } else { + + /* Non-disk-type devices don't need to blacklist any pages + * or to force 192-byte transfer lengths for MODE SENSE. + * But they do need to use MODE SENSE(10). */ + sdev->use_10_for_ms = 1; + } + + /* this is to satisfy the compiler, tho I don't think the * return code is ever checked anywhere. */ return 0; }