aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nftlmount.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/mtd/nftlmount.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/mtd/nftlmount.c')
-rw-r--r--drivers/mtd/nftlmount.c39
1 files changed, 19 insertions, 20 deletions
diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
index 51b9d6af307..e3cd1ffad2f 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -32,7 +32,7 @@
32 32
33/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the 33/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
34 * various device information of the NFTL partition and Bad Unit Table. Update 34 * various device information of the NFTL partition and Bad Unit Table. Update
35 * the ReplUnitTable[] table according to the Bad Unit Table. ReplUnitTable[] 35 * the ReplUnitTable[] table accroding to the Bad Unit Table. ReplUnitTable[]
36 * is used for management of Erase Unit in other routines in nftl.c and nftlmount.c 36 * is used for management of Erase Unit in other routines in nftl.c and nftlmount.c
37 */ 37 */
38static int find_boot_record(struct NFTLrecord *nftl) 38static int find_boot_record(struct NFTLrecord *nftl)
@@ -63,8 +63,8 @@ static int find_boot_record(struct NFTLrecord *nftl)
63 63
64 /* Check for ANAND header first. Then can whinge if it's found but later 64 /* Check for ANAND header first. Then can whinge if it's found but later
65 checks fail */ 65 checks fail */
66 ret = mtd_read(mtd, block * nftl->EraseSize, SECTORSIZE, 66 ret = mtd->read(mtd, block * nftl->EraseSize, SECTORSIZE,
67 &retlen, buf); 67 &retlen, buf);
68 /* We ignore ret in case the ECC of the MediaHeader is invalid 68 /* We ignore ret in case the ECC of the MediaHeader is invalid
69 (which is apparently acceptable) */ 69 (which is apparently acceptable) */
70 if (retlen != SECTORSIZE) { 70 if (retlen != SECTORSIZE) {
@@ -242,8 +242,7 @@ The new DiskOnChip driver already scanned the bad block table. Just query it.
242 if (buf[i & (SECTORSIZE - 1)] != 0xff) 242 if (buf[i & (SECTORSIZE - 1)] != 0xff)
243 nftl->ReplUnitTable[i] = BLOCK_RESERVED; 243 nftl->ReplUnitTable[i] = BLOCK_RESERVED;
244#endif 244#endif
245 if (mtd_block_isbad(nftl->mbd.mtd, 245 if (nftl->mbd.mtd->block_isbad(nftl->mbd.mtd, i * nftl->EraseSize))
246 i * nftl->EraseSize))
247 nftl->ReplUnitTable[i] = BLOCK_RESERVED; 246 nftl->ReplUnitTable[i] = BLOCK_RESERVED;
248 } 247 }
249 248
@@ -275,7 +274,7 @@ static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int
275 int i; 274 int i;
276 275
277 for (i = 0; i < len; i += SECTORSIZE) { 276 for (i = 0; i < len; i += SECTORSIZE) {
278 if (mtd_read(mtd, address, SECTORSIZE, &retlen, buf)) 277 if (mtd->read(mtd, address, SECTORSIZE, &retlen, buf))
279 return -1; 278 return -1;
280 if (memcmpb(buf, 0xff, SECTORSIZE) != 0) 279 if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
281 return -1; 280 return -1;
@@ -298,7 +297,7 @@ static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int
298 * 297 *
299 * Return: 0 when succeed, -1 on error. 298 * Return: 0 when succeed, -1 on error.
300 * 299 *
301 * ToDo: 1. Is it necessary to check_free_sector after erasing ?? 300 * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
302 */ 301 */
303int NFTL_formatblock(struct NFTLrecord *nftl, int block) 302int NFTL_formatblock(struct NFTLrecord *nftl, int block)
304{ 303{
@@ -327,7 +326,7 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
327 instr->mtd = nftl->mbd.mtd; 326 instr->mtd = nftl->mbd.mtd;
328 instr->addr = block * nftl->EraseSize; 327 instr->addr = block * nftl->EraseSize;
329 instr->len = nftl->EraseSize; 328 instr->len = nftl->EraseSize;
330 mtd_erase(mtd, instr); 329 mtd->erase(mtd, instr);
331 330
332 if (instr->state == MTD_ERASE_FAILED) { 331 if (instr->state == MTD_ERASE_FAILED) {
333 printk("Error while formatting block %d\n", block); 332 printk("Error while formatting block %d\n", block);
@@ -338,7 +337,7 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
338 nb_erases = le32_to_cpu(uci.WearInfo); 337 nb_erases = le32_to_cpu(uci.WearInfo);
339 nb_erases++; 338 nb_erases++;
340 339
341 /* wrap (almost impossible with current flash) or free block */ 340 /* wrap (almost impossible with current flashs) or free block */
342 if (nb_erases == 0) 341 if (nb_erases == 0)
343 nb_erases = 1; 342 nb_erases = 1;
344 343
@@ -356,7 +355,7 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
356fail: 355fail:
357 /* could not format, update the bad block table (caller is responsible 356 /* could not format, update the bad block table (caller is responsible
358 for setting the ReplUnitTable to BLOCK_RESERVED on failure) */ 357 for setting the ReplUnitTable to BLOCK_RESERVED on failure) */
359 mtd_block_markbad(nftl->mbd.mtd, instr->addr); 358 nftl->mbd.mtd->block_markbad(nftl->mbd.mtd, instr->addr);
360 return -1; 359 return -1;
361} 360}
362 361
@@ -364,10 +363,10 @@ fail:
364 * Mark as 'IGNORE' each incorrect sector. This check is only done if the chain 363 * Mark as 'IGNORE' each incorrect sector. This check is only done if the chain
365 * was being folded when NFTL was interrupted. 364 * was being folded when NFTL was interrupted.
366 * 365 *
367 * The check_free_sectors in this function is necessary. There is a possible 366 * The check_free_sectors in this function is neceressary. There is a possible
368 * situation that after writing the Data area, the Block Control Information is 367 * situation that after writing the Data area, the Block Control Information is
369 * not updated according (due to power failure or something) which leaves the block 368 * not updated according (due to power failure or something) which leaves the block
370 * in an inconsistent state. So we have to check if a block is really FREE in this 369 * in an umconsistent state. So we have to check if a block is really FREE in this
371 * case. */ 370 * case. */
372static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_block) 371static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_block)
373{ 372{
@@ -429,7 +428,7 @@ static int calc_chain_length(struct NFTLrecord *nftl, unsigned int first_block)
429 428
430 for (;;) { 429 for (;;) {
431 length++; 430 length++;
432 /* avoid infinite loops, although this is guaranteed not to 431 /* avoid infinite loops, although this is guaranted not to
433 happen because of the previous checks */ 432 happen because of the previous checks */
434 if (length >= nftl->nb_blocks) { 433 if (length >= nftl->nb_blocks) {
435 printk("nftl: length too long %d !\n", length); 434 printk("nftl: length too long %d !\n", length);
@@ -448,11 +447,11 @@ static int calc_chain_length(struct NFTLrecord *nftl, unsigned int first_block)
448/* format_chain: Format an invalid Virtual Unit chain. It frees all the Erase Units in a 447/* format_chain: Format an invalid Virtual Unit chain. It frees all the Erase Units in a
449 * Virtual Unit Chain, i.e. all the units are disconnected. 448 * Virtual Unit Chain, i.e. all the units are disconnected.
450 * 449 *
451 * It is not strictly correct to begin from the first block of the chain because 450 * It is not stricly correct to begin from the first block of the chain because
452 * if we stop the code, we may see again a valid chain if there was a first_block 451 * if we stop the code, we may see again a valid chain if there was a first_block
453 * flag in a block inside it. But is it really a problem ? 452 * flag in a block inside it. But is it really a problem ?
454 * 453 *
455 * FixMe: Figure out what the last statement means. What if power failure when we are 454 * FixMe: Figure out what the last statesment means. What if power failure when we are
456 * in the for (;;) loop formatting blocks ?? 455 * in the for (;;) loop formatting blocks ??
457 */ 456 */
458static void format_chain(struct NFTLrecord *nftl, unsigned int first_block) 457static void format_chain(struct NFTLrecord *nftl, unsigned int first_block)
@@ -486,7 +485,7 @@ static void format_chain(struct NFTLrecord *nftl, unsigned int first_block)
486 * totally free (only 0xff). 485 * totally free (only 0xff).
487 * 486 *
488 * Definition: Free Erase Unit -- A properly erased/formatted Free Erase Unit should have meet the 487 * Definition: Free Erase Unit -- A properly erased/formatted Free Erase Unit should have meet the
489 * following criteria: 488 * following critia:
490 * 1. */ 489 * 1. */
491static int check_and_mark_free_block(struct NFTLrecord *nftl, int block) 490static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
492{ 491{
@@ -503,7 +502,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
503 erase_mark = le16_to_cpu ((h1.EraseMark | h1.EraseMark1)); 502 erase_mark = le16_to_cpu ((h1.EraseMark | h1.EraseMark1));
504 if (erase_mark != ERASE_MARK) { 503 if (erase_mark != ERASE_MARK) {
505 /* if no erase mark, the block must be totally free. This is 504 /* if no erase mark, the block must be totally free. This is
506 possible in two cases : empty filesystem or interrupted erase (very unlikely) */ 505 possible in two cases : empty filsystem or interrupted erase (very unlikely) */
507 if (check_free_sectors (nftl, block * nftl->EraseSize, nftl->EraseSize, 1) != 0) 506 if (check_free_sectors (nftl, block * nftl->EraseSize, nftl->EraseSize, 1) != 0)
508 return -1; 507 return -1;
509 508
@@ -545,7 +544,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
545/* get_fold_mark: Read fold mark from Unit Control Information #2, we use FOLD_MARK_IN_PROGRESS 544/* get_fold_mark: Read fold mark from Unit Control Information #2, we use FOLD_MARK_IN_PROGRESS
546 * to indicate that we are in the progression of a Virtual Unit Chain folding. If the UCI #2 545 * to indicate that we are in the progression of a Virtual Unit Chain folding. If the UCI #2
547 * is FOLD_MARK_IN_PROGRESS when mounting the NFTL, the (previous) folding process is interrupted 546 * is FOLD_MARK_IN_PROGRESS when mounting the NFTL, the (previous) folding process is interrupted
548 * for some reason. A clean up/check of the VUC is necessary in this case. 547 * for some reason. A clean up/check of the VUC is neceressary in this case.
549 * 548 *
550 * WARNING: return 0 if read error 549 * WARNING: return 0 if read error
551 */ 550 */
@@ -658,7 +657,7 @@ int NFTL_mount(struct NFTLrecord *s)
658 printk("Block %d: incorrect logical block: %d expected: %d\n", 657 printk("Block %d: incorrect logical block: %d expected: %d\n",
659 block, logical_block, first_logical_block); 658 block, logical_block, first_logical_block);
660 /* the chain is incorrect : we must format it, 659 /* the chain is incorrect : we must format it,
661 but we need to read it completely */ 660 but we need to read it completly */
662 do_format_chain = 1; 661 do_format_chain = 1;
663 } 662 }
664 if (is_first_block) { 663 if (is_first_block) {
@@ -670,7 +669,7 @@ int NFTL_mount(struct NFTLrecord *s)
670 printk("Block %d: incorrectly marked as first block in chain\n", 669 printk("Block %d: incorrectly marked as first block in chain\n",
671 block); 670 block);
672 /* the chain is incorrect : we must format it, 671 /* the chain is incorrect : we must format it,
673 but we need to read it completely */ 672 but we need to read it completly */
674 do_format_chain = 1; 673 do_format_chain = 1;
675 } else { 674 } else {
676 printk("Block %d: folding in progress - ignoring first block flag\n", 675 printk("Block %d: folding in progress - ignoring first block flag\n",