summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/as3525/sd-as3525.c276
-rw-r--r--firmware/target/arm/as3525/sd-as3525v2.c188
-rw-r--r--firmware/target/arm/ata-nand-telechips.c6
-rw-r--r--firmware/target/arm/imx233/ata-target.h4
-rw-r--r--firmware/target/arm/imx233/sdmmc-imx233.c190
-rw-r--r--firmware/target/arm/imx31/ata-target.h4
-rw-r--r--firmware/target/arm/pp/ata-sd-pp.c274
-rw-r--r--firmware/target/arm/pp/ata-target.h4
-rw-r--r--firmware/target/arm/rk27xx/sd-rk27xx.c187
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h4
-rw-r--r--firmware/target/arm/s3c2440/sd-s3c2440.c100
-rw-r--r--firmware/target/arm/s5l8700/ata-nand-s5l8700.c1
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c76
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c69
-rw-r--r--firmware/target/arm/tcc780x/sd-tcc780x.c129
-rw-r--r--firmware/target/arm/tms320dm320/sdmmc-dm320.c139
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c96
-rw-r--r--firmware/target/sh/archos/ondio/ata_mmc.c139
18 files changed, 692 insertions, 1194 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c
index e65a7525b6..d6c6654319 100644
--- a/firmware/target/arm/as3525/sd-as3525.c
+++ b/firmware/target/arm/as3525/sd-as3525.c
@@ -24,7 +24,6 @@
24 24
25#include "config.h" /* for HAVE_MULTIDRIVE & AMS_OF_SIZE */ 25#include "config.h" /* for HAVE_MULTIDRIVE & AMS_OF_SIZE */
26#include "fs_defines.h" 26#include "fs_defines.h"
27#include "thread.h"
28#include "led.h" 27#include "led.h"
29#include "sdmmc.h" 28#include "sdmmc.h"
30#include "system.h" 29#include "system.h"
@@ -39,20 +38,15 @@
39#include "dma-target.h" /* DMA request lines */ 38#include "dma-target.h" /* DMA request lines */
40#include "clock-target.h" 39#include "clock-target.h"
41#include "panic.h" 40#include "panic.h"
41#include "storage.h"
42
42#ifdef HAVE_BUTTON_LIGHT 43#ifdef HAVE_BUTTON_LIGHT
43#include "backlight-target.h" 44#include "backlight-target.h"
44#endif 45#endif
45#include "stdbool.h" 46
46#include "ata_idle_notify.h"
47#include "sd.h"
48#include "usb.h"
49/*#define LOGF_ENABLE*/ 47/*#define LOGF_ENABLE*/
50#include "logf.h" 48#include "logf.h"
51 49
52#ifdef HAVE_HOTSWAP
53#include "disk.h"
54#endif
55
56//#define VERIFY_WRITE 1 50//#define VERIFY_WRITE 1
57 51
58/* command flags */ 52/* command flags */
@@ -119,16 +113,19 @@ static tCardInfo card_info[NUM_DRIVES];
119#define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 100) /* 100 ms */ 113#define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 100) /* 100 ms */
120#define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 250) /* 250 ms */ 114#define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 250) /* 250 ms */
121 115
116#ifdef CONFIG_STORAGE_MULTI
117static int sd_first_drive = 0;
118#else
119#define sd_first_drive 0
120#endif
121
122/* for compatibility */ 122/* for compatibility */
123static long last_disk_activity = -1; 123static long last_disk_activity = -1;
124 124
125#define MIN_YIELD_PERIOD 5 /* ticks */ 125#define MIN_YIELD_PERIOD 5 /* ticks */
126static long next_yield = 0; 126static long next_yield = 0;
127 127
128static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)]; 128static struct mutex sd_mtx;
129static const char sd_thread_name[] = "ata/sd";
130static struct mutex sd_mtx;
131static struct event_queue sd_queue;
132bool sd_enabled = false; 129bool sd_enabled = false;
133 130
134#if defined(HAVE_MULTIDRIVE) 131#if defined(HAVE_MULTIDRIVE)
@@ -147,6 +144,59 @@ static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0])
147 144
148static inline void mci_delay(void) { udelay(1000) ; } 145static inline void mci_delay(void) { udelay(1000) ; }
149 146
147static void enable_controller(bool on)
148{
149
150#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
151 extern int buttonlight_is_on;
152#endif
153
154#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
155 static bool cpu_boosted = false;
156#endif
157
158 if (sd_enabled == on)
159 return; /* nothing to do */
160
161 sd_enabled = on;
162
163 if(on)
164 {
165#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
166 /* buttonlight AMSes need a bit of special handling for the buttonlight
167 * here due to the dual mapping of GPIOD and XPD */
168 bitmod32(&CCU_IO, 1<<2, 3<<2); /* XPD is SD-MCI interface (b3:2 = 01) */
169 if (buttonlight_is_on)
170 GPIOD_DIR &= ~(1<<7);
171 else
172 buttonlight_hw_off();
173#endif
174
175#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
176 if(card_detect_target()) /* If SD card present Boost cpu for voltage */
177 {
178 cpu_boosted = true;
179 cpu_boost(true);
180 }
181#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
182 }
183 else
184 {
185#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
186 if(cpu_boosted)
187 {
188 cpu_boost(false);
189 cpu_boosted = false;
190 }
191#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
192
193#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
194 bitmod32(&CCU_IO, 0<<2, 3<<2); /* XPD is general purpose IO (b3:2 = 00) */
195 if (buttonlight_is_on)
196 buttonlight_hw_on();
197#endif
198 }
199}
150 200
151static inline bool card_detect_target(void) 201static inline bool card_detect_target(void)
152{ 202{
@@ -161,18 +211,13 @@ static inline bool card_detect_target(void)
161#ifdef HAVE_HOTSWAP 211#ifdef HAVE_HOTSWAP
162static int sd1_oneshot_callback(struct timeout *tmo) 212static int sd1_oneshot_callback(struct timeout *tmo)
163{ 213{
164 (void)tmo;
165
166 /* This is called only if the state was stable for 300ms - check state 214 /* This is called only if the state was stable for 300ms - check state
167 * and post appropriate event. */ 215 * and post appropriate event. */
168 if (card_detect_target()) 216 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
169 { 217 SYS_HOTSWAP_EXTRACTED,
170 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 218 sd_first_drive + SD_SLOT_AS3525);
171 }
172 else
173 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
174
175 return 0; 219 return 0;
220 (void)tmo;
176} 221}
177 222
178void sd_gpioa_isr(void) 223void sd_gpioa_isr(void)
@@ -435,87 +480,6 @@ static int sd_init_card(const int drive)
435 return 0; 480 return 0;
436} 481}
437 482
438static void sd_thread(void) NORETURN_ATTR;
439static void sd_thread(void)
440{
441 struct queue_event ev;
442 bool idle_notified = false;
443
444 while (1)
445 {
446 queue_wait_w_tmo(&sd_queue, &ev, HZ);
447
448 switch ( ev.id )
449 {
450#ifdef HAVE_HOTSWAP
451 case SYS_HOTSWAP_INSERTED:
452 case SYS_HOTSWAP_EXTRACTED:;
453 int success = 1;
454
455 disk_unmount(SD_SLOT_AS3525); /* release "by force" */
456
457 mutex_lock(&sd_mtx); /* lock-out card activity */
458
459 /* Force card init for new card, re-init for re-inserted one or
460 * clear if the last attempt to init failed with an error. */
461 card_info[SD_SLOT_AS3525].initialized = 0;
462
463 if (ev.id == SYS_HOTSWAP_INSERTED)
464 {
465 success = 0;
466 sd_enable(true);
467 init_pl180_controller(SD_SLOT_AS3525);
468 int rc = sd_init_card(SD_SLOT_AS3525);
469 sd_enable(false);
470 if (rc >= 0)
471 success = 2;
472 else /* initialisation failed */
473 panicf("microSD init failed : %d", rc);
474 }
475
476 mutex_unlock(&sd_mtx);
477
478 if (success > 1)
479 success = disk_mount(SD_SLOT_AS3525); /* 0 if fail */
480
481 /*
482 * Mount succeeded, or this was an EXTRACTED event,
483 * in both cases notify the system about the changed filesystems
484 */
485 if (success)
486 queue_broadcast(SYS_FS_CHANGED, 0);
487
488 break;
489#endif /* HAVE_HOTSWAP */
490
491 case SYS_TIMEOUT:
492 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
493 {
494 idle_notified = false;
495 }
496 else
497 {
498 /* never let a timer wrap confuse us */
499 next_yield = current_tick;
500
501 if (!idle_notified)
502 {
503 call_storage_idle_notifys(false);
504 idle_notified = true;
505 }
506 }
507 break;
508
509 case SYS_USB_CONNECTED:
510 usb_acknowledge(SYS_USB_CONNECTED_ACK);
511 /* Wait until the USB cable is extracted again */
512 usb_wait_for_disconnect(&sd_queue);
513
514 break;
515 }
516 }
517}
518
519static void init_pl180_controller(const int drive) 483static void init_pl180_controller(const int drive)
520{ 484{
521 MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0; 485 MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0;
@@ -576,12 +540,8 @@ int sd_init(void)
576 /* init mutex */ 540 /* init mutex */
577 mutex_init(&sd_mtx); 541 mutex_init(&sd_mtx);
578 542
579 queue_init(&sd_queue, true); 543 sd_enabled = true; /* force action on next call */
580 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0, 544 enable_controller(false);
581 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
582
583 sd_enabled = true;
584 sd_enable(false);
585 545
586 return 0; 546 return 0;
587} 547}
@@ -698,7 +658,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
698 unsigned long response; 658 unsigned long response;
699 bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1)); 659 bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1));
700 660
701 sd_enable(true); 661 enable_controller(true);
702 led(true); 662 led(true);
703 663
704 if (card_info[drive].initialized <= 0) 664 if (card_info[drive].initialized <= 0)
@@ -873,7 +833,7 @@ sd_transfer_error:
873sd_transfer_error_nodma: 833sd_transfer_error_nodma:
874 834
875 led(false); 835 led(false);
876 sd_enable(false); 836 enable_controller(false);
877 837
878 if (ret) /* error */ 838 if (ret) /* error */
879 card_info[drive].initialized = 0; 839 card_info[drive].initialized = 0;
@@ -947,55 +907,9 @@ long sd_last_disk_activity(void)
947 907
948void sd_enable(bool on) 908void sd_enable(bool on)
949{ 909{
950#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE) 910 mutex_lock(&sd_mtx);
951 extern int buttonlight_is_on; 911 enable_controller(on);
952#endif 912 mutex_unlock(&sd_mtx);
953
954#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
955 static bool cpu_boosted = false;
956#endif
957
958 if (sd_enabled == on)
959 return; /* nothing to do */
960
961 sd_enabled = on;
962
963 if(on)
964 {
965#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
966 /* buttonlight AMSes need a bit of special handling for the buttonlight
967 * here due to the dual mapping of GPIOD and XPD */
968 bitmod32(&CCU_IO, 1<<2, 3<<2); /* XPD is SD-MCI interface (b3:2 = 01) */
969 if (buttonlight_is_on)
970 GPIOD_DIR &= ~(1<<7);
971 else
972 buttonlight_hw_off();
973#endif
974
975#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
976 if(card_detect_target()) /* If SD card present Boost cpu for voltage */
977 {
978 cpu_boosted = true;
979 cpu_boost(true);
980 }
981#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
982 }
983 else
984 {
985#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
986 if(cpu_boosted)
987 {
988 cpu_boost(false);
989 cpu_boosted = false;
990 }
991#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
992
993#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
994 bitmod32(&CCU_IO, 0<<2, 3<<2); /* XPD is general purpose IO (b3:2 = 00) */
995 if (buttonlight_is_on)
996 buttonlight_hw_on();
997#endif
998 }
999} 913}
1000 914
1001tCardInfo *card_get_info_target(int card_no) 915tCardInfo *card_get_info_target(int card_no)
@@ -1006,9 +920,45 @@ tCardInfo *card_get_info_target(int card_no)
1006#ifdef CONFIG_STORAGE_MULTI 920#ifdef CONFIG_STORAGE_MULTI
1007int sd_num_drives(int first_drive) 921int sd_num_drives(int first_drive)
1008{ 922{
1009 /* We don't care which logical drive number(s) we have been assigned */ 923 sd_first_drive = first_drive;
1010 (void)first_drive;
1011
1012 return NUM_DRIVES; 924 return NUM_DRIVES;
1013} 925}
1014#endif /* CONFIG_STORAGE_MULTI */ 926#endif /* CONFIG_STORAGE_MULTI */
927
928int sd_event(long id, intptr_t data)
929{
930 int rc = 0;
931
932 switch (id)
933 {
934#ifdef HAVE_HOTSWAP
935 case SYS_HOTSWAP_INSERTED:
936 case SYS_HOTSWAP_EXTRACTED:
937 mutex_lock(&sd_mtx); /* lock-out card activity */
938
939 /* Force card init for new card, re-init for re-inserted one or
940 * clear if the last attempt to init failed with an error. */
941 card_info[data].initialized = 0;
942
943 if (id == SYS_HOTSWAP_INSERTED)
944 {
945 enable_controller(true);
946 init_pl180_controller(data);
947 rc = sd_init_card(data);
948 enable_controller(false);
949 }
950
951 mutex_unlock(&sd_mtx);
952 break;
953#endif /* HAVE_HOTSWAP */
954 case Q_STORAGE_TICK:
955 /* never let a timer wrap confuse us */
956 next_yield = current_tick;
957 default:
958 rc = storage_event_default_handler(id, data, last_disk_activity,
959 STORAGE_SD);
960 break;
961 }
962
963 return rc;
964}
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c
index 3f39629e0b..f78345577c 100644
--- a/firmware/target/arm/as3525/sd-as3525v2.c
+++ b/firmware/target/arm/as3525/sd-as3525v2.c
@@ -22,7 +22,6 @@
22 22
23#include "config.h" /* for HAVE_MULTIVOLUME */ 23#include "config.h" /* for HAVE_MULTIVOLUME */
24#include "fs_defines.h" 24#include "fs_defines.h"
25#include "thread.h"
26#include "gcc_extensions.h" 25#include "gcc_extensions.h"
27#include "led.h" 26#include "led.h"
28#include "sdmmc.h" 27#include "sdmmc.h"
@@ -36,19 +35,7 @@
36#include "pl081.h" /* DMA controller */ 35#include "pl081.h" /* DMA controller */
37#include "dma-target.h" /* DMA request lines */ 36#include "dma-target.h" /* DMA request lines */
38#include "clock-target.h" 37#include "clock-target.h"
39#include "panic.h" 38#include "storage.h"
40#include "stdbool.h"
41#include "ata_idle_notify.h"
42#include "sd.h"
43#include "usb.h"
44
45#ifdef HAVE_HOTSWAP
46#include "disk.h"
47#endif
48
49#include "lcd.h"
50#include <stdarg.h>
51#include "sysfont.h"
52 39
53#define INTERNAL_AS3525 0 /* embedded SD card */ 40#define INTERNAL_AS3525 0 /* embedded SD card */
54#define SD_SLOT_AS3525 1 /* SD slot if present */ 41#define SD_SLOT_AS3525 1 /* SD slot if present */
@@ -327,13 +314,15 @@ static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0])
327 314
328static tCardInfo card_info[NUM_DRIVES]; 315static tCardInfo card_info[NUM_DRIVES];
329 316
317#ifdef CONFIG_STORAGE_MULTI
318static int sd_first_drive = 0;
319#else
320#define sd_first_drive 0
321#endif
322
330/* for compatibility */ 323/* for compatibility */
331static long last_disk_activity = -1; 324static long last_disk_activity = -1;
332
333static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
334static const char sd_thread_name[] = "ata/sd";
335static struct mutex sd_mtx SHAREDBSS_ATTR; 325static struct mutex sd_mtx SHAREDBSS_ATTR;
336static struct event_queue sd_queue;
337#ifndef BOOTLOADER 326#ifndef BOOTLOADER
338bool sd_enabled = false; 327bool sd_enabled = false;
339#endif 328#endif
@@ -371,6 +360,22 @@ void INT_NAND(void)
371 MCI_CTRL |= INT_ENABLE; 360 MCI_CTRL |= INT_ENABLE;
372} 361}
373 362
363#ifndef BOOTLOADER
364static void enable_controller(bool on)
365{
366 if (on)
367 {
368 bitset32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
369 CGU_SDSLOT |= (1<<7); /* interface enable */
370 }
371 else
372 {
373 CGU_SDSLOT &= ~(1<<7); /* interface enable */
374 bitclr32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
375 }
376}
377#endif /* BOOTLOADER */
378
374static inline bool card_detect_target(void) 379static inline bool card_detect_target(void)
375{ 380{
376#if defined(HAVE_MULTIDRIVE) 381#if defined(HAVE_MULTIDRIVE)
@@ -577,75 +582,6 @@ static int sd_init_card(const int drive)
577 return 0; 582 return 0;
578} 583}
579 584
580static void sd_thread(void) NORETURN_ATTR;
581static void sd_thread(void)
582{
583 struct queue_event ev;
584 bool idle_notified = false;
585
586 while (1)
587 {
588 queue_wait_w_tmo(&sd_queue, &ev, HZ);
589
590 switch ( ev.id )
591 {
592#ifdef HAVE_HOTSWAP
593 case SYS_HOTSWAP_INSERTED:
594 case SYS_HOTSWAP_EXTRACTED:;
595 int success = 1;
596
597 disk_unmount(SD_SLOT_AS3525); /* release "by force" */
598
599 mutex_lock(&sd_mtx); /* lock-out card activity */
600
601 /* Force card init for new card, re-init for re-inserted one or
602 * clear if the last attempt to init failed with an error. */
603 card_info[SD_SLOT_AS3525].initialized = 0;
604
605 if (ev.id == SYS_HOTSWAP_INSERTED)
606 {
607 sd_enable(true);
608 success = sd_init_card(SD_SLOT_AS3525) == 0 ? 2 : 0;
609 sd_enable(false);
610 }
611
612 mutex_unlock(&sd_mtx);
613
614 if (success > 1)
615 success = disk_mount(SD_SLOT_AS3525); /* 0 if fail */
616
617 /*
618 * Mount succeeded, or this was an EXTRACTED event,
619 * in both cases notify the system about the changed filesystems
620 */
621 if (success)
622 queue_broadcast(SYS_FS_CHANGED, 0);
623
624 break;
625#endif /* HAVE_HOTSWAP */
626
627 case SYS_TIMEOUT:
628 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
629 {
630 idle_notified = false;
631 }
632 else if (!idle_notified)
633 {
634 call_storage_idle_notifys(false);
635 idle_notified = true;
636 }
637 break;
638
639 case SYS_USB_CONNECTED:
640 usb_acknowledge(SYS_USB_CONNECTED_ACK);
641 /* Wait until the USB cable is extracted again */
642 usb_wait_for_disconnect(&sd_queue);
643
644 break;
645 }
646 }
647}
648
649static void init_controller(void) 585static void init_controller(void)
650{ 586{
651 int hcon_numcards = ((MCI_HCON>>1) & 0x1F) + 1; 587 int hcon_numcards = ((MCI_HCON>>1) & 0x1F) + 1;
@@ -706,6 +642,7 @@ int sd_init(void)
706 | (AS3525_SDSLOT_DIV << 2) 642 | (AS3525_SDSLOT_DIV << 2)
707 | 1; /* clock source = PLLA */ 643 | 1; /* clock source = PLLA */
708 644
645 mutex_init(&sd_mtx);
709 semaphore_init(&transfer_completion_signal, 1, 0); 646 semaphore_init(&transfer_completion_signal, 1, 0);
710 semaphore_init(&command_completion_signal, 1, 0); 647 semaphore_init(&command_completion_signal, 1, 0);
711 648
@@ -737,16 +674,9 @@ int sd_init(void)
737 if(ret < 0) 674 if(ret < 0)
738 return ret; 675 return ret;
739 676
740 /* init mutex */
741 mutex_init(&sd_mtx);
742
743 queue_init(&sd_queue, true);
744 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
745 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
746
747#ifndef BOOTLOADER 677#ifndef BOOTLOADER
748 sd_enabled = true; 678 sd_enabled = true;
749 sd_enable(false); 679 enable_controller(false);
750#endif 680#endif
751 return 0; 681 return 0;
752} 682}
@@ -767,7 +697,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
767 697
768 mutex_lock(&sd_mtx); 698 mutex_lock(&sd_mtx);
769#ifndef BOOTLOADER 699#ifndef BOOTLOADER
770 sd_enable(true); 700 enable_controller(true);
771 led(true); 701 led(true);
772#endif 702#endif
773 703
@@ -925,7 +855,7 @@ retry_with_reinit:
925 855
926exit: 856exit:
927#ifndef BOOTLOADER 857#ifndef BOOTLOADER
928 sd_enable(false); 858 enable_controller(false);
929 led(false); 859 led(false);
930#endif 860#endif
931 mutex_unlock(&sd_mtx); 861 mutex_unlock(&sd_mtx);
@@ -952,16 +882,9 @@ long sd_last_disk_activity(void)
952 882
953void sd_enable(bool on) 883void sd_enable(bool on)
954{ 884{
955 if (on) 885 mutex_lock(&sd_mtx);
956 { 886 enable_controller(on);
957 bitset32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE); 887 mutex_unlock(&sd_mtx);
958 CGU_SDSLOT |= (1<<7); /* interface enable */
959 }
960 else
961 {
962 CGU_SDSLOT &= ~(1<<7); /* interface enable */
963 bitclr32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
964 }
965} 888}
966#endif /* BOOTLOADER */ 889#endif /* BOOTLOADER */
967 890
@@ -983,18 +906,13 @@ bool sd_present(IF_MD_NONVOID(int drive))
983 906
984static int sd1_oneshot_callback(struct timeout *tmo) 907static int sd1_oneshot_callback(struct timeout *tmo)
985{ 908{
986 (void)tmo;
987
988 /* This is called only if the state was stable for 300ms - check state 909 /* This is called only if the state was stable for 300ms - check state
989 * and post appropriate event. */ 910 * and post appropriate event. */
990 if (card_detect_target()) 911 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
991 { 912 SYS_HOTSWAP_EXTRACTED,
992 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 913 sd_first_drive + SD_SLOT_AS3525);
993 }
994 else
995 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
996
997 return 0; 914 return 0;
915 (void)tmo;
998} 916}
999 917
1000void sd_gpioa_isr(void) 918void sd_gpioa_isr(void)
@@ -1012,9 +930,41 @@ void sd_gpioa_isr(void)
1012#ifdef CONFIG_STORAGE_MULTI 930#ifdef CONFIG_STORAGE_MULTI
1013int sd_num_drives(int first_drive) 931int sd_num_drives(int first_drive)
1014{ 932{
1015 /* We don't care which logical drive number(s) we have been assigned */ 933 sd_first_drive = first_drive;
1016 (void)first_drive;
1017
1018 return NUM_DRIVES; 934 return NUM_DRIVES;
1019} 935}
1020#endif /* CONFIG_STORAGE_MULTI */ 936#endif /* CONFIG_STORAGE_MULTI */
937
938int sd_event(long id, intptr_t data)
939{
940 int rc = 0;
941
942 switch (id)
943 {
944#ifdef HAVE_HOTSWAP
945 case SYS_HOTSWAP_INSERTED:
946 case SYS_HOTSWAP_EXTRACTED:
947 mutex_lock(&sd_mtx); /* lock-out card activity */
948
949 /* Force card init for new card, re-init for re-inserted one or
950 * clear if the last attempt to init failed with an error. */
951 card_info[data].initialized = 0;
952
953 if (id == SYS_HOTSWAP_INSERTED)
954 {
955 enable_controller(true);
956 rc = sd_init_card(data);
957 enable_controller(false);
958 }
959
960 mutex_unlock(&sd_mtx);
961 break;
962#endif /* HAVE_HOTSWAP */
963 default:
964 rc = storage_event_default_handler(id, data, last_disk_activity,
965 STORAGE_SD);
966 break;
967 }
968
969 return rc;
970}
diff --git a/firmware/target/arm/ata-nand-telechips.c b/firmware/target/arm/ata-nand-telechips.c
index 869a53c1ef..73d92a5215 100644
--- a/firmware/target/arm/ata-nand-telechips.c
+++ b/firmware/target/arm/ata-nand-telechips.c
@@ -1065,3 +1065,9 @@ void nand_enable(bool onoff)
1065} 1065}
1066 1066
1067#endif /* CONFIG_STORAGE_MULTI */ 1067#endif /* CONFIG_STORAGE_MULTI */
1068
1069int nand_event(long id, intptr_t data)
1070{
1071 return storage_event_default_handler(id, data, last_disk_activity,
1072 STORAGE_NAND);
1073}
diff --git a/firmware/target/arm/imx233/ata-target.h b/firmware/target/arm/imx233/ata-target.h
index a95ea03247..2c553ebbff 100644
--- a/firmware/target/arm/imx233/ata-target.h
+++ b/firmware/target/arm/imx233/ata-target.h
@@ -23,10 +23,6 @@
23 23
24#include "config.h" 24#include "config.h"
25 25
26#ifdef BOOTLOADER
27#define ATA_DRIVER_CLOSE
28#endif
29
30#ifdef HAVE_ATA_DMA 26#ifdef HAVE_ATA_DMA
31/* FIXME does this chips does MWDMA ? */ 27/* FIXME does this chips does MWDMA ? */
32#define ATA_MAX_MWDMA 2 28#define ATA_MAX_MWDMA 2
diff --git a/firmware/target/arm/imx233/sdmmc-imx233.c b/firmware/target/arm/imx233/sdmmc-imx233.c
index d3dabafecb..af090e8a07 100644
--- a/firmware/target/arm/imx233/sdmmc-imx233.c
+++ b/firmware/target/arm/imx233/sdmmc-imx233.c
@@ -217,9 +217,6 @@ static struct sdmmc_status_t sdmmc_status[SDMMC_NUM_DRIVES];
217#define SDMMC_STATUS(drive) sdmmc_status[drive] 217#define SDMMC_STATUS(drive) sdmmc_status[drive]
218 218
219/* sd only */ 219/* sd only */
220static long sdmmc_stack[(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
221static const char sdmmc_thread_name[] = "sdmmc";
222static struct event_queue sdmmc_queue;
223#if CONFIG_STORAGE & STORAGE_SD 220#if CONFIG_STORAGE & STORAGE_SD
224static int sd_first_drive; 221static int sd_first_drive;
225static unsigned _sd_num_drives; 222static unsigned _sd_num_drives;
@@ -260,10 +257,38 @@ static void sdmmc_detect_callback(int ssp)
260{ 257{
261 /* This is called only if the state was stable for 300ms - check state 258 /* This is called only if the state was stable for 300ms - check state
262 * and post appropriate event. */ 259 * and post appropriate event. */
263 if(imx233_ssp_sdmmc_detect(ssp)) 260 long evid = imx233_ssp_sdmmc_detect(ssp) ?
264 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 261 SYS_HOTSWAP_INSERTED : SYS_HOTSWAP_EXTRACTED;
265 else 262
266 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0); 263 /* Have to reverse lookup the ssp */
264 for (unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++)
265 {
266 if (SDMMC_SSP(drive) != ssp)
267 continue;
268
269 int first_drive, *map;
270 switch (SDMMC_MODE(drive))
271 {
272#if (CONFIG_STORAGE & STORAGE_MMC)
273 case MMC_MODE:
274 first_drive = mmc_first_drive;
275 map = mmc_map;
276 break;
277#endif
278#if (CONFIG_STORAGE & STORAGE_SD)
279 case SD_MODE:
280 first_drive = sd_first_drive;
281 map = sd_map;
282 break;
283#endif
284 default:
285 continue;
286 }
287
288 /* message requires logical drive number as data */
289 queue_broadcast(evid, first_drive + map[drive]);
290 }
291
267 imx233_ssp_sdmmc_setup_detect(ssp, true, sdmmc_detect_callback, false, 292 imx233_ssp_sdmmc_setup_detect(ssp, true, sdmmc_detect_callback, false,
268 imx233_ssp_sdmmc_is_detect_inverted(ssp)); 293 imx233_ssp_sdmmc_is_detect_inverted(ssp));
269} 294}
@@ -483,7 +508,48 @@ static int init_sd_card(int drive)
483 508
484 return 0; 509 return 0;
485} 510}
486#endif 511
512int sd_event(long id, intptr_t data)
513{
514 int rc = 0;
515
516 switch (id)
517 {
518#ifdef HAVE_HOTSWAP
519 case SYS_HOTSWAP_INSERTED:
520 case SYS_HOTSWAP_EXTRACTED:;
521 const int drive = sd_map[data];
522
523 /* Skip non-removable drivers */
524 if(!sdmmc_removable(drive))
525 {
526 rc = -1;
527 break;
528 }
529
530 mutex_lock(&mutex[drive]); /* lock-out card activity */
531
532 /* Force card init for new card, re-init for re-inserted one or
533 * clear if the last attempt to init failed with an error. */
534 SDMMC_INFO(drive).initialized = 0;
535
536 if(id == SYS_HOTSWAP_INSERTED)
537 rc = init_drive(drive);
538
539 /* unlock card */
540 mutex_unlock(&mutex[drive]);
541 /* Access is now safe */
542 break;
543#endif /* HAVE_HOTSWAP */
544 default:
545 rc = storage_event_default_handler(id, data, sd_last_disk_activity(),
546 STORAGE_SD);
547 break;
548 }
549
550 return rc;
551}
552#endif /* CONFIG_STORAGE & STORAGE_SD */
487 553
488#if CONFIG_STORAGE & STORAGE_MMC 554#if CONFIG_STORAGE & STORAGE_MMC
489static int init_mmc_drive(int drive) 555static int init_mmc_drive(int drive)
@@ -573,7 +639,13 @@ static int init_mmc_drive(int drive)
573 639
574 return 0; 640 return 0;
575} 641}
576#endif 642
643int mmc_event(long id, intptr_t data)
644{
645 return storage_event_default_handler(id, data, mmc_last_disk_activity(),
646 STORAGE_MMC);
647}
648#endif /* CONFIG_STORAGE & STORAGE_MMC */
577 649
578/* low-level function, don't call directly! */ 650/* low-level function, don't call directly! */
579static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, bool read) 651static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, bool read)
@@ -770,98 +842,6 @@ static int init_drive(int drive)
770 return 0; 842 return 0;
771} 843}
772 844
773static void sdmmc_thread(void) NORETURN_ATTR;
774static void sdmmc_thread(void)
775{
776 struct queue_event ev;
777 bool idle_notified = false;
778 int timeout = 0;
779
780 while (1)
781 {
782 queue_wait_w_tmo(&sdmmc_queue, &ev, HZ);
783
784 switch(ev.id)
785 {
786#if CONFIG_STORAGE & STORAGE_SD
787 case SYS_HOTSWAP_INSERTED:
788 case SYS_HOTSWAP_EXTRACTED:
789 {
790 int microsd_init = ev.id == SYS_HOTSWAP_INSERTED ? 0 : 1;
791
792 /* We now have exclusive control of fat cache and sd.
793 * Release "by force", ensure file
794 * descriptors aren't leaked and any busy
795 * ones are invalid if mounting. */
796 for(unsigned sd_drive = 0; sd_drive < _sd_num_drives; sd_drive++)
797 {
798 int drive = sd_map[sd_drive];
799 /* Skip non-removable drivers */
800 if(!sdmmc_removable(drive))
801 continue;
802
803 disk_unmount(sd_first_drive + sd_drive);
804
805 mutex_lock(&mutex[drive]); /* lock-out card activity */
806
807 /* Force card init for new card, re-init for re-inserted one or
808 * clear if the last attempt to init failed with an error. */
809 SDMMC_INFO(sd_map[sd_drive]).initialized = 0;
810
811 int rc = -1;
812 if(ev.id == SYS_HOTSWAP_INSERTED)
813 {
814 rc = init_drive(drive);
815 if(rc < 0) /* initialisation failed */
816 panicf("%s init failed : %d", SDMMC_CONF(sd_map[sd_drive]).name, rc);
817 }
818
819 /* unlock card */
820 mutex_unlock(&mutex[drive]);
821
822 if (rc >= 0)
823 microsd_init += disk_mount(sd_first_drive + sd_drive); /* 0 if fail */
824 }
825 /* Access is now safe */
826 /*
827 * One or more mounts succeeded, or this was an EXTRACTED event,
828 * in both cases notify the system about the changed filesystems
829 */
830 if(microsd_init)
831 queue_broadcast(SYS_FS_CHANGED, 0);
832
833 break;
834 }
835#endif
836 case SYS_TIMEOUT:
837#if CONFIG_STORAGE & STORAGE_SD
838 timeout = MAX(timeout, sd_last_disk_activity()+(3*HZ));
839#endif
840#if CONFIG_STORAGE & STORAGE_MMC
841 timeout = MAX(timeout, mmc_last_disk_activity()+(3*HZ));
842#endif
843 if(TIME_BEFORE(current_tick, timeout))
844 {
845 idle_notified = false;
846 }
847 else
848 {
849 if(!idle_notified)
850 {
851 call_storage_idle_notifys(false);
852 idle_notified = true;
853 }
854 }
855 break;
856 case SYS_USB_CONNECTED:
857 usb_acknowledge(SYS_USB_CONNECTED_ACK);
858 /* Wait until the USB cable is extracted again */
859 usb_wait_for_disconnect(&sdmmc_queue);
860 break;
861 }
862 }
863}
864
865static int sdmmc_init(void) 845static int sdmmc_init(void)
866{ 846{
867 static int is_initialized = false; 847 static int is_initialized = false;
@@ -871,10 +851,6 @@ static int sdmmc_init(void)
871 for(unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++) 851 for(unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++)
872 mutex_init(&mutex[drive]); 852 mutex_init(&mutex[drive]);
873 853
874 queue_init(&sdmmc_queue, true);
875 create_thread(sdmmc_thread, sdmmc_stack, sizeof(sdmmc_stack), 0,
876 sdmmc_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
877
878 for(unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++) 854 for(unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++)
879 { 855 {
880 if(sdmmc_removable(drive)) 856 if(sdmmc_removable(drive))
@@ -1024,10 +1000,6 @@ void mmc_enable(bool on)
1024 (void) on; 1000 (void) on;
1025} 1001}
1026 1002
1027void mmc_sleep(void)
1028{
1029}
1030
1031void mmc_sleepnow(void) 1003void mmc_sleepnow(void)
1032{ 1004{
1033} 1005}
diff --git a/firmware/target/arm/imx31/ata-target.h b/firmware/target/arm/imx31/ata-target.h
index 6893e83198..9363a8579c 100644
--- a/firmware/target/arm/imx31/ata-target.h
+++ b/firmware/target/arm/imx31/ata-target.h
@@ -23,10 +23,6 @@
23 23
24#include "config.h" 24#include "config.h"
25 25
26#ifdef BOOTLOADER
27#define ATA_DRIVER_CLOSE
28#endif
29
30/* Plain C read & write loops */ 26/* Plain C read & write loops */
31/* They likely won't be used anyway since DMA potentially works for any 27/* They likely won't be used anyway since DMA potentially works for any
32 * sector number and alignment. */ 28 * sector number and alignment. */
diff --git a/firmware/target/arm/pp/ata-sd-pp.c b/firmware/target/arm/pp/ata-sd-pp.c
index edb806ab96..fb0a9e150e 100644
--- a/firmware/target/arm/pp/ata-sd-pp.c
+++ b/firmware/target/arm/pp/ata-sd-pp.c
@@ -24,16 +24,10 @@
24#ifdef HAVE_HOTSWAP 24#ifdef HAVE_HOTSWAP
25#include "sd-pp-target.h" 25#include "sd-pp-target.h"
26#endif 26#endif
27#include "ata_idle_notify.h"
28#include "system.h" 27#include "system.h"
29#include <string.h> 28#include <string.h>
30#include "thread.h"
31#include "led.h" 29#include "led.h"
32#include "disk.h"
33#include "cpu.h" 30#include "cpu.h"
34#include "panic.h"
35#include "usb.h"
36#include "sd.h"
37#include "storage.h" 31#include "storage.h"
38#include "fs_defines.h" 32#include "fs_defines.h"
39 33
@@ -151,12 +145,6 @@
151/* for compatibility */ 145/* for compatibility */
152static long last_disk_activity = -1; 146static long last_disk_activity = -1;
153 147
154/** static, private data **/
155static bool initialized = false;
156static unsigned int sd_thread_id = 0;
157
158#define Q_CLOSE 1
159
160static long next_yield = 0; 148static long next_yield = 0;
161#define MIN_YIELD_PERIOD 1000 149#define MIN_YIELD_PERIOD 1000
162 150
@@ -177,30 +165,28 @@ static struct sd_card_status sd_status[NUM_DRIVES] =
177#endif 165#endif
178}; 166};
179 167
180/* Shoot for around 75% usage */ 168static struct mutex sd_mtx SHAREDBSS_ATTR;
181static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
182static const char sd_thread_name[] = "ata/sd";
183static struct mutex sd_mtx SHAREDBSS_ATTR;
184static struct event_queue sd_queue SHAREDBSS_ATTR;
185 169
186#ifdef HAVE_HOTSWAP 170#ifdef HAVE_HOTSWAP
187static int sd_first_drive = 0; 171static int sd_first_drive = 0;
188#endif 172#endif
189 173
190/* Posted when card plugged status has changed */
191#define SD_HOTSWAP 1
192/* Actions taken by sd_thread when card status has changed */
193enum sd_thread_actions
194{
195 SDA_NONE = 0x0,
196 SDA_UNMOUNTED = 0x1,
197 SDA_MOUNTED = 0x2
198};
199
200/* Private Functions */ 174/* Private Functions */
201 175
202static unsigned int check_time[NUM_EC]; 176static unsigned int check_time[NUM_EC];
203 177
178static inline void enable_controller(bool on)
179{
180 if(on)
181 {
182 DEV_EN |= DEV_ATA; /* Enable controller */
183 }
184 else
185 {
186 DEV_EN &= ~DEV_ATA; /* Disable controller */
187 }
188}
189
204static inline bool sd_check_timeout(long timeout, int id) 190static inline bool sd_check_timeout(long timeout, int id)
205{ 191{
206 return !TIME_AFTER(USEC_TIMER, check_time[id] + timeout); 192 return !TIME_AFTER(USEC_TIMER, check_time[id] + timeout);
@@ -876,7 +862,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
876 /* TODO: Add DMA support. */ 862 /* TODO: Add DMA support. */
877 863
878 mutex_lock(&sd_mtx); 864 mutex_lock(&sd_mtx);
879 sd_enable(true); 865 enable_controller(true);
880 led(true); 866 led(true);
881 867
882sd_read_retry: 868sd_read_retry:
@@ -964,7 +950,7 @@ sd_read_retry:
964 while (1) 950 while (1)
965 { 951 {
966 led(false); 952 led(false);
967 sd_enable(false); 953 enable_controller(false);
968 mutex_unlock(&sd_mtx); 954 mutex_unlock(&sd_mtx);
969 955
970 return ret; 956 return ret;
@@ -994,7 +980,7 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
994 unsigned int bank; 980 unsigned int bank;
995 981
996 mutex_lock(&sd_mtx); 982 mutex_lock(&sd_mtx);
997 sd_enable(true); 983 enable_controller(true);
998 led(true); 984 led(true);
999 985
1000sd_write_retry: 986sd_write_retry:
@@ -1092,7 +1078,7 @@ sd_write_retry:
1092 while (1) 1078 while (1)
1093 { 1079 {
1094 led(false); 1080 led(false);
1095 sd_enable(false); 1081 enable_controller(false);
1096 mutex_unlock(&sd_mtx); 1082 mutex_unlock(&sd_mtx);
1097 1083
1098 return ret; 1084 return ret;
@@ -1108,182 +1094,79 @@ sd_write_error:
1108 } 1094 }
1109} 1095}
1110 1096
1111#ifndef SD_DRIVER_CLOSE
1112static void sd_thread(void) NORETURN_ATTR;
1113#endif
1114static void sd_thread(void)
1115{
1116 struct queue_event ev;
1117 bool idle_notified = false;
1118
1119 while (1)
1120 {
1121 queue_wait_w_tmo(&sd_queue, &ev, HZ);
1122
1123 switch ( ev.id )
1124 {
1125#ifdef HAVE_HOTSWAP
1126 case SYS_HOTSWAP_INSERTED:
1127 case SYS_HOTSWAP_EXTRACTED:;
1128 int success = 1;
1129
1130 disk_unmount(sd_first_drive+1); /* release "by force" */
1131
1132 mutex_lock(&sd_mtx); /* lock-out card activity */
1133
1134 /* Force card init for new card, re-init for re-inserted one or
1135 * clear if the last attempt to init failed with an error. */
1136 card_info[1].initialized = 0;
1137 sd_status[1].retry = 0;
1138
1139 /* Access is now safe */
1140 mutex_unlock(&sd_mtx);
1141
1142 if (ev.id == SYS_HOTSWAP_INSERTED)
1143 success = disk_mount(sd_first_drive+1); /* 0 if fail */
1144
1145 if (success)
1146 queue_broadcast(SYS_FS_CHANGED, 0);
1147 break;
1148#endif /* HAVE_HOTSWAP */
1149 case SYS_TIMEOUT:
1150 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
1151 {
1152 idle_notified = false;
1153 }
1154 else
1155 {
1156 /* never let a timer wrap confuse us */
1157 next_yield = USEC_TIMER;
1158
1159 if (!idle_notified)
1160 {
1161 call_storage_idle_notifys(false);
1162 idle_notified = true;
1163 }
1164 }
1165 break;
1166 case SYS_USB_CONNECTED:
1167 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1168 /* Wait until the USB cable is extracted again */
1169 usb_wait_for_disconnect(&sd_queue);
1170 break;
1171
1172#ifdef SD_DRIVER_CLOSE
1173 case Q_CLOSE:
1174 return;
1175#endif
1176 }
1177 }
1178}
1179
1180#ifdef SD_DRIVER_CLOSE
1181void sd_close(void)
1182{
1183 unsigned int thread_id = sd_thread_id;
1184
1185 if (thread_id == 0)
1186 return;
1187
1188 sd_thread_id = 0;
1189
1190 queue_post(&sd_queue, Q_CLOSE, 0);
1191 thread_wait(thread_id);
1192}
1193#endif /* SD_DRIVER_CLOSE */
1194
1195void sd_enable(bool on) 1097void sd_enable(bool on)
1196{ 1098{
1197 if(on) 1099 mutex_lock(&sd_mtx);
1198 { 1100 enable_controller(on);
1199 DEV_EN |= DEV_ATA; /* Enable controller */ 1101 mutex_unlock(&sd_mtx);
1200 }
1201 else
1202 {
1203 DEV_EN &= ~DEV_ATA; /* Disable controller */
1204 }
1205} 1102}
1206 1103
1207
1208int sd_init(void) 1104int sd_init(void)
1209{ 1105{
1210 int ret = 0; 1106 int ret = 0;
1211 1107
1212 if (!initialized) 1108 mutex_init(&sd_mtx);
1213 mutex_init(&sd_mtx);
1214
1215 mutex_lock(&sd_mtx);
1216 1109
1217 led(false); 1110 led(false);
1218 1111
1219 if (!initialized) 1112 /* init controller */
1220 {
1221 initialized = true;
1222
1223 /* init controller */
1224#if defined(PHILIPS_SA9200) 1113#if defined(PHILIPS_SA9200)
1225 GPIOA_ENABLE = 0x00; 1114 GPIOA_ENABLE = 0x00;
1226 GPIO_SET_BITWISE(GPIOD_ENABLE, 0x01); 1115 GPIO_SET_BITWISE(GPIOD_ENABLE, 0x01);
1227#else 1116#else
1228 outl(inl(0x70000088) & ~(0x4), 0x70000088); 1117 outl(inl(0x70000088) & ~(0x4), 0x70000088);
1229 outl(inl(0x7000008c) & ~(0x4), 0x7000008c); 1118 outl(inl(0x7000008c) & ~(0x4), 0x7000008c);
1230 GPO32_ENABLE |= 0x4; 1119 GPO32_ENABLE |= 0x4;
1231 1120
1232 GPIO_SET_BITWISE(GPIOG_ENABLE, (0x3 << 5)); 1121 GPIO_SET_BITWISE(GPIOG_ENABLE, (0x3 << 5));
1233 GPIO_SET_BITWISE(GPIOG_OUTPUT_EN, (0x3 << 5)); 1122 GPIO_SET_BITWISE(GPIOG_OUTPUT_EN, (0x3 << 5));
1234 GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, (0x3 << 5)); 1123 GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, (0x3 << 5));
1235#endif 1124#endif
1236 1125
1237#ifdef HAVE_HOTSWAP 1126#ifdef HAVE_HOTSWAP
1238 /* enable card detection port - mask interrupt first */ 1127 /* enable card detection port - mask interrupt first */
1239#ifdef SANSA_E200 1128#ifdef SANSA_E200
1240 GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80); 1129 GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80);
1241 1130
1242 GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x80); 1131 GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x80);
1243 GPIO_SET_BITWISE(GPIOA_ENABLE, 0x80); 1132 GPIO_SET_BITWISE(GPIOA_ENABLE, 0x80);
1244#elif defined SANSA_C200 1133#elif defined SANSA_C200
1245 GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08); 1134 GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08);
1246 1135
1247 GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_EN, 0x08); 1136 GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_EN, 0x08);
1248 GPIO_SET_BITWISE(GPIOL_ENABLE, 0x08); 1137 GPIO_SET_BITWISE(GPIOL_ENABLE, 0x08);
1249#endif 1138#endif
1250#endif 1139#endif
1251 sd_select_device(0); 1140 sd_select_device(0);
1252
1253 if (currcard->initialized < 0)
1254 ret = currcard->initialized;
1255 1141
1256 queue_init(&sd_queue, true); 1142 if (currcard->initialized < 0)
1257 sd_thread_id = create_thread(sd_thread, sd_stack, sizeof(sd_stack), 1143 ret = currcard->initialized;
1258 0, sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
1259 IF_COP(, CPU));
1260 1144
1261 /* enable interupt for the mSD card */ 1145 /* enable interupt for the mSD card */
1262 sleep(HZ/10); 1146 sleep(HZ/10);
1263#ifdef HAVE_HOTSWAP 1147#ifdef HAVE_HOTSWAP
1264#ifdef SANSA_E200 1148#ifdef SANSA_E200
1265 CPU_INT_EN = HI_MASK; 1149 CPU_INT_EN = HI_MASK;
1266 CPU_HI_INT_EN = GPIO0_MASK; 1150 CPU_HI_INT_EN = GPIO0_MASK;
1267 1151
1268 GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80); 1152 GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80);
1269 1153
1270 GPIOA_INT_CLR = 0x80; 1154 GPIOA_INT_CLR = 0x80;
1271 1155
1272 /* enable the card detect interrupt */ 1156 /* enable the card detect interrupt */
1273 GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80); 1157 GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80);
1274#elif defined SANSA_C200 1158#elif defined SANSA_C200
1275 CPU_INT_EN = HI_MASK; 1159 CPU_INT_EN = HI_MASK;
1276 CPU_HI_INT_EN = GPIO2_MASK; 1160 CPU_HI_INT_EN = GPIO2_MASK;
1277 1161
1278 GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08); 1162 GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08);
1279 1163
1280 GPIOL_INT_CLR = 0x08; 1164 GPIOL_INT_CLR = 0x08;
1281 1165
1282 /* enable the card detect interrupt */ 1166 /* enable the card detect interrupt */
1283 GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08); 1167 GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08);
1284#endif
1285#endif 1168#endif
1286 } 1169#endif /* HAVE_HOTSWAP */
1287 1170
1288 mutex_unlock(&sd_mtx); 1171 mutex_unlock(&sd_mtx);
1289 1172
@@ -1294,19 +1177,17 @@ tCardInfo *card_get_info_target(int card_no)
1294{ 1177{
1295 return &card_info[card_no]; 1178 return &card_info[card_no];
1296} 1179}
1180
1297#ifdef HAVE_HOTSWAP 1181#ifdef HAVE_HOTSWAP
1298static int sd1_oneshot_callback(struct timeout *tmo) 1182static int sd1_oneshot_callback(struct timeout *tmo)
1299{ 1183{
1300 (void)tmo;
1301
1302 /* This is called only if the state was stable for 300ms - check state 1184 /* This is called only if the state was stable for 300ms - check state
1303 * and post appropriate event. */ 1185 * and post appropriate event. */
1304 if (card_detect_target()) 1186 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
1305 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 1187 SYS_HOTSWAP_EXTRACTED,
1306 else 1188 sd_first_drive+1);
1307 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
1308
1309 return 0; 1189 return 0;
1190 (void)tmo;
1310} 1191}
1311 1192
1312/* called on insertion/removal interrupt */ 1193/* called on insertion/removal interrupt */
@@ -1377,3 +1258,36 @@ int sd_num_drives(int first_drive)
1377#endif 1258#endif
1378} 1259}
1379#endif 1260#endif
1261
1262int sd_event(long id, intptr_t data)
1263{
1264 int rc = 0;
1265
1266 switch (id)
1267 {
1268#ifdef HAVE_HOTSWAP
1269 case SYS_HOTSWAP_INSERTED:
1270 case SYS_HOTSWAP_EXTRACTED:
1271 mutex_lock(&sd_mtx); /* lock-out card activity */
1272
1273 /* Force card init for new card, re-init for re-inserted one or
1274 * clear if the last attempt to init failed with an error. */
1275 card_info[data].initialized = 0;
1276 sd_status[data].retry = 0;
1277
1278 /* Access is now safe */
1279 mutex_unlock(&sd_mtx);
1280 break;
1281#endif /* HAVE_HOTSWAP */
1282
1283 case Q_STORAGE_TICK:
1284 /* never let a timer wrap confuse us */
1285 next_yield = USEC_TIMER;
1286 default:
1287 rc = storage_event_default_handler(id, data, last_disk_activity,
1288 STORAGE_SD);
1289 break;
1290 }
1291
1292 return rc;
1293}
diff --git a/firmware/target/arm/pp/ata-target.h b/firmware/target/arm/pp/ata-target.h
index b888f85b88..a11aeda36d 100644
--- a/firmware/target/arm/pp/ata-target.h
+++ b/firmware/target/arm/pp/ata-target.h
@@ -24,10 +24,6 @@
24 24
25#include "config.h" 25#include "config.h"
26 26
27#ifdef HAVE_BOOTLOADER_USB_MODE
28#define ATA_DRIVER_CLOSE
29#endif
30
31/* primary channel */ 27/* primary channel */
32#define ATA_DATA (*((volatile unsigned short*)(IDE_BASE + 0x1e0))) 28#define ATA_DATA (*((volatile unsigned short*)(IDE_BASE + 0x1e0)))
33#define ATA_ERROR (*((volatile unsigned char*)(IDE_BASE + 0x1e4))) 29#define ATA_ERROR (*((volatile unsigned char*)(IDE_BASE + 0x1e4)))
diff --git a/firmware/target/arm/rk27xx/sd-rk27xx.c b/firmware/target/arm/rk27xx/sd-rk27xx.c
index 6eeff7bae5..2ddfd0cf0a 100644
--- a/firmware/target/arm/rk27xx/sd-rk27xx.c
+++ b/firmware/target/arm/rk27xx/sd-rk27xx.c
@@ -34,13 +34,7 @@
34#include <string.h> 34#include <string.h>
35#include "panic.h" 35#include "panic.h"
36#include "stdbool.h" 36#include "stdbool.h"
37#include "ata_idle_notify.h" 37#include "storage.h"
38#include "sd.h"
39#include "usb.h"
40
41#ifdef HAVE_HOTSWAP
42#include "disk.h"
43#endif
44 38
45#include "lcd.h" 39#include "lcd.h"
46#include <stdarg.h> 40#include <stdarg.h>
@@ -57,21 +51,39 @@ static tCardInfo card_info;
57/* for compatibility */ 51/* for compatibility */
58static long last_disk_activity = -1; 52static long last_disk_activity = -1;
59 53
60static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
61static unsigned char aligned_buf[512] STORAGE_ALIGN_ATTR; 54static unsigned char aligned_buf[512] STORAGE_ALIGN_ATTR;
62 55
63static const char sd_thread_name[] = "ata/sd";
64static struct mutex sd_mtx SHAREDBSS_ATTR; 56static struct mutex sd_mtx SHAREDBSS_ATTR;
65static struct event_queue sd_queue;
66#ifndef BOOTLOADER 57#ifndef BOOTLOADER
67bool sd_enabled = false; 58bool sd_enabled = false;
68#endif 59#endif
69 60
61#ifdef CONFIG_STORAGE_MULTI
62static int sd_first_drive = 0;
63#else
64#define sd_first_drive 0
65#endif
66
70static struct semaphore transfer_completion_signal; 67static struct semaphore transfer_completion_signal;
71static struct semaphore command_completion_signal; 68static struct semaphore command_completion_signal;
72static volatile bool retry; 69static volatile bool retry;
73static volatile int cmd_error; 70static volatile int cmd_error;
74 71
72static void enable_controller(bool on)
73{
74 /* enable or disable clock signal for SD module */
75 if (on)
76 {
77 SCU_CLKCFG &= ~CLKCFG_SD;
78 led(true);
79 }
80 else
81 {
82 SCU_CLKCFG |= CLKCFG_SD;
83 led(false);
84 }
85}
86
75/* interrupt handler for SD */ 87/* interrupt handler for SD */
76void INT_SD(void) 88void INT_SD(void)
77{ 89{
@@ -318,81 +330,6 @@ static int sd_init_card(void)
318 return 0; 330 return 0;
319} 331}
320 332
321static void sd_thread(void) NORETURN_ATTR;
322static void sd_thread(void)
323{
324 struct queue_event ev;
325 bool idle_notified = false;
326
327 while (1)
328 {
329 queue_wait_w_tmo(&sd_queue, &ev, HZ);
330
331 switch ( ev.id )
332 {
333#ifdef HAVE_HOTSWAP
334 case SYS_HOTSWAP_INSERTED:
335 case SYS_HOTSWAP_EXTRACTED:;
336 int success = 1;
337
338 disk_unmount(sd_first_drive); /* release "by force" */
339
340 mutex_lock(&sd_mtx); /* lock-out card activity */
341
342 /* Force card init for new card, re-init for re-inserted one or
343 * clear if the last attempt to init failed with an error. */
344 card_info.initialized = 0;
345
346 if (ev.id == SYS_HOTSWAP_INSERTED)
347 {
348 success = 0;
349 sd_enable(true);
350 int rc = sd_init_card(sd_first_drive);
351 sd_enable(false);
352 if (rc >= 0)
353 success = 2;
354 else /* initialisation failed */
355 panicf("microSD init failed : %d", rc);
356 }
357
358 /* Access is now safe */
359 mutex_unlock(&sd_mtx);
360
361 if (success > 1)
362 success = disk_mount(sd_first_drive); /* 0 if fail */
363
364 /*
365 * Mount succeeded, or this was an EXTRACTED event,
366 * in both cases notify the system about the changed filesystems
367 */
368 if (success)
369 queue_broadcast(SYS_FS_CHANGED, 0);
370
371 break;
372#endif /* HAVE_HOTSWAP */
373
374 case SYS_TIMEOUT:
375 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
376 {
377 idle_notified = false;
378 }
379 else if (!idle_notified)
380 {
381 call_storage_idle_notifys(false);
382 idle_notified = true;
383 }
384 break;
385
386 case SYS_USB_CONNECTED:
387 usb_acknowledge(SYS_USB_CONNECTED_ACK);
388 /* Wait until the USB cable is extracted again */
389 usb_wait_for_disconnect(&sd_queue);
390
391 break;
392 }
393 }
394}
395
396static void init_controller(void) 333static void init_controller(void)
397{ 334{
398 /* reset SD module */ 335 /* reset SD module */
@@ -441,6 +378,7 @@ int sd_init(void)
441{ 378{
442 int ret; 379 int ret;
443 380
381 mutex_init(&sd_mtx);
444 semaphore_init(&transfer_completion_signal, 1, 0); 382 semaphore_init(&transfer_completion_signal, 1, 0);
445 semaphore_init(&command_completion_signal, 1, 0); 383 semaphore_init(&command_completion_signal, 1, 0);
446 384
@@ -450,13 +388,6 @@ int sd_init(void)
450 if(ret < 0) 388 if(ret < 0)
451 return ret; 389 return ret;
452 390
453 /* init mutex */
454 mutex_init(&sd_mtx);
455
456 queue_init(&sd_queue, true);
457 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
458 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
459
460 return 0; 391 return 0;
461} 392}
462 393
@@ -523,7 +454,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
523 unsigned char *dst; 454 unsigned char *dst;
524 455
525 mutex_lock(&sd_mtx); 456 mutex_lock(&sd_mtx);
526 sd_enable(true); 457 enable_controller(true);
527 458
528 if (count <= 0 || start + count > card_info.numblocks) 459 if (count <= 0 || start + count > card_info.numblocks)
529 return -1; 460 return -1;
@@ -627,7 +558,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
627 558
628 } /* while (retry_cnt++ < 20) */ 559 } /* while (retry_cnt++ < 20) */
629 560
630 sd_enable(false); 561 enable_controller(false);
631 mutex_unlock(&sd_mtx); 562 mutex_unlock(&sd_mtx);
632 563
633 return ret; 564 return ret;
@@ -659,7 +590,7 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
659 /* bool card_selected = false; */ 590 /* bool card_selected = false; */
660 591
661 mutex_lock(&sd_mtx); 592 mutex_lock(&sd_mtx);
662 sd_enable(true); 593 enable_controller(true);
663 594
664 if (count <= 0 || start + count > card_info.numblocks) 595 if (count <= 0 || start + count > card_info.numblocks)
665 return -1; 596 return -1;
@@ -731,7 +662,7 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
731 break; 662 break;
732 } 663 }
733 664
734 sd_enable(false); 665 enable_controller(false);
735 mutex_unlock(&sd_mtx); 666 mutex_unlock(&sd_mtx);
736 667
737#ifdef RK27XX_SD_DEBUG 668#ifdef RK27XX_SD_DEBUG
@@ -746,17 +677,9 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
746 677
747void sd_enable(bool on) 678void sd_enable(bool on)
748{ 679{
749 /* enable or disable clock signal for SD module */ 680 mutex_lock(&sd_mtx);
750 if (on) 681 enable_controller(on);
751 { 682 mutex_unlock(&sd_mtx);
752 SCU_CLKCFG &= ~CLKCFG_SD;
753 led(true);
754 }
755 else
756 {
757 SCU_CLKCFG |= CLKCFG_SD;
758 led(false);
759 }
760} 683}
761 684
762#ifndef BOOTLOADER 685#ifndef BOOTLOADER
@@ -788,18 +711,13 @@ bool sd_present(IF_MD_NONVOID(int drive))
788 711
789static int sd_oneshot_callback(struct timeout *tmo) 712static int sd_oneshot_callback(struct timeout *tmo)
790{ 713{
791 (void)tmo;
792
793 /* This is called only if the state was stable for 300ms - check state 714 /* This is called only if the state was stable for 300ms - check state
794 * and post appropriate event. */ 715 * and post appropriate event. */
795 if (card_detect_target()) 716 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
796 { 717 SYS_HOTSWAP_EXTRACTED,
797 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 718 sd_first_drive);
798 }
799 else
800 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
801
802 return 0; 719 return 0;
720 (void)tmo;
803} 721}
804 722
805/* interrupt handler for SD detect */ 723/* interrupt handler for SD detect */
@@ -809,9 +727,42 @@ static int sd_oneshot_callback(struct timeout *tmo)
809#ifdef CONFIG_STORAGE_MULTI 727#ifdef CONFIG_STORAGE_MULTI
810int sd_num_drives(int first_drive) 728int sd_num_drives(int first_drive)
811{ 729{
812 (void)first_drive;
813
814 /* we have only one SD drive */ 730 /* we have only one SD drive */
731 sd_first_drive = first_drive;
815 return 1; 732 return 1;
816} 733}
817#endif /* CONFIG_STORAGE_MULTI */ 734#endif /* CONFIG_STORAGE_MULTI */
735
736int sd_event(long id, intptr_t data)
737{
738 int rc = 0;
739
740 switch (id)
741 {
742#ifdef HAVE_HOTSWAP
743 case SYS_HOTSWAP_INSERTED:
744 case SYS_HOTSWAP_EXTRACTED:
745 mutex_lock(&sd_mtx); /* lock-out card activity */
746
747 /* Force card init for new card, re-init for re-inserted one or
748 * clear if the last attempt to init failed with an error. */
749 card_info.initialized = 0;
750
751 if (id == SYS_HOTSWAP_INSERTED)
752 {
753 enable_controller(true);
754 rc = sd_init_card();
755 enable_controller(false);
756 }
757
758 mutex_unlock(&sd_mtx);
759 break;
760#endif /* HAVE_HOTSWAP */
761 default:
762 rc = storage_event_default_handler(id, data, last_disk_activity,
763 STORAGE_SD);
764 break;
765 }
766
767 return rc;
768}
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h b/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h
index 7ca7d77c4f..5403b2418a 100644
--- a/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h
@@ -21,10 +21,6 @@
21#ifndef ATA_TARGET_H 21#ifndef ATA_TARGET_H
22#define ATA_TARGET_H 22#define ATA_TARGET_H
23 23
24#ifdef BOOTLOADER
25#define ATA_DRIVER_CLOSE
26#endif
27
28/* Plain C read & write loops */ 24/* Plain C read & write loops */
29#define PREFER_C_READING 25#define PREFER_C_READING
30#define PREFER_C_WRITING 26#define PREFER_C_WRITING
diff --git a/firmware/target/arm/s3c2440/sd-s3c2440.c b/firmware/target/arm/s3c2440/sd-s3c2440.c
index e8de3ac78d..2ff68aa4ee 100644
--- a/firmware/target/arm/s3c2440/sd-s3c2440.c
+++ b/firmware/target/arm/s3c2440/sd-s3c2440.c
@@ -21,11 +21,9 @@
21 21
22//#define SD_DEBUG 22//#define SD_DEBUG
23 23
24#include "sd.h"
25#include "system.h" 24#include "system.h"
26#include <string.h> 25#include <string.h>
27#include "gcc_extensions.h" 26#include "gcc_extensions.h"
28#include "thread.h"
29#include "panic.h" 27#include "panic.h"
30 28
31#ifdef SD_DEBUG 29#ifdef SD_DEBUG
@@ -33,8 +31,8 @@
33#endif 31#endif
34#ifdef HAVE_HOTSWAP 32#ifdef HAVE_HOTSWAP
35#include "sdmmc.h" 33#include "sdmmc.h"
36#include "disk.h"
37#endif 34#endif
35#include "storage.h"
38#include "dma-target.h" 36#include "dma-target.h"
39#include "system-target.h" 37#include "system-target.h"
40#include "led-mini2440.h" 38#include "led-mini2440.h"
@@ -90,6 +88,12 @@ struct sd_card_status
90/* for compatibility */ 88/* for compatibility */
91static long last_disk_activity = -1; 89static long last_disk_activity = -1;
92 90
91#ifdef CONFIG_STORAGE_MULTI
92static int sd_first_drive = 0;
93#else
94#define sd_first_drive 0
95#endif
96
93static bool initialized = false; 97static bool initialized = false;
94static bool sd_enabled = false; 98static bool sd_enabled = false;
95static long next_yield = 0; 99static long next_yield = 0;
@@ -109,11 +113,7 @@ static struct sd_card_status sd_status[NUM_CARDS] =
109#endif 113#endif
110#endif 114#endif
111 115
112/* Shoot for around 75% usage */
113static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
114static const char sd_thread_name[] = "sd";
115static struct mutex sd_mtx SHAREDBSS_ATTR; 116static struct mutex sd_mtx SHAREDBSS_ATTR;
116static struct event_queue sd_queue;
117static struct semaphore transfer_completion_signal; 117static struct semaphore transfer_completion_signal;
118static volatile unsigned int transfer_error[NUM_DRIVES]; 118static volatile unsigned int transfer_error[NUM_DRIVES];
119/* align on cache line size */ 119/* align on cache line size */
@@ -511,17 +511,13 @@ static inline bool card_detect_target(void)
511 511
512static int sd1_oneshot_callback(struct timeout *tmo) 512static int sd1_oneshot_callback(struct timeout *tmo)
513{ 513{
514 (void)tmo;
515
516 /* This is called only if the state was stable for 300ms - check state 514 /* This is called only if the state was stable for 300ms - check state
517 * and post appropriate event. */ 515 * and post appropriate event. */
518 if (card_detect_target()) 516 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
519 { 517 SYS_HOTSWAP_EXTRACTED,
520 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 518 sd_first_drive + CARD_NUM_SLOT);
521 }
522 else
523 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
524 return 0; 519 return 0;
520 (void)tmo;
525} 521}
526 522
527void EINT8_23(void) 523void EINT8_23(void)
@@ -571,46 +567,6 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
571#endif /* HAVE_HOTSWAP */ 567#endif /* HAVE_HOTSWAP */
572/*****************************************************************************/ 568/*****************************************************************************/
573 569
574static void sd_thread(void) NORETURN_ATTR;
575static void sd_thread(void)
576{
577 struct queue_event ev;
578
579 /* TODO */
580 while (1)
581 {
582 queue_wait_w_tmo(&sd_queue, &ev, HZ);
583 switch ( ev.id )
584 {
585#ifdef HAVE_HOTSWAP
586 case SYS_HOTSWAP_INSERTED:
587 case SYS_HOTSWAP_EXTRACTED:;
588 int success = 1;
589
590 disk_unmount(0); /* release "by force" */
591
592 mutex_lock(&sd_mtx); /* lock-out card activity */
593
594 /* Force card init for new card, re-init for re-inserted one or
595 * clear if the last attempt to init failed with an error. */
596 card_info[0].initialized = 0;
597
598 /* Access is now safe */
599 mutex_unlock(&sd_mtx);
600
601 if (ev.id == SYS_HOTSWAP_INSERTED)
602 success = disk_mount(0); /* 0 if fail */
603
604 /* notify the system about the changed filesystems
605 */
606 if (success)
607 queue_broadcast(SYS_FS_CHANGED, 0);
608 break;
609#endif /* HAVE_HOTSWAP */
610 }
611 }
612}
613
614static int sd_wait_for_state(const int card_no, unsigned int state) 570static int sd_wait_for_state(const int card_no, unsigned int state)
615{ 571{
616 unsigned long response = 0; 572 unsigned long response = 0;
@@ -907,9 +863,6 @@ int sd_init(void)
907 semaphore_init(&transfer_completion_signal, 1, 0); 863 semaphore_init(&transfer_completion_signal, 1, 0);
908 /* init mutex */ 864 /* init mutex */
909 mutex_init(&sd_mtx); 865 mutex_init(&sd_mtx);
910 queue_init(&sd_queue, true);
911 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
912 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
913 866
914 uncached_buffer = UNCACHED_ADDR(&aligned_buffer[0]); 867 uncached_buffer = UNCACHED_ADDR(&aligned_buffer[0]);
915 868
@@ -950,18 +903,11 @@ tCardInfo *card_get_info_target(int card_no)
950int sd_num_drives(int first_drive) 903int sd_num_drives(int first_drive)
951{ 904{
952 dbgprintf ("sd_num_drv"); 905 dbgprintf ("sd_num_drv");
953#if 0
954 /* Store which logical drive number(s) we have been assigned */ 906 /* Store which logical drive number(s) we have been assigned */
955 sd_first_drive = first_drive; 907 sd_first_drive = first_drive;
956#endif
957
958 return NUM_CARDS; 908 return NUM_CARDS;
959} 909}
960 910
961void sd_sleepnow(void)
962{
963}
964
965bool sd_disk_is_active(void) 911bool sd_disk_is_active(void)
966{ 912{
967 return false; 913 return false;
@@ -980,3 +926,27 @@ int sd_spinup_time(void)
980#endif /* CONFIG_STORAGE_MULTI */ 926#endif /* CONFIG_STORAGE_MULTI */
981/*****************************************************************************/ 927/*****************************************************************************/
982 928
929int sd_event(long id, intptr_t data)
930{
931 int rc = 0;
932
933 switch (id)
934 {
935#ifdef HAVE_HOTSWAP
936 case SYS_HOTSWAP_INSERTED:
937 case SYS_HOTSWAP_EXTRACTED:
938 mutex_lock(&sd_mtx);
939 /* Force card init for new card, re-init for re-inserted one or
940 * clear if the last attempt to init failed with an error. */
941 card_info[data].initialized = 0;
942 mutex_unlock(&sd_mtx);
943 break;
944#endif /* HAVE_HOTSWAP */
945 default:
946 rc = storage_event_default_handler(id, data, last_disk_activity,
947 STORAGE_SD);
948 break;
949 }
950
951 return rc;
952}
diff --git a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
index 227f6b703b..7f68b82a0d 100644
--- a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
+++ b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
@@ -52,7 +52,6 @@ void nand_spindown(int seconds)
52 52
53void nand_sleep(void) 53void nand_sleep(void)
54{ 54{
55 nand_power_down();
56} 55}
57 56
58void nand_sleepnow(void) 57void nand_sleepnow(void)
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
index 1698dc2b9b..4b74405c1c 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
+++ b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
@@ -31,8 +31,7 @@
31#include <mmu-arm.h> 31#include <mmu-arm.h>
32#include <string.h> 32#include <string.h>
33#include "led.h" 33#include "led.h"
34#include "ata_idle_notify.h" 34#include "storage.h"
35
36 35
37#define NAND_CMD_READ 0x00 36#define NAND_CMD_READ 0x00
38#define NAND_CMD_PROGCNFRM 0x10 37#define NAND_CMD_PROGCNFRM 0x10
@@ -91,7 +90,6 @@ static int nand_powered = 0;
91static int nand_interleaved = 0; 90static int nand_interleaved = 0;
92static int nand_cached = 0; 91static int nand_cached = 0;
93static long nand_last_activity_value = -1; 92static long nand_last_activity_value = -1;
94static long nand_stack[DEFAULT_STACK_SIZE];
95 93
96static struct mutex nand_mtx; 94static struct mutex nand_mtx;
97static struct semaphore nand_complete; 95static struct semaphore nand_complete;
@@ -359,20 +357,22 @@ void nand_power_up(void)
359 357
360void nand_power_down(void) 358void nand_power_down(void)
361{ 359{
362 if (!nand_powered) return;
363 mutex_lock(&nand_mtx); 360 mutex_lock(&nand_mtx);
364 pmu_ldo_power_off(4); 361 if (nand_powered)
365 PCON2 = 0x11111111; 362 {
366 PDAT2 = 0; 363 pmu_ldo_power_off(4);
367 PCON3 = 0x11111111; 364 PCON2 = 0x11111111;
368 PDAT3 = 0; 365 PDAT2 = 0;
369 PCON4 = 0x11111111; 366 PCON3 = 0x11111111;
370 PDAT4 = 0; 367 PDAT3 = 0;
371 PCON5 = (PCON5 & ~0xF) | 1; 368 PCON4 = 0x11111111;
372 PUNK5 = 1; 369 PDAT4 = 0;
373 PWRCONEXT |= 0x40; 370 PCON5 = (PCON5 & ~0xF) | 1;
374 PWRCON |= 0x100000; 371 PUNK5 = 1;
375 nand_powered = 0; 372 PWRCONEXT |= 0x40;
373 PWRCON |= 0x100000;
374 nand_powered = 0;
375 }
376 mutex_unlock(&nand_mtx); 376 mutex_unlock(&nand_mtx);
377} 377}
378 378
@@ -714,20 +714,6 @@ const struct nand_device_info_type* nand_get_device_type(uint32_t bank)
714 return &nand_deviceinfotable[nand_type[bank]]; 714 return &nand_deviceinfotable[nand_type[bank]];
715} 715}
716 716
717static void nand_thread(void)
718{
719 while (1)
720 {
721 if (TIME_AFTER(current_tick, nand_last_activity_value + HZ / 5)
722 && nand_powered)
723 {
724 call_storage_idle_notifys(false);
725 nand_power_down();
726 }
727 sleep(HZ / 10);
728 }
729}
730
731int nand_device_init(void) 717int nand_device_init(void)
732{ 718{
733 mutex_init(&nand_mtx); 719 mutex_init(&nand_mtx);
@@ -776,10 +762,30 @@ int nand_device_init(void)
776 nand_cached = ((nand_deviceinfotable[nand_type[0]].id >> 23) & 1); 762 nand_cached = ((nand_deviceinfotable[nand_type[0]].id >> 23) & 1);
777 763
778 nand_last_activity_value = current_tick; 764 nand_last_activity_value = current_tick;
779 create_thread(nand_thread, nand_stack,
780 sizeof(nand_stack), 0, "nand"
781 IF_PRIO(, PRIORITY_USER_INTERFACE)
782 IF_COP(, CPU));
783
784 return 0; 765 return 0;
785} 766}
767
768int nand_event(long id, intptr_t data)
769{
770 int rc = 0;
771
772 if (LIKELY(id == Q_STORAGE_TICK))
773 {
774 if (!nand_powered ||
775 TIME_BEFORE(current_tick, nand_last_activity_value + HZ / 5))
776 {
777 STG_EVENT_ASSERT_ACTIVE(STORAGE_NAND);
778 }
779 }
780 else if (id == Q_STORAGE_SLEEPNOW)
781 {
782 nand_power_down();
783 }
784 else
785 {
786 rc = storage_event_default_handler(id, data, nand_last_activity_value,
787 STORAGE_NAND);
788 }
789
790 return rc;
791}
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
index ef39a5cabb..36d119aff3 100644
--- a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
@@ -19,8 +19,6 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "config.h" 21#include "config.h"
22#include "thread.h"
23#include "disk.h"
24#include "storage.h" 22#include "storage.h"
25#include "timer.h" 23#include "timer.h"
26#include "kernel.h" 24#include "kernel.h"
@@ -31,8 +29,6 @@
31#include "mmcdefs-target.h" 29#include "mmcdefs-target.h"
32#include "s5l8702.h" 30#include "s5l8702.h"
33#include "led.h" 31#include "led.h"
34#include "ata_idle_notify.h"
35#include "disk_cache.h"
36 32
37 33
38#ifndef ATA_RETRIES 34#ifndef ATA_RETRIES
@@ -58,7 +54,6 @@ static struct semaphore ata_wakeup;
58static uint32_t ata_dma_flags; 54static uint32_t ata_dma_flags;
59static long ata_last_activity_value = -1; 55static long ata_last_activity_value = -1;
60static long ata_sleep_timeout = 20 * HZ; 56static long ata_sleep_timeout = 20 * HZ;
61static uint32_t ata_stack[(DEFAULT_STACK_SIZE + 0x400) / 4];
62static bool ata_powered; 57static bool ata_powered;
63static const int ata_retries = ATA_RETRIES; 58static const int ata_retries = ATA_RETRIES;
64static const bool ata_error_srst = true; 59static const bool ata_error_srst = true;
@@ -889,21 +884,6 @@ static int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool wr
889 return 0; 884 return 0;
890} 885}
891 886
892static void ata_thread(void)
893{
894 while (true)
895 {
896 mutex_lock(&ata_mutex);
897 if (TIME_AFTER(current_tick, ata_last_activity_value + ata_sleep_timeout) && ata_powered)
898 {
899 call_storage_idle_notifys(false);
900 ata_power_down();
901 }
902 mutex_unlock(&ata_mutex);
903 sleep(HZ / 2);
904 }
905}
906
907/* API Functions */ 887/* API Functions */
908int ata_soft_reset(void) 888int ata_soft_reset(void)
909{ 889{
@@ -982,11 +962,6 @@ void ata_spindown(int seconds)
982 ata_sleep_timeout = seconds * HZ; 962 ata_sleep_timeout = seconds * HZ;
983} 963}
984 964
985void ata_sleep(void)
986{
987 ata_last_activity_value = current_tick - ata_sleep_timeout + HZ / 5;
988}
989
990void ata_sleepnow(void) 965void ata_sleepnow(void)
991{ 966{
992 mutex_lock(&ata_mutex); 967 mutex_lock(&ata_mutex);
@@ -994,11 +969,6 @@ void ata_sleepnow(void)
994 mutex_unlock(&ata_mutex); 969 mutex_unlock(&ata_mutex);
995} 970}
996 971
997void ata_close(void)
998{
999 ata_sleepnow();
1000}
1001
1002void ata_spin(void) 972void ata_spin(void)
1003{ 973{
1004 ata_set_active(); 974 ata_set_active();
@@ -1034,10 +1004,6 @@ int ata_init(void)
1034 mutex_unlock(&ata_mutex); 1004 mutex_unlock(&ata_mutex);
1035 if (IS_ERR(rc)) return rc; 1005 if (IS_ERR(rc)) return rc;
1036 1006
1037 create_thread(ata_thread, ata_stack,
1038 sizeof(ata_stack), 0, "ATA idle monitor"
1039 IF_PRIO(, PRIORITY_USER_INTERFACE)
1040 IF_COP(, CPU));
1041 return 0; 1007 return 0;
1042} 1008}
1043 1009
@@ -1129,3 +1095,38 @@ void INT_MMC(void)
1129 SDCI_IRQ = irq; 1095 SDCI_IRQ = irq;
1130} 1096}
1131 1097
1098int ata_event(long id, intptr_t data)
1099{
1100 int rc = 0;
1101
1102 /* GCC does a lousy job culling unreachable cases in the default handler
1103 if statements are in a switch statement, so we'll do it this way. Only
1104 the first case is frequently hit anyway. */
1105 if (LIKELY(id == Q_STORAGE_TICK))
1106 {
1107 if (!ata_powered ||
1108 TIME_BEFORE(current_tick, ata_last_activity_value + ata_sleep_timeout))
1109 {
1110 STG_EVENT_ASSERT_ACTIVE(STORAGE_ATA);
1111 }
1112 }
1113 else if (id == Q_STORAGE_SLEEPNOW)
1114 {
1115 ata_sleepnow();
1116 }
1117 else if (id == Q_STORAGE_SLEEP)
1118 {
1119 ata_last_activity_value = current_tick - ata_sleep_timeout + HZ / 5;
1120 }
1121 else if (id == SYS_USB_CONNECTED)
1122 {
1123 STG_EVENT_ASSERT_ACTIVE(STORAGE_ATA);
1124 }
1125 else
1126 {
1127 rc = storage_event_default_handler(id, data, ata_last_activity_value,
1128 STORAGE_ATA);
1129 }
1130
1131 return rc;
1132}
diff --git a/firmware/target/arm/tcc780x/sd-tcc780x.c b/firmware/target/arm/tcc780x/sd-tcc780x.c
index ba98539157..c80c3b746f 100644
--- a/firmware/target/arm/tcc780x/sd-tcc780x.c
+++ b/firmware/target/arm/tcc780x/sd-tcc780x.c
@@ -19,17 +19,13 @@
19 * KIND, either express or implied. 19 * KIND, either express or implied.
20 * 20 *
21 ****************************************************************************/ 21 ****************************************************************************/
22#include "sd.h" 22#include "config.h"
23#include "system.h" 23#include "system.h"
24#include <string.h> 24#include <string.h>
25#include "gcc_extensions.h" 25#include "gcc_extensions.h"
26#include "sdmmc.h" 26#include "sdmmc.h"
27#include "storage.h" 27#include "storage.h"
28#include "led.h" 28#include "led.h"
29#include "thread.h"
30#include "disk.h"
31#include "ata_idle_notify.h"
32#include "usb.h"
33 29
34#if defined(HAVE_INTERNAL_SD) && defined(HAVE_HOTSWAP) 30#if defined(HAVE_INTERNAL_SD) && defined(HAVE_HOTSWAP)
35#define CARD_NUM_INTERNAL 0 31#define CARD_NUM_INTERNAL 0
@@ -55,9 +51,6 @@
55/* for compatibility */ 51/* for compatibility */
56static long last_disk_activity = -1; 52static long last_disk_activity = -1;
57 53
58/** static, private data **/
59static bool initialized = false;
60
61static long next_yield = 0; 54static long next_yield = 0;
62#define MIN_YIELD_PERIOD 1000 55#define MIN_YIELD_PERIOD 1000
63 56
@@ -80,14 +73,13 @@ static struct sd_card_status sd_status[NUM_DRIVES] =
80#endif 73#endif
81}; 74};
82 75
83/* Shoot for around 75% usage */
84static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
85static const char sd_thread_name[] = "sd";
86static struct mutex sd_mtx SHAREDBSS_ATTR; 76static struct mutex sd_mtx SHAREDBSS_ATTR;
87static struct event_queue sd_queue;
88 77
78#ifdef CONFIG_STORAGE_MULTI
89static int sd_first_drive = 0; 79static int sd_first_drive = 0;
90 80#else
81#define sd_first_drive 0
82#endif
91 83
92static bool sd_poll_status(unsigned int trigger, long timeout) 84static bool sd_poll_status(unsigned int trigger, long timeout)
93{ 85{
@@ -216,16 +208,13 @@ static inline bool card_detect_target(void)
216 208
217static int sd1_oneshot_callback(struct timeout *tmo) 209static int sd1_oneshot_callback(struct timeout *tmo)
218{ 210{
219 (void)tmo;
220
221 /* This is called only if the state was stable for 300ms - check state 211 /* This is called only if the state was stable for 300ms - check state
222 * and post appropriate event. */ 212 * and post appropriate event. */
223 if (card_detect_target()) 213 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
224 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 214 SYS_HOTSWAP_EXTRACTED,
225 else 215 sd_first_drive + CARD_NUM_SLOT);
226 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
227
228 return 0; 216 return 0;
217 (void)tmo;
229} 218}
230 219
231void EXT0(void) 220void EXT0(void)
@@ -642,71 +631,6 @@ sd_write_error:
642 } 631 }
643} 632}
644 633
645static void sd_thread(void) NORETURN_ATTR;
646static void sd_thread(void)
647{
648 struct queue_event ev;
649 bool idle_notified = false;
650
651 while (1)
652 {
653 queue_wait_w_tmo(&sd_queue, &ev, HZ);
654
655 switch ( ev.id )
656 {
657#ifdef HAVE_HOTSWAP
658 case SYS_HOTSWAP_INSERTED:
659 case SYS_HOTSWAP_EXTRACTED:;
660 int success = 1;
661
662 /* Release "by force" */
663 disk_unmount(sd_first_drive + CARD_NUM_SLOT);
664
665 mutex_lock(&sd_mtx); /* lock-out card activity */
666
667 /* Force card init for new card, re-init for re-inserted one or
668 * clear if the last attempt to init failed with an error. */
669 card_info[CARD_NUM_SLOT].initialized = 0;
670 sd_status[CARD_NUM_SLOT].retry = 0;
671
672 mutex_unlock(&sd_mtx);
673
674 if (ev.id == SYS_HOTSWAP_INSERTED)
675 success = disk_mount(sd_first_drive + CARD_NUM_SLOT);
676
677 if (success)
678 queue_broadcast(SYS_FS_CHANGED, 0);
679
680 break;
681#endif /* HAVE_HOTSWAP */
682
683 case SYS_TIMEOUT:
684 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
685 {
686 idle_notified = false;
687 }
688 else
689 {
690 /* never let a timer wrap confuse us */
691 next_yield = USEC_TIMER;
692
693 if (!idle_notified)
694 {
695 call_storage_idle_notifys(false);
696 idle_notified = true;
697 }
698 }
699 break;
700
701 case SYS_USB_CONNECTED:
702 usb_acknowledge(SYS_USB_CONNECTED_ACK);
703 /* Wait until the USB cable is extracted again */
704 usb_wait_for_disconnect(&sd_queue);
705 break;
706 }
707 }
708}
709
710void sd_enable(bool on) 634void sd_enable(bool on)
711{ 635{
712 if(on) 636 if(on)
@@ -725,6 +649,7 @@ void sd_enable(bool on)
725 649
726int sd_init(void) 650int sd_init(void)
727{ 651{
652 static bool initialized = false;
728 int ret = 0; 653 int ret = 0;
729 654
730 if (!initialized) 655 if (!initialized)
@@ -752,11 +677,6 @@ int sd_init(void)
752 /* Configure card power(?) GPIO as output */ 677 /* Configure card power(?) GPIO as output */
753 GPIOC_DIR |= (1<<24); 678 GPIOC_DIR |= (1<<24);
754 679
755 queue_init(&sd_queue, true);
756 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
757 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
758 IF_COP(, CPU));
759
760 sleep(HZ/10); 680 sleep(HZ/10);
761 681
762#ifdef HAVE_HOTSWAP 682#ifdef HAVE_HOTSWAP
@@ -794,10 +714,6 @@ int sd_num_drives(int first_drive)
794#endif 714#endif
795} 715}
796 716
797void sd_sleepnow(void)
798{
799}
800
801bool sd_disk_is_active(void) 717bool sd_disk_is_active(void)
802{ 718{
803 return false; 719 return false;
@@ -814,3 +730,28 @@ int sd_spinup_time(void)
814} 730}
815 731
816#endif /* CONFIG_STORAGE_MULTI */ 732#endif /* CONFIG_STORAGE_MULTI */
733
734int sd_event(long id, intptr_t data)
735{
736 int rc = 0;
737
738 switch (id)
739 {
740#ifdef HAVE_HOTSWAP
741 case SYS_HOTSWAP_INSERTED:
742 case SYS_HOTSWAP_EXTRACTED:
743 mutex_lock(&sd_mtx);
744 /* Force card init for new card, re-init for re-inserted one or
745 * clear if the last attempt to init failed with an error. */
746 card_info[data].initialized = 0;
747 sd_status[data].retry = 0;
748 mutex_unlock(&sd_mtx);
749 break;
750#endif /* HAVE_HOTSWAP */
751 default:
752 rc = storage_event_default_handler(id, data, last_disk_activity, STORAGE_SD);
753 break;
754 }
755
756 return rc;
757}
diff --git a/firmware/target/arm/tms320dm320/sdmmc-dm320.c b/firmware/target/arm/tms320dm320/sdmmc-dm320.c
index a6e261bcfa..8818d645d8 100644
--- a/firmware/target/arm/tms320dm320/sdmmc-dm320.c
+++ b/firmware/target/arm/tms320dm320/sdmmc-dm320.c
@@ -19,13 +19,10 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "sd.h"
23#include "system.h" 22#include "system.h"
24#include <string.h> 23#include <string.h>
25#include "gcc_extensions.h" 24#include "gcc_extensions.h"
26#include "thread.h"
27#include "panic.h" 25#include "panic.h"
28#include "kernel.h"
29#include "dma-target.h" 26#include "dma-target.h"
30#include "ata_idle_notify.h" 27#include "ata_idle_notify.h"
31 28
@@ -42,8 +39,8 @@
42#endif 39#endif
43#endif 40#endif
44#include "sdmmc.h" 41#include "sdmmc.h"
45#include "disk.h"
46#include "system-target.h" 42#include "system-target.h"
43#include "storage.h"
47 44
48/* The configuration method is not very flexible. */ 45/* The configuration method is not very flexible. */
49#define CARD_NUM_SLOT 1 46#define CARD_NUM_SLOT 1
@@ -105,7 +102,6 @@ struct sd_card_status
105static long last_disk_activity = -1; 102static long last_disk_activity = -1;
106 103
107static bool initialized = false; 104static bool initialized = false;
108static unsigned int sd_thread_id = 0;
109 105
110static bool sd_enabled = false; 106static bool sd_enabled = false;
111static long next_yield = 0; 107static long next_yield = 0;
@@ -122,10 +118,7 @@ static struct sd_card_status sd_status[NUM_CARDS] =
122}; 118};
123 119
124/* Shoot for around 75% usage */ 120/* Shoot for around 75% usage */
125static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
126static const char sd_thread_name[] = "sd";
127static struct mutex sd_mtx SHAREDBSS_ATTR; 121static struct mutex sd_mtx SHAREDBSS_ATTR;
128static struct event_queue sd_queue;
129static volatile unsigned int transfer_error[NUM_DRIVES]; 122static volatile unsigned int transfer_error[NUM_DRIVES];
130/* align on cache line size */ 123/* align on cache line size */
131static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] 124static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE]
@@ -154,20 +147,16 @@ static void sd_card_mux(int card_no)
154#endif 147#endif
155} 148}
156 149
150static inline void enable_controller(bool on)
151{
152 sd_enabled = on;
153}
157 154
158void sd_enable(bool on) 155void sd_enable(bool on)
159{ 156{
160 if (sd_enabled == on) 157 mutex_lock(&sd_mtx);
161 return; /* nothing to do */ 158 enable_controller(on);
162 159 mutex_unlock(&sd_mtx);
163 if (on)
164 {
165 sd_enabled = true;
166 }
167 else
168 {
169 sd_enabled = false;
170 }
171} 160}
172 161
173/* sets clock rate just like OF does */ 162/* sets clock rate just like OF does */
@@ -514,17 +503,13 @@ static inline bool card_detect_target(void)
514 503
515static int sd1_oneshot_callback(struct timeout *tmo) 504static int sd1_oneshot_callback(struct timeout *tmo)
516{ 505{
517 (void)tmo;
518
519 /* This is called only if the state was stable for 300ms - check state 506 /* This is called only if the state was stable for 300ms - check state
520 * and post appropriate event. */ 507 * and post appropriate event. */
521 if (card_detect_target()) 508 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
522 { 509 SYS_HOTSWAP_EXTRACTED,
523 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 510 CARD_NUM_SLOT);
524 }
525 else
526 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
527 return 0; 511 return 0;
512 (void)tmo;
528} 513}
529 514
530#ifdef SANSA_CONNECT 515#ifdef SANSA_CONNECT
@@ -577,57 +562,6 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
577 562
578#endif /* HAVE_HOTSWAP */ 563#endif /* HAVE_HOTSWAP */
579 564
580static void sd_thread(void) NORETURN_ATTR;
581static void sd_thread(void)
582{
583 struct queue_event ev;
584 bool idle_notified = false;
585
586 while (1)
587 {
588 queue_wait_w_tmo(&sd_queue, &ev, HZ);
589 switch ( ev.id )
590 {
591#ifdef HAVE_HOTSWAP
592 case SYS_HOTSWAP_INSERTED:
593 case SYS_HOTSWAP_EXTRACTED:;
594 int success = 1;
595
596 disk_unmount(0); /* release "by force" */
597
598 mutex_lock(&sd_mtx); /* lock-out card activity */
599
600 /* Force card init for new card, re-init for re-inserted one or
601 * clear if the last attempt to init failed with an error. */
602 card_info[0].initialized = 0;
603
604 mutex_unlock(&sd_mtx);
605
606 if (ev.id == SYS_HOTSWAP_INSERTED)
607 success = disk_mount(0); /* 0 if fail */
608
609 /* notify the system about the changed filesystems */
610 if (success)
611 queue_broadcast(SYS_FS_CHANGED, 0);
612
613 break;
614#endif /* HAVE_HOTSWAP */
615
616 case SYS_TIMEOUT:
617 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
618 {
619 idle_notified = false;
620 }
621 else if (!idle_notified)
622 {
623 call_storage_idle_notifys(false);
624 idle_notified = true;
625 }
626 break;
627 }
628 }
629}
630
631static int sd_wait_for_state(unsigned int state) 565static int sd_wait_for_state(unsigned int state)
632{ 566{
633 unsigned long response = 0; 567 unsigned long response = 0;
@@ -671,7 +605,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
671 605
672 dbgprintf("transfer %d %d %d", card_no, start, count); 606 dbgprintf("transfer %d %d %d", card_no, start, count);
673 mutex_lock(&sd_mtx); 607 mutex_lock(&sd_mtx);
674 sd_enable(true); 608 enable_controller(true);
675 609
676sd_transfer_retry: 610sd_transfer_retry:
677 if (card_no == CARD_NUM_SLOT && !card_detect_target()) 611 if (card_no == CARD_NUM_SLOT && !card_detect_target())
@@ -812,7 +746,7 @@ sd_transfer_retry:
812 746
813 while (1) 747 while (1)
814 { 748 {
815 sd_enable(false); 749 enable_controller(false);
816 mutex_unlock(&sd_mtx); 750 mutex_unlock(&sd_mtx);
817 751
818 return ret; 752 return ret;
@@ -860,14 +794,17 @@ int sd_init(void)
860{ 794{
861 int ret = EC_OK; 795 int ret = EC_OK;
862 796
863#ifndef BOOTLOADER 797 if (!initialized)
864 sd_enabled = true; 798 {
865 sd_enable(false); 799 mutex_init(&sd_mtx);
866#endif 800 initialized = true;
867 mutex_init(&sd_mtx); 801 }
868 802
869 mutex_lock(&sd_mtx); 803 mutex_lock(&sd_mtx);
870 initialized = true; 804
805#ifndef BOOTLOADER
806 enable_controller(false);
807#endif
871 808
872 /* based on linux/drivers/mmc/dm320mmc.c 809 /* based on linux/drivers/mmc/dm320mmc.c
873 Copyright (C) 2006 ZSI, All Rights Reserved. 810 Copyright (C) 2006 ZSI, All Rights Reserved.
@@ -919,12 +856,6 @@ int sd_init(void)
919 856
920 /* Disable Memory Card CLK - it is enabled on demand by TMS320DM320 */ 857 /* Disable Memory Card CLK - it is enabled on demand by TMS320DM320 */
921 bitclr16(&IO_MMC_MEM_CLK_CONTROL, (1 << 8)); 858 bitclr16(&IO_MMC_MEM_CLK_CONTROL, (1 << 8));
922
923 queue_init(&sd_queue, true);
924 sd_thread_id = create_thread(sd_thread, sd_stack, sizeof(sd_stack),
925 0, sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
926 IF_COP(, CPU));
927
928 mutex_unlock(&sd_mtx); 859 mutex_unlock(&sd_mtx);
929 860
930 return ret; 861 return ret;
@@ -940,7 +871,27 @@ tCardInfo *card_get_info_target(int card_no)
940 return &card_info[card_no]; 871 return &card_info[card_no];
941} 872}
942 873
943void sd_sleepnow(void) 874int sd_event(long id, intptr_t data)
944{ 875{
945} 876 int rc = 0;
946 877
878 switch (id)
879 {
880#ifdef HAVE_HOTSWAP
881 case SYS_HOTSWAP_INSERTED:
882 case SYS_HOTSWAP_EXTRACTED:
883 mutex_lock(&sd_mtx); /* lock-out card activity */
884 /* Force card init for new card, re-init for re-inserted one or
885 * clear if the last attempt to init failed with an error. */
886 card_info[data].initialized = 0;
887 mutex_unlock(&sd_mtx);
888 break;
889#endif /* HAVE_HOTSWAP */
890 default:
891 rc = storage_event_default_handler(id, data, last_disk_activity,
892 STORAGE_SD);
893 break;
894 }
895
896 return rc;
897}
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
index 0e74444cf3..3ddbff0510 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
@@ -22,32 +22,23 @@
22#include "config.h" 22#include "config.h"
23#include "gcc_extensions.h" 23#include "gcc_extensions.h"
24#include "jz4740.h" 24#include "jz4740.h"
25#include "ata.h"
26#include "ata_idle_notify.h"
27#include "ata-sd-target.h" 25#include "ata-sd-target.h"
28#include "disk.h"
29#include "led.h" 26#include "led.h"
30#include "sdmmc.h" 27#include "sdmmc.h"
31#include "logf.h" 28#include "logf.h"
32#include "sd.h"
33#include "system.h"
34#include "kernel.h"
35#include "storage.h" 29#include "storage.h"
36#include "string.h" 30#include "string.h"
37#include "usb.h"
38 31
39static long last_disk_activity = -1; 32static long last_disk_activity = -1;
40#if defined(CONFIG_STORAGE_MULTI) || defined(HAVE_HOTSWAP) 33#if defined(CONFIG_STORAGE_MULTI) || defined(HAVE_HOTSWAP)
41static int sd_drive_nr = 0; 34static int sd_drive_nr = 0;
35#else
36#define sd_drive_nr 0
42#endif 37#endif
43static tCardInfo card; 38static tCardInfo card;
44 39
45static long sd_stack[(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
46static const char sd_thread_name[] = "ata/sd";
47static struct event_queue sd_queue;
48static struct mutex sd_mtx; 40static struct mutex sd_mtx;
49static struct semaphore sd_wakeup; 41static struct semaphore sd_wakeup;
50static void sd_thread(void) NORETURN_ATTR;
51 42
52static int use_4bit; 43static int use_4bit;
53static int num_6; 44static int num_6;
@@ -1229,11 +1220,6 @@ int sd_init(void)
1229 { 1220 {
1230 semaphore_init(&sd_wakeup, 1, 0); 1221 semaphore_init(&sd_wakeup, 1, 0);
1231 mutex_init(&sd_mtx); 1222 mutex_init(&sd_mtx);
1232 queue_init(&sd_queue, true);
1233 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
1234 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
1235 IF_COP(, CPU));
1236
1237 inited = true; 1223 inited = true;
1238 } 1224 }
1239 1225
@@ -1265,7 +1251,7 @@ static inline void sd_stop_transfer(void)
1265 mutex_unlock(&sd_mtx); 1251 mutex_unlock(&sd_mtx);
1266} 1252}
1267 1253
1268int sd_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* buf) 1254int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf)
1269{ 1255{
1270#ifdef HAVE_MULTIVOLUME 1256#ifdef HAVE_MULTIVOLUME
1271 (void)drive; 1257 (void)drive;
@@ -1404,7 +1390,7 @@ int sd_soft_reset(void)
1404} 1390}
1405 1391
1406#ifdef HAVE_HOTSWAP 1392#ifdef HAVE_HOTSWAP
1407bool sd_removable(IF_MV_NONVOID(int drive)) 1393bool sd_removable(IF_MD_NONVOID(int drive))
1408{ 1394{
1409#ifdef HAVE_MULTIVOLUME 1395#ifdef HAVE_MULTIVOLUME
1410 (void)drive; 1396 (void)drive;
@@ -1414,19 +1400,16 @@ bool sd_removable(IF_MV_NONVOID(int drive))
1414 1400
1415static int sd_oneshot_callback(struct timeout *tmo) 1401static int sd_oneshot_callback(struct timeout *tmo)
1416{ 1402{
1417 (void)tmo;
1418 int state = card_detect_target(); 1403 int state = card_detect_target();
1419 1404
1420 /* This is called only if the state was stable for 300ms - check state 1405 /* This is called only if the state was stable for 300ms - check state
1421 * and post appropriate event. */ 1406 * and post appropriate event. */
1422 if (state) 1407 queue_broadcast(state ? SYS_HOTSWAP_INSERTED : SYS_HOTSWAP_EXTRACTED,
1423 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 1408 sd_drive_nr);
1424 else
1425 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
1426 1409
1427 sd_gpio_setup_irq(state); 1410 sd_gpio_setup_irq(state);
1428
1429 return 0; 1411 return 0;
1412 (void)tmo;
1430} 1413}
1431 1414
1432/* called on insertion/removal interrupt */ 1415/* called on insertion/removal interrupt */
@@ -1453,58 +1436,27 @@ int sd_num_drives(int first_drive)
1453} 1436}
1454#endif 1437#endif
1455 1438
1456static void sd_thread(void) 1439int sd_event(long id, intptr_t data)
1457{ 1440{
1458 struct queue_event ev; 1441 int rc = 0;
1459 bool idle_notified = false;
1460 1442
1461 while (1) 1443 switch (id)
1462 { 1444 {
1463 queue_wait_w_tmo(&sd_queue, &ev, HZ);
1464
1465 switch (ev.id)
1466 {
1467#ifdef HAVE_HOTSWAP 1445#ifdef HAVE_HOTSWAP
1468 case SYS_HOTSWAP_INSERTED: 1446 case SYS_HOTSWAP_INSERTED:
1469 case SYS_HOTSWAP_EXTRACTED:; 1447 case SYS_HOTSWAP_EXTRACTED:
1470 int success = 1; 1448 mutex_lock(&sd_mtx); /* lock-out card activity */
1471 1449 /* Force card init for new card, re-init for re-inserted one or
1472 disk_unmount(sd_drive_nr); /* release "by force" */ 1450 * clear if the last attempt to init failed with an error. */
1473 1451 card.initialized = 0;
1474 mutex_lock(&sd_mtx); /* lock-out card activity */ 1452 mutex_unlock(&sd_mtx);
1475 1453 break;
1476 /* Force card init for new card, re-init for re-inserted one or
1477 * clear if the last attempt to init failed with an error. */
1478 card.initialized = 0;
1479
1480 mutex_unlock(&sd_mtx);
1481
1482 if(ev.id == SYS_HOTSWAP_INSERTED)
1483 success = disk_mount(sd_drive_nr); /* 0 if fail */
1484
1485 if(success)
1486 queue_broadcast(SYS_FS_CHANGED, 0);
1487
1488 break;
1489#endif /* HAVE_HOTSWAP */ 1454#endif /* HAVE_HOTSWAP */
1490 1455 default:
1491 case SYS_TIMEOUT: 1456 rc = storage_event_default_handler(id, data, last_disk_activity,
1492 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ))) 1457 STORAGE_SD);
1493 idle_notified = false; 1458 break;
1494 else
1495 {
1496 if (!idle_notified)
1497 {
1498 call_storage_idle_notifys(false);
1499 idle_notified = true;
1500 }
1501 }
1502 break;
1503 case SYS_USB_CONNECTED:
1504 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1505 /* Wait until the USB cable is extracted again */
1506 usb_wait_for_disconnect(&sd_queue);
1507 break;
1508 }
1509 } 1459 }
1460
1461 return rc;
1510} 1462}
diff --git a/firmware/target/sh/archos/ondio/ata_mmc.c b/firmware/target/sh/archos/ondio/ata_mmc.c
index 5d95a0e789..f252e1c4ce 100644
--- a/firmware/target/sh/archos/ondio/ata_mmc.c
+++ b/firmware/target/sh/archos/ondio/ata_mmc.c
@@ -18,27 +18,29 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include <stdbool.h> 21#include "config.h"
22#include "mmc.h"
23#include "ata_mmc.h" 22#include "ata_mmc.h"
24#include "sdmmc.h" 23#include "sdmmc.h"
25#include "ata_idle_notify.h"
26#include "kernel.h" 24#include "kernel.h"
27#include "thread.h"
28#include "led.h" 25#include "led.h"
29#include "sh7034.h" 26#include "sh7034.h"
30#include "system.h" 27#include "system.h"
31#include "debug.h" 28#include "debug.h"
32#include "panic.h" 29#include "panic.h"
33#include "usb.h"
34#include "power.h" 30#include "power.h"
35#include "string.h" 31#include "string.h"
36#include "hwcompat.h" 32#include "hwcompat.h"
37#include "adc.h" 33#include "adc.h"
38#include "bitswap.h" 34#include "bitswap.h"
39#include "disk.h" /* for mount/unmount */
40#include "storage.h" 35#include "storage.h"
41 36
37
38#ifdef HAVE_MULTIDRIVE
39#define MMC_NUM_DRIVES 2
40#else
41#define MMC_NUM_DRIVES 1
42#endif
43
42#define BLOCK_SIZE 512 /* fixed */ 44#define BLOCK_SIZE 512 /* fixed */
43 45
44/* Command definitions */ 46/* Command definitions */
@@ -90,15 +92,14 @@ static long last_disk_activity = -1;
90 92
91/* private variables */ 93/* private variables */
92 94
93static struct mutex mmc_mutex SHAREDBSS_ATTR; 95#ifdef CONFIG_STORAGE_MULTI
94 96static int mmc_first_drive = 0;
95#ifdef HAVE_HOTSWAP
96static long mmc_stack[((DEFAULT_STACK_SIZE*2) + 0x800)/sizeof(long)];
97#else 97#else
98static long mmc_stack[(DEFAULT_STACK_SIZE*2)/sizeof(long)]; 98#define mmc_first_drive 0
99#endif 99#endif
100static const char mmc_thread_name[] = "mmc"; 100
101static struct event_queue mmc_queue SHAREDBSS_ATTR; 101static struct mutex mmc_mutex SHAREDBSS_ATTR;
102
102static bool initialized = false; 103static bool initialized = false;
103static bool new_mmc_circuit; 104static bool new_mmc_circuit;
104 105
@@ -158,6 +159,21 @@ static void mmc_tick(void);
158 159
159/* implementation */ 160/* implementation */
160 161
162static void enable_controller(bool on)
163{
164 PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO,
165 * if not modified below */
166 if (on)
167 PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */
168
169 and_b(~0x80, &PADRL); /* assert flash reset */
170 sleep(HZ/100);
171 or_b(0x80, &PADRL); /* de-assert flash reset */
172 sleep(HZ/100);
173 card_info[0].initialized = false;
174 card_info[1].initialized = false;
175}
176
161void mmc_enable_int_flash_clock(bool on) 177void mmc_enable_int_flash_clock(bool on)
162{ 178{
163 /* Internal flash clock is enabled by setting PA12 high with the new 179 /* Internal flash clock is enabled by setting PA12 high with the new
@@ -763,51 +779,6 @@ bool mmc_disk_is_active(void)
763 return mutex_test(&mmc_mutex); 779 return mutex_test(&mmc_mutex);
764} 780}
765 781
766static void mmc_thread(void)
767{
768 struct queue_event ev;
769 bool idle_notified = false;
770
771 while (1) {
772 queue_wait_w_tmo(&mmc_queue, &ev, HZ);
773 switch ( ev.id )
774 {
775 case SYS_USB_CONNECTED:
776 usb_acknowledge(SYS_USB_CONNECTED_ACK);
777 /* Wait until the USB cable is extracted again */
778 usb_wait_for_disconnect(&mmc_queue);
779 break;
780
781#ifdef HAVE_HOTSWAP
782 case SYS_HOTSWAP_INSERTED:
783 disk_mount(1); /* mount MMC */
784 queue_broadcast(SYS_FS_CHANGED, 0);
785 break;
786
787 case SYS_HOTSWAP_EXTRACTED:
788 disk_unmount(1); /* release "by force" */
789 queue_broadcast(SYS_FS_CHANGED, 0);
790 break;
791#endif
792
793 default:
794 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
795 {
796 idle_notified = false;
797 }
798 else
799 {
800 if (!idle_notified)
801 {
802 call_storage_idle_notifys(false);
803 idle_notified = true;
804 }
805 }
806 break;
807 }
808 }
809}
810
811bool mmc_detect(void) 782bool mmc_detect(void)
812{ 783{
813 return (adc_read(ADC_MMC_SWITCH) < 0x200); 784 return (adc_read(ADC_MMC_SWITCH) < 0x200);
@@ -868,11 +839,11 @@ static void mmc_tick(void)
868 { 839 {
869 if (current_status) 840 if (current_status)
870 { 841 {
871 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 842 queue_broadcast(SYS_HOTSWAP_INSERTED, mmc_first_drive + 1);
872 } 843 }
873 else 844 else
874 { 845 {
875 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0); 846 queue_broadcast(SYS_HOTSWAP_EXTRACTED, mmc_first_drive + 1);
876 mmc_status = MMC_UNTOUCHED; 847 mmc_status = MMC_UNTOUCHED;
877 card_info[1].initialized = false; 848 card_info[1].initialized = false;
878 } 849 }
@@ -882,17 +853,9 @@ static void mmc_tick(void)
882 853
883void mmc_enable(bool on) 854void mmc_enable(bool on)
884{ 855{
885 PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO, 856 mutex_lock(&mmc_mutex);
886 * if not modified below */ 857 enable_controller(on);
887 if (on) 858 mutex_unlock(&mmc_mutex);
888 PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */
889
890 and_b(~0x80, &PADRL); /* assert flash reset */
891 sleep(HZ/100);
892 or_b(0x80, &PADRL); /* de-assert flash reset */
893 sleep(HZ/100);
894 card_info[0].initialized = false;
895 card_info[1].initialized = false;
896} 859}
897 860
898int mmc_init(void) 861int mmc_init(void)
@@ -900,10 +863,8 @@ int mmc_init(void)
900 int rc = 0; 863 int rc = 0;
901 864
902 if (!initialized) 865 if (!initialized)
903 {
904 mutex_init(&mmc_mutex); 866 mutex_init(&mmc_mutex);
905 queue_init(&mmc_queue, true); 867
906 }
907 mutex_lock(&mmc_mutex); 868 mutex_lock(&mmc_mutex);
908 led(false); 869 led(false);
909 870
@@ -933,15 +894,10 @@ int mmc_init(void)
933 IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */ 894 IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */
934 895
935 new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0); 896 new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0);
936
937 create_thread(mmc_thread, mmc_stack,
938 sizeof(mmc_stack), 0, mmc_thread_name
939 IF_PRIO(, PRIORITY_SYSTEM)
940 IF_COP(, CPU));
941 tick_add_task(mmc_tick); 897 tick_add_task(mmc_tick);
942 initialized = true; 898 initialized = true;
943 } 899 }
944 mmc_enable(true); 900 enable_controller(true);
945 901
946 mutex_unlock(&mmc_mutex); 902 mutex_unlock(&mmc_mutex);
947 return rc; 903 return rc;
@@ -998,11 +954,6 @@ bool mmc_present(IF_MD_NONVOID(int drive))
998} 954}
999#endif 955#endif
1000 956
1001
1002void mmc_sleep(void)
1003{
1004}
1005
1006void mmc_spin(void) 957void mmc_spin(void)
1007{ 958{
1008} 959}
@@ -1015,13 +966,13 @@ void mmc_spindown(int seconds)
1015#ifdef CONFIG_STORAGE_MULTI 966#ifdef CONFIG_STORAGE_MULTI
1016int mmc_num_drives(int first_drive) 967int mmc_num_drives(int first_drive)
1017{ 968{
1018 /* We don't care which logical drive number(s) we have been assigned */ 969 mmc_first_drive = first_drive;
1019 (void)first_drive; 970 return MMC_NUM_DRIVES;
1020 971}
1021#ifdef HAVE_MULTIDRIVE 972#endif /* CONFIG_STORAGE_MULTI */
1022 return 2; 973
1023#else 974int mmc_event(long id, intptr_t data)
1024 return 1; 975{
1025#endif 976 return storage_event_default_handler(id, data, last_disk_activity,
977 STORAGE_MMC);
1026} 978}
1027#endif