mtd/drivers/mtd/nand nand_base.c,1.96,1.97

gleixner at infradead.org gleixner at infradead.org
Fri Jun 4 04:24:11 EDT 2004


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

Modified Files:
	nand_base.c 
Log Message:
Hardware ECC 8 Byte per 512 byte data support. Signed-off-by: Thomas Gleixner <tglx at linutronix.de>

Index: nand_base.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand_base.c,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -r1.96 -r1.97
--- nand_base.c	4 Jun 2004 07:55:44 -0000	1.96
+++ nand_base.c	4 Jun 2004 08:24:08 -0000	1.97
@@ -795,10 +795,11 @@
 	u_char *oob_buf,  struct nand_oobinfo *oobsel, int cached)
 {
 	int 	i, status;
-	u_char	ecc_code[6];
+	u_char	ecc_code[8];
 	int	eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
 	int  	*oob_config = oobsel->eccpos;
 	int	datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
+	int	eccbytes = 0;
 	
 	/* FIXME: Enable cached programming */
 	cached = 0;
@@ -825,27 +826,22 @@
 		this->write_buf(mtd, this->data_poi, mtd->oobblock);
 		break;
 		
-	/* Hardware ecc 3 byte / 256 data, write 256 byte */	
-	/* Hardware ecc 3 byte / 512 byte data, write 512 bytee */	
+	/* Hardware ecc 8 byte / 512 byte data */	
+	case NAND_ECC_HW8_512:	
+		eccbytes += 2;
+	/* Hardware ecc 6 byte / 512 byte data */	
+	case NAND_ECC_HW6_512:	
+		eccbytes += 3;
+	/* Hardware ecc 3 byte / 256 data */	
+	/* Hardware ecc 3 byte / 512 byte data */	
 	case NAND_ECC_HW3_256:		
 	case NAND_ECC_HW3_512:
+		eccbytes += 3;
 		for (; eccsteps; eccsteps--) {
 			this->enable_hwecc(mtd, NAND_ECC_WRITE);	/* enable hardware ecc logic for write */
 			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 += this->eccsize;
-		}
-		break;
-				
-	/* Hardware ecc 6 byte / 512 byte data, write 512 byte */	
-	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], this->eccsize);
-			this->calculate_ecc(mtd, NULL, ecc_code);
-			for (i = 0; i < 6; i++, eccidx++)
+			for (i = 0; i < eccbytes; i++, eccidx++)
 				oob_buf[oob_config[eccidx]] = ecc_code[i];
 			datidx += this->eccsize;
 		}
@@ -1011,11 +1007,12 @@
 	int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0;
 	struct nand_chip *this = mtd->priv;
 	u_char *data_poi, *oob_data = oob_buf;
-	u_char ecc_calc[24];
-	u_char ecc_code[24];
+	u_char ecc_calc[32];
+	u_char ecc_code[32];
         int eccmode, eccsteps;
 	int	*oob_config, datidx;
 	int	blockcheck = (mtd->erasesize >> this->page_shift) - 1;
+	int	eccbytes = 3;
 
 
 	DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
@@ -1054,6 +1051,14 @@
 
 	end = mtd->oobblock;
 	ecc = this->eccsize;
+	switch (eccmode) {
+	case NAND_ECC_HW6_512: /* Hardware ECC 6 byte / 512 byte data  */
+		eccbytes = 6;
+		break;						
+	case NAND_ECC_HW8_512: /* Hardware ECC 8 byte / 512 byte data  */
+		eccbytes = 8;
+		break;						
+	}	 
 
 	/* Loop until all data read */
 	while (read < len) {
@@ -1111,18 +1116,12 @@
 			
 		case NAND_ECC_HW3_256: /* Hardware ECC 3 byte /256 byte data */
 		case NAND_ECC_HW3_512: /* Hardware ECC 3 byte /512 byte data */	
-			for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) {
-				this->enable_hwecc(mtd, NAND_ECC_READ);	
-				this->read_buf(mtd, &data_poi[datidx], ecc);
-				this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);	/* read from hardware */
-			}
-			break;						
-
 		case NAND_ECC_HW6_512: /* Hardware ECC 6 byte / 512 byte data  */
-			for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=6, datidx += ecc) {
+		case NAND_ECC_HW8_512: /* Hardware ECC 8 byte / 512 byte data  */
+			for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
 				this->enable_hwecc(mtd, NAND_ECC_READ);	
 				this->read_buf(mtd, &data_poi[datidx], ecc);
-				this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);	/* read from hardware */
+				this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
 			}
 			break;						
 
@@ -1147,7 +1146,7 @@
 			ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
 			
 			/* Get next chunk of ecc bytes */
-			j += eccmode == NAND_ECC_HW6_512 ? 6 : 3;
+			j += eccbytes;
 			
 			/* check, if we have a fs supplied oob-buffer, 
 			 * This is the legacy mode. Used by YAFFS1
@@ -2384,6 +2383,7 @@
 
 	case NAND_ECC_HW3_512: 
 	case NAND_ECC_HW6_512: 
+	case NAND_ECC_HW8_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;
@@ -2420,6 +2420,7 @@
 	switch (this->eccmode) {
 	case NAND_ECC_HW3_512:
 	case NAND_ECC_HW6_512:
+	case NAND_ECC_HW8_512:
 		this->eccsteps = mtd->oobblock / 512;
 		break;
 	case NAND_ECC_HW3_256:





More information about the linux-mtd-cvs mailing list