diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/as3525/sd-as3525.c | 276 | ||||
-rw-r--r-- | firmware/target/arm/as3525/sd-as3525v2.c | 188 | ||||
-rw-r--r-- | firmware/target/arm/ata-nand-telechips.c | 6 | ||||
-rw-r--r-- | firmware/target/arm/imx233/ata-target.h | 4 | ||||
-rw-r--r-- | firmware/target/arm/imx233/sdmmc-imx233.c | 190 | ||||
-rw-r--r-- | firmware/target/arm/imx31/ata-target.h | 4 | ||||
-rw-r--r-- | firmware/target/arm/pp/ata-sd-pp.c | 274 | ||||
-rw-r--r-- | firmware/target/arm/pp/ata-target.h | 4 | ||||
-rw-r--r-- | firmware/target/arm/rk27xx/sd-rk27xx.c | 187 | ||||
-rw-r--r-- | firmware/target/arm/s3c2440/gigabeat-fx/ata-target.h | 4 | ||||
-rw-r--r-- | firmware/target/arm/s3c2440/sd-s3c2440.c | 100 | ||||
-rw-r--r-- | firmware/target/arm/s5l8700/ata-nand-s5l8700.c | 1 | ||||
-rw-r--r-- | firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c | 76 | ||||
-rw-r--r-- | firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c | 69 | ||||
-rw-r--r-- | firmware/target/arm/tcc780x/sd-tcc780x.c | 129 | ||||
-rw-r--r-- | firmware/target/arm/tms320dm320/sdmmc-dm320.c | 139 |
16 files changed, 623 insertions, 1028 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 | ||
117 | static int sd_first_drive = 0; | ||
118 | #else | ||
119 | #define sd_first_drive 0 | ||
120 | #endif | ||
121 | |||
122 | /* for compatibility */ | 122 | /* for compatibility */ |
123 | static long last_disk_activity = -1; | 123 | static long last_disk_activity = -1; |
124 | 124 | ||
125 | #define MIN_YIELD_PERIOD 5 /* ticks */ | 125 | #define MIN_YIELD_PERIOD 5 /* ticks */ |
126 | static long next_yield = 0; | 126 | static long next_yield = 0; |
127 | 127 | ||
128 | static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)]; | 128 | static struct mutex sd_mtx; |
129 | static const char sd_thread_name[] = "ata/sd"; | ||
130 | static struct mutex sd_mtx; | ||
131 | static struct event_queue sd_queue; | ||
132 | bool sd_enabled = false; | 129 | bool 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 | ||
148 | static inline void mci_delay(void) { udelay(1000) ; } | 145 | static inline void mci_delay(void) { udelay(1000) ; } |
149 | 146 | ||
147 | static 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 | ||
151 | static inline bool card_detect_target(void) | 201 | static 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 |
162 | static int sd1_oneshot_callback(struct timeout *tmo) | 212 | static 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 | ||
178 | void sd_gpioa_isr(void) | 223 | void 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 | ||
438 | static void sd_thread(void) NORETURN_ATTR; | ||
439 | static 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 | |||
519 | static void init_pl180_controller(const int drive) | 483 | static 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: | |||
873 | sd_transfer_error_nodma: | 833 | sd_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 | ||
948 | void sd_enable(bool on) | 908 | void 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 | ||
1001 | tCardInfo *card_get_info_target(int card_no) | 915 | tCardInfo *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 |
1007 | int sd_num_drives(int first_drive) | 921 | int 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 | |||
928 | int 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 | ||
328 | static tCardInfo card_info[NUM_DRIVES]; | 315 | static tCardInfo card_info[NUM_DRIVES]; |
329 | 316 | ||
317 | #ifdef CONFIG_STORAGE_MULTI | ||
318 | static int sd_first_drive = 0; | ||
319 | #else | ||
320 | #define sd_first_drive 0 | ||
321 | #endif | ||
322 | |||
330 | /* for compatibility */ | 323 | /* for compatibility */ |
331 | static long last_disk_activity = -1; | 324 | static long last_disk_activity = -1; |
332 | |||
333 | static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)]; | ||
334 | static const char sd_thread_name[] = "ata/sd"; | ||
335 | static struct mutex sd_mtx SHAREDBSS_ATTR; | 325 | static struct mutex sd_mtx SHAREDBSS_ATTR; |
336 | static struct event_queue sd_queue; | ||
337 | #ifndef BOOTLOADER | 326 | #ifndef BOOTLOADER |
338 | bool sd_enabled = false; | 327 | bool 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 | ||
364 | static 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 | |||
374 | static inline bool card_detect_target(void) | 379 | static 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 | ||
580 | static void sd_thread(void) NORETURN_ATTR; | ||
581 | static 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 | |||
649 | static void init_controller(void) | 585 | static 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 | ||
926 | exit: | 856 | exit: |
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 | ||
953 | void sd_enable(bool on) | 883 | void 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 | ||
984 | static int sd1_oneshot_callback(struct timeout *tmo) | 907 | static 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 | ||
1000 | void sd_gpioa_isr(void) | 918 | void sd_gpioa_isr(void) |
@@ -1012,9 +930,41 @@ void sd_gpioa_isr(void) | |||
1012 | #ifdef CONFIG_STORAGE_MULTI | 930 | #ifdef CONFIG_STORAGE_MULTI |
1013 | int sd_num_drives(int first_drive) | 931 | int 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 | |||
938 | int 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 | |||
1069 | int 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 */ |
220 | static long sdmmc_stack[(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)]; | ||
221 | static const char sdmmc_thread_name[] = "sdmmc"; | ||
222 | static struct event_queue sdmmc_queue; | ||
223 | #if CONFIG_STORAGE & STORAGE_SD | 220 | #if CONFIG_STORAGE & STORAGE_SD |
224 | static int sd_first_drive; | 221 | static int sd_first_drive; |
225 | static unsigned _sd_num_drives; | 222 | static 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 | |
512 | int 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 |
489 | static int init_mmc_drive(int drive) | 555 | static 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 | |
643 | int 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! */ |
579 | static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, bool read) | 651 | static 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 | ||
773 | static void sdmmc_thread(void) NORETURN_ATTR; | ||
774 | static 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 | |||
865 | static int sdmmc_init(void) | 845 | static 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 | ||
1027 | void mmc_sleep(void) | ||
1028 | { | ||
1029 | } | ||
1030 | |||
1031 | void mmc_sleepnow(void) | 1003 | void 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 */ |
152 | static long last_disk_activity = -1; | 146 | static long last_disk_activity = -1; |
153 | 147 | ||
154 | /** static, private data **/ | ||
155 | static bool initialized = false; | ||
156 | static unsigned int sd_thread_id = 0; | ||
157 | |||
158 | #define Q_CLOSE 1 | ||
159 | |||
160 | static long next_yield = 0; | 148 | static 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 */ | 168 | static struct mutex sd_mtx SHAREDBSS_ATTR; |
181 | static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)]; | ||
182 | static const char sd_thread_name[] = "ata/sd"; | ||
183 | static struct mutex sd_mtx SHAREDBSS_ATTR; | ||
184 | static struct event_queue sd_queue SHAREDBSS_ATTR; | ||
185 | 169 | ||
186 | #ifdef HAVE_HOTSWAP | 170 | #ifdef HAVE_HOTSWAP |
187 | static int sd_first_drive = 0; | 171 | static 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 */ | ||
193 | enum 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 | ||
202 | static unsigned int check_time[NUM_EC]; | 176 | static unsigned int check_time[NUM_EC]; |
203 | 177 | ||
178 | static 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 | |||
204 | static inline bool sd_check_timeout(long timeout, int id) | 190 | static 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 | ||
882 | sd_read_retry: | 868 | sd_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 | ||
1000 | sd_write_retry: | 986 | sd_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 | ||
1112 | static void sd_thread(void) NORETURN_ATTR; | ||
1113 | #endif | ||
1114 | static 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 | ||
1181 | void 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 | |||
1195 | void sd_enable(bool on) | 1097 | void 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 | |||
1208 | int sd_init(void) | 1104 | int 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 |
1298 | static int sd1_oneshot_callback(struct timeout *tmo) | 1182 | static 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 | |||
1262 | int 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 */ |
58 | static long last_disk_activity = -1; | 52 | static long last_disk_activity = -1; |
59 | 53 | ||
60 | static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)]; | ||
61 | static unsigned char aligned_buf[512] STORAGE_ALIGN_ATTR; | 54 | static unsigned char aligned_buf[512] STORAGE_ALIGN_ATTR; |
62 | 55 | ||
63 | static const char sd_thread_name[] = "ata/sd"; | ||
64 | static struct mutex sd_mtx SHAREDBSS_ATTR; | 56 | static struct mutex sd_mtx SHAREDBSS_ATTR; |
65 | static struct event_queue sd_queue; | ||
66 | #ifndef BOOTLOADER | 57 | #ifndef BOOTLOADER |
67 | bool sd_enabled = false; | 58 | bool sd_enabled = false; |
68 | #endif | 59 | #endif |
69 | 60 | ||
61 | #ifdef CONFIG_STORAGE_MULTI | ||
62 | static int sd_first_drive = 0; | ||
63 | #else | ||
64 | #define sd_first_drive 0 | ||
65 | #endif | ||
66 | |||
70 | static struct semaphore transfer_completion_signal; | 67 | static struct semaphore transfer_completion_signal; |
71 | static struct semaphore command_completion_signal; | 68 | static struct semaphore command_completion_signal; |
72 | static volatile bool retry; | 69 | static volatile bool retry; |
73 | static volatile int cmd_error; | 70 | static volatile int cmd_error; |
74 | 71 | ||
72 | static 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 */ |
76 | void INT_SD(void) | 88 | void 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 | ||
321 | static void sd_thread(void) NORETURN_ATTR; | ||
322 | static 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 | |||
396 | static void init_controller(void) | 333 | static 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 | ||
747 | void sd_enable(bool on) | 678 | void 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 | ||
789 | static int sd_oneshot_callback(struct timeout *tmo) | 712 | static 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 |
810 | int sd_num_drives(int first_drive) | 728 | int 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 | |||
736 | int 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 */ |
91 | static long last_disk_activity = -1; | 89 | static long last_disk_activity = -1; |
92 | 90 | ||
91 | #ifdef CONFIG_STORAGE_MULTI | ||
92 | static int sd_first_drive = 0; | ||
93 | #else | ||
94 | #define sd_first_drive 0 | ||
95 | #endif | ||
96 | |||
93 | static bool initialized = false; | 97 | static bool initialized = false; |
94 | static bool sd_enabled = false; | 98 | static bool sd_enabled = false; |
95 | static long next_yield = 0; | 99 | static 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 */ | ||
113 | static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)]; | ||
114 | static const char sd_thread_name[] = "sd"; | ||
115 | static struct mutex sd_mtx SHAREDBSS_ATTR; | 116 | static struct mutex sd_mtx SHAREDBSS_ATTR; |
116 | static struct event_queue sd_queue; | ||
117 | static struct semaphore transfer_completion_signal; | 117 | static struct semaphore transfer_completion_signal; |
118 | static volatile unsigned int transfer_error[NUM_DRIVES]; | 118 | static 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 | ||
512 | static int sd1_oneshot_callback(struct timeout *tmo) | 512 | static 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 | ||
527 | void EINT8_23(void) | 523 | void 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 | ||
574 | static void sd_thread(void) NORETURN_ATTR; | ||
575 | static 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 | |||
614 | static int sd_wait_for_state(const int card_no, unsigned int state) | 570 | static 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) | |||
950 | int sd_num_drives(int first_drive) | 903 | int 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 | ||
961 | void sd_sleepnow(void) | ||
962 | { | ||
963 | } | ||
964 | |||
965 | bool sd_disk_is_active(void) | 911 | bool 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 | ||
929 | int 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 | ||
53 | void nand_sleep(void) | 53 | void nand_sleep(void) |
54 | { | 54 | { |
55 | nand_power_down(); | ||
56 | } | 55 | } |
57 | 56 | ||
58 | void nand_sleepnow(void) | 57 | void 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; | |||
91 | static int nand_interleaved = 0; | 90 | static int nand_interleaved = 0; |
92 | static int nand_cached = 0; | 91 | static int nand_cached = 0; |
93 | static long nand_last_activity_value = -1; | 92 | static long nand_last_activity_value = -1; |
94 | static long nand_stack[DEFAULT_STACK_SIZE]; | ||
95 | 93 | ||
96 | static struct mutex nand_mtx; | 94 | static struct mutex nand_mtx; |
97 | static struct semaphore nand_complete; | 95 | static struct semaphore nand_complete; |
@@ -359,20 +357,22 @@ void nand_power_up(void) | |||
359 | 357 | ||
360 | void nand_power_down(void) | 358 | void 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 | ||
717 | static 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 | |||
731 | int nand_device_init(void) | 717 | int 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 | |||
768 | int 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; | |||
58 | static uint32_t ata_dma_flags; | 54 | static uint32_t ata_dma_flags; |
59 | static long ata_last_activity_value = -1; | 55 | static long ata_last_activity_value = -1; |
60 | static long ata_sleep_timeout = 20 * HZ; | 56 | static long ata_sleep_timeout = 20 * HZ; |
61 | static uint32_t ata_stack[(DEFAULT_STACK_SIZE + 0x400) / 4]; | ||
62 | static bool ata_powered; | 57 | static bool ata_powered; |
63 | static const int ata_retries = ATA_RETRIES; | 58 | static const int ata_retries = ATA_RETRIES; |
64 | static const bool ata_error_srst = true; | 59 | static 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 | ||
892 | static 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 */ |
908 | int ata_soft_reset(void) | 888 | int 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 | ||
985 | void ata_sleep(void) | ||
986 | { | ||
987 | ata_last_activity_value = current_tick - ata_sleep_timeout + HZ / 5; | ||
988 | } | ||
989 | |||
990 | void ata_sleepnow(void) | 965 | void 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 | ||
997 | void ata_close(void) | ||
998 | { | ||
999 | ata_sleepnow(); | ||
1000 | } | ||
1001 | |||
1002 | void ata_spin(void) | 972 | void 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 | ||
1098 | int 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 */ |
56 | static long last_disk_activity = -1; | 52 | static long last_disk_activity = -1; |
57 | 53 | ||
58 | /** static, private data **/ | ||
59 | static bool initialized = false; | ||
60 | |||
61 | static long next_yield = 0; | 54 | static 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 */ | ||
84 | static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)]; | ||
85 | static const char sd_thread_name[] = "sd"; | ||
86 | static struct mutex sd_mtx SHAREDBSS_ATTR; | 76 | static struct mutex sd_mtx SHAREDBSS_ATTR; |
87 | static struct event_queue sd_queue; | ||
88 | 77 | ||
78 | #ifdef CONFIG_STORAGE_MULTI | ||
89 | static int sd_first_drive = 0; | 79 | static int sd_first_drive = 0; |
90 | 80 | #else | |
81 | #define sd_first_drive 0 | ||
82 | #endif | ||
91 | 83 | ||
92 | static bool sd_poll_status(unsigned int trigger, long timeout) | 84 | static bool sd_poll_status(unsigned int trigger, long timeout) |
93 | { | 85 | { |
@@ -216,16 +208,13 @@ static inline bool card_detect_target(void) | |||
216 | 208 | ||
217 | static int sd1_oneshot_callback(struct timeout *tmo) | 209 | static 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 | ||
231 | void EXT0(void) | 220 | void EXT0(void) |
@@ -642,71 +631,6 @@ sd_write_error: | |||
642 | } | 631 | } |
643 | } | 632 | } |
644 | 633 | ||
645 | static void sd_thread(void) NORETURN_ATTR; | ||
646 | static 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 | |||
710 | void sd_enable(bool on) | 634 | void sd_enable(bool on) |
711 | { | 635 | { |
712 | if(on) | 636 | if(on) |
@@ -725,6 +649,7 @@ void sd_enable(bool on) | |||
725 | 649 | ||
726 | int sd_init(void) | 650 | int 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 | ||
797 | void sd_sleepnow(void) | ||
798 | { | ||
799 | } | ||
800 | |||
801 | bool sd_disk_is_active(void) | 717 | bool 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 | |||
734 | int 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 | |||
105 | static long last_disk_activity = -1; | 102 | static long last_disk_activity = -1; |
106 | 103 | ||
107 | static bool initialized = false; | 104 | static bool initialized = false; |
108 | static unsigned int sd_thread_id = 0; | ||
109 | 105 | ||
110 | static bool sd_enabled = false; | 106 | static bool sd_enabled = false; |
111 | static long next_yield = 0; | 107 | static 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 */ |
125 | static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)]; | ||
126 | static const char sd_thread_name[] = "sd"; | ||
127 | static struct mutex sd_mtx SHAREDBSS_ATTR; | 121 | static struct mutex sd_mtx SHAREDBSS_ATTR; |
128 | static struct event_queue sd_queue; | ||
129 | static volatile unsigned int transfer_error[NUM_DRIVES]; | 122 | static volatile unsigned int transfer_error[NUM_DRIVES]; |
130 | /* align on cache line size */ | 123 | /* align on cache line size */ |
131 | static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] | 124 | static 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 | ||
150 | static inline void enable_controller(bool on) | ||
151 | { | ||
152 | sd_enabled = on; | ||
153 | } | ||
157 | 154 | ||
158 | void sd_enable(bool on) | 155 | void 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 | ||
515 | static int sd1_oneshot_callback(struct timeout *tmo) | 504 | static 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 | ||
580 | static void sd_thread(void) NORETURN_ATTR; | ||
581 | static 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 | |||
631 | static int sd_wait_for_state(unsigned int state) | 565 | static 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 | ||
676 | sd_transfer_retry: | 610 | sd_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 | ||
943 | void sd_sleepnow(void) | 874 | int 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 | } | ||