summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2009-06-11 17:28:24 +0000
committerRafaël Carré <rafael.carre@gmail.com>2009-06-11 17:28:24 +0000
commit460a1c44977b6dc4e4327a1826760cd35944c6a3 (patch)
treeb3ae6ce3f6bf01421ba2a869def95e195d012077 /firmware
parent7572141d42008ce6acd0c2907e4f548cf05fe108 (diff)
downloadrockbox-460a1c44977b6dc4e4327a1826760cd35944c6a3.tar.gz
rockbox-460a1c44977b6dc4e4327a1826760cd35944c6a3.zip
Sansa AMS storage driver: restart bank selection if data transfer failed, and precise a comment about retry variable
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21248 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/target/arm/as3525/ata_sd_as3525.c73
1 files changed, 39 insertions, 34 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c
index 919cd50e9d..d7989db073 100644
--- a/firmware/target/arm/as3525/ata_sd_as3525.c
+++ b/firmware/target/arm/as3525/ata_sd_as3525.c
@@ -571,50 +571,55 @@ static int sd_select_bank(signed char bank)
unsigned char card_data[512];
int ret;
- ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN);
- if (ret < 0)
- return ret - 2;
+ do {
+ /* The ISR will set this to true if an error occurred */
+ retry = false;
- if(!send_cmd(INTERNAL_AS3525, SD_SWITCH_FUNC, 0x80ffffef, MCI_ARG, NULL))
- return -1;
+ ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN);
+ if (ret < 0)
+ return ret - 2;
- mci_delay();
+ if(!send_cmd(INTERNAL_AS3525, SD_SWITCH_FUNC, 0x80ffffef, MCI_ARG, NULL))
+ return -1;
- if(!send_cmd(INTERNAL_AS3525, 35, 0, MCI_NO_FLAGS, NULL))
- return -2;
+ mci_delay();
- mci_delay();
+ if(!send_cmd(INTERNAL_AS3525, 35, 0, MCI_NO_FLAGS, NULL))
+ return -2;
- memset(card_data, 0, 512);
- if(bank == -1)
- { /* enable bank switching */
- card_data[0] = 16;
- card_data[1] = 1;
- card_data[2] = 10;
- }
- else
- card_data[0] = bank;
+ mci_delay();
- dma_retain();
- dma_enable_channel(0, card_data, MCI_FIFO(INTERNAL_AS3525), DMA_PERI_SD,
- DMAC_FLOWCTRL_PERI_MEM_TO_PERI, true, false, 0, DMA_S8, NULL);
+ memset(card_data, 0, 512);
+ if(bank == -1)
+ { /* enable bank switching */
+ card_data[0] = 16;
+ card_data[1] = 1;
+ card_data[2] = 10;
+ }
+ else
+ card_data[0] = bank;
- MCI_DATA_TIMER(INTERNAL_AS3525) = SD_MAX_WRITE_TIMEOUT;
- MCI_DATA_LENGTH(INTERNAL_AS3525) = 512;
- MCI_DATA_CTRL(INTERNAL_AS3525) = (1<<0) /* enable */ |
- (0<<1) /* transfer direction */ |
- (1<<3) /* DMA */ |
- (9<<4) /* 2^9 = 512 */ ;
+ dma_retain();
+ dma_enable_channel(0, card_data, MCI_FIFO(INTERNAL_AS3525), DMA_PERI_SD,
+ DMAC_FLOWCTRL_PERI_MEM_TO_PERI, true, false, 0, DMA_S8, NULL);
- wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
+ MCI_DATA_TIMER(INTERNAL_AS3525) = SD_MAX_WRITE_TIMEOUT;
+ MCI_DATA_LENGTH(INTERNAL_AS3525) = 512;
+ MCI_DATA_CTRL(INTERNAL_AS3525) = (1<<0) /* enable */ |
+ (0<<1) /* transfer direction */ |
+ (1<<3) /* DMA */ |
+ (9<<4) /* 2^9 = 512 */ ;
- dma_release();
+ wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
- mci_delay();
+ dma_release();
- ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN);
- if (ret < 0)
- return ret - 4;
+ mci_delay();
+
+ ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN);
+ if (ret < 0)
+ return ret - 4;
+ } while(retry);
card_info[INTERNAL_AS3525].current_bank = (bank == -1) ? 0 : bank;
@@ -670,7 +675,7 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start,
write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
unsigned long bank_start = start;
- /* Interrupt handler might set this to true during transfer */
+ /* The ISR will set this to true if an error occurred */
retry = false;
/* Only switch banks for internal storage */