9
0
Fork 0

mtd: introduce ecc strength

This introduces the ecc stength fields in the structures and fills
them in, but leaves them unused right now.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Sascha Hauer 2013-07-18 15:02:58 +02:00
parent e3885851b7
commit d155610821
9 changed files with 44 additions and 0 deletions

View File

@ -1686,6 +1686,7 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.read_oob = nand_read_oob_std;
chip->ecc.size = mtd->writesize;
chip->ecc.bytes = 0;
chip->ecc.strength = 0;
break;
#endif
default:
@ -1762,6 +1763,7 @@ int nand_scan_tail(struct mtd_info *mtd)
#endif
/* propagate ecc.layout to mtd_info */
mtd->ecclayout = chip->ecc.layout;
mtd->ecc_strength = chip->ecc.strength;
/* Check, if we should skip the bad block table scan */
if (chip->options & NAND_SKIP_BBTSCAN)

View File

@ -1298,6 +1298,9 @@ static int __init imxnd_probe(struct device_d *dev)
writew(NFC_V2_SPAS_SPARESIZE(16), host->regs + NFC_V2_SPAS);
}
if (this->ecc.mode == NAND_ECC_HW)
this->ecc.strength = host->eccsize;
/* second phase scan */
if (nand_scan_tail(mtd)) {
err = -ENXIO;

View File

@ -1246,6 +1246,7 @@ static int mxs_nand_probe(struct device_d *dev)
nand->ecc.mode = NAND_ECC_HW;
nand->ecc.bytes = 9;
nand->ecc.size = 512;
nand->ecc.strength = 8;
/* first scan to find the device and get the page size */
err = nand_scan_ident(mtd, 1);

View File

@ -85,6 +85,9 @@
#define GPMC_ECC_SIZE_CONFIG_ECCSIZE0(x) ((x) << 12)
#define GPMC_ECC_SIZE_CONFIG_ECCSIZE1(x) ((x) << 22)
#define BCH8_MAX_ERROR 8 /* upto 8 bit correctable */
#define BCH4_MAX_ERROR 4 /* upto 4 bit correctable */
int omap_gpmc_decode_bch(int select_4_8, unsigned char *ecc, unsigned int *err_loc);
static char *ecc_mode_strings[] = {
@ -785,6 +788,7 @@ static int omap_gpmc_eccmode(struct gpmc_nand_info *oinfo,
case OMAP_ECC_HAMMING_CODE_HW_ROMCODE:
oinfo->nand.ecc.bytes = 3;
oinfo->nand.ecc.size = 512;
oinfo->nand.ecc.strength = 1;
oinfo->ecc_parity_pairs = 12;
if (oinfo->nand.options & NAND_BUSWIDTH_16) {
offset = 2;
@ -802,6 +806,7 @@ static int omap_gpmc_eccmode(struct gpmc_nand_info *oinfo,
case OMAP_ECC_BCH4_CODE_HW:
oinfo->nand.ecc.bytes = 4 * 7;
oinfo->nand.ecc.size = 4 * 512;
oinfo->nand.ecc.strength = BCH4_MAX_ERROR;
omap_oobinfo.oobfree->offset = offset;
omap_oobinfo.oobfree->length = minfo->oobsize -
offset - omap_oobinfo.eccbytes;
@ -812,6 +817,7 @@ static int omap_gpmc_eccmode(struct gpmc_nand_info *oinfo,
case OMAP_ECC_BCH8_CODE_HW:
oinfo->nand.ecc.bytes = 4 * 13;
oinfo->nand.ecc.size = 4 * 512;
oinfo->nand.ecc.strength = BCH8_MAX_ERROR;
omap_oobinfo.oobfree->offset = offset;
omap_oobinfo.oobfree->length = minfo->oobsize -
offset - omap_oobinfo.eccbytes;
@ -822,6 +828,7 @@ static int omap_gpmc_eccmode(struct gpmc_nand_info *oinfo,
case OMAP_ECC_BCH8_CODE_HW_ROMCODE:
oinfo->nand.ecc.bytes = 4 * 13;
oinfo->nand.ecc.size = 4 * 512;
oinfo->nand.ecc.strength = BCH8_MAX_ERROR;
nand->ecc.read_page = omap_gpmc_read_page_bch_rom_mode;
omap_oobinfo.oobfree->length = 0;
j = 0;
@ -837,6 +844,7 @@ static int omap_gpmc_eccmode(struct gpmc_nand_info *oinfo,
case OMAP_ECC_SOFT:
nand->ecc.layout = NULL;
nand->ecc.mode = NAND_ECC_SOFT;
oinfo->nand.ecc.strength = 1;
break;
default:
return -EINVAL;

View File

@ -456,6 +456,8 @@ static int s3c24x0_nand_probe(struct device_d *dev)
*/
chip->ecc.mode = NAND_ECC_HW;
chip->ecc.bytes = 3; /* always 24 bit ECC per turn */
chip->ecc.strength = 1;
#ifdef CONFIG_CPU_S3C2440
if (readl(host->base) & 0x8) {
/* large page (2048 bytes per page) */

View File

@ -91,4 +91,5 @@ void nand_init_ecc_soft(struct nand_chip *chip)
#endif
chip->ecc.size = 256;
chip->ecc.bytes = 3;
chip->ecc.strength = 1;
}

View File

@ -209,6 +209,7 @@ static int nomadik_nand_probe(struct device_d *dev)
nand->ecc.hwctl = nomadik_ecc_control;
nand->ecc.size = 512;
nand->ecc.bytes = 3;
nand->ecc.strength = 1;
nand->options = pdata->options;

View File

@ -104,6 +104,15 @@ struct mtd_info {
u_int32_t oobsize; // Amount of OOB data per block (e.g. 16)
u_int32_t oobavail; // Available OOB bytes per block
/*
* read ops return -EUCLEAN if max number of bitflips corrected on any
* one region comprising an ecc step equals or exceeds this value.
* Settable by driver, else defaults to ecc_strength. User can override
* in sysfs. N.B. The meaning of the -EUCLEAN return code has changed;
* see Documentation/ABI/testing/sysfs-class-mtd for more detail.
*/
unsigned int bitflip_threshold;
// Kernel-only stuff starts here.
char *name;
int index;
@ -111,6 +120,9 @@ struct mtd_info {
/* ecc layout structure pointer - read only ! */
struct nand_ecclayout *ecclayout;
/* max number of correctible bit errors per ecc step */
unsigned int ecc_strength;
/* Data for variable erase regions. If numeraseregions is zero,
* it means that the whole device has erasesize as given above.
*/
@ -273,4 +285,16 @@ int mtd_all_ff(const void *buf, unsigned int len);
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
static inline int mtd_is_bitflip(int err) {
return err == -EUCLEAN;
}
static inline int mtd_is_eccerr(int err) {
return err == -EBADMSG;
}
static inline int mtd_is_bitflip_or_eccerr(int err) {
return mtd_is_bitflip(err) || mtd_is_eccerr(err);
}
#endif /* __MTD_MTD_H__ */

View File

@ -300,6 +300,7 @@ struct nand_hw_control {
* @steps: number of ecc steps per page
* @size: data bytes per ecc step
* @bytes: ecc bytes per step
* @strength: max number of correctible bits per ECC step
* @total: total number of ecc bytes per page
* @prepad: padding information for syndrome based ecc generators
* @postpad: padding information for syndrome based ecc generators
@ -321,6 +322,7 @@ struct nand_ecc_ctrl {
int size;
int bytes;
int total;
int strength;
int prepad;
int postpad;
struct nand_ecclayout *layout;