Some USB mass-storage devices claim to have a write-back cache but don't support the SYNCHRONIZE CACHE command, which means there is no way to tell these devices to flush their caches out to permanent storage. Unfortunately, there is nothing we can do about this. Until recently this deficiency did not cause any noticeable problems. But following commit 89fb4cd1f717 ("scsi: handle flush errors properly"), the errors are propagated to userspace where they get reported as failures. As a workaround, this patch adds a quirks flag for these devices to the usb-storage driver, and a corresponding SCSI device flag, to indicate the device can't handle SYNCHRONIZE CACHE. If the flag is set, the sd driver will override the cache settings reported by the device, so that the device appears to be write-through. This will prevent the unsupported command from being sent. This addresses Bugzilla #89511. Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> Reported-by: Jun Itou <itou_jun@xxxxxxxxxxx> Reported-by: Markus Rathgeb <maggu2810@xxxxxxxxx> Reported-by: Matt <vickm78@xxxxxxxxxxx> Tested-by: Markus Rathgeb <maggu2810@xxxxxxxxx> Tested-by: Matt <vickm78@xxxxxxxxxxx> Fixes: 89fb4cd1f717a871ef79fa7debbe840e3225cd54 CC: James Bottomley <JBottomley@xxxxxxxxxxxxx> CC: <stable@xxxxxxxxxxxxxxx> --- As far as I'm concerned, this can be merged by either Greg or James (once the current merge window is over, of course). Alan Stern [as1779] drivers/scsi/sd.c | 7 +++++++ drivers/usb/storage/scsiglue.c | 4 ++++ drivers/usb/storage/unusual_devs.h | 21 +++++++++++++++++++++ include/linux/usb_usual.h | 2 ++ include/scsi/scsi_device.h | 1 + 5 files changed, 35 insertions(+) Index: usb-4.0/include/scsi/scsi_device.h =================================================================== --- usb-4.0.orig/include/scsi/scsi_device.h +++ usb-4.0/include/scsi/scsi_device.h @@ -174,6 +174,7 @@ struct scsi_device { unsigned no_dif:1; /* T10 PI (DIF) should be disabled */ unsigned broken_fua:1; /* Don't set FUA bit */ unsigned lun_in_cdb:1; /* Store LUN bits in CDB[1] */ + unsigned broken_synch_cache:1; /* SYNCHRONIZE_CACHE is broken */ atomic_t disk_events_disable_depth; /* disable depth for disk events */ Index: usb-4.0/drivers/scsi/sd.c =================================================================== --- usb-4.0.orig/drivers/scsi/sd.c +++ usb-4.0/drivers/scsi/sd.c @@ -2929,6 +2929,13 @@ static void sd_probe_async(void *data, a sdkp->first_scan = 1; sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS; + /* + * Some buggy USB bridges don't implement SYNCHRONIZE_CACHE + * but still claim to be write-back. Override them. + */ + if (sdp->broken_synch_cache) + sdkp->cache_override = 1; + sd_revalidate_disk(gd); gd->driverfs_dev = &sdp->sdev_gendev; Index: usb-4.0/include/linux/usb_usual.h =================================================================== --- usb-4.0.orig/include/linux/usb_usual.h +++ usb-4.0/include/linux/usb_usual.h @@ -79,6 +79,8 @@ /* Cannot handle MI_REPORT_SUPPORTED_OPERATION_CODES */ \ US_FLAG(MAX_SECTORS_240, 0x08000000) \ /* Sets max_sectors to 240 */ \ + US_FLAG(NO_SYNCHRONIZE_CACHE, 0x10000000) \ + /* Cannot handle SYNCHRONIZE CACHE */ \ #define US_FLAG(name, value) US_FL_##name = value , enum { US_DO_ALL_FLAGS }; Index: usb-4.0/drivers/usb/storage/scsiglue.c =================================================================== --- usb-4.0.orig/drivers/usb/storage/scsiglue.c +++ usb-4.0/drivers/usb/storage/scsiglue.c @@ -260,6 +260,10 @@ static int slave_configure(struct scsi_d if (us->fflags & US_FL_BROKEN_FUA) sdev->broken_fua = 1; + /* Likewise for SYNCHRONIZE CACHE */ + if (us->fflags & US_FL_NO_SYNCHRONIZE_CACHE) + sdev->broken_synch_cache = 1; + } else { /* Non-disk-type devices don't need to blacklist any pages Index: usb-4.0/drivers/usb/storage/unusual_devs.h =================================================================== --- usb-4.0.orig/drivers/usb/storage/unusual_devs.h +++ usb-4.0/drivers/usb/storage/unusual_devs.h @@ -392,6 +392,13 @@ UNUSUAL_DEV( 0x04b8, 0x0602, 0x0110, 0x "785EPX Storage", USB_SC_SCSI, USB_PR_BULK, NULL, US_FL_SINGLE_LUN), +/* Reported by Jun Itou <itou_jun@xxxxxxxxxxx> */ +UNUSUAL_DEV( 0x04bb, 0x0109, 0x0100, 0x0100, + "I-O DATA DEVICE INC.", + "I-O DATA HDZ-UES", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_SYNCHRONIZE_CACHE), + /* Not sure who reported this originally but * Pavel Machek <pavel@xxxxxx> reported that the extra US_FL_SINGLE_LUN * flag be added */ @@ -409,6 +416,13 @@ UNUSUAL_DEV( 0x04ce, 0x0002, 0x026c, 0x USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_FIX_CAPACITY), +/* Reported by Markus Rathgeb <maggu2810@xxxxxxxxx> */ +UNUSUAL_DEV( 0x04cf, 0x8818, 0xb007, 0xb007, + "Myson Century, Inc.", + "USB Mass Storage Device", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_SYNCHRONIZE_CACHE), + /* Reported by Kriston Fincher <kriston@xxxxxxxxxxx> * Patch submitted by Sean Millichamp <sean@xxxxxxxxxxx> * This is to support the Panasonic PalmCam PV-SD4090 @@ -1372,6 +1386,13 @@ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0 USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_SANE_SENSE ), +/* Reported by matt <vickm78@xxxxxxxxxxx> */ +UNUSUAL_DEV( 0x0bc2, 0x3332, 0x0012, 0x0012, + "Seagate", + "External", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_SYNCHRONIZE_CACHE), + UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, "Maxtor", "USB to SATA", -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in