mtd/drivers/mtd/nand nand_base.c,1.155,1.156
tpoynor at infradead.org
tpoynor at infradead.org
Fri Nov 18 18:12:36 EST 2005
Update of /home/cvs/mtd/drivers/mtd/nand
In directory phoenix.infradead.org:/tmp/cvs-serv23133/drivers/mtd/nand
Modified Files:
nand_base.c
Log Message:
[MTD] NAND: Fix truncated OOB writes
The nand-layout-based code does not properly write ECC bytes to OOB when
NAND_HWECC_SYNDROME option is not set. Cleaned up some ambiguous variable
names. Fix problems on flashes with 40 bytes of ecc / page.
From: Vitaly Wool and Todd Poynor
Signed-off-by: Todd Poynor <tpoynor at mvista.com>
Index: nand_base.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand_base.c,v
retrieving revision 1.155
retrieving revision 1.156
diff -u -r1.155 -r1.156
--- nand_base.c 14 Nov 2005 06:45:25 -0000 1.155
+++ nand_base.c 18 Nov 2005 23:12:31 -0000 1.156
@@ -893,8 +893,8 @@
static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
u_char *oob_buf, struct nand_oobinfo *oobsel, int cached)
{
- int i, status;
- u_char ecc_code[32];
+ int i, oobidx, status;
+ u_char ecc_code[40];
int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
int *oob_config = oobsel->eccpos;
int datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
@@ -927,8 +927,8 @@
break;
default:
eccbytes = this->eccbytes;
- for (i = 0; eccsteps; eccsteps--) {
- int j = 0, last_datidx = datidx, last_i = i;
+ for (oobidx = 0; eccsteps; eccsteps--) {
+ int j = 0, last_datidx = datidx, last_oobidx;
for (; this->layout[j].length; j++) {
switch (this->layout[j].type) {
case ITEM_TYPE_DATA:
@@ -938,19 +938,15 @@
break;
case ITEM_TYPE_ECC:
this->enable_hwecc(mtd, NAND_ECC_WRITESYN);
- this->calculate_ecc(mtd, &this->data_poi[last_datidx], &ecc_code[i]);
- for (; i < last_i + this->layout[j].length; i++, eccidx++)
- oob_buf[oob_config[eccidx]] = ecc_code[i];
- /* If the hardware ecc provides syndromes then
- * the ecc code must be written immidiately after
- * the data bytes (words) */
- if (this->options & NAND_HWECC_SYNDROME)
- this->write_buf(mtd, ecc_code, this->layout[j].length);
+ this->calculate_ecc(mtd, &this->data_poi[last_datidx], &ecc_code[eccidx]);
+ for (last_oobidx = oobidx; oobidx < last_oobidx + this->layout[j].length; oobidx++, eccidx++)
+ oob_buf[oobidx] = ecc_code[eccidx];
+ this->write_buf(mtd, ecc_code, this->layout[j].length);
break;
case ITEM_TYPE_OOB:
this->enable_hwecc(mtd, NAND_ECC_WRITEOOB);
- this->write_buf(mtd, &oob_buf[i], this->layout[j].length);
- i += this->layout[j].length;
+ this->write_buf(mtd, &oob_buf[oobidx], this->layout[j].length);
+ oobidx += this->layout[j].length;
break;
}
}
@@ -1157,7 +1153,7 @@
{
int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1;
- int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0;
+ int read = 0, oob = 0, oobidx, ecc_status = 0, ecc_failed = 0, eccidx;
struct nand_chip *this = mtd->priv;
u_char *data_poi, *oob_data = oob_buf;
u_char ecc_calc[32];
@@ -1269,8 +1265,8 @@
break;
default:
- for (i = 0, datidx = 0; eccsteps; eccsteps--) {
- int last_datidx = datidx, last_i = i;
+ for (oobidx = 0, datidx = 0, eccidx = 0; eccsteps; eccsteps--) {
+ int last_datidx = datidx, last_oobidx = oobidx;
for (j = 0; this->layout[j].length; j++) {
switch (this->layout[j].type) {
case ITEM_TYPE_DATA:
@@ -1284,30 +1280,28 @@
DEBUG (MTD_DEBUG_LEVEL3, "%s: reading %d ecc bytes\n", __FUNCTION__, this->layout[j].length);
/* let the particular driver decide whether to read ECC */
this->enable_hwecc(mtd, NAND_ECC_READSYN);
- this->read_buf(mtd, &oob_data[i], this->layout[j].length);
+ this->read_buf(mtd, &oob_data[oobidx], this->layout[j].length);
if (!compareecc) {
-
/* We calc error correction directly, it checks the hw
* generator for an error, reads back the syndrome and
* does the error correction on the fly */
- ecc_status = this->correct_data(mtd, &data_poi[last_datidx], &oob_data[last_i], &ecc_code[last_i]);
+ ecc_status = this->correct_data(mtd, &data_poi[last_datidx], &oob_data[last_oobidx], &ecc_code[eccidx]);
if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
"Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
ecc_failed++;
}
- i += this->layout[j].length;
- } else {
- this->calculate_ecc(mtd, &data_poi[last_datidx], &ecc_calc[last_i]);
- i += this->layout[j].length;
- }
+ } else
+ this->calculate_ecc(mtd, &data_poi[last_datidx], &ecc_calc[eccidx]);
+ oobidx += this->layout[j].length;
+ eccidx += this->layout[j].length;
break;
case ITEM_TYPE_OOB:
DEBUG (MTD_DEBUG_LEVEL3, "%s: reading %d free oob bytes\n", __FUNCTION__, this->layout[j].length);
this->enable_hwecc(mtd, NAND_ECC_READOOB);
- this->read_buf(mtd, &oob_data[i], this->layout[j].length);
- i += this->layout[j].length;
+ this->read_buf(mtd, &oob_data[oobidx], this->layout[j].length);
+ oobidx += this->layout[j].length;
break;
}
}
More information about the linux-mtd-cvs
mailing list