summaryrefslogtreecommitdiff
path: root/firmware/target/arm/as3525
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2017-03-15 01:51:54 -0400
committerMichael Sevakis <jethead71@rockbox.org>2017-10-26 14:35:41 -0400
commit1654efc31339972d0e6bd41a499fcffc0a45822e (patch)
tree5fb7f59ab918a3694608bb1138c2c52fb47698c3 /firmware/target/arm/as3525
parent7807934a271e9eb7b045cdcd89ba70fb59a91d69 (diff)
downloadrockbox-1654efc31339972d0e6bd41a499fcffc0a45822e.tar.gz
rockbox-1654efc31339972d0e6bd41a499fcffc0a45822e.zip
Unify storage threads into one
* Editing a bunch of drivers' thread routines in order to implement a new feature is tedious. * No matter the number of storage drivers, they share one thread. No extra threads needed for CONFIG_STORAGE_MULTI. * Each has an event callback called by the storage thread. * A default callback is provided to fake sleeping in order to trigger idle callbacks. It could also do other default processing. Changes to it will be part of driver code without editing each one. * Drivers may sleep and wake as they please as long as they give a low pulse on their storage bit to ask to go into sleep mode. Idle callback is called on its behalf and driver immediately put into sleep mode. * Drivers may indicate they are to continue receiving events in USB mode, otherwise they receve nothing until disconnect (they do receive SYS_USB_DISCONNECTED no matter what). * Rework a few things to keep the callback implementation sane and maintainable. ata.c was dreadful with all those bools; make it a state machine and easier to follow. Remove last_user_activity; it has no purpose that isn't served by keeping the disk active through last_disk_activity instead. * Even-out stack sizes partly because of a lack of a decent place to define them by driver or SoC or whatever; it doesn't seem too critical to do that anyway. Many are simply too large while at least one isn't really adequate. They may be individually overridden if necessary (figure out where). The thread uses the greatest size demanded. Newer file code is much more frugal with stack space. I barely see use crack 50% after idle callbacks (usually mid-40s). Card insert/eject doesn't demand much. * No forcing of idle callbacks. If it isn't necessary for one or more non-disk storage types, it really isn't any more necessary for disk storage. Besides, it makes the whole thing easier to implement. Change-Id: Id30c284d82a8af66e47f2cfe104c52cbd8aa7215
Diffstat (limited to 'firmware/target/arm/as3525')
-rw-r--r--firmware/target/arm/as3525/sd-as3525.c276
-rw-r--r--firmware/target/arm/as3525/sd-as3525v2.c188
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
117static int sd_first_drive = 0;
118#else
119#define sd_first_drive 0
120#endif
121
122/* for compatibility */ 122/* for compatibility */
123static long last_disk_activity = -1; 123static long last_disk_activity = -1;
124 124
125#define MIN_YIELD_PERIOD 5 /* ticks */ 125#define MIN_YIELD_PERIOD 5 /* ticks */
126static long next_yield = 0; 126static long next_yield = 0;
127 127
128static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)]; 128static struct mutex sd_mtx;
129static const char sd_thread_name[] = "ata/sd";
130static struct mutex sd_mtx;
131static struct event_queue sd_queue;
132bool sd_enabled = false; 129bool sd_enabled = false;
133 130
134#if defined(HAVE_MULTIDRIVE) 131#if defined(HAVE_MULTIDRIVE)
@@ -147,6 +144,59 @@ static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0])
147 144
148static inline void mci_delay(void) { udelay(1000) ; } 145static inline void mci_delay(void) { udelay(1000) ; }
149 146
147static void enable_controller(bool on)
148{
149
150#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
151 extern int buttonlight_is_on;
152#endif
153
154#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
155 static bool cpu_boosted = false;
156#endif
157
158 if (sd_enabled == on)
159 return; /* nothing to do */
160
161 sd_enabled = on;
162
163 if(on)
164 {
165#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
166 /* buttonlight AMSes need a bit of special handling for the buttonlight
167 * here due to the dual mapping of GPIOD and XPD */
168 bitmod32(&CCU_IO, 1<<2, 3<<2); /* XPD is SD-MCI interface (b3:2 = 01) */
169 if (buttonlight_is_on)
170 GPIOD_DIR &= ~(1<<7);
171 else
172 buttonlight_hw_off();
173#endif
174
175#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
176 if(card_detect_target()) /* If SD card present Boost cpu for voltage */
177 {
178 cpu_boosted = true;
179 cpu_boost(true);
180 }
181#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
182 }
183 else
184 {
185#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
186 if(cpu_boosted)
187 {
188 cpu_boost(false);
189 cpu_boosted = false;
190 }
191#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
192
193#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
194 bitmod32(&CCU_IO, 0<<2, 3<<2); /* XPD is general purpose IO (b3:2 = 00) */
195 if (buttonlight_is_on)
196 buttonlight_hw_on();
197#endif
198 }
199}
150 200
151static inline bool card_detect_target(void) 201static inline bool card_detect_target(void)
152{ 202{
@@ -161,18 +211,13 @@ static inline bool card_detect_target(void)
161#ifdef HAVE_HOTSWAP 211#ifdef HAVE_HOTSWAP
162static int sd1_oneshot_callback(struct timeout *tmo) 212static int sd1_oneshot_callback(struct timeout *tmo)
163{ 213{
164 (void)tmo;
165
166 /* This is called only if the state was stable for 300ms - check state 214 /* This is called only if the state was stable for 300ms - check state
167 * and post appropriate event. */ 215 * and post appropriate event. */
168 if (card_detect_target()) 216 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
169 { 217 SYS_HOTSWAP_EXTRACTED,
170 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 218 sd_first_drive + SD_SLOT_AS3525);
171 }
172 else
173 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
174
175 return 0; 219 return 0;
220 (void)tmo;
176} 221}
177 222
178void sd_gpioa_isr(void) 223void sd_gpioa_isr(void)
@@ -435,87 +480,6 @@ static int sd_init_card(const int drive)
435 return 0; 480 return 0;
436} 481}
437 482
438static void sd_thread(void) NORETURN_ATTR;
439static void sd_thread(void)
440{
441 struct queue_event ev;
442 bool idle_notified = false;
443
444 while (1)
445 {
446 queue_wait_w_tmo(&sd_queue, &ev, HZ);
447
448 switch ( ev.id )
449 {
450#ifdef HAVE_HOTSWAP
451 case SYS_HOTSWAP_INSERTED:
452 case SYS_HOTSWAP_EXTRACTED:;
453 int success = 1;
454
455 disk_unmount(SD_SLOT_AS3525); /* release "by force" */
456
457 mutex_lock(&sd_mtx); /* lock-out card activity */
458
459 /* Force card init for new card, re-init for re-inserted one or
460 * clear if the last attempt to init failed with an error. */
461 card_info[SD_SLOT_AS3525].initialized = 0;
462
463 if (ev.id == SYS_HOTSWAP_INSERTED)
464 {
465 success = 0;
466 sd_enable(true);
467 init_pl180_controller(SD_SLOT_AS3525);
468 int rc = sd_init_card(SD_SLOT_AS3525);
469 sd_enable(false);
470 if (rc >= 0)
471 success = 2;
472 else /* initialisation failed */
473 panicf("microSD init failed : %d", rc);
474 }
475
476 mutex_unlock(&sd_mtx);
477
478 if (success > 1)
479 success = disk_mount(SD_SLOT_AS3525); /* 0 if fail */
480
481 /*
482 * Mount succeeded, or this was an EXTRACTED event,
483 * in both cases notify the system about the changed filesystems
484 */
485 if (success)
486 queue_broadcast(SYS_FS_CHANGED, 0);
487
488 break;
489#endif /* HAVE_HOTSWAP */
490
491 case SYS_TIMEOUT:
492 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
493 {
494 idle_notified = false;
495 }
496 else
497 {
498 /* never let a timer wrap confuse us */
499 next_yield = current_tick;
500
501 if (!idle_notified)
502 {
503 call_storage_idle_notifys(false);
504 idle_notified = true;
505 }
506 }
507 break;
508
509 case SYS_USB_CONNECTED:
510 usb_acknowledge(SYS_USB_CONNECTED_ACK);
511 /* Wait until the USB cable is extracted again */
512 usb_wait_for_disconnect(&sd_queue);
513
514 break;
515 }
516 }
517}
518
519static void init_pl180_controller(const int drive) 483static void init_pl180_controller(const int drive)
520{ 484{
521 MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0; 485 MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0;
@@ -576,12 +540,8 @@ int sd_init(void)
576 /* init mutex */ 540 /* init mutex */
577 mutex_init(&sd_mtx); 541 mutex_init(&sd_mtx);
578 542
579 queue_init(&sd_queue, true); 543 sd_enabled = true; /* force action on next call */
580 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0, 544 enable_controller(false);
581 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
582
583 sd_enabled = true;
584 sd_enable(false);
585 545
586 return 0; 546 return 0;
587} 547}
@@ -698,7 +658,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
698 unsigned long response; 658 unsigned long response;
699 bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1)); 659 bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1));
700 660
701 sd_enable(true); 661 enable_controller(true);
702 led(true); 662 led(true);
703 663
704 if (card_info[drive].initialized <= 0) 664 if (card_info[drive].initialized <= 0)
@@ -873,7 +833,7 @@ sd_transfer_error:
873sd_transfer_error_nodma: 833sd_transfer_error_nodma:
874 834
875 led(false); 835 led(false);
876 sd_enable(false); 836 enable_controller(false);
877 837
878 if (ret) /* error */ 838 if (ret) /* error */
879 card_info[drive].initialized = 0; 839 card_info[drive].initialized = 0;
@@ -947,55 +907,9 @@ long sd_last_disk_activity(void)
947 907
948void sd_enable(bool on) 908void sd_enable(bool on)
949{ 909{
950#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE) 910 mutex_lock(&sd_mtx);
951 extern int buttonlight_is_on; 911 enable_controller(on);
952#endif 912 mutex_unlock(&sd_mtx);
953
954#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
955 static bool cpu_boosted = false;
956#endif
957
958 if (sd_enabled == on)
959 return; /* nothing to do */
960
961 sd_enabled = on;
962
963 if(on)
964 {
965#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
966 /* buttonlight AMSes need a bit of special handling for the buttonlight
967 * here due to the dual mapping of GPIOD and XPD */
968 bitmod32(&CCU_IO, 1<<2, 3<<2); /* XPD is SD-MCI interface (b3:2 = 01) */
969 if (buttonlight_is_on)
970 GPIOD_DIR &= ~(1<<7);
971 else
972 buttonlight_hw_off();
973#endif
974
975#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
976 if(card_detect_target()) /* If SD card present Boost cpu for voltage */
977 {
978 cpu_boosted = true;
979 cpu_boost(true);
980 }
981#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
982 }
983 else
984 {
985#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
986 if(cpu_boosted)
987 {
988 cpu_boost(false);
989 cpu_boosted = false;
990 }
991#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
992
993#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
994 bitmod32(&CCU_IO, 0<<2, 3<<2); /* XPD is general purpose IO (b3:2 = 00) */
995 if (buttonlight_is_on)
996 buttonlight_hw_on();
997#endif
998 }
999} 913}
1000 914
1001tCardInfo *card_get_info_target(int card_no) 915tCardInfo *card_get_info_target(int card_no)
@@ -1006,9 +920,45 @@ tCardInfo *card_get_info_target(int card_no)
1006#ifdef CONFIG_STORAGE_MULTI 920#ifdef CONFIG_STORAGE_MULTI
1007int sd_num_drives(int first_drive) 921int sd_num_drives(int first_drive)
1008{ 922{
1009 /* We don't care which logical drive number(s) we have been assigned */ 923 sd_first_drive = first_drive;
1010 (void)first_drive;
1011
1012 return NUM_DRIVES; 924 return NUM_DRIVES;
1013} 925}
1014#endif /* CONFIG_STORAGE_MULTI */ 926#endif /* CONFIG_STORAGE_MULTI */
927
928int sd_event(long id, intptr_t data)
929{
930 int rc = 0;
931
932 switch (id)
933 {
934#ifdef HAVE_HOTSWAP
935 case SYS_HOTSWAP_INSERTED:
936 case SYS_HOTSWAP_EXTRACTED:
937 mutex_lock(&sd_mtx); /* lock-out card activity */
938
939 /* Force card init for new card, re-init for re-inserted one or
940 * clear if the last attempt to init failed with an error. */
941 card_info[data].initialized = 0;
942
943 if (id == SYS_HOTSWAP_INSERTED)
944 {
945 enable_controller(true);
946 init_pl180_controller(data);
947 rc = sd_init_card(data);
948 enable_controller(false);
949 }
950
951 mutex_unlock(&sd_mtx);
952 break;
953#endif /* HAVE_HOTSWAP */
954 case Q_STORAGE_TICK:
955 /* never let a timer wrap confuse us */
956 next_yield = current_tick;
957 default:
958 rc = storage_event_default_handler(id, data, last_disk_activity,
959 STORAGE_SD);
960 break;
961 }
962
963 return rc;
964}
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c
index 3f39629e0b..f78345577c 100644
--- a/firmware/target/arm/as3525/sd-as3525v2.c
+++ b/firmware/target/arm/as3525/sd-as3525v2.c
@@ -22,7 +22,6 @@
22 22
23#include "config.h" /* for HAVE_MULTIVOLUME */ 23#include "config.h" /* for HAVE_MULTIVOLUME */
24#include "fs_defines.h" 24#include "fs_defines.h"
25#include "thread.h"
26#include "gcc_extensions.h" 25#include "gcc_extensions.h"
27#include "led.h" 26#include "led.h"
28#include "sdmmc.h" 27#include "sdmmc.h"
@@ -36,19 +35,7 @@
36#include "pl081.h" /* DMA controller */ 35#include "pl081.h" /* DMA controller */
37#include "dma-target.h" /* DMA request lines */ 36#include "dma-target.h" /* DMA request lines */
38#include "clock-target.h" 37#include "clock-target.h"
39#include "panic.h" 38#include "storage.h"
40#include "stdbool.h"
41#include "ata_idle_notify.h"
42#include "sd.h"
43#include "usb.h"
44
45#ifdef HAVE_HOTSWAP
46#include "disk.h"
47#endif
48
49#include "lcd.h"
50#include <stdarg.h>
51#include "sysfont.h"
52 39
53#define INTERNAL_AS3525 0 /* embedded SD card */ 40#define INTERNAL_AS3525 0 /* embedded SD card */
54#define SD_SLOT_AS3525 1 /* SD slot if present */ 41#define SD_SLOT_AS3525 1 /* SD slot if present */
@@ -327,13 +314,15 @@ static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0])
327 314
328static tCardInfo card_info[NUM_DRIVES]; 315static tCardInfo card_info[NUM_DRIVES];
329 316
317#ifdef CONFIG_STORAGE_MULTI
318static int sd_first_drive = 0;
319#else
320#define sd_first_drive 0
321#endif
322
330/* for compatibility */ 323/* for compatibility */
331static long last_disk_activity = -1; 324static long last_disk_activity = -1;
332
333static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
334static const char sd_thread_name[] = "ata/sd";
335static struct mutex sd_mtx SHAREDBSS_ATTR; 325static struct mutex sd_mtx SHAREDBSS_ATTR;
336static struct event_queue sd_queue;
337#ifndef BOOTLOADER 326#ifndef BOOTLOADER
338bool sd_enabled = false; 327bool sd_enabled = false;
339#endif 328#endif
@@ -371,6 +360,22 @@ void INT_NAND(void)
371 MCI_CTRL |= INT_ENABLE; 360 MCI_CTRL |= INT_ENABLE;
372} 361}
373 362
363#ifndef BOOTLOADER
364static void enable_controller(bool on)
365{
366 if (on)
367 {
368 bitset32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
369 CGU_SDSLOT |= (1<<7); /* interface enable */
370 }
371 else
372 {
373 CGU_SDSLOT &= ~(1<<7); /* interface enable */
374 bitclr32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
375 }
376}
377#endif /* BOOTLOADER */
378
374static inline bool card_detect_target(void) 379static inline bool card_detect_target(void)
375{ 380{
376#if defined(HAVE_MULTIDRIVE) 381#if defined(HAVE_MULTIDRIVE)
@@ -577,75 +582,6 @@ static int sd_init_card(const int drive)
577 return 0; 582 return 0;
578} 583}
579 584
580static void sd_thread(void) NORETURN_ATTR;
581static void sd_thread(void)
582{
583 struct queue_event ev;
584 bool idle_notified = false;
585
586 while (1)
587 {
588 queue_wait_w_tmo(&sd_queue, &ev, HZ);
589
590 switch ( ev.id )
591 {
592#ifdef HAVE_HOTSWAP
593 case SYS_HOTSWAP_INSERTED:
594 case SYS_HOTSWAP_EXTRACTED:;
595 int success = 1;
596
597 disk_unmount(SD_SLOT_AS3525); /* release "by force" */
598
599 mutex_lock(&sd_mtx); /* lock-out card activity */
600
601 /* Force card init for new card, re-init for re-inserted one or
602 * clear if the last attempt to init failed with an error. */
603 card_info[SD_SLOT_AS3525].initialized = 0;
604
605 if (ev.id == SYS_HOTSWAP_INSERTED)
606 {
607 sd_enable(true);
608 success = sd_init_card(SD_SLOT_AS3525) == 0 ? 2 : 0;
609 sd_enable(false);
610 }
611
612 mutex_unlock(&sd_mtx);
613
614 if (success > 1)
615 success = disk_mount(SD_SLOT_AS3525); /* 0 if fail */
616
617 /*
618 * Mount succeeded, or this was an EXTRACTED event,
619 * in both cases notify the system about the changed filesystems
620 */
621 if (success)
622 queue_broadcast(SYS_FS_CHANGED, 0);
623
624 break;
625#endif /* HAVE_HOTSWAP */
626
627 case SYS_TIMEOUT:
628 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
629 {
630 idle_notified = false;
631 }
632 else if (!idle_notified)
633 {
634 call_storage_idle_notifys(false);
635 idle_notified = true;
636 }
637 break;
638
639 case SYS_USB_CONNECTED:
640 usb_acknowledge(SYS_USB_CONNECTED_ACK);
641 /* Wait until the USB cable is extracted again */
642 usb_wait_for_disconnect(&sd_queue);
643
644 break;
645 }
646 }
647}
648
649static void init_controller(void) 585static void init_controller(void)
650{ 586{
651 int hcon_numcards = ((MCI_HCON>>1) & 0x1F) + 1; 587 int hcon_numcards = ((MCI_HCON>>1) & 0x1F) + 1;
@@ -706,6 +642,7 @@ int sd_init(void)
706 | (AS3525_SDSLOT_DIV << 2) 642 | (AS3525_SDSLOT_DIV << 2)
707 | 1; /* clock source = PLLA */ 643 | 1; /* clock source = PLLA */
708 644
645 mutex_init(&sd_mtx);
709 semaphore_init(&transfer_completion_signal, 1, 0); 646 semaphore_init(&transfer_completion_signal, 1, 0);
710 semaphore_init(&command_completion_signal, 1, 0); 647 semaphore_init(&command_completion_signal, 1, 0);
711 648
@@ -737,16 +674,9 @@ int sd_init(void)
737 if(ret < 0) 674 if(ret < 0)
738 return ret; 675 return ret;
739 676
740 /* init mutex */
741 mutex_init(&sd_mtx);
742
743 queue_init(&sd_queue, true);
744 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
745 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
746
747#ifndef BOOTLOADER 677#ifndef BOOTLOADER
748 sd_enabled = true; 678 sd_enabled = true;
749 sd_enable(false); 679 enable_controller(false);
750#endif 680#endif
751 return 0; 681 return 0;
752} 682}
@@ -767,7 +697,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
767 697
768 mutex_lock(&sd_mtx); 698 mutex_lock(&sd_mtx);
769#ifndef BOOTLOADER 699#ifndef BOOTLOADER
770 sd_enable(true); 700 enable_controller(true);
771 led(true); 701 led(true);
772#endif 702#endif
773 703
@@ -925,7 +855,7 @@ retry_with_reinit:
925 855
926exit: 856exit:
927#ifndef BOOTLOADER 857#ifndef BOOTLOADER
928 sd_enable(false); 858 enable_controller(false);
929 led(false); 859 led(false);
930#endif 860#endif
931 mutex_unlock(&sd_mtx); 861 mutex_unlock(&sd_mtx);
@@ -952,16 +882,9 @@ long sd_last_disk_activity(void)
952 882
953void sd_enable(bool on) 883void sd_enable(bool on)
954{ 884{
955 if (on) 885 mutex_lock(&sd_mtx);
956 { 886 enable_controller(on);
957 bitset32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE); 887 mutex_unlock(&sd_mtx);
958 CGU_SDSLOT |= (1<<7); /* interface enable */
959 }
960 else
961 {
962 CGU_SDSLOT &= ~(1<<7); /* interface enable */
963 bitclr32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
964 }
965} 888}
966#endif /* BOOTLOADER */ 889#endif /* BOOTLOADER */
967 890
@@ -983,18 +906,13 @@ bool sd_present(IF_MD_NONVOID(int drive))
983 906
984static int sd1_oneshot_callback(struct timeout *tmo) 907static int sd1_oneshot_callback(struct timeout *tmo)
985{ 908{
986 (void)tmo;
987
988 /* This is called only if the state was stable for 300ms - check state 909 /* This is called only if the state was stable for 300ms - check state
989 * and post appropriate event. */ 910 * and post appropriate event. */
990 if (card_detect_target()) 911 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
991 { 912 SYS_HOTSWAP_EXTRACTED,
992 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 913 sd_first_drive + SD_SLOT_AS3525);
993 }
994 else
995 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
996
997 return 0; 914 return 0;
915 (void)tmo;
998} 916}
999 917
1000void sd_gpioa_isr(void) 918void sd_gpioa_isr(void)
@@ -1012,9 +930,41 @@ void sd_gpioa_isr(void)
1012#ifdef CONFIG_STORAGE_MULTI 930#ifdef CONFIG_STORAGE_MULTI
1013int sd_num_drives(int first_drive) 931int sd_num_drives(int first_drive)
1014{ 932{
1015 /* We don't care which logical drive number(s) we have been assigned */ 933 sd_first_drive = first_drive;
1016 (void)first_drive;
1017
1018 return NUM_DRIVES; 934 return NUM_DRIVES;
1019} 935}
1020#endif /* CONFIG_STORAGE_MULTI */ 936#endif /* CONFIG_STORAGE_MULTI */
937
938int sd_event(long id, intptr_t data)
939{
940 int rc = 0;
941
942 switch (id)
943 {
944#ifdef HAVE_HOTSWAP
945 case SYS_HOTSWAP_INSERTED:
946 case SYS_HOTSWAP_EXTRACTED:
947 mutex_lock(&sd_mtx); /* lock-out card activity */
948
949 /* Force card init for new card, re-init for re-inserted one or
950 * clear if the last attempt to init failed with an error. */
951 card_info[data].initialized = 0;
952
953 if (id == SYS_HOTSWAP_INSERTED)
954 {
955 enable_controller(true);
956 rc = sd_init_card(data);
957 enable_controller(false);
958 }
959
960 mutex_unlock(&sd_mtx);
961 break;
962#endif /* HAVE_HOTSWAP */
963 default:
964 rc = storage_event_default_handler(id, data, last_disk_activity,
965 STORAGE_SD);
966 break;
967 }
968
969 return rc;
970}