freemyipod r968 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r967‎ | r968 | r969 >
Date:23:34, 21 July 2014
Author:theseven
Status:new
Tags:
Comment:
emCORE: iPod Classic: Make clickwheel driver aware of MENU+SELECT reset.
Modified paths:
  • /emcore/trunk/clickwheel.h (modified) (history)
  • /emcore/trunk/fat.c (modified) (history)
  • /emcore/trunk/fat.h (modified) (history)
  • /emcore/trunk/target/ipodclassic/storage_ata-target.h (modified) (history)
  • /emcore/trunk/target/ipodclassic/storage_ata.c (modified) (history)
  • /emcore/trunk/target/ipodnano2g/clickwheel.c (modified) (history)
  • /emcore/trunk/target/ipodnano3g/clickwheel.c (modified) (history)
  • /emcore/trunk/target/ipodnano3g/targetinit.c (modified) (history)

Diff [purge]

Index: emcore/trunk/target/ipodclassic/storage_ata.c
@@ -109,6 +109,16 @@
110110 ata_error_srst = enable;
111111 }
112112
 113+int ata_lock_exclusive(int timeout)
 114+{
 115+ return mutex_lock(&ata_mutex, timeout);
 116+}
 117+
 118+void ata_unlock_exclusive()
 119+{
 120+ mutex_unlock(&ata_mutex);
 121+}
 122+
113123 static uint16_t ata_read_cbr(uint32_t volatile* reg)
114124 {
115125 while (!(ATA_PIO_READY & 2)) yield();
@@ -1323,7 +1333,10 @@
13241334
13251335 int ata_init(void)
13261336 {
1327 - mutex_init(&ata_mutex);
 1337+ // Remove this, as it isn't strictly required and causes a race condition.
 1338+ // The clickwheel dispatcher can run ata_lock_exclusive before ata_init is run.
 1339+ // BSS is initialized to zeroes, which are interpreted as an unlocked mutex anyway.
 1340+ //mutex_init(&ata_mutex);
13281341 wakeup_init(&ata_wakeup);
13291342 wakeup_init(&mmc_wakeup);
13301343 wakeup_init(&mmc_comp_wakeup);
Index: emcore/trunk/target/ipodclassic/storage_ata-target.h
@@ -68,6 +68,8 @@
6969
7070 extern void ata_set_retries(int retries);
7171 extern void ata_srst_after_error(bool enable);
 72+extern int ata_lock_exclusive(int timeout);
 73+extern void ata_unlock_exclusive();
7274 extern int ata_soft_reset();
7375 extern int ata_hard_reset();
7476 extern int ata_read_taskfile(struct ata_raw_cmd_t* cmd);
Index: emcore/trunk/target/ipodnano2g/clickwheel.c
@@ -31,13 +31,15 @@
3232
3333
3434 static struct wakeup clickwheel_wakeup IBSS_ATTR;
 35+static struct wakeup clickwheel_init_wakeup INITDATA_ATTR;
3536 static volatile uint32_t clickwheel_packet IBSS_ATTR;
3637 static struct scheduler_thread clickwheel_thread_handle;
3738 static uint32_t clickwheel_stack[0x100] STACK_ATTR;
 39+static bool wheel_initialized IBSS_ATTR;
3840 static bool oldtouched IBSS_ATTR;
3941 static int oldpos IBSS_ATTR;
4042 static int oldbuttons IBSS_ATTR;
41 -static uint32_t lastpacket IBSS_ATTR;
 43+static int lastpacket IBSS_ATTR;
4244 static int packets IBSS_ATTR;
4345 static int collect IBSS_ATTR;
4446 static int lastdiff IBSS_ATTR;
@@ -124,14 +126,21 @@
125127 {
126128 if (data & 0x1F0000) oldbuttons = (data >> 16) & 0x1F;
127129 DEBUGF("This is an init packet, button state: %02X", oldbuttons);
 130+ if (!wheel_initialized)
 131+ {
 132+ wheel_initialized = true;
 133+ wakeup_signal(&clickwheel_init_wakeup);
 134+ }
128135 }
129136 }
130137 }
131138
132139
133 -void clickwheel_init()
 140+int clickwheel_init()
