diff options
Diffstat (limited to 'firmware/target/arm/as3525/ata_sd_as3525.c')
-rw-r--r-- | firmware/target/arm/as3525/ata_sd_as3525.c | 26 |
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; | |||
121 | #endif | 121 | #endif |
122 | 122 | ||
123 | static struct wakeup transfer_completion_signal; | 123 | static struct wakeup transfer_completion_signal; |
124 | static volatile bool retry; | 124 | static volatile unsigned int transfer_error[NUM_VOLUMES]; |
125 | #define PL180_MAX_TRANSFER_ERRORS 10 | ||
125 | 126 | ||
126 | #define UNALIGNED_NUM_SECTORS 10 | 127 | #define UNALIGNED_NUM_SECTORS 10 |
127 | static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SECTOR_SIZE] __attribute__((aligned(32))); /* align on cache line size */ | 128 | 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) | |||
161 | { | 162 | { |
162 | const int status = MCI_STATUS(INTERNAL_AS3525); | 163 | const int status = MCI_STATUS(INTERNAL_AS3525); |
163 | 164 | ||
164 | if(status & MCI_ERROR) | 165 | transfer_error[INTERNAL_AS3525] = status & MCI_ERROR; |
165 | retry = true; | ||
166 | 166 | ||
167 | wakeup_signal(&transfer_completion_signal); | 167 | wakeup_signal(&transfer_completion_signal); |
168 | MCI_CLEAR(INTERNAL_AS3525) = status; | 168 | MCI_CLEAR(INTERNAL_AS3525) = status; |
@@ -173,8 +173,7 @@ void INT_MCI0(void) | |||
173 | { | 173 | { |
174 | const int status = MCI_STATUS(SD_SLOT_AS3525); | 174 | const int status = MCI_STATUS(SD_SLOT_AS3525); |
175 | 175 | ||
176 | if(status & MCI_ERROR) | 176 | transfer_error[SD_SLOT_AS3525] = status & MCI_ERROR; |
177 | retry = true; | ||
178 | 177 | ||
179 | wakeup_signal(&transfer_completion_signal); | 178 | wakeup_signal(&transfer_completion_signal); |
180 | MCI_CLEAR(SD_SLOT_AS3525) = status; | 179 | MCI_CLEAR(SD_SLOT_AS3525) = status; |
@@ -558,10 +557,12 @@ static int sd_wait_for_state(const int drive, unsigned int state) | |||
558 | static int sd_select_bank(signed char bank) | 557 | static int sd_select_bank(signed char bank) |
559 | { | 558 | { |
560 | int ret; | 559 | int ret; |
560 | unsigned loops = 0; | ||
561 | 561 | ||
562 | do { | 562 | do { |
563 | /* The ISR will set this to true if an error occurred */ | 563 | if(loops++ > PL180_MAX_TRANSFER_ERRORS) |
564 | retry = false; | 564 | panicf("SD bank %d error : 0x%x", bank, |
565 | transfer_error[INTERNAL_AS3525]); | ||
565 | 566 | ||
566 | ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN); | 567 | ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN); |
567 | if (ret < 0) | 568 | if (ret < 0) |
@@ -610,7 +611,7 @@ static int sd_select_bank(signed char bank) | |||
610 | ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN); | 611 | ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN); |
611 | if (ret < 0) | 612 | if (ret < 0) |
612 | return ret - 4; | 613 | return ret - 4; |
613 | } while(retry); | 614 | } while(transfer_error[INTERNAL_AS3525]); |
614 | 615 | ||
615 | card_info[INTERNAL_AS3525].current_bank = (bank == -1) ? 0 : bank; | 616 | card_info[INTERNAL_AS3525].current_bank = (bank == -1) ? 0 : bank; |
616 | 617 | ||
@@ -624,6 +625,7 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, | |||
624 | const int drive = 0; | 625 | const int drive = 0; |
625 | #endif | 626 | #endif |
626 | int ret = 0; | 627 | int ret = 0; |
628 | unsigned loops = 0; | ||
627 | 629 | ||
628 | /* skip SanDisk OF */ | 630 | /* skip SanDisk OF */ |
629 | if (drive == INTERNAL_AS3525) | 631 | if (drive == INTERNAL_AS3525) |
@@ -663,9 +665,6 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, | |||
663 | write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; | 665 | write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; |
664 | unsigned long bank_start = start; | 666 | unsigned long bank_start = start; |
665 | 667 | ||
666 | /* The ISR will set this to true if an error occurred */ | ||
667 | retry = false; | ||
668 | |||
669 | /* Only switch banks for internal storage */ | 668 | /* Only switch banks for internal storage */ |
670 | if(drive == INTERNAL_AS3525) | 669 | if(drive == INTERNAL_AS3525) |
671 | { | 670 | { |
@@ -728,14 +727,17 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, | |||
728 | 727 | ||
729 | 728 | ||
730 | wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); | 729 | wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); |
731 | if(!retry) | 730 | if(!transfer_error[drive]) |
732 | { | 731 | { |
733 | if(!write) | 732 | if(!write) |
734 | memcpy(buf, uncached_buffer, transfer * SECTOR_SIZE); | 733 | memcpy(buf, uncached_buffer, transfer * SECTOR_SIZE); |
735 | buf += transfer * SECTOR_SIZE; | 734 | buf += transfer * SECTOR_SIZE; |
736 | start += transfer; | 735 | start += transfer; |
737 | count -= transfer; | 736 | count -= transfer; |
737 | loops = 0; /* reset errors counter */ | ||
738 | } | 738 | } |
739 | else if(loops++ > PL180_MAX_TRANSFER_ERRORS) | ||
740 | panicf("SD transfer error : 0x%x", transfer_error[drive]); | ||
739 | 741 | ||
740 | last_disk_activity = current_tick; | 742 | last_disk_activity = current_tick; |
741 | 743 | ||