summaryrefslogtreecommitdiff
path: root/firmware/target/arm/pp/ata-sd-pp.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/pp/ata-sd-pp.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/pp/ata-sd-pp.c')
-rw-r--r--firmware/target/arm/pp/ata-sd-pp.c274
1 files changed, 94 insertions, 180 deletions
diff --git a/firmware/target/arm/pp/ata-sd-pp.c b/firmware/target/arm/pp/ata-sd-pp.c
index edb806ab96..fb0a9e150e 100644
--- a/firmware/target/arm/pp/ata-sd-pp.c
+++ b/firmware/target/arm/pp/ata-sd-pp.c
@@ -24,16 +24,10 @@
24#ifdef HAVE_HOTSWAP 24#ifdef HAVE_HOTSWAP
25#include "sd-pp-target.h" 25#include "sd-pp-target.h"
26#endif 26#endif
27#include "ata_idle_notify.h"
28#include "system.h" 27#include "system.h"
29#include <string.h> 28#include <string.h>
30#include "thread.h"
31#include "led.h" 29#include "led.h"
32#include "disk.h"
33#include "cpu.h" 30#include "cpu.h"
34#include "panic.h"
35#include "usb.h"
36#include "sd.h"
37#include "storage.h" 31#include "storage.h"
38#include "fs_defines.h" 32#include "fs_defines.h"
39 33
@@ -151,12 +145,6 @@
151/* for compatibility */ 145/* for compatibility */
152static long last_disk_activity = -1; 146static long last_disk_activity = -1;
153 147
154/** static, private data **/
155static bool initialized = false;
156static unsigned int sd_thread_id = 0;
157
158#define Q_CLOSE 1
159
160static long next_yield = 0; 148static long next_yield = 0;
161#define MIN_YIELD_PERIOD 1000 149#define MIN_YIELD_PERIOD 1000
162 150
@@ -177,30 +165,28 @@ static struct sd_card_status sd_status[NUM_DRIVES] =
177#endif 165#endif
178}; 166};
179 167
180/* Shoot for around 75% usage */ 168static struct mutex sd_mtx SHAREDBSS_ATTR;
181static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
182static const char sd_thread_name[] = "ata/sd";
183static struct mutex sd_mtx SHAREDBSS_ATTR;
184static struct event_queue sd_queue SHAREDBSS_ATTR;
185 169
186#ifdef HAVE_HOTSWAP 170#ifdef HAVE_HOTSWAP
187static int sd_first_drive = 0; 171static int sd_first_drive = 0;
188#endif 172#endif
189 173
190/* Posted when card plugged status has changed */
191#define SD_HOTSWAP 1
192/* Actions taken by sd_thread when card status has changed */
193enum sd_thread_actions
194{
195 SDA_NONE = 0x0,
196 SDA_UNMOUNTED = 0x1,
197 SDA_MOUNTED = 0x2
198};
199
200/* Private Functions */ 174/* Private Functions */
201 175
202static unsigned int check_time[NUM_EC]; 176static unsigned int check_time[NUM_EC];
203 177
178static inline void enable_controller(bool on)
179{
180 if(on)
181 {
182 DEV_EN |= DEV_ATA; /* Enable controller */
183 }
184 else
185 {
186 DEV_EN &= ~DEV_ATA; /* Disable controller */
187 }
188}
189
204static inline bool sd_check_timeout(long timeout, int id) 190static inline bool sd_check_timeout(long timeout, int id)
205{ 191{
206 return !TIME_AFTER(USEC_TIMER, check_time[id] + timeout); 192 return !TIME_AFTER(USEC_TIMER, check_time[id] + timeout);
@@ -876,7 +862,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
876 /* TODO: Add DMA support. */ 862 /* TODO: Add DMA support. */
877 863
878 mutex_lock(&sd_mtx); 864 mutex_lock(&sd_mtx);
879 sd_enable(true); 865 enable_controller(true);
880 led(true); 866 led(true);
881 867
882sd_read_retry: 868sd_read_retry:
@@ -964,7 +950,7 @@ sd_read_retry:
964 while (1) 950 while (1)
965 { 951 {
966 led(false); 952 led(false);
967 sd_enable(false); 953 enable_controller(false);
968 mutex_unlock(&sd_mtx); 954 mutex_unlock(&sd_mtx);
969 955
970 return ret; 956 return ret;
@@ -994,7 +980,7 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
994 unsigned int bank; 980 unsigned int bank;
995 981
996 mutex_lock(&sd_mtx); 982 mutex_lock(&sd_mtx);
997 sd_enable(true); 983 enable_controller(true);
998 led(true); 984 led(true);
999 985
1000sd_write_retry: 986sd_write_retry:
@@ -1092,7 +1078,7 @@ sd_write_retry:
1092 while (1) 1078 while (1)
1093 { 1079 {
1094 led(false); 1080 led(false);
1095 sd_enable(false); 1081 enable_controller(false);
1096 mutex_unlock(&sd_mtx); 1082 mutex_unlock(&sd_mtx);
1097 1083
1098 return ret; 1084 return ret;
@@ -1108,182 +1094,79 @@ sd_write_error:
1108 } 1094 }
1109} 1095}
1110 1096
1111#ifndef SD_DRIVER_CLOSE
1112static void sd_thread(void) NORETURN_ATTR;
1113#endif
1114static void sd_thread(void)
1115{
1116 struct queue_event ev;
1117 bool idle_notified = false;
1118
1119 while (1)
1120 {
1121 queue_wait_w_tmo(&sd_queue, &ev, HZ);
1122
1123 switch ( ev.id )
1124 {
1125#ifdef HAVE_HOTSWAP
1126 case SYS_HOTSWAP_INSERTED:
1127 case SYS_HOTSWAP_EXTRACTED:;
1128 int success = 1;
1129
1130 disk_unmount(sd_first_drive+1); /* release "by force" */
1131
1132 mutex_lock(&sd_mtx); /* lock-out card activity */
1133
1134 /* Force card init for new card, re-init for re-inserted one or
1135 * clear if the last attempt to init failed with an error. */
1136 card_info[1].initialized = 0;
1137 sd_status[1].retry = 0;
1138
1139 /* Access is now safe */
1140 mutex_unlock(&sd_mtx);
1141
1142 if (ev.id == SYS_HOTSWAP_INSERTED)
1143 success = disk_mount(sd_first_drive+1); /* 0 if fail */
1144
1145 if (success)
1146 queue_broadcast(SYS_FS_CHANGED, 0);
1147 break;
1148#endif /* HAVE_HOTSWAP */
1149 case SYS_TIMEOUT:
1150 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
1151 {
1152 idle_notified = false;
1153 }
1154 else
1155 {
1156 /* never let a timer wrap confuse us */
1157 next_yield = USEC_TIMER;
1158
1159 if (!idle_notified)
1160 {
1161 call_storage_idle_notifys(false);
1162 idle_notified = true;
1163 }
1164 }
1165 break;
1166 case SYS_USB_CONNECTED:
1167 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1168 /* Wait until the USB cable is extracted again */
1169 usb_wait_for_disconnect(&sd_queue);
1170 break;
1171
1172#ifdef SD_DRIVER_CLOSE
1173 case Q_CLOSE:
1174 return;
1175#endif
1176 }
1177 }
1178}
1179
1180#ifdef SD_DRIVER_CLOSE
1181void sd_close(void)
1182{
1183 unsigned int thread_id = sd_thread_id;
1184
1185 if (thread_id == 0)
1186 return;
1187
1188 sd_thread_id = 0;
1189
1190 queue_post(&sd_queue, Q_CLOSE, 0);
1191 thread_wait(thread_id);
1192}
1193#endif /* SD_DRIVER_CLOSE */
1194
1195void sd_enable(bool on) 1097void sd_enable(bool on)
1196{ 1098{
1197 if(on) 1099 mutex_lock(&sd_mtx);
1198 { 1100 enable_controller(on);
1199 DEV_EN |= DEV_ATA; /* Enable controller */ 1101 mutex_unlock(&sd_mtx);
1200 }
1201 else
1202 {
1203 DEV_EN &= ~DEV_ATA; /* Disable controller */
1204 }
1205} 1102}
1206 1103
1207
1208int sd_init(void) 1104int sd_init(void)
1209{ 1105{
1210 int ret = 0; 1106 int ret = 0;
1211 1107
1212 if (!initialized) 1108 mutex_init(&sd_mtx);
1213 mutex_init(&sd_mtx);
1214
1215 mutex_lock(&sd_mtx);
1216 1109
1217 led(false); 1110 led(false);
1218 1111
1219 if (!initialized) 1112 /* init controller */
1220 {
1221 initialized = true;
1222
1223 /* init controller */
1224#if defined(PHILIPS_SA9200) 1113#if defined(PHILIPS_SA9200)
1225 GPIOA_ENABLE = 0x00; 1114 GPIOA_ENABLE = 0x00;
1226 GPIO_SET_BITWISE(GPIOD_ENABLE, 0x01); 1115 GPIO_SET_BITWISE(GPIOD_ENABLE, 0x01);
1227#else 1116#else
1228 outl(inl(0x70000088) & ~(0x4), 0x70000088); 1117 outl(inl(0x70000088) & ~(0x4), 0x70000088);
1229 outl(inl(0x7000008c) & ~(0x4), 0x7000008c); 1118 outl(inl(0x7000008c) & ~(0x4), 0x7000008c);
1230 GPO32_ENABLE |= 0x4; 1119 GPO32_ENABLE |= 0x4;
1231 1120
1232 GPIO_SET_BITWISE(GPIOG_ENABLE, (0x3 << 5)); 1121 GPIO_SET_BITWISE(GPIOG_ENABLE, (0x3 << 5));
1233 GPIO_SET_BITWISE(GPIOG_OUTPUT_EN, (0x3 << 5)); 1122 GPIO_SET_BITWISE(GPIOG_OUTPUT_EN, (0x3 << 5));
1234 GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, (0x3 << 5)); 1123 GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, (0x3 << 5));
1235#endif 1124#endif
1236 1125
1237#ifdef HAVE_HOTSWAP 1126#ifdef HAVE_HOTSWAP
1238 /* enable card detection port - mask interrupt first */ 1127 /* enable card detection port - mask interrupt first */
1239#ifdef SANSA_E200 1128#ifdef SANSA_E200
1240 GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80); 1129 GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80);
1241 1130
1242 GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x80); 1131 GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x80);
1243 GPIO_SET_BITWISE(GPIOA_ENABLE, 0x80); 1132 GPIO_SET_BITWISE(GPIOA_ENABLE, 0x80);
1244#elif defined SANSA_C200 1133#elif defined SANSA_C200
1245 GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08); 1134 GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08);
1246 1135
1247 GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_EN, 0x08); 1136 GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_EN, 0x08);
1248 GPIO_SET_BITWISE(GPIOL_ENABLE, 0x08); 1137 GPIO_SET_BITWISE(GPIOL_ENABLE, 0x08);
1249#endif 1138#endif
1250#endif 1139#endif
1251 sd_select_device(0); 1140 sd_select_device(0);
1252
1253 if (currcard->initialized < 0)
1254 ret = currcard->initialized;
1255 1141
1256 queue_init(&sd_queue, true); 1142 if (currcard->initialized < 0)
1257 sd_thread_id = create_thread(sd_thread, sd_stack, sizeof(sd_stack), 1143 ret = currcard->initialized;
1258 0, sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
1259 IF_COP(, CPU));
1260 1144
1261 /* enable interupt for the mSD card */ 1145 /* enable interupt for the mSD card */
1262 sleep(HZ/10); 1146 sleep(HZ/10);
1263#ifdef HAVE_HOTSWAP 1147#ifdef HAVE_HOTSWAP
1264#ifdef SANSA_E200 1148#ifdef SANSA_E200
1265 CPU_INT_EN = HI_MASK; 1149 CPU_INT_EN = HI_MASK;
1266 CPU_HI_INT_EN = GPIO0_MASK; 1150 CPU_HI_INT_EN = GPIO0_MASK;
1267 1151
1268 GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80); 1152 GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80);
1269 1153
1270 GPIOA_INT_CLR = 0x80; 1154 GPIOA_INT_CLR = 0x80;
1271 1155
1272 /* enable the card detect interrupt */ 1156 /* enable the card detect interrupt */
1273 GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80); 1157 GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80);
1274#elif defined SANSA_C200 1158#elif defined SANSA_C200
1275 CPU_INT_EN = HI_MASK; 1159 CPU_INT_EN = HI_MASK;
1276 CPU_HI_INT_EN = GPIO2_MASK; 1160 CPU_HI_INT_EN = GPIO2_MASK;
1277 1161
1278 GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08); 1162 GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08);
1279 1163
1280 GPIOL_INT_CLR = 0x08; 1164 GPIOL_INT_CLR = 0x08;
1281 1165
1282 /* enable the card detect interrupt */ 1166 /* enable the card detect interrupt */
1283 GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08); 1167 GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08);
1284#endif
1285#endif 1168#endif
1286 } 1169#endif /* HAVE_HOTSWAP */
1287 1170
1288 mutex_unlock(&sd_mtx); 1171 mutex_unlock(&sd_mtx);
1289 1172
@@ -1294,19 +1177,17 @@ tCardInfo *card_get_info_target(int card_no)
1294{ 1177{
1295 return &card_info[card_no]; 1178 return &card_info[card_no];
1296} 1179}
1180
1297#ifdef HAVE_HOTSWAP 1181#ifdef HAVE_HOTSWAP
1298static int sd1_oneshot_callback(struct timeout *tmo) 1182static int sd1_oneshot_callback(struct timeout *tmo)
1299{ 1183{
1300 (void)tmo;
1301
1302 /* This is called only if the state was stable for 300ms - check state 1184 /* This is called only if the state was stable for 300ms - check state
1303 * and post appropriate event. */ 1185 * and post appropriate event. */
1304 if (card_detect_target()) 1186 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
1305 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 1187 SYS_HOTSWAP_EXTRACTED,
1306 else 1188 sd_first_drive+1);
1307 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
1308
1309 return 0; 1189 return 0;
1190 (void)tmo;
1310} 1191}
1311 1192
1312/* called on insertion/removal interrupt */ 1193/* called on insertion/removal interrupt */
@@ -1377,3 +1258,36 @@ int sd_num_drives(int first_drive)
1377#endif 1258#endif
1378} 1259}
1379#endif 1260#endif
1261
1262int sd_event(long id, intptr_t data)
1263{
1264 int rc = 0;
1265
1266 switch (id)
1267 {
1268#ifdef HAVE_HOTSWAP
1269 case SYS_HOTSWAP_INSERTED:
1270 case SYS_HOTSWAP_EXTRACTED:
1271 mutex_lock(&sd_mtx); /* lock-out card activity */
1272
1273 /* Force card init for new card, re-init for re-inserted one or
1274 * clear if the last attempt to init failed with an error. */
1275 card_info[data].initialized = 0;
1276 sd_status[data].retry = 0;
1277
1278 /* Access is now safe */
1279 mutex_unlock(&sd_mtx);
1280 break;
1281#endif /* HAVE_HOTSWAP */
1282
1283 case Q_STORAGE_TICK:
1284 /* never let a timer wrap confuse us */
1285 next_yield = USEC_TIMER;
1286 default:
1287 rc = storage_event_default_handler(id, data, last_disk_activity,
1288 STORAGE_SD);
1289 break;
1290 }
1291
1292 return rc;
1293}