Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce553bd1 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

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: default avatarAlan Stern <stern@rowland.harvard.edu>
Reported-and-tested-by: default avatarAndreas Hartmann <andihartmann@01019freenet.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent aa18c4b6
Loading
Loading
Loading
Loading
+33 −8
Original line number Diff line number Diff line
@@ -95,12 +95,12 @@ static struct us_unusual_dev ene_ub6250_unusual_dev_list[] = {
#define REG_HW_TRAP1        0xFF89

/* SRB Status */
#define SS_SUCCESS                  0x00      /* No Sense */
#define SS_NOT_READY                0x02
#define SS_MEDIUM_ERR               0x03
#define SS_HW_ERR                   0x04
#define SS_ILLEGAL_REQUEST          0x05
#define SS_UNIT_ATTENTION           0x06
#define SS_SUCCESS		0x000000	/* No Sense */
#define SS_NOT_READY		0x023A00	/* Medium not present */
#define SS_MEDIUM_ERR		0x031100	/* Unrecovered read error */
#define SS_HW_ERR		0x040800	/* Communication failure */
#define SS_ILLEGAL_REQUEST	0x052000	/* Invalid command */
#define SS_UNIT_ATTENTION	0x062900	/* Reset occurred */

/* ENE Load FW Pattern */
#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;
}

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)
{
	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;
	struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra;

	info->SrbStatus = SS_SUCCESS;
	switch (srb->cmnd[0]) {
	case TEST_UNIT_READY:
		result = sd_scsi_test_unit_ready(us, srb);
		break; /* 0x00 */
	case REQUEST_SENSE:
		result = do_scsi_request_sense(us, srb);
		break; /* 0x03 */
	case INQUIRY:
		result = sd_scsi_inquiry(us, srb);
		break; /* 0x12 */
@@ -2242,6 +2260,8 @@ static int sd_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)
		result = USB_STOR_TRANSPORT_FAILED;
		break;
	}
	if (result == USB_STOR_TRANSPORT_GOOD)
		info->SrbStatus = SS_SUCCESS;
	return result;
}

@@ -2252,11 +2272,14 @@ static int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)
{
	int result;
	struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra;
	info->SrbStatus = SS_SUCCESS;

	switch (srb->cmnd[0]) {
	case TEST_UNIT_READY:
		result = ms_scsi_test_unit_ready(us, srb);
		break; /* 0x00 */
	case REQUEST_SENSE:
		result = do_scsi_request_sense(us, srb);
		break; /* 0x03 */
	case INQUIRY:
		result = ms_scsi_inquiry(us, srb);
		break; /* 0x12 */
@@ -2277,6 +2300,8 @@ static int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)
		result = USB_STOR_TRANSPORT_FAILED;
		break;
	}
	if (result == USB_STOR_TRANSPORT_GOOD)
		info->SrbStatus = SS_SUCCESS;
	return result;
}