Index: firmware/target/arm/as3525/debug-as3525.c
===================================================================
--- firmware/target/arm/as3525/debug-as3525.c (revision 21087)
+++ firmware/target/arm/as3525/debug-as3525.c (working copy)
@@ -28,6 +28,7 @@
#include "sprintf.h"
#include "cpu.h"
#include "pl180.h"
+#include "sd.h"

#define _DEBUG_PRINTF(a,varargs...) \
snprintf(buf, sizeof(buf), (a), ##varargs); lcd_puts(0,line++,buf)
@@ -339,10 +340,11 @@
{
char buf[50];
int line;
+ int buf2[128*2];

lcd_clear_display();
lcd_setfont(FONT_SYSFIXED);
-
+ sd_read_sectors(0, 0x7A7800 - 0xf000 - 1, 2, buf2);
while(1)
{
line = 0;
@@ -359,6 +361,7 @@
line++;
_DEBUG_PRINTF("[CP15]");
_DEBUG_PRINTF("CP15: 0x%8x", read_cp15());
+ _DEBUG_PRINTF("bank1 last: %x bank2 1st: %x", buf2[127], buf2[128]);
lcd_update();
if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
break;
Index: firmware/target/arm/as3525/ata_sd_as3525.c
===================================================================
--- firmware/target/arm/as3525/ata_sd_as3525.c (revision 21087)
+++ firmware/target/arm/as3525/ata_sd_as3525.c (working copy)
@@ -142,8 +142,8 @@
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 @@
{ /* 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 @@

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();

/*
@@ -627,7 +627,6 @@
const int drive = 0;
#endif
int ret = 0;
- int bank;
bool unaligned_transfer = (int)buf & 3;

/* skip SanDisk OF */
@@ -648,29 +647,10 @@

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;
}

@@ -684,13 +664,35 @@
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;
@@ -699,10 +701,14 @@
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;