diff options
| author | Rafaël Carré <rafael.carre@gmail.com> | 2009-05-26 21:08:47 +0000 |
|---|---|---|
| committer | Rafaël Carré <rafael.carre@gmail.com> | 2009-05-26 21:08:47 +0000 |
| commit | 83eb479732879e9852064644942ca36a7fd986a9 (patch) | |
| tree | af8f86de1c1829da8f13c6ca7f4dc963ca01c2b5 | |
| parent | 3ca0614de9a3c4dc633e4c9f9ba459d89e44dd92 (diff) | |
| download | rockbox-83eb479732879e9852064644942ca36a7fd986a9.zip rockbox-83eb479732879e9852064644942ca36a7fd986a9.tar.gz rockbox-83eb479732879e9852064644942ca36a7fd986a9.tar.bz2 rockbox-83eb479732879e9852064644942ca36a7fd986a9.tar.xz | |
FS#10216 : Sansa AMS : Do not cross a bank boundary in a single transfer (Only for 8GB or more -if they exist- players)
Also add a few comments in the code
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21096 a1c6a512-1295-4272-9138-f99709370657
| -rw-r--r-- | firmware/target/arm/as3525/ata_sd_as3525.c | 66 |
1 files changed, 36 insertions, 30 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c index 03a6a8b..a0b9b13 100644 --- a/firmware/target/arm/as3525/ata_sd_as3525.c +++ b/firmware/target/arm/as3525/ata_sd_as3525.c @@ -142,8 +142,8 @@ void INT_GPIOA(void) GPIOA_IC = (1<<2); timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); } -#endif -#endif +#endif /* defined(SANSA_E200V2) || defined(SANSA_FUZE) */ +#endif /* HAVE_HOTSWAP */ void INT_NAND(void) { @@ -211,7 +211,7 @@ static bool send_cmd(const int drive, const int cmd, const int arg, { /* resp received */ if(flags & MCI_LONG_RESP) { - /* store the response in little endian order for the words */ + /* store the response in reverse words order */ response[0] = MCI_RESP3(drive); response[1] = MCI_RESP2(drive); response[2] = MCI_RESP1(drive); @@ -322,7 +322,7 @@ static int sd_init_card(const int drive) card_info[drive].initialized = 1; - MCI_CLOCK(drive) |= MCI_CLOCK_BYPASS; /* full speed */ + MCI_CLOCK(drive) |= MCI_CLOCK_BYPASS; /* full speed for controller clock */ mci_delay(); /* @@ -626,7 +626,6 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, const int drive = 0; #endif int ret = 0; - int bank; bool unaligned_transfer = (int)buf & 3; /* skip SanDisk OF */ @@ -647,29 +646,10 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, last_disk_activity = current_tick; - /* Only switch banks for internal storage */ - if(drive == INTERNAL_AS3525) - { - bank = start / BLOCKS_PER_BANK; - - if(card_info[INTERNAL_AS3525].current_bank != bank) - { - ret = sd_select_bank(bank); - if (ret < 0) - { - ret -= 20; - goto sd_transfer_error; - } - } - - start -= bank * BLOCKS_PER_BANK; - } - - ret = sd_wait_for_state(drive, SD_TRAN); if (ret < 0) { - ret -= 2*20; + ret -= 20; goto sd_transfer_error; } @@ -683,13 +663,35 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, void *dma_buf; const int cmd = write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; - int arg = start; - if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ - arg *= BLOCK_SIZE; + unsigned long bank_start = start; /* Interrupt handler might set this to true during transfer */ retry = false; + /* Only switch banks for internal storage */ + if(drive == INTERNAL_AS3525) + { + int bank = start / BLOCKS_PER_BANK; /* Current bank */ + + /* Switch bank if needed */ + if(card_info[INTERNAL_AS3525].current_bank != bank) + { + ret = sd_select_bank(bank); + if (ret < 0) + { + ret -= 2*20; + goto sd_transfer_error; + } + } + + /* Adjust start block in current bank */ + bank_start -= bank * BLOCKS_PER_BANK; + + /* Do not cross a bank boundary in a single transfer loop */ + if((transfer + bank_start) >= BLOCKS_PER_BANK) + transfer = BLOCKS_PER_BANK - bank_start; + } + if(unaligned_transfer) { dma_buf = aligned_buffer; @@ -698,10 +700,14 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, if(write) memcpy(aligned_buffer, buf, transfer * SECTOR_SIZE); } - else + else /* Aligned transfers are faster : no memcpy */ dma_buf = buf; - if(!send_cmd(drive, cmd, arg, MCI_ARG, NULL)) + /* Set bank_start to the correct unit (blocks or bytes) */ + if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ + bank_start *= BLOCK_SIZE; + + if(!send_cmd(drive, cmd, bank_start, MCI_ARG, NULL)) { ret -= 3*20; goto sd_transfer_error; |