summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2009-07-11 14:27:26 +0000
committerRafaël Carré <rafael.carre@gmail.com>2009-07-11 14:27:26 +0000
commit405d12de7e5f1a5eb5a001fe183345f8f8aec72c (patch)
tree94b941b494e52908f41efa0f05694460021193bc /firmware/target/arm
parent24cf6ce2f3f8600849a512b25f357bd99837365e (diff)
downloadrockbox-405d12de7e5f1a5eb5a001fe183345f8f8aec72c.tar.gz
rockbox-405d12de7e5f1a5eb5a001fe183345f8f8aec72c.tar.bz2
rockbox-405d12de7e5f1a5eb5a001fe183345f8f8aec72c.zip
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
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/as3525/ata_sd_as3525.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c
index ae3d466abf..d959b89e7d 100644
--- a/firmware/target/arm/as3525/ata_sd_as3525.c
+++ b/firmware/target/arm/as3525/ata_sd_as3525.c
@@ -121,7 +121,8 @@ static bool sd_enabled = false;
#endif
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
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);
- if(status & MCI_ERROR)
- retry = true;
+ transfer_error[INTERNAL_AS3525] = status & MCI_ERROR;
wakeup_signal(&transfer_completion_signal);
MCI_CLEAR(INTERNAL_AS3525) = status;
@@ -173,8 +173,7 @@ void INT_MCI0(void)
{
const int status = MCI_STATUS(SD_SLOT_AS3525);
- if(status & MCI_ERROR)
- retry = true;
+ transfer_error[SD_SLOT_AS3525] = status & MCI_ERROR;
wakeup_signal(&transfer_completion_signal);
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)
{
int ret;
+ unsigned loops = 0;
do {
- /* The ISR will set this to true if an error occurred */
- retry = false;
+ if(loops++ > PL180_MAX_TRANSFER_ERRORS)
+ panicf("SD bank %d error : 0x%x", bank,
+ transfer_error[INTERNAL_AS3525]);
ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN);
if (ret < 0)
@@ -610,7 +611,7 @@ static int sd_select_bank(signed char bank)
ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN);
if (ret < 0)
return ret - 4;
- } while(retry);
+ } while(transfer_error[INTERNAL_AS3525]);
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;
#endif
int ret = 0;
+ unsigned loops = 0;
/* skip SanDisk OF */
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;
unsigned long bank_start = start;
- /* The ISR will set this to true if an error occurred */
- retry = false;
-
/* Only switch banks for internal storage */
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);
- if(!retry)
+ if(!transfer_error[drive])
{
if(!write)
memcpy(buf, uncached_buffer, transfer * SECTOR_SIZE);
buf += transfer * SECTOR_SIZE;
start += 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;