Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+157 -48
+157 -48
firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c
··· 29 29 #include "system.h" 30 30 #include "kernel.h" 31 31 #include "panic.h" 32 + #include "debug.h" 32 33 33 34 34 35 ··· 183 184 184 185 /* Keeps the state of the bank's VFL, both on flash and in memory. 185 186 There is one of these per bank. */ 186 - typedef struct ftl_vfl_cxt_type 187 + struct ftl_vfl_cxt_type 187 188 { 188 189 189 190 /* Cross-bank update sequence number, incremented on every VFL ··· 252 253 /* Second checksum (XOR), there is a bug in whimory regarding this. */ 253 254 uint32_t checksum2; 254 255 255 - } __attribute__((packed)) FTLVFLCxtType; 256 + } __attribute__((packed)); 256 257 257 258 258 259 /* Layout of the spare bytes of each page on the flash */ ··· 513 514 /* The following line is pretty obviously a bug in Whimory, 514 515 but we do it the same way for compatibility. */ 515 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 518 return 1; 518 519 } 519 520 ··· 577 578 retries until it works or all available pages have been tried */ 578 579 static uint32_t ftl_vfl_commit_cxt(uint32_t bank) 579 580 { 581 + DEBUGF("FTL: VFL: Committing context on bank %d\n", bank); 580 582 if (ftl_vfl_cxt[bank].nextcxtpage + 8 <= ftl_nand_type->pagesperblock) 581 583 if (ftl_vfl_store_cxt(bank) == 0) return 0; 582 584 uint32_t current = ftl_vfl_cxt[bank].activecxtblock; ··· 595 597 ftl_vfl_cxt[bank].nextcxtpage = 0; 596 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 601 return 1; 600 602 } 601 603 #endif ··· 678 680 uint32_t spareused = ftl_vfl_cxt[bank].spareused; 679 681 for (spareindex = 0; spareindex < spareused; spareindex++) 680 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 686 return ftl_vfl_cxt[bank].firstspare + spareindex; 687 + } 682 688 return block; 683 689 } 684 690 ··· 816 822 static uint32_t ftl_vfl_read(uint32_t vpage, void* buffer, void* sparebuffer, 817 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 829 uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks; 820 830 uint32_t syshyperblocks = ftl_nand_type->blocks 821 831 - ftl_nand_type->userblocks - 0x17; 822 832 uint32_t abspage = vpage + ppb * syshyperblocks; 823 833 if (abspage >= ftl_nand_type->blocks * ppb || abspage < ppb) 824 - panicf("FTL: Trying to read out-of-bounds vPage %u", (unsigned)vpage); 825 - //return 4; 834 + { 835 + DEBUGF("FTL: Trying to read out-of-bounds vPage %u\n", (unsigned)vpage); 836 + return 4; 837 + } 826 838 827 839 uint32_t bank = abspage % ftl_banks; 828 840 uint32_t block = abspage / (ftl_nand_type->pagesperblock * ftl_banks); ··· 842 854 (void)remaponfail; 843 855 #else 844 856 if (remaponfail == 1 &&(ret & 0x11D) != 0 && (ret & 2) == 0) 857 + { 858 + DEBUGF("FTL: VFL: Scheduling vBlock %d for remapping!\n", block); 845 859 ftl_vfl_schedule_block_for_remap(bank, block); 860 + } 846 861 #endif 847 862 return ret; 848 863 } ··· 855 870 static uint32_t ftl_vfl_read_fast(uint32_t vpage, void* buffer, void* sparebuffer, 856 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 877 uint32_t i, rc = 0; 859 878 uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks; 860 879 uint32_t syshyperblocks = ftl_nand_type->blocks 861 880 - ftl_nand_type->userblocks - 0x17; 862 881 uint32_t abspage = vpage + ppb * syshyperblocks; 863 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); 865 - //return 4; 883 + { 884 + DEBUGF("FTL: Trying to read out-of-bounds vPage %u\n", (unsigned)vpage); 885 + return 4; 886 + } 866 887 867 888 uint32_t bank = abspage % ftl_banks; 868 889 uint32_t block = abspage / (ftl_nand_type->pagesperblock * ftl_banks); ··· 926 947 void* buffer, void* sparebuffer) 927 948 { 928 949 uint32_t i, j; 950 + #ifdef VFL_TRACE 951 + DEBUGF("FTL: VFL: Writing page %d\n", vpage); 952 + #endif 953 + 929 954 uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks; 930 955 uint32_t syshyperblocks = ftl_nand_type->blocks 931 956 - ftl_nand_type->userblocks - 0x17; 932 957 uint32_t abspage = vpage + ppb * syshyperblocks; 933 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 961 (unsigned)vpage); 936 - //return 4; 962 + return 4; 963 + } 937 964 938 965 uint32_t bank[5]; 939 966 uint32_t block[5]; ··· 997 1024 { 998 1025 uint32_t i, j, k; 999 1026 uint32_t minusn, vflcxtidx, last; 1000 - FTLVFLCxtType* cxt; 1027 + struct ftl_vfl_cxt_type* cxt; 1001 1028 uint16_t vflcxtblock[4]; 1002 1029 #ifndef FTL_READONLY 1003 1030 ftl_vfl_usn = 0; ··· 1042 1069 minusn = ftl_sparebuffer[0].meta.usn; 1043 1070 vflcxtidx = k; 1044 1071 } 1045 - if (vflcxtidx == 4) //return 1; 1046 - panicf("FTL: No VFL CXT block found on bank %u!", 1072 + if (vflcxtidx == 4) 1073 + { 1074 + DEBUGF("FTL: No VFL CXT block found on bank %u!\n", 1047 1075 (unsigned)i); 1076 + return 1; 1077 + } 1048 1078 last = 0; 1049 1079 uint32_t max = ftl_nand_type->pagesperblock; 1050 1080 for (k = 8; k < max; k += 8) ··· 1070 1100 break; 1071 1101 } 1072 1102 } 1073 - else //return 1; 1074 - panicf("FTL: Couldn't load bank %u lowlevel BBT!", (unsigned)i); 1103 + else 1104 + { 1105 + DEBUGF("FTL: Couldn't load bank %u lowlevel BBT!\n", (unsigned)i); 1106 + return 1; 1107 + } 1075 1108 cxt = ftl_vfl_get_newest_cxt(); 1076 1109 for (i = 0; i < ftl_banks; i++) 1077 1110 memcpy(ftl_vfl_cxt[i].ftlctrlblocks, cxt->ftlctrlblocks, 6); ··· 1101 1134 ftlcxtblock = cxt->ftlctrlblocks[i]; 1102 1135 } 1103 1136 1104 - if (ftlcxtblock == 0xffffffff) //return 1; 1105 - panicf("FTL: Couldn't find readable FTL CXT block!"); 1137 + if (ftlcxtblock == 0xffffffff) 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 1144 uint32_t ftlcxtfound = 0; 1108 1145 for (i = ftl_nand_type->pagesperblock * ftl_banks - 1; i > 0; i--) 1109 1146 { ··· 1119 1156 else 1120 1157 { 1121 1158 /* This will trip if there was an unclean unmount before. */ 1122 - #ifndef FTL_FORCEMOUNT 1123 - panicf("FTL: Unclean shutdown before!"); 1159 + DEBUGF("FTL: Unclean shutdown before!\n"); 1160 + #ifdef FTL_FORCEMOUNT 1161 + DEBUGF("FTL: Forcing mount nevertheless...\n"); 1162 + #else 1124 1163 break; 1125 1164 #endif 1126 1165 } 1127 1166 } 1128 1167 1129 - if (ftlcxtfound == 0) //return 1; 1130 - panicf("FTL: Couldn't find FTL CXT page!"); 1168 + if (ftlcxtfound == 0) 1169 + { 1170 + DEBUGF("FTL: Couldn't find FTL CXT page!\n"); 1171 + return 1; 1172 + } 1131 1173 1132 1174 uint32_t pagestoread = ftl_nand_type->userblocks >> 10; 1133 1175 if ((ftl_nand_type->userblocks & 0x1FF) != 0) pagestoread++; ··· 1136 1178 { 1137 1179 if ((ftl_vfl_read(ftl_cxt.ftl_map_pages[i], 1138 1180 ftl_buffer, &ftl_sparebuffer[0], 1, 1) & 0x11F) != 0) 1139 - panicf("FTL: Failed to read block map page %u", (unsigned)i); 1140 - //return 1; 1181 + { 1182 + DEBUGF("FTL: Failed to read block map page %u\n", (unsigned)i); 1183 + return 1; 1184 + } 1141 1185 1142 1186 uint32_t toread = 2048; 1143 1187 if (toread > (ftl_nand_type->userblocks << 1) - (i << 11)) ··· 1154 1198 { 1155 1199 if ((ftl_vfl_read(ftl_cxt.ftl_erasectr_pages[i], 1156 1200 ftl_buffer, &ftl_sparebuffer[0], 1, 1) & 0x11F) != 0) 1157 - panicf("FTL: Failed to read erase counter page %u", (unsigned)i); 1158 - //return 1; 1201 + { 1202 + DEBUGF("FTL: Failed to read erase counter page %u\n", (unsigned)i); 1203 + return 1; 1204 + } 1159 1205 1160 1206 uint32_t toread = 2048; 1161 1207 if (toread > ((ftl_nand_type->userblocks + 23) << 1) - (i << 11)) ··· 1175 1221 memset(ftl_erasectr_dirt, 0, 8); 1176 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 1260 return 0; 1179 1261 } 1180 1262 ··· 1201 1283 uint32_t ppb = ftl_nand_type->pagesperblock * ftl_banks; 1202 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 1290 if (sector + count > ftl_nand_type->userblocks * ppb) 1291 + { 1292 + DEBUGF("FTL: Sector %d is out of range!\n", sector + count - 1); 1205 1293 return 1; 1206 - 1294 + } 1207 1295 if (count == 0) return 0; 1208 1296 1209 1297 mutex_lock(&ftl_mtx); ··· 1217 1305 #ifndef FTL_READONLY 1218 1306 struct ftl_log_type* logentry = ftl_get_log_entry(block); 1219 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 1312 if (logentry->scatteredvblock != 0xFFFF 1221 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 1319 abspage = logentry->scatteredvblock * ppb 1223 1320 + logentry->pageoffsets[page]; 1321 + } 1322 + } 1224 1323 #endif 1225 1324 1226 1325 #ifndef FTL_READONLY ··· 1237 1336 memset(&((uint8_t*)buffer)[(i + j) << 11], 0, 0x800); 1238 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 1340 error = 1; 1241 1341 memset(&((uint8_t*)buffer)[(i + j) << 11], 0, 0x800); 1242 1342 } ··· 1249 1349 if (ret & 2) memset(&((uint8_t*)buffer)[i << 11], 0, 0x800); 1250 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 1353 error = 1; 1253 1354 memset(&((uint8_t*)buffer)[i << 11], 0, 0x800); 1254 1355 } ··· 1422 1523 if (newblock == 0xFFFFFFFF) return 1; 1423 1524 ftl_cxt.ftlctrlblocks[i] = newblock; 1424 1525 ftl_cxt.ftlctrlpage = newblock * ppb; 1526 + DEBUGF("Starting new FTL control block at %d\n", ftl_cxt.ftlctrlpage); 1425 1527 uint32_t pagestoread = (ftl_nand_type->userblocks + 23) >> 10; 1426 1528 if (((ftl_nand_type->userblocks + 23) & 0x1FF) != 0) pagestoread++; 1427 1529 for (i = 0; i < pagestoread; i++) ··· 1753 1855 uint32_t mappages = (ftl_nand_type->userblocks + 0x3ff) >> 10; 1754 1856 uint32_t ctrpages = (ftl_nand_type->userblocks + 23 + 0x3ff) >> 10; 1755 1857 uint32_t endpage = ftl_cxt.ftlctrlpage + mappages + ctrpages + 1; 1858 + DEBUGF("FTL: Committing context\n"); 1756 1859 if (endpage >= (ftl_cxt.ftlctrlpage / ppb + 1) * ppb) 1757 1860 ftl_cxt.ftlctrlpage |= ppb - 1; 1758 1861 for (i = 0; i < ctrpages; i++) ··· 1779 1882 ftl_sparebuffer[0].meta.type = 0x43; 1780 1883 if (ftl_vfl_write(ftl_cxt.ftlctrlpage, 1, &ftl_cxt, &ftl_sparebuffer[0]) != 0) 1781 1884 return 1; 1885 + DEBUGF("FTL: Wrote context to page %d\n", ftl_cxt.ftlctrlpage); 1782 1886 return 0; 1783 1887 } 1784 1888 #endif ··· 1834 1938 uint32_t i, j, k; 1835 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 1945 if (sector + count > ftl_nand_type->userblocks * ppb) 1946 + { 1947 + DEBUGF("FTL: Sector %d is out of range!\n", sector + count - 1); 1838 1948 return 1; 1839 - 1949 + } 1840 1950 if (count == 0) return 0; 1841 1951 1842 1952 mutex_lock(&ftl_mtx); ··· 1845 1955 { 1846 1956 for (i = 0; i < 3; i++) 1847 1957 { 1958 + DEBUGF("FTL: Marking dirty, try %d\n", i); 1848 1959 if (ftl_next_ctrl_pool_page() != 0) 1849 1960 { 1850 1961 mutex_unlock(&ftl_mtx); ··· 1863 1974 mutex_unlock(&ftl_mtx); 1864 1975 return 1; 1865 1976 } 1977 + DEBUGF("FTL: Wrote dirty mark to %d\n", ftl_cxt.ftlctrlpage); 1866 1978 ftl_cxt.clean_flag = 0; 1867 1979 } 1868 1980 ··· 1879 1991 } 1880 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 1997 uint32_t vblock = logentry->scatteredvblock; 1883 1998 logentry->scatteredvblock = 0xFFFF; 1884 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 2004 ftl_release_pool_block(vblock); 1887 2005 vblock = ftl_allocate_pool_block(); 1888 2006 if (vblock == 0xFFFFFFFF) ··· 1922 2040 { 1923 2041 if (logentry->pagesused == ppb) 1924 2042 { 2043 + #ifdef FTL_TRACE 2044 + DEBUGF("FTL: Scattered block is full, committing\n"); 2045 + #endif 1925 2046 ftl_remove_scattered_block(logentry); 1926 2047 logentry = ftl_allocate_log_entry(block); 1927 2048 if (logentry == (struct ftl_log_type*)0) ··· 1998 2119 if (ftl_cxt.clean_flag == 1) return 0; 1999 2120 2000 2121 mutex_lock(&ftl_mtx); 2122 + 2123 + #ifdef FTL_TRACE 2124 + DEBUGF("FTL: Syncing\n"); 2125 + #endif 2001 2126 2002 2127 if (ftl_cxt.swapcounter >= 20) 2003 2128 for (i = 0; i < 4; i++) ··· 2050 2175 ftl_nand_type = nand_get_device_type(0); 2051 2176 foundsignature = 0; 2052 2177 blockwiped = 1; 2053 - mutex_unlock(&ftl_mtx); 2054 2178 for (i = 0; i < ftl_nand_type->pagesperblock; i++) 2055 2179 { 2056 2180 result = nand_read_page(0, i, ftl_buffer, (uint32_t*)0, 1, 1); ··· 2070 2194 skip = 0; 2071 2195 if (founddevinfo == 0) 2072 2196 { 2073 - mutex_unlock(&ftl_mtx); 2074 - panicf("FTL: No DEVICEINFO found!"); 2075 - //return 1; 2197 + DEBUGF("FTL: No DEVICEINFO found!\n"); 2198 + return 1; 2076 2199 } 2077 2200 if (foundsignature != 0 && (result & 0x11F) != 0) 2078 2201 { 2079 - mutex_unlock(&ftl_mtx); 2080 - panicf("FTL: Problem with the signature!"); 2081 - //return 1; 2202 + DEBUGF("FTL: Problem with the signature!\n"); 2203 + return 1; 2082 2204 } 2083 2205 if (ftl_vfl_open() == 0) 2084 2206 if (ftl_open() == 0) 2085 - { 2086 - mutex_unlock(&ftl_mtx); 2087 2207 return 0; 2088 - } 2089 2208 2090 - panicf("FTL: Initialization failed!"); 2091 - 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 - 2209 + DEBUGF("FTL: Initialization failed!\n"); 2100 2210 2101 - mutex_unlock(&ftl_mtx); 2102 2211 return 1; 2103 2212 }