summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/usb/usb_msctest.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/dev/usb/usb_msctest.c')
-rw-r--r--freebsd/sys/dev/usb/usb_msctest.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/freebsd/sys/dev/usb/usb_msctest.c b/freebsd/sys/dev/usb/usb_msctest.c
index 4d28346c..19accddf 100644
--- a/freebsd/sys/dev/usb/usb_msctest.c
+++ b/freebsd/sys/dev/usb/usb_msctest.c
@@ -100,6 +100,9 @@ static uint8_t scsi_cmotech_eject[] = { 0xff, 0x52, 0x44, 0x45, 0x56, 0x43,
static uint8_t scsi_huawei_eject[] = { 0x11, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
+static uint8_t scsi_huawei_eject2[] = { 0x11, 0x06, 0x20, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00 };
static uint8_t scsi_tct_eject[] = { 0x06, 0xf5, 0x04, 0x02, 0x52, 0x70 };
static uint8_t scsi_sync_cache[] = { 0x35, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
@@ -107,6 +110,8 @@ 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 };
+static uint8_t scsi_prevent_removal[] = { 0x1e, 0, 0, 0, 1, 0 };
+static uint8_t scsi_allow_removal[] = { 0x1e, 0, 0, 0, 0, 0 };
#define BULK_SIZE 64 /* dummy */
#define ERR_CSW_FAILED -1
@@ -479,6 +484,7 @@ bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun,
sc->data_rem = data_len;
sc->data_timeout = (data_timeout + USB_MS_HZ);
sc->actlen = 0;
+ sc->error = 0;
sc->cmd_len = cmd_len;
memset(&sc->cbw->CBWCDB, 0, sizeof(sc->cbw->CBWCDB));
memcpy(&sc->cbw->CBWCDB, cmd_ptr, cmd_len);
@@ -689,10 +695,28 @@ usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index)
USB_MS_HZ);
if (err != 0) {
+ if (err != ERR_CSW_FAILED)
+ goto error;
+ DPRINTF("Test unit ready failed\n");
+ }
+
+ 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),
+ 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);
}
+
timeout = 1;
retry_sync_cache:
@@ -708,7 +732,6 @@ retry_sync_cache:
DPRINTF("Device doesn't handle synchronize cache\n");
usbd_add_dynamic_quirk(udev, UQ_MSC_NO_SYNC_CACHE);
-
} else {
/*
@@ -782,6 +805,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 */
@@ -800,7 +824,6 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method)
if (sc == NULL)
return (USB_ERR_INVAL);
- err = 0;
switch (method) {
case MSC_EJECT_STOPUNIT:
err = bbb_command_start(sc, DIR_IN, 0, NULL, 0,
@@ -831,6 +854,11 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method)
&scsi_huawei_eject, sizeof(scsi_huawei_eject),
USB_MS_HZ);
break;
+ case MSC_EJECT_HUAWEI2:
+ err = bbb_command_start(sc, DIR_IN, 0, NULL, 0,
+ &scsi_huawei_eject2, sizeof(scsi_huawei_eject2),
+ USB_MS_HZ);
+ break;
case MSC_EJECT_TCT:
/*
* TCTMobile needs DIR_IN flag. To get it, we
@@ -841,9 +869,11 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method)
sizeof(scsi_tct_eject), USB_MS_HZ);
break;
default:
- printf("usb_msc_eject: unknown eject method (%d)\n", method);
- break;
+ DPRINTF("Unknown eject method (%d)\n", method);
+ bbb_detach(sc);
+ return (USB_ERR_INVAL);
}
+
DPRINTF("Eject CD command status: %s\n", usbd_errstr(err));
bbb_detach(sc);