mtd/drivers/mtd/nand nand.c,1.50,1.51

David Woodhouse dwmw2 at infradead.org
Thu Jul 3 06:38:15 EDT 2003


Update of /home/cvs/mtd/drivers/mtd/nand
In directory phoenix.infradead.org:/tmp/cvs-serv8621

Modified Files:
	nand.c 
Log Message:
Add support for device-specific block_bad() method, rather than unconditionally
checking NAND_BADBLOCK_POS.

Reset chip before write_oob. I wish I knew why :)

Fix endless loop in read_oob.


Index: nand.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -r1.50 -r1.51
--- nand.c	2 Jul 2003 13:09:00 -0000	1.50
+++ nand.c	3 Jul 2003 10:38:12 -0000	1.51
@@ -156,7 +156,7 @@
  */
 static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len);
 static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
-static int nand_verify_buf(struct mtd_info *mtd, u_char *buf, int len);
+static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len);
 
 static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
 static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
@@ -213,7 +213,7 @@
 		buf[i] = readb(this->IO_ADDR_R);
 }
 
-static int nand_verify_buf(struct mtd_info *mtd, u_char *buf, int len)
+static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
 {
 	int i;
 	struct nand_chip *this = mtd->priv;
@@ -225,6 +225,18 @@
 	return 0;
 }
 
+/* Appropriate chip should already be selected */
+static int nand_block_bad(struct mtd_info *mtd, unsigned long page)
+{
+	struct nand_chip *this = mtd->priv;
+	
+	this->cmdfunc (mtd, NAND_CMD_READOOB, NAND_BADBLOCK_POS, page);
+	if (this->read_byte(mtd) != 0xff)
+		return 1;
+
+	return 0;
+}
+
 /*
  * Send command to NAND device
  */
@@ -568,7 +580,7 @@
 */
 static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
 {
-	return (nand_read_ecc (mtd, from, len, retlen, buf, NULL, NULL));
+	return nand_read_ecc (mtd, from, len, retlen, buf, NULL, NULL);
 }			   
 
 
@@ -794,7 +806,9 @@
 	i = 0;
 	while (i < len) {
 		int thislen = (mtd->oobsize - col) & (mtd->oobsize - 1);
-
+		if (!thislen)
+			thislen = mtd->oobsize;
+		thislen = min_t(int, thislen, len);
 		this->read_buf(mtd, &buf[i], thislen);
 		i += thislen;
 		col += thislen;
@@ -938,6 +952,13 @@
 	/* Select the NAND device */
 	this->select_chip(mtd, 0);
 
+	/* Reset the chip. Some chips (like the Toshiba TC5832DC found
+	   in one of my DiskOnChip 2000 test units) will clear the whole
+	   data page too if we don't do this. I have no clue why, but
+	   I seem to have 'fixed' it in the doc2000 driver in
+	   August 1999.  dwmw2. */
+	this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+
 	/* Check the WP bit */
 	this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
 	if (!(this->read_byte(mtd) & 0x80)) {
@@ -945,9 +966,9 @@
 		ret = -EIO;
 		goto out;
 	}
-
 	/* Write out desired data */
 	this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page);
+
 	/* prepad 0xff for partial programming */
 	this->write_buf(mtd, ffchars, column);
 	/* write data */
@@ -1174,8 +1195,7 @@
 
 	while (len) {
 		/* Check if we have a bad block, we do not erase bad blocks ! */
-		this->cmdfunc (mtd, NAND_CMD_READOOB, NAND_BADBLOCK_POS, page);
-		if (this->read_byte(mtd) != 0xff) {
+		if (this->block_bad(mtd, page)) {
 			printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page);
 			instr->state = MTD_ERASE_FAILED;
 			goto erase_exit;
@@ -1308,6 +1328,8 @@
 	if (this->waitfunc == NULL)
 		this->waitfunc = nand_wait;
 
+	if (!this->block_bad)
+		this->block_bad = nand_block_bad;
 	if (!this->select_chip)
 		this->select_chip = nand_select_chip;
 	if (!this->write_byte)
@@ -1352,7 +1374,7 @@
 				if (nand_manuf_ids[i].id == nand_maf_id)
 					break;
 			}	
-			printk (KERN_INFO "NAND device: Manufacture ID:"
+			printk (KERN_INFO "NAND device: Manufacturer ID:"
 				" 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, 
 				nand_manuf_ids[i].name , mtd->name);
 			break;




More information about the linux-mtd-cvs mailing list