Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107159376
D30919.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D30919.diff
View Options
diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c
--- a/sys/dev/usb/storage/umass.c
+++ b/sys/dev/usb/storage/umass.c
@@ -2294,6 +2294,13 @@
xpt_done(ccb);
goto done;
}
+ } else if (sc->sc_transfer.cmd_data[0] == START_STOP_UNIT) {
+ if (sc->sc_quirks & NO_START_STOP) {
+ ccb->csio.scsi_status = SCSI_STATUS_OK;
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ xpt_done(ccb);
+ goto done;
+ }
}
umass_command_start(sc, dir, ccb->csio.data_ptr,
ccb->csio.dxfer_len,
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -2047,13 +2047,16 @@
}
#if USB_HAVE_MSCTEST
if (set_config_failed == 0 && config_index == 0 &&
+ usb_test_quirk(&uaa, UQ_MSC_NO_START_STOP) == 0 &&
+ usb_test_quirk(&uaa, UQ_MSC_NO_PREVENT_ALLOW) == 0 &&
usb_test_quirk(&uaa, UQ_MSC_NO_SYNC_CACHE) == 0 &&
+ usb_test_quirk(&uaa, UQ_MSC_NO_TEST_UNIT_READY) == 0 &&
usb_test_quirk(&uaa, UQ_MSC_NO_GETMAXLUN) == 0) {
/*
* Try to figure out if there are any MSC quirks we
* should apply automatically:
*/
- err = usb_msc_auto_quirk(udev, 0);
+ err = usb_msc_auto_quirk(udev, 0, &uaa);
if (err != 0) {
set_config_failed = 1;
diff --git a/sys/dev/usb/usb_msctest.h b/sys/dev/usb/usb_msctest.h
--- a/sys/dev/usb/usb_msctest.h
+++ b/sys/dev/usb/usb_msctest.h
@@ -2,7 +2,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
+ * Copyright (c) 2008-2022 Hans Petter Selasky.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -44,7 +44,7 @@
usb_error_t usb_msc_eject(struct usb_device *udev,
uint8_t iface_index, int method);
usb_error_t usb_msc_auto_quirk(struct usb_device *udev,
- uint8_t iface_index);
+ uint8_t iface_index, const struct usb_attach_arg *uaa);
usb_error_t usb_msc_read_10(struct usb_device *udev,
uint8_t iface_index, uint32_t lba, uint32_t blocks,
void *buffer);
diff --git a/sys/dev/usb/usb_msctest.c b/sys/dev/usb/usb_msctest.c
--- a/sys/dev/usb/usb_msctest.c
+++ b/sys/dev/usb/usb_msctest.c
@@ -2,7 +2,8 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
- * Copyright (c) 2008,2011 Hans Petter Selasky. All rights reserved.
+ * Copyright (c) 2008-2022 Hans Petter Selasky.
+ * Copyright (c) 2021-2022 Idwer Vollering.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,9 +30,6 @@
/*
* The following file contains code that will detect USB autoinstall
* disks.
- *
- * TODO: Potentially we could add code to automatically detect USB
- * mass storage quirks for not supported SCSI commands!
*/
#ifdef USB_GLOBAL_INCLUDE_FILE
@@ -97,7 +95,8 @@
static uint8_t scsi_test_unit_ready[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static uint8_t scsi_inquiry[] = { 0x12, 0x00, 0x00, 0x00, SCSI_INQ_LEN, 0x00 };
static uint8_t scsi_rezero_init[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static uint8_t scsi_start_stop_unit[] = { 0x1b, 0x00, 0x00, 0x00, 0x02, 0x00 };
+static uint8_t scsi_start_unit[] = { 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00 };
+static uint8_t scsi_stop_unit[] = { 0x1b, 0x00, 0x00, 0x00, 0x02, 0x00 };
static uint8_t scsi_ztestor_eject[] = { 0x85, 0x01, 0x01, 0x01, 0x18, 0x01,
0x01, 0x01, 0x01, 0x01, 0x00, 0x00 };
static uint8_t scsi_cmotech_eject[] = { 0xff, 0x52, 0x44, 0x45, 0x56, 0x43,
@@ -759,28 +758,49 @@
return (buf);
}
+#define USB_ADD_QUIRK(udev, any, which) do { \
+ if (usb_get_manufacturer(udev) != NULL && usb_get_product(udev) != NULL) { \
+ DPRINTFN(0, #which " set for USB mass storage device %s %s (0x%04x:0x%04x)\n", \
+ usb_get_manufacturer(udev), \
+ usb_get_product(udev), \
+ UGETW(udev->ddesc.idVendor), \
+ UGETW(udev->ddesc.idProduct)); \
+ } else { \
+ DPRINTFN(0, #which " set for USB mass storage device, 0x%04x:0x%04x\n", \
+ UGETW(udev->ddesc.idVendor), \
+ UGETW(udev->ddesc.idProduct)); \
+ } \
+ usbd_add_dynamic_quirk(udev, which); \
+ any = 1; \
+} while (0)
+
usb_error_t
-usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index)
+usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index,
+ const struct usb_attach_arg *uaa)
{
struct bbb_transfer *sc;
uint8_t timeout;
uint8_t is_no_direct;
uint8_t sid_type;
+ uint8_t any_quirk;
int err;
sc = bbb_attach(udev, iface_index, UICLASS_MASS);
if (sc == NULL)
return (0);
+ any_quirk = 0;
+
/*
* Some devices need a delay after that the configuration
* value is set to function properly:
*/
usb_pause_mtx(NULL, hz);
- if (usb_msc_get_max_lun(udev, iface_index) == 0) {
+ if (usb_test_quirk(uaa, UQ_MSC_NO_GETMAXLUN) == 0 &&
+ usb_msc_get_max_lun(udev, iface_index) == 0) {
DPRINTF("Device has only got one LUN.\n");
- usbd_add_dynamic_quirk(udev, UQ_MSC_NO_GETMAXLUN);
+ USB_ADD_QUIRK(udev, any_quirk, UQ_MSC_NO_GETMAXLUN);
}
is_no_direct = 1;
@@ -807,37 +827,40 @@
goto done;
}
- err = bbb_command_start(sc, DIR_IN, 0, NULL, 0,
- &scsi_test_unit_ready, sizeof(scsi_test_unit_ready),
- USB_MS_HZ);
+ if (usb_test_quirk(uaa, UQ_MSC_NO_TEST_UNIT_READY) == 0) {
+ err = bbb_command_start(sc, DIR_NONE, 0, NULL, 0,
+ &scsi_test_unit_ready, sizeof(scsi_test_unit_ready),
+ USB_MS_HZ);
- if (err != 0) {
- if (err != ERR_CSW_FAILED)
- goto error;
- DPRINTF("Test unit ready failed\n");
+ if (err != 0) {
+ if (err != ERR_CSW_FAILED)
+ goto error;
+ USB_ADD_QUIRK(udev, any_quirk, UQ_MSC_NO_TEST_UNIT_READY);
+ }
}
- err = bbb_command_start(sc, DIR_OUT, 0, NULL, 0,
- &scsi_prevent_removal, sizeof(scsi_prevent_removal),
- USB_MS_HZ);
-
- if (err == 0) {
- err = bbb_command_start(sc, DIR_OUT, 0, NULL, 0,
- &scsi_allow_removal, sizeof(scsi_allow_removal),
+ if (usb_test_quirk(uaa, UQ_MSC_NO_PREVENT_ALLOW) == 0) {
+ err = bbb_command_start(sc, DIR_NONE, 0, NULL, 0,
+ &scsi_prevent_removal, sizeof(scsi_prevent_removal),
USB_MS_HZ);
- }
- if (err != 0) {
- if (err != ERR_CSW_FAILED)
- goto error;
- DPRINTF("Device doesn't handle prevent and allow removal\n");
- usbd_add_dynamic_quirk(udev, UQ_MSC_NO_PREVENT_ALLOW);
+ if (err == 0) {
+ err = bbb_command_start(sc, DIR_NONE, 0, NULL, 0,
+ &scsi_allow_removal, sizeof(scsi_allow_removal),
+ USB_MS_HZ);
+ }
+
+ if (err != 0) {
+ if (err != ERR_CSW_FAILED)
+ goto error;
+ USB_ADD_QUIRK(udev, any_quirk, UQ_MSC_NO_PREVENT_ALLOW);
+ }
}
timeout = 1;
retry_sync_cache:
- err = bbb_command_start(sc, DIR_IN, 0, NULL, 0,
+ err = bbb_command_start(sc, DIR_NONE, 0, NULL, 0,
&scsi_sync_cache, sizeof(scsi_sync_cache),
USB_MS_HZ);
@@ -845,9 +868,7 @@
if (err != ERR_CSW_FAILED)
goto error;
- DPRINTF("Device doesn't handle synchronize cache\n");
-
- usbd_add_dynamic_quirk(udev, UQ_MSC_NO_SYNC_CACHE);
+ USB_ADD_QUIRK(udev, any_quirk, UQ_MSC_NO_SYNC_CACHE);
} else {
/*
* Certain Kingston memory sticks fail the first
@@ -872,11 +893,7 @@
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);
+ USB_ADD_QUIRK(udev, any_quirk, UQ_MSC_NO_SYNC_CACHE);
} else {
if (err != ERR_CSW_FAILED)
goto error;
@@ -884,6 +901,18 @@
}
}
+ if (usb_test_quirk(uaa, UQ_MSC_NO_START_STOP) == 0) {
+ err = bbb_command_start(sc, DIR_NONE, 0, NULL, 0,
+ &scsi_start_unit, sizeof(scsi_start_unit),
+ USB_MS_HZ);
+
+ if (err != 0) {
+ if (err != ERR_CSW_FAILED)
+ goto error;
+ USB_ADD_QUIRK(udev, any_quirk, UQ_MSC_NO_START_STOP);
+ }
+ }
+
/* clear sense status of any failed commands on the device */
err = bbb_command_start(sc, DIR_IN, 0, sc->buffer,
@@ -907,24 +936,28 @@
if (err != ERR_CSW_FAILED)
goto error;
}
+ goto done;
+error:
+ /* Apply most quirks */
+ USB_ADD_QUIRK(udev, any_quirk, UQ_MSC_NO_SYNC_CACHE);
+ USB_ADD_QUIRK(udev, any_quirk, UQ_MSC_NO_PREVENT_ALLOW);
+ USB_ADD_QUIRK(udev, any_quirk, UQ_MSC_NO_TEST_UNIT_READY);
+ USB_ADD_QUIRK(udev, any_quirk, UQ_MSC_NO_START_STOP);
done:
bbb_detach(sc);
- return (0);
-error:
- bbb_detach(sc);
-
- 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);
+ if (any_quirk) {
+ /* Unconfigure device, to clear software data toggle. */
+ usbd_set_config_index(udev, USB_UNCONFIG_INDEX);
- /* Need to re-enumerate the device */
- usbd_req_re_enumerate(udev, NULL);
+ /* Need to re-enumerate the device to clear its state. */
+ usbd_req_re_enumerate(udev, NULL);
+ return (USB_ERR_STALLED);
+ }
- return (USB_ERR_STALLED);
+ /* No quirks were added, continue as usual. */
+ return (0);
}
usb_error_t
@@ -944,7 +977,7 @@
USB_MS_HZ);
DPRINTF("Test unit ready status: %s\n", usbd_errstr(err));
err = bbb_command_start(sc, DIR_IN, 0, NULL, 0,
- &scsi_start_stop_unit, sizeof(scsi_start_stop_unit),
+ &scsi_stop_unit, sizeof(scsi_stop_unit),
USB_MS_HZ);
break;
case MSC_EJECT_REZERO:
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 12, 1:03 AM (21 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15759471
Default Alt Text
D30919.diff (9 KB)
Attached To
Mode
D30919: Automagically apply quirks on USB storage devices
Attached
Detach File
Event Timeline
Log In to Comment