mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-10 05:35:20 -05:00
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
This commit is contained in:
parent
3ca0614de9
commit
83eb479732
1 changed files with 36 additions and 30 deletions
|
|
@ -142,8 +142,8 @@ void INT_GPIOA(void)
|
||||||
GPIOA_IC = (1<<2);
|
GPIOA_IC = (1<<2);
|
||||||
timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0);
|
timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* defined(SANSA_E200V2) || defined(SANSA_FUZE) */
|
||||||
#endif
|
#endif /* HAVE_HOTSWAP */
|
||||||
|
|
||||||
void INT_NAND(void)
|
void INT_NAND(void)
|
||||||
{
|
{
|
||||||
|
|
@ -211,7 +211,7 @@ static bool send_cmd(const int drive, const int cmd, const int arg,
|
||||||
{ /* resp received */
|
{ /* resp received */
|
||||||
if(flags & MCI_LONG_RESP)
|
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[0] = MCI_RESP3(drive);
|
||||||
response[1] = MCI_RESP2(drive);
|
response[1] = MCI_RESP2(drive);
|
||||||
response[2] = MCI_RESP1(drive);
|
response[2] = MCI_RESP1(drive);
|
||||||
|
|
@ -322,7 +322,7 @@ static int sd_init_card(const int drive)
|
||||||
|
|
||||||
card_info[drive].initialized = 1;
|
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();
|
mci_delay();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -626,7 +626,6 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start,
|
||||||
const int drive = 0;
|
const int drive = 0;
|
||||||
#endif
|
#endif
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int bank;
|
|
||||||
bool unaligned_transfer = (int)buf & 3;
|
bool unaligned_transfer = (int)buf & 3;
|
||||||
|
|
||||||
/* skip SanDisk OF */
|
/* skip SanDisk OF */
|
||||||
|
|
@ -647,29 +646,10 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start,
|
||||||
|
|
||||||
last_disk_activity = current_tick;
|
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);
|
ret = sd_wait_for_state(drive, SD_TRAN);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
ret -= 2*20;
|
ret -= 20;
|
||||||
goto sd_transfer_error;
|
goto sd_transfer_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -683,13 +663,35 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start,
|
||||||
void *dma_buf;
|
void *dma_buf;
|
||||||
const int cmd =
|
const int cmd =
|
||||||
write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
|
write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
|
||||||
int arg = start;
|
unsigned long bank_start = start;
|
||||||
if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */
|
|
||||||
arg *= BLOCK_SIZE;
|
|
||||||
|
|
||||||
/* Interrupt handler might set this to true during transfer */
|
/* Interrupt handler might set this to true during transfer */
|
||||||
retry = false;
|
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)
|
if(unaligned_transfer)
|
||||||
{
|
{
|
||||||
dma_buf = aligned_buffer;
|
dma_buf = aligned_buffer;
|
||||||
|
|
@ -698,10 +700,14 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start,
|
||||||
if(write)
|
if(write)
|
||||||
memcpy(aligned_buffer, buf, transfer * SECTOR_SIZE);
|
memcpy(aligned_buffer, buf, transfer * SECTOR_SIZE);
|
||||||
}
|
}
|
||||||
else
|
else /* Aligned transfers are faster : no memcpy */
|
||||||
dma_buf = buf;
|
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;
|
ret -= 3*20;
|
||||||
goto sd_transfer_error;
|
goto sd_transfer_error;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue