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