scsi: introduce a quirk for false cache reporting

Some SATA to USB bridges fail to cooperate with some
drives resulting in no cache being present being reported
to the host. That causes the host to skip sending
a command to synchronize caches. That causes data loss
when the drive is powered down.

Signed-off-by: Oliver Neukum <oneukum@suse.com>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Oliver Neukum 2016-09-12 15:19:41 +02:00 коммит произвёл Greg Kroah-Hartman
Родитель 6406c3d226
Коммит 050bc4e846
5 изменённых файлов: 24 добавлений и 1 удалений

Просмотреть файл

@ -4238,6 +4238,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
u = IGNORE_UAS (don't bind to the uas driver); u = IGNORE_UAS (don't bind to the uas driver);
w = NO_WP_DETECT (don't test whether the w = NO_WP_DETECT (don't test whether the
medium is write-protected). medium is write-protected).
y = ALWAYS_SYNC (issue a SYNCHRONIZE_CACHE
even if the device claims no cache)
Example: quirks=0419:aaf5:rl,0421:0433:rc Example: quirks=0419:aaf5:rl,0421:0433:rc
user_debug= [KNL,ARM] user_debug= [KNL,ARM]

Просмотреть файл

@ -296,6 +296,14 @@ static int slave_configure(struct scsi_device *sdev)
if (us->fflags & US_FL_BROKEN_FUA) if (us->fflags & US_FL_BROKEN_FUA)
sdev->broken_fua = 1; sdev->broken_fua = 1;
/* Some even totally fail to indicate a cache */
if (us->fflags & US_FL_ALWAYS_SYNC) {
/* don't read caching information */
sdev->skip_ms_page_8 = 1;
sdev->skip_ms_page_3f = 1;
/* assume sync is needed */
sdev->wce_default_on = 1;
}
} else { } else {
/* /*

Просмотреть файл

@ -338,6 +338,13 @@ UNUSUAL_DEV( 0x046b, 0xff40, 0x0100, 0x0100,
USB_SC_DEVICE, USB_PR_DEVICE, NULL, USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_NO_WP_DETECT), US_FL_NO_WP_DETECT),
/* Reported by Egbert Eich <eich@suse.com> */
UNUSUAL_DEV( 0x0480, 0xd010, 0x0100, 0x9999,
"Toshiba",
"External USB 3.0",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_ALWAYS_SYNC),
/* Patch submitted by Philipp Friedrich <philipp@void.at> */ /* Patch submitted by Philipp Friedrich <philipp@void.at> */
UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100, UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100,
"Kyocera", "Kyocera",

Просмотреть файл

@ -498,7 +498,8 @@ void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags)
US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16 | 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_NO_ATA_1X | US_FL_NO_REPORT_OPCODES |
US_FL_MAX_SECTORS_240 | US_FL_NO_REPORT_LUNS); US_FL_MAX_SECTORS_240 | US_FL_NO_REPORT_LUNS |
US_FL_ALWAYS_SYNC);
p = quirks; p = quirks;
while (*p) { while (*p) {
@ -581,6 +582,9 @@ void usb_stor_adjust_quirks(struct usb_device *udev, unsigned long *fflags)
case 'w': case 'w':
f |= US_FL_NO_WP_DETECT; f |= US_FL_NO_WP_DETECT;
break; break;
case 'y':
f |= US_FL_ALWAYS_SYNC;
break;
/* Ignore unrecognized flag characters */ /* Ignore unrecognized flag characters */
} }
} }

Просмотреть файл

@ -81,6 +81,8 @@
/* Sets max_sectors to 240 */ \ /* Sets max_sectors to 240 */ \
US_FLAG(NO_REPORT_LUNS, 0x10000000) \ US_FLAG(NO_REPORT_LUNS, 0x10000000) \
/* Cannot handle REPORT_LUNS */ \ /* Cannot handle REPORT_LUNS */ \
US_FLAG(ALWAYS_SYNC, 0x20000000) \
/* lies about caching, so always sync */ \
#define US_FLAG(name, value) US_FL_##name = value , #define US_FLAG(name, value) US_FL_##name = value ,
enum { US_DO_ALL_FLAGS }; enum { US_DO_ALL_FLAGS };