aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2
diff options
context:
space:
mode:
authorArtem B. Bityutskiy <dedekind@infradead.org>2005-09-30 09:59:17 -0400
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-11-06 17:01:48 -0500
commitdaba5cc4bcd025a9b4fd02a9117c71bfd400d811 (patch)
treeda74b64b3bbd4ae215ced6d2d54abe7fdf83818e /fs/jffs2
parent83a368380e172c1b2e9fd6ec2a62e457684adf0c (diff)
[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 <pm-mtd@mw-itcon.de> Acked-by: Artem B. Bityutskiy <dedekind@infradead.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/jffs2')
-rw-r--r--fs/jffs2/os-linux.h6
-rw-r--r--fs/jffs2/scan.c6
-rw-r--r--fs/jffs2/wbuf.c50
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 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: os-linux.h,v 1.63 2005/09/21 11:55:21 dedekind Exp $ 10 * $Id: os-linux.h,v 1.64 2005/09/30 13:59:13 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -65,8 +65,9 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
65 65
66#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY) 66#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
67 67
68#define SECTOR_ADDR(x) ( (((unsigned long)(x) / c->sector_size) * c->sector_size) )
68#ifndef CONFIG_JFFS2_FS_WRITEBUFFER 69#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
69#define SECTOR_ADDR(x) ( ((unsigned long)(x) & ~(c->sector_size-1)) ) 70
70 71
71#ifdef CONFIG_JFFS2_SUMMARY 72#ifdef CONFIG_JFFS2_SUMMARY
72#define jffs2_can_mark_obsolete(c) (0) 73#define jffs2_can_mark_obsolete(c) (0)
@@ -102,7 +103,6 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
102#else /* NAND and/or ECC'd NOR support present */ 103#else /* NAND and/or ECC'd NOR support present */
103 104
104#define jffs2_is_writebuffered(c) (c->wbuf != NULL) 105#define jffs2_is_writebuffered(c) (c->wbuf != NULL)
105#define SECTOR_ADDR(x) ( ((unsigned long)(x) / (unsigned long)(c->sector_size)) * c->sector_size )
106 106
107#ifdef CONFIG_JFFS2_SUMMARY 107#ifdef CONFIG_JFFS2_SUMMARY
108#define jffs2_can_mark_obsolete(c) (0) 108#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 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: scan.c,v 1.124 2005/09/21 13:05:22 dedekind Exp $ 10 * $Id: scan.c,v 1.125 2005/09/30 13:59:13 dedekind Exp $
11 * 11 *
12 */ 12 */
13#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -233,12 +233,12 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
233 c->nextblock->dirty_size = 0; 233 c->nextblock->dirty_size = 0;
234 } 234 }
235#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 235#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
236 if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) { 236 if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size % c->wbuf_pagesize)) {
237 /* If we're going to start writing into a block which already 237 /* If we're going to start writing into a block which already
238 contains data, and the end of the data isn't page-aligned, 238 contains data, and the end of the data isn't page-aligned,
239 skip a little and align it. */ 239 skip a little and align it. */
240 240
241 uint32_t skip = c->nextblock->free_size & (c->wbuf_pagesize-1); 241 uint32_t skip = c->nextblock->free_size % c->wbuf_pagesize;
242 242
243 D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n", 243 D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n",
244 skip)); 244 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 @@
9 * 9 *
10 * For licensing information, see the file 'LICENCE' in this directory. 10 * For licensing information, see the file 'LICENCE' in this directory.
11 * 11 *
12 * $Id: wbuf.c,v 1.99 2005/09/21 16:11:04 dedekind Exp $ 12 * $Id: wbuf.c,v 1.100 2005/09/30 13:59:13 dedekind Exp $
13 * 13 *
14 */ 14 */
15 15
@@ -30,6 +30,9 @@
30static unsigned char *brokenbuf; 30static unsigned char *brokenbuf;
31#endif 31#endif
32 32
33#define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) )
34#define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) )
35
33/* max. erase failures before we mark a block bad */ 36/* max. erase failures before we mark a block bad */
34#define MAX_ERASE_FAILURES 2 37#define MAX_ERASE_FAILURES 2
35 38
@@ -433,7 +436,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
433 if we have a switch to next page, we will not have 436 if we have a switch to next page, we will not have
434 enough remaining space for this. 437 enough remaining space for this.
435 */ 438 */
436 if (pad && !jffs2_dataflash(c)) { 439 if (pad ) {
437 c->wbuf_len = PAD(c->wbuf_len); 440 c->wbuf_len = PAD(c->wbuf_len);
438 441
439 /* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR 442 /* 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)
482 } 485 }
483 486
484 spin_lock(&c->erase_completion_lock); 487 spin_lock(&c->erase_completion_lock);
485 488
486 /* Adjust free size of the block if we padded. */ 489 /* Adjust free size of the block if we padded. */
487 if (pad && !jffs2_dataflash(c)) { 490 if (pad) {
488 struct jffs2_eraseblock *jeb; 491 struct jffs2_eraseblock *jeb;
489 492
490 jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; 493 jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
@@ -601,15 +604,6 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c)
601 604
602 return ret; 605 return ret;
603} 606}
604
605#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
606#define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) )
607#define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) )
608#else
609#define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) )
610#define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) )
611#endif
612
613int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino) 607int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino)
614{ 608{
615 struct kvec outvecs[3]; 609 struct kvec outvecs[3];
@@ -1203,14 +1197,38 @@ int jffs2_dataflash_setup(struct jffs2_sb_info *c) {
1203 1197
1204 /* Initialize write buffer */ 1198 /* Initialize write buffer */
1205 init_rwsem(&c->wbuf_sem); 1199 init_rwsem(&c->wbuf_sem);
1206 c->wbuf_pagesize = c->sector_size; 1200
1207 c->wbuf_ofs = 0xFFFFFFFF; 1201
1202 c->wbuf_pagesize = c->mtd->erasesize;
1203
1204 /* Find a suitable c->sector_size
1205 * - Not too much sectors
1206 * - Sectors have to be at least 4 K + some bytes
1207 * - All known dataflashes have erase sizes of 528 or 1056
1208 * - we take at least 8 eraseblocks and want to have at least 8K size
1209 * - The concatenation should be a power of 2
1210 */
1211
1212 c->sector_size = 8 * c->mtd->erasesize;
1213
1214 while (c->sector_size < 8192) {
1215 c->sector_size *= 2;
1216 }
1217
1218 /* It may be necessary to adjust the flash size */
1219 c->flash_size = c->mtd->size;
1208 1220
1221 if ((c->flash_size % c->sector_size) != 0) {
1222 c->flash_size = (c->flash_size / c->sector_size) * c->sector_size;
1223 printk(KERN_WARNING "JFFS2 flash size adjusted to %dKiB\n", c->flash_size);
1224 };
1225
1226 c->wbuf_ofs = 0xFFFFFFFF;
1209 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); 1227 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
1210 if (!c->wbuf) 1228 if (!c->wbuf)
1211 return -ENOMEM; 1229 return -ENOMEM;
1212 1230
1213 printk(KERN_INFO "JFFS2 write-buffering enabled (%i)\n", c->wbuf_pagesize); 1231 printk(KERN_INFO "JFFS2 write-buffering enabled buffer (%d) erasesize (%d)\n", c->wbuf_pagesize, c->sector_size);
1214 1232
1215 return 0; 1233 return 0;
1216} 1234}