diff options
author | Frank Gevaerts <frank@gevaerts.be> | 2008-07-09 19:56:09 +0000 |
---|---|---|
committer | Frank Gevaerts <frank@gevaerts.be> | 2008-07-09 19:56:09 +0000 |
commit | 3f3bb75d6a3e919460d369ba95e1518f622e18ea (patch) | |
tree | 7c25f5feb1b592b25c578ccd69fe1c84379b2a1c /firmware | |
parent | 1acd5355873b77ff0422cdad4fb6b549652265ec (diff) | |
download | rockbox-3f3bb75d6a3e919460d369ba95e1518f622e18ea.tar.gz rockbox-3f3bb75d6a3e919460d369ba95e1518f622e18ea.zip |
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
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/usbstack/usb_storage.c | 20 |
1 files changed, 19 insertions, 1 deletions
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 @@ | |||
34 | 34 | ||
35 | #ifdef USB_STORAGE | 35 | #ifdef USB_STORAGE |
36 | 36 | ||
37 | /* The SD card driver on Sansa c200 and e200 can cause write corruption, | ||
38 | * often triggered by simultaneous USB activity. This can be largely avoided | ||
39 | * by not overlapping ata_write_sector() with USB transfers. This does reduce | ||
40 | * write performance, so we only do it for the affected DAPs | ||
41 | */ | ||
42 | #if defined(SANSA_C200) || defined(SANSA_E200) | ||
43 | #define SERIALIZE_WRITES | ||
44 | #endif | ||
37 | /* Enable the following define to export only the SD card slot. This | 45 | /* Enable the following define to export only the SD card slot. This |
38 | * is useful for USBCV MSC tests, as those are destructive. | 46 | * is useful for USBCV MSC tests, as those are destructive. |
39 | * This won't work right if the device doesn't have a card slot. | 47 | * 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) | |||
408 | (BUFFER_SIZE/SECTOR_SIZE); | 416 | (BUFFER_SIZE/SECTOR_SIZE); |
409 | unsigned int next_count = cur_cmd.count - | 417 | unsigned int next_count = cur_cmd.count - |
410 | MIN(cur_cmd.count,BUFFER_SIZE/SECTOR_SIZE); | 418 | MIN(cur_cmd.count,BUFFER_SIZE/SECTOR_SIZE); |
419 | int next_select = !cur_cmd.data_select; | ||
411 | 420 | ||
421 | #ifndef SERIALIZE_WRITES | ||
412 | if(next_count!=0) { | 422 | if(next_count!=0) { |
413 | /* Ask the host to send more, to the other buffer */ | 423 | /* Ask the host to send more, to the other buffer */ |
414 | receive_block_data(cur_cmd.data[!cur_cmd.data_select], | 424 | receive_block_data(cur_cmd.data[next_select], |
415 | MIN(BUFFER_SIZE,next_count*SECTOR_SIZE)); | 425 | MIN(BUFFER_SIZE,next_count*SECTOR_SIZE)); |
416 | } | 426 | } |
427 | #endif | ||
417 | 428 | ||
418 | /* Now write the data that just came in, while the host is | 429 | /* Now write the data that just came in, while the host is |
419 | sending the next bit */ | 430 | sending the next bit */ |
@@ -429,6 +440,13 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length) | |||
429 | cur_sense_data.ascq=0; | 440 | cur_sense_data.ascq=0; |
430 | break; | 441 | break; |
431 | } | 442 | } |
443 | #ifdef SERIALIZE_WRITES | ||
444 | if(next_count!=0) { | ||
445 | /* Ask the host to send more, to the other buffer */ | ||
446 | receive_block_data(cur_cmd.data[next_select], | ||
447 | MIN(BUFFER_SIZE,next_count*SECTOR_SIZE)); | ||
448 | } | ||
449 | #endif | ||
432 | 450 | ||
433 | if(next_count==0) { | 451 | if(next_count==0) { |
434 | send_csw(UMS_STATUS_GOOD); | 452 | send_csw(UMS_STATUS_GOOD); |