diff options
Diffstat (limited to 'firmware/target/arm/as3525')
-rw-r--r-- | firmware/target/arm/as3525/sd-as3525.c | 276 | ||||
-rw-r--r-- | firmware/target/arm/as3525/sd-as3525v2.c | 188 |
2 files changed, 182 insertions, 282 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 | } | ||