diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/mtd/nftlmount.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/mtd/nftlmount.c')
-rw-r--r-- | drivers/mtd/nftlmount.c | 39 |
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 | */ |
38 | static int find_boot_record(struct NFTLrecord *nftl) | 38 | static 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 | */ |
303 | int NFTL_formatblock(struct NFTLrecord *nftl, int block) | 302 | int 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) | |||
356 | fail: | 355 | fail: |
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. */ |
372 | static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_block) | 371 | static 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 | */ |
458 | static void format_chain(struct NFTLrecord *nftl, unsigned int first_block) | 457 | static 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. */ |
491 | static int check_and_mark_free_block(struct NFTLrecord *nftl, int block) | 490 | static 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", |