Fixed usb_storage to support more USB sticks

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.
This commit is contained in:
Wojciech Zajac 2014-06-25 13:45:06 +02:00 committed by Lionel Sambuc
parent 3316064b29
commit 78cd341562
3 changed files with 53 additions and 8 deletions

View file

@ -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;
}

View file

@ -24,7 +24,7 @@
/*---------------------------*
* declared types *
*---------------------------*
*---------------------------*/
/* URB's endpoint configuration */
typedef struct urb_ep_config {

View file

@ -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;