summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2012-08-13 18:00:34 +0000
committerhselasky <hselasky@FreeBSD.org>2012-08-13 18:00:34 +0000
commit17fe66b571ab4c2502984f2ec0a4f4e0a4b2fb4e (patch)
tree969c6c78b2202d33a8f2a5ce878c2cbf260399d4
parent5cc57da5bdc9726742de94e3af6857522acf2d5b (diff)
downloadFreeBSD-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.c42
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 */
OpenPOWER on IntegriCloud