mtd/fs/jffs2 wbuf.c,1.31,1.32

David Woodhouse dwmw2 at infradead.org
Mon Jun 30 10:36:50 EDT 2003


Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv11465/fs/jffs2

Modified Files:
	wbuf.c 
Log Message:
Clean up NAND ECC switches -- do it once only during mount, fail if
there's an ECC type we don't grok, etc. 


Index: wbuf.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/wbuf.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- wbuf.c	30 Jun 2003 10:58:58 -0000	1.31
+++ wbuf.c	30 Jun 2003 14:36:47 -0000	1.32
@@ -24,23 +24,6 @@
 /* two seconds timeout for timed wbuf-flushing */
 #define WBUF_FLUSH_TIMEOUT	2 * HZ
 
-#define JFFS2_OOB_ECCPOS0		0
-#define JFFS2_OOB_ECCPOS1		1
-#define JFFS2_OOB_ECCPOS2		2
-#define JFFS2_OOB_ECCPOS3		3
-#define JFFS2_OOB_ECCPOS4		6
-#define JFFS2_OOB_ECCPOS5		7
-
-#define NAND_JFFS2_OOB8_FSDAPOS		6
-#define NAND_JFFS2_OOB16_FSDAPOS	8
-#define NAND_JFFS2_OOB8_FSDALEN		2
-#define NAND_JFFS2_OOB16_FSDALEN	8
-
-struct nand_oobinfo jffs2_oobinfo = {
-	useecc: 1,
-	eccpos: {JFFS2_OOB_ECCPOS0, JFFS2_OOB_ECCPOS1, JFFS2_OOB_ECCPOS2, JFFS2_OOB_ECCPOS3, JFFS2_OOB_ECCPOS4, JFFS2_OOB_ECCPOS5}
-};
-
 static inline void jffs2_refile_wbuf_blocks(struct jffs2_sb_info *c)
 {
 	struct list_head *this, *next;
@@ -179,7 +162,7 @@
 	/* else jffs2_flash_writev has actually filled in the rest of the
 	   buffer for us, and will deal with the node refs etc. later. */
 	
-	ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, &jffs2_oobinfo);
+	ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, c->oobinfo);
 	
 	if (ret || retlen != c->wbuf_pagesize) {
 		if (ret)
@@ -396,7 +379,7 @@
 		outvecs[splitvec].iov_len = split_ofs;
 
 		/* We did cross a page boundary, so we write some now */
-		ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, &jffs2_oobinfo); 
+		ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo); 
 		if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) {
 			/* At this point we have no problem,
 			   c->wbuf is empty. 
@@ -469,7 +452,7 @@
 
 	/* Read flash */
 	if (!jffs2_can_mark_obsolete(c)) {
-		ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, &jffs2_oobinfo);
+		ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
 
 		if ( (ret == -EIO) && (*retlen == len) ) {
 			printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
@@ -527,20 +510,10 @@
 	int 	ret = 0;
 	int	i,len,cnt,page;
 	size_t  retlen;
-	int	fsdata_pos,badblock_pos,oob_size;
+	int	oob_size;
 
 	oob_size = c->mtd->oobsize;
 
-	switch(c->mtd->ecctype) {
-	case MTD_ECC_SW:		
-		fsdata_pos = (c->wbuf_pagesize == 256) ? NAND_JFFS2_OOB8_FSDAPOS : NAND_JFFS2_OOB16_FSDAPOS;
-		badblock_pos = NAND_BADBLOCK_POS;
-		break;
-	default:
-		D1(printk(KERN_WARNING "jffs2_write_oob_empty(): Invalid ECC type\n"));
-		return -EINVAL;
-	}	
-
 	/* allocate a buffer for all oob data in this sector */
 	len = 4 * oob_size;
 	buf = kmalloc(len, GFP_KERNEL);
@@ -568,7 +541,7 @@
 	/* Special check for first two pages */
 	for (page = 0; page < 2 * oob_size; page += oob_size) {
 		/* Check for bad block marker */
-		if (buf[page+badblock_pos] != 0xff) {
+		if (buf[page+c->badblock_pos] != 0xff) {
 			D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Bad or failed block at %08x\n",jeb->offset));
 			/* Return 2 for bad and 3 for failed block 
 			   bad goes to list_bad and failed to list_erase */
@@ -577,7 +550,7 @@
 		}
 		cnt = oob_size;
 		if (mode)
-			cnt -= fsdata_pos;
+			cnt -= c->fsdata_pos;
 		for(i = 0; i < cnt ; i+=sizeof(unsigned short)) {
 			unsigned short dat = *(unsigned short *)(&buf[page+i]);
 			if(dat != 0xffff) {
@@ -617,23 +590,11 @@
 	unsigned char *p;
 	int ret, i, cnt, retval = 0;
 	size_t retlen, offset;
-	int fsdata_pos, fsdata_len, oob_size, badblock_pos;
+	int oob_size;
 
 	offset = jeb->offset;
 	oob_size = c->mtd->oobsize;
 
-	switch (c->mtd->ecctype) {
-	case MTD_ECC_SW:
-		fsdata_pos = (c->wbuf_pagesize == 256) ? NAND_JFFS2_OOB8_FSDAPOS : NAND_JFFS2_OOB16_FSDAPOS;
-		fsdata_len = (c->wbuf_pagesize == 256) ? NAND_JFFS2_OOB8_FSDALEN : NAND_JFFS2_OOB16_FSDALEN;
-		badblock_pos = NAND_BADBLOCK_POS;
-		break;
-	default:
-		D1 (printk (KERN_WARNING "jffs2_write_nand_cleanmarker(): Invalid ECC type\n"));
-		return -EINVAL;
-	}
-
-
 	/* Loop through the physical blocks */
 	for (cnt = 0; cnt < (c->sector_size / c->mtd->erasesize); cnt++) {
 		/*
@@ -653,14 +614,14 @@
 		}
 
 		/* Check for bad block marker */
-		if (buf[badblock_pos] != 0xff) {
+		if (buf[c->badblock_pos] != 0xff) {
 			D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Bad block at %08x\n", jeb->offset));
 			return 2;
 		}
 
 		/* Check for failure counter in the second page */
-		if (buf[badblock_pos + oob_size] != 0xff) {
-			D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Block marked as failed at %08x, fail count:%d\n", jeb->offset, buf[badblock_pos + oob_size]));
+		if (buf[c->badblock_pos + oob_size] != 0xff) {
+			D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Block marked as failed at %08x, fail count:%d\n", jeb->offset, buf[c->badblock_pos + oob_size]));
 			return 3;
 		}
 
@@ -671,8 +632,8 @@
 			n.totlen = cpu_to_je32 (8);
 			p = (unsigned char *) &n;
 
-			for (i = 0; i < fsdata_len; i++) {
-				if (buf[fsdata_pos + i] != p[i]) {
+			for (i = 0; i < c->fsdata_len; i++) {
+				if (buf[c->fsdata_pos + i] != p[i]) {
 					D2 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Cleanmarker node not detected in block at %08x\n", jeb->offset));
 					retval = 1;
 				}
@@ -687,31 +648,20 @@
 {
 	struct 	jffs2_unknown_node n;
 	int 	ret;
-	int	fsdata_pos,fsdata_len;
 	size_t 	retlen;
 
-	switch(c->mtd->ecctype) {
-	case MTD_ECC_SW:	
-		fsdata_pos = (c->wbuf_pagesize == 256) ? NAND_JFFS2_OOB8_FSDAPOS : NAND_JFFS2_OOB16_FSDAPOS;
-		fsdata_len = (c->wbuf_pagesize == 256) ? NAND_JFFS2_OOB8_FSDALEN : NAND_JFFS2_OOB16_FSDALEN;
-		break;
-	default:
-		D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Invalid ECC type\n"));
-		return -EINVAL;
-	}	
-	
 	n.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
 	n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
 	n.totlen = cpu_to_je32(8);
 
-	ret = jffs2_flash_write_oob(c, jeb->offset + fsdata_pos, fsdata_len, &retlen, (unsigned char *)&n);
+	ret = jffs2_flash_write_oob(c, jeb->offset + c->fsdata_pos, c->fsdata_len, &retlen, (unsigned char *)&n);
 	
 	if (ret) {
 		D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
 		return ret;
 	}
-	if (retlen != fsdata_len) {
-		D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Short write for block at %08x: %zd not %d\n", jeb->offset, retlen, fsdata_len));
+	if (retlen != c->fsdata_len) {
+		D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Short write for block at %08x: %zd not %d\n", jeb->offset, retlen, c->fsdata_len));
 		return ret;
 	}
 	return 0;
@@ -725,18 +675,9 @@
 	unsigned char buf[16];
 	int	ret;
 	size_t 	retlen;
-	int	oob_size, badblock_pos;
+	int	oob_size;
 
 	oob_size = c->mtd->oobsize;
-
-	switch(c->mtd->ecctype) {
-	case MTD_ECC_SW:	
-		badblock_pos = NAND_BADBLOCK_POS;
-		break;
-	default:
-		D1(printk(KERN_WARNING "jffs2_nand_read_failcnt(): Invalid ECC type\n"));
-		return -EINVAL;
-	}	
 	
 	ret = c->mtd->read_oob(c->mtd, jeb->offset + c->mtd->oobblock, oob_size , &retlen, buf);
 	
@@ -750,7 +691,7 @@
 		return -EIO;
 	}
 
-	jeb->bad_count =  buf[badblock_pos];	
+	jeb->bad_count =  buf[c->badblock_pos];	
 	return 0;
 }
 
@@ -767,25 +708,16 @@
 int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
 {
 	unsigned char buf = 0x0;
-	int 	ret,pos;
+	int 	ret;
 	size_t 	retlen;
 
-	switch(c->mtd->ecctype) {
-	case MTD_ECC_SW:	
-		pos = NAND_BADBLOCK_POS;
-		break;
-	default:
-		D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Invalid ECC type\n"));
-		return -EINVAL;
-	}	
-
 	/* if the count is < max, we try to write the counter to the 2nd page oob area */
 	if( ++jeb->bad_count < MAX_ERASE_FAILURES) {
 		buf = (unsigned char)jeb->bad_count;
-		pos += c->mtd->oobblock;
+		c->badblock_pos += c->mtd->oobblock;
 	}
 	
-	ret = jffs2_flash_write_oob(c, jeb->offset + pos, 1, &retlen, &buf);
+	ret = jffs2_flash_write_oob(c, jeb->offset + c->badblock_pos, 1, &retlen, &buf);
 	
 	if (ret) {
 		D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
@@ -798,6 +730,25 @@
 	return 0;
 }
 
+#define JFFS2_OOB_ECCPOS0		0
+#define JFFS2_OOB_ECCPOS1		1
+#define JFFS2_OOB_ECCPOS2		2
+#define JFFS2_OOB_ECCPOS3		3
+#define JFFS2_OOB_ECCPOS4		6
+#define JFFS2_OOB_ECCPOS5		7
+
+#define NAND_JFFS2_OOB8_FSDAPOS		6
+#define NAND_JFFS2_OOB16_FSDAPOS	8
+#define NAND_JFFS2_OOB8_FSDALEN		2
+#define NAND_JFFS2_OOB16_FSDALEN	8
+
+static struct nand_oobinfo jffs2_oobinfo_swecc = {
+	useecc: 1,
+	eccpos: {JFFS2_OOB_ECCPOS0, JFFS2_OOB_ECCPOS1, JFFS2_OOB_ECCPOS2, JFFS2_OOB_ECCPOS3, JFFS2_OOB_ECCPOS4, JFFS2_OOB_ECCPOS5}
+};
+
+
+
 int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
 {
 	/* Cleanmarker is out-of-band, so inline size zero */
@@ -806,9 +757,6 @@
 	/* Initialise write buffer */
 	c->wbuf_pagesize = c->mtd->oobblock;
 	c->wbuf_ofs = 0xFFFFFFFF;
-	c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
-	if (!c->wbuf)
-		return -ENOMEM;
 
 	/* Initialise process for timed wbuf flush */
 	INIT_WORK(&c->wbuf_task,(void*) jffs2_wbuf_process, (void *)c);
@@ -817,6 +765,29 @@
 	init_timer(&c->wbuf_timer);
 	c->wbuf_timer.function = jffs2_wbuf_timeout;
 	c->wbuf_timer.data = (unsigned long) c;
+
+	switch(c->mtd->ecctype) {
+	case MTD_ECC_SW:
+		c->oobinfo = &jffs2_oobinfo_swecc;
+		if (c->mtd->oobsize == 8) {
+			c->fsdata_pos = NAND_JFFS2_OOB8_FSDAPOS;
+			c->fsdata_len = NAND_JFFS2_OOB8_FSDALEN;
+		} else {
+			c->fsdata_pos = NAND_JFFS2_OOB16_FSDAPOS;
+			c->fsdata_len = NAND_JFFS2_OOB16_FSDALEN;
+		}
+		c->badblock_pos = NAND_BADBLOCK_POS;
+		break;
+
+	default:
+		printk("JFFS2 doesn't yet know how to handle ECC type %d\n",
+		       c->mtd->ecctype);
+		return -EINVAL;
+	}
+
+	c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
+	if (!c->wbuf)
+		return -ENOMEM;
 
 	return 0;
 }




More information about the linux-mtd-cvs mailing list