diff options
Diffstat (limited to 'firmware/target/arm/as3525')
-rw-r--r-- | firmware/target/arm/as3525/ata_sd_as3525.c | 42 |
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 @@ | |||
49 | 49 | ||
50 | #ifdef HAVE_HOTSWAP | 50 | #ifdef HAVE_HOTSWAP |
51 | #include "disk.h" | 51 | #include "disk.h" |
52 | #include "panic.h" | ||
52 | #endif | 53 | #endif |
53 | 54 | ||
54 | /* command flags */ | 55 | /* command flags */ |
@@ -242,7 +243,7 @@ static bool send_cmd(const int drive, const int cmd, const int arg, | |||
242 | static int sd_init_card(const int drive) | 243 | static int sd_init_card(const int drive) |
243 | { | 244 | { |
244 | unsigned long response; | 245 | unsigned long response; |
245 | int max_tries = 100; /* max acmd41 attemps */ | 246 | long init_timeout; |
246 | bool sdhc; | 247 | bool sdhc; |
247 | unsigned long temp_reg[4]; | 248 | unsigned long temp_reg[4]; |
248 | int i; | 249 | int i; |
@@ -257,29 +258,29 @@ static int sd_init_card(const int drive) | |||
257 | if((response & 0xFFF) == 0x1AA) | 258 | if((response & 0xFFF) == 0x1AA) |
258 | sdhc = true; | 259 | sdhc = true; |
259 | 260 | ||
261 | /* timeout for initialization is 1sec, from SD Specification 2.00 */ | ||
262 | init_timeout = current_tick + HZ; | ||
263 | |||
260 | do { | 264 | do { |
261 | /* some MicroSD cards seems to need more delays, so play safe */ | 265 | /* timeout */ |
262 | mci_delay(); | 266 | if(current_tick > init_timeout) |
263 | mci_delay(); | 267 | return -2; |
264 | mci_delay(); | ||
265 | mci_delay(); | ||
266 | 268 | ||
267 | /* app_cmd */ | 269 | /* app_cmd */ |
268 | if( !send_cmd(drive, SD_APP_CMD, 0, MCI_RESP|MCI_ARG, &response) || | 270 | if( !send_cmd(drive, SD_APP_CMD, 0, MCI_RESP|MCI_ARG, &response) || |
269 | !(response & (1<<5)) ) | 271 | !(response & (1<<5)) ) |
270 | { | 272 | { |
271 | return -2; | 273 | return -3; |
272 | } | 274 | } |
273 | 275 | ||
274 | /* acmd41 */ | 276 | /* acmd41 */ |
275 | if(!send_cmd(drive, SD_APP_OP_COND, (sdhc ? 0x40FF8000 : (1<<23)), | 277 | if(!send_cmd(drive, SD_APP_OP_COND, (sdhc ? 0x40FF8000 : (1<<23)), |
276 | MCI_RESP|MCI_ARG, &card_info[drive].ocr)) | 278 | MCI_RESP|MCI_ARG, &card_info[drive].ocr)) |
277 | return -3; | 279 | { |
278 | 280 | return -4; | |
279 | } while(!(card_info[drive].ocr & (1<<31)) && max_tries--); | 281 | } |
280 | 282 | ||
281 | if(max_tries < 0) | 283 | } while(!(card_info[drive].ocr & (1<<31))); |
282 | return -4; | ||
283 | 284 | ||
284 | /* send CID */ | 285 | /* send CID */ |
285 | if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP|MCI_ARG, | 286 | 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) | |||
343 | { | 344 | { |
344 | struct queue_event ev; | 345 | struct queue_event ev; |
345 | bool idle_notified = false; | 346 | bool idle_notified = false; |
347 | #ifdef HAVE_HOTSWAP | ||
348 | int microsd_init; | ||
349 | #endif | ||
346 | 350 | ||
347 | while (1) | 351 | while (1) |
348 | { | 352 | { |
@@ -374,8 +378,18 @@ static void sd_thread(void) | |||
374 | { | 378 | { |
375 | sd_enable(true); | 379 | sd_enable(true); |
376 | init_pl180_controller(SD_SLOT_AS3525); | 380 | init_pl180_controller(SD_SLOT_AS3525); |
377 | sd_init_card(SD_SLOT_AS3525); | 381 | microsd_init = sd_init_card(SD_SLOT_AS3525); |
378 | disk_mount(SD_SLOT_AS3525); | 382 | if (microsd_init < 0) |
383 | panicf("microSD init failed : %d", microsd_init); | ||
384 | |||
385 | if (!disk_mount(SD_SLOT_AS3525)) /* mount failed */ | ||
386 | { | ||
387 | /* Access is now safe */ | ||
388 | mutex_unlock(&sd_mtx); | ||
389 | fat_unlock(); | ||
390 | sd_enable(false); | ||
391 | break; | ||
392 | } | ||
379 | } | 393 | } |
380 | 394 | ||
381 | queue_broadcast(SYS_FS_CHANGED, 0); | 395 | queue_broadcast(SYS_FS_CHANGED, 0); |