The Intel Value SSD has a bug where it will lock solid if it encounters a delay between the command and data phases of the usb bulk storage transactions. This bug is easily reproduced by adding a 2.5sec delay just before the comment labelled DATA STAGE in drivers/usb/storage/transport.c in usb_stor_Bulk_transport(). We can't really guarantee to not hit this bug, but if we decrease our nice level, we may be somewhat less likely to see this already rare issue surface. Add another flag to the unusual_devs that signals that we should boost our priority and do that for the troublesome device. RFC as I don't really know if the increased priority has other bad effects -- looking for comments on that. Also, I'm not really sure if one little device deserves a new flag esp as it only decreases the chances of hitting the bug... Signed-off-by: Arthur Jones <ajones@xxxxxxxxxxxx> --- drivers/usb/storage/unusual_devs.h | 6 ++++++ drivers/usb/storage/usb.c | 17 +++++++++++++++++ include/linux/usb_usual.h | 4 +++- 3 files changed, 26 insertions(+), 1 deletions(-) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 64a0a2c..67963e3 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1846,6 +1846,12 @@ UNUSUAL_DEV( 0x4146, 0xba01, 0x0100, 0x0100, "Micro Mini 1GB", US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), +/* Arthur Jones <ajones@xxxxxxxxxxxx> */ +UNUSUAL_DEV( 0x8086, 0xf1a5, 0x0200, 0x0200, + "Intel", + "Value SSD", + US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NO_CMD_DELAY ), + /* Reported by Andrew Simmons <andrew.simmons@xxxxxxxxx> */ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, "DataStor", diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 5a53d4f..7a54753 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -266,6 +266,16 @@ static int usb_stor_control_thread(void * __us) struct us_data *us = (struct us_data *)__us; struct Scsi_Host *host = us_to_host(us); + /* + * Intel Value SSD can lock solid if there + * is a delay between command and data + * phase -- sort of the opposite of US_FL_GO_SLOW. + * Try boosting our priority a bit in the hopes + * of making the delays less likely... + */ + if (us->fflags & US_FL_NO_CMD_DELAY) + set_user_nice(current, -10); + for(;;) { US_DEBUGP("*** thread sleeping.\n"); if (wait_for_completion_interruptible(&us->cmnd_ready)) @@ -534,6 +544,13 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id, if (dev->speed != USB_SPEED_HIGH) us->fflags &= ~US_FL_GO_SLOW; + /* Hmmm - not sure who should win here... */ + if ((us->fflags & (US_FL_GO_SLOW | US_FL_NO_CMD_DELAY)) == + (US_FL_GO_SLOW | US_FL_NO_CMD_DELAY)) { + printk(KERN_INFO USB_STORAGE "incompatible device flags."); + us->fflags &= ~US_FL_NO_CMD_DELAY; + } + /* Log a message if a non-generic unusual_dev entry contains an * unnecessary subclass or protocol override. This may stimulate * reports from users that will help us remove unneeded entries diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h index a4b947e..883fd1e 100644 --- a/include/linux/usb_usual.h +++ b/include/linux/usb_usual.h @@ -58,7 +58,9 @@ US_FLAG(CAPACITY_OK, 0x00010000) \ /* READ CAPACITY response is correct */ \ US_FLAG(BAD_SENSE, 0x00020000) \ - /* Bad Sense (never more than 18 bytes) */ + /* Bad Sense (never more than 18 bytes) */ \ + US_FLAG(NO_CMD_DELAY, 0x00040000) \ + /* Try not to delay after command phase */ #define US_FLAG(name, value) US_FL_##name = value , enum { US_DO_ALL_FLAGS }; -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html