diff options
author | hselasky <hselasky@FreeBSD.org> | 2011-09-05 14:37:59 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2011-09-05 14:37:59 +0000 |
commit | eb99022db126133f178247a50376dc31f336349d (patch) | |
tree | 96fafc4ea37ed098bd61709533cbea2341e95146 | |
parent | 566ec163bd941bb5c3387c736651a924e9048110 (diff) | |
download | FreeBSD-src-eb99022db126133f178247a50376dc31f336349d.zip FreeBSD-src-eb99022db126133f178247a50376dc31f336349d.tar.gz |
Some USB mass storage devices requires that the sense information
is retrieved after a failed SCSI command to continue normal
operation. Else this sense information is retrived at the next
SCSI command.
Approved by: re (kib)
Reported by: Alex Kozlov
MFC after: 1 week
PR: usb/160299
-rw-r--r-- | sys/dev/usb/usb_msctest.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/sys/dev/usb/usb_msctest.c b/sys/dev/usb/usb_msctest.c index 061c3d3..9447a93 100644 --- a/sys/dev/usb/usb_msctest.c +++ b/sys/dev/usb/usb_msctest.c @@ -1,6 +1,6 @@ /* $FreeBSD$ */ /*- - * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. + * Copyright (c) 2008,2011 Hans Petter Selasky. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -83,7 +83,10 @@ enum { DIR_NONE, }; +#define SCSI_MAX_LEN 0x100 #define SCSI_INQ_LEN 0x24 +#define SCSI_SENSE_LEN 0xFF + 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 }; @@ -98,6 +101,8 @@ static uint8_t scsi_huawei_eject[] = { 0x11, 0x06, 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 }; +static uint8_t scsi_request_sense[] = { 0x03, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #define BULK_SIZE 64 /* dummy */ #define ERR_CSW_FAILED -1 @@ -151,7 +156,7 @@ struct bbb_transfer { uint8_t status_try; int error; - uint8_t buffer[256]; + uint8_t buffer[SCSI_MAX_LEN] __aligned(4); }; static usb_callback_t bbb_command_callback; @@ -661,6 +666,32 @@ usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index) usbd_add_dynamic_quirk(udev, UQ_MSC_NO_SYNC_CACHE); } + /* clear sense status of any failed commands on the device */ + + err = bbb_command_start(sc, DIR_IN, 0, sc->buffer, + SCSI_INQ_LEN, &scsi_inquiry, sizeof(scsi_inquiry), + USB_MS_HZ); + + DPRINTF("Inquiry = %d\n", err); + + if (err != 0) { + + if (err != ERR_CSW_FAILED) + goto error; + } + + err = bbb_command_start(sc, DIR_IN, 0, sc->buffer, + SCSI_SENSE_LEN, &scsi_request_sense, + sizeof(scsi_request_sense), USB_MS_HZ); + + DPRINTF("Request sense = %d\n", err); + + if (err != 0) { + + if (err != ERR_CSW_FAILED) + goto error; + } + done: bbb_detach(sc); return (0); |