diff options
author | Sebastian Siewior <bigeasy@tglx.de> | 2008-04-18 16:44:24 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2008-04-22 09:13:14 -0400 |
commit | c27e9b80bee039cfefa51c7af08b01eaab3dfb61 (patch) | |
tree | 37e0da84a4529d95f7b775ab66f29ef99446f7fe /drivers/mtd/nand | |
parent | cb53b3b99992b6c548d56cdf47bc710640ee2ee1 (diff) |
[MTD] [NAND] fix possible Ooops in rfc_from4
I found this while I was looking how the rs_lib is working. The rs_decoder is
initialized _after_ the nand core code read the BBT table and _after_ the
partition table has been added. The driver has a private BBT description
which is in located in flash data so we Ooops if there is a bit flip _or_ if a
bit flips while reading the partition table.
This patch moves the initialization of the rs_lib before the first possible
access by nand core.
Signed-off-by: Sebastian Siewior <bigeasy@linutronix.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jörn Engel <joern@wh.fh-wedel.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r-- | drivers/mtd/nand/rtc_from4.c | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c index 0f6ac250f434..26f88215bc47 100644 --- a/drivers/mtd/nand/rtc_from4.c +++ b/drivers/mtd/nand/rtc_from4.c | |||
@@ -478,6 +478,7 @@ static int __init rtc_from4_init(void) | |||
478 | struct nand_chip *this; | 478 | struct nand_chip *this; |
479 | unsigned short bcr1, bcr2, wcr2; | 479 | unsigned short bcr1, bcr2, wcr2; |
480 | int i; | 480 | int i; |
481 | int ret; | ||
481 | 482 | ||
482 | /* Allocate memory for MTD device structure and private data */ | 483 | /* Allocate memory for MTD device structure and private data */ |
483 | rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); | 484 | rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); |
@@ -537,6 +538,22 @@ static int __init rtc_from4_init(void) | |||
537 | this->ecc.hwctl = rtc_from4_enable_hwecc; | 538 | this->ecc.hwctl = rtc_from4_enable_hwecc; |
538 | this->ecc.calculate = rtc_from4_calculate_ecc; | 539 | this->ecc.calculate = rtc_from4_calculate_ecc; |
539 | this->ecc.correct = rtc_from4_correct_data; | 540 | this->ecc.correct = rtc_from4_correct_data; |
541 | |||
542 | /* We could create the decoder on demand, if memory is a concern. | ||
543 | * This way we have it handy, if an error happens | ||
544 | * | ||
545 | * Symbolsize is 10 (bits) | ||
546 | * Primitve polynomial is x^10+x^3+1 | ||
547 | * first consecutive root is 0 | ||
548 | * primitve element to generate roots = 1 | ||
549 | * generator polinomial degree = 6 | ||
550 | */ | ||
551 | rs_decoder = init_rs(10, 0x409, 0, 1, 6); | ||
552 | if (!rs_decoder) { | ||
553 | printk(KERN_ERR "Could not create a RS decoder\n"); | ||
554 | ret = -ENOMEM; | ||
555 | goto err_1; | ||
556 | } | ||
540 | #else | 557 | #else |
541 | printk(KERN_INFO "rtc_from4_init: using software ECC detection.\n"); | 558 | printk(KERN_INFO "rtc_from4_init: using software ECC detection.\n"); |
542 | 559 | ||
@@ -549,8 +566,8 @@ static int __init rtc_from4_init(void) | |||
549 | 566 | ||
550 | /* Scan to find existence of the device */ | 567 | /* Scan to find existence of the device */ |
551 | if (nand_scan(rtc_from4_mtd, RTC_FROM4_MAX_CHIPS)) { | 568 | if (nand_scan(rtc_from4_mtd, RTC_FROM4_MAX_CHIPS)) { |
552 | kfree(rtc_from4_mtd); | 569 | ret = -ENXIO; |
553 | return -ENXIO; | 570 | goto err_2; |
554 | } | 571 | } |
555 | 572 | ||
556 | /* Perform 'device recovery' for each chip in case there was a power loss. */ | 573 | /* Perform 'device recovery' for each chip in case there was a power loss. */ |
@@ -566,28 +583,19 @@ static int __init rtc_from4_init(void) | |||
566 | #endif | 583 | #endif |
567 | 584 | ||
568 | /* Register the partitions */ | 585 | /* Register the partitions */ |
569 | add_mtd_partitions(rtc_from4_mtd, partition_info, NUM_PARTITIONS); | 586 | ret = add_mtd_partitions(rtc_from4_mtd, partition_info, NUM_PARTITIONS); |
587 | if (ret) | ||
588 | goto err_3; | ||
570 | 589 | ||
571 | #ifdef RTC_FROM4_HWECC | ||
572 | /* We could create the decoder on demand, if memory is a concern. | ||
573 | * This way we have it handy, if an error happens | ||
574 | * | ||
575 | * Symbolsize is 10 (bits) | ||
576 | * Primitve polynomial is x^10+x^3+1 | ||
577 | * first consecutive root is 0 | ||
578 | * primitve element to generate roots = 1 | ||
579 | * generator polinomial degree = 6 | ||
580 | */ | ||
581 | rs_decoder = init_rs(10, 0x409, 0, 1, 6); | ||
582 | if (!rs_decoder) { | ||
583 | printk(KERN_ERR "Could not create a RS decoder\n"); | ||
584 | nand_release(rtc_from4_mtd); | ||
585 | kfree(rtc_from4_mtd); | ||
586 | return -ENOMEM; | ||
587 | } | ||
588 | #endif | ||
589 | /* Return happy */ | 590 | /* Return happy */ |
590 | return 0; | 591 | return 0; |
592 | err_3: | ||
593 | nand_release(rtc_from4_mtd); | ||
594 | err_2: | ||
595 | free_rs(rs_decoder); | ||
596 | err_1: | ||
597 | kfree(rtc_from4_mtd); | ||
598 | return ret; | ||
591 | } | 599 | } |
592 | 600 | ||
593 | module_init(rtc_from4_init); | 601 | module_init(rtc_from4_init); |