mtd/drivers/mtd/nand nand.c,1.27,1.28

gleixner at infradead.org gleixner at infradead.org
Sat Aug 10 19:07:04 EDT 2002


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

Modified Files:
	nand.c 
Log Message:
modifications for hardware ecc support

Index: nand.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- nand.c	10 Aug 2002 07:58:07 -0000	1.27
+++ nand.c	10 Aug 2002 23:07:01 -0000	1.28
@@ -9,6 +9,7 @@
  *	http://www.linux-mtd.infradead.org/tech/nand.html
  *	
  *  Copyright (C) 2000 Steven J. Hill (sjhill at cotw.com)
+ * 		  2002 Thomas Gleixner (tglx at linutronix.de)
  *
  *  10-29-2001  Thomas Gleixner (tglx at linutronix.de)
  * 		- Changed nand_chip structure for controlline function to
@@ -67,6 +68,15 @@
  *		Fixed writing tail of data. Thanks to Alice Hennessy
  *		<ahennessy at mvista.com>.
  *
+ *  08-10-2002 	Thomas Gleixner (tglx at linutronix.de)
+ *		nand_read_ecc and nand_write_page restructured to support
+ *		hardware ECC. Thanks to Steven Hein (ssh at sgi.com)
+ *		for basic implementation and suggestions.
+ *		3 new pointers in nand_chip structure:
+ *		calculate_ecc, correct_data, enabled_hwecc 					 
+ *		forcing all hw-drivers to support page cache
+ *		eccvalid_pos is now mandatory
+ *
  * $Id$
  *
  * This program is free software; you can redistribute it and/or modify
@@ -82,13 +92,10 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ids.h>
+#include <linux/mtd/nand_ecc.h>
 #include <linux/interrupt.h>
 #include <asm/io.h>
 
-#ifdef CONFIG_MTD_NAND_ECC
-#include <linux/mtd/nand_ecc.h>
-#endif
-
 /*
  * Macros for low-level register control
  */
@@ -113,18 +120,17 @@
  */
 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,
-			  size_t * retlen, u_char * buf, u_char * ecc_code);
+			  size_t * retlen, u_char * buf, u_char * eccbuf);
 static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
 static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf);
 static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-			   size_t * retlen, const u_char * buf, u_char * ecc_code);
+			   size_t * retlen, const u_char * buf, u_char * eccbuf);
 static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf);
 static int nand_writev (struct mtd_info *mtd, const struct iovec *vecs,
 			unsigned long count, loff_t to, size_t * retlen);
 static int nand_erase (struct mtd_info *mtd, struct erase_info *instr);
 static void nand_sync (struct mtd_info *mtd);
-static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this,
-			    int page, int col, int last, u_char * ecc_code);
+static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, int col, int last);
 
 /*
  * Send command to NAND device
@@ -297,49 +303,49 @@
  *	Nand_page_program function is used for write and writev !
  */
 static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this,
