summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorMichael Sparmann <theseven@rockbox.org>2010-08-12 08:49:54 +0000
committerMichael Sparmann <theseven@rockbox.org>2010-08-12 08:49:54 +0000
commitc65a8e07552711f6a62bcdc195adbf9ff0345c0e (patch)
treea5a29f5504cc0af9d66464c6d26797bf7ac229ac /firmware
parentb4d6d1e64392177f91adb2327f00f24091c0d56d (diff)
downloadrockbox-c65a8e07552711f6a62bcdc195adbf9ff0345c0e.tar.gz
rockbox-c65a8e07552711f6a62bcdc195adbf9ff0345c0e.zip
emBIOS backports part four: Add a lot of DEBUGF()s to the FTL code, and return proper error codes instead of panicing in a lot of error cases.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27783 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c205
1 files changed, 157 insertions, 48 deletions
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c
index 69fac62289..f7c636d7bd 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c
+++ b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c
@@ -29,6 +29,7 @@
29#include "system.h" 29#include "system.h"
30#include "kernel.h" 30#include "kernel.h"
31#include "panic.h" 31#include "panic.h"
32#include "debug.h"
32 33
33 34
34 35
@@ -183,7 +184,7 @@ struct ftl_cxt_type
183 184
184/* Keeps the state of the bank's VFL, both on flash and in memory. 185/* Keeps the state of the bank's VFL, both on flash and in memory.
185 There is one of these per bank. */ 186 There is one of these per bank. */
186typedef struct ftl_vfl_cxt_type 187struct ftl_vfl_cxt_type
187{ 188{
188 189
189 /* Cross-bank update sequence number, incremented on every VFL 190 /* Cross-bank update sequence number, incremented on every VFL
@@ -252,7 +253,7 @@ typedef struct ftl_vfl_cxt_type
252 /* Second checksum (XOR), there is a bug in whimory regarding this. */ 253 /* Second checksum (XOR), there is a bug in whimory regarding this. */
253 uint32_t checksum2; 254 uint32_t checksum2;
254 255
255} __attribute__((packed)) FTLVFLCxtType; 256} __attribute__((packed));
256 257
257 258
258/* Layout of the spare bytes of each page on the flash */ 259/* Layout of the spare bytes of each page on the flash */
@@ -513,7 +514,7 @@ static uint32_t ftl_vfl_verify_checksum(uint32_t bank)
513 /* The following line is pretty obviously a bug in Whimory, 514 /* The following line is pretty obviously a bug in Whimory,
514 but we do it the same way for compatibility. */ 515 but we do it the same way for compatibility. */
515 if (checksum2 != ftl_vfl_cxt[bank].checksum2) return 0; 516 if (checksum2 != ftl_vfl_cxt[bank].checksum2) return 0;
516 panicf("FTL: Bad VFL CXT checksum!"); 517 DEBUGF("FTL: Bad VFL CXT checksum on bank %d!\n", bank);
517 return 1; 518 return 1;
518} 519}
519 520
@@ -577,6 +578,7 @@ static uint32_t ftl_vfl_store_cxt(uint32_t bank)
577 retries until it works or all available pages have been tried */ 578 retries until it works or all available pages have been tried */
578static uint32_t ftl_vfl_commit_cxt(uint32_t bank) 579static uint32_t ftl_vfl_commit_cxt(uint32_t bank)
579{ 580{
581 DEBUGF("FTL: VFL: Committing context on bank %d\n", bank);
580 if (ftl_vfl_cxt[bank].nextcxtpage + 8 <= ftl_nand_type->pagesperblock) 582 if (ftl_vfl_cxt[bank].nextcxtpage + 8 <= ftl_nand_type->pagesperblock)
581 if (ftl_vfl_store_cxt(bank) == 0) return 0; 583 if (ftl_vfl_store_cxt(bank) == 0) return 0;
582 uint32_t current = ftl_vfl_cxt[bank].activecxtblock; 584 uint32_t current = ftl_vfl_cxt[bank].activecxtblock;
@@ -595,7 +597,7 @@ static uint32_t ftl_vfl_commit_cxt(uint32_t bank)
595 ftl_vfl_cxt[bank].nextcxtpage = 0; 597 ftl_vfl_cxt[bank].nextcxtpage = 0;
596 if (ftl_vfl_store_cxt(bank) == 0) return 0; 598 if (ftl_vfl_store_cxt(bank) == 0) return 0;
597 } 599 }
598 panicf("FTL: Failed to commit VFL CXT!"); 600 panicf("VFL: Failed to commit VFL CXT!");
599 return 1; 601 return 1;
600} 602}
601#endif 603#endif
@@ -678,7 +680,11 @@ static uint32_t ftl_vfl_get_physical_block(uint32_t bank, uint32_t block)
678 uint32_t spareused = ftl_vfl_cxt[bank].spareused; 680 uint32_t spareused = ftl_vfl_cxt[bank].spareused;
679 for (spareindex = 0; spareindex < spareused; spareindex++) 681 for (spareindex = 0; spareindex < spareused; spareindex++)
680 if (ftl_vfl_cxt[bank].remaptable[spareindex] == block) 682 if (ftl_vfl_cxt[bank].remaptable[spareindex] == block)
683 {
684 DEBUGF("FTL: VFL: Following remapped block: %d => %d\n",
685 block, ftl_vfl_cxt[bank].firstspare + spareindex);
681 return ftl_vfl_cxt[bank].firstspare + spareindex; 686 return ftl_vfl_cxt[bank].firstspare + spareindex;
687 }
682 return block; 688 return block;
683} 689}
684 690
@@ -816,13 +822,19 @@ static uint32_t ftl_vfl_remap_block(uint32_t bank, uint32_t block)
816static uint32_t ftl_vfl_read(uint32_t vpage, void* buffer, void* sparebuffer, 822static uint32_t ftl_vfl_read(uint32_t vpage, void* buffer, void* sparebuffer,
817 uint32_t checkempty, uint32_t remaponfail) 823 uint32_t checkempty, uint32_t remaponfail)
818{ 824{
825#ifdef VFL_TRACE
826 DEBUGF("FTL: VFL: Reading page %d\n", vpage);
827#endif
828
819 uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks; 829 uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
820 uint32_t syshyperblocks = ftl_nand_type->blocks 830 uint32_t syshyperblocks = ftl_nand_type->blocks
821 - ftl_nand_type->userblocks - 0x17; 831 - ftl_nand_type->userblocks - 0x17;
822 uint32_t abspage = vpage + ppb * syshyperblocks; 832 uint32_t abspage = vpage + ppb * syshyperblocks;
823 if (abspage >= ftl_nand_type->blocks * ppb || abspage < ppb) 833 if (abspage >= ftl_nand_type->blocks * ppb || abspage < ppb)
824 panicf("FTL: Trying to read out-of-bounds vPage %u", (unsigned)vpage); 834 {
825 //return 4; 835 DEBUGF("FTL: Trying to read out-of-bounds vPage %u\n", (unsigned)vpage);
836 return 4;
837 }
826 838
827 uint32_t bank = abspage % ftl_banks; 839 uint32_t bank = abspage % ftl_banks;
828 uint32_t block = abspage / (ftl_nand_type->pagesperblock * ftl_banks); 840 uint32_t block = abspage / (ftl_nand_type->pagesperblock * ftl_banks);
@@ -842,7 +854,10 @@ static uint32_t ftl_vfl_read(uint32_t vpage, void* buffer, void* sparebuffer,
842 (void)remaponfail; 854 (void)remaponfail;
843#else 855#else
844 if (remaponfail == 1 &&(ret & 0x11D) != 0 && (ret & 2) == 0) 856 if (remaponfail == 1 &&(ret & 0x11D) != 0 && (ret & 2) == 0)
857 {
858 DEBUGF("FTL: VFL: Scheduling vBlock %d for remapping!\n", block);
845 ftl_vfl_schedule_block_for_remap(bank, block); 859 ftl_vfl_schedule_block_for_remap(bank, block);
860 }
846#endif 861#endif
847 return ret; 862 return ret;
848 } 863 }
@@ -855,14 +870,20 @@ static uint32_t ftl_vfl_read(uint32_t vpage, void* buffer, void* sparebuffer,
855static uint32_t ftl_vfl_read_fast(uint32_t vpage, void* buffer, void* sparebuffer, 870static uint32_t ftl_vfl_read_fast(uint32_t vpage, void* buffer, void* sparebuffer,
856 uint32_t checkempty, uint32_t remaponfail) 871 uint32_t checkempty, uint32_t remaponfail)
857{ 872{
873#ifdef VFL_TRACE
874 DEBUGF("FTL: VFL: Fast reading page %d on all banks\n", vpage);
875#endif
876
858 uint32_t i, rc = 0; 877 uint32_t i, rc = 0;
859 uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks; 878 uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
860 uint32_t syshyperblocks = ftl_nand_type->blocks 879 uint32_t syshyperblocks = ftl_nand_type->blocks
861 - ftl_nand_type->userblocks - 0x17; 880 - ftl_nand_type->userblocks - 0x17;
862 uint32_t abspage = vpage + ppb * syshyperblocks; 881 uint32_t abspage = vpage + ppb * syshyperblocks;
863 if (abspage + ftl_banks - 1 >= ftl_nand_type->blocks * ppb || abspage < ppb) 882 if (abspage + ftl_banks - 1 >= ftl_nand_type->blocks * ppb || abspage < ppb)
864 panicf("FTL: Trying to read out-of-bounds vPage %u", (unsigned)vpage); 883 {
865 //return 4; 884 DEBUGF("FTL: Trying to read out-of-bounds vPage %u\n", (unsigned)vpage);
885 return 4;
886 }
866 887
867 uint32_t bank = abspage % ftl_banks; 888 uint32_t bank = abspage % ftl_banks;
868 uint32_t block = abspage / (ftl_nand_type->pagesperblock * ftl_banks); 889 uint32_t block = abspage / (ftl_nand_type->pagesperblock * ftl_banks);
@@ -926,14 +947,20 @@ static uint32_t ftl_vfl_write(uint32_t vpage, uint32_t count,
926 void* buffer, void* sparebuffer) 947 void* buffer, void* sparebuffer)
927{ 948{
928 uint32_t i, j; 949 uint32_t i, j;
950#ifdef VFL_TRACE
951 DEBUGF("FTL: VFL: Writing page %d\n", vpage);
952#endif
953
929 uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks; 954 uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
930 uint32_t syshyperblocks = ftl_nand_type->blocks 955 uint32_t syshyperblocks = ftl_nand_type->blocks
931 - ftl_nand_type->userblocks - 0x17; 956 - ftl_nand_type->userblocks - 0x17;
932 uint32_t abspage = vpage + ppb * syshyperblocks; 957 uint32_t abspage = vpage + ppb * syshyperblocks;
933 if (abspage + count > ftl_nand_type->blocks * ppb || abspage < ppb) 958 if (abspage + count > ftl_nand_type->blocks * ppb || abspage < ppb)
934 panicf("FTL: Trying to write out-of-bounds vPage %u", 959 {
960 DEBUGF("FTL: Trying to write out-of-bounds vPage %u\n",
935 (unsigned)vpage); 961 (unsigned)vpage);
936 //return 4; 962 return 4;
963 }
937 964
938 uint32_t bank[5]; 965 uint32_t bank[5];
939 uint32_t block[5]; 966 uint32_t block[5];
@@ -997,7 +1024,7 @@ static uint32_t ftl_vfl_open(void)
997{ 1024{
998 uint32_t i, j, k; 1025 uint32_t i, j, k;
999 uint32_t minusn, vflcxtidx, last; 1026 uint32_t minusn, vflcxtidx, last;
1000 FTLVFLCxtType* cxt; 1027 struct ftl_vfl_cxt_type* cxt;
1001 uint16_t vflcxtblock[4]; 1028 uint16_t vflcxtblock[4];
1002#ifndef FTL_READONLY 1029#ifndef FTL_READONLY
1003 ftl_vfl_usn = 0; 1030 ftl_vfl_usn = 0;
@@ -1042,9 +1069,12 @@ static uint32_t ftl_vfl_open(void)
1042 minusn = ftl_sparebuffer[0].meta.usn; 1069 minusn = ftl_sparebuffer[0].meta.usn;
1043 vflcxtidx = k; 1070 vflcxtidx = k;
1044 } 1071 }
1045 if (vflcxtidx == 4) //return 1; 1072 if (vflcxtidx == 4)
1046 panicf("FTL: No VFL CXT block found on bank %u!", 1073 {
1074 DEBUGF("FTL: No VFL CXT block found on bank %u!\n",
1047 (unsigned)i); 1075 (unsigned)i);
1076 return 1;
1077 }
1048 last = 0; 1078 last = 0;
1049 uint32_t max = ftl_nand_type->pagesperblock; 1079 uint32_t max = ftl_nand_type->pagesperblock;
1050 for (k = 8; k < max; k += 8) 1080 for (k = 8; k < max; k += 8)
@@ -1070,8 +1100,11 @@ static uint32_t ftl_vfl_open(void)
1070 break; 1100 break;
1071 } 1101 }
1072 } 1102 }
1073 else //return 1; 1103 else
1074 panicf("FTL: Couldn't load bank %u lowlevel BBT!", (unsigned)i); 1104 {
1105 DEBUGF("FTL: Couldn't load bank %u lowlevel BBT!\n", (unsigned)i);
1106 return 1;
1107 }
1075 cxt = ftl_vfl_get_newest_cxt(); 1108 cxt = ftl_vfl_get_newest_cxt();
1076 for (i = 0; i < ftl_banks; i++) 1109 for (i = 0; i < ftl_banks; i++)
1077 memcpy(ftl_vfl_cxt[i].ftlctrlblocks, cxt->ftlctrlblocks, 6); 1110 memcpy(ftl_vfl_cxt[i].ftlctrlblocks, cxt->ftlctrlblocks, 6);
@@ -1101,9 +1134,13 @@ static uint32_t ftl_open(void)
1101 ftlcxtblock = cxt->ftlctrlblocks[i]; 1134 ftlcxtblock = cxt->ftlctrlblocks[i];
1102 } 1135 }
1103 1136
1104 if (ftlcxtblock == 0xffffffff) //return 1; 1137 if (ftlcxtblock == 0xffffffff)
1105 panicf("FTL: Couldn't find readable FTL CXT block!"); 1138 {
1139 DEBUGF("FTL: Couldn't find readable FTL CXT block!\n");
1140 return 1;
1141 }
1106 1142
1143 DEBUGF("FTL: Found FTL context block: vBlock %d\n", ftlcxtblock);
1107 uint32_t ftlcxtfound = 0; 1144 uint32_t ftlcxtfound = 0;
1108 for (i = ftl_nand_type->pagesperblock * ftl_banks - 1; i > 0; i--) 1145 for (i = ftl_nand_type->pagesperblock * ftl_banks - 1; i > 0; i--)
1109 { 1146 {
@@ -1119,15 +1156,20 @@ static uint32_t ftl_open(void)
1119 else 1156 else
1120 { 1157 {
1121 /* This will trip if there was an unclean unmount before. */ 1158 /* This will trip if there was an unclean unmount before. */
1122#ifndef FTL_FORCEMOUNT 1159 DEBUGF("FTL: Unclean shutdown before!\n");
1123 panicf("FTL: Unclean shutdown before!"); 1160#ifdef FTL_FORCEMOUNT
1161 DEBUGF("FTL: Forcing mount nevertheless...\n");
1162#else
1124 break; 1163 break;
1125#endif 1164#endif
1126 } 1165 }
1127 } 1166 }
1128 1167
1129 if (ftlcxtfound == 0) //return 1; 1168 if (ftlcxtfound == 0)
1130 panicf("FTL: Couldn't find FTL CXT page!"); 1169 {
1170 DEBUGF("FTL: Couldn't find FTL CXT page!\n");
1171 return 1;
1172 }
1131 1173
1132 uint32_t pagestoread = ftl_nand_type->userblocks >> 10; 1174 uint32_t pagestoread = ftl_nand_type->userblocks >> 10;
1133 if ((ftl_nand_type->userblocks & 0x1FF) != 0) pagestoread++; 1175 if ((ftl_nand_type->userblocks & 0x1FF) != 0) pagestoread++;
@@ -1136,8 +1178,10 @@ static uint32_t ftl_open(void)
1136 { 1178 {
1137 if ((ftl_vfl_read(ftl_cxt.ftl_map_pages[i], 1179 if ((ftl_vfl_read(ftl_cxt.ftl_map_pages[i],
1138 ftl_buffer, &ftl_sparebuffer[0], 1, 1) & 0x11F) != 0) 1180 ftl_buffer, &ftl_sparebuffer[0], 1, 1) & 0x11F) != 0)
1139 panicf("FTL: Failed to read block map page %u", (unsigned)i); 1181 {
1140 //return 1; 1182 DEBUGF("FTL: Failed to read block map page %u\n", (unsigned)i);
1183 return 1;
1184 }
1141 1185
1142 uint32_t toread = 2048; 1186 uint32_t toread = 2048;
1143 if (toread > (ftl_nand_type->userblocks << 1) - (i << 11)) 1187 if (toread > (ftl_nand_type->userblocks << 1) - (i << 11))
@@ -1154,8 +1198,10 @@ static uint32_t ftl_open(void)
1154 { 1198 {
1155 if ((ftl_vfl_read(ftl_cxt.ftl_erasectr_pages[i], 1199 if ((ftl_vfl_read(ftl_cxt.ftl_erasectr_pages[i],
1156 ftl_buffer, &ftl_sparebuffer[0], 1, 1) & 0x11F) != 0) 1200 ftl_buffer, &ftl_sparebuffer[0], 1, 1) & 0x11F) != 0)
1157 panicf("FTL: Failed to read erase counter page %u", (unsigned)i); 1201 {
1158 //return 1; 1202 DEBUGF("FTL: Failed to read erase counter page %u\n", (unsigned)i);
1203 return 1;
1204 }
1159 1205
1160 uint32_t toread = 2048; 1206 uint32_t toread = 2048;
1161 if (toread > ((ftl_nand_type->userblocks + 23) << 1) - (i << 11)) 1207 if (toread > ((ftl_nand_type->userblocks + 23) << 1) - (i << 11))
@@ -1175,6 +1221,42 @@ static uint32_t ftl_open(void)
1175 memset(ftl_erasectr_dirt, 0, 8); 1221 memset(ftl_erasectr_dirt, 0, 8);
1176#endif 1222#endif
1177 1223
1224#ifdef FTL_DEBUG
1225 uint32_t j, k;
1226 for (i = 0; i < ftl_banks; i++)
1227 {
1228 uint32_t badblocks = 0;
1229#ifndef FTL_READONLY
1230 for (j = 0; j < (*ftl_nand_type).blocks >> 3; j++)
1231 {
1232 uint8_t bbtentry = ftl_bbt[i][j];
1233 for (k = 0; k < 8; k++) if ((bbtentry & (1 << k)) == 0) badblocks++;
1234 }
1235 DEBUGF("FTL: BBT for bank %d: %d bad blocks\n", i, badblocks);
1236 badblocks = 0;
1237#endif
1238 for (j = 0; j < ftl_vfl_cxt[i].sparecount; j++)
1239 if (ftl_vfl_cxt[i].remaptable[j] == 0xFFFF) badblocks++;
1240 DEBUGF("FTL: VFL: Bank %d: %d of %d spare blocks are bad\n",
1241 i, badblocks, ftl_vfl_cxt[i].sparecount);
1242 DEBUGF("FTL: VFL: Bank %d: %d blocks remapped\n",
1243 i, ftl_vfl_cxt[i].spareused);
1244 DEBUGF("FTL: VFL: Bank %d: %d blocks scheduled for remapping\n",
1245 i, 0x334 - ftl_vfl_cxt[i].scheduledstart);
1246 }
1247#ifndef FTL_READONLY
1248 uint32_t min = 0xFFFFFFFF, max = 0, total = 0;
1249 for (i = 0; i < (*ftl_nand_type).userblocks + 23; i++)
1250 {
1251 if (ftl_erasectr[i] > max) max = ftl_erasectr[i];
1252 if (ftl_erasectr[i] < min) min = ftl_erasectr[i];
1253 total += ftl_erasectr[i];
1254 }
1255 DEBUGF("FTL: Erase counters: Minimum: %d, maximum %d, average: %d, total: %d\n",
1256 min, max, total / ((*ftl_nand_type).userblocks + 23), total);
1257#endif
1258#endif
1259
1178 return 0; 1260 return 0;
1179} 1261}
1180 1262
@@ -1201,9 +1283,15 @@ uint32_t ftl_read(uint32_t sector, uint32_t count, void* buffer)
1201 uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks; 1283 uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
1202 uint32_t error = 0; 1284 uint32_t error = 0;
1203 1285
1286#ifdef FTL_TRACE
1287 DEBUGF("FTL: Reading %d sectors starting at %d\n", count, sector);
1288#endif
1289
1204 if (sector + count > ftl_nand_type->userblocks * ppb) 1290 if (sector + count > ftl_nand_type->userblocks * ppb)
1291 {
1292 DEBUGF("FTL: Sector %d is out of range!\n", sector + count - 1);
1205 return 1; 1293 return 1;
1206 1294 }
1207 if (count == 0) return 0; 1295 if (count == 0) return 0;
1208 1296
1209 mutex_lock(&ftl_mtx); 1297 mutex_lock(&ftl_mtx);
@@ -1217,10 +1305,21 @@ uint32_t ftl_read(uint32_t sector, uint32_t count, void* buffer)
1217#ifndef FTL_READONLY 1305#ifndef FTL_READONLY
1218 struct ftl_log_type* logentry = ftl_get_log_entry(block); 1306 struct ftl_log_type* logentry = ftl_get_log_entry(block);
1219 if (logentry != (struct ftl_log_type*)0) 1307 if (logentry != (struct ftl_log_type*)0)
1308 {
1309#ifdef FTL_TRACE
1310 DEBUGF("FTL: Block %d has a log entry\n", block);
1311#endif
1220 if (logentry->scatteredvblock != 0xFFFF 1312 if (logentry->scatteredvblock != 0xFFFF
1221 && logentry->pageoffsets[page] != 0xFFFF) 1313 && logentry->pageoffsets[page] != 0xFFFF)
1314 {
1315#ifdef FTL_TRACE
1316 DEBUGF("FTL: Found page %d at block %d, page %d\n", page,
1317 (*logentry).scatteredvblock, (*logentry).pageoffsets[page]);
1318#endif
1222 abspage = logentry->scatteredvblock * ppb 1319 abspage = logentry->scatteredvblock * ppb
1223 + logentry->pageoffsets[page]; 1320 + logentry->pageoffsets[page];
1321 }
1322 }
1224#endif 1323#endif
1225 1324
1226#ifndef FTL_READONLY 1325#ifndef FTL_READONLY
@@ -1237,6 +1336,7 @@ uint32_t ftl_read(uint32_t sector, uint32_t count, void* buffer)
1237 memset(&((uint8_t*)buffer)[(i + j) << 11], 0, 0x800); 1336 memset(&((uint8_t*)buffer)[(i + j) << 11], 0, 0x800);
1238 else if ((ret & (0xd << (j << 2))) || ftl_sparebuffer[j].user.eccmark != 0xFF) 1337 else if ((ret & (0xd << (j << 2))) || ftl_sparebuffer[j].user.eccmark != 0xFF)
1239 { 1338 {
1339 DEBUGF("FTL: Error while reading sector %d!\n", (sector + i));
1240 error = 1; 1340 error = 1;
1241 memset(&((uint8_t*)buffer)[(i + j) << 11], 0, 0x800); 1341 memset(&((uint8_t*)buffer)[(i + j) << 11], 0, 0x800);
1242 } 1342 }
@@ -1249,6 +1349,7 @@ uint32_t ftl_read(uint32_t sector, uint32_t count, void* buffer)
1249 if (ret & 2) memset(&((uint8_t*)buffer)[i << 11], 0, 0x800); 1349 if (ret & 2) memset(&((uint8_t*)buffer)[i << 11], 0, 0x800);
1250 else if ((ret & 0x11D) != 0 || ftl_sparebuffer[0].user.eccmark != 0xFF) 1350 else if ((ret & 0x11D) != 0 || ftl_sparebuffer[0].user.eccmark != 0xFF)
1251 { 1351 {
1352 DEBUGF("FTL: Error while reading sector %d!\n", (sector + i));
1252 error = 1; 1353 error = 1;
1253 memset(&((uint8_t*)buffer)[i << 11], 0, 0x800); 1354 memset(&((uint8_t*)buffer)[i << 11], 0, 0x800);
1254 } 1355 }
@@ -1422,6 +1523,7 @@ static uint32_t ftl_next_ctrl_pool_page(void)
1422 if (newblock == 0xFFFFFFFF) return 1; 1523 if (newblock == 0xFFFFFFFF) return 1;
1423 ftl_cxt.ftlctrlblocks[i] = newblock; 1524 ftl_cxt.ftlctrlblocks[i] = newblock;
1424 ftl_cxt.ftlctrlpage = newblock * ppb; 1525 ftl_cxt.ftlctrlpage = newblock * ppb;
1526 DEBUGF("Starting new FTL control block at %d\n", ftl_cxt.ftlctrlpage);
1425 uint32_t pagestoread = (ftl_nand_type->userblocks + 23) >> 10; 1527 uint32_t pagestoread = (ftl_nand_type->userblocks + 23) >> 10;
1426 if (((ftl_nand_type->userblocks + 23) & 0x1FF) != 0) pagestoread++; 1528 if (((ftl_nand_type->userblocks + 23) & 0x1FF) != 0) pagestoread++;
1427 for (i = 0; i < pagestoread; i++) 1529 for (i = 0; i < pagestoread; i++)
@@ -1753,6 +1855,7 @@ static uint32_t ftl_commit_cxt(void)
1753 uint32_t mappages = (ftl_nand_type->userblocks + 0x3ff) >> 10; 1855 uint32_t mappages = (ftl_nand_type->userblocks + 0x3ff) >> 10;
1754 uint32_t ctrpages = (ftl_nand_type->userblocks + 23 + 0x3ff) >> 10; 1856 uint32_t ctrpages = (ftl_nand_type->userblocks + 23 + 0x3ff) >> 10;
1755 uint32_t endpage = ftl_cxt.ftlctrlpage + mappages + ctrpages + 1; 1857 uint32_t endpage = ftl_cxt.ftlctrlpage + mappages + ctrpages + 1;
1858 DEBUGF("FTL: Committing context\n");
1756 if (endpage >= (ftl_cxt.ftlctrlpage / ppb + 1) * ppb) 1859 if (endpage >= (ftl_cxt.ftlctrlpage / ppb + 1) * ppb)
1757 ftl_cxt.ftlctrlpage |= ppb - 1; 1860 ftl_cxt.ftlctrlpage |= ppb - 1;
1758 for (i = 0; i < ctrpages; i++) 1861 for (i = 0; i < ctrpages; i++)
@@ -1779,6 +1882,7 @@ static uint32_t ftl_commit_cxt(void)
1779 ftl_sparebuffer[0].meta.type = 0x43; 1882 ftl_sparebuffer[0].meta.type = 0x43;
1780 if (ftl_vfl_write(ftl_cxt.ftlctrlpage, 1, &ftl_cxt, &ftl_sparebuffer[0]) != 0) 1883 if (ftl_vfl_write(ftl_cxt.ftlctrlpage, 1, &ftl_cxt, &ftl_sparebuffer[0]) != 0)
1781 return 1; 1884 return 1;
1885 DEBUGF("FTL: Wrote context to page %d\n", ftl_cxt.ftlctrlpage);
1782 return 0; 1886 return 0;
1783} 1887}
1784#endif 1888#endif
@@ -1834,9 +1938,15 @@ uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer)
1834 uint32_t i, j, k; 1938 uint32_t i, j, k;
1835 uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks; 1939 uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks;
1836 1940
1941#ifdef FTL_TRACE
1942 DEBUGF("FTL: Writing %d sectors starting at %d\n", count, sector);
1943#endif
1944
1837 if (sector + count > ftl_nand_type->userblocks * ppb) 1945 if (sector + count > ftl_nand_type->userblocks * ppb)
1946 {
1947 DEBUGF("FTL: Sector %d is out of range!\n", sector + count - 1);
1838 return 1; 1948 return 1;
1839 1949 }
1840 if (count == 0) return 0; 1950 if (count == 0) return 0;
1841 1951
1842 mutex_lock(&ftl_mtx); 1952 mutex_lock(&ftl_mtx);
@@ -1845,6 +1955,7 @@ uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer)
1845 { 1955 {
1846 for (i = 0; i < 3; i++) 1956 for (i = 0; i < 3; i++)
1847 { 1957 {
1958 DEBUGF("FTL: Marking dirty, try %d\n", i);
1848 if (ftl_next_ctrl_pool_page() != 0) 1959 if (ftl_next_ctrl_pool_page() != 0)
1849 { 1960 {
1850 mutex_unlock(&ftl_mtx); 1961 mutex_unlock(&ftl_mtx);
@@ -1863,6 +1974,7 @@ uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer)
1863 mutex_unlock(&ftl_mtx); 1974 mutex_unlock(&ftl_mtx);
1864 return 1; 1975 return 1;
1865 } 1976 }
1977 DEBUGF("FTL: Wrote dirty mark to %d\n", ftl_cxt.ftlctrlpage);
1866 ftl_cxt.clean_flag = 0; 1978 ftl_cxt.clean_flag = 0;
1867 } 1979 }
1868 1980
@@ -1879,10 +1991,16 @@ uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer)
1879 } 1991 }
1880 if (page == 0 && count - i >= ppb) 1992 if (page == 0 && count - i >= ppb)
1881 { 1993 {
1994#ifdef FTL_TRACE
1995 DEBUGF("FTL: Going to write a full hyperblock in one shot\n");
1996#endif
1882 uint32_t vblock = logentry->scatteredvblock; 1997 uint32_t vblock = logentry->scatteredvblock;
1883 logentry->scatteredvblock = 0xFFFF; 1998 logentry->scatteredvblock = 0xFFFF;
1884 if (logentry->pagesused != 0) 1999 if (logentry->pagesused != 0)
1885 { 2000 {
2001#ifdef FTL_TRACE
2002 DEBUGF("FTL: Scattered block had some pages already used, committing\n");
2003#endif
1886 ftl_release_pool_block(vblock); 2004 ftl_release_pool_block(vblock);
1887 vblock = ftl_allocate_pool_block(); 2005 vblock = ftl_allocate_pool_block();
1888 if (vblock == 0xFFFFFFFF) 2006 if (vblock == 0xFFFFFFFF)
@@ -1922,6 +2040,9 @@ uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer)
1922 { 2040 {
1923 if (logentry->pagesused == ppb) 2041 if (logentry->pagesused == ppb)
1924 { 2042 {
2043#ifdef FTL_TRACE
2044 DEBUGF("FTL: Scattered block is full, committing\n");
2045#endif
1925 ftl_remove_scattered_block(logentry); 2046 ftl_remove_scattered_block(logentry);
1926 logentry = ftl_allocate_log_entry(block); 2047 logentry = ftl_allocate_log_entry(block);
1927 if (logentry == (struct ftl_log_type*)0) 2048 if (logentry == (struct ftl_log_type*)0)
@@ -1998,6 +2119,10 @@ uint32_t ftl_sync(void)
1998 if (ftl_cxt.clean_flag == 1) return 0; 2119 if (ftl_cxt.clean_flag == 1) return 0;
1999 2120
2000 mutex_lock(&ftl_mtx); 2121 mutex_lock(&ftl_mtx);
2122
2123#ifdef FTL_TRACE
2124 DEBUGF("FTL: Syncing\n");
2125#endif
2001 2126
2002 if (ftl_cxt.swapcounter >= 20) 2127 if (ftl_cxt.swapcounter >= 20)
2003 for (i = 0; i < 4; i++) 2128 for (i = 0; i < 4; i++)
@@ -2050,7 +2175,6 @@ uint32_t ftl_init(void)
2050 ftl_nand_type = nand_get_device_type(0); 2175 ftl_nand_type = nand_get_device_type(0);
2051 foundsignature = 0; 2176 foundsignature = 0;
2052 blockwiped = 1; 2177 blockwiped = 1;
2053 mutex_unlock(&ftl_mtx);
2054 for (i = 0; i < ftl_nand_type->pagesperblock; i++) 2178 for (i = 0; i < ftl_nand_type->pagesperblock; i++)
2055 { 2179 {
2056 result = nand_read_page(0, i, ftl_buffer, (uint32_t*)0, 1, 1); 2180 result = nand_read_page(0, i, ftl_buffer, (uint32_t*)0, 1, 1);
@@ -2070,34 +2194,19 @@ uint32_t ftl_init(void)
2070 skip = 0; 2194 skip = 0;
2071 if (founddevinfo == 0) 2195 if (founddevinfo == 0)
2072 { 2196 {
2073 mutex_unlock(&ftl_mtx); 2197 DEBUGF("FTL: No DEVICEINFO found!\n");
2074 panicf("FTL: No DEVICEINFO found!"); 2198 return 1;
2075 //return 1;
2076 } 2199 }
2077 if (foundsignature != 0 && (result & 0x11F) != 0) 2200 if (foundsignature != 0 && (result & 0x11F) != 0)
2078 { 2201 {
2079 mutex_unlock(&ftl_mtx); 2202 DEBUGF("FTL: Problem with the signature!\n");
2080 panicf("FTL: Problem with the signature!"); 2203 return 1;
2081 //return 1;
2082 } 2204 }
2083 if (ftl_vfl_open() == 0) 2205 if (ftl_vfl_open() == 0)
2084 if (ftl_open() == 0) 2206 if (ftl_open() == 0)
2085 {
2086 mutex_unlock(&ftl_mtx);
2087 return 0; 2207 return 0;
2088 }
2089 2208
2090 panicf("FTL: Initialization failed!"); 2209 DEBUGF("FTL: Initialization failed!\n");
2091 2210
2092/* Something went terribly wrong. We may want to allow the user to erase
2093 block zero in that condition, to make norboot reinitialize the FTL.
2094 (However there is curently no point in this, as iLoader would already
2095 fail if this would be the case.)
2096
2097 nand_block_erase(0, 0);
2098*/
2099
2100
2101 mutex_unlock(&ftl_mtx);
2102 return 1; 2211 return 1;
2103} 2212}