Sansa AMS: panic with the PL180 controller status register in case of errors

The maximum number of errors is 10 (arbitrary)
A recovery mechanism is not in place (yet) but could be implemented in the future

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21776 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Rafaël Carré 2009-07-11 14:27:26 +00:00
parent 24cf6ce2f3
commit 405d12de7e

View file

@ -121,7 +121,8 @@ static bool sd_enabled = false;
#endif #endif
static struct wakeup transfer_completion_signal; static struct wakeup transfer_completion_signal;
static volatile bool retry; static volatile unsigned int transfer_error[NUM_VOLUMES];
#define PL180_MAX_TRANSFER_ERRORS 10
#define UNALIGNED_NUM_SECTORS 10 #define UNALIGNED_NUM_SECTORS 10
static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SECTOR_SIZE] __attribute__((aligned(32))); /* align on cache line size */ static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SECTOR_SIZE] __attribute__((aligned(32))); /* align on cache line size */
@ -161,8 +162,7 @@ void INT_NAND(void)
{ {
const int status = MCI_STATUS(INTERNAL_AS3525); const int status = MCI_STATUS(INTERNAL_AS3525);
if(status & MCI_ERROR) transfer_error[INTERNAL_AS3525] = status & MCI_ERROR;
retry = true;
wakeup_signal(&transfer_completion_signal); wakeup_signal(&transfer_completion_signal);
MCI_CLEAR(INTERNAL_AS3525) = status; MCI_CLEAR(INTERNAL_AS3525) = status;
@ -173,8 +173,7 @@ void INT_MCI0(void)
{ {
const int status = MCI_STATUS(SD_SLOT_AS3525); const int status = MCI_STATUS(SD_SLOT_AS3525);
if(status & MCI_ERROR) transfer_error[SD_SLOT_AS3525] = status & MCI_ERROR;
retry = true;
wakeup_signal(&transfer_completion_signal); wakeup_signal(&transfer_completion_signal);
MCI_CLEAR(SD_SLOT_AS3525) = status; MCI_CLEAR(SD_SLOT_AS3525) = status;
@ -558,10 +557,12 @@ static int sd_wait_for_state(const int drive, unsigned int state)
static int sd_select_bank(signed char bank) static int sd_select_bank(signed char bank)
{ {
int ret; int ret;
unsigned loops = 0;
do { do {
/* The ISR will set this to true if an error occurred */ if(loops++ > PL180_MAX_TRANSFER_ERRORS)
retry = false; panicf("SD bank %d error : 0x%x", bank,
transfer_error[INTERNAL_AS3525]);
ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN); ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN);
if (ret < 0) if (ret < 0)
@ -610,7 +611,7 @@ static int sd_select_bank(signed char bank)
ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN); ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN);
if (ret < 0) if (ret < 0)
return ret - 4; return ret - 4;
} while(retry); } while(transfer_error[INTERNAL_AS3525]);
card_info[INTERNAL_AS3525].current_bank = (bank == -1) ? 0 : bank; card_info[INTERNAL_AS3525].current_bank = (bank == -1) ? 0 : bank;
@ -624,6 +625,7 @@ 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;
unsigned loops = 0;
/* skip SanDisk OF */ /* skip SanDisk OF */
if (drive == INTERNAL_AS3525) if (drive == INTERNAL_AS3525)
@ -663,9 +665,6 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start,
write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
unsigned long bank_start = start; unsigned long bank_start = start;
/* The ISR will set this to true if an error occurred */
retry = false;
/* Only switch banks for internal storage */ /* Only switch banks for internal storage */
if(drive == INTERNAL_AS3525) if(drive == INTERNAL_AS3525)
{ {
@ -728,14 +727,17 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start,
wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
if(!retry) if(!transfer_error[drive])
{ {
if(!write) if(!write)
memcpy(buf, uncached_buffer, transfer * SECTOR_SIZE); memcpy(buf, uncached_buffer, transfer * SECTOR_SIZE);
buf += transfer * SECTOR_SIZE; buf += transfer * SECTOR_SIZE;
start += transfer; start += transfer;
count -= transfer; count -= transfer;
loops = 0; /* reset errors counter */
} }
else if(loops++ > PL180_MAX_TRANSFER_ERRORS)
panicf("SD transfer error : 0x%x", transfer_error[drive]);
last_disk_activity = current_tick; last_disk_activity = current_tick;