mtd/drivers/mtd/nand nand_base.c,1.121,1.122
gleixner at infradead.org
gleixner at infradead.org
Mon Nov 1 15:04:01 EST 2004
Update of /home/cvs/mtd/drivers/mtd/nand
In directory phoenix.infradead.org:/tmp/cvs-serv31718/drivers/mtd/nand
Modified Files:
nand_base.c
Log Message:
Cleanup HW-ECC. Calc ecc bytes during setup. Add HW12_2048 ECC mode (Initial Patch provided by Juha Yrjola <juha.yrjola at nokia.com>)
Index: nand_base.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand_base.c,v
retrieving revision 1.121
retrieving revision 1.122
diff -u -r1.121 -r1.122
--- nand_base.c 6 Oct 2004 19:53:11 -0000 1.121
+++ nand_base.c 1 Nov 2004 20:03:57 -0000 1.122
@@ -840,18 +840,8 @@
}
this->write_buf(mtd, this->data_poi, mtd->oobblock);
break;
-
- /* 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;
+ default:
+ eccbytes = this->ecc_bytes;
for (; eccsteps; eccsteps--) {
/* enable hardware ecc logic for write */
this->enable_hwecc(mtd, NAND_ECC_WRITE);
@@ -864,14 +854,9 @@
* the data bytes (words) */
if (this->options & NAND_HWECC_SYNDROME)
this->write_buf(mtd, ecc_code, eccbytes);
-
datidx += this->eccsize;
}
break;
-
- default:
- printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
- BUG();
}
/* Write out OOB data */
@@ -1051,7 +1036,7 @@
int eccmode, eccsteps;
int *oob_config, datidx;
int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
- int eccbytes = 3;
+ int eccbytes;
int compareecc = 1;
int oobreadlen;
@@ -1092,19 +1077,9 @@
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;
- case NAND_ECC_NONE:
- compareecc = 0;
- break;
- }
-
- if (this->options & NAND_HWECC_SYNDROME)
+ eccbytes = this->eccbytes;
+
+ if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
compareecc = 0;
oobreadlen = mtd->oobsize;
@@ -1164,13 +1139,10 @@
for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc)
this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
break;
-
- case NAND_ECC_HW3_256: /* Hardware ECC 3 byte /256 byte data */
- case NAND_ECC_HW3_512: /* Hardware ECC 3 byte /512 byte data */
- case NAND_ECC_HW6_512: /* Hardware ECC 6 byte / 512 byte data */
- case NAND_ECC_HW8_512: /* Hardware ECC 8 byte / 512 byte data */
+
+ default:
for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
- this->enable_hwecc(mtd, NAND_ECC_READ);
+ this->enable_hwecc(mtd, NAND_ECC_READ);
this->read_buf(mtd, &data_poi[datidx], ecc);
/* HW ecc with syndrome calculation must read the
@@ -1193,10 +1165,6 @@
}
}
break;
-
- default:
- printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
- BUG();
}
/* read oobdata */
@@ -2433,8 +2401,19 @@
* fallback to software ECC
*/
this->eccsize = 256; /* set default eccsize */
+ this->eccbytes = 3;
switch (this->eccmode) {
+ case NAND_ECC_HW12_2048:
+ if (mtd->oobblock < 2048) {
+ printk(KERN_WARNING "2048 byte HW ECC not possible on %d byte page size, fallback to SW ECC\n",
+ mtd->oobblock);
+ this->eccmode = NAND_ECC_SOFT;
+ this->calculate_ecc = nand_calculate_ecc;
+ this->correct_data = nand_correct_data;
+ } else
+ this->eccsize = 2048;
+ break;
case NAND_ECC_HW3_512:
case NAND_ECC_HW6_512:
@@ -2444,16 +2423,13 @@
this->eccmode = NAND_ECC_SOFT;
this->calculate_ecc = nand_calculate_ecc;
this->correct_data = nand_correct_data;
- break;
} else
- this->eccsize = 512; /* set eccsize to 512 and fall through for function check */
-
+ this->eccsize = 512; /* set eccsize to 512 */
+ break;
+
case NAND_ECC_HW3_256:
- if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
- break;
- printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
- BUG();
-
+ break;
+
case NAND_ECC_NONE:
printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
this->eccmode = NAND_ECC_NONE;
@@ -2468,11 +2444,32 @@
printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
BUG();
}
-
+
+ /* Check hardware ecc function availability and adjust number of ecc bytes per
+ * calculation step
+ */
+ switch (this->eccmode) {
+ case NAND_ECC_HW12_2048:
+ this->eccbytes += 4;
+ case NAND_ECC_HW8_512:
+ this->eccbytes += 2;
+ case NAND_ECC_HW6_512:
+ this->eccbytes += 3;
+ case NAND_ECC_HW3_512:
+ case NAND_ECC_HW3_256:
+ if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
+ break;
+ printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
+ BUG();
+ }
+
mtd->eccsize = this->eccsize;
/* Set the number of read / write steps for one page to ensure ECC generation */
switch (this->eccmode) {
+ case NAND_ECC_HW12_2048:
+ this->eccsteps = mtd->oobblock / 2048;
+ break;
case NAND_ECC_HW3_512:
case NAND_ECC_HW6_512:
case NAND_ECC_HW8_512:
More information about the linux-mtd-cvs
mailing list