summaryrefslogtreecommitdiff
path: root/firmware/target/sh/archos
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/sh/archos
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/sh/archos')
-rw-r--r--firmware/target/sh/archos/ondio/ata_mmc.c139
1 files changed, 45 insertions, 94 deletions
diff --git a/firmware/target/sh/archos/ondio/ata_mmc.c b/firmware/target/sh/archos/ondio/ata_mmc.c
index 5d95a0e789..f252e1c4ce 100644
--- a/firmware/target/sh/archos/ondio/ata_mmc.c
+++ b/firmware/target/sh/archos/ondio/ata_mmc.c
@@ -18,27 +18,29 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include <stdbool.h> 21#include "config.h"
22#include "mmc.h"
23#include "ata_mmc.h" 22#include "ata_mmc.h"
24#include "sdmmc.h" 23#include "sdmmc.h"
25#include "ata_idle_notify.h"
26#include "kernel.h" 24#include "kernel.h"
27#include "thread.h"
28#include "led.h" 25#include "led.h"
29#include "sh7034.h" 26#include "sh7034.h"
30#include "system.h" 27#include "system.h"
31#include "debug.h" 28#include "debug.h"
32#include "panic.h" 29#include "panic.h"
33#include "usb.h"
34#include "power.h" 30#include "power.h"
35#include "string.h" 31#include "string.h"
36#include "hwcompat.h" 32#include "hwcompat.h"
37#include "adc.h" 33#include "adc.h"
38#include "bitswap.h" 34#include "bitswap.h"
39#include "disk.h" /* for mount/unmount */
40#include "storage.h" 35#include "storage.h"
41 36
37
38#ifdef HAVE_MULTIDRIVE
39#define MMC_NUM_DRIVES 2
40#else
41#define MMC_NUM_DRIVES 1
42#endif
43
42#define BLOCK_SIZE 512 /* fixed */ 44#define BLOCK_SIZE 512 /* fixed */
43 45
44/* Command definitions */ 46/* Command definitions */
@@ -90,15 +92,14 @@ static long last_disk_activity = -1;
90 92
91/* private variables */ 93/* private variables */
92 94
93static struct mutex mmc_mutex SHAREDBSS_ATTR; 95#ifdef CONFIG_STORAGE_MULTI
94 96static int mmc_first_drive = 0;
95#ifdef HAVE_HOTSWAP
96static long mmc_stack[((DEFAULT_STACK_SIZE*2) + 0x800)/sizeof(long)];
97#else 97#else
98static long mmc_stack[(DEFAULT_STACK_SIZE*2)/sizeof(long)]; 98#define mmc_first_drive 0
99#endif 99#endif
100static const char mmc_thread_name[] = "mmc"; 100
101static struct event_queue mmc_queue SHAREDBSS_ATTR; 101static struct mutex mmc_mutex SHAREDBSS_ATTR;
102
102static bool initialized = false; 103static bool initialized = false;
103static bool new_mmc_circuit; 104static bool new_mmc_circuit;
104 105
@@ -158,6 +159,21 @@ static void mmc_tick(void);
158 159
159/* implementation */ 160/* implementation */
160 161
162static void enable_controller(bool on)
163{
164 PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO,
165 * if not modified below */
166 if (on)
167 PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */
168
169 and_b(~0x80, &PADRL); /* assert flash reset */
170 sleep(HZ/100);
171 or_b(0x80, &PADRL); /* de-assert flash reset */
172 sleep(HZ/100);
173 card_info[0].initialized = false;
174 card_info[1].initialized = false;
175}
176
161void mmc_enable_int_flash_clock(bool on) 177void mmc_enable_int_flash_clock(bool on)
162{ 178{
163 /* Internal flash clock is enabled by setting PA12 high with the new 179 /* Internal flash clock is enabled by setting PA12 high with the new
@@ -763,51 +779,6 @@ bool mmc_disk_is_active(void)
763 return mutex_test(&mmc_mutex); 779 return mutex_test(&mmc_mutex);
764} 780}
765 781
766static void mmc_thread(void)
767{
768 struct queue_event ev;
769 bool idle_notified = false;
770
771 while (1) {
772 queue_wait_w_tmo(&mmc_queue, &ev, HZ);
773 switch ( ev.id )
774 {
775 case SYS_USB_CONNECTED:
776 usb_acknowledge(SYS_USB_CONNECTED_ACK);
777 /* Wait until the USB cable is extracted again */
778 usb_wait_for_disconnect(&mmc_queue);
779 break;
780
781#ifdef HAVE_HOTSWAP
782 case SYS_HOTSWAP_INSERTED:
783 disk_mount(1); /* mount MMC */
784 queue_broadcast(SYS_FS_CHANGED, 0);
785 break;
786
787 case SYS_HOTSWAP_EXTRACTED:
788 disk_unmount(1); /* release "by force" */
789 queue_broadcast(SYS_FS_CHANGED, 0);
790 break;
791#endif
792
793 default:
794 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
795 {
796 idle_notified = false;
797 }
798 else
799 {
800 if (!idle_notified)
801 {
802 call_storage_idle_notifys(false);
803 idle_notified = true;
804 }
805 }
806 break;
807 }
808 }
809}
810
811bool mmc_detect(void) 782bool mmc_detect(void)
812{ 783{
813 return (adc_read(ADC_MMC_SWITCH) < 0x200); 784 return (adc_read(ADC_MMC_SWITCH) < 0x200);
@@ -868,11 +839,11 @@ static void mmc_tick(void)
868 { 839 {
869 if (current_status) 840 if (current_status)
870 { 841 {
871 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 842 queue_broadcast(SYS_HOTSWAP_INSERTED, mmc_first_drive + 1);
872 } 843 }
873 else 844 else
874 { 845 {
875 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0); 846 queue_broadcast(SYS_HOTSWAP_EXTRACTED, mmc_first_drive + 1);
876 mmc_status = MMC_UNTOUCHED; 847 mmc_status = MMC_UNTOUCHED;
877 card_info[1].initialized = false; 848 card_info[1].initialized = false;
878 } 849 }
@@ -882,17 +853,9 @@ static void mmc_tick(void)
882 853
883void mmc_enable(bool on) 854void mmc_enable(bool on)
884{ 855{
885 PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO, 856 mutex_lock(&mmc_mutex);
886 * if not modified below */ 857 enable_controller(on);
887 if (on) 858 mutex_unlock(&mmc_mutex);
888 PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */
889
890 and_b(~0x80, &PADRL); /* assert flash reset */
891 sleep(HZ/100);
892 or_b(0x80, &PADRL); /* de-assert flash reset */
893 sleep(HZ/100);
894 card_info[0].initialized = false;
895 card_info[1].initialized = false;
896} 859}
897 860
898int mmc_init(void) 861int mmc_init(void)
@@ -900,10 +863,8 @@ int mmc_init(void)
900 int rc = 0; 863 int rc = 0;
901 864
902 if (!initialized) 865 if (!initialized)
903 {
904 mutex_init(&mmc_mutex); 866 mutex_init(&mmc_mutex);
905 queue_init(&mmc_queue, true); 867
906 }
907 mutex_lock(&mmc_mutex); 868 mutex_lock(&mmc_mutex);
908 led(false); 869 led(false);
909 870
@@ -933,15 +894,10 @@ int mmc_init(void)
933 IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */ 894 IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */
934 895
935 new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0); 896 new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0);
936
937 create_thread(mmc_thread, mmc_stack,
938 sizeof(mmc_stack), 0, mmc_thread_name
939 IF_PRIO(, PRIORITY_SYSTEM)
940 IF_COP(, CPU));
941 tick_add_task(mmc_tick); 897 tick_add_task(mmc_tick);
942 initialized = true; 898 initialized = true;
943 } 899 }
944 mmc_enable(true); 900 enable_controller(true);
945 901
946 mutex_unlock(&mmc_mutex); 902 mutex_unlock(&mmc_mutex);
947 return rc; 903 return rc;
@@ -998,11 +954,6 @@ bool mmc_present(IF_MD_NONVOID(int drive))
998} 954}
999#endif 955#endif
1000 956
1001
1002void mmc_sleep(void)
1003{
1004}
1005
1006void mmc_spin(void) 957void mmc_spin(void)
1007{ 958{
1008} 959}
@@ -1015,13 +966,13 @@ void mmc_spindown(int seconds)
1015#ifdef CONFIG_STORAGE_MULTI 966#ifdef CONFIG_STORAGE_MULTI
1016int mmc_num_drives(int first_drive) 967int mmc_num_drives(int first_drive)
1017{ 968{
1018 /* We don't care which logical drive number(s) we have been assigned */ 969 mmc_first_drive = first_drive;
1019 (void)first_drive; 970 return MMC_NUM_DRIVES;
1020 971}
1021#ifdef HAVE_MULTIDRIVE 972#endif /* CONFIG_STORAGE_MULTI */
1022 return 2; 973
1023#else 974int mmc_event(long id, intptr_t data)
1024 return 1; 975{
1025#endif 976 return storage_event_default_handler(id, data, last_disk_activity,
977 STORAGE_MMC);
1026} 978}
1027#endif