summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2009-07-10 12:51:50 +0000
committerRafaël Carré <rafael.carre@gmail.com>2009-07-10 12:51:50 +0000
commitc51e26a43da2891db80b9e38dc44b0ab3001afbe (patch)
tree2ff59b8e5474ed0edca10a64d3470de2208cc758 /firmware/target/arm
parent37c7a67b474bb8a348c0ed909932d2329e96242c (diff)
downloadrockbox-c51e26a43da2891db80b9e38dc44b0ab3001afbe.tar.gz
rockbox-c51e26a43da2891db80b9e38dc44b0ab3001afbe.tar.bz2
rockbox-c51e26a43da2891db80b9e38dc44b0ab3001afbe.zip
Sansa AMS SD driver: fix error checking in µSD insertion
If µSD init fails, rockbox will panic and give an error number Use a maximal delay of 1 second for µSD (and internal storage) init, as specified in the SD Specification 2.00 git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21742 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/as3525/ata_sd_as3525.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c
index 96ad8fea76..2766c76e41 100644
--- a/firmware/target/arm/as3525/ata_sd_as3525.c
+++ b/firmware/target/arm/as3525/ata_sd_as3525.c
@@ -49,6 +49,7 @@
#ifdef HAVE_HOTSWAP
#include "disk.h"
+#include "panic.h"
#endif
/* command flags */
@@ -242,7 +243,7 @@ static bool send_cmd(const int drive, const int cmd, const int arg,
static int sd_init_card(const int drive)
{
unsigned long response;
- int max_tries = 100; /* max acmd41 attemps */
+ long init_timeout;
bool sdhc;
unsigned long temp_reg[4];
int i;
@@ -257,29 +258,29 @@ static int sd_init_card(const int drive)
if((response & 0xFFF) == 0x1AA)
sdhc = true;
+ /* timeout for initialization is 1sec, from SD Specification 2.00 */
+ init_timeout = current_tick + HZ;
+
do {
- /* some MicroSD cards seems to need more delays, so play safe */
- mci_delay();
- mci_delay();
- mci_delay();
- mci_delay();
+ /* timeout */
+ if(current_tick > init_timeout)
+ return -2;
/* app_cmd */
if( !send_cmd(drive, SD_APP_CMD, 0, MCI_RESP|MCI_ARG, &response) ||
!(response & (1<<5)) )
{
- return -2;
+ return -3;
}
/* acmd41 */
if(!send_cmd(drive, SD_APP_OP_COND, (sdhc ? 0x40FF8000 : (1<<23)),
MCI_RESP|MCI_ARG, &card_info[drive].ocr))
- return -3;
-
- } while(!(card_info[drive].ocr & (1<<31)) && max_tries--);
+ {
+ return -4;
+ }
- if(max_tries < 0)
- return -4;
+ } while(!(card_info[drive].ocr & (1<<31)));
/* send CID */
if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP|MCI_ARG,
@@ -343,6 +344,9 @@ static void sd_thread(void)
{
struct queue_event ev;
bool idle_notified = false;
+#ifdef HAVE_HOTSWAP
+ int microsd_init;
+#endif
while (1)
{
@@ -374,8 +378,18 @@ static void sd_thread(void)
{
sd_enable(true);
init_pl180_controller(SD_SLOT_AS3525);
- sd_init_card(SD_SLOT_AS3525);
- disk_mount(SD_SLOT_AS3525);
+ microsd_init = sd_init_card(SD_SLOT_AS3525);
+ if (microsd_init < 0)
+ panicf("microSD init failed : %d", microsd_init);
+
+ if (!disk_mount(SD_SLOT_AS3525)) /* mount failed */
+ {
+ /* Access is now safe */
+ mutex_unlock(&sd_mtx);
+ fat_unlock();
+ sd_enable(false);
+ break;
+ }
}
queue_broadcast(SYS_FS_CHANGED, 0);