-			    int page, int col, int last, u_char * ecc_code)
+			    int page, int col, int last)
 {
 
-	int i, status;
-#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
-#ifdef CONFIG_MTD_NAND_ECC
-	int ecc_bytes = (mtd->oobblock == 512) ? 6 : 3;
-#endif
-#endif
+	int 	i, status;
+	char	ecc_code[6];
+
 	/* pad oob area */
 	for (i = mtd->oobblock; i < mtd->oobblock + mtd->oobsize; i++)
 		this->data_buf[i] = 0xff;
 
-#ifdef CONFIG_MTD_NAND_ECC
-	/* Zero out the ECC array */
-	for (i = 0; i < 6; i++)
-		ecc_code[i] = 0x00;
+	/* check, if ecc is enabled */
+	if (this->eccmode != NAND_ECC_NONE) {
 
-	/* Read back previous written data, if col > 0 */
-	if (col) {
-		this->cmdfunc (mtd, NAND_CMD_READ0, col, page);
-		for (i = 0; i < col; i++)
-			this->data_buf[i] = readb (this->IO_ADDR_R);
+		/* Zero out the ECC array */
+		for (i = 0; i < 6; i++)
+			ecc_code[i] = 0x00;
+		/* Read back previous written data, if col > 0 */
+		if (col) {
+			this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
+			for (i = 0; i < col; i++)
+				this->data_buf[i] = readb (this->IO_ADDR_R);
+		}
 	}
-
-	/* Calculate and write the ECC if we have enough data */
-	if ((col < mtd->eccsize) && (last >= mtd->eccsize)) {
-		nand_calculate_ecc (&this->data_buf[0], &(ecc_code[0]));
-		for (i = 0; i < 3; i++)
-			this->data_buf[(mtd->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
-		if (oob_config.eccvalid_pos != -1)
+	
+	/* software ecc 3 Bytes ECC / 256 Byte Data ? */
+	if (this->eccmode == NAND_ECC_SOFT) {
+		/* Calculate and write the ECC if we have enough data */
+		if ((col < this->eccsize) && (last >= this->eccsize)) {
+			this->calculate_ecc (&this->data_buf[0], &(ecc_code[0]));
+			for (i = 0; i < 3; i++)
+				this->data_buf[(mtd->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
 			this->data_buf[mtd->oobblock + oob_config.eccvalid_pos] = 0xf0;
-	}
+		}
 
-	/* Calculate and write the second ECC if we have enough data */
-	if ((mtd->oobblock == 512) && (last == mtd->oobblock)) {
-		nand_calculate_ecc (&this->data_buf[256], &(ecc_code[3]));
-		for (i = 3; i < 6; i++)
-			this->data_buf[(mtd->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
-		if (oob_config.eccvalid_pos != -1)
+		/* Calculate and write the second ECC if we have enough data */
+		if ((mtd->oobblock == 512) && (last == mtd->oobblock)) {
+			this->calculate_ecc (&this->data_buf[256], &(ecc_code[3]));
+			for (i = 3; i < 6; i++)
+				this->data_buf[(mtd->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
 			this->data_buf[mtd->oobblock + oob_config.eccvalid_pos] &= 0x0f;
-	}
-#endif
+		}
+	}	
+
 	/* Prepad for partial page programming !!! */
 	for (i = 0; i < col; i++)
 		this->data_buf[i] = 0xff;
@@ -351,8 +357,59 @@
 	/* Send command to begin auto page programming */
 	this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
 
-	/* Write out complete page of data */
-	for (i = 0; i < (mtd->oobblock + mtd->oobsize); i++)
+	/* Write out complete page of data, take care of eccmode */
+	switch (this->eccmode) {
+	/* No ecc and software ecc 3/256, write all */
+	case NAND_ECC_NONE:
+	case NAND_ECC_SOFT:	
+		for (i = 0; i < mtd->oobblock ; i++)
+			writeb (this->data_buf[i], this->IO_ADDR_W);
+		break;
+	/* Hardware ecc 3 byte / 256 data, write first half, get ecc, then second, if 512 byte pagesize */	
+	case NAND_ECC_HW3_256:		
+		this->enable_hwecc (NAND_ECC_WRITE);	/* enable hardware ecc logic for write */
+		for (i = 0; i < this->eccsize ; i++)
+			writeb (this->data_buf[i], this->IO_ADDR_W);
+		
+		if ( (col == 0) && (last >= this->eccsize)) {	
+			this->calculate_ecc (&this->data_buf[0], &(ecc_code[0]));
+			for (i = 0; i < 3; i++)
+				this->data_buf[(mtd->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
+			this->data_buf[mtd->oobblock + oob_config.eccvalid_pos] = 0xf0;
+		}
+			
+		this->enable_hwecc (NAND_ECC_WRITE);	/* enable hardware ecc logic for write*/
+		for (i = this->eccsize; i < mtd->oobblock ; i++)
+			writeb (this->data_buf[i], this->IO_ADDR_W);
+
+		if ((col <= this->eccsize) && (mtd->oobblock == 512) && (last == mtd->oobblock)) {
+			this->calculate_ecc (&this->data_buf[256], &(ecc_code[3]));
+			for (i = 3; i < 6; i++)
+				this->data_buf[(mtd->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
+			this->data_buf[mtd->oobblock + oob_config.eccvalid_pos] &= 0x0f;
+		}
+		break;	
+	/* Hardware ecc 3 byte / 512 byte data, write full page */	
+	case NAND_ECC_HW3_512:	
+		this->enable_hwecc (NAND_ECC_WRITE);	/* enable hardware ecc logic */
+		for (i = 0; i < mtd->oobblock ; i++)
+			writeb (this->data_buf[i], this->IO_ADDR_W);
+
+		if ( (col == 0) && (last == mtd->oobblock)) {	
+			this->calculate_ecc (&this->data_buf[0], &(ecc_code[0]));
+			for (i = 0; i < 3; i++)
+				this->data_buf[(mtd->oobblock + oob_config.ecc_pos[i])] = ecc_code[i];
+			this->data_buf[mtd->oobblock + oob_config.eccvalid_pos] = 0xf0;
+		}
+		break;
+		
+	default:
+		printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
+		BUG();	
+	}	
+	
+	/* Write out OOB data */
+	for (i = mtd->oobblock; i < (mtd->oobblock + mtd->oobsize); i++)
 		writeb (this->data_buf[i], this->IO_ADDR_W);
 
 	/* Send command to actually program the data */
@@ -366,6 +423,7 @@
 		DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: " "Failed write, page 0x%08x, ", page);
 		return -EIO;
 	}
+
 #ifdef CONFIG_MTD_NAND_VERIFY_WRITE
 	/*
 	 * The NAND device assumes that it is always writing to
@@ -394,55 +452,58 @@
 		}
 	}
 
-#ifdef CONFIG_MTD_NAND_ECC
 	/*
 	 * We also want to check that the ECC bytes wrote
 	 * correctly for the same reasons stated above.
 	 */
-	this->cmdfunc (mtd, NAND_CMD_READOOB, 0x00, page);
-	for (i = 0; i < mtd->oobsize; i++)
-		this->data_buf[i] = readb (this->IO_ADDR_R);
-	for (i = 0; i < ecc_bytes; i++) {
-		if ((this->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) {
-			DEBUG (MTD_DEBUG_LEVEL0,
-			       "nand_write_ecc: Failed ECC write "
-			       "verify, page 0x%08x, " "%6i bytes were succesful\n", page, i);
-			return -EIO;
+	if (this->eccmode != NAND_ECC_NONE) {
+		int ecc_bytes;
+
+		switch (this->eccmode) {
+		case NAND_ECC_SOFT:
+		case NAND_ECC_HW3_256: ecc_bytes = (mtd->oobblock == 512) ? 6 : 3; break;
+		case NAND_ECC_HW3_512: ecc_bytes = 3; break;
+		}
+
+		this->cmdfunc (mtd, NAND_CMD_READOOB, 0x00, page);
+		for (i = 0; i < mtd->oobsize; i++)
+			this->data_buf[i] = readb (this->IO_ADDR_R);
+	
+		for (i = 0; i < ecc_bytes; i++) {
+			if ((this->data_buf[(oob_config.ecc_pos[i])] != ecc_code[i]) && ecc_code[i]) {
+				DEBUG (MTD_DEBUG_LEVEL0,
+				       "nand_write_ecc: Failed ECC write "
+				       "verify, page 0x%08x, " "%6i bytes were succesful\n", page, i);
+				return -EIO;
+			}
 		}
 	}
 #endif
-#endif
 	return 0;
 }
 
 /*
- * NAND read
- */
+*	Use NAND read ECC
+*/
 static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
 {
-#ifdef CONFIG_MTD_NAND_ECC
-	struct nand_chip *this = mtd->priv;
+	return (nand_read_ecc (mtd, from, len, retlen, buf, NULL));
+}			   
 
-	return nand_read_ecc (mtd, from, len, retlen, buf, this->ecc_code_buf);
-#else
-	return nand_read_ecc (mtd, from, len, retlen, buf, NULL);
-#endif
-}
 
 /*
  * NAND read with ECC
  */
 static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-			  size_t * retlen, u_char * buf, u_char * ecc_code)
+			  size_t * retlen, u_char * buf, u_char * eccbuf)
 {
 	int j, col, page;
 	int erase_state = 0;
 	int ecc_status = 0, ecc_failed = 0;
 	struct nand_chip *this = mtd->priv;
 	u_char *data_poi;
-#ifdef CONFIG_MTD_NAND_ECC
 	u_char ecc_calc[6];
-#endif
+	u_char ecc_code[6];
 
 	DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
 
@@ -470,51 +531,76 @@
 
 	/* Loop until all data read */
 	while (*retlen < len) {
-
-#ifdef CONFIG_MTD_NAND_ECC
-
 		/* Do we have this page in cache ? */
 		if (this->cache_page == page)
 			goto readdata;
-
+			
 		/* Send the read command */
 		this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
-		/* Read in a page + oob data */
-		for (j = 0; j < mtd->oobblock + mtd->oobsize; j++)
-			this->data_buf[j] = readb (this->IO_ADDR_R);
-		this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
+				
+		switch (this->eccmode) {
+		case NAND_ECC_NONE:	/* No ECC, Read in a page */		
+		case NAND_ECC_SOFT:	/* Software ECC 3/256: Read in a page + oob data */
+			for (j = 0; j < mtd->oobblock; j++)
+				this->data_buf[j] = readb (this->IO_ADDR_R);
+			break;	
+			
+		case NAND_ECC_HW3_256: /* Hardware ECC 3 byte /256 byte data: Read in first 256 byte, get ecc, read second, if pagesize = 512 */
+			this->enable_hwecc (NAND_ECC_READ);	
+			for (j = 0; j < this->eccsize; j++)
+				this->data_buf[j] = readb (this->IO_ADDR_R);
+			this->calculate_ecc (&this->data_buf[0], &ecc_calc[0]);	/* read from hardware */
+
+			this->enable_hwecc (NAND_ECC_READ);	
+			for (j = this->eccsize; j < mtd->oobblock; j++)
+				this->data_buf[j] = readb (this->IO_ADDR_R);
+			this->calculate_ecc (&this->data_buf[256], &ecc_calc[3]); /* read from hardware */	
+			break;						
+				
+		case NAND_ECC_HW3_512: /* Hardware ECC 3 byte / 512 byte data : Read in a page + oob data */
+			this->enable_hwecc (NAND_ECC_READ);	
+			for (j = 0; j < mtd->oobblock; j++)
+				this->data_buf[j] = readb (this->IO_ADDR_R);
+			this->calculate_ecc (&this->data_buf[0], &ecc_calc[0]);	/* read from hardware */
+			break;
+		default:
+			printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
+			BUG();	
+		}
 
+		/* read back oobdata */
+		for (j = mtd->oobblock; j < (mtd->oobblock + mtd->oobsize); j++)
+			this->data_buf[j] = readb (this->IO_ADDR_R);
 		/* copy data into cache, for read out of cache and if ecc fails */
-		if (this->data_cache)
-			memcpy (this->data_cache, this->data_buf, mtd->oobblock + mtd->oobsize);
-
+		memcpy (this->data_cache, this->data_buf, mtd->oobblock + mtd->oobsize);
+		/* Skip ECC, if not active */
+		if (this->eccmode == NAND_ECC_NONE)
+			goto readdata;	
 		/* Pick the ECC bytes out of the oob data */
 		for (j = 0; j < 6; j++)
 			ecc_code[j] = this->data_buf[(mtd->oobblock + oob_config.ecc_pos[j])];
-
 		/* Calculate the ECC and verify it */
 		/* If block was not written with ECC, skip ECC */
-		if (oob_config.eccvalid_pos != -1 &&
-		    (this->data_buf[mtd->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) {
+		if ((this->data_buf[mtd->oobblock + oob_config.eccvalid_pos] & 0x0f) != 0x0f) {
 
-			nand_calculate_ecc (&this->data_buf[0], &ecc_calc[0]);
-			switch (nand_correct_data (&this->data_buf[0], &ecc_code[0], &ecc_calc[0])) {
+			if (this->eccmode == NAND_ECC_SOFT)
+				this->calculate_ecc (&this->data_buf[0], &ecc_calc[0]);
+			switch (this->correct_data (&this->data_buf[0], &ecc_code[0], &ecc_calc[0])) {
 			case -1:
 				DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
 				ecc_failed++;
 				break;
 			case 1:
 			case 2:	/* transfer ECC corrected data to cache */
-				memcpy (this->data_cache, this->data_buf, 256);
+				memcpy (this->data_cache, this->data_buf, this->eccmode == NAND_ECC_HW3_512 ? 512 : 256);
 				break;
 			}
 		}
-
-		if (oob_config.eccvalid_pos != -1 &&
-		    mtd->oobblock == 512 && (this->data_buf[mtd->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) {
-
-			nand_calculate_ecc (&this->data_buf[256], &ecc_calc[3]);
-			switch (nand_correct_data (&this->data_buf[256], &ecc_code[3], &ecc_calc[3])) {
+		if ( (mtd->oobblock == 512) && (this->data_buf[mtd->oobblock + oob_config.eccvalid_pos] & 0xf0) != 0xf0) {
+	
+			if (this->eccmode == NAND_ECC_SOFT)
+				this->calculate_ecc (&this->data_buf[256], &ecc_calc[3]);
+			switch (this->correct_data (&this->data_buf[256], &ecc_code[3], &ecc_calc[3])) {
 			case -1:
 				DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
 				ecc_failed++;
@@ -526,9 +612,10 @@
 				break;
 			}
 		}
+
 readdata:
 		/* Read the data from ECC data buffer into return buffer */
-		data_poi = (this->data_cache) ? this->data_cache : this->data_buf;
+		data_poi = this->data_cache;
 		data_poi += col;
 		if ((*retlen + (mtd->oobblock - col)) >= len) {
 			while (*retlen < len)
@@ -538,25 +625,10 @@
 				buf[(*retlen)++] = *data_poi++;
 		}
 		/* Set cache page address, invalidate, if ecc_failed */
-		this->cache_page = (this->data_cache && !ecc_failed) ? page : -1;
-
+		this->cache_page = !ecc_failed ? page : -1;
 		ecc_status += ecc_failed;
 		ecc_failed = 0;
 
-#else
-		/* Send the read command */
-		this->cmdfunc (mtd, NAND_CMD_READ0, col, page);
-
-		/* Read the data directly into the return buffer */
-		if ((*retlen + (mtd->oobblock - col)) >= len) {
-			while (*retlen < len)
-				buf[(*retlen)++] = readb (this->IO_ADDR_R);
-			/* We're done */
-			continue;
-		} else
-			for (j = col; j < mtd->oobblock; j++)
-				buf[(*retlen)++] = readb (this->IO_ADDR_R);
-#endif
 		/* For subsequent reads align to page boundary. */
 		col = 0;
 		/* Increment page address */
@@ -646,24 +718,17 @@
 }
 
 /*
- * NAND write
- */
+*	Use NAND write ECC
+*/
 static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
 {
-#ifdef CONFIG_MTD_NAND_ECC
-	struct nand_chip *this = mtd->priv;
-
-	return nand_write_ecc (mtd, to, len, retlen, buf, this->ecc_code_buf);
-#else
-	return nand_write_ecc (mtd, to, len, retlen, buf, NULL);
-#endif
-}
-
+	return (nand_write_ecc (mtd, to, len, retlen, buf, NULL));
+}			   
 /*
  * NAND write with ECC
  */
 static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-			   size_t * retlen, const u_char * buf, u_char * ecc_code)
+			   size_t * retlen, const u_char * buf, u_char * eccbuf)
 {
 	int i, page, col, cnt, ret = 0;
 	struct nand_chip *this = mtd->priv;
@@ -714,7 +779,7 @@
 				this->data_buf[i] = buf[(*retlen + cnt)];
 
 		/* We use the same function for write and writev !) */
-		ret = nand_write_page (mtd, this, page, col, i, ecc_code);
+		ret = nand_write_page (mtd, this, page, col, i);
 		if (ret)
 			goto out;
 
@@ -914,7 +979,7 @@
 		}
 
 		/* We use the same function for write and writev !) */
-		ret = nand_write_page (mtd, this, page, col, cnt, this->ecc_code_buf);
+		ret = nand_write_page (mtd, this, page, col, cnt);
 		if (ret)
 			goto out;
 
@@ -1139,6 +1204,9 @@
 	if (this->waitfunc == NULL)
 		this->waitfunc = nand_wait;
 
+	/* make sure, that cache page is invalid */
+	this->cache_page = -1;
+
 	/* Select the device */
 	nand_select ();
 
@@ -1173,6 +1241,48 @@
 		}
 	}
 
+	/* 
+	 * check ECC mode, default to software
+	 * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
+	 * fallback to software ECC 
+	*/
+#ifdef CONFIG_MTD_NAND_ECC	
+	this->eccsize = 256;	/* set default eccsize */	
+
+	switch (this->eccmode) {
+
+	case NAND_ECC_HW3_512: 
+		if (mtd->oobblock == 256) {
+			printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
+			this->eccmode = NAND_ECC_SOFT;
+			this->calculate_ecc = nand_calculate_ecc;
+			this->correct_data = nand_correct_data;
+			break;		
+		} else 
+			this->eccsize = 512; /* set eccsize to 512 and fall through for function check */
+
+	case NAND_ECC_HW3_256:
+		if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
+			break;
+		printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
+		BUG();	
+
+	case NAND_ECC_NONE: 
+		this->eccmode = NAND_ECC_SOFT;
+
+	case NAND_ECC_SOFT:	
+		this->calculate_ecc = nand_calculate_ecc;
+		this->correct_data = nand_correct_data;
+		break;
+
+	default:
+		printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
+		BUG();	
+	}	
+#else
+	this->eccmode = ECC_NONE;
+#endif
+
 	/* Initialize state, waitqueue and spinlock */
 	this->state = FL_READY;
 	init_waitqueue_head (&this->wq);
@@ -1190,8 +1300,8 @@
 	oob_config.ecc_pos[3] = NAND_JFFS2_OOB_ECCPOS3;
 	oob_config.ecc_pos[4] = NAND_JFFS2_OOB_ECCPOS4;
 	oob_config.ecc_pos[5] = NAND_JFFS2_OOB_ECCPOS5;
-	oob_config.badblock_pos = NAND_FORCE_BADBPOS;
-	oob_config.eccvalid_pos = 4;
+	oob_config.badblock_pos = NAND_JFFS2_OOB_BADBPOS;
+	oob_config.eccvalid_pos = NAND_JFFS2_OOB_ECCVPOS;
 #else
 	oob_config.ecc_pos[0] = NAND_NOOB_ECCPOS0;
 	oob_config.ecc_pos[1] = NAND_NOOB_ECCPOS1;
@@ -1199,7 +1309,7 @@
 	oob_config.ecc_pos[3] = NAND_NOOB_ECCPOS3;
 	oob_config.ecc_pos[4] = NAND_NOOB_ECCPOS4;
 	oob_config.ecc_pos[5] = NAND_NOOB_ECCPOS5;
-	oob_config.badblock_pos = NAND_FORCE_BADBPOS;
+	oob_config.badblock_pos = NAND_NOOB_BADBPOS;
 	oob_config.eccvalid_pos = NAND_NOOB_ECCVPOS;
 #endif
 





More information about the linux-mtd-cvs mailing list