Re: EBH with OneNAND doesn't work

zhao, forrest
2005-12-19T11:17:26Z

On Mon, 2005-12-19 at 11:52 +0100, Christian Lehne wrote:
> Jarkko Lavinen wrote:
> > I am trying to use JFFS2 (JFFS2 from cvs -D 'Nov 12, 2005' with the
> > mtd driver part from CVS head) on OneNAND simulator and real OneNAND
> > device.
> >
> > I erased the test partition with "flash_eraseall /dev/mtd0". I mount the
> > partition and no other fs operation is done. When I just unmount and
> mount
> > again, I get
> >
> > # mount -t jffs2 /dev/mtdblock0 /mnt
> > ...
> > Dec 16 12:35:11 slayer kernel: jffs2_scan_eraseblock(): Scanning
> block at 0x0
> > Dec 16 12:35:11 slayer kernel: JFFS2: Erase block at 0x00000000 is
> not formatted. It will be erased
> > Dec 16 12:35:11 slayer kernel: jffs2_scan_eraseblock(): Scanning
> block at 0x10000
> > Dec 16 12:35:11 slayer kernel: JFFS2: Erase block at 0x00010000 is
> not formatted. It will be erased
> > ...
> > Dec 16 12:35:11 slayer kernel: Cowardly refusing to erase blocks on
> filesystem with no valid JFFS2 nodes
> > Dec 16 12:35:11 slayer kernel: empty_blocks 0, bad_blocks 0,
> c->nr_blocks 256
> > Dec 16 12:35:11 slayer kernel: c->used_size: 0
> > Dec 16 12:35:11 slayer kernel: c->nr_free_blocks 0
> > Dec 16 12:35:11 slayer kernel:
> (c->nr_free_blocks+empty_blocks+bad_blocks): 0
> > Dec 16 12:35:11 slayer kernel: [JFFS2 DBG] (3779)
> jffs2_do_mount_fs: build_fs failed
> >
> >
> > JFFS2 is complaining about many pages being unformatted. It shouldn't
> > do this, since the pages should be properly formatted after the first
> > mount within a second when using a fast machine. At least on Nandsim and
> > Ramtd they are.
> >
> > Also, no pages are used so pages shold be either free or empty but the
> > number of free or empty pages is zero. This triggers the Cowardly
> > message,
> >
> > I am seeing the same problem on both real OneNAND and OneNand
> > simulator. On Nandsim or Ramtd everything seems to work ok.
> >
> > The problem might be related to the free OOB bytes being scattered in
> > OneNand. The first free OOB region start at offset 2 and with length 3
> > bytes with autoplacement.
>
> Hi,
>
> as my colleague announced we had the same problem with a
> OneNAND512(KFG1216x2A) Chip.
> We had two problems: the one with the oob-handling which is discussed in
> another thread and the low-level read/write routine for onenand
> So here are two patches which will work for us but which is
> unfortunately not generic.
>
> In onenand_base.c I changed the bitmask for oobfree. as i can see with
> our chip i am not allowed to use (2,3) (reserved for crc), thats why i
> toggled (14,2) (which is free) and (2,3).
> the main problem i had is in
> onenand_read_bufferram/onenand_write_bufferram.
> as i understand bufferram-hardware accesses, i am not allowed to use
> memcpy for this, instead i use a (slow!!) copy routine with
> onenand_readw/onenand_writew. with that it works fine.
> (interestingly i only got read/write errors in OOB-Area not in data-Area
> when using memcpy.)
>
> Note that i am working with 16Bit data. onenand_write_bufferram() will
> fail if someone wrote an odd number of data!!!
> can someone tell me if there are cases where this function is called
> with an odd number of data?
> in my target i can't see this.
>
>
> In flash_eraseall.c there is a JFFS2_NODETYPE_ERASEBLOCK_HEADER-marker
> written but i couldn't find such a marker in the kernel-sources, so i
> replaced it with a cleanmarker which worked fine by us. but i miss the
> whole to understand the effects of this, so maybe someone with more
> experience can have a lock at this.
> Also the size of the structures (jffs2_raw_ebh) in flash_eraseall and
> kernel seems to differ, so we just use 8 Bytes instead.
> Last we wrote only ebhlen Data to OOB-Area (ebhlen with our chip is 2
> Bytes so we finally use only 2 bytes for OOB-Data, don't know if this is
> enough but it works fine, think we will have to wait for a generic
> solution with oob-handling)
>
>
> sorry for my poor solution but i am currently under pressure of time (as
> probably all of you.. ).
>
> Regards,
> Christian
>
>
>
> diff -uN util/flash_eraseall.c a/util/flash_eraseall.c
> --- util/flash_eraseall.c 2005-12-19 10:38:20.000000000 +0100
> +++ util/flash_eraseall.c 2005-11-08 02:02:20.000000000 +0100
> @@ -83,8 +83,8 @@
>
> if (jffs2) {
> ebh.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
> + ebh.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER);
> + ebh.totlen = cpu_to_je32(8);
> - ebh.nodetype = cpu_to_je16
> (JFFS2_NODETYPE_ERASEBLOCK_HEADER);
> - ebh.totlen = cpu_to_je32(sizeof(struct jffs2_raw_ebh));
> ebh.hdr_crc = cpu_to_je32 (crc32 (0, &ebh, sizeof
> (struct jffs2_unknown_node) - 4));
> ebh.reserved = 0;
> ebh.compat_fset = JFFS2_EBH_COMPAT_FSET;
> @@ -92,7 +92,7 @@
> ebh.rocompat_fset = JFFS2_EBH_ROCOMPAT_FSET;
> ebh.erase_count = cpu_to_je32(0);
> ebh.node_crc = cpu_to_je32(crc32(0, (unsigned char
> *)&ebh + sizeof(struct jffs2_unknown_node) + 4,
> + 8 - sizeof(struct
> jffs2_unknown_node) - 4));
> - sizeof(struct jffs2_raw_ebh) -
> sizeof(struct jffs2_unknown_node) - 4));
>
> if (isNAND) {
> struct nand_oobinfo oobinfo;
> @@ -182,11 +182,10 @@
> struct mtd_oob_buf oob;
> uint32_t i = 0, written = 0;
>
> + while (written < ebhlen) {
> - while (written < sizeof(struct jffs2_raw_ebh)) {
> oob.ptr = (unsigned char *) &ebh + written;
> oob.start = erase.start +
> meminfo.oobblock*i + ebhpos;
> oob.length = (sizeof(struct
> jffs2_raw_ebh) - written) < ebhlen ? (sizeof(struct jffs2_raw_ebh) -
> written) : ebhlen;
> +
> if (ioctl (fd, MEMWRITEOOB, &oob) != 0) {
> fprintf(stderr, "\n%s: %s: MTD
> writeoob failure: %s\n", exe_name, mtd_device, strerror(errno));
> break;
>
>
>
>
>
>
>
>
> diff -uN ..
> --- linux/drivers/mtd/onenand/onenand_base.c 2005-12-19
> 10:46:37.000000000 +0100
> +++ linux/drivers/mtd/onenand/onenand_base.c 2005-12-16
> 02:02:11.000000000 +0100
> @@ -33,8 +33,8 @@
> 56, 57, 58, 59, 60,
> },
> .oobfree = {
> + {14, 2}, { 2, 3}, {18, 3}, {30, 2},
> + {34, 3}, {46, 2}, {50, 3}, {62, 2} }
> - {2, 3}, {14, 2}, {18, 3}, {30, 2},
> - {24, 3}, {46, 2}, {40, 3}, {62, 2} }
> };
>
> /**
> @@ -367,33 +367,12 @@
> {
> struct onenand_chip *this = mtd->priv;
> void __iomem *bufferram;
> + unsigned short *p;
> + int i;
>
> bufferram = this->base + area;
>
> bufferram += onenand_bufferram_offset(mtd, area);
>
> + p = (unsigned short *)buffer;
> + for (i=0; i< (count >> 1 ); i++)
> + p[i] = onenand_readw(bufferram + offset + 2*i);
> + if(count%2)
> + buffer[count-1] = (unsigned char) (0xff &
> onenand_readw(bufferram + offset + count - 1));
> +
> - memcpy(buffer, bufferram + offset, count);
>
> return 0;
> }
> @@ -442,40 +421,12 @@
> {
> struct onenand_chip *this = mtd->priv;
> void __iomem *bufferram;
> + unsigned short *p;
> + int i;
>
> bufferram = this->base + area;
>
> bufferram += onenand_bufferram_offset(mtd, area);
>
> + p = (unsigned short *)buffer;
> + for (i=0; i< (count >> 1 ); i++){
> + onenand_writew(*p, bufferram + offset + 2 * i);
> + p++;
> + }
> + if(count%2)
> + printk("FATAL ERROR: onenand_write_bufferram count is
> odd : %x\n", count);
> + if(offset%2)
> + printk("FATAL ERROR: onenand_write_bufferram offset is
> odd : %x\n", offset);
> +
> - memcpy(bufferram + offset, buffer, count);
>
> return 0;
> }
>

Please report bug to me if EBH still can work together with patched
OneNAND.
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/