Message ID | 910818750812260536ke7d67e5l587c7c18a2064bd@mail.gmail.com |
---|---|
State | New, archived |
Headers | show |
On Fri, Dec 26, 2008 at 08:36:45AM -0500, ARXX Dev Team wrote: >Our board has a PowerPC core inside Xilinx Virtex II Pro FPGA. We have >a Intel Strataflash attached to the FPGA accessed via a 16-bit >interface. Since our interface to the flash part is 16-bit wide and we >do not have any chip selects or other mechanisms to prevent 32-bit >accesses to the part, some of the jffs2 scanning/erasing code fails. >Hence we had to create the patch below to use MTD layer functions (or >simple 8/16 bit access code) to correctly access the part instead of >original jffs2 code that was accessing the flash directly 32-bit wide. >We are would like your opinion as well as find out if this fix (in >some form) needs to go back into jffs2 code for parts that cannot be >accessed 32-bit wide (or need to prevent 32-bit accesses). >we sincerely appreciate your help, Why don't you write a custom mapping driver that prevents the 32-bit accesses at the MTD level? That seems like a more appropriate place than sticking it in JFFS2 code, which is supposed to be fairly hardware independent (with the obvious exception of major flash class types like NOR, NAND, etc). josh
That is exactly what we have done. Hence we have added calls to jffs2_fill_scan_buf(..) in our patch instead of direct access that was in jffs2 code. Without MTD layer function calls, jffs2 scan/erase functions fail. As you will see in our code patch, we have accessed flash data using MTD layer functions (or 16-bit pointers) instead of 32-bit access that exist in jffs2 code. > > Why don't you write a custom mapping driver that prevents the 32-bit > accesses at the MTD level? That seems like a more appropriate place > than sticking it in JFFS2 code, which is supposed to be fairly > hardware independent (with the obvious exception of major flash class > types like NOR, NAND, etc). > > josh >
On Fri, Dec 26, 2008 at 12:55:08PM -0500, ARXX Dev Team wrote: >That is exactly what we have done. Hence we have added calls to No, it isn't. If it's what you had done, then your mapping driver would have taken the 32-bit accesses and acted accordingly and turned them into two 16-bit reads. >jffs2_fill_scan_buf(..) in our patch instead of direct access that was >in jffs2 code. Without MTD layer function calls, jffs2 scan/erase >functions fail. As you will see in our code patch, we have accessed >flash data using MTD layer functions (or 16-bit pointers) instead of >32-bit access that exist in jffs2 code. I can't exactly read your patch because it seems to be corrupted somehow. But I'm not sure those hacks are needed at all. It seems you are trying to force use of the mtd->point methods and this doesn't really seem to fit with your hardware. The mtd->read function should call your driver, which should be able to determine what to do for your hardware. josh
================= Start of Patch =========================== diff -Naur linux-2.6.24_old/fs/jffs2/ erase.c linux-2.6.24_new/fs/jffs2/erase.c --- linux-2.6.24_old/fs/jffs2/erase.c 2008-01-24 17:58:37.000000000 -0500 +++ linux-2.6.24_new/fs/jffs2/erase.c 2008-12-10 18:39:34.000000000 -0500 @@ -346,7 +346,20 @@ wordebuf = ebuf-sizeof(*wordebuf); retlen /= sizeof(*wordebuf); do { +#ifdef CONFIG_ARXXPPC + unsigned short* wordebuf16; + unsigned long testebuf; + + ++wordebuf; + wordebuf16 = (unsigned short*)(wordebuf); + testebuf = *wordebuf16 & 0x0000ffff; + wordebuf16++; + testebuf |= ((*wordebuf16 & 0x0000ffff) << 16); + + if (testebuf != ~0) +#else if (*++wordebuf != ~0) +#endif /* CONFIG_ARXXPPC */ break; } while(--retlen); c->mtd->unpoint(c->mtd, ebuf, jeb->offset, c->sector_size); @@ -382,7 +395,20 @@ for (i=0; i<readlen; i += sizeof(unsigned long)) { /* It's OK. We know it's properly aligned */ unsigned long *datum = ebuf + i; + +#ifdef CONFIG_ARXXPPC + unsigned short* datum16; + unsigned long testdatum; + + datum16 = (unsigned short*)(ebuf + i); + testdatum = *datum16 & 0x0000ffff; + datum16++; + testdatum |= ((*datum16 & 0x0000ffff) << 16); + + if (testdatum + 1) { +#else if (*datum + 1) { +#endif /* CONFIG_ARXXPPC */ *bad_offset += i; printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", *datum, *bad_offset); goto fail; diff -Naur linux-2.6.24_old/fs/jffs2/scan.c linux-2.6.24_new/fs/jffs2/scan.c --- linux-2.6.24_old/fs/jffs2/scan.c 2008-01-24 17:58:37.000000000 -0500 +++ linux-2.6.24_new/fs/jffs2/scan.c 2008-12-10 18:46:46.000000000 -0500 @@ -35,7 +35,7 @@ static uint32_t pseudo_random; static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s); + unsigned char *buf, uint32_t flash_ofs, uint32_t buf_size,