mtd/drivers/mtd/nand nand_base.c,1.121,1.122

gleixner at infradead.org gleixner at infradead.org
Mon Nov 1 15:04:01 EST 2004


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

Modified Files:
	nand_base.c 
Log Message:
Cleanup HW-ECC. Calc ecc bytes during setup. Add HW12_2048 ECC mode (Initial Patch provided by Juha Yrjola <juha.yrjola at nokia.com>)

Index: nand_base.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/nand_base.c,v
retrieving revision 1.121
retrieving revision 1.122
diff -u -r1.121 -r1.122
--- nand_base.c	6 Oct 2004 19:53:11 -0000	1.121
+++ nand_base.c	1 Nov 2004 20:03:57 -0000	1.122
@@ -840,18 +840,8 @@
 		}
 		this->write_buf(mtd, this->data_poi, mtd->oobblock);
 		break;
-		
-	/* 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;
+	default:
+		eccbytes = this->ecc_bytes;
 		for (; eccsteps; eccsteps--) {
 			/* enable hardware ecc logic for write */
 			this->enable_hwecc(mtd, NAND_ECC_WRITE);
@@ -864,14 +854,9 @@
 			 * the data bytes (words) */
 			if (this->options & NAND_HWECC_SYNDROME)
 				this->write_buf(mtd, ecc_code, eccbytes);
-
 			datidx += this->eccsize;
 		}
 		break;
-
-	default:
-		printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
-		BUG();	
 	}
 										
 	/* Write out OOB data */
@@ -1051,7 +1036,7 @@
         int eccmode, eccsteps;
 	int	*oob_config, datidx;
 	int	blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
-	int	eccbytes = 3;
+	int	eccbytes;
 	int	compareecc = 1;
 	int	oobreadlen;
 
@@ -1092,19 +1077,9 @@
 
 	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;
-	case NAND_ECC_NONE:
-		compareecc = 0;
-		break;						
-	}	 
-
-	if (this->options & NAND_HWECC_SYNDROME)
+	eccbytes = this->eccbytes;
+	
+	if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
 		compareecc = 0;
 
 	oobreadlen = mtd->oobsize;
@@ -1164,13 +1139,10 @@
 			for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) 
 				this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
 			break;	
-			
-		case NAND_ECC_HW3_256: /* Hardware ECC 3 byte /256 byte data */
-		case NAND_ECC_HW3_512: /* Hardware ECC 3 byte /512 byte data */	
-		case NAND_ECC_HW6_512: /* Hardware ECC 6 byte / 512 byte data  */
-		case NAND_ECC_HW8_512: /* Hardware ECC 8 byte / 512 byte data  */
+
+		default:
 			for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
-				this->enable_hwecc(mtd, NAND_ECC_READ);	
+				this->enable_hwecc(mtd, NAND_ECC_READ);
 				this->read_buf(mtd, &data_poi[datidx], ecc);
 
 				/* HW ecc with syndrome calculation must read the
@@ -1193,10 +1165,6 @@
 				}	
 			}
 			break;						
-
-		default:
-			printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
-			BUG();	
 		}
 
 		/* read oobdata */
@@ -2433,8 +2401,19 @@
 	 * fallback to software ECC 
 	*/
 	this->eccsize = 256;	/* set default eccsize */	
+	this->eccbytes = 3;
 
 	switch (this->eccmode) {
+	case NAND_ECC_HW12_2048:
+		if (mtd->oobblock < 2048) {
+			printk(KERN_WARNING "2048 byte HW ECC not possible on %d byte page size, fallback to SW ECC\n",
+			       mtd->oobblock);
+			this->eccmode = NAND_ECC_SOFT;
+			this->calculate_ecc = nand_calculate_ecc;
+			this->correct_data = nand_correct_data;
+		} else
+			this->eccsize = 2048;
+		break;
 
 	case NAND_ECC_HW3_512: 
 	case NAND_ECC_HW6_512: 
@@ -2444,16 +2423,13 @@
 			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 */
-
+			this->eccsize = 512; /* set eccsize to 512 */
+		break;
+			
 	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();	
-
+		break;
+		
 	case NAND_ECC_NONE: 
 		printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
 		this->eccmode = NAND_ECC_NONE;
@@ -2468,11 +2444,32 @@
 		printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
 		BUG();	
 	}	
-	
+
+	/* Check hardware ecc function availability and adjust number of ecc bytes per 
+	 * calculation step
+	*/
+	switch (this->eccmode) {
+	case NAND_ECC_HW12_2048:
+		this->eccbytes += 4;
+	case NAND_ECC_HW8_512: 
+		this->eccbytes += 2;
+	case NAND_ECC_HW6_512: 
+		this->eccbytes += 3;
+	case NAND_ECC_HW3_512: 
+	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();	
+	}
+		
 	mtd->eccsize = this->eccsize;
 	
 	/* Set the number of read / write steps for one page to ensure ECC generation */
 	switch (this->eccmode) {
+	case NAND_ECC_HW12_2048:
+		this->eccsteps = mtd->oobblock / 2048;
+		break;
 	case NAND_ECC_HW3_512:
 	case NAND_ECC_HW6_512:
 	case NAND_ECC_HW8_512:





More information about the linux-mtd-cvs mailing list