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 */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to