diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index 3ee7acfab5..f233549a2b 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c @@ -34,6 +34,14 @@ #ifdef USB_STORAGE +/* The SD card driver on Sansa c200 and e200 can cause write corruption, + * often triggered by simultaneous USB activity. This can be largely avoided + * by not overlapping ata_write_sector() with USB transfers. This does reduce + * write performance, so we only do it for the affected DAPs + */ +#if defined(SANSA_C200) || defined(SANSA_E200) +#define SERIALIZE_WRITES +#endif /* Enable the following define to export only the SD card slot. This * is useful for USBCV MSC tests, as those are destructive. * This won't work right if the device doesn't have a card slot. @@ -408,12 +416,15 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length) (BUFFER_SIZE/SECTOR_SIZE); unsigned int next_count = cur_cmd.count - MIN(cur_cmd.count,BUFFER_SIZE/SECTOR_SIZE); + int next_select = !cur_cmd.data_select; +#ifndef SERIALIZE_WRITES if(next_count!=0) { /* Ask the host to send more, to the other buffer */ - receive_block_data(cur_cmd.data[!cur_cmd.data_select], + receive_block_data(cur_cmd.data[next_select], MIN(BUFFER_SIZE,next_count*SECTOR_SIZE)); } +#endif /* Now write the data that just came in, while the host is sending the next bit */ @@ -429,6 +440,13 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length) cur_sense_data.ascq=0; break; } +#ifdef SERIALIZE_WRITES + if(next_count!=0) { + /* Ask the host to send more, to the other buffer */ + receive_block_data(cur_cmd.data[next_select], + MIN(BUFFER_SIZE,next_count*SECTOR_SIZE)); + } +#endif if(next_count==0) { send_csw(UMS_STATUS_GOOD);