USB: ene_usb6250: implement REQUEST SENSE

In the ene_usb6250 sub-driver for usb-storage, there is no support for
the REQUEST SENSE command.  This command is issued whenever a failure
occurs, and without it the driver has no way to tell the SCSI core
what the reason for the failure was.

This patch adds a do_scsi_request_sense() routine to the driver.  The
new routine reports the error code stored by the previous command.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-and-tested-by: Andreas Hartmann <andihartmann@01019freenet.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Alan Stern 2017-05-16 11:48:01 -04:00 committed by Greg Kroah-Hartman
parent aa18c4b6e0
commit ce553bd103
1 changed files with 33 additions and 8 deletions

View File

@ -95,12 +95,12 @@ static struct us_unusual_dev ene_ub6250_unusual_dev_list[] = {
#define REG_HW_TRAP1 0xFF89 #define REG_HW_TRAP1 0xFF89
/* SRB Status */ /* SRB Status */
#define SS_SUCCESS 0x00 /* No Sense */ #define SS_SUCCESS 0x000000 /* No Sense */
#define SS_NOT_READY 0x02 #define SS_NOT_READY 0x023A00 /* Medium not present */
#define SS_MEDIUM_ERR 0x03 #define SS_MEDIUM_ERR 0x031100 /* Unrecovered read error */
#define SS_HW_ERR 0x04 #define SS_HW_ERR 0x040800 /* Communication failure */
#define SS_ILLEGAL_REQUEST 0x05 #define SS_ILLEGAL_REQUEST 0x052000 /* Invalid command */
#define SS_UNIT_ATTENTION 0x06 #define SS_UNIT_ATTENTION 0x062900 /* Reset occurred */
/* ENE Load FW Pattern */ /* ENE Load FW Pattern */
#define SD_INIT1_PATTERN 1 #define SD_INIT1_PATTERN 1
@ -577,6 +577,22 @@ static int ene_send_scsi_cmd(struct us_data *us, u8 fDir, void *buf, int use_sg)
return USB_STOR_TRANSPORT_GOOD; return USB_STOR_TRANSPORT_GOOD;
} }
static int do_scsi_request_sense(struct us_data *us, struct scsi_cmnd *srb)
{
struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
unsigned char buf[18];
memset(buf, 0, 18);
buf[0] = 0x70; /* Current error */
buf[2] = info->SrbStatus >> 16; /* Sense key */
buf[7] = 10; /* Additional length */
buf[12] = info->SrbStatus >> 8; /* ASC */
buf[13] = info->SrbStatus; /* ASCQ */
usb_stor_set_xfer_buf(buf, sizeof(buf), srb);
return USB_STOR_TRANSPORT_GOOD;
}
static int sd_scsi_test_unit_ready(struct us_data *us, struct scsi_cmnd *srb) static int sd_scsi_test_unit_ready(struct us_data *us, struct scsi_cmnd *srb)
{ {
struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
@ -2212,11 +2228,13 @@ static int sd_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)
int result; int result;
struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra; struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra;
info->SrbStatus = SS_SUCCESS;
switch (srb->cmnd[0]) { switch (srb->cmnd[0]) {
case TEST_UNIT_READY: case TEST_UNIT_READY:
result = sd_scsi_test_unit_ready(us, srb); result = sd_scsi_test_unit_ready(us, srb);
break; /* 0x00 */ break; /* 0x00 */
case REQUEST_SENSE:
result = do_scsi_request_sense(us, srb);
break; /* 0x03 */
case INQUIRY: case INQUIRY:
result = sd_scsi_inquiry(us, srb); result = sd_scsi_inquiry(us, srb);
break; /* 0x12 */ break; /* 0x12 */
@ -2242,6 +2260,8 @@ static int sd_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)
result = USB_STOR_TRANSPORT_FAILED; result = USB_STOR_TRANSPORT_FAILED;
break; break;
} }
if (result == USB_STOR_TRANSPORT_GOOD)
info->SrbStatus = SS_SUCCESS;
return result; return result;
} }
@ -2252,11 +2272,14 @@ static int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)
{ {
int result; int result;
struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra; struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra;
info->SrbStatus = SS_SUCCESS;
switch (srb->cmnd[0]) { switch (srb->cmnd[0]) {
case TEST_UNIT_READY: case TEST_UNIT_READY:
result = ms_scsi_test_unit_ready(us, srb); result = ms_scsi_test_unit_ready(us, srb);
break; /* 0x00 */ break; /* 0x00 */
case REQUEST_SENSE:
result = do_scsi_request_sense(us, srb);
break; /* 0x03 */
case INQUIRY: case INQUIRY:
result = ms_scsi_inquiry(us, srb); result = ms_scsi_inquiry(us, srb);
break; /* 0x12 */ break; /* 0x12 */
@ -2277,6 +2300,8 @@ static int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)
result = USB_STOR_TRANSPORT_FAILED; result = USB_STOR_TRANSPORT_FAILED;
break; break;
} }
if (result == USB_STOR_TRANSPORT_GOOD)
info->SrbStatus = SS_SUCCESS;
return result; return result;
} }