Commit 6a918bade9dab40aaef80559bd1169c69e8d69cb

Authored by Mike Dunn
Committed by David Woodhouse
1 parent 1d0b95b083

mtd: flash drivers set ecc strength

Flash device drivers initialize 'ecc_strength' in struct mtd_info, which is the
maximum number of bit errors that can be corrected in one writesize region.

Drivers using the nand interface intitialize 'strength' in struct nand_ecc_ctrl,
which is the maximum number of bit errors that can be corrected in one ecc step.
Nand infrastructure code translates this to 'ecc_strength'.

Also for nand drivers, the nand infrastructure code sets ecc.strength for ecc
modes NAND_ECC_SOFT, NAND_ECC_SOFT_BCH, and NAND_ECC_NONE.  It is set in the
driver for all other modes.

Signed-off-by: Mike Dunn <mikedunn@newsguy.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>

Showing 31 changed files with 63 additions and 1 deletions Side-by-side Diff

drivers/mtd/devices/doc2000.c
... ... @@ -564,6 +564,7 @@
564 564 mtd->flags = MTD_CAP_NANDFLASH;
565 565 mtd->writebufsize = mtd->writesize = 512;
566 566 mtd->oobsize = 16;
  567 + mtd->ecc_strength = 2;
567 568 mtd->owner = THIS_MODULE;
568 569 mtd->_erase = doc_erase;
569 570 mtd->_read = doc_read;
drivers/mtd/devices/doc2001.c
... ... @@ -348,6 +348,7 @@
348 348 mtd->erasesize = 0x2000;
349 349 mtd->writebufsize = mtd->writesize = 512;
350 350 mtd->oobsize = 16;
  351 + mtd->ecc_strength = 2;
351 352 mtd->owner = THIS_MODULE;
352 353 mtd->_erase = doc_erase;
353 354 mtd->_read = doc_read;
drivers/mtd/devices/doc2001plus.c
... ... @@ -469,6 +469,7 @@
469 469 mtd->flags = MTD_CAP_NANDFLASH;
470 470 mtd->writebufsize = mtd->writesize = 512;
471 471 mtd->oobsize = 16;
  472 + mtd->ecc_strength = 2;
472 473 mtd->owner = THIS_MODULE;
473 474 mtd->_erase = doc_erase;
474 475 mtd->_read = doc_read;
drivers/mtd/devices/docg3.c
... ... @@ -1832,6 +1832,7 @@
1832 1832 mtd->_write_oob = doc_write_oob;
1833 1833 mtd->_block_isbad = doc_block_isbad;
1834 1834 mtd->ecclayout = &docg3_oobinfo;
  1835 + mtd->ecc_strength = DOC_ECC_BCH_T;
1835 1836 }
1836 1837  
1837 1838 /**
drivers/mtd/mtdpart.c
... ... @@ -516,6 +516,7 @@
516 516 }
517 517  
518 518 slave->mtd.ecclayout = master->ecclayout;
  519 + slave->mtd.ecc_strength = master->ecc_strength;
519 520 if (master->_block_isbad) {
520 521 uint64_t offs = 0;
521 522  
drivers/mtd/nand/alauda.c
... ... @@ -591,6 +591,7 @@
591 591 mtd->_block_isbad = alauda_isbad;
592 592 mtd->priv = al;
593 593 mtd->owner = THIS_MODULE;
  594 + mtd->ecc_strength = 1;
594 595  
595 596 err = mtd_device_register(mtd, NULL, 0);
596 597 if (err) {
drivers/mtd/nand/atmel_nand.c
... ... @@ -554,6 +554,7 @@
554 554 nand_chip->ecc.hwctl = atmel_nand_hwctl;
555 555 nand_chip->ecc.read_page = atmel_nand_read_page;
556 556 nand_chip->ecc.bytes = 4;
  557 + nand_chip->ecc.strength = 1;
557 558 }
558 559  
559 560 nand_chip->chip_delay = 20; /* 20us command delay time */
drivers/mtd/nand/bcm_umi_nand.c
... ... @@ -476,6 +476,14 @@
476 476 largepage_bbt.options = NAND_BBT_SCAN2NDPAGE;
477 477 this->badblock_pattern = &largepage_bbt;
478 478 }
  479 +
  480 + /*
  481 + * FIXME: ecc strength value of 6 bits per 512 bytes of data is a
  482 + * conservative guess, given 13 ecc bytes and using bch alg.
  483 + * (Assume Galois field order m=15 to allow a margin of error.)
  484 + */
  485 + this->ecc.strength = 6;
  486 +
479 487 #endif
480 488  
481 489 /* Now finish off the scan, now that ecc.layout has been initialized. */
drivers/mtd/nand/bf5xx_nand.c
... ... @@ -702,9 +702,11 @@
702 702 if (likely(mtd->writesize >= 512)) {
703 703 chip->ecc.size = 512;
704 704 chip->ecc.bytes = 6;
  705 + chip->ecc.strength = 2;
705 706 } else {
706 707 chip->ecc.size = 256;
707 708 chip->ecc.bytes = 3;
  709 + chip->ecc.strength = 1;
708 710 bfin_write_NFC_CTL(bfin_read_NFC_CTL() & ~(1 << NFC_PG_SIZE_OFFSET));
709 711 SSYNC();
710 712 }
drivers/mtd/nand/cafe_nand.c
... ... @@ -783,6 +783,7 @@
783 783 cafe->nand.ecc.mode = NAND_ECC_HW_SYNDROME;
784 784 cafe->nand.ecc.size = mtd->writesize;
785 785 cafe->nand.ecc.bytes = 14;
  786 + cafe->nand.ecc.strength = 4;
786 787 cafe->nand.ecc.hwctl = (void *)cafe_nand_bug;
787 788 cafe->nand.ecc.calculate = (void *)cafe_nand_bug;
788 789 cafe->nand.ecc.correct = (void *)cafe_nand_bug;
drivers/mtd/nand/cs553x_nand.c
... ... @@ -248,6 +248,8 @@
248 248 goto out_ior;
249 249 }
250 250  
  251 + this->ecc.strength = 1;
  252 +
251 253 new_mtd->name = kasprintf(GFP_KERNEL, "cs553x_nand_cs%d", cs);
252 254  
253 255 cs553x_mtd[cs] = new_mtd;
drivers/mtd/nand/davinci_nand.c
... ... @@ -641,6 +641,7 @@
641 641 info->chip.ecc.bytes = 3;
642 642 }
643 643 info->chip.ecc.size = 512;
  644 + info->chip.ecc.strength = pdata->ecc_bits;
644 645 break;
645 646 default:
646 647 ret = -EINVAL;
drivers/mtd/nand/denali.c
... ... @@ -1590,6 +1590,7 @@
1590 1590 ECC_15BITS * (denali->mtd.writesize /
1591 1591 ECC_SECTOR_SIZE)))) {
1592 1592 /* if MLC OOB size is large enough, use 15bit ECC*/
  1593 + denali->nand.ecc.strength = 15;
1593 1594 denali->nand.ecc.layout = &nand_15bit_oob;
1594 1595 denali->nand.ecc.bytes = ECC_15BITS;
1595 1596 iowrite32(15, denali->flash_reg + ECC_CORRECTION);
1596 1597  
... ... @@ -1600,12 +1601,14 @@
1600 1601 " contain 8bit ECC correction codes");
1601 1602 goto failed_req_irq;
1602 1603 } else {
  1604 + denali->nand.ecc.strength = 8;
1603 1605 denali->nand.ecc.layout = &nand_8bit_oob;
1604 1606 denali->nand.ecc.bytes = ECC_8BITS;
1605 1607 iowrite32(8, denali->flash_reg + ECC_CORRECTION);
1606 1608 }
1607 1609  
1608 1610 denali->nand.ecc.bytes *= denali->devnum;
  1611 + denali->nand.ecc.strength *= denali->devnum;
1609 1612 denali->nand.ecc.layout->eccbytes *=
1610 1613 denali->mtd.writesize / ECC_SECTOR_SIZE;
1611 1614 denali->nand.ecc.layout->oobfree[0].offset =
drivers/mtd/nand/diskonchip.c
... ... @@ -1653,6 +1653,7 @@
1653 1653 nand->ecc.mode = NAND_ECC_HW_SYNDROME;
1654 1654 nand->ecc.size = 512;
1655 1655 nand->ecc.bytes = 6;
  1656 + nand->ecc.strength = 2;
1656 1657 nand->bbt_options = NAND_BBT_USE_FLASH;
1657 1658  
1658 1659 doc->physadr = physadr;
drivers/mtd/nand/docg4.c
... ... @@ -1191,6 +1191,7 @@
1191 1191 nand->ecc.size = DOCG4_PAGE_SIZE;
1192 1192 nand->ecc.prepad = 8;
1193 1193 nand->ecc.bytes = 8;
  1194 + nand->ecc.strength = DOCG4_T;
1194 1195 nand->options =
1195 1196 NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE | NAND_NO_AUTOINCR;
1196 1197 nand->IO_ADDR_R = nand->IO_ADDR_W = doc->virtadr + DOC_IOSPACE_DATA;
drivers/mtd/nand/fsl_elbc_nand.c
... ... @@ -813,6 +813,12 @@
813 813 &fsl_elbc_oob_sp_eccm1 : &fsl_elbc_oob_sp_eccm0;
814 814 chip->ecc.size = 512;
815 815 chip->ecc.bytes = 3;
  816 + chip->ecc.strength = 1;
  817 + /*
  818 + * FIXME: can hardware ecc correct 4 bitflips if page size is
  819 + * 2k? Then does hardware report number of corrections for this
  820 + * case? If so, ecc_stats reporting needs to be fixed as well.
  821 + */
816 822 } else {
817 823 /* otherwise fall back to default software ECC */
818 824 chip->ecc.mode = NAND_ECC_SOFT;
drivers/mtd/nand/fsmc_nand.c
... ... @@ -863,10 +863,12 @@
863 863 nand->ecc.calculate = fsmc_read_hwecc_ecc4;
864 864 nand->ecc.correct = fsmc_bch8_correct_data;
865 865 nand->ecc.bytes = 13;
  866 + nand->ecc.strength = 8;
866 867 } else {
867 868 nand->ecc.calculate = fsmc_read_hwecc_ecc1;
868 869 nand->ecc.correct = nand_correct_data;
869 870 nand->ecc.bytes = 3;
  871 + nand->ecc.strength = 1;
870 872 }
871 873  
872 874 /*
drivers/mtd/nand/jz4740_nand.c
... ... @@ -332,6 +332,11 @@
332 332 chip->ecc.mode = NAND_ECC_HW_OOB_FIRST;
333 333 chip->ecc.size = 512;
334 334 chip->ecc.bytes = 9;
  335 + chip->ecc.strength = 2;
  336 + /*
  337 + * FIXME: ecc_strength value of 2 bits per 512 bytes of data is a
  338 + * conservative guess, given 9 ecc bytes and reed-solomon alg.
  339 + */
335 340  
336 341 if (pdata)
337 342 chip->ecc.layout = pdata->ecc_layout;
drivers/mtd/nand/mxc_nand.c
... ... @@ -1225,6 +1225,13 @@
1225 1225 goto escan;
1226 1226 }
1227 1227  
  1228 + if (this->ecc.mode == NAND_ECC_HW) {
  1229 + if (nfc_is_v1())
  1230 + this->ecc.strength = 1;
  1231 + else
  1232 + this->ecc.strength = (host->eccsize == 4) ? 4 : 8;
  1233 + }
  1234 +
1228 1235 /* Register the partitions */
1229 1236 mtd_device_parse_register(mtd, part_probes, NULL, pdata->parts,
1230 1237 pdata->nr_parts);
drivers/mtd/nand/nand_base.c
... ... @@ -3350,6 +3350,7 @@
3350 3350 if (!chip->ecc.size)
3351 3351 chip->ecc.size = 256;
3352 3352 chip->ecc.bytes = 3;
  3353 + chip->ecc.strength = 1;
3353 3354 break;
3354 3355  
3355 3356 case NAND_ECC_SOFT_BCH:
... ... @@ -3384,6 +3385,8 @@
3384 3385 pr_warn("BCH ECC initialization failed!\n");
3385 3386 BUG();
3386 3387 }
  3388 + chip->ecc.strength =
  3389 + chip->ecc.bytes*8 / fls(8*chip->ecc.size);
3387 3390 break;
3388 3391  
3389 3392 case NAND_ECC_NONE:
... ... @@ -3397,6 +3400,7 @@
3397 3400 chip->ecc.write_oob = nand_write_oob_std;
3398 3401 chip->ecc.size = mtd->writesize;
3399 3402 chip->ecc.bytes = 0;
  3403 + chip->ecc.strength = 0;
3400 3404 break;
3401 3405  
3402 3406 default:
3403 3407  
... ... @@ -3478,8 +3482,9 @@
3478 3482 mtd->_block_markbad = nand_block_markbad;
3479 3483 mtd->writebufsize = mtd->writesize;
3480 3484  
3481   - /* propagate ecc.layout to mtd_info */
  3485 + /* propagate ecc info to mtd_info */
3482 3486 mtd->ecclayout = chip->ecc.layout;
  3487 + mtd->ecc_strength = chip->ecc.strength * chip->ecc.steps;
3483 3488  
3484 3489 /* Check, if we should skip the bad block table scan */
3485 3490 if (chip->options & NAND_SKIP_BBTSCAN)
drivers/mtd/nand/ndfc.c
... ... @@ -179,6 +179,7 @@
179 179 chip->ecc.mode = NAND_ECC_HW;
180 180 chip->ecc.size = 256;
181 181 chip->ecc.bytes = 3;
  182 + chip->ecc.strength = 1;
