diff options
author | Andrew Victor <andrew@sanpeople.com> | 2005-02-09 04:17:45 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-05-23 06:28:03 -0400 |
commit | 8f15fd55f9bf266139b10850947e19c4e3f4e9b7 (patch) | |
tree | 3df936efbffbbd6c20dd75f51780ac37458285ff /fs/jffs2/wbuf.c | |
parent | 3be36675d41a30ed3b192f92684f1417aa0f8bfe (diff) |
[JFFS2] Add support for JFFS2-on-Dataflash devices.
For Dataflash, can_mark_obsolete = false and the NAND write buffering
code (wbuf.c) is used.
Since the DataFlash chip will automatically erase pages when writing,
the cleanmarkers are not needed - so cleanmarker_oob = false and
cleanmarker_size = 0
DataFlash page-sizes are not a power of two (they're multiples of 528
bytes). The SECTOR_ADDR macro (added in the previous core patch) is
replaced with a (slower) div/mod version if CONFIG_JFFS2_FS_DATAFLASH is
selected.
Signed-off-by: Andrew Victor <andrew@sanpeople.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/jffs2/wbuf.c')
-rw-r--r-- | fs/jffs2/wbuf.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index 894dea88678d..a35e007e5bf8 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.87 2005/02/09 09:09:02 pavlov Exp $ | 12 | * $Id: wbuf.c,v 1.88 2005/02/09 09:17:41 pavlov Exp $ |
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
@@ -435,7 +435,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) | |||
435 | if we have a switch to next page, we will not have | 435 | if we have a switch to next page, we will not have |
436 | enough remaining space for this. | 436 | enough remaining space for this. |
437 | */ | 437 | */ |
438 | if (pad) { | 438 | if (pad && !jffs2_dataflash(c)) { |
439 | c->wbuf_len = PAD(c->wbuf_len); | 439 | c->wbuf_len = PAD(c->wbuf_len); |
440 | 440 | ||
441 | /* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR | 441 | /* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR |
@@ -486,7 +486,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) | |||
486 | spin_lock(&c->erase_completion_lock); | 486 | spin_lock(&c->erase_completion_lock); |
487 | 487 | ||
488 | /* Adjust free size of the block if we padded. */ | 488 | /* Adjust free size of the block if we padded. */ |
489 | if (pad) { | 489 | if (pad && !jffs2_dataflash(c)) { |
490 | struct jffs2_eraseblock *jeb; | 490 | struct jffs2_eraseblock *jeb; |
491 | 491 | ||
492 | jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; | 492 | jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; |
@@ -604,8 +604,14 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c) | |||
604 | return ret; | 604 | return ret; |
605 | } | 605 | } |
606 | 606 | ||
607 | #ifdef CONFIG_JFFS2_FS_DATAFLASH | ||
608 | #define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) ) | ||
609 | #define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) ) | ||
610 | #else | ||
607 | #define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) ) | 611 | #define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) ) |
608 | #define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) ) | 612 | #define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) ) |
613 | #endif | ||
614 | |||
609 | 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) | 615 | 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) |
610 | { | 616 | { |
611 | struct kvec outvecs[3]; | 617 | struct kvec outvecs[3]; |
@@ -1192,6 +1198,29 @@ void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c) | |||
1192 | kfree(c->wbuf); | 1198 | kfree(c->wbuf); |
1193 | } | 1199 | } |
1194 | 1200 | ||
1201 | #ifdef CONFIG_JFFS2_FS_DATAFLASH | ||
1202 | int jffs2_dataflash_setup(struct jffs2_sb_info *c) { | ||
1203 | c->cleanmarker_size = 0; /* No cleanmarkers needed */ | ||
1204 | |||
1205 | /* Initialize write buffer */ | ||
1206 | init_rwsem(&c->wbuf_sem); | ||
1207 | c->wbuf_pagesize = c->sector_size; | ||
1208 | c->wbuf_ofs = 0xFFFFFFFF; | ||
1209 | |||
1210 | c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL); | ||
1211 | if (!c->wbuf) | ||
1212 | return -ENOMEM; | ||
1213 | |||
1214 | printk(KERN_INFO "JFFS2 write-buffering enabled (%i)\n", c->wbuf_pagesize); | ||
1215 | |||
1216 | return 0; | ||
1217 | } | ||
1218 | |||
1219 | void jffs2_dataflash_cleanup(struct jffs2_sb_info *c) { | ||
1220 | kfree(c->wbuf); | ||
1221 | } | ||
1222 | #endif | ||
1223 | |||
1195 | #ifdef CONFIG_JFFS2_FS_NOR_ECC | 1224 | #ifdef CONFIG_JFFS2_FS_NOR_ECC |
1196 | int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) { | 1225 | int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) { |
1197 | /* Cleanmarker is actually larger on the flashes */ | 1226 | /* Cleanmarker is actually larger on the flashes */ |