svn commit: r277367 - in stable/8/sys/dev/usb: . quirk storage
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Jan 19 07:16:24 UTC 2015
Author: hselasky
Date: Mon Jan 19 07:16:22 2015
New Revision: 277367
URL: https://svnweb.freebsd.org/changeset/base/277367
Log:
MFC r239237, r242628 and r277044:
- Add the UQ_MSC_NO_PREVENT_ALLOW quirk to handle devices that do not support
the 'PREVENT/ALLOW MEDIUM REMOVAL' SCSI command.
- Improve auto-quirks detection for certain Kingston memory sticks.
- Increase the maximum number of dynamic USB quirks. USB memory stick
devices which don't support the synchronize cache SCSI command are
likely to also not support the prevent-allow medium removal SCSI
command.
Modified:
stable/8/sys/dev/usb/quirk/usb_quirk.c
stable/8/sys/dev/usb/quirk/usb_quirk.h
stable/8/sys/dev/usb/storage/umass.c
stable/8/sys/dev/usb/usb_freebsd.h
stable/8/sys/dev/usb/usb_msctest.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/dev/ (props changed)
stable/8/sys/dev/usb/ (props changed)
Modified: stable/8/sys/dev/usb/quirk/usb_quirk.c
==============================================================================
--- stable/8/sys/dev/usb/quirk/usb_quirk.c Mon Jan 19 07:14:36 2015 (r277366)
+++ stable/8/sys/dev/usb/quirk/usb_quirk.c Mon Jan 19 07:16:22 2015 (r277367)
@@ -397,6 +397,7 @@ static struct usb_quirk_entry usb_quirks
UQ_MSC_FORCE_PROTO_SCSI, UQ_MSC_NO_GETMAXLUN),
USB_QUIRK(SONY, PORTABLE_HDD_V2, 0x0000, 0xffff, UQ_MSC_FORCE_WIRE_BBB,
UQ_MSC_FORCE_PROTO_SCSI),
+ USB_QUIRK(STMICRO, ST72682, 0x0000, 0xffff, UQ_MSC_NO_PREVENT_ALLOW),
USB_QUIRK(SUPERTOP, IDE, 0x0000, 0xffff, UQ_MSC_IGNORE_RESIDUE,
UQ_MSC_NO_SYNC_CACHE),
USB_QUIRK(SUPERTOP, FLASHDRIVE, 0x0000, 0xffff, UQ_MSC_NO_TEST_UNIT_READY,
@@ -523,6 +524,7 @@ static const char *usb_quirk_str[USB_QUI
[UQ_MSC_NO_GETMAXLUN] = "UQ_MSC_NO_GETMAXLUN",
[UQ_MSC_NO_INQUIRY] = "UQ_MSC_NO_INQUIRY",
[UQ_MSC_NO_INQUIRY_EVPD] = "UQ_MSC_NO_INQUIRY_EVPD",
+ [UQ_MSC_NO_PREVENT_ALLOW] = "UQ_MSC_NO_PREVENT_ALLOW",
[UQ_MSC_NO_SYNC_CACHE] = "UQ_MSC_NO_SYNC_CACHE",
[UQ_MSC_SHUTTLE_INIT] = "UQ_MSC_SHUTTLE_INIT",
[UQ_MSC_ALT_IFACE_1] = "UQ_MSC_ALT_IFACE_1",
Modified: stable/8/sys/dev/usb/quirk/usb_quirk.h
==============================================================================
--- stable/8/sys/dev/usb/quirk/usb_quirk.h Mon Jan 19 07:14:36 2015 (r277366)
+++ stable/8/sys/dev/usb/quirk/usb_quirk.h Mon Jan 19 07:16:22 2015 (r277367)
@@ -75,6 +75,7 @@ enum {
UQ_MSC_NO_GETMAXLUN, /* does not support get max LUN */
UQ_MSC_NO_INQUIRY, /* fake generic inq response */
UQ_MSC_NO_INQUIRY_EVPD, /* does not support inq EVPD */
+ UQ_MSC_NO_PREVENT_ALLOW, /* does not support medium removal */
UQ_MSC_NO_SYNC_CACHE, /* does not support sync cache */
UQ_MSC_SHUTTLE_INIT, /* requires Shuttle init sequence */
UQ_MSC_ALT_IFACE_1, /* switch to alternate interface 1 */
Modified: stable/8/sys/dev/usb/storage/umass.c
==============================================================================
--- stable/8/sys/dev/usb/storage/umass.c Mon Jan 19 07:14:36 2015 (r277366)
+++ stable/8/sys/dev/usb/storage/umass.c Mon Jan 19 07:16:22 2015 (r277367)
@@ -371,6 +371,8 @@ typedef uint8_t (umass_transform_t)(stru
* result.
*/
#define NO_SYNCHRONIZE_CACHE 0x4000
+ /* Device does not support 'PREVENT/ALLOW MEDIUM REMOVAL'. */
+#define NO_PREVENT_ALLOW 0x8000
struct umass_softc {
@@ -841,6 +843,8 @@ umass_probe_proto(device_t dev, struct u
quirks |= NO_INQUIRY;
if (usb_test_quirk(uaa, UQ_MSC_NO_INQUIRY_EVPD))
quirks |= NO_INQUIRY_EVPD;
+ if (usb_test_quirk(uaa, UQ_MSC_NO_PREVENT_ALLOW))
+ quirks |= NO_PREVENT_ALLOW;
if (usb_test_quirk(uaa, UQ_MSC_NO_SYNC_CACHE))
quirks |= NO_SYNCHRONIZE_CACHE;
if (usb_test_quirk(uaa, UQ_MSC_SHUTTLE_INIT))
@@ -2376,6 +2380,13 @@ umass_cam_action(struct cam_sim *sim, un
if (sc->sc_quirks & FORCE_SHORT_INQUIRY) {
ccb->csio.dxfer_len = SHORT_INQUIRY_LENGTH;
}
+ } else if (sc->sc_transfer.cmd_data[0] == PREVENT_ALLOW) {
+ if (sc->sc_quirks & NO_PREVENT_ALLOW) {
+ ccb->csio.scsi_status = SCSI_STATUS_OK;
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ xpt_done(ccb);
+ goto done;
+ }
} else if (sc->sc_transfer.cmd_data[0] == SYNCHRONIZE_CACHE) {
if (sc->sc_quirks & NO_SYNCHRONIZE_CACHE) {
ccb->csio.scsi_status = SCSI_STATUS_OK;
Modified: stable/8/sys/dev/usb/usb_freebsd.h
==============================================================================
--- stable/8/sys/dev/usb/usb_freebsd.h Mon Jan 19 07:14:36 2015 (r277366)
+++ stable/8/sys/dev/usb/usb_freebsd.h Mon Jan 19 07:16:22 2015 (r277367)
@@ -63,7 +63,7 @@
#define USB_EP0_BUFSIZE 1024 /* bytes */
#define USB_CS_RESET_LIMIT 20 /* failures = 20 * 50 ms = 1sec */
-#define USB_MAX_AUTO_QUIRK 4 /* maximum number of dynamic quirks */
+#define USB_MAX_AUTO_QUIRK 8 /* maximum number of dynamic quirks */
typedef uint32_t usb_timeout_t; /* milliseconds */
typedef uint32_t usb_frlength_t; /* bytes */
Modified: stable/8/sys/dev/usb/usb_msctest.c
==============================================================================
--- stable/8/sys/dev/usb/usb_msctest.c Mon Jan 19 07:14:36 2015 (r277366)
+++ stable/8/sys/dev/usb/usb_msctest.c Mon Jan 19 07:16:22 2015 (r277367)
@@ -104,6 +104,8 @@ static uint8_t scsi_sync_cache[] = { 0x3
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
@@ -648,7 +650,7 @@ usb_msc_auto_quirk(struct usb_device *ud
}
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);
@@ -677,7 +679,9 @@ usb_msc_auto_quirk(struct usb_device *ud
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);
@@ -687,9 +691,49 @@ usb_msc_auto_quirk(struct usb_device *ud
if (err != ERR_CSW_FAILED)
goto error;
- DPRINTF("Device doesn't handle synchronize cache\n");
+ DPRINTF("Device doesn't handle synchronize cache "
+ "and prevent allow medium removal\n");
usbd_add_dynamic_quirk(udev, UQ_MSC_NO_SYNC_CACHE);
+ usbd_add_dynamic_quirk(udev, UQ_MSC_NO_PREVENT_ALLOW);
+ } 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 nor"
+ "prevent allow medium removal\n");
+
+ usbd_add_dynamic_quirk(udev,
+ UQ_MSC_NO_SYNC_CACHE);
+ usbd_add_dynamic_quirk(udev,
+ UQ_MSC_NO_PREVENT_ALLOW);
+ } else {
+ if (err != ERR_CSW_FAILED)
+ goto error;
+ }
+ }
}
/* clear sense status of any failed commands on the device */
@@ -728,6 +772,7 @@ error:
DPRINTF("Device did not respond, enabling all quirks\n");
usbd_add_dynamic_quirk(udev, UQ_MSC_NO_SYNC_CACHE);
+ usbd_add_dynamic_quirk(udev, UQ_MSC_NO_PREVENT_ALLOW);
usbd_add_dynamic_quirk(udev, UQ_MSC_NO_TEST_UNIT_READY);
/* Need to re-enumerate the device */
More information about the svn-src-stable
mailing list