mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
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>
This commit is contained in:
parent
1d0b95b083
commit
6a918bade9
@ -564,6 +564,7 @@ void DoC2k_init(struct mtd_info *mtd)
|
||||
mtd->flags = MTD_CAP_NANDFLASH;
|
||||
mtd->writebufsize = mtd->writesize = 512;
|
||||
mtd->oobsize = 16;
|
||||
mtd->ecc_strength = 2;
|
||||
mtd->owner = THIS_MODULE;
|
||||
mtd->_erase = doc_erase;
|
||||
mtd->_read = doc_read;
|
||||
|
@ -348,6 +348,7 @@ void DoCMil_init(struct mtd_info *mtd)
|
||||
mtd->erasesize = 0x2000;
|
||||
mtd->writebufsize = mtd->writesize = 512;
|
||||
mtd->oobsize = 16;
|
||||
mtd->ecc_strength = 2;
|
||||
mtd->owner = THIS_MODULE;
|
||||
mtd->_erase = doc_erase;
|
||||
mtd->_read = doc_read;
|
||||
|
@ -469,6 +469,7 @@ void DoCMilPlus_init(struct mtd_info *mtd)
|
||||
mtd->flags = MTD_CAP_NANDFLASH;
|
||||
mtd->writebufsize = mtd->writesize = 512;
|
||||
mtd->oobsize = 16;
|
||||
mtd->ecc_strength = 2;
|
||||
mtd->owner = THIS_MODULE;
|
||||
mtd->_erase = doc_erase;
|
||||
mtd->_read = doc_read;
|
||||
|
@ -1832,6 +1832,7 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
|
||||
mtd->_write_oob = doc_write_oob;
|
||||
mtd->_block_isbad = doc_block_isbad;
|
||||
mtd->ecclayout = &docg3_oobinfo;
|
||||
mtd->ecc_strength = DOC_ECC_BCH_T;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -516,6 +516,7 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
|
||||
}
|
||||
|
||||
slave->mtd.ecclayout = master->ecclayout;
|
||||
slave->mtd.ecc_strength = master->ecc_strength;
|
||||
if (master->_block_isbad) {
|
||||
uint64_t offs = 0;
|
||||
|
||||
|
@ -591,6 +591,7 @@ static int alauda_init_media(struct alauda *al)
|
||||
mtd->_block_isbad = alauda_isbad;
|
||||
mtd->priv = al;
|
||||
mtd->owner = THIS_MODULE;
|
||||
mtd->ecc_strength = 1;
|
||||
|
||||
err = mtd_device_register(mtd, NULL, 0);
|
||||
if (err) {
|
||||
|
@ -554,6 +554,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
|
||||
nand_chip->ecc.hwctl = atmel_nand_hwctl;
|
||||
nand_chip->ecc.read_page = atmel_nand_read_page;
|
||||
nand_chip->ecc.bytes = 4;
|
||||
nand_chip->ecc.strength = 1;
|
||||
}
|
||||
|
||||
nand_chip->chip_delay = 20; /* 20us command delay time */
|
||||
|
@ -476,6 +476,14 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
|
||||
largepage_bbt.options = NAND_BBT_SCAN2NDPAGE;
|
||||
this->badblock_pattern = &largepage_bbt;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: ecc strength value of 6 bits per 512 bytes of data is a
|
||||
* conservative guess, given 13 ecc bytes and using bch alg.
|
||||
* (Assume Galois field order m=15 to allow a margin of error.)
|
||||
*/
|
||||
this->ecc.strength = 6;
|
||||
|
||||
#endif
|
||||
|
||||
/* Now finish off the scan, now that ecc.layout has been initialized. */
|
||||
|
@ -702,9 +702,11 @@ static int bf5xx_nand_scan(struct mtd_info *mtd)
|
||||
if (likely(mtd->writesize >= 512)) {
|
||||
chip->ecc.size = 512;
|
||||
chip->ecc.bytes = 6;
|
||||
chip->ecc.strength = 2;
|
||||
} else {
|
||||
chip->ecc.size = 256;
|
||||
chip->ecc.bytes = 3;
|
||||
chip->ecc.strength = 1;
|
||||
bfin_write_NFC_CTL(bfin_read_NFC_CTL() & ~(1 << NFC_PG_SIZE_OFFSET));
|
||||
SSYNC();
|
||||
}
|
||||
|
@ -783,6 +783,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
|
||||
cafe->nand.ecc.mode = NAND_ECC_HW_SYNDROME;
|
||||
cafe->nand.ecc.size = mtd->writesize;
|
||||
cafe->nand.ecc.bytes = 14;
|
||||
cafe->nand.ecc.strength = 4;
|
||||
cafe->nand.ecc.hwctl = (void *)cafe_nand_bug;
|
||||
cafe->nand.ecc.calculate = (void *)cafe_nand_bug;
|
||||
cafe->nand.ecc.correct = (void *)cafe_nand_bug;
|
||||
|
@ -248,6 +248,8 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
|
||||
goto out_ior;
|
||||
}
|
||||
|
||||
this->ecc.strength = 1;
|
||||
|
||||
new_mtd->name = kasprintf(GFP_KERNEL, "cs553x_nand_cs%d", cs);
|
||||
|
||||
cs553x_mtd[cs] = new_mtd;
|
||||
|
@ -641,6 +641,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
|
||||
info->chip.ecc.bytes = 3;
|
||||
}
|
||||
info->chip.ecc.size = 512;
|
||||
info->chip.ecc.strength = pdata->ecc_bits;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
|
@ -1590,6 +1590,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
ECC_15BITS * (denali->mtd.writesize /
|
||||
ECC_SECTOR_SIZE)))) {
|
||||
/* if MLC OOB size is large enough, use 15bit ECC*/
|
||||
denali->nand.ecc.strength = 15;
|
||||
denali->nand.ecc.layout = &nand_15bit_oob;
|
||||
denali->nand.ecc.bytes = ECC_15BITS;
|
||||
iowrite32(15, denali->flash_reg + ECC_CORRECTION);
|
||||
@ -1600,12 +1601,14 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
" contain 8bit ECC correction codes");
|
||||
goto failed_req_irq;
|
||||
} else {
|
||||
denali->nand.ecc.strength = 8;
|
||||
denali->nand.ecc.layout = &nand_8bit_oob;
|
||||
denali->nand.ecc.bytes = ECC_8BITS;
|
||||
iowrite32(8, denali->flash_reg + ECC_CORRECTION);
|
||||
}
|
||||
|
||||
denali->nand.ecc.bytes *= denali->devnum;
|
||||
denali->nand.ecc.strength *= denali->devnum;
|
||||
denali->nand.ecc.layout->eccbytes *=
|
||||
denali->mtd.writesize / ECC_SECTOR_SIZE;
|
||||
denali->nand.ecc.layout->oobfree[0].offset =
|
||||
|
@ -1653,6 +1653,7 @@ static int __init doc_probe(unsigned long physadr)
|
||||
nand->ecc.mode = NAND_ECC_HW_SYNDROME;
|
||||
nand->ecc.size = 512;
|
||||
nand->ecc.bytes = 6;
|
||||
nand->ecc.strength = 2;
|
||||
nand->bbt_options = NAND_BBT_USE_FLASH;
|
||||
|
||||
doc->physadr = physadr;
|
||||
|
@ -1191,6 +1191,7 @@ static void __init init_mtd_structs(struct mtd_info *mtd)
|
||||
nand->ecc.size = DOCG4_PAGE_SIZE;
|
||||
nand->ecc.prepad = 8;
|
||||
nand->ecc.bytes = 8;
|
||||
nand->ecc.strength = DOCG4_T;
|
||||
nand->options =
|
||||
NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE | NAND_NO_AUTOINCR;
|
||||
nand->IO_ADDR_R = nand->IO_ADDR_W = doc->virtadr + DOC_IOSPACE_DATA;
|
||||
|
@ -813,6 +813,12 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
|
||||
&fsl_elbc_oob_sp_eccm1 : &fsl_elbc_oob_sp_eccm0;
|
||||
chip->ecc.size = 512;
|
||||
chip->ecc.bytes = 3;
|
||||
chip->ecc.strength = 1;
|
||||
/*
|
||||
* FIXME: can hardware ecc correct 4 bitflips if page size is
|
||||
* 2k? Then does hardware report number of corrections for this
|
||||
* case? If so, ecc_stats reporting needs to be fixed as well.
|
||||
*/
|
||||
} else {
|
||||
/* otherwise fall back to default software ECC */
|
||||
chip->ecc.mode = NAND_ECC_SOFT;
|
||||
|
@ -863,10 +863,12 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
|
||||
nand->ecc.calculate = fsmc_read_hwecc_ecc4;
|
||||
nand->ecc.correct = fsmc_bch8_correct_data;
|
||||
nand->ecc.bytes = 13;
|
||||
nand->ecc.strength = 8;
|
||||
} else {
|
||||
nand->ecc.calculate = fsmc_read_hwecc_ecc1;
|
||||
nand->ecc.correct = nand_correct_data;
|
||||
nand->ecc.bytes = 3;
|
||||
nand->ecc.strength = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -332,6 +332,11 @@ static int __devinit jz_nand_probe(struct platform_device *pdev)
|
||||
chip->ecc.mode = NAND_ECC_HW_OOB_FIRST;
|
||||
chip->ecc.size = 512;
|
||||
chip->ecc.bytes = 9;
|
||||
chip->ecc.strength = 2;
|
||||
/*
|
||||
* FIXME: ecc_strength value of 2 bits per 512 bytes of data is a
|
||||
* conservative guess, given 9 ecc bytes and reed-solomon alg.
|
||||
*/
|
||||
|
||||
if (pdata)
|
||||
chip->ecc.layout = pdata->ecc_layout;
|
||||
|
@ -1225,6 +1225,13 @@ static int __init mxcnd_probe(struct platform_device *pdev)
|
||||
goto escan;
|
||||
}
|
||||
|
||||
if (this->ecc.mode == NAND_ECC_HW) {
|
||||
if (nfc_is_v1())
|
||||
this->ecc.strength = 1;
|
||||
else
|
||||
this->ecc.strength = (host->eccsize == 4) ? 4 : 8;
|
||||
}
|
||||
|
||||
/* Register the partitions */
|
||||
mtd_device_parse_register(mtd, part_probes, NULL, pdata->parts,
|
||||
pdata->nr_parts);
|
||||
|
@ -3350,6 +3350,7 @@ int nand_scan_tail(struct mtd_info *mtd)
|
||||
if (!chip->ecc.size)
|
||||
chip->ecc.size = 256;
|
||||
chip->ecc.bytes = 3;
|
||||
chip->ecc.strength = 1;
|
||||
break;
|
||||
|
||||
case NAND_ECC_SOFT_BCH:
|
||||
@ -3384,6 +3385,8 @@ int nand_scan_tail(struct mtd_info *mtd)
|
||||
pr_warn("BCH ECC initialization failed!\n");
|
||||
BUG();
|
||||
}
|
||||
chip->ecc.strength =
|
||||
chip->ecc.bytes*8 / fls(8*chip->ecc.size);
|
||||
break;
|
||||
|
||||
case NAND_ECC_NONE:
|
||||
@ -3397,6 +3400,7 @@ int nand_scan_tail(struct mtd_info *mtd)
|
||||
chip->ecc.write_oob = nand_write_oob_std;
|
||||
chip->ecc.size = mtd->writesize;
|
||||
chip->ecc.bytes = 0;
|
||||
chip->ecc.strength = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -3478,8 +3482,9 @@ int nand_scan_tail(struct mtd_info *mtd)
|
||||
mtd->_block_markbad = nand_block_markbad;
|
||||
mtd->writebufsize = mtd->writesize;
|
||||
|
||||
/* propagate ecc.layout to mtd_info */
|
||||
/* propagate ecc info to mtd_info */
|
||||
mtd->ecclayout = chip->ecc.layout;
|
||||
mtd->ecc_strength = chip->ecc.strength * chip->ecc.steps;
|
||||
|
||||
/* Check, if we should skip the bad block table scan */
|
||||
if (chip->options & NAND_SKIP_BBTSCAN)
|
||||
|
@ -179,6 +179,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
|
||||
chip->ecc.mode = NAND_ECC_HW;
|
||||
chip->ecc.size = 256;
|
||||
chip->ecc.bytes = 3;
|
||||
chip->ecc.strength = 1;
|
||||
chip->priv = ndfc;
|
||||
|
||||
ndfc->mtd.priv = chip;
|
||||
|
@ -1058,6 +1058,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
|
||||
(pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) {
|
||||
info->nand.ecc.bytes = 3;
|
||||
info->nand.ecc.size = 512;
|
||||
info->nand.ecc.strength = 1;
|
||||
info->nand.ecc.calculate = omap_calculate_ecc;
|
||||
info->nand.ecc.hwctl = omap_enable_hwecc;
|
||||
info->nand.ecc.correct = omap_correct_data;
|
||||
|
@ -1002,6 +1002,7 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
|
||||
KEEP_CONFIG:
|
||||
chip->ecc.mode = NAND_ECC_HW;
|
||||
chip->ecc.size = host->page_size;
|
||||
chip->ecc.strength = 1;
|
||||
|
||||
chip->options = NAND_NO_AUTOINCR;
|
||||
chip->options |= NAND_NO_READRDY;
|
||||
|
@ -891,6 +891,7 @@ int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
|
||||
chip->ecc.mode = NAND_ECC_HW_SYNDROME;
|
||||
chip->ecc.size = R852_DMA_LEN;
|
||||
chip->ecc.bytes = SM_OOB_SIZE;
|
||||
chip->ecc.strength = 2;
|
||||
chip->ecc.hwctl = r852_ecc_hwctl;
|
||||
chip->ecc.calculate = r852_ecc_calculate;
|
||||
chip->ecc.correct = r852_ecc_correct;
|
||||
|
@ -527,6 +527,7 @@ static int __init rtc_from4_init(void)
|
||||
this->ecc.mode = NAND_ECC_HW_SYNDROME;
|
||||
this->ecc.size = 512;
|
||||
this->ecc.bytes = 8;
|
||||
this->ecc.strength = 3;
|
||||
/* return the status of extra status and ECC checks */
|
||||
this->errstat = rtc_from4_errstat;
|
||||
/* set the nand_oobinfo to support FPGA H/W error detection */
|
||||
|
@ -823,6 +823,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
|
||||
chip->ecc.calculate = s3c2410_nand_calculate_ecc;
|
||||
chip->ecc.correct = s3c2410_nand_correct_data;
|
||||
chip->ecc.mode = NAND_ECC_HW;
|
||||
chip->ecc.strength = 1;
|
||||
|
||||
switch (info->cpu_type) {
|
||||
case TYPE_S3C2410:
|
||||
|
@ -825,6 +825,7 @@ static int flctl_chip_init_tail(struct mtd_info *mtd)
|
||||
|
||||
chip->ecc.size = 512;
|
||||
chip->ecc.bytes = 10;
|
||||
chip->ecc.strength = 4;
|
||||
chip->ecc.read_page = flctl_read_page_hwecc;
|
||||
chip->ecc.write_page = flctl_write_page_hwecc;
|
||||
chip->ecc.mode = NAND_ECC_HW;
|
||||
|
@ -167,6 +167,7 @@ static int __devinit sharpsl_nand_probe(struct platform_device *pdev)
|
||||
this->ecc.mode = NAND_ECC_HW;
|
||||
this->ecc.size = 256;
|
||||
this->ecc.bytes = 3;
|
||||
this->ecc.strength = 1;
|
||||
this->badblock_pattern = data->badblock_pattern;
|
||||
this->ecc.layout = data->ecc_layout;
|
||||
this->ecc.hwctl = sharpsl_nand_enable_hwecc;
|
||||
|
@ -430,6 +430,7 @@ static int tmio_probe(struct platform_device *dev)
|
||||
nand_chip->ecc.mode = NAND_ECC_HW;
|
||||
nand_chip->ecc.size = 512;
|
||||
nand_chip->ecc.bytes = 6;
|
||||
nand_chip->ecc.strength = 2;
|
||||
nand_chip->ecc.hwctl = tmio_nand_enable_hwecc;
|
||||
nand_chip->ecc.calculate = tmio_nand_calculate_ecc;
|
||||
nand_chip->ecc.correct = tmio_nand_correct_data;
|
||||
|
@ -356,6 +356,7 @@ static int __init txx9ndfmc_probe(struct platform_device *dev)
|
||||
/* txx9ndfmc_nand_scan will overwrite ecc.size and ecc.bytes */
|
||||
chip->ecc.size = 256;
|
||||
chip->ecc.bytes = 3;
|
||||
chip->ecc.strength = 1;
|
||||
chip->chip_delay = 100;
|
||||
chip->controller = &drvdata->hw_control;
|
||||
|
||||
|
@ -4080,6 +4080,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
|
||||
mtd->oobavail = this->ecclayout->oobavail;
|
||||
|
||||
mtd->ecclayout = this->ecclayout;
|
||||
mtd->ecc_strength = 1;
|
||||
|
||||
/* Fill in remaining MTD driver data */
|
||||
mtd->type = ONENAND_IS_MLC(this) ? MTD_MLCNANDFLASH : MTD_NANDFLASH;
|
||||
|
Loading…
Reference in New Issue
Block a user