]> Zhao Yanbai Git Server - minix.git/commitdiff
Fixed usb_storage to support more USB sticks
authorWojciech Zajac <wzajac@jpembedded.eu>
Wed, 25 Jun 2014 11:45:06 +0000 (13:45 +0200)
committerLionel Sambuc <lionel@minix3.org>
Mon, 28 Jul 2014 15:05:55 +0000 (17:05 +0200)
More TEST UNIT READY calls, as some sticks seem to require them, while others are indifferent.

Mass storage 'reset recovery' is disabled by default, as it broke communication with some sticks.

Minor fixes.

drivers/usb_storage/scsi.c
drivers/usb_storage/urb_helper.h
drivers/usb_storage/usb_storage.c

index f4ff43e1a98d87db0b27b6c0c67d31ca88fefa12..8ed74d419e4d71ba48c366a4367c877edd1e0b49 100755 (executable)
@@ -258,7 +258,7 @@ check_csw(mass_storage_csw * csw, unsigned int tag)
        }
 
        if (CSW_STATUS_GOOD != csw->bCSWStatus) {
-               MASS_MSG("CSW status error!");
+               MASS_MSG("CSW status error (0x%02X)!", csw->bCSWStatus);
                return EXIT_FAILURE;
        }
 
index 700323ae6ce9eeace82ac5e099bcf1ba998630cc..c9033c93b5e5cb492d8bdc0407a604a7b997f974 100755 (executable)
@@ -24,7 +24,7 @@
 
 /*---------------------------*
  *    declared types         *
- *---------------------------*
+ *---------------------------*/
 /* URB's endpoint configuration */
 typedef struct urb_ep_config {
 
index c455554e8b24c83425dc73f0e6a06f60e0f25781..ecafdccba253a52aa6bc2ee670648406c735d102 100755 (executable)
@@ -45,10 +45,12 @@ static int mass_storage_send_scsi_data_in(void *, unsigned int);
 static int mass_storage_send_scsi_data_out(void *, unsigned int);
 static int mass_storage_send_scsi_csw_in(void);
 
+#ifdef MASS_RESET_RECOVERY
 /* Bulk only URB related prototypes */
 static int mass_storage_reset_recovery(void);
 static int mass_storage_send_bulk_reset(void);
 static int mass_storage_send_clear_feature(int, int);
+#endif
 
 /* SEF related functions */
 static int mass_storage_sef_hdlr(int, sef_init_info_t *);
@@ -59,6 +61,7 @@ static void ddekit_usb_task(void *);
 
 /* Mass storage related prototypes */
 static void mass_storage_task(void *);
+static int mass_storage_test(void);
 static int mass_storage_try_first_open(void);
 static int mass_storage_transfer_restrictions(u64_t, unsigned long);
 static ssize_t mass_storage_write(unsigned long, endpoint_t, iovec_t *,
@@ -143,6 +146,8 @@ static unsigned char buffer[BUFFER_SIZE];
 /* Length of local buffer where descriptors are temporarily stored */
 #define MAX_DESCRIPTORS_LEN 128
 
+/* Maximum 'Test Unit Ready' command retries */
+#define MAX_TEST_RETRIES 3
 
 /*---------------------------*
  *    defined functions      *
@@ -333,6 +338,7 @@ mass_storage_send_scsi_csw_in(void)
 }
 
 
+#ifdef MASS_RESET_RECOVERY
 /*===========================================================================*
  *    mass_storage_reset_recovery                                            *
  *===========================================================================*/
@@ -472,6 +478,7 @@ mass_storage_send_clear_feature(int ep_num, int direction)
 
        return EXIT_SUCCESS;
 }
+#endif
 
 
 /*===========================================================================*
@@ -575,6 +582,33 @@ mass_storage_task(void * UNUSED(unused))
 }
 
 
+/*===========================================================================*
+ *    mass_storage_test                                                      *
+ *===========================================================================*/
+static int
+mass_storage_test(void)
+{
+       int repeat;
+
+       MASS_DEBUG_DUMP;
+
+       for (repeat = 0; repeat < MAX_TEST_RETRIES; repeat++) {
+
+               /* SCSI TEST UNIT READY OUT stage */
+               if (mass_storage_send_scsi_cbw_out(SCSI_TEST_UNIT_READY, NULL))
+                       return EXIT_FAILURE;
+
+               /* TODO: Only CSW failure should normally contribute to retry */
+
+               /* SCSI TEST UNIT READY IN stage */
+               if (EXIT_SUCCESS == mass_storage_send_scsi_csw_in())
+                       return EXIT_SUCCESS;
+       }
+
+       return EXIT_FAILURE;
+}
+
+
 /*===========================================================================*
  *    mass_storage_try_first_open                                            *
  *===========================================================================*/
@@ -593,6 +627,11 @@ mass_storage_try_first_open()
        llba = 0; /* Last logical block address */
        blen = 0; /* Block length (usually 512B) */
 
+       /* Run TEST UNIT READY before other SCSI command
+        * Some devices refuse to work without this */
+       if (mass_storage_test())
+               return EIO;
+
        /* SCSI INQUIRY OUT stage */
        if (mass_storage_send_scsi_cbw_out(SCSI_INQUIRY, NULL))
                return EIO;
@@ -609,6 +648,11 @@ mass_storage_try_first_open()
        if (check_inquiry_reply(inquiry))
                return EIO;
 
+       /* Run TEST UNIT READY before other SCSI command
+        * Some devices refuse to work without this */
+       if (mass_storage_test())
+               return EIO;
+
        /* SCSI READ CAPACITY OUT stage */
        if (mass_storage_send_scsi_cbw_out(SCSI_READ_CAPACITY, NULL))
                return EIO;
@@ -1005,11 +1049,13 @@ mass_storage_open(devminor_t minor, int UNUSED(access))
        /* Copy evaluated current drive for simplified dereference */
        d = driver_state.cur_drive;
 
+#ifdef MASS_RESET_RECOVERY
        /* In case of previous CBW mismatch */
        if (mass_storage_reset_recovery()) {
                MASS_MSG("Resetting mass storage device failed");
                return EIO;
        }
+#endif
 
        /* In case of missing endpoint information, do simple
         * enumeration and hold it for future use */
@@ -1050,12 +1096,9 @@ mass_storage_open(devminor_t minor, int UNUSED(access))
                        return ENXIO;
        }
 
-       /* SCSI TEST UNIT READY OUT stage */
-       if (mass_storage_send_scsi_cbw_out(SCSI_TEST_UNIT_READY, NULL))
-               return EIO;
-
-       /* SCSI TEST UNIT READY IN stage */
-       if (mass_storage_send_scsi_csw_in())
+       /* Run TEST UNIT READY before further commands
+        * Some devices refuse to work without this */
+       if (mass_storage_test())
                return EIO;
 
        /* Opening completed */
@@ -1346,6 +1389,8 @@ mass_storage_geometry(devminor_t minor, struct part_geom * part)
 static void
 mass_storage_geometry(devminor_t UNUSED(minor), struct part_geom * part)
 {
+       MASS_DEBUG_DUMP;
+
        part->cylinders = part->size / SECTOR_SIZE;
        part->heads = 64;
        part->sectors = 32;