summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tcc780x/sd-tcc780x.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/tcc780x/sd-tcc780x.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/tcc780x/sd-tcc780x.c')
-rw-r--r--firmware/target/arm/tcc780x/sd-tcc780x.c129
1 files changed, 35 insertions, 94 deletions
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 */
56static long last_disk_activity = -1; 52static long last_disk_activity = -1;
57 53
58/** static, private data **/
59static bool initialized = false;
60
61static long next_yield = 0; 54static 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 */
84static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
85static const char sd_thread_name[] = "sd";
86static struct mutex sd_mtx SHAREDBSS_ATTR; 76static struct mutex sd_mtx SHAREDBSS_ATTR;
87static struct event_queue sd_queue;
88 77
78#ifdef CONFIG_STORAGE_MULTI
89static int sd_first_drive = 0; 79static int sd_first_drive = 0;
90 80#else
81#define sd_first_drive 0
82#endif
91 83
92static bool sd_poll_status(unsigned int trigger, long timeout) 84static bool sd_poll_status(unsigned int trigger, long timeout)
93{ 85{
@@ -216,16 +208,13 @@ static inline bool card_detect_target(void)
216 208
217static int sd1_oneshot_callback(struct timeout *tmo) 209static 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
231void EXT0(void) 220void EXT0(void)
@@ -642,71 +631,6 @@ sd_write_error:
642 } 631 }
643} 632}
644 633
645static void sd_thread(void) NORETURN_ATTR;
646static 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
710void sd_enable(bool on) 634void sd_enable(bool on)
711{ 635{
712 if(on) 636 if(on)
@@ -725,6 +649,7 @@ void sd_enable(bool on)
725 649
726int sd_init(void) 650int 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
797void sd_sleepnow(void)
798{
799}
800
801bool sd_disk_is_active(void) 717bool 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
734int 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}