diff options
author | Oliver Neukum <oneukum@suse.de> | 2007-02-08 09:04:48 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-02-16 15:32:19 -0800 |
commit | 61bf54b71d5abf767ee46284be19965d7253ddbf (patch) | |
tree | 04bda12e495bc19be2712dff9da35f5e3271691a /drivers | |
parent | 5b06470816fb5e658e81db2a55b530ff2ba711c9 (diff) | |
download | blackbird-obmc-linux-61bf54b71d5abf767ee46284be19965d7253ddbf.tar.gz blackbird-obmc-linux-61bf54b71d5abf767ee46284be19965d7253ddbf.zip |
USB Storage: indistinguishable devices with broken and unbroken firmware
there's a USB mass storage device which exists in two version. One
reports the correct size and the other does not. Apart from that they
are identical and cannot be told apart. Here's a heuristic based on the
empirical finding that drives have even sizes.
Signed-off-by: Oliver Neukum <oneukum@suse.de>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/sd.c | 11 | ||||
-rw-r--r-- | drivers/usb/storage/scsiglue.c | 6 | ||||
-rw-r--r-- | drivers/usb/storage/unusual_devs.h | 2 |
3 files changed, 17 insertions, 2 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 3f048bd6326d..5a8f55fea5ff 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1269,9 +1269,18 @@ repeat: /* Some devices return the total number of sectors, not the * highest sector number. Make the necessary adjustment. */ - if (sdp->fix_capacity) + if (sdp->fix_capacity) { --sdkp->capacity; + /* Some devices have version which report the correct sizes + * and others which do not. We guess size according to a heuristic + * and err on the side of lowering the capacity. */ + } else { + if (sdp->guess_capacity) + if (sdkp->capacity & 0x01) /* odd sizes are odd */ + --sdkp->capacity; + } + got_data: if (sector_size == 0) { sector_size = 512; diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 70234f5dbeeb..e227f64d5641 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -153,6 +153,12 @@ static int slave_configure(struct scsi_device *sdev) if (us->flags & US_FL_FIX_CAPACITY) sdev->fix_capacity = 1; + /* A few disks have two indistinguishable version, one of + * which reports the correct capacity and the other does not. + * The sd driver has to guess which is the case. */ + if (us->flags & US_FL_CAPACITY_HEURISTICS) + sdev->guess_capacity = 1; + /* Some devices report a SCSI revision level above 2 but are * unable to handle the REPORT LUNS command (for which * support is mandatory at level 3). Since we already have diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index bab054b8d94f..568366569769 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1434,7 +1434,7 @@ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, "DataStor", "USB4500 FW1.04", US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), + US_FL_CAPACITY_HEURISTICS), /* Control/Bulk transport for all SubClass values */ USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), |