mtd/drivers/mtd/nand nand_base.c,1.96,1.97
gleixner at infradead.org
gleixner at infradead.org
Fri Jun 4 04:24:11 EDT 2004
Update of /home/cvs/mtd/drivers/mtd/nand
In directory phoenix.infradead.org:/tmp/cvs-serv29725
Modified Files:
nand_base.c
Log Message:
Hardware ECC 8 Byte per 512 byte data support. Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Index: nand_base.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand_base.c,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -r1.96 -r1.97
--- nand_base.c 4 Jun 2004 07:55:44 -0000 1.96
+++ nand_base.c 4 Jun 2004 08:24:08 -0000 1.97
@@ -795,10 +795,11 @@
u_char *oob_buf, struct nand_oobinfo *oobsel, int cached)
{
int i, status;
- u_char ecc_code[6];
+ u_char ecc_code[8];
int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
int *oob_config = oobsel->eccpos;
int datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
+ int eccbytes = 0;
/* FIXME: Enable cached programming */
cached = 0;
@@ -825,27 +826,22 @@
this->write_buf(mtd, this->data_poi, mtd->oobblock);
break;
- /* Hardware ecc 3 byte / 256 data, write 256 byte */
- /* Hardware ecc 3 byte / 512 byte data, write 512 bytee */
+ /* Hardware ecc 8 byte / 512 byte data */
+ case NAND_ECC_HW8_512:
+ eccbytes += 2;
+ /* Hardware ecc 6 byte / 512 byte data */
+ case NAND_ECC_HW6_512:
+ eccbytes += 3;
+ /* Hardware ecc 3 byte / 256 data */
+ /* Hardware ecc 3 byte / 512 byte data */
case NAND_ECC_HW3_256:
case NAND_ECC_HW3_512:
+ eccbytes += 3;
for (; eccsteps; eccsteps--) {
this->enable_hwecc(mtd, NAND_ECC_WRITE); /* enable hardware ecc logic for write */
this->write_buf(mtd, &this->data_poi[datidx], this->eccsize);
this->calculate_ecc(mtd, NULL, ecc_code);
- for (i = 0; i < 3; i++, eccidx++)
- oob_buf[oob_config[eccidx]] = ecc_code[i];
- datidx += this->eccsize;
- }
- break;
-
- /* Hardware ecc 6 byte / 512 byte data, write 512 byte */
- case NAND_ECC_HW6_512:
- for (; eccsteps; eccsteps--) {
- this->enable_hwecc(mtd, NAND_ECC_WRITE); /* enable hardware ecc logic for write */
- this->write_buf(mtd, &this->data_poi[datidx], this->eccsize);
- this->calculate_ecc(mtd, NULL, ecc_code);
- for (i = 0; i < 6; i++, eccidx++)
+ for (i = 0; i < eccbytes; i++, eccidx++)
oob_buf[oob_config[eccidx]] = ecc_code[i];
datidx += this->eccsize;
}
@@ -1011,11 +1007,12 @@
int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0;
struct nand_chip *this = mtd->priv;
u_char *data_poi, *oob_data = oob_buf;
- u_char ecc_calc[24];
- u_char ecc_code[24];
+ u_char ecc_calc[32];
+ u_char ecc_code[32];
int eccmode, eccsteps;
int *oob_config, datidx;
int blockcheck = (mtd->erasesize >> this->page_shift) - 1;
+ int eccbytes = 3;
DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
@@ -1054,6 +1051,14 @@
end = mtd->oobblock;
ecc = this->eccsize;
+ switch (eccmode) {
+ case NAND_ECC_HW6_512: /* Hardware ECC 6 byte / 512 byte data */
+ eccbytes = 6;
+ break;
+ case NAND_ECC_HW8_512: /* Hardware ECC 8 byte / 512 byte data */
+ eccbytes = 8;
+ break;
+ }
/* Loop until all data read */
while (read < len) {
@@ -1111,18 +1116,12 @@
case NAND_ECC_HW3_256: /* Hardware ECC 3 byte /256 byte data */
case NAND_ECC_HW3_512: /* Hardware ECC 3 byte /512 byte data */
- for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) {
- this->enable_hwecc(mtd, NAND_ECC_READ);
- this->read_buf(mtd, &data_poi[datidx], ecc);
- this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); /* read from hardware */
- }
- break;
-
case NAND_ECC_HW6_512: /* Hardware ECC 6 byte / 512 byte data */
- for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=6, datidx += ecc) {
+ case NAND_ECC_HW8_512: /* Hardware ECC 8 byte / 512 byte data */
+ for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
this->enable_hwecc(mtd, NAND_ECC_READ);
this->read_buf(mtd, &data_poi[datidx], ecc);
- this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); /* read from hardware */
+ this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
}
break;
@@ -1147,7 +1146,7 @@
ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
/* Get next chunk of ecc bytes */
- j += eccmode == NAND_ECC_HW6_512 ? 6 : 3;
+ j += eccbytes;
/* check, if we have a fs supplied oob-buffer,
* This is the legacy mode. Used by YAFFS1
@@ -2384,6 +2383,7 @@
case NAND_ECC_HW3_512:
case NAND_ECC_HW6_512:
+ case NAND_ECC_HW8_512:
if (mtd->oobblock == 256) {
printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
this->eccmode = NAND_ECC_SOFT;
@@ -2420,6 +2420,7 @@
switch (this->eccmode) {
case NAND_ECC_HW3_512:
case NAND_ECC_HW6_512:
+ case NAND_ECC_HW8_512:
this->eccsteps = mtd->oobblock / 512;
break;
case NAND_ECC_HW3_256:
More information about the linux-mtd-cvs
mailing list