* EBH with OneNAND doesn't work @ 2005-12-16 12:23 Jarkko Lavinen 2005-12-16 12:37 ` Bernhard Priewasser 2005-12-19 10:52 ` Christian Lehne 0 siblings, 2 replies; 9+ messages in thread From: Jarkko Lavinen @ 2005-12-16 12:23 UTC (permalink / raw) To: linux-mtd; +Cc: zhao forrest 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. Regards Jarkko Lavinen ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: EBH with OneNAND doesn't work 2005-12-16 12:23 EBH with OneNAND doesn't work Jarkko Lavinen @ 2005-12-16 12:37 ` Bernhard Priewasser 2005-12-19 10:52 ` Christian Lehne 1 sibling, 0 replies; 9+ messages in thread From: Bernhard Priewasser @ 2005-12-16 12:37 UTC (permalink / raw) To: Jarkko Lavinen; +Cc: zhao forrest, linux-mtd > The problem might be related to the free OOB bytes It is. 1. OOB positions in struct nand_oobinfo are wrong in OneNAND driver. 2. flash_eraseall has to be fixed, there are also some OOB troubles when working on OneNAND. Both issues are already fixed up by us; we got JFFS2 mounting and running on OneNAND. A colleague of mine will clean up the massacre we did in MTD OneNAND and provide a patch, hopefully on monday. Regards, Bernhard ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: EBH with OneNAND doesn't work 2005-12-16 12:23 EBH with OneNAND doesn't work Jarkko Lavinen 2005-12-16 12:37 ` Bernhard Priewasser @ 2005-12-19 10:52 ` Christian Lehne 2005-12-19 11:07 ` zhao, forrest 2005-12-21 9:30 ` Jarkko Lavinen 1 sibling, 2 replies; 9+ messages in thread From: Christian Lehne @ 2005-12-19 10:52 UTC (permalink / raw) To: Jarkko Lavinen, linux-mtd; +Cc: priewasser, tglx 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; } ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: EBH with OneNAND doesn't work 2005-12-19 10:52 ` Christian Lehne @ 2005-12-19 11:07 ` zhao, forrest 2005-12-21 7:24 ` Kyungmin Park 2005-12-21 9:30 ` Jarkko Lavinen 1 sibling, 1 reply; 9+ messages in thread From: zhao, forrest @ 2005-12-19 11:07 UTC (permalink / raw) To: Christian Lehne; +Cc: linux-mtd, tglx, Jarkko Lavinen, priewasser 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/ ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: EBH with OneNAND doesn't work 2005-12-19 11:07 ` zhao, forrest @ 2005-12-21 7:24 ` Kyungmin Park 2005-12-21 7:40 ` zhao, forrest 0 siblings, 1 reply; 9+ messages in thread From: Kyungmin Park @ 2005-12-21 7:24 UTC (permalink / raw) To: 'zhao, forrest', 'Christian Lehne' Cc: 'Jarkko Lavinen', tglx, linux-mtd, priewasser Hi As you know the OneNAND has only 16bit bandwidth When you access OneNAND with 8bit bandwidth, OneNAND can't work correctly In the previous JFFS2 w/o EBH, there's no problem with OOB. But JFFS2 w/ EBH is different. we have to handle byte access in OneNAND The previous patch is handle byte without optimized memory copy The following patch handles only byte offset. Please apply the following patch and test again Thank you Kyungmin Park p.s, Does it need to check byte access in 'offset', I never see that case. Index: drivers/mtd/onenand/onenand_base.c =================================================================== RCS file: /home/cvs/mtd/drivers/mtd/onenand/onenand_base.c,v retrieving revision 1.12 diff -u -p -r1.12 onenand_base.c --- drivers/mtd/onenand/onenand_base.c 21 Dec 2005 04:59:19 -0000 1.12 +++ drivers/mtd/onenand/onenand_base.c 21 Dec 2005 07:05:16 -0000 @@ -373,6 +373,17 @@ static int onenand_read_bufferram(struct bufferram += onenand_bufferram_offset(mtd, area); + if (ONENAND_CHECK_BYTE_ACCESS(count)) { + unsigned short word; + + /* Align with word(16-bit) size */ + count--; + + /* Read word and save byte */ + word = this->read_word(bufferram + offset + count); + buffer[count] = (word & 0xff); + } + memcpy(buffer, bufferram + offset, count); return 0; @@ -400,6 +411,17 @@ static int onenand_sync_read_bufferram(s this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ); + if (ONENAND_CHECK_BYTE_ACCESS(count)) { + unsigned short word; + + /* Align with word(16-bit) size */ + count--; + + /* Read word and save byte */ + word = this->read_word(bufferram + offset + count); + buffer[count] = (word & 0xff); + } + memcpy(buffer, bufferram + offset, count); this->mmcontrol(mtd, 0); @@ -427,6 +449,22 @@ static int onenand_write_bufferram(struc bufferram += onenand_bufferram_offset(mtd, area); + if (ONENAND_CHECK_BYTE_ACCESS(count)) { + unsigned short word; + int byte_offset; + + /* Align with word(16-bit) size */ + count--; + + /* Calculate byte access offset */ + byte_offset = offset + count; + + /* Read word and save byte */ + word = this->read_word(bufferram + byte_offset); + word = (word & ~0xff) | buffer[count]; + this->write_word(word, bufferram + byte_offset); + } + memcpy(bufferram + offset, buffer, count); return 0; Index: include/linux/mtd/onenand.h =================================================================== RCS file: /home/cvs/mtd/include/linux/mtd/onenand.h,v retrieving revision 1.10 diff -u -p -r1.10 onenand.h --- include/linux/mtd/onenand.h 21 Dec 2005 02:55:41 -0000 1.10 +++ include/linux/mtd/onenand.h 21 Dec 2005 07:05:16 -0000 @@ -130,6 +130,9 @@ struct onenand_chip { #define ONENAND_SET_SYS_CFG1(v, this) \ (this->write_word(v, this->base + ONENAND_REG_SYS_CFG1)) +/* Check byte access in OneNAND */ +#define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1) + /* * Options bits */ > > > > 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; > > } > > T ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: EBH with OneNAND doesn't work 2005-12-21 7:24 ` Kyungmin Park @ 2005-12-21 7:40 ` zhao, forrest 0 siblings, 0 replies; 9+ messages in thread From: zhao, forrest @ 2005-12-21 7:40 UTC (permalink / raw) To: kyungmin.park Cc: 'Christian Lehne', tglx, linux-mtd, 'Jarkko Lavinen', priewasser On Wed, 2005-12-21 at 16:24 +0900, Kyungmin Park wrote: > Hi > > As you know the OneNAND has only 16bit bandwidth > When you access OneNAND with 8bit bandwidth, OneNAND can't work correctly > > In the previous JFFS2 w/o EBH, there's no problem with OOB. > But JFFS2 w/ EBH is different. we have to handle byte access in OneNAND > > p.s, Does it need to check byte access in 'offset', I never see that case. I think it's OK not checking "offset" as long as the free_oob exported by OneNAND driver is 16-bit-aligned. EBH is stored only from the start of a free_oob area. But not sure if other application will start to store data from arbitrary offset within a free_oob area in the future. Thanks, Forrest ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: EBH with OneNAND doesn't work 2005-12-19 10:52 ` Christian Lehne 2005-12-19 11:07 ` zhao, forrest @ 2005-12-21 9:30 ` Jarkko Lavinen 2005-12-21 11:06 ` Jarkko Lavinen 2005-12-21 12:43 ` Vitaly Wool 1 sibling, 2 replies; 9+ messages in thread From: Jarkko Lavinen @ 2005-12-21 9:30 UTC (permalink / raw) To: Christian Lehne; +Cc: priewasser, tglx, linux-mtd, Zhao, Forrest Thanks Christian, your patch helpt me to get JFFS2 working without using too many printks. Currently wbuf.c:jffs2_check_nand_cleanmarker_ebh() assumes the node header fits in the first free region. The magic and node type would take 4 bytes. If we have only 2 byte free regions available, this is not enough and the struct jffs2_unknown_node needs to be assembled. I am using new helper function jffs2_copy_nand_fsdata(), from Forrest's code. Forrest assembled the longer EBH struct (28 bytes) from several free regions. Similar assmebly is also needed for the struct unknown_node. Optimally JFFS2 would use more free regions available at OOB. This would result fewer amount of OOBs being used less writing to OOBs. Jarkko Lavinen Index: fs/jffs2/wbuf.c =================================================================== RCS file: /home/cvs/mtd/fs/jffs2/wbuf.c,v retrieving revision 1.108 diff -u -b -B -p -r1.108 wbuf.c --- fs/jffs2/wbuf.c 18 Nov 2005 07:27:45 -0000 1.108 +++ fs/jffs2/wbuf.c 21 Dec 2005 09:19:56 -0000 @@ -984,6 +984,21 @@ out: return ret; } +static void jffs2_copy_nand_fsdata(struct jffs2_sb_info *c, void *to, + unsigned char *from, int len, int oob_size) +{ + uint32_t read_in, i, copy_len; + + read_in = i = 0; + while (read_in < len) { + copy_len = min_t(uint32_t, c->fsdata_len, len - read_in); + memcpy(to + read_in, &from[oob_size*i + c->fsdata_pos], copy_len); + read_in += copy_len; + i++; + } + +} + /* * Scan for a valid cleanmarker and for bad blocks * For virtual blocks (concatenated physical blocks) check the cleanmarker @@ -997,9 +1012,9 @@ int jffs2_check_nand_cleanmarker_ebh (st uint32_t oob_nr, total_len; unsigned char *buf; int ret; - struct jffs2_unknown_node *n; + struct jffs2_unknown_node *n, unode; struct jffs2_raw_ebh eh; - uint32_t read_in = 0, i = 0, copy_len, node_crc; + uint32_t node_crc; offset = jeb->offset; *data_len = 0; @@ -1028,7 +1043,13 @@ int jffs2_check_nand_cleanmarker_ebh (st goto out; } + if (c->fsdata_len >= sizeof(struct jffs2_unknown_node *)) { n = (struct jffs2_unknown_node *) &buf[c->fsdata_pos]; + } else { + n = &unode; + jffs2_copy_nand_fsdata(c, n, buf, sizeof(sizeof(struct jffs2_unknown_node)), oob_size); + } + if (je16_to_cpu(n->magic) != JFFS2_MAGIC_BITMASK) { D1 (printk(KERN_WARNING "jffs2_check_nand_cleanmarker_ebh(): Cleanmarker node not detected in block at %08x\n", jeb->offset)); ret = 1; @@ -1043,16 +1064,11 @@ int jffs2_check_nand_cleanmarker_ebh (st ret = 1; } goto out; - }else if (je16_to_cpu(n->nodetype) == JFFS2_NODETYPE_ERASEBLOCK_HEADER) { + } else if (je16_to_cpu(n->nodetype) == JFFS2_NODETYPE_ERASEBLOCK_HEADER) { /* Read the scattered data(in buf[]) into struct jffs2_raw_ebh */ - while (read_in < sizeof(struct jffs2_raw_ebh)) { - copy_len = min_t(uint32_t, c->fsdata_len, sizeof(struct jffs2_raw_ebh) - read_in); - memcpy((unsigned char *)&eh + read_in, &buf[oob_size*i + c->fsdata_pos], copy_len); - read_in += copy_len; - i++; - } + jffs2_copy_nand_fsdata(c, &eh, buf, sizeof(struct jffs2_raw_ebh), oob_size); - node_crc = crc32(0, &eh, sizeof(struct jffs2_raw_ebh)-8); + node_crc = crc32(0, &eh, sizeof(struct jffs2_raw_ebh) - 8); if (node_crc != je32_to_cpu(eh.node_crc)) { ret = 1; goto out; ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: EBH with OneNAND doesn't work 2005-12-21 9:30 ` Jarkko Lavinen @ 2005-12-21 11:06 ` Jarkko Lavinen 2005-12-21 12:43 ` Vitaly Wool 1 sibling, 0 replies; 9+ messages in thread From: Jarkko Lavinen @ 2005-12-21 11:06 UTC (permalink / raw) To: linux-mtd; +Cc: Christian Lehne, tglx, priewasser, Zhao, Forrest On Wed, Dec 21, 2005 at 11:30:34AM +0200, Jarkko Lavinen wrote: > + jffs2_copy_nand_fsdata(c, n, buf, sizeof(sizeof(struct jffs2_unknown_node)), oob_size); Grrr... sizeof(sizeof()) looks ugly crap. Jarkko ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: EBH with OneNAND doesn't work 2005-12-21 9:30 ` Jarkko Lavinen 2005-12-21 11:06 ` Jarkko Lavinen @ 2005-12-21 12:43 ` Vitaly Wool 1 sibling, 0 replies; 9+ messages in thread From: Vitaly Wool @ 2005-12-21 12:43 UTC (permalink / raw) To: Jarkko Lavinen Cc: Christian Lehne, tglx, priewasser, Zhao, Forrest, linux-mtd Jarkko Lavinen wrote: >Thanks Christian, your patch helpt me to get JFFS2 working without >using too many printks. > >Currently wbuf.c:jffs2_check_nand_cleanmarker_ebh() assumes the node header >fits in the first free region. The magic and node type would take 4 bytes. >If we have only 2 byte free regions available, this is not enough >and the struct jffs2_unknown_node needs to be assembled. > > I hope we'll eliminate this problem soon when new functions to read/write the free OOB area as a contiguous array of bytes are introduced. Vitaly ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2005-12-21 12:43 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-12-16 12:23 EBH with OneNAND doesn't work Jarkko Lavinen 2005-12-16 12:37 ` Bernhard Priewasser 2005-12-19 10:52 ` Christian Lehne 2005-12-19 11:07 ` zhao, forrest 2005-12-21 7:24 ` Kyungmin Park 2005-12-21 7:40 ` zhao, forrest 2005-12-21 9:30 ` Jarkko Lavinen 2005-12-21 11:06 ` Jarkko Lavinen 2005-12-21 12:43 ` Vitaly Wool
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox