summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sparmann <theseven@rockbox.org>2009-10-20 20:20:39 +0000
committerMichael Sparmann <theseven@rockbox.org>2009-10-20 20:20:39 +0000
commit1668cfa3dded5fcece8301a224402a709d956fec (patch)
tree95c963e207004e896f5d5a85f9451cb63a77a379
parentad29c35d7b8b8bc9acc7da857bd642b1fdbf3a4c (diff)
downloadrockbox-1668cfa3dded5fcece8301a224402a709d956fec.tar.gz
rockbox-1668cfa3dded5fcece8301a224402a709d956fec.zip
Fixed a bunch of iPod Nano 2G FTL bugs.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23296 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c26
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. */
338struct ftl_trouble_type 338struct ftl_trouble_type
339{ 339{
340 340
@@ -1161,24 +1161,27 @@ uint32_t ftl_erase_block(uint32_t block)
1161uint32_t ftl_allocate_pool_block(void) 1161uint32_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 */
1192void ftl_release_pool_block(uint32_t block) 1195void 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. */
1434uint32_t ftl_commit_sequential(struct ftl_log_type* entry) 1440uint32_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. */
1822uint32_t ftl_init(void) 1828uint32_t ftl_init(void)