]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/usb/storage/ene_ub6250.c
USB: ene_usb6250: turn off the Removable flag
[karo-tx-linux.git] / drivers / usb / storage / ene_ub6250.c
index 369f3c24815a1462f405f1a6bc3f2cbdd034e21b..22b850a1ce06c545dc085479b90a08bac76a0ad3 100644 (file)
@@ -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,24 +577,26 @@ static int ene_send_scsi_cmd(struct us_data *us, u8 fDir, void *buf, int use_sg)
        return USB_STOR_TRANSPORT_GOOD;
 }
 
-static int sd_scsi_test_unit_ready(struct us_data *us, struct scsi_cmnd *srb)
+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];
 
-       if (info->SD_Status.Insert && info->SD_Status.Ready)
-               return USB_STOR_TRANSPORT_GOOD;
-       else {
-               ene_sd_init(us);
-               return USB_STOR_TRANSPORT_GOOD;
-       }
+       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_inquiry(struct us_data *us, struct scsi_cmnd *srb)
+static int do_scsi_inquiry(struct us_data *us, struct scsi_cmnd *srb)
 {
        unsigned char data_ptr[36] = {
-               0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55,
+               0x00, 0x00, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55,
                0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61,
                0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20,
                0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30 };
@@ -603,6 +605,20 @@ static int sd_scsi_inquiry(struct us_data *us, struct scsi_cmnd *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;
+
+       if (info->SD_Status.Insert && info->SD_Status.Ready)
+               return USB_STOR_TRANSPORT_GOOD;
+       else {
+               ene_sd_init(us);
+               return USB_STOR_TRANSPORT_GOOD;
+       }
+
+       return USB_STOR_TRANSPORT_GOOD;
+}
+
 static int sd_scsi_mode_sense(struct us_data *us, struct scsi_cmnd *srb)
 {
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
@@ -1446,19 +1462,6 @@ static int ms_scsi_test_unit_ready(struct us_data *us, struct scsi_cmnd *srb)
        return USB_STOR_TRANSPORT_GOOD;
 }
 
-static int ms_scsi_inquiry(struct us_data *us, struct scsi_cmnd *srb)
-{
-       /* pr_info("MS_SCSI_Inquiry\n"); */
-       unsigned char data_ptr[36] = {
-               0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55,
-               0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61,
-               0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20,
-               0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30};
-
-       usb_stor_set_xfer_buf(data_ptr, 36, srb);
-       return USB_STOR_TRANSPORT_GOOD;
-}
-
 static int ms_scsi_mode_sense(struct us_data *us, struct scsi_cmnd *srb)
 {
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
@@ -1929,6 +1932,8 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag)
        bcb->CDB[0] = 0xEF;
 
        result = ene_send_scsi_cmd(us, FDIR_WRITE, buf, 0);
+       if (us->srb != NULL)
+               scsi_set_resid(us->srb, 0);
        info->BIN_FLAG = flag;
        kfree(buf);
 
@@ -2210,13 +2215,15 @@ 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);
+               result = do_scsi_inquiry(us, srb);
                break; /* 0x12 */
        case MODE_SENSE:
                result = sd_scsi_mode_sense(us, srb);
@@ -2240,6 +2247,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;
 }
 
@@ -2250,13 +2259,16 @@ 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);
+               result = do_scsi_inquiry(us, srb);
                break; /* 0x12 */
        case MODE_SENSE:
                result = ms_scsi_mode_sense(us, srb);
@@ -2275,26 +2287,29 @@ 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;
 }
 
 static int ene_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
-       int result = 0;
+       int result = USB_STOR_XFER_GOOD;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
 
        /*US_DEBUG(usb_stor_show_command(us, srb)); */
        scsi_set_resid(srb, 0);
-       if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready))) {
+       if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready)))
                result = ene_init(us);
-       } else {
+       if (result == USB_STOR_XFER_GOOD) {
+               result = USB_STOR_TRANSPORT_ERROR;
                if (info->SD_Status.Ready)
                        result = sd_scsi_irp(us, srb);
 
                if (info->MS_Status.Ready)
                        result = ms_scsi_irp(us, srb);
        }
-       return 0;
+       return result;
 }
 
 static struct scsi_host_template ene_ub6250_host_template;