mtd/fs/jffs2 Makefile.24, 1.1, 1.2 Makefile.common, 1.7, 1.8 erase.c,
1.70, 1.71 fs.c, 1.51, 1.52 os-linux.h, 1.52, 1.53 scan.c,
1.116, 1.117 wbuf.c, 1.87, 1.88
Andrew Victor
pavlov at infradead.org
Wed Feb 9 04:17:44 EST 2005
Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv26392/fs/jffs2
Modified Files:
Makefile.24 Makefile.common erase.c fs.c os-linux.h scan.c
wbuf.c
Log Message:
Adds 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 at sanpeople.com>
Index: Makefile.24
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/Makefile.24,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Makefile.24 9 Aug 2004 18:46:05 -0000 1.1
+++ Makefile.24 9 Feb 2005 09:17:40 -0000 1.2
@@ -30,6 +30,7 @@
LINUX_OBJS += super-v24.o crc32.o rbtree.o
NAND_OBJS-$(CONFIG_JFFS2_FS_NAND) += wbuf.o
+NAND_OBJS-$(CONFIG_JFFS2_FS_DATAFLASH) += wbuf.o
COMPR_OBJS-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o
COMPR_OBJS-$(CONFIG_JFFS2_RTIME) += compr_rtime.o
Index: Makefile.common
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/Makefile.common,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Makefile.common 3 Nov 2004 12:57:38 -0000 1.7
+++ Makefile.common 9 Feb 2005 09:17:40 -0000 1.8
@@ -13,6 +13,7 @@
jffs2-$(CONFIG_JFFS2_FS_NAND) += wbuf.o
jffs2-$(CONFIG_JFFS2_FS_NOR_ECC) += wbuf.o
+jffs2-$(CONFIG_JFFS2_FS_DATAFLASH) += wbuf.o
jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o
jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o
jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o
Index: erase.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/erase.c,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -r1.70 -r1.71
--- erase.c 9 Feb 2005 09:09:01 -0000 1.70
+++ erase.c 9 Feb 2005 09:17:40 -0000 1.71
@@ -310,7 +310,7 @@
int ret;
uint32_t bad_offset;
- if (!jffs2_cleanmarker_oob(c)) {
+ if ((!jffs2_cleanmarker_oob(c)) && (c->cleanmarker_size > 0)) {
marker_ref = jffs2_alloc_raw_node_ref();
if (!marker_ref) {
printk(KERN_WARNING "Failed to allocate raw node ref for clean marker\n");
@@ -351,7 +351,7 @@
bad_offset += i;
printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum, bad_offset);
bad:
- if (!jffs2_cleanmarker_oob(c))
+ if ((!jffs2_cleanmarker_oob(c)) && (c->cleanmarker_size > 0))
jffs2_free_raw_node_ref(marker_ref);
kfree(ebuf);
bad2:
@@ -387,6 +387,13 @@
jeb->used_size = 0;
jeb->dirty_size = 0;
jeb->wasted_size = 0;
+ } else if (c->cleanmarker_size == 0) {
+ jeb->first_node = jeb->last_node = NULL;
+
+ jeb->free_size = c->sector_size;
+ jeb->used_size = 0;
+ jeb->dirty_size = 0;
+ jeb->wasted_size = 0;
} else {
struct kvec vecs[1];
struct jffs2_unknown_node marker = {
Index: fs.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/fs.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -r1.51 -r1.52
--- fs.c 28 Nov 2004 12:19:37 -0000 1.51
+++ fs.c 9 Feb 2005 09:17:40 -0000 1.52
@@ -455,6 +455,12 @@
return -EINVAL;
}
#endif
+#ifndef CONFIG_JFFS2_FS_DATAFLASH
+ if (c->mtd->type == MTD_DATAFLASH) {
+ printk(KERN_ERR "jffs2: Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in.\n");
+ return -EINVAL;
+ }
+#endif
c->flash_size = c->mtd->size;
@@ -660,6 +666,14 @@
if (ret)
return ret;
}
+
+ /* and Dataflash */
+ if (jffs2_dataflash(c)) {
+ ret = jffs2_dataflash_setup(c);
+ if (ret)
+ return ret;
+ }
+
return ret;
}
@@ -673,4 +687,9 @@
if (jffs2_nor_ecc(c)) {
jffs2_nor_ecc_flash_cleanup(c);
}
+
+ /* and DataFlash */
+ if (jffs2_dataflash(c)) {
+ jffs2_dataflash_cleanup(c);
+ }
}
Index: os-linux.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/os-linux.h,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -r1.52 -r1.53
--- os-linux.h 9 Feb 2005 09:09:01 -0000 1.52
+++ os-linux.h 9 Feb 2005 09:17:41 -0000 1.53
@@ -97,12 +97,16 @@
#endif
}
+#ifdef CONFIG_JFFS2_FS_DATAFLASH
+#define SECTOR_ADDR(x) ( ((unsigned long)(x) / (unsigned long)(c->sector_size)) * c->sector_size )
+#else
#define SECTOR_ADDR(x) ( ((unsigned long)(x) & ~(c->sector_size-1)) )
+#endif
#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
#define jffs2_is_writebuffered(c) (c->wbuf != NULL)
-#if (!defined CONFIG_JFFS2_FS_NAND && !defined CONFIG_JFFS2_FS_NOR_ECC)
+#if (!defined CONFIG_JFFS2_FS_NAND && !defined CONFIG_JFFS2_FS_NOR_ECC && !defined CONFIG_JFFS2_FS_DATAFLASH)
#define jffs2_can_mark_obsolete(c) (1)
#define jffs2_cleanmarker_oob(c) (0)
#define jffs2_write_nand_cleanmarker(c,jeb) (-EIO)
@@ -119,6 +123,7 @@
#define jffs2_wbuf_timeout NULL
#define jffs2_wbuf_process NULL
#define jffs2_nor_ecc(c) (0)
+#define jffs2_dataflash(c) (0)
#define jffs2_nor_ecc_flash_setup(c) (0)
#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0)
@@ -154,6 +159,15 @@
#define jffs2_nor_ecc_flash_setup(c) (0)
#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0)
#endif /* NOR ECC */
+#ifdef CONFIG_JFFS2_FS_DATAFLASH
+#define jffs2_dataflash(c) (c->mtd->type == MTD_DATAFLASH)
+int jffs2_dataflash_setup(struct jffs2_sb_info *c);
+void jffs2_dataflash_cleanup(struct jffs2_sb_info *c);
+#else
+#define jffs2_dataflash(c) (0)
+#define jffs2_dataflash_setup(c) (0)
+#define jffs2_dataflash_cleanup(c) do {} while (0)
+#endif /* DATAFLASH */
#endif /* NAND */
/* erase.c */
Index: scan.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/scan.c,v
retrieving revision 1.116
retrieving revision 1.117
diff -u -r1.116 -r1.117
--- scan.c 9 Feb 2005 09:09:02 -0000 1.116
+++ scan.c 9 Feb 2005 09:17:41 -0000 1.117
@@ -68,7 +68,7 @@
static inline int min_free(struct jffs2_sb_info *c)
{
uint32_t min = 2 * sizeof(struct jffs2_raw_inode);
-#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC
+#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC || defined CONFIG_JFFS2_FS_DATAFLASH
if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize)
return c->wbuf_pagesize;
#endif
@@ -228,7 +228,7 @@
c->dirty_size -= c->nextblock->dirty_size;
c->nextblock->dirty_size = 0;
}
-#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC
+#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC || defined CONFIG_JFFS2_FS_DATAFLASH
if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) {
/* If we're going to start writing into a block which already
contains data, and the end of the data isn't page-aligned,
@@ -351,7 +351,10 @@
}
#endif
D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset));
- return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */
+ if (c->cleanmarker_size == 0)
+ return BLK_STATE_CLEANMARKER; /* don't bother with re-erase */
+ else
+ return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */
}
if (ofs) {
D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset,
Index: wbuf.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/wbuf.c,v
retrieving revision 1.87
retrieving revision 1.88
diff -u -r1.87 -r1.88
--- wbuf.c 9 Feb 2005 09:09:02 -0000 1.87
+++ wbuf.c 9 Feb 2005 09:17:41 -0000 1.88
@@ -435,7 +435,7 @@
if we have a switch to next page, we will not have
enough remaining space for this.
*/
- if (pad) {
+ if (pad && !jffs2_dataflash(c)) {
c->wbuf_len = PAD(c->wbuf_len);
/* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR
@@ -486,7 +486,7 @@
spin_lock(&c->erase_completion_lock);
/* Adjust free size of the block if we padded. */
- if (pad) {
+ if (pad && !jffs2_dataflash(c)) {
struct jffs2_eraseblock *jeb;
jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
@@ -604,8 +604,14 @@
return ret;
}
+#ifdef CONFIG_JFFS2_FS_DATAFLASH
+#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];
@@ -1192,6 +1198,29 @@
kfree(c->wbuf);
}
+#ifdef CONFIG_JFFS2_FS_DATAFLASH
+int jffs2_dataflash_setup(struct jffs2_sb_info *c) {
+ c->cleanmarker_size = 0; /* No cleanmarkers needed */
+
+ /* Initialize write buffer */
+ init_rwsem(&c->wbuf_sem);
+ c->wbuf_pagesize = c->sector_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);
+
+ return 0;
+}
+
+void jffs2_dataflash_cleanup(struct jffs2_sb_info *c) {
+ kfree(c->wbuf);
+}
+#endif
+
#ifdef CONFIG_JFFS2_FS_NOR_ECC
int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) {
/* Cleanmarker is actually larger on the flashes */
More information about the linux-mtd-cvs
mailing list