diff options
author | hselasky <hselasky@FreeBSD.org> | 2012-08-13 18:00:34 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2012-08-13 18:00:34 +0000 |
commit | 17fe66b571ab4c2502984f2ec0a4f4e0a4b2fb4e (patch) | |
tree | 969c6c78b2202d33a8f2a5ce878c2cbf260399d4 | |
parent | 5cc57da5bdc9726742de94e3af6857522acf2d5b (diff) | |
download | FreeBSD-src-17fe66b571ab4c2502984f2ec0a4f4e0a4b2fb4e.zip FreeBSD-src-17fe66b571ab4c2502984f2ec0a4f4e0a4b2fb4e.tar.gz |
Improve auto-quirks detection for certain Kingston memory sticks.
MFC after: 2 weeks
-rw-r--r-- | sys/dev/usb/usb_msctest.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/sys/dev/usb/usb_msctest.c b/sys/dev/usb/usb_msctest.c index 9952264..eb90fda 100644 --- a/sys/dev/usb/usb_msctest.c +++ b/sys/dev/usb/usb_msctest.c @@ -103,6 +103,8 @@ static uint8_t scsi_sync_cache[] = { 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static uint8_t scsi_request_sense[] = { 0x03, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t scsi_read_capacity[] = { 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; #define BULK_SIZE 64 /* dummy */ #define ERR_CSW_FAILED -1 @@ -652,7 +654,7 @@ usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index) } is_no_direct = 1; - for (timeout = 4; timeout; timeout--) { + for (timeout = 4; timeout != 0; timeout--) { err = bbb_command_start(sc, DIR_IN, 0, sc->buffer, SCSI_INQ_LEN, &scsi_inquiry, sizeof(scsi_inquiry), USB_MS_HZ); @@ -681,7 +683,9 @@ usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index) if (err != ERR_CSW_FAILED) goto error; } + timeout = 1; +retry_sync_cache: err = bbb_command_start(sc, DIR_IN, 0, NULL, 0, &scsi_sync_cache, sizeof(scsi_sync_cache), USB_MS_HZ); @@ -694,6 +698,42 @@ usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index) DPRINTF("Device doesn't handle synchronize cache\n"); usbd_add_dynamic_quirk(udev, UQ_MSC_NO_SYNC_CACHE); + + } else { + + /* + * Certain Kingston memory sticks fail the first + * read capacity after a synchronize cache command + * has been issued. Disable the synchronize cache + * command for such devices. + */ + + err = bbb_command_start(sc, DIR_IN, 0, sc->buffer, 8, + &scsi_read_capacity, sizeof(scsi_read_capacity), + USB_MS_HZ); + + if (err != 0) { + if (err != ERR_CSW_FAILED) + goto error; + + err = bbb_command_start(sc, DIR_IN, 0, sc->buffer, 8, + &scsi_read_capacity, sizeof(scsi_read_capacity), + USB_MS_HZ); + + if (err == 0) { + if (timeout--) + goto retry_sync_cache; + + DPRINTF("Device most likely doesn't " + "handle synchronize cache\n"); + + usbd_add_dynamic_quirk(udev, + UQ_MSC_NO_SYNC_CACHE); + } else { + if (err != ERR_CSW_FAILED) + goto error; + } + } } /* clear sense status of any failed commands on the device */ |