182 183 chip->priv = ndfc;
183 184  
184 185 ndfc->mtd.priv = chip;
drivers/mtd/nand/omap2.c
... ... @@ -1058,6 +1058,7 @@
1058 1058 (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) {
1059 1059 info->nand.ecc.bytes = 3;
1060 1060 info->nand.ecc.size = 512;
  1061 + info->nand.ecc.strength = 1;
1061 1062 info->nand.ecc.calculate = omap_calculate_ecc;
1062 1063 info->nand.ecc.hwctl = omap_enable_hwecc;
1063 1064 info->nand.ecc.correct = omap_correct_data;
drivers/mtd/nand/pxa3xx_nand.c
... ... @@ -1002,6 +1002,7 @@
1002 1002 KEEP_CONFIG:
1003 1003 chip->ecc.mode = NAND_ECC_HW;
1004 1004 chip->ecc.size = host->page_size;
  1005 + chip->ecc.strength = 1;
1005 1006  
1006 1007 chip->options = NAND_NO_AUTOINCR;
1007 1008 chip->options |= NAND_NO_READRDY;
drivers/mtd/nand/r852.c
... ... @@ -891,6 +891,7 @@
891 891 chip->ecc.mode = NAND_ECC_HW_SYNDROME;
892 892 chip->ecc.size = R852_DMA_LEN;
893 893 chip->ecc.bytes = SM_OOB_SIZE;
  894 + chip->ecc.strength = 2;
894 895 chip->ecc.hwctl = r852_ecc_hwctl;
895 896 chip->ecc.calculate = r852_ecc_calculate;
896 897 chip->ecc.correct = r852_ecc_correct;
drivers/mtd/nand/rtc_from4.c
... ... @@ -527,6 +527,7 @@
527 527 this->ecc.mode = NAND_ECC_HW_SYNDROME;
528 528 this->ecc.size = 512;
529 529 this->ecc.bytes = 8;
  530 + this->ecc.strength = 3;
530 531 /* return the status of extra status and ECC checks */
531 532 this->errstat = rtc_from4_errstat;
532 533 /* set the nand_oobinfo to support FPGA H/W error detection */
drivers/mtd/nand/s3c2410.c
... ... @@ -823,6 +823,7 @@
823 823 chip->ecc.calculate = s3c2410_nand_calculate_ecc;
824 824 chip->ecc.correct = s3c2410_nand_correct_data;
825 825 chip->ecc.mode = NAND_ECC_HW;
  826 + chip->ecc.strength = 1;
826 827  
827 828 switch (info->cpu_type) {
828 829 case TYPE_S3C2410:
drivers/mtd/nand/sh_flctl.c
... ... @@ -825,6 +825,7 @@
825 825  
826 826 chip->ecc.size = 512;
827 827 chip->ecc.bytes = 10;
  828 + chip->ecc.strength = 4;
828 829 chip->ecc.read_page = flctl_read_page_hwecc;
829 830 chip->ecc.write_page = flctl_write_page_hwecc;
830 831 chip->ecc.mode = NAND_ECC_HW;
drivers/mtd/nand/sharpsl.c
... ... @@ -167,6 +167,7 @@
167 167 this->ecc.mode = NAND_ECC_HW;
168 168 this->ecc.size = 256;
169 169 this->ecc.bytes = 3;
  170 + this->ecc.strength = 1;
170 171 this->badblock_pattern = data->badblock_pattern;
171 172 this->ecc.layout = data->ecc_layout;
172 173 this->ecc.hwctl = sharpsl_nand_enable_hwecc;
drivers/mtd/nand/tmio_nand.c
... ... @@ -430,6 +430,7 @@
430 430 nand_chip->ecc.mode = NAND_ECC_HW;
431 431 nand_chip->ecc.size = 512;
432 432 nand_chip->ecc.bytes = 6;
  433 + nand_chip->ecc.strength = 2;
433 434 nand_chip->ecc.hwctl = tmio_nand_enable_hwecc;
434 435 nand_chip->ecc.calculate = tmio_nand_calculate_ecc;
435 436 nand_chip->ecc.correct = tmio_nand_correct_data;
drivers/mtd/nand/txx9ndfmc.c
... ... @@ -356,6 +356,7 @@
356 356 /* txx9ndfmc_nand_scan will overwrite ecc.size and ecc.bytes */
357 357 chip->ecc.size = 256;
358 358 chip->ecc.bytes = 3;
  359 + chip->ecc.strength = 1;
359 360 chip->chip_delay = 100;
360 361 chip->controller = &drvdata->hw_control;
361 362  
drivers/mtd/onenand/onenand_base.c
... ... @@ -4080,6 +4080,7 @@
4080 4080 mtd->oobavail = this->ecclayout->oobavail;
4081 4081  
4082 4082 mtd->ecclayout = this->ecclayout;
  4083 + mtd->ecc_strength = 1;
4083 4084  
4084 4085 /* Fill in remaining MTD driver data */
4085 4086 mtd->type = ONENAND_IS_MLC(this) ? MTD_MLCNANDFLASH : MTD_NANDFLASH;