134141 {
135142 wakeup_init(&clickwheel_wakeup);
 143+ wakeup_init(&clickwheel_init_wakeup);
 144+ wheel_initialized = false;
136145 oldtouched = false;
137146 oldbuttons = 0;
138147 lastpacket = 0;
@@ -154,6 +163,9 @@
155164 thread_create(&clickwheel_thread_handle, "Clickwheel dispatcher", clickwheel_thread,
156165 clickwheel_stack, sizeof(clickwheel_stack), OS_THREAD, 200, true,
157166 NULL, NULL, NULL, NULL);
 167+ wakeup_wait(&clickwheel_init_wakeup, 100000);
 168+ if (!wheel_initialized) RET_ERR(0);
 169+ return 0;
158170 }
159171
160172 void INT_WHEEL(void) ICODE_ATTR;
Index: emcore/trunk/target/ipodnano3g/targetinit.c
@@ -37,6 +37,18 @@
3838 int i;
3939
4040 clickwheel_init();
 41+ int buttons = clickwheel_get_state() & 0x1f;
 42+ if (buttons == 0x11)
 43+ {
 44+ cputs(CONSOLE_BOOT, "MENU+SELECT is being pressed.\n"
 45+ "Continue pressing these buttons to enter DFU mode.\n");
 46+ while (buttons == 0x11)
 47+ {
 48+ sleep(100000);
 49+ buttons = clickwheel_get_state() & 0x1f;
 50+ }
 51+ cputs(CONSOLE_BOOT, "MENU+SELECT was released. Continuing normal boot.\n");
 52+ }
4153
4254 uint8_t* nor = (uint8_t*)memalign(0x10, 0x1000);
4355 uint32_t* norword = (uint32_t*)nor;
Index: emcore/trunk/target/ipodnano3g/clickwheel.c
@@ -28,16 +28,23 @@
2929 #include "timer.h"
3030 #include "s5l8702.h"
3131 #include "contextswitch.h"
 32+#ifdef TARGET_ipodclassic
 33+#include "fat.h"
 34+#include "storage_ata.h"
 35+#include "../ipodclassic/storage_ata-target.h"
 36+#endif
3237
3338
3439 static struct wakeup clickwheel_wakeup IBSS_ATTR;
 40+static struct wakeup clickwheel_init_wakeup INITDATA_ATTR;
3541 static volatile uint32_t clickwheel_packet IBSS_ATTR;
3642 static struct scheduler_thread clickwheel_thread_handle;
3743 static uint32_t clickwheel_stack[0x100] STACK_ATTR;
 44+static bool wheel_initialized IBSS_ATTR;
3845 static bool oldtouched IBSS_ATTR;
3946 static int oldpos IBSS_ATTR;
4047 static int oldbuttons IBSS_ATTR;
41 -static uint32_t lastpacket IBSS_ATTR;
 48+static int lastpacket IBSS_ATTR;
4249 static int packets IBSS_ATTR;
4350 static int collect IBSS_ATTR;
4451 static int lastdiff IBSS_ATTR;
@@ -55,14 +62,15 @@
5663 uint32_t data = clickwheel_packet;
5764 leave_critical_section(mode);
5865 DEBUGF("Acquired clickwheel packet: %08X", data);
 66+ int newbuttons = (data >> 8) & 0x1f;
5967 if ((data & 0x800000FF) == 0x8000001A)
6068 {
61 - int newbuttons = (data >> 8) & 0x1f;
6269 int newpos = (data >> 16) & 0xff;
6370 bool newtouched = (data & 0x40000000) ? true : false;
6471
6572 DEBUGF("This is a change packet, button state: %02X, position: %02d, touched: %d",
6673 newbuttons, newpos, newtouched);
 74+
6775 int buttonschanged = oldbuttons ^ newbuttons;
6876 DEBUGF("Changed buttons: %02X", buttonschanged);
6977 for (i = 0; i < 5; i++)
@@ -115,7 +123,6 @@
116124 lastdiff = 0;
117125 }
118126
119 - oldbuttons = newbuttons;
120127 oldpos = newpos;
121128 oldtouched = newtouched;
122129 lastpacket = USEC_TIMER;
@@ -122,16 +129,36 @@
123130 }
124131 else if ((data & 0x8000FFFF) == 0x8000023A)
125132 {
126 - if (data & 0x1F0000) oldbuttons = (data >> 16) & 0x1F;
127 - DEBUGF("This is an init packet, button state: %02X", oldbuttons);
 133+ if (data & 0x1F0000) newbuttons = (data >> 16) & 0x1F;
 134+ DEBUGF("This is an init packet, button state: %02X", newbuttons);
 135+ if (!wheel_initialized)
 136+ {
 137+ wheel_initialized = true;
 138+ wakeup_signal(&clickwheel_init_wakeup);
 139+ }
128140 }
 141+
 142+ #ifdef TARGET_ipodclassic
 143+ if (newbuttons == 0x11 && oldbuttons != 0x11)
 144+ {
 145+ ata_lock_exclusive(TIMEOUT_BLOCK);
 146+ flush_fat(true);
 147+ ata_sleepnow();
 148+ }
 149+ else if (newbuttons != 0x11 && oldbuttons == 0x11)
 150+ ata_unlock_exclusive();
 151+#endif
 152+
 153+ oldbuttons = newbuttons;
129154 }
130155 }
131156
132157
133 -void clickwheel_init()
 158+int clickwheel_init()
134159 {
135160 wakeup_init(&clickwheel_wakeup);
 161+ wakeup_init(&clickwheel_init_wakeup);
 162+ wheel_initialized = false;
136163 oldtouched = false;
137164 oldbuttons = 0;
138165 lastpacket = 0;
@@ -150,6 +177,9 @@
151178 thread_create(&clickwheel_thread_handle, "Clickwheel dispatcher", clickwheel_thread,
152179 clickwheel_stack, sizeof(clickwheel_stack), OS_THREAD, 200, true,
153180 NULL, NULL, NULL, NULL);
 181+ wakeup_wait(&clickwheel_init_wakeup, 100000);
 182+ if (!wheel_initialized) RET_ERR(0);
 183+ return 0;
154184 }
155185
156186 void INT_WHEEL(void) ICODE_ATTR;
Index: emcore/trunk/clickwheel.h
@@ -28,7 +28,7 @@
2929 #include "global.h"
3030
3131
32 -void clickwheel_init(void) INITCODE_ATTR;
 32+int clickwheel_init(void) INITCODE_ATTR;
3333 uint32_t clickwheel_get_state(void);
3434
3535
Index: emcore/trunk/fat.c
@@ -182,7 +182,6 @@
183183 static bool flush_fat_disabled = false;
184184
185185 static int update_fsinfo(IF_MV_NONVOID(struct bpb* fat_bpb));
186 -static int flush_fat(IF_MV_NONVOID(struct bpb* fat_bpb));
187186 static int bpb_is_sane(IF_MV_NONVOID(struct bpb* fat_bpb));
188187 static void *cache_fat_sector(IF_MV2(struct bpb* fat_bpb,)
189188 long secnum, bool dirty);
@@ -487,10 +486,11 @@
488487 #else
489488 (void)volume;
490489 #endif
 490+ if (!initialized) return;
491491
492492 if(flush)
493493 {
494 - rc = flush_fat(IF_MV(fat_bpb)); /* the clean way, while still alive */
 494+ rc = flush_fat(IF_MV2(fat_bpb,) true); /* the clean way, while still alive */
495495 }
496496 else
497497 { /* volume is not accessible any more, e.g. MMC removed */
@@ -1024,12 +1024,12 @@
10251025 return 0;
10261026 }
10271027
1028 -static int flush_fat(IF_MV_NONVOID(struct bpb* fat_bpb))
 1028+int flush_fat(IF_MV2(struct bpb* fat_bpb,) bool force)
10291029 {
10301030 int i;
10311031 int rc;
10321032 unsigned char *sec;
1033 - if (flush_fat_disabled)
 1033+ if (flush_fat_disabled && !force)
10341034 {
10351035 DEBUGF("flush_fat() skipped");
10361036 return 0;
@@ -1780,7 +1780,7 @@
17811781 /* Set the firstcluster field in the direntry */
17821782 update_short_entry(&newdir, 0, FAT_ATTR_DIRECTORY);
17831783
1784 - rc = flush_fat(IF_MV(fat_bpb));
 1784+ rc = flush_fat(IF_MV2(fat_bpb,) false);
17851785 if (rc < 0)
17861786 return rc * 10 - 5;
17871787
@@ -1830,7 +1830,7 @@
18311831 return rc * 10 - 1;
18321832 }
18331833
1834 - flush_fat(IF_MV(fat_bpb));
 1834+ flush_fat(IF_MV2(fat_bpb,) false);
18351835
18361836 #ifdef TEST_FAT
18371837 if ( file->firstcluster ) {
@@ -1968,7 +1968,7 @@
19691969 file->firstcluster = 0;
19701970 file->dircluster = 0;
19711971
1972 - rc = flush_fat(IF_MV(fat_bpb));
 1972+ rc = flush_fat(IF_MV2(fat_bpb,) false);
19731973 if (rc < 0)
19741974 return rc * 10 - 2;
19751975
@@ -2017,7 +2017,7 @@
20182018 if (rc < 0)
20192019 return rc * 10 - 4;
20202020
2021 - rc = flush_fat(IF_MV(fat_bpb));
 2021+ rc = flush_fat(IF_MV2(fat_bpb,) false);
20222022 if (rc < 0)
20232023 return rc * 10 - 5;
20242024
@@ -2575,5 +2575,5 @@
25762576 void fat_enable_flushing(bool state)
25772577 {
25782578 flush_fat_disabled = !state;
2579 - if (state) flush_fat();
 2579+ if (state) flush_fat(true);
25802580 }
Index: emcore/trunk/fat.h
@@ -142,6 +142,7 @@
143143 extern bool fat_ismounted(int volume);
144144 extern void* fat_get_sector_buffer(void);
145145 extern void fat_release_sector_buffer(void);
 146+extern int flush_fat(IF_MV2(struct bpb* fat_bpb,) bool force);
146147
147148
148149 #endif