summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233/sdmmc-imx233.c
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/imx233/sdmmc-imx233.c
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/imx233/sdmmc-imx233.c')
-rw-r--r--firmware/target/arm/imx233/sdmmc-imx233.c190
1 files changed, 81 insertions, 109 deletions
diff --git a/firmware/target/arm/imx233/sdmmc-imx233.c b/firmware/target/arm/imx233/sdmmc-imx233.c
index d3dabafecb..af090e8a07 100644
--- a/firmware/target/arm/imx233/sdmmc-imx233.c
+++ b/firmware/target/arm/imx233/sdmmc-imx233.c
@@ -217,9 +217,6 @@ static struct sdmmc_status_t sdmmc_status[SDMMC_NUM_DRIVES];
217#define SDMMC_STATUS(drive) sdmmc_status[drive] 217#define SDMMC_STATUS(drive) sdmmc_status[drive]
218 218
219/* sd only */ 219/* sd only */
220static long sdmmc_stack[(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
221static const char sdmmc_thread_name[] = "sdmmc";
222static struct event_queue sdmmc_queue;
223#if CONFIG_STORAGE & STORAGE_SD 220#if CONFIG_STORAGE & STORAGE_SD
224static int sd_first_drive; 221static int sd_first_drive;
225static unsigned _sd_num_drives; 222static unsigned _sd_num_drives;
@@ -260,10 +257,38 @@ static void sdmmc_detect_callback(int ssp)
260{ 257{
261 /* This is called only if the state was stable for 300ms - check state 258 /* This is called only if the state was stable for 300ms - check state
262 * and post appropriate event. */ 259 * and post appropriate event. */
263 if(imx233_ssp_sdmmc_detect(ssp)) 260 long evid = imx233_ssp_sdmmc_detect(ssp) ?
264 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 261 SYS_HOTSWAP_INSERTED : SYS_HOTSWAP_EXTRACTED;
265 else 262
266 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0); 263 /* Have to reverse lookup the ssp */
264 for (unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++)
265 {
266 if (SDMMC_SSP(drive) != ssp)
267 continue;
268
269 int first_drive, *map;
270 switch (SDMMC_MODE(drive))
271 {
272#if (CONFIG_STORAGE & STORAGE_MMC)
273 case MMC_MODE:
274 first_drive = mmc_first_drive;
275 map = mmc_map;
276 break;
277#endif
278#if (CONFIG_STORAGE & STORAGE_SD)
279 case SD_MODE:
280 first_drive = sd_first_drive;
281 map = sd_map;
282 break;
283#endif
284 default:
285 continue;
286 }
287
288 /* message requires logical drive number as data */
289 queue_broadcast(evid, first_drive + map[drive]);
290 }
291
267 imx233_ssp_sdmmc_setup_detect(ssp, true, sdmmc_detect_callback, false, 292 imx233_ssp_sdmmc_setup_detect(ssp, true, sdmmc_detect_callback, false,
268 imx233_ssp_sdmmc_is_detect_inverted(ssp)); 293 imx233_ssp_sdmmc_is_detect_inverted(ssp));
269} 294}
@@ -483,7 +508,48 @@ static int init_sd_card(int drive)
483 508
484 return 0; 509 return 0;
485} 510}
486#endif 511
512int sd_event(long id, intptr_t data)
513{
514 int rc = 0;
515
516 switch (id)
517 {
518#ifdef HAVE_HOTSWAP
519 case SYS_HOTSWAP_INSERTED:
520 case SYS_HOTSWAP_EXTRACTED:;
521 const int drive = sd_map[data];
522
523 /* Skip non-removable drivers */
524 if(!sdmmc_removable(drive))
525 {
526 rc = -1;
527 break;
528 }
529
530 mutex_lock(&mutex[drive]); /* lock-out card activity */
531
532 /* Force card init for new card, re-init for re-inserted one or
533 * clear if the last attempt to init failed with an error. */
534 SDMMC_INFO(drive).initialized = 0;
535
536 if(id == SYS_HOTSWAP_INSERTED)
537 rc = init_drive(drive);
538
539 /* unlock card */
540 mutex_unlock(&mutex[drive]);
541 /* Access is now safe */
542 break;
543#endif /* HAVE_HOTSWAP */
544 default:
545 rc = storage_event_default_handler(id, data, sd_last_disk_activity(),
546 STORAGE_SD);
547 break;
548 }
549
550 return rc;
551}
552#endif /* CONFIG_STORAGE & STORAGE_SD */
487 553
488#if CONFIG_STORAGE & STORAGE_MMC 554#if CONFIG_STORAGE & STORAGE_MMC
489static int init_mmc_drive(int drive) 555static int init_mmc_drive(int drive)
@@ -573,7 +639,13 @@ static int init_mmc_drive(int drive)
573 639
574 return 0; 640 return 0;
575} 641}
576#endif 642
643int mmc_event(long id, intptr_t data)
644{
645 return storage_event_default_handler(id, data, mmc_last_disk_activity(),
646 STORAGE_MMC);
647}
648#endif /* CONFIG_STORAGE & STORAGE_MMC */
577 649
578/* low-level function, don't call directly! */ 650/* low-level function, don't call directly! */
579static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, bool read) 651static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, bool read)
@@ -770,98 +842,6 @@ static int init_drive(int drive)
770 return 0; 842 return 0;
771} 843}
772 844
773static void sdmmc_thread(void) NORETURN_ATTR;
774static void sdmmc_thread(void)
775{
776 struct queue_event ev;
777 bool idle_notified = false;
778 int timeout = 0;
779
780 while (1)
781 {
782 queue_wait_w_tmo(&sdmmc_queue, &ev, HZ);
783
784 switch(ev.id)
785 {
786#if CONFIG_STORAGE & STORAGE_SD
787 case SYS_HOTSWAP_INSERTED:
788 case SYS_HOTSWAP_EXTRACTED:
789 {
790 int microsd_init = ev.id == SYS_HOTSWAP_INSERTED ? 0 : 1;
791
792 /* We now have exclusive control of fat cache and sd.
793 * Release "by force", ensure file
794 * descriptors aren't leaked and any busy
795 * ones are invalid if mounting. */
796 for(unsigned sd_drive = 0; sd_drive < _sd_num_drives; sd_drive++)
797 {
798 int drive = sd_map[sd_drive];
799 /* Skip non-removable drivers */
800 if(!sdmmc_removable(drive))
801 continue;
802
803 disk_unmount(sd_first_drive + sd_drive);
804
805 mutex_lock(&mutex[drive]); /* lock-out card activity */
806
807 /* Force card init for new card, re-init for re-inserted one or
808 * clear if the last attempt to init failed with an error. */
809 SDMMC_INFO(sd_map[sd_drive]).initialized = 0;
810
811 int rc = -1;
812 if(ev.id == SYS_HOTSWAP_INSERTED)
813 {
814 rc = init_drive(drive);
815 if(rc < 0) /* initialisation failed */
816 panicf("%s init failed : %d", SDMMC_CONF(sd_map[sd_drive]).name, rc);
817 }
818
819 /* unlock card */
820 mutex_unlock(&mutex[drive]);
821
822 if (rc >= 0)
823 microsd_init += disk_mount(sd_first_drive + sd_drive); /* 0 if fail */
824 }
825 /* Access is now safe */
826 /*
827 * One or more mounts succeeded, or this was an EXTRACTED event,
828 * in both cases notify the system about the changed filesystems
829 */
830 if(microsd_init)
831 queue_broadcast(SYS_FS_CHANGED, 0);
832
833 break;
834 }
835#endif
836 case SYS_TIMEOUT:
837#if CONFIG_STORAGE & STORAGE_SD
838 timeout = MAX(timeout, sd_last_disk_activity()+(3*HZ));
839#endif
840#if CONFIG_STORAGE & STORAGE_MMC
841 timeout = MAX(timeout, mmc_last_disk_activity()+(3*HZ));
842#endif
843 if(TIME_BEFORE(current_tick, timeout))
844 {
845 idle_notified = false;
846 }
847 else
848 {
849 if(!idle_notified)
850 {
851 call_storage_idle_notifys(false);
852 idle_notified = true;
853 }
854 }
855 break;
856 case SYS_USB_CONNECTED:
857 usb_acknowledge(SYS_USB_CONNECTED_ACK);
858 /* Wait until the USB cable is extracted again */
859 usb_wait_for_disconnect(&sdmmc_queue);
860 break;
861 }
862 }
863}
864
865static int sdmmc_init(void) 845static int sdmmc_init(void)
866{ 846{
867 static int is_initialized = false; 847 static int is_initialized = false;
@@ -871,10 +851,6 @@ static int sdmmc_init(void)
871 for(unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++) 851 for(unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++)
872 mutex_init(&mutex[drive]); 852 mutex_init(&mutex[drive]);
873 853
874 queue_init(&sdmmc_queue, true);
875 create_thread(sdmmc_thread, sdmmc_stack, sizeof(sdmmc_stack), 0,
876 sdmmc_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
877
878 for(unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++) 854 for(unsigned drive = 0; drive < SDMMC_NUM_DRIVES; drive++)
879 { 855 {
880 if(sdmmc_removable(drive)) 856 if(sdmmc_removable(drive))
@@ -1024,10 +1000,6 @@ void mmc_enable(bool on)
1024 (void) on; 1000 (void) on;
1025} 1001}
1026 1002
1027void mmc_sleep(void)
1028{
1029}
1030
1031void mmc_sleepnow(void) 1003void mmc_sleepnow(void)
1032{ 1004{
1033} 1005}