summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8702/ipod6g
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/s5l8702/ipod6g
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/s5l8702/ipod6g')
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c69
1 files changed, 35 insertions, 34 deletions
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
index ef39a5cabb..36d119aff3 100644
--- a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
@@ -19,8 +19,6 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "config.h" 21#include "config.h"
22#include "thread.h"
23#include "disk.h"
24#include "storage.h" 22#include "storage.h"
25#include "timer.h" 23#include "timer.h"
26#include "kernel.h" 24#include "kernel.h"
@@ -31,8 +29,6 @@
31#include "mmcdefs-target.h" 29#include "mmcdefs-target.h"
32#include "s5l8702.h" 30#include "s5l8702.h"
33#include "led.h" 31#include "led.h"
34#include "ata_idle_notify.h"
35#include "disk_cache.h"
36 32
37 33
38#ifndef ATA_RETRIES 34#ifndef ATA_RETRIES
@@ -58,7 +54,6 @@ static struct semaphore ata_wakeup;
58static uint32_t ata_dma_flags; 54static uint32_t ata_dma_flags;
59static long ata_last_activity_value = -1; 55static long ata_last_activity_value = -1;
60static long ata_sleep_timeout = 20 * HZ; 56static long ata_sleep_timeout = 20 * HZ;
61static uint32_t ata_stack[(DEFAULT_STACK_SIZE + 0x400) / 4];
62static bool ata_powered; 57static bool ata_powered;
63static const int ata_retries = ATA_RETRIES; 58static const int ata_retries = ATA_RETRIES;
64static const bool ata_error_srst = true; 59static const bool ata_error_srst = true;
@@ -889,21 +884,6 @@ static int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool wr
889 return 0; 884 return 0;
890} 885}
891 886
892static void ata_thread(void)
893{
894 while (true)
895 {
896 mutex_lock(&ata_mutex);
897 if (TIME_AFTER(current_tick, ata_last_activity_value + ata_sleep_timeout) && ata_powered)
898 {
899 call_storage_idle_notifys(false);
900 ata_power_down();
901 }
902 mutex_unlock(&ata_mutex);
903 sleep(HZ / 2);
904 }
905}
906
907/* API Functions */ 887/* API Functions */
908int ata_soft_reset(void) 888int ata_soft_reset(void)
909{ 889{
@@ -982,11 +962,6 @@ void ata_spindown(int seconds)
982 ata_sleep_timeout = seconds * HZ; 962 ata_sleep_timeout = seconds * HZ;
983} 963}
984 964
985void ata_sleep(void)
986{
987 ata_last_activity_value = current_tick - ata_sleep_timeout + HZ / 5;
988}
989
990void ata_sleepnow(void) 965void ata_sleepnow(void)
991{ 966{
992 mutex_lock(&ata_mutex); 967 mutex_lock(&ata_mutex);
@@ -994,11 +969,6 @@ void ata_sleepnow(void)
994 mutex_unlock(&ata_mutex); 969 mutex_unlock(&ata_mutex);
995} 970}
996 971
997void ata_close(void)
998{
999 ata_sleepnow();
1000}
1001
1002void ata_spin(void) 972void ata_spin(void)
1003{ 973{
1004 ata_set_active(); 974 ata_set_active();
@@ -1034,10 +1004,6 @@ int ata_init(void)
1034 mutex_unlock(&ata_mutex); 1004 mutex_unlock(&ata_mutex);
1035 if (IS_ERR(rc)) return rc; 1005 if (IS_ERR(rc)) return rc;
1036 1006
1037 create_thread(ata_thread, ata_stack,
1038 sizeof(ata_stack), 0, "ATA idle monitor"
1039 IF_PRIO(, PRIORITY_USER_INTERFACE)
1040 IF_COP(, CPU));
1041 return 0; 1007 return 0;
1042} 1008}
1043 1009
@@ -1129,3 +1095,38 @@ void INT_MMC(void)
1129 SDCI_IRQ = irq; 1095 SDCI_IRQ = irq;
1130} 1096}
1131 1097
1098int ata_event(long id, intptr_t data)
1099{
1100 int rc = 0;
1101
1102 /* GCC does a lousy job culling unreachable cases in the default handler
1103 if statements are in a switch statement, so we'll do it this way. Only
1104 the first case is frequently hit anyway. */
1105 if (LIKELY(id == Q_STORAGE_TICK))
1106 {
1107 if (!ata_powered ||
1108 TIME_BEFORE(current_tick, ata_last_activity_value + ata_sleep_timeout))
1109 {
1110 STG_EVENT_ASSERT_ACTIVE(STORAGE_ATA);
1111 }
1112 }
1113 else if (id == Q_STORAGE_SLEEPNOW)
1114 {
1115 ata_sleepnow();
1116 }
1117 else if (id == Q_STORAGE_SLEEP)
1118 {
1119 ata_last_activity_value = current_tick - ata_sleep_timeout + HZ / 5;
1120 }
1121 else if (id == SYS_USB_CONNECTED)
1122 {
1123 STG_EVENT_ASSERT_ACTIVE(STORAGE_ATA);
1124 }
1125 else
1126 {
1127 rc = storage_event_default_handler(id, data, ata_last_activity_value,
1128 STORAGE_ATA);
1129 }
1130
1131 return rc;
1132}