1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Rafaël Carré 2009-07-10 12:51:50 +00:00
parent 37c7a67b47
commit c51e26a43d

View file

@ -49,6 +49,7 @@
#ifdef HAVE_HOTSWAP #ifdef HAVE_HOTSWAP
#include "disk.h" #include "disk.h"
#include "panic.h"
#endif #endif
/* command flags */ /* 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) static int sd_init_card(const int drive)
{ {
unsigned long response; unsigned long response;
int max_tries = 100; /* max acmd41 attemps */ long init_timeout;
bool sdhc; bool sdhc;
unsigned long temp_reg[4]; unsigned long temp_reg[4];
int i; int i;
@ -257,29 +258,29 @@ static int sd_init_card(const int drive)
if((response & 0xFFF) == 0x1AA) if((response & 0xFFF) == 0x1AA)
sdhc = true; sdhc = true;
/* timeout for initialization is 1sec, from SD Specification 2.00 */
init_timeout = current_tick + HZ;
do { do {
/* some MicroSD cards seems to need more delays, so play safe */ /* timeout */
mci_delay(); if(current_tick > init_timeout)
mci_delay(); return -2;
mci_delay();
mci_delay();
/* app_cmd */ /* app_cmd */
if( !send_cmd(drive, SD_APP_CMD, 0, MCI_RESP|MCI_ARG, &response) || if( !send_cmd(drive, SD_APP_CMD, 0, MCI_RESP|MCI_ARG, &response) ||
!(response & (1<<5)) ) !(response & (1<<5)) )
{ {
return -2; return -3;
} }
/* acmd41 */ /* acmd41 */
if(!send_cmd(drive, SD_APP_OP_COND, (sdhc ? 0x40FF8000 : (1<<23)), if(!send_cmd(drive, SD_APP_OP_COND, (sdhc ? 0x40FF8000 : (1<<23)),
MCI_RESP|MCI_ARG, &card_info[drive].ocr)) MCI_RESP|MCI_ARG, &card_info[drive].ocr))
return -3; {
} while(!(card_info[drive].ocr & (1<<31)) && max_tries--);
if(max_tries < 0)
return -4; return -4;
}
} while(!(card_info[drive].ocr & (1<<31)));
/* send CID */ /* send CID */
if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP|MCI_ARG, 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; struct queue_event ev;
bool idle_notified = false; bool idle_notified = false;
#ifdef HAVE_HOTSWAP
int microsd_init;
#endif
while (1) while (1)
{ {
@ -374,8 +378,18 @@ static void sd_thread(void)
{ {
sd_enable(true); sd_enable(true);
init_pl180_controller(SD_SLOT_AS3525); init_pl180_controller(SD_SLOT_AS3525);
sd_init_card(SD_SLOT_AS3525); microsd_init = sd_init_card(SD_SLOT_AS3525);
disk_mount(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); queue_broadcast(SYS_FS_CHANGED, 0);