mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 13:15:18 -05:00
Hopefully fixes the 'two byte inserted bug' of #FS8663. Combination of Martin Ritters and my findings on the issue.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19911 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
3cf148945e
commit
0852527d5f
1 changed files with 43 additions and 16 deletions
|
|
@ -481,15 +481,47 @@ static inline void copy_read_sectors_slow(unsigned char** buf)
|
|||
/* Writes have to be kept slow for now */
|
||||
static inline void copy_write_sectors(const unsigned char** buf)
|
||||
{
|
||||
int cnt = FIFO_LEN;
|
||||
int cnt = FIFO_LEN - 1;
|
||||
unsigned t;
|
||||
long time;
|
||||
|
||||
do
|
||||
time = USEC_TIMER + 3;
|
||||
if (((intptr_t)*buf & 3) == 0)
|
||||
{
|
||||
asm volatile (
|
||||
"ldmia %[buf]!, { r3, r5, r7, r9 } \r\n"
|
||||
"mov r4, r3, lsr #16 \r\n"
|
||||
"mov r6, r5, lsr #16 \r\n"
|
||||
"mov r8, r7, lsr #16 \r\n"
|
||||
"mov r10, r9, lsr #16 \r\n"
|
||||
"stmia %[data], { r3-r10 } \r\n"
|
||||
"ldmia %[buf]!, { r3, r5, r7, r9 } \r\n"
|
||||
"mov r4, r3, lsr #16 \r\n"
|
||||
"mov r6, r5, lsr #16 \r\n"
|
||||
"mov r8, r7, lsr #16 \r\n"
|
||||
"mov %[t], r9, lsr #16 \r\n"
|
||||
"stmia %[data], { r3-r9 } \r\n"
|
||||
: [buf]"+&r"(*buf), [t]"=&r"(t)
|
||||
: [data]"r"(&MMC_DATA_FIFO)
|
||||
: "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
t = *(*buf)++;
|
||||
t |= *(*buf)++ << 8;
|
||||
MMC_DATA_FIFO = t;
|
||||
} while (--cnt > 0); /* tail loop is faster */
|
||||
t = *(*buf)++;
|
||||
t |= *(*buf)++ << 8;
|
||||
MMC_DATA_FIFO = t;
|
||||
} while (--cnt > 0); /* tail loop is faster */
|
||||
}
|
||||
/* Don't write the last word before at least 3 usec have elapsed since FIFO_EMPTY */
|
||||
/* This prevents the 'two bytes inserted' bug. */
|
||||
|
||||
while (!TIME_AFTER(USEC_TIMER, time));
|
||||
MMC_DATA_FIFO = t;
|
||||
}
|
||||
|
||||
static int sd_select_bank(unsigned char bank)
|
||||
|
|
@ -988,15 +1020,13 @@ sd_write_retry:
|
|||
{
|
||||
/* SDHC */
|
||||
ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL,
|
||||
0x1c00 | CMDAT_BUSY | CMDAT_WR_RD |
|
||||
CMDAT_DATA_EN | CMDAT_RES_TYPE1);
|
||||
CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start*BLOCK_SIZE, NULL,
|
||||
0x1c00 | CMDAT_BUSY | CMDAT_WR_RD |
|
||||
CMDAT_DATA_EN | CMDAT_RES_TYPE1);
|
||||
CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
|
||||
}
|
||||
if (ret < 0)
|
||||
goto sd_write_error;
|
||||
|
|
@ -1011,18 +1041,15 @@ sd_write_retry:
|
|||
MMC_SD_STATE = SD_PRG;
|
||||
}
|
||||
|
||||
udelay(2); /* needed here (loop is too fast :-) */
|
||||
copy_write_sectors(&buf); /* Copy one chunk of 16 words */
|
||||
/* TODO: Switch bank if necessary */
|
||||
|
||||
/* Wait for the FIFO to empty */
|
||||
if (sd_poll_status(STAT_XMIT_FIFO_EMPTY, 0x80000))
|
||||
if (!sd_poll_status(STAT_XMIT_FIFO_EMPTY, 0x80000))
|
||||
{
|
||||
copy_write_sectors(&buf); /* Copy one chunk of 16 words */
|
||||
/* TODO: Switch bank if necessary */
|
||||
continue;
|
||||
ret = -EC_FIFO_WR_EMPTY;
|
||||
goto sd_write_error;
|
||||
}
|
||||
|
||||
ret = -EC_FIFO_WR_EMPTY;
|
||||
goto sd_write_error;
|
||||
}
|
||||
|
||||
last_disk_activity = current_tick;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue