aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoern Engel <joern@wh.fh-wedel.de>2006-05-22 17:18:12 -0400
committerJoern Engel <joern@wh.fh-wedel.de>2006-05-22 17:18:12 -0400
commitc8b229de2b05c2b3e8d282ce260935a88ac030ca (patch)
tree09391866a6a9740df2a178c7894557025c9dc2c8
parent28318776a80bc3261f9af91ef79e6e38bb9f5bec (diff)
[MTD] Merge STMicro NOR_ECC code with Intel Sibley code
In 2002, STMicro started producing NOR flashes with internal ECC protection for small blocks (8 or 16 bytes). Support for those flashes was added by me. In 2005, Intel Sibley flashes copied this strategy and Nico added support for those. Merge the code for both. Signed-off-by: Joern Engel <joern@wh.fh-wedel.de>
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0020.c4
-rw-r--r--fs/jffs2/fs.c12
-rw-r--r--fs/jffs2/os-linux.h10
-rw-r--r--fs/jffs2/wbuf.c36
4 files changed, 6 insertions, 56 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index 3911c98ba578..d745285fccf8 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -239,8 +239,8 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
239 mtd->suspend = cfi_staa_suspend; 239 mtd->suspend = cfi_staa_suspend;
240 mtd->resume = cfi_staa_resume; 240 mtd->resume = cfi_staa_resume;
241 mtd->flags = MTD_CAP_NORFLASH; 241 mtd->flags = MTD_CAP_NORFLASH;
242 mtd->flags |= MTD_ECC; /* FIXME: Not all STMicro flashes have this */ 242 mtd->flags |= MTD_PROGRAM_REGIONS; /* FIXME: Not all STMicro flashes have this */
243 mtd->eccsize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */ 243 mtd->writesize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */
244 map->fldrv = &cfi_staa_chipdrv; 244 map->fldrv = &cfi_staa_chipdrv;
245 __module_get(THIS_MODULE); 245 __module_get(THIS_MODULE);
246 mtd->name = map->name; 246 mtd->name = map->name;
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index a0f84673ce54..79f70251a4eb 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -664,13 +664,6 @@ static int jffs2_flash_setup(struct jffs2_sb_info *c) {
664 return ret; 664 return ret;
665 } 665 }
666 666
667 /* add setups for other bizarre flashes here... */
668 if (jffs2_nor_ecc(c)) {
669 ret = jffs2_nor_ecc_flash_setup(c);
670 if (ret)
671 return ret;
672 }
673
674 /* and Dataflash */ 667 /* and Dataflash */
675 if (jffs2_dataflash(c)) { 668 if (jffs2_dataflash(c)) {
676 ret = jffs2_dataflash_setup(c); 669 ret = jffs2_dataflash_setup(c);
@@ -694,11 +687,6 @@ void jffs2_flash_cleanup(struct jffs2_sb_info *c) {
694 jffs2_nand_flash_cleanup(c); 687 jffs2_nand_flash_cleanup(c);
695 } 688 }
696 689
697 /* add cleanups for other bizarre flashes here... */
698 if (jffs2_nor_ecc(c)) {
699 jffs2_nor_ecc_flash_cleanup(c);
700 }
701
702 /* and DataFlash */ 690 /* and DataFlash */
703 if (jffs2_dataflash(c)) { 691 if (jffs2_dataflash(c)) {
704 jffs2_dataflash_cleanup(c); 692 jffs2_dataflash_cleanup(c);
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index d2ad2a2081d8..1a6eb955e0be 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -92,11 +92,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
92#define jffs2_flash_writev(a,b,c,d,e,f) jffs2_flash_direct_writev(a,b,c,d,e) 92#define jffs2_flash_writev(a,b,c,d,e,f) jffs2_flash_direct_writev(a,b,c,d,e)
93#define jffs2_wbuf_timeout NULL 93#define jffs2_wbuf_timeout NULL
94#define jffs2_wbuf_process NULL 94#define jffs2_wbuf_process NULL
95#define jffs2_nor_ecc(c) (0)
96#define jffs2_dataflash(c) (0) 95#define jffs2_dataflash(c) (0)
97#define jffs2_nor_wbuf_flash(c) (0)
98#define jffs2_nor_ecc_flash_setup(c) (0)
99#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0)
100#define jffs2_dataflash_setup(c) (0) 96#define jffs2_dataflash_setup(c) (0)
101#define jffs2_dataflash_cleanup(c) do {} while (0) 97#define jffs2_dataflash_cleanup(c) do {} while (0)
102#define jffs2_nor_wbuf_flash_setup(c) (0) 98#define jffs2_nor_wbuf_flash_setup(c) (0)
@@ -110,7 +106,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
110#define jffs2_can_mark_obsolete(c) (0) 106#define jffs2_can_mark_obsolete(c) (0)
111#else 107#else
112#define jffs2_can_mark_obsolete(c) \ 108#define jffs2_can_mark_obsolete(c) \
113 ((c->mtd->type == MTD_NORFLASH && !(c->mtd->flags & (MTD_ECC|MTD_PROGRAM_REGIONS))) || \ 109 ((c->mtd->type == MTD_NORFLASH && !(c->mtd->flags & (MTD_PROGRAM_REGIONS))) || \
114 c->mtd->type == MTD_RAM) 110 c->mtd->type == MTD_RAM)
115#endif 111#endif
116 112
@@ -135,10 +131,6 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c);
135int jffs2_nand_flash_setup(struct jffs2_sb_info *c); 131int jffs2_nand_flash_setup(struct jffs2_sb_info *c);
136void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c); 132void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c);
137 133
138#define jffs2_nor_ecc(c) (c->mtd->type == MTD_NORFLASH && (c->mtd->flags & MTD_ECC))
139int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c);
140void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c);
141
142#define jffs2_dataflash(c) (c->mtd->type == MTD_DATAFLASH) 134#define jffs2_dataflash(c) (c->mtd->type == MTD_DATAFLASH)
143int jffs2_dataflash_setup(struct jffs2_sb_info *c); 135int jffs2_dataflash_setup(struct jffs2_sb_info *c);
144void jffs2_dataflash_cleanup(struct jffs2_sb_info *c); 136void jffs2_dataflash_cleanup(struct jffs2_sb_info *c);
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 355226d8ce29..087c2e438a6d 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -637,17 +637,6 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
637 memset(c->wbuf,0xff,c->wbuf_pagesize); 637 memset(c->wbuf,0xff,c->wbuf_pagesize);
638 } 638 }
639 639
640 /* Fixup the wbuf if we are moving to a new eraseblock. The checks below
641 fail for ECC'd NOR because cleanmarker == 16, so a block starts at
642 xxx0010. */
643 if (jffs2_nor_ecc(c)) {
644 if (((c->wbuf_ofs % c->sector_size) == 0) && !c->wbuf_len) {
645 c->wbuf_ofs = PAGE_DIV(to);
646 c->wbuf_len = PAGE_MOD(to);
647 memset(c->wbuf,0xff,c->wbuf_pagesize);
648 }
649 }
650
651 /* Sanity checks on target address. 640 /* Sanity checks on target address.
652 It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs), 641 It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs),
653 and it's permitted to write at the beginning of a new 642 and it's permitted to write at the beginning of a new
@@ -1244,29 +1233,10 @@ void jffs2_dataflash_cleanup(struct jffs2_sb_info *c) {
1244 kfree(c->wbuf); 1233 kfree(c->wbuf);
1245} 1234}
1246 1235
1247int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) {
1248 /* Cleanmarker is actually larger on the flashes */
1249 c->cleanmarker_size = 16;
1250
1251 /* Initialize write buffer */
1252 init_rwsem(&c->wbuf_sem);
1253 c->wbuf_pagesize = c->mtd->eccsize;
1254 c->wbuf_ofs = 0xFFFFFFFF;
1255
1256 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
1257 if (!c->wbuf)
1258 return -ENOMEM;
1259
1260 return 0;
1261}
1262
1263void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c) {
1264 kfree(c->wbuf);
1265}
1266
1267int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) { 1236int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) {
1268 /* Cleanmarker currently occupies a whole programming region */ 1237 /* Cleanmarker currently occupies whole programming regions,
1269 c->cleanmarker_size = c->mtd->writesize; 1238 * either one or 2 for 8Byte STMicro flashes. */
1239 c->cleanmarker_size = max(16u, c->mtd->writesize);
1270 1240
1271 /* Initialize write buffer */ 1241 /* Initialize write buffer */
1272 init_rwsem(&c->wbuf_sem); 1242 init_rwsem(&c->wbuf_sem);