diff options
-rw-r--r-- | firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c index d6b4f1aedc..e3bdca6b30 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c | |||
@@ -334,7 +334,7 @@ union ftl_spare_data_type | |||
334 | }; | 334 | }; |
335 | 335 | ||
336 | 336 | ||
337 | // Keeps track of troublesome blocks, only in memory, lost on unmount. */ | 337 | /* Keeps track of troublesome blocks, only in memory, lost on unmount. */ |
338 | struct ftl_trouble_type | 338 | struct ftl_trouble_type |
339 | { | 339 | { |
340 | 340 | ||
@@ -1161,24 +1161,27 @@ uint32_t ftl_erase_block(uint32_t block) | |||
1161 | uint32_t ftl_allocate_pool_block(void) | 1161 | uint32_t ftl_allocate_pool_block(void) |
1162 | { | 1162 | { |
1163 | uint32_t i; | 1163 | uint32_t i; |
1164 | uint32_t erasectr = 0xFFFFFFFF, bestidx = 0, block; | 1164 | uint32_t erasectr = 0xFFFFFFFF, bestidx = 0xFFFFFFFF, block; |
1165 | for (i = 0; i < ftl_cxt.freecount; i++) | 1165 | for (i = 0; i < ftl_cxt.freecount; i++) |
1166 | { | 1166 | { |
1167 | uint32_t idx = ftl_cxt.nextfreeidx + i; | 1167 | uint32_t idx = ftl_cxt.nextfreeidx + i; |
1168 | if (idx >= 0x14) idx -= 0x14; | 1168 | if (idx >= 0x14) idx -= 0x14; |
1169 | if (!ftl_cxt.blockpool[idx]) continue; | ||
1169 | if (ftl_erasectr[ftl_cxt.blockpool[idx]] < erasectr) | 1170 | if (ftl_erasectr[ftl_cxt.blockpool[idx]] < erasectr) |
1170 | { | 1171 | { |
1171 | erasectr = ftl_erasectr[ftl_cxt.blockpool[idx]]; | 1172 | erasectr = ftl_erasectr[ftl_cxt.blockpool[idx]]; |
1172 | bestidx = idx; | 1173 | bestidx = idx; |
1173 | } | 1174 | } |
1174 | } | 1175 | } |
1176 | if (bestidx == 0xFFFFFFFF) panicf("Out of pool blocks!"); | ||
1175 | block = ftl_cxt.blockpool[bestidx]; | 1177 | block = ftl_cxt.blockpool[bestidx]; |
1176 | if (bestidx != ftl_cxt.nextfreeidx) | 1178 | if (bestidx != ftl_cxt.nextfreeidx) |
1177 | { | 1179 | { |
1178 | ftl_cxt.blockpool[bestidx] = ftl_cxt.blockpool[ftl_cxt.nextfreeidx]; | 1180 | ftl_cxt.blockpool[bestidx] = ftl_cxt.blockpool[ftl_cxt.nextfreeidx]; |
1179 | ftl_cxt.blockpool[ftl_cxt.nextfreeidx] = block; | 1181 | ftl_cxt.blockpool[ftl_cxt.nextfreeidx] = block; |
1180 | } | 1182 | } |
1181 | if (block > (*ftl_nand_type).userblocks) return 0; | 1183 | if (block > (uint32_t)(*ftl_nand_type).userblocks + 0x17) |
1184 | panicf("FTL: Bad block number in pool: %u", (unsigned)block); | ||
1182 | if (ftl_erase_block(block) != 0) return 0; | 1185 | if (ftl_erase_block(block) != 0) return 0; |
1183 | if (++ftl_cxt.nextfreeidx == 0x14) ftl_cxt.nextfreeidx = 0; | 1186 | if (++ftl_cxt.nextfreeidx == 0x14) ftl_cxt.nextfreeidx = 0; |
1184 | ftl_cxt.freecount--; | 1187 | ftl_cxt.freecount--; |
@@ -1191,7 +1194,9 @@ uint32_t ftl_allocate_pool_block(void) | |||
1191 | /* Releases a vBlock back into the pool */ | 1194 | /* Releases a vBlock back into the pool */ |
1192 | void ftl_release_pool_block(uint32_t block) | 1195 | void ftl_release_pool_block(uint32_t block) |
1193 | { | 1196 | { |
1194 | if (block >= (uint32_t)(*ftl_nand_type).userblocks + 0x17) return; | 1197 | if (!block) panicf("FTL: Tried to put block 0 into the pool!"); |
1198 | if (block >= (uint32_t)(*ftl_nand_type).userblocks + 0x17) | ||
1199 | panicf("FTL: Tried to release block %u", (unsigned)block); | ||
1195 | uint32_t idx = ftl_cxt.nextfreeidx + ftl_cxt.freecount++; | 1200 | uint32_t idx = ftl_cxt.nextfreeidx + ftl_cxt.freecount++; |
1196 | if (idx >= 0x14) idx -= 0x14; | 1201 | if (idx >= 0x14) idx -= 0x14; |
1197 | ftl_cxt.blockpool[idx] = block; | 1202 | ftl_cxt.blockpool[idx] = block; |
@@ -1370,10 +1375,11 @@ uint32_t ftl_compact_scattered(struct ftl_log_type* entry) | |||
1370 | for (i = 0; i < 4; i++) | 1375 | for (i = 0; i < 4; i++) |
1371 | { | 1376 | { |
1372 | uint32_t block = ftl_allocate_pool_block(); | 1377 | uint32_t block = ftl_allocate_pool_block(); |
1378 | if (block == 0) return 1; | ||
1373 | (*entry).pagesused = 0; | 1379 | (*entry).pagesused = 0; |
1374 | (*entry).pagescurrent = 0; | 1380 | (*entry).pagescurrent = 0; |
1375 | (*entry).issequential = 1; | 1381 | (*entry).issequential = 1; |
1376 | if (block == 0) return 1; | 1382 | (*entry).scatteredvblock = block; |
1377 | error = 0; | 1383 | error = 0; |
1378 | for (j = 0; j < ppb; j++) | 1384 | for (j = 0; j < ppb; j++) |
1379 | if ((*entry).pageoffsets[j] != 0xFFFF) | 1385 | if ((*entry).pageoffsets[j] != 0xFFFF) |
@@ -1430,7 +1436,7 @@ uint32_t ftl_commit_scattered(struct ftl_log_type* entry) | |||
1430 | /* Fills the rest of a scattered page block that was actually written | 1436 | /* Fills the rest of a scattered page block that was actually written |
1431 | sequentially until now, in order to be able to save a block erase by | 1437 | sequentially until now, in order to be able to save a block erase by |
1432 | committing it without needing to copy it again. | 1438 | committing it without needing to copy it again. |
1433 | If this fails for whatever reason, it will be committed the usual way. */ | 1439 | If this fails for whichever reason, it will be committed the usual way. */ |
1434 | uint32_t ftl_commit_sequential(struct ftl_log_type* entry) | 1440 | uint32_t ftl_commit_sequential(struct ftl_log_type* entry) |
1435 | { | 1441 | { |
1436 | uint32_t ppb = (*ftl_nand_type).pagesperblock * ftl_banks; | 1442 | uint32_t ppb = (*ftl_nand_type).pagesperblock * ftl_banks; |
@@ -1534,7 +1540,7 @@ struct ftl_log_type* ftl_allocate_log_entry(uint32_t block) | |||
1534 | 1540 | ||
1535 | if (entry == (struct ftl_log_type*)0) | 1541 | if (entry == (struct ftl_log_type*)0) |
1536 | { | 1542 | { |
1537 | if (ftl_cxt.freecount == 3) | 1543 | while (ftl_cxt.freecount <= 3) |
1538 | if (ftl_remove_scattered_block((struct ftl_log_type*)0) != 0) | 1544 | if (ftl_remove_scattered_block((struct ftl_log_type*)0) != 0) |
1539 | return (struct ftl_log_type*)0; | 1545 | return (struct ftl_log_type*)0; |
1540 | entry = ftl_log; | 1546 | entry = ftl_log; |
@@ -1547,8 +1553,8 @@ struct ftl_log_type* ftl_allocate_log_entry(uint32_t block) | |||
1547 | } | 1553 | } |
1548 | } | 1554 | } |
1549 | 1555 | ||
1550 | (*entry).logicalvblock = block; | ||
1551 | ftl_init_log_entry(entry); | 1556 | ftl_init_log_entry(entry); |
1557 | (*entry).logicalvblock = block; | ||
1552 | (*entry).usn = ftl_cxt.nextblockusn - 1; | 1558 | (*entry).usn = ftl_cxt.nextblockusn - 1; |
1553 | 1559 | ||
1554 | return entry; | 1560 | return entry; |
@@ -1815,8 +1821,8 @@ uint32_t ftl_sync(void) | |||
1815 | #endif | 1821 | #endif |
1816 | 1822 | ||
1817 | 1823 | ||
1818 | /* Initializes and mounts the FTL. As long as nothing was written, | 1824 | /* Initializes and mounts the FTL. |
1819 | you won't need to unmount it. | 1825 | As long as nothing was written, you won't need to unmount it. |
1820 | Before shutting down after writing something, call ftl_sync(), | 1826 | Before shutting down after writing something, call ftl_sync(), |
1821 | which will just do nothing if everything was already clean. */ | 1827 | which will just do nothing if everything was already clean. */ |
1822 | uint32_t ftl_init(void) | 1828 | uint32_t ftl_init(void) |