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 <st...@rowland.harvard.edu>
Reported-and-tested-by: Andreas Hartmann <andihartm...@01019freenet.de>

---


[as1829]


 drivers/usb/storage/ene_ub6250.c |   41 +++++++++++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 8 deletions(-)

Index: usb-4.x/drivers/usb/storage/ene_ub6250.c
===================================================================
--- usb-4.x.orig/drivers/usb/storage/ene_ub6250.c
+++ usb-4.x/drivers/usb/storage/ene_ub6250.c
@@ -95,12 +95,12 @@ static struct us_unusual_dev ene_ub6250_
 #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
@@ -584,6 +584,22 @@ static int ene_send_scsi_cmd(struct us_d
        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;
@@ -2227,11 +2243,13 @@ static int sd_scsi_irp(struct us_data *u
        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 */
@@ -2257,6 +2275,8 @@ static int sd_scsi_irp(struct us_data *u
                result = USB_STOR_TRANSPORT_FAILED;
                break;
        }
+       if (result == USB_STOR_TRANSPORT_GOOD)
+               info->SrbStatus = SS_SUCCESS;
        return result;
 }
 
@@ -2267,11 +2287,14 @@ static int ms_scsi_irp(struct us_data *u
 {
        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 */
@@ -2292,6 +2315,8 @@ static int ms_scsi_irp(struct us_data *u
                result = USB_STOR_TRANSPORT_FAILED;
                break;
        }
+       if (result == USB_STOR_TRANSPORT_GOOD)
+               info->SrbStatus = SS_SUCCESS;
        return result;
 }
 


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to