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