From 3f3bb75d6a3e919460d369ba95e1518f622e18ea Mon Sep 17 00:00:00 2001 From: Frank Gevaerts Date: Wed, 9 Jul 2008 19:56:09 +0000 Subject: Don't do overlapping USB transactions and SD writes. This seems to avoid FS#8663 git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17997 a1c6a512-1295-4272-9138-f99709370657 --- firmware/usbstack/usb_storage.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'firmware') 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); -- cgit v1.2.3