mtd/drivers/mtd/nand nand.c,1.81,1.82
gleixner at infradead.org
gleixner at infradead.org
Fri Apr 30 07:43:28 EDT 2004
Update of /home/cvs/mtd/drivers/mtd/nand
In directory phoenix.infradead.org:/tmp/cvs-serv11073
Modified Files:
nand.c
Log Message:
fix cache inconstistency, fix eccsize hanlding
Index: nand.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand.c,v
retrieving revision 1.81
retrieving revision 1.82
diff -u -r1.81 -r1.82
--- nand.c 16 Apr 2004 04:12:00 -0000 1.81
+++ nand.c 30 Apr 2004 11:43:24 -0000 1.82
@@ -29,10 +29,6 @@
*
* TODO:
* Enable cached programming for 2k page size chips
- * Read aligned to ECC boundaries if we dont read page aligned
- * (May speed things up alot)
- * Check if buffering the last not aligned read can speed up
- * performance
*
* $Id$
*
@@ -628,7 +624,7 @@
this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
for (i = 0; i < 3; i++, eccidx++)
oob_buf[oob_config[eccidx]] = ecc_code[i];
- datidx += mtd->eccsize;
+ datidx += this->eccsize;
}
this->write_buf(mtd, this->data_poi, mtd->oobblock);
break;
@@ -639,11 +635,11 @@
case NAND_ECC_HW3_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], mtd->eccsize);
+ 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 += mtd->eccsize;
+ datidx += this->eccsize;
}
break;
@@ -651,11 +647,11 @@
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], mtd->eccsize);
+ this->write_buf(mtd, &this->data_poi[datidx], this->eccsize);
this->calculate_ecc(mtd, NULL, ecc_code);
for (i = 0; i < 6; i++, eccidx++)
oob_buf[oob_config[eccidx]] = ecc_code[i];
- datidx += mtd->eccsize;
+ datidx += this->eccsize;
}
break;
@@ -857,7 +853,7 @@
col = from & (mtd->oobblock - 1);
end = mtd->oobblock;
- ecc = mtd->eccsize;
+ ecc = this->eccsize;
/* Loop until all data read */
while (read < len) {
@@ -1117,8 +1113,8 @@
*/
if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
/* For subsequent page reads set offset to 0 */
- this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page);
- }
+ this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
+ }
}
}
@@ -1264,11 +1260,15 @@
}
/* Setup variables and oob buffer */
+ totalpages = len >> this->page_shift;
page = ((int) to) >> this->page_shift;
+ /* Invalidate the page cache, if we write to the cached page */
+ if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
+ this->pagebuf = -1;
+
/* Set it relative to chip */
page &= this->pagemask;
startpage = page;
- totalpages = len >> this->page_shift;
/* Calc number of pages we can write in one go */
numpages = min (ppblock - (startpage & (ppblock - 1)), totalpages);
oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages);
@@ -1276,14 +1276,14 @@
/* Loop until all data is written */
while (written < len) {
+
this->data_poi = (u_char*) &buf[written];
/* Write one page. If this is the last page to write
* or the last page in this block, then use the
* real pageprogram command, else select cached programming
* if supported by the chip.
*/
- ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel,
- (--numpages > 0));
+ ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0));
if (ret) {
DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
goto out;
@@ -1398,6 +1398,10 @@
if (nand_check_wp(mtd))
goto out;
+ /* Invalidate the page cache, if we write to the cached page */
+ if (page == this->pagebuf)
+ this->pagebuf = -1;
+
if (NAND_MUST_PAD(this)) {
/* Write out desired data */
this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask);
@@ -1528,6 +1532,10 @@
/* Setup start page */
page = ((int) to) >> this->page_shift;
+ /* Invalidate the page cache, if we write to the cached page */
+ if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->pageshift))
+ this->pagebuf = -1;
+
startpage = page & this->pagemask;
/* Loop until all iovecs' data has been written */
@@ -1686,9 +1694,14 @@
instr->state = MTD_ERASE_FAILED;
goto erase_exit;
}
+
+ /* Invalidate the page cache, if we erase the block which contains
+ the current cached page */
+ if (page >= this->pagebuf && this->pagebuf < (page + pages_per_block))
+ this->pagebuf = -1;
/* Send commands to erase a page */
- this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page);
+ this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page & this->pagemask);
this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1);
status = this->waitfunc (mtd, this, FL_ERASING);
@@ -2052,6 +2065,8 @@
printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
BUG();
}
+
+ mtd->eccsize = this->eccsize;
/* Set the number of read / write steps for one page to ensure ECC generation */
switch (this->eccmode) {
More information about the linux-mtd-cvs
mailing list