summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tms320dm320/sdmmc-dm320.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/tms320dm320/sdmmc-dm320.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/tms320dm320/sdmmc-dm320.c')
-rw-r--r--firmware/target/arm/tms320dm320/sdmmc-dm320.c139
1 files changed, 45 insertions, 94 deletions
diff --git a/firmware/target/arm/tms320dm320/sdmmc-dm320.c b/firmware/target/arm/tms320dm320/sdmmc-dm320.c
index a6e261bcfa..8818d645d8 100644
--- a/firmware/target/arm/tms320dm320/sdmmc-dm320.c
+++ b/firmware/target/arm/tms320dm320/sdmmc-dm320.c
@@ -19,13 +19,10 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "sd.h"
23#include "system.h" 22#include "system.h"
24#include <string.h> 23#include <string.h>
25#include "gcc_extensions.h" 24#include "gcc_extensions.h"
26#include "thread.h"
27#include "panic.h" 25#include "panic.h"
28#include "kernel.h"
29#include "dma-target.h" 26#include "dma-target.h"
30#include "ata_idle_notify.h" 27#include "ata_idle_notify.h"
31 28
@@ -42,8 +39,8 @@
42#endif 39#endif
43#endif 40#endif
44#include "sdmmc.h" 41#include "sdmmc.h"
45#include "disk.h"
46#include "system-target.h" 42#include "system-target.h"
43#include "storage.h"
47 44
48/* The configuration method is not very flexible. */ 45/* The configuration method is not very flexible. */
49#define CARD_NUM_SLOT 1 46#define CARD_NUM_SLOT 1
@@ -105,7 +102,6 @@ struct sd_card_status
105static long last_disk_activity = -1; 102static long last_disk_activity = -1;
106 103
107static bool initialized = false; 104static bool initialized = false;
108static unsigned int sd_thread_id = 0;
109 105
110static bool sd_enabled = false; 106static bool sd_enabled = false;
111static long next_yield = 0; 107static long next_yield = 0;
@@ -122,10 +118,7 @@ static struct sd_card_status sd_status[NUM_CARDS] =
122}; 118};
123 119
124/* Shoot for around 75% usage */ 120/* Shoot for around 75% usage */
125static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
126static const char sd_thread_name[] = "sd";
127static struct mutex sd_mtx SHAREDBSS_ATTR; 121static struct mutex sd_mtx SHAREDBSS_ATTR;
128static struct event_queue sd_queue;
129static volatile unsigned int transfer_error[NUM_DRIVES]; 122static volatile unsigned int transfer_error[NUM_DRIVES];
130/* align on cache line size */ 123/* align on cache line size */
131static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] 124static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE]
@@ -154,20 +147,16 @@ static void sd_card_mux(int card_no)
154#endif 147#endif
155} 148}
156 149
150static inline void enable_controller(bool on)
151{
152 sd_enabled = on;
153}
157 154
158void sd_enable(bool on) 155void sd_enable(bool on)
159{ 156{
160 if (sd_enabled == on) 157 mutex_lock(&sd_mtx);
161 return; /* nothing to do */ 158 enable_controller(on);
162 159 mutex_unlock(&sd_mtx);
163 if (on)
164 {
165 sd_enabled = true;
166 }
167 else
168 {
169 sd_enabled = false;
170 }
171} 160}
172 161
173/* sets clock rate just like OF does */ 162/* sets clock rate just like OF does */
@@ -514,17 +503,13 @@ static inline bool card_detect_target(void)
514 503
515static int sd1_oneshot_callback(struct timeout *tmo) 504static int sd1_oneshot_callback(struct timeout *tmo)
516{ 505{
517 (void)tmo;
518
519 /* This is called only if the state was stable for 300ms - check state 506 /* This is called only if the state was stable for 300ms - check state
520 * and post appropriate event. */ 507 * and post appropriate event. */
521 if (card_detect_target()) 508 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
522 { 509 SYS_HOTSWAP_EXTRACTED,
523 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 510 CARD_NUM_SLOT);
524 }
525 else
526 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
527 return 0; 511 return 0;
512 (void)tmo;
528} 513}
529 514
530#ifdef SANSA_CONNECT 515#ifdef SANSA_CONNECT
@@ -577,57 +562,6 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
577 562
578#endif /* HAVE_HOTSWAP */ 563#endif /* HAVE_HOTSWAP */
579 564
580static void sd_thread(void) NORETURN_ATTR;
581static void sd_thread(void)
582{
583 struct queue_event ev;
584 bool idle_notified = false;
585
586 while (1)
587 {
588 queue_wait_w_tmo(&sd_queue, &ev, HZ);
589 switch ( ev.id )
590 {
591#ifdef HAVE_HOTSWAP
592 case SYS_HOTSWAP_INSERTED:
593 case SYS_HOTSWAP_EXTRACTED:;
594 int success = 1;
595
596 disk_unmount(0); /* release "by force" */
597
598 mutex_lock(&sd_mtx); /* lock-out card activity */
599
600 /* Force card init for new card, re-init for re-inserted one or
601 * clear if the last attempt to init failed with an error. */
602 card_info[0].initialized = 0;
603
604 mutex_unlock(&sd_mtx);
605
606 if (ev.id == SYS_HOTSWAP_INSERTED)
607 success = disk_mount(0); /* 0 if fail */
608
609 /* notify the system about the changed filesystems */
610 if (success)
611 queue_broadcast(SYS_FS_CHANGED, 0);
612
613 break;
614#endif /* HAVE_HOTSWAP */
615
616 case SYS_TIMEOUT:
617 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
618 {
619 idle_notified = false;
620 }
621 else if (!idle_notified)
622 {
623 call_storage_idle_notifys(false);
624 idle_notified = true;
625 }
626 break;
627 }
628 }
629}
630
631static int sd_wait_for_state(unsigned int state) 565static int sd_wait_for_state(unsigned int state)
632{ 566{
633 unsigned long response = 0; 567 unsigned long response = 0;
@@ -671,7 +605,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
671 605
672 dbgprintf("transfer %d %d %d", card_no, start, count); 606 dbgprintf("transfer %d %d %d", card_no, start, count);
673 mutex_lock(&sd_mtx); 607 mutex_lock(&sd_mtx);
674 sd_enable(true); 608 enable_controller(true);
675 609
676sd_transfer_retry: 610sd_transfer_retry:
677 if (card_no == CARD_NUM_SLOT && !card_detect_target()) 611 if (card_no == CARD_NUM_SLOT && !card_detect_target())
@@ -812,7 +746,7 @@ sd_transfer_retry:
812 746
813 while (1) 747 while (1)
814 { 748 {
815 sd_enable(false); 749 enable_controller(false);
816 mutex_unlock(&sd_mtx); 750 mutex_unlock(&sd_mtx);
817 751
818 return ret; 752 return ret;
@@ -860,14 +794,17 @@ int sd_init(void)
860{ 794{
861 int ret = EC_OK; 795 int ret = EC_OK;
862 796
863#ifndef BOOTLOADER 797 if (!initialized)
864 sd_enabled = true; 798 {
865 sd_enable(false); 799 mutex_init(&sd_mtx);
866#endif 800 initialized = true;
867 mutex_init(&sd_mtx); 801 }
868 802
869 mutex_lock(&sd_mtx); 803 mutex_lock(&sd_mtx);
870 initialized = true; 804
805#ifndef BOOTLOADER
806 enable_controller(false);
807#endif
871 808
872 /* based on linux/drivers/mmc/dm320mmc.c 809 /* based on linux/drivers/mmc/dm320mmc.c
873 Copyright (C) 2006 ZSI, All Rights Reserved. 810 Copyright (C) 2006 ZSI, All Rights Reserved.
@@ -919,12 +856,6 @@ int sd_init(void)
919 856
920 /* Disable Memory Card CLK - it is enabled on demand by TMS320DM320 */ 857 /* Disable Memory Card CLK - it is enabled on demand by TMS320DM320 */
921 bitclr16(&IO_MMC_MEM_CLK_CONTROL, (1 << 8)); 858 bitclr16(&IO_MMC_MEM_CLK_CONTROL, (1 << 8));
922
923 queue_init(&sd_queue, true);
924 sd_thread_id = create_thread(sd_thread, sd_stack, sizeof(sd_stack),
925 0, sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
926 IF_COP(, CPU));
927
928 mutex_unlock(&sd_mtx); 859 mutex_unlock(&sd_mtx);
929 860
930 return ret; 861 return ret;
@@ -940,7 +871,27 @@ tCardInfo *card_get_info_target(int card_no)
940 return &card_info[card_no]; 871 return &card_info[card_no];
941} 872}
942 873
943void sd_sleepnow(void) 874int sd_event(long id, intptr_t data)
944{ 875{
945} 876 int rc = 0;
946 877
878 switch (id)
879 {
880#ifdef HAVE_HOTSWAP
881 case SYS_HOTSWAP_INSERTED:
882 case SYS_HOTSWAP_EXTRACTED:
883 mutex_lock(&sd_mtx); /* lock-out card activity */
884 /* Force card init for new card, re-init for re-inserted one or
885 * clear if the last attempt to init failed with an error. */
886 card_info[data].initialized = 0;
887 mutex_unlock(&sd_mtx);
888 break;
889#endif /* HAVE_HOTSWAP */
890 default:
891 rc = storage_event_default_handler(id, data, last_disk_activity,
892 STORAGE_SD);
893 break;
894 }
895
896 return rc;
897}