indistinguishable devices with broken and unbroken firmware
Subsystems (3)
PATCH 1/1 indistinguishable devices with broken and unbroken firmware
Hi,
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. I know it's ugly, but it fixes an ugly bug.
Regards
Oliver
----
drivers/usb/storage/unusual_devs.h +1 -1
@@ -1430,7 +1430,7 @@ "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),
drivers/usb/storage/scsiglue.c +6 -0
@@ -170,6 +170,12 @@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
drivers/scsi/sd.c +7 -0
@@ -1273,6 +1273,13 @@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. */ +if (sdp->guess_capacity) +if (sdkp->capacity &0x01 )/* odd sizes are odd */ + --sdkp->capacity; + got_data:if (sector_size ==0 ) { sector_size =512 ;
include/linux/usb_usual.h +3 -1
@@ -46,7 +46,9 @@US_FLAG (MAX_SECTORS_64 ,0x00000400 ) \ /* Sets max_sectors to 64 */ \US_FLAG (IGNORE_DEVICE ,0x00000800 ) \ - /* Don't claim device */ + /* Don't claim device */ \ +US_FLAG (CAPACITY_HEURISTICS ,0x00001000 ) \ + /* sometimes sizes is too big */#define US_FLAG (name, value) US_FL_##name = value ,enum {US_DO_ALL_FLAGS };
include/scsi/scsi_device.h +1 -0
@@ -122,6 +122,7 @@ unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ unsigned select_no_atn:1; unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */ + unsigned guess_capacity:1; /* READ_CAPACITY might be too high by 1 */ unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */unsigned int device_blocked;/* Device returned QUEUE_FULL. */
Quoted 7 lines · Oliver Neukum
Hi,
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. I know it's ugly, but it fixes an ugly bug.
Do we really need a second flag? Alternatively fix_capacity could be changed to mean fix size if odd.
Am Mittwoch, 7. Februar 2007 16:05 schrieb Christoph Hellwig:
Quoted 11 lines · Oliver Neukum
Quoted 7 lines
Hi,
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. I know it's ugly, but it fixes an ugly bug.
Do we really need a second flag? Alternatively
fix_capacitycould be changed to mean fix size if odd.
Until we learn about devices which really do have an odd number of sectors. And then we'll have a problem. I'd like to avoid heuristics when we know for sure.
Regards
Oliver
Alan Stern
maintainerQuoted 10 lines · Oliver Neukum
Am Mittwoch, 7. Februar 2007 16:05 schrieb Christoph Hellwig:
Quoted 9 lines · Oliver Neukum
Quoted 7 lines
Hi,
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. I know it's ugly, but it fixes an ugly bug.
Quoted 6 lines
Quoted 2 lines
Do we really need a second flag? Alternatively
fix_capacitycould be changed to mean fix size if odd.Until we learn about devices which really do have an odd number of sectors. And then we'll have a problem. I'd like to avoid heuristics when we know for sure.
In fact there are devices which have an odd number of sectors. I once thought that would be a good heuristic to apply to all devices, but it won't work.
Alan Stern
Alan Stern
maintainerdrivers/scsi/sd.c line 1281
Quoted 12 lines · Oliver Neukum
drivers/scsi/sd.c +6
-0@@ -1273,6 +1273,13 @@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. */ +if (sdp->guess_capacity) +if (sdkp->capacity &0x01 )/* odd sizes are odd */ + --sdkp->capacity;
Please make this "else if ...". Just in case somebody ever manages to set both sdp->fix_capacity and sdp->guess_capacity.
Otherwise it looks reasonable to me.
Alan Stern