From daba5cc4bcd025a9b4fd02a9117c71bfd400d811 Mon Sep 17 00:00:00 2001 From: "Artem B. Bityutskiy" Date: Fri, 30 Sep 2005 14:59:17 +0100 Subject: [PATCH] [JFFS2] Fix dataflash support - assume wbuf may be of size which is not power of 2 - don't make strange assumption about not padding wbuf for DataFlash - use wbuf = DataFlash page and eraseblock >= 8 Dataflash pages From: Peter Menzebach Acked-by: Artem B. Bityutskiy Signed-off-by: Thomas Gleixner --- fs/jffs2/os-linux.h | 6 +++--- fs/jffs2/scan.c | 6 +++--- fs/jffs2/wbuf.c | 50 ++++++++++++++++++++++++++++++--------------- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index 48ad4202fbb1..04d4167ab252 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: os-linux.h,v 1.63 2005/09/21 11:55:21 dedekind Exp $ + * $Id: os-linux.h,v 1.64 2005/09/30 13:59:13 dedekind Exp $ * */ @@ -65,8 +65,9 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) #define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY) +#define SECTOR_ADDR(x) ( (((unsigned long)(x) / c->sector_size) * c->sector_size) ) #ifndef CONFIG_JFFS2_FS_WRITEBUFFER -#define SECTOR_ADDR(x) ( ((unsigned long)(x) & ~(c->sector_size-1)) ) + #ifdef CONFIG_JFFS2_SUMMARY #define jffs2_can_mark_obsolete(c) (0) @@ -102,7 +103,6 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) #else /* NAND and/or ECC'd NOR support present */ #define jffs2_is_writebuffered(c) (c->wbuf != NULL) -#define SECTOR_ADDR(x) ( ((unsigned long)(x) / (unsigned long)(c->sector_size)) * c->sector_size ) #ifdef CONFIG_JFFS2_SUMMARY #define jffs2_can_mark_obsolete(c) (0) diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 8df7456472b8..805a166469d2 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: scan.c,v 1.124 2005/09/21 13:05:22 dedekind Exp $ + * $Id: scan.c,v 1.125 2005/09/30 13:59:13 dedekind Exp $ * */ #include @@ -233,12 +233,12 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) c->nextblock->dirty_size = 0; } #ifdef CONFIG_JFFS2_FS_WRITEBUFFER - if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) { + if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size % c->wbuf_pagesize)) { /* If we're going to start writing into a block which already contains data, and the end of the data isn't page-aligned, skip a little and align it. */ - uint32_t skip = c->nextblock->free_size & (c->wbuf_pagesize-1); + uint32_t skip = c->nextblock->free_size % c->wbuf_pagesize; D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n", skip)); diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index 11e05bc014f1..44d8a894a41b 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c @@ -9,7 +9,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: wbuf.c,v 1.99 2005/09/21 16:11:04 dedekind Exp $ + * $Id: wbuf.c,v 1.100 2005/09/30 13:59:13 dedekind Exp $ * */ @@ -30,6 +30,9 @@ static unsigned char *brokenbuf; #endif +#define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) ) +#define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) ) + /* max. erase failures before we mark a block bad */ #define MAX_ERASE_FAILURES 2 @@ -433,7 +436,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) if we have a switch to next page, we will not have enough remaining space for this. */ - if (pad && !jffs2_dataflash(c)) { + if (pad ) { c->wbuf_len = PAD(c->wbuf_len); /* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR @@ -482,9 +485,9 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) } spin_lock(&c->erase_completion_lock); - + /* Adjust free size of the block if we padded. */ - if (pad && !jffs2_dataflash(c)) { + if (pad) { struct jffs2_eraseblock *jeb; jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; @@ -601,15 +604,6 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c) return ret; } - -#ifdef CONFIG_JFFS2_FS_WRITEBUFFER -#define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) ) -#define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) ) -#else -#define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) ) -#define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) ) -#endif - int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino) { struct kvec outvecs[3]; @@ -1203,14 +1197,38 @@ int jffs2_dataflash_setup(struct jffs2_sb_info *c) { /* Initialize write buffer */ init_rwsem(&c->wbuf_sem); - c->wbuf_pagesize = c->sector_size; - c->wbuf_ofs = 0xFFFFFFFF; + + + c->wbuf_pagesize = c->mtd->erasesize; + + /* Find a suitable c->sector_size + * - Not too much sectors + * - Sectors have to be at least 4 K + some bytes + * - All known dataflashes have erase sizes of 528 or 1056 + * - we take at least 8 eraseblocks and want to have at least 8K size + * - The concatenation should be a power of 2 + */ + c->sector_size = 8 * c->mtd->erasesize; + + while (c->sector_size < 8192) { + c->sector_size *= 2; + } + + /* It may be necessary to adjust the flash size */ + c->flash_size = c->mtd->size; + + if ((c->flash_size % c->sector_size) != 0) { + c->flash_size = (c->flash_size / c->sector_size) * c->sector_size; + printk(KERN_WARNING "JFFS2 flash size adjusted to %dKiB\n", c->flash_size); + }; + + c->wbuf_ofs = 0xFFFFFFFF; c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); if (!c->wbuf) return -ENOMEM; - printk(KERN_INFO "JFFS2 write-buffering enabled (%i)\n", c->wbuf_pagesize); + printk(KERN_INFO "JFFS2 write-buffering enabled buffer (%d) erasesize (%d)\n", c->wbuf_pagesize, c->sector_size); return 0; }