[JFFS2] Fix dataflash support
authorArtem B. Bityutskiy <dedekind@infradead.org>
Fri, 30 Sep 2005 13:59:17 +0000 (14:59 +0100)
committerThomas Gleixner <tglx@mtd.linutronix.de>
Sun, 6 Nov 2005 22:01:48 +0000 (23:01 +0100)
- 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 <pm-mtd@mw-itcon.de>
Acked-by: Artem B. Bityutskiy <dedekind@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
fs/jffs2/os-linux.h
fs/jffs2/scan.c
fs/jffs2/wbuf.c

index 48ad4202fbb1bcf32ab40042161e47caefd1c339..04d4167ab2527f8555e7dddc4827fad7ef9195ff 100644 (file)
@@ -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)
index 8df7456472b873aab7d4c9860cb8762b5b12fb14..805a166469d28ca2f5a29058aeb81fb3674e29f0 100644 (file)
@@ -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 <linux/kernel.h>
@@ -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));
index 11e05bc014f1fd706d09245b59574d981d2d975b..44d8a894a41bf1c0e8a432a6712a86904edd6311 100644 (file)
@@ -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;
 }