freemyipod r249 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r248‎ | r249 | r250 >
Date:00:58, 3 November 2010
Author:theseven
Status:new
Tags:
Comment:
emBIOS: Handle FTL problems more gracefully on iPod Nano 2G
Modified paths:
  • /embios/trunk/init.c (modified) (history)
  • /embios/trunk/panic.c (modified) (history)
  • /embios/trunk/target/ipodnano2g/ftl.c (modified) (history)
  • /embios/trunk/target/ipodnano2g/nand.c (modified) (history)
  • /embios/trunk/thread.c (modified) (history)
  • /embios/trunk/thread.h (modified) (history)

Diff [purge]

Index: embios/trunk/init.c
@@ -77,6 +77,11 @@
7878 static const char initthreadname[] INITCONST_ATTR = "Initialization thread";
7979 static uint32_t initstack[0x400] INITSTACK_ATTR;
8080 extern int _loadspaceend;
 81+#ifdef HAVE_STORAGE
 82+static const char storageinitthreadname[] INITCONST_ATTR = "Storage init thread";
 83+static uint32_t storageinitstack[0x400] INITBSS_ATTR;
 84+static struct wakeup storageinitwakeup;
 85+#endif
8186 struct bootinfo_t bootinfo_src INITHEAD_ATTR =
8287 {
8388 .signature = "emBIboot",
@@ -168,6 +173,23 @@
169174 cputs(CONSOLE_BOOT, "Waiting for USB commands\n\n");
170175 }
171176
 177+#ifdef HAVE_STORAGE
 178+void storageinitthread() INITCODE_ATTR;
 179+void storageinitthread()
 180+{
 181+ DEBUGF("Initializing storage drivers...");
 182+ storage_init();
 183+ DEBUGF("Initializing storage subsystem...");
 184+ disk_init_subsystem();
 185+ DEBUGF("Reading partition tables...");
 186+ disk_init();
 187+ DEBUGF("Mounting partitions...");
 188+ disk_mount_all();
 189+ DEBUGF("Storage init finished.");
 190+ wakeup_signal(&storageinitwakeup);
 191+}
 192+#endif
 193+
172194 void initthread() INITCODE_ATTR;
173195 void initthread()
174196 {
@@ -175,10 +197,15 @@
176198 i2c_init();
177199 #endif
178200 power_init();
 201+ cputs(CONSOLE_BOOT, welcomestring);
 202+#ifdef HAVE_STORAGE
 203+ wakeup_init(&storageinitwakeup);
 204+ int storagethread = thread_create(storageinitthreadname, storageinitthread, storageinitstack,
 205+ sizeof(storageinitstack), USER_THREAD, 127, true);
 206+#endif
179207 #ifdef HAVE_USB
180208 usb_init();
181209 #endif
182 - cputs(CONSOLE_BOOT, welcomestring);
183210 #ifdef HAVE_BACKLIGHT
184211 backlight_init();
185212 #endif
@@ -185,19 +212,25 @@
186213 #ifdef HAVE_BUTTON
187214 button_init();
188215 #endif
189 -#ifdef HAVE_STORAGE
190 - DEBUGF("Initializing storage drivers...");
191 - storage_init();
192 - DEBUGF("Initializing storage subsystem...");
193 - disk_init_subsystem();
194 - DEBUGF("Reading partition tables...");
195 - disk_init();
196 - DEBUGF("Mounting partitions...");
197 - disk_mount_all();
198 -#endif
199216 #ifdef HAVE_TARGETINIT_LATE
200217 targetinit_late();
201218 #endif
 219+#ifdef HAVE_STORAGE
 220+ while (true)
 221+ {
 222+ if (wakeup_wait(&storageinitwakeup, 100000) == THREAD_OK) break;
 223+ enum thread_state state = thread_get_state(storagethread);
 224+ if (state == THREAD_DEFUNCT || state == THREAD_DEFUNCT_ACK)
 225+ {
 226+ if (wakeup_wait(&storageinitwakeup, 0) == THREAD_OK) break;
 227+ thread_terminate(storagethread);
 228+ break;
 229+ }
 230+ }
 231+#endif
 232+#ifdef HAVE_TARGETINIT_VERYLATE
 233+ targetinit_verylate();
 234+#endif
202235 DEBUGF("Finished initialisation sequence");
203236 boot();
204237 }
Index: embios/trunk/panic.c
@@ -37,19 +37,18 @@
3838
3939 void handle_panic(enum panic_severity severity)
4040 {
41 - int i;
42 - if (severity == PANIC_KILLTHREAD) thread_exit();
43 - else
 41+ uint32_t mode = enter_critical_section();
 42+ if (severity == PANIC_KILLUSERTHREADS)
4443 {
45 - uint32_t mode = enter_critical_section();
 44+ int i;
4645 for (i = 0; i < MAX_THREADS; i++)
4746 if (scheduler_threads[i].type == USER_THREAD)
4847 scheduler_threads[i].state = THREAD_SUSPENDED;
49 - current_thread->state = THREAD_DEFUNCT_ACK;
50 - current_thread->block_type = THREAD_DEFUNCT_PANIC;
51 - leave_critical_section(mode);
52 - context_switch();
5348 }
 49+ current_thread->state = THREAD_DEFUNCT_ACK;
 50+ current_thread->block_type = THREAD_DEFUNCT_PANIC;
 51+ leave_critical_section(mode);
 52+ context_switch();
5453 }
5554
5655 void panic(enum panic_severity severity, const char* string)
Index: embios/trunk/target/ipodnano2g/nand.c
@@ -346,7 +346,7 @@
347347 for (i = 0; i < 4; i++)
348348 if (nand_type[i] >= 0)
349349 if (nand_reset(i))
350 - panicf(PANIC_FATAL, "nand_power_up: nand_reset(bank=%d) failed.", (unsigned int)i);
 350+ panicf(PANIC_KILLTHREAD, "nand_power_up: nand_reset(bank=%d) failed.", (unsigned int)i);
351351 nand_powered = 1;
352352 nand_last_activity_value = USEC_TIMER;
353353 mutex_unlock(&nand_mtx);
@@ -382,11 +382,11 @@
383383 uint8_t* spare = nand_spare;
384384 if (sparebuffer) spare = (uint8_t*)sparebuffer;
385385 if ((uint32_t)databuffer & (CACHEALIGN_SIZE - 1))
386 - panicf(PANIC_KILLUSERTHREADS,
 386+ panicf(PANIC_KILLTHREAD,
387387 "nand_read_page: Misaligned data buffer at %08X (bank %lu, page %lu)",
388388 (unsigned int)databuffer, bank, page);
389389 if ((uint32_t)sparebuffer & (CACHEALIGN_SIZE - 1))
390 - panicf(PANIC_KILLUSERTHREADS,
 390+ panicf(PANIC_KILLTHREAD,
391391 "nand_read_page: Misaligned spare buffer at %08X (bank %lu, page %lu)",
392392 (unsigned int)sparebuffer, bank, page);
393393 mutex_lock(&nand_mtx, TIMEOUT_BLOCK);
@@ -467,11 +467,11 @@
468468 uint8_t* spare = nand_spare;
469469 if (sparebuffer) spare = (uint8_t*)sparebuffer;
470470 if ((uint32_t)databuffer & 0xf)
471 - panicf(PANIC_KILLUSERTHREADS,
 471+ panicf(PANIC_KILLTHREAD,
472472 "nand_write_page: Misaligned data buffer at %08X (bank %lu, page %lu)",
473473 (unsigned int)databuffer, bank, page);
474474 if ((uint32_t)sparebuffer & 0xf)
475 - panicf(PANIC_KILLUSERTHREADS,
 475+ panicf(PANIC_KILLTHREAD,
476476 "nand_write_page: Misaligned spare buffer at %08X (bank %lu, page %lu)",
477477 (unsigned int)sparebuffer, bank, page);
478478 mutex_lock(&nand_mtx, TIMEOUT_BLOCK);
Index: embios/trunk/target/ipodnano2g/ftl.c
@@ -615,7 +615,8 @@
616616 ftl_vfl_cxt[bank].nextcxtpage = 0;
617617 if (ftl_vfl_store_cxt(bank) == 0) return 0;
618618 }
619 - panicf(PANIC_FATAL, "VFL: Failed to commit VFL CXT!");
 619+ ftl_initialized = false;
 620+ panicf(PANIC_KILLTHREAD, "VFL: Failed to commit VFL CXT!");
620621 return 1;
621622 }
622623 #endif
@@ -729,7 +730,8 @@
730731 static void ftl_vfl_schedule_block_for_remap(uint32_t bank, uint32_t block)
731732 {
732733 if (ftl_vfl_check_remap_scheduled(bank, block) == 1) return;
733 - panicf(PANIC_FATAL, "FTL: Scheduling bank %u block %u for remap!",
 734+ ftl_initialized = false;
 735+ panicf(PANIC_KILLTHREAD, "FTL: Scheduling bank %u block %u for remap!",
734736 (unsigned)bank, (unsigned)block);
735737 if (ftl_vfl_cxt[bank].scheduledstart == ftl_vfl_cxt[bank].spareused)
736738 return;
@@ -816,7 +818,8 @@
817819 {
818820 uint32_t i;
819821 uint32_t newblock = 0, newidx;
820 - panicf(PANIC_FATAL, "FTL: Remapping bank %u block %u!",
 822+ ftl_initialized = false;
 823+ panicf(PANIC_KILLTHREAD, "FTL: Remapping bank %u block %u!",
821824 (unsigned)bank, (unsigned)block);
822825 if (bank >= ftl_banks || block >= ftl_nand_type->blocks) return 0;
823826 for (i = 0; i < ftl_vfl_cxt[bank].sparecount; i++)
@@ -1009,7 +1012,8 @@
10101013 if (nand_read_page(bank[ftl_banks], physpage[ftl_banks],
10111014 ftl_buffer, &ftl_sparebuffer[0], 1, 1) & 0x11F)
10121015 {
1013 - panicf(PANIC_FATAL, "FTL: write error (2) on vPage %u, bank %u, pPage %u",
 1016+ ftl_initialized = false;
 1017+ panicf(PANIC_KILLTHREAD, "FTL: write error (2) on vPage %u, bank %u, pPage %u",
10141018 (unsigned)(vpage + i - ftl_banks),
10151019 (unsigned)bank[ftl_banks],
10161020 (unsigned)physpage[ftl_banks]);
@@ -1021,7 +1025,8 @@
10221026 if (nand_read_page(bank[0], physpage[0], ftl_buffer,
10231027 &ftl_sparebuffer[0], 1, 1) & 0x11F)
10241028 {
1025 - panicf(PANIC_FATAL, "FTL: write error (1) on vPage %u, bank %u, pPage %u",
 1029+ ftl_initialized = false;
 1030+ panicf(PANIC_KILLTHREAD, "FTL: write error (1) on vPage %u, bank %u, pPage %u",
10261031 (unsigned)(vpage + i), (unsigned)bank[0], (unsigned)physpage[0]);
10271032 ftl_vfl_log_trouble(bank[0], block[0]);
10281033 }
@@ -1032,7 +1037,8 @@
10331038 if (nand_read_page(bank[i - 1], physpage[i - 1],
10341039 ftl_buffer, &ftl_sparebuffer[0], 1, 1) & 0x11F)
10351040 {
1036 - panicf(PANIC_FATAL, "FTL: write error (2) on vPage %u, bank %u, pPage %u",
 1041+ ftl_initialized = false;
 1042+ panicf(PANIC_KILLTHREAD, "FTL: write error (2) on vPage %u, bank %u, pPage %u",
10371043 (unsigned)(vpage + count - i),
10381044 (unsigned)bank[i - 1], (unsigned)physpage[i - 1]);
10391045 ftl_vfl_log_trouble(bank[i - 1], block[i - 1]);
@@ -1113,9 +1119,12 @@
11141120 if (ftl_vfl_read_page(i, vflcxtblock[vflcxtidx],
11151121 last, ftl_buffer,
11161122 &ftl_sparebuffer[0]) != 0)
1117 - panicf(PANIC_FATAL, "FTL: Re-reading VFL CXT block "
1118 - "on bank %u failed!?", (unsigned)i);
 1123+ {
 1124+ ftl_initialized = false;
 1125+ panicf(PANIC_KILLTHREAD, "FTL: Re-reading VFL CXT block "
 1126+ "on bank %u failed!?", (unsigned)i);
11191127 //return 1;
 1128+ }
11201129 memcpy(&ftl_vfl_cxt[i], ftl_buffer, 0x800);
11211130 if (ftl_vfl_verify_checksum(i) != 0) return 1;
11221131 #ifndef FTL_READONLY
@@ -1329,6 +1338,11 @@
13301339 if (count == 0) return 0;
13311340
13321341 mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
 1342+ if (!ftl_initialized)
 1343+ {
 1344+ mutex_unlock(&ftl_mtx);
 1345+ return -1;
 1346+ }
13331347
13341348 for (i = 0; i < count; i++)
13351349 {
@@ -1422,7 +1436,8 @@
14231437 }
14241438 if (rc != 0)
14251439 {
1426 - panicf(PANIC_FATAL, "FTL: Block erase failed on bank %u block %u",
 1440+ ftl_initialized = false;
 1441+ panicf(PANIC_KILLTHREAD, "FTL: Block erase failed on bank %u block %u",
14271442 (unsigned)i, (unsigned)block);
14281443 if (pblock != block)
14291444 {
@@ -1471,7 +1486,11 @@
14721487 bestidx = idx;
14731488 }
14741489 }
1475 - if (bestidx == 0xFFFFFFFF) panicf(PANIC_FATAL, "FTL: Out of pool blocks!");
 1490+ if (bestidx == 0xFFFFFFFF0)
 1491+ {
 1492+ ftl_initialized = false;
 1493+ panicf(PANIC_KILLTHREAD, "FTL: Out of pool blocks!");
 1494+ }
14761495 block = ftl_cxt.blockpool[bestidx];
14771496 if (bestidx != ftl_cxt.nextfreeidx)
14781497 {
@@ -1479,7 +1498,10 @@
14801499 ftl_cxt.blockpool[ftl_cxt.nextfreeidx] = block;
14811500 }
14821501 if (block > (uint32_t)ftl_nand_type->userblocks + 0x17)
1483 - panicf(PANIC_FATAL, "FTL: Bad block number in pool: %u", (unsigned)block);
 1502+ {
 1503+ ftl_initialized = false;
 1504+ panicf(PANIC_KILLTHREAD, "FTL: Bad block number in pool: %u", (unsigned)block);
 1505+ }
14841506 if (ftl_erase_block(block) != 0) return 0xFFFFFFFF;
14851507 if (++ftl_cxt.nextfreeidx == 0x14) ftl_cxt.nextfreeidx = 0;
14861508 ftl_cxt.freecount--;
@@ -1493,7 +1515,10 @@
14941516 static void ftl_release_pool_block(uint32_t block)
14951517 {
14961518 if (block >= (uint32_t)ftl_nand_type->userblocks + 0x17)
1497 - panicf(PANIC_FATAL, "FTL: Tried to release block %u", (unsigned)block);
 1519+ {
 1520+ ftl_initialized = false;
 1521+ panicf(PANIC_KILLTHREAD, "FTL: Tried to release block %u", (unsigned)block);
 1522+ }
14981523 uint32_t idx = ftl_cxt.nextfreeidx + ftl_cxt.freecount++;
14991524 if (idx >= 0x14) idx -= 0x14;
15001525 ftl_cxt.blockpool[idx] = block;
@@ -1863,7 +1888,11 @@
18641889
18651890 if (entry == NULL)
18661891 {
1867 - if (ftl_cxt.freecount < 3) panicf(PANIC_FATAL, "FTL: Detected a pool block leak!");
 1892+ if (ftl_cxt.freecount < 3)
 1893+ {
 1894+ ftl_initialized = false;
 1895+ panicf(PANIC_KILLTHREAD, "FTL: Detected a pool block leak!");
 1896+ }
18681897 else if (ftl_cxt.freecount == 3)
18691898 if (ftl_remove_scattered_block(NULL) != 0)
18701899 return NULL;
@@ -1994,6 +2023,11 @@
19952024 if (count == 0) return 0;
19962025
19972026 mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
 2027+ if (!ftl_initialized)
 2028+ {
 2029+ mutex_unlock(&ftl_mtx);
 2030+ return -1;
 2031+ }
19982032
19992033 if (ftl_cxt.clean_flag == 1)
20002034 {
@@ -2125,8 +2159,12 @@
21262160 }
21272161 i += cnt;
21282162 }
2129 - else panicf(PANIC_FATAL, "FTL: Write error: %u %u %u!",
2130 - (unsigned)sector, (unsigned)count, (unsigned)i);
 2163+ else
 2164+ {
 2165+ ftl_initialized = false;
 2166+ panicf(PANIC_KILLTHREAD, "FTL: Write error: %u %u %u!",
 2167+ (unsigned)sector, (unsigned)count, (unsigned)i);
 2168+ }
21312169 }
21322170 if (logentry->pagesused == ppb) ftl_remove_scattered_block(logentry);
21332171 }
@@ -2166,6 +2204,11 @@
21672205 if (ftl_cxt.clean_flag == 1) return 0;
21682206
21692207 mutex_lock(&ftl_mtx, TIMEOUT_BLOCK);
 2208+ if (!ftl_initialized)
 2209+ {
 2210+ mutex_unlock(&ftl_mtx);
 2211+ return -1;
 2212+ }
21702213
21712214 #ifdef FTL_TRACE
21722215 DEBUGF("FTL: Syncing");
@@ -2543,7 +2586,7 @@
25442587 uint32_t i;
25452588 int rc;
25462589 if ((rc = nand_device_init()) != 0)
2547 - panicf(PANIC_FATAL, "FTL: Lowlevel NAND driver init failed: %d", rc);
 2590+ panicf(PANIC_KILLTHREAD, "FTL: Lowlevel NAND driver init failed: %d", rc);
25482591 ftl_banks = 0;
25492592 for (i = 0; i < 4; i++)
25502593 if (nand_get_device_type(i) != 0) ftl_banks = i + 1;
@@ -2561,7 +2604,7 @@
25622605 ftl_initialized = true;
25632606 return 0;
25642607 }
2565 - cputs(CONSOLE_BOOT, "The FTL seems to be damaged. Forcing check.\n");
 2608+ cputs(CONSOLE_BOOT, "The FTL seems to be unclean. Forcing check.\n");
25662609 if (ftl_repair() != 0)
25672610 cputs(CONSOLE_BOOT, "FTL recovery failed. Use disk mode to recover.\n");
25682611 else
Index: embios/trunk/thread.c
@@ -453,6 +453,11 @@
454454 return ret;
455455 }
456456
 457+enum thread_state thread_get_state(int thread)
 458+{
 459+ return scheduler_threads[thread].state;
 460+}
 461+
457462 void thread_exit()
458463 {
459464 thread_terminate(-1);
Index: embios/trunk/thread.h
@@ -115,6 +115,7 @@
116116 int thread_suspend(int thread);
117117 int thread_resume(int thread);
118118 int thread_terminate(int thread);
 119+enum thread_state thread_get_state(int thread);
119120 void thread_exit();
120121 void mutex_init(struct mutex* obj) ICODE_ATTR;
121122 int mutex_lock(struct mutex* obj, int timeout) ICODE_ATTR;