mtd/fs/jffs2 wbuf.c,1.20,1.21
gleixner at infradead.org
gleixner at infradead.org
Sun Nov 24 16:08:49 EST 2002
Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv32002
Modified Files:
wbuf.c
Log Message:
support virtual blocks of 2/4/8 physical blocks
Index: wbuf.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/wbuf.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- wbuf.c 12 Nov 2002 11:33:02 -0000 1.20
+++ wbuf.c 24 Nov 2002 21:08:45 -0000 1.21
@@ -578,69 +578,83 @@
return ret;
}
-int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
+/*
+* Scan for a valid cleanmarker and for bad blocks
+* For virtual blocks (concatenated physical blocks) check the cleanmarker
+* only in the first page of the first physical block, but scan for bad blocks in all
+* physical blocks
+*/
+int jffs2_check_nand_cleanmarker (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
{
struct jffs2_unknown_node n;
unsigned char buf[32];
unsigned char *p;
- int ret,i;
- size_t retlen;
- int fsdata_pos,fsdata_len, oob_size, badblock_pos;
+ int ret, i, cnt, retval = 0;
+ size_t retlen, offset;
+ int fsdata_pos, fsdata_len, oob_size, badblock_pos;
+ offset = jeb->offset;
oob_size = c->mtd->oobsize;
- switch(c->mtd->ecctype) {
- case MTD_ECC_SW:
+ 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"));
+ D1 (printk (KERN_WARNING "jffs2_write_nand_cleanmarker(): Invalid ECC type\n"));
return -EINVAL;
- }
-
- /*
- * We read oob data from page 0 and 1 of the block.
- * page 0 contains cleanmarker and badblock info
- * page 2 contains failure count of this block
- */
- ret = c->mtd->read_oob(c->mtd, jeb->offset, oob_size << 1 , &retlen, buf);
-
- if (ret) {
- D1(printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
- return ret;
- }
- if (retlen < (oob_size << 1) ) {
- D1(printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB return short read (%d bytes not %d) for block at %08x\n", retlen, oob_size << 1 , jeb->offset));
- return -EIO;
}
- /* Check for bad block marker */
- if (buf[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]));
- return 3;
- }
+ /* Loop through the physical blocks */
+ for (cnt = 0; cnt < (c->sector_size / c->mtd->erasesize); cnt++) {
+ /*
+ * We read oob data from page 0 and 1 of the block.
+ * page 0 contains cleanmarker and badblock info
+ * page 1 contains failure count of this block
+ */
+ ret = c->mtd->read_oob (c->mtd, offset, oob_size << 1, &retlen, buf);
+
+ if (ret) {
+ D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
+ return ret;
+ }
+ if (retlen < (oob_size << 1)) {
+ D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB return short read (%d bytes not %d) for block at %08x\n", retlen, oob_size << 1, jeb->offset));
+ return -EIO;
+ }
+
+ /* Check for bad block marker */
+ if (buf[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]));
+ return 3;
+ }
- n.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
- n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
- n.totlen = cpu_to_je32(8);
- p = (unsigned char *) &n;
-
- for (i = 0; i < fsdata_len; i++) {
- if (buf[fsdata_pos+i] != p[i]) {
- D2(printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Cleanmarker node not detected in block at %08x\n", jeb->offset));
- return 1;
+ /* Check cleanmarker only on the first physical block */
+ if (!cnt) {
+ n.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
+ n.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER);
+ n.totlen = cpu_to_je32 (8);
+ p = (unsigned char *) &n;
+
+ for (i = 0; i < fsdata_len; i++) {
+ if (buf[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;
+ }
+ }
}
+ offset += c->mtd->erasesize;
}
-
- return 0;
+ return retval;
}
int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
More information about the linux-mtd-cvs
mailing list