diff options
Diffstat (limited to 'freebsd/sys/dev/usb/usb_msctest.c')
-rw-r--r-- | freebsd/sys/dev/usb/usb_msctest.c | 38 |
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); |