From f6647d3c02cd45675f61bbda59206f9c9df3192e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 4 Apr 2011 11:23:36 +0200 Subject: nand: factor out software ecc support to seperate file in order to make it optional later. Signed-off-by: Sascha Hauer --- drivers/mtd/nand/Makefile | 2 +- drivers/mtd/nand/nand.h | 1 + drivers/mtd/nand/nand_base.c | 75 +--------------------------------- drivers/mtd/nand/nand_swecc.c | 94 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 75 deletions(-) create mode 100644 drivers/mtd/nand/nand_swecc.c (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index ffd3be14f2..c99633c720 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -1,6 +1,6 @@ # Generic NAND options -obj-$(CONFIG_NAND) += nand.o nand_ecc.o nand_hwecc.o +obj-$(CONFIG_NAND) += nand.o nand_ecc.o nand_hwecc.o nand_swecc.o obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o obj-$(CONFIG_NAND) += nand_base.o nand_bbt.o diff --git a/drivers/mtd/nand/nand.h b/drivers/mtd/nand/nand.h index 39cf135d8a..70d0ba98d0 100644 --- a/drivers/mtd/nand/nand.h +++ b/drivers/mtd/nand/nand.h @@ -9,5 +9,6 @@ int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip, int page); void nand_init_ecc_hw(struct nand_chip *chip); +void nand_init_ecc_soft(struct nand_chip *chip); #endif /* __NAND_H */ diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 1923d26bce..ea34da910b 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -686,46 +686,6 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, return 0; } -/** - * nand_read_page_swecc - [REPLACABLE] software ecc based page read function - * @mtd: mtd info structure - * @chip: nand chip info structure - * @buf: buffer to store read data - */ -static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, - uint8_t *buf) -{ - int i, eccsize = chip->ecc.size; - int eccbytes = chip->ecc.bytes; - int eccsteps = chip->ecc.steps; - uint8_t *p = buf; - uint8_t *ecc_calc = chip->buffers->ecccalc; - uint8_t *ecc_code = chip->buffers->ecccode; - uint32_t *eccpos = chip->ecc.layout->eccpos; - - chip->ecc.read_page_raw(mtd, chip, buf); - - for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) - chip->ecc.calculate(mtd, p, &ecc_calc[i]); - - for (i = 0; i < chip->ecc.total; i++) - ecc_code[i] = chip->oob_poi[eccpos[i]]; - - eccsteps = chip->ecc.steps; - p = buf; - - for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { - int stat; - - stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); - if (stat < 0) - mtd->ecc_stats.failed++; - else - mtd->ecc_stats.corrected += stat; - } - return 0; -} - /** * nand_read_page_syndrome - [REPLACABLE] hardware ecc syndrom based page read * @mtd: mtd info structure @@ -1283,32 +1243,6 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); } -/** - * nand_write_page_swecc - [REPLACABLE] software ecc based page write function - * @mtd: mtd info structure - * @chip: nand chip info structure - * @buf: data buffer - */ -static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, - const uint8_t *buf) -{ - int i, eccsize = chip->ecc.size; - int eccbytes = chip->ecc.bytes; - int eccsteps = chip->ecc.steps; - uint8_t *ecc_calc = chip->buffers->ecccalc; - const uint8_t *p = buf; - uint32_t *eccpos = chip->ecc.layout->eccpos; - - /* Software ecc calculation */ - for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) - chip->ecc.calculate(mtd, p, &ecc_calc[i]); - - for (i = 0; i < chip->ecc.total; i++) - chip->oob_poi[eccpos[i]] = ecc_calc[i]; - - chip->ecc.write_page_raw(mtd, chip, buf); -} - /** * nand_write_page_syndrome - [REPLACABLE] hardware ecc syndrom based page write * @mtd: mtd info structure @@ -2312,14 +2246,7 @@ int nand_scan_tail(struct mtd_info *mtd) break; case NAND_ECC_SOFT: - chip->ecc.calculate = nand_calculate_ecc; - chip->ecc.correct = nand_correct_data; - chip->ecc.read_page = nand_read_page_swecc; - chip->ecc.write_page = nand_write_page_swecc; - chip->ecc.read_oob = nand_read_oob_std; - chip->ecc.write_oob = nand_write_oob_std; - chip->ecc.size = 256; - chip->ecc.bytes = 3; + nand_init_ecc_soft(chip); break; case NAND_ECC_NONE: diff --git a/drivers/mtd/nand/nand_swecc.c b/drivers/mtd/nand/nand_swecc.c new file mode 100644 index 0000000000..93511cbe3d --- /dev/null +++ b/drivers/mtd/nand/nand_swecc.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nand.h" + +/** + * nand_read_page_swecc - [REPLACABLE] software ecc based page read function + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: buffer to store read data + */ +static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, + uint8_t *buf) +{ + int i, eccsize = chip->ecc.size; + int eccbytes = chip->ecc.bytes; + int eccsteps = chip->ecc.steps; + uint8_t *p = buf; + uint8_t *ecc_calc = chip->buffers->ecccalc; + uint8_t *ecc_code = chip->buffers->ecccode; + uint32_t *eccpos = chip->ecc.layout->eccpos; + + chip->ecc.read_page_raw(mtd, chip, buf); + + for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) + chip->ecc.calculate(mtd, p, &ecc_calc[i]); + + for (i = 0; i < chip->ecc.total; i++) + ecc_code[i] = chip->oob_poi[eccpos[i]]; + + eccsteps = chip->ecc.steps; + p = buf; + + for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { + int stat; + + stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); + if (stat < 0) + mtd->ecc_stats.failed++; + else + mtd->ecc_stats.corrected += stat; + } + return 0; +} + +/** + * nand_write_page_swecc - [REPLACABLE] software ecc based page write function + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: data buffer + */ +#ifdef CONFIG_NAND_WRITE +static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, + const uint8_t *buf) +{ + int i, eccsize = chip->ecc.size; + int eccbytes = chip->ecc.bytes; + int eccsteps = chip->ecc.steps; + uint8_t *ecc_calc = chip->buffers->ecccalc; + const uint8_t *p = buf; + uint32_t *eccpos = chip->ecc.layout->eccpos; + + /* Software ecc calculation */ + for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) + chip->ecc.calculate(mtd, p, &ecc_calc[i]); + + for (i = 0; i < chip->ecc.total; i++) + chip->oob_poi[eccpos[i]] = ecc_calc[i]; + + chip->ecc.write_page_raw(mtd, chip, buf); +} +#endif + +void nand_init_ecc_soft(struct nand_chip *chip) +{ + chip->ecc.calculate = nand_calculate_ecc; + chip->ecc.correct = nand_correct_data; + chip->ecc.read_page = nand_read_page_swecc; + chip->ecc.read_oob = nand_read_oob_std; +#ifdef CONFIG_NAND_WRITE + chip->ecc.write_page = nand_write_page_swecc; + chip->ecc.write_oob = nand_write_oob_std; +#endif + chip->ecc.size = 256; + chip->ecc.bytes = 3; +} -- cgit v1.2.3