From brm at infradead.org  Tue Sep  2 12:36:43 2003
From: brm at infradead.org (Brian Murphy)
Date: Mon May 15 21:48:43 2006
Subject: mtd/drivers/mtd/maps lasat.c,1.5,1.6
Message-ID: <E19uE95-00031K-2K@phoenix.infradead.org>

Update of /home/cvs/mtd/drivers/mtd/maps
In directory phoenix.infradead.org:/tmp/cvs-serv11593

Modified Files:
	lasat.c 
Log Message:
update LASAT map to correspond with the latest development code

Index: lasat.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/maps/lasat.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- lasat.c	21 May 2003 12:45:19 -0000	1.5
+++ lasat.c	2 Sep 2003 16:36:40 -0000	1.6
@@ -1,8 +1,7 @@
 /*
- * Flash device on lasat 100 and 200 boards
+ * Flash device on Lasat 100 and 200 boards
  *
- * Presumably (C) 2002 Brian Murphy <brian@murphy.dk> or whoever he
- * works for.
+ * (C) 2002 Brian Murphy <brian@murphy.dk>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License version
@@ -22,44 +21,53 @@
 #include <linux/mtd/partitions.h>
 #include <linux/config.h>
 #include <asm/lasat/lasat.h>
-#include <asm/lasat/lasat_mtd.h>
 
-static struct mtd_info *mymtd;
-
-static struct map_info sp_map = {
-	.name = "SP flash",
-	.buswidth = 4,
-};
+static struct mtd_info *lasat_mtd;
 
 static struct mtd_partition partition_info[LASAT_MTD_LAST];
 static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Filesystem", "Config"};
 
-static int __init init_sp(void)
+static void lasat_set_vpp(struct map_info *map, int vpp)
 {
-	int i;
-	/* this does not play well with the old flash code which 
-	 * protects and uprotects the flash when necessary */
-	/* FIXME: Implement set_vpp() */
-       	printk(KERN_NOTICE "Unprotecting flash\n");
-	*lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit;
-
-	sp_map.virt = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER);
-	sp_map.phys = virt_to_phys(sp_map.virt);
-	sp_map.size = lasat_board_info.li_flash_size;
+	if (vpp)
+	    *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit;
+	else
+	    *lasat_misc->flash_wp_reg &= ~(1 << lasat_misc->flash_wp_bit);
+}
+
+static struct map_info lasat_map = {
+	.name = "LASAT flash",
+	.buswidth = 4,
+	.set_vpp = lasat_set_vpp
+};
 
-	simple_map_init(&sp_map);
+static int __init init_lasat(void)
+{
+	int i;
+	/* since we use AMD chips and set_vpp is not implimented
+	 * for these (yet) we still have to permanently enable flash write */
+	printk(KERN_NOTICE "Unprotecting flash\n");
+	ENABLE_VPP((&lasat_map));
+
+	lasat_map.phys = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER);
+	lasat_map.virt = (unsigned long)ioremap_nocache(
+		        lasat_map.phys, lasat_board_info.li_flash_size);
+	lasat_map.size = lasat_board_info.li_flash_size;
 
-       	printk(KERN_NOTICE "sp flash device: %lx at %lx\n", 
-			sp_map.size, sp_map.phys);
+	simple_map_init(&lasat_map);
 
 	for (i=0; i < LASAT_MTD_LAST; i++)
 		partition_info[i].name = lasat_mtd_partnames[i];
 
-	mymtd = do_map_probe("cfi_probe", &sp_map);
-	if (mymtd) {
+	lasat_mtd = do_map_probe("cfi_probe", &lasat_map);
+
+	if (!lasat_mtd)
+	    lasat_mtd = do_map_probe("jedec_probe", &lasat_map);
+
+	if (lasat_mtd) {
 		u32 size, offset = 0;
 
-		mymtd->owner = THIS_MODULE;
+		lasat_mtd->owner = THIS_MODULE;
 
 		for (i=0; i < LASAT_MTD_LAST; i++) {
 			size = lasat_flash_partition_size(i);
@@ -68,26 +76,26 @@
 			offset += size;
 		}
 
-		add_mtd_partitions( mymtd, partition_info, LASAT_MTD_LAST );
+		add_mtd_partitions( lasat_mtd, partition_info, LASAT_MTD_LAST );
 		return 0;
 	}
 
 	return -ENXIO;
 }
 
-static void __exit cleanup_sp(void)
+static void __exit cleanup_lasat(void)
 {
-	if (mymtd) {
-		del_mtd_partitions(mymtd);
-		map_destroy(mymtd);
+	if (lasat_mtd) {
+		del_mtd_partitions(lasat_mtd);
+		map_destroy(lasat_mtd);
 	}
-	if (sp_map.virt) {
-		sp_map.virt = 0;
+	if (lasat_map.virt) {
+		lasat_map.virt = 0;
 	}
 }
 
-module_init(init_sp);
-module_exit(cleanup_sp);
+module_init(init_lasat);
+module_exit(cleanup_lasat);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Brian Murphy <brian@murphy.dk>");


From brm at infradead.org  Tue Sep  2 13:59:44 2003
From: brm at infradead.org (Brian Murphy)
Date: Mon May 15 21:48:43 2006
Subject: mtd/drivers/mtd/maps Config.in,1.54,1.55 Kconfig,1.12,1.13
Message-ID: <E19uFRQ-00043B-8g@phoenix.infradead.org>

Update of /home/cvs/mtd/drivers/mtd/maps
In directory phoenix.infradead.org:/tmp/cvs-serv15560

Modified Files:
	Config.in Kconfig 
Log Message:
allowing non CFI configurations for the LASAT map

Index: Config.in
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/maps/Config.in,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -r1.54 -r1.55
--- Config.in	28 Aug 2003 06:50:24 -0000	1.54
+++ Config.in	2 Sep 2003 17:59:41 -0000	1.55
@@ -87,7 +87,7 @@
       int '    Bus width in octets' CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH 2
    fi
    dep_tristate '  Momenco Ocelot boot flash device' CONFIG_MTD_OCELOT $CONFIG_MOMENCO_OCELOT
-   dep_tristate '  LASAT flash device' CONFIG_MTD_LASAT $CONFIG_MTD_CFI $CONFIG_LASAT
+   dep_tristate '  LASAT flash device' CONFIG_MTD_LASAT $CONFIG_LASAT
 fi
 
 if [ "$CONFIG_SUPERH" = "y" ]; then

Index: Kconfig
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/maps/Kconfig,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- Kconfig	23 Jun 2003 07:38:11 -0000	1.12
+++ Kconfig	2 Sep 2003 17:59:41 -0000	1.13
@@ -177,7 +177,7 @@
 
 config MTD_LASAT
 	tristate "Flash chips on LASAT board"
-	depends on LASAT && MTD_CFI
+	depends on LASAT
 	help
 	  Support for the flash chips on the Lasat 100 and 200 boards.
 


From dwmw2 at infradead.org  Fri Sep  5 11:30:43 2003
From: dwmw2 at infradead.org (David Woodhouse)
Date: Mon May 15 21:48:43 2006
Subject: mtd/util README,1.3,NONE
Message-ID: <E19vIXr-0005Qx-Jh@phoenix.infradead.org>

Update of /home/cvs/mtd/util
In directory phoenix.infradead.org:/tmp/cvs-serv20869

Removed Files:
	README 
Log Message:
Remove README which was mostly full of crap

--- README DELETED ---


From dwmw2 at infradead.org  Mon Sep  8 07:37:26 2003
From: dwmw2 at infradead.org (David Woodhouse)
Date: Mon May 15 21:48:44 2006
Subject: mtd/drivers/mtd mtd_blkdevs.c,1.17,1.18 mtd_blkdevs-24.c,1.12,1.13
Message-ID: <E19wKKk-0003Nv-Jg@phoenix.infradead.org>

Update of /home/cvs/mtd/drivers/mtd
In directory phoenix.infradead.org:/tmp/cvs-serv12992

Modified Files:
	mtd_blkdevs.c mtd_blkdevs-24.c 
Log Message:
block size fixes

Index: mtd_blkdevs.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/mtd_blkdevs.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- mtd_blkdevs.c	9 Jul 2003 09:00:49 -0000	1.17
+++ mtd_blkdevs.c	8 Sep 2003 11:37:23 -0000	1.18
@@ -295,7 +295,10 @@
 	snprintf(gd->devfs_name, sizeof(gd->devfs_name),
 		 "%s/%c", tr->name, (tr->part_bits?'a':'0') + new->devnum);
 
-	set_capacity(gd, new->size);
+	/* 2.5 has capacity in units of 512 bytes while still
+	   having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */
+	set_capacity(gd, (new->size * new->blksize) >> 9);
+
 	gd->private_data = new;
 	new->blkcore_priv = gd;
 	gd->queue = &tr->blkcore_priv->rq;

Index: mtd_blkdevs-24.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/mtd_blkdevs-24.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- mtd_blkdevs-24.c	8 Jul 2003 08:16:49 -0000	1.12
+++ mtd_blkdevs-24.c	8 Sep 2003 11:37:24 -0000	1.13
@@ -465,7 +465,12 @@
 		tr->blkcore_priv->part_table[i].start_sect = 0;
 	}
 
-	tr->blkcore_priv->sizes[new->devnum << tr->part_bits] = new->size;
+	/* 2.4 kernel takes block device size in BLOCK_SIZE_BITS 
+	   (usually 10), rather than in units of its own blksize. */
+	tr->blkcore_priv->sizes[new->devnum << tr->part_bits] = 
+		(new->size * new->blksize) >> BLOCK_SIZE_BITS;
+
+	/* But this is still in device's sectors? $DEITY knows */
 	tr->blkcore_priv->part_table[new->devnum << tr->part_bits].nr_sects = new->size;
 
 	if (tr->part_bits) {


From dwmw2 at infradead.org  Mon Sep  8 08:45:59 2003
From: dwmw2 at infradead.org (David Woodhouse)
Date: Mon May 15 21:48:44 2006
Subject: mtd/drivers/mtd mtd_blkdevs-24.c,1.13,1.14
Message-ID: <E19wLP5-0003Ys-DF@phoenix.infradead.org>

Update of /home/cvs/mtd/drivers/mtd
In directory phoenix.infradead.org:/tmp/cvs-serv13671

Modified Files:
	mtd_blkdevs-24.c 
Log Message:
	  <viro_zzz> dwmw2: BLOCK_SIZE_BITS has nothing to do with block devices
	  <viro> dwmw2: any code which sets blk_size[][] should be 
			size >> 10 /+ 2.4 and its dumb units */


Index: mtd_blkdevs-24.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/mtd_blkdevs-24.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- mtd_blkdevs-24.c	8 Sep 2003 11:37:24 -0000	1.13
+++ mtd_blkdevs-24.c	8 Sep 2003 12:45:56 -0000	1.14
@@ -124,7 +124,7 @@
 	   actually want to deal with signals. We can't just call 
 	   exit_sighand() since that'll cause an oops when we finally
 	   do exit. */
-#if 1
+#if 0
 	spin_lock_irq(&current->sigmask_lock);
 	sigfillset(&current->blocked);
 	recalc_sigpending(current);
@@ -465,10 +465,13 @@
 		tr->blkcore_priv->part_table[i].start_sect = 0;
 	}
 
-	/* 2.4 kernel takes block device size in BLOCK_SIZE_BITS 
-	   (usually 10), rather than in units of its own blksize. */
+	/*
+	  <viro_zzz> dwmw2: BLOCK_SIZE_BITS has nothing to do with block devices
+	  <viro> dwmw2: any code which sets blk_size[][] should be 
+			size >> 10 /+ 2.4 and its dumb units */
+
 	tr->blkcore_priv->sizes[new->devnum << tr->part_bits] = 
-		(new->size * new->blksize) >> BLOCK_SIZE_BITS;
+		(new->size * new->blksize) >> 10; /* 2.4 and its dumb units */
 
 	/* But this is still in device's sectors? $DEITY knows */
 	tr->blkcore_priv->part_table[new->devnum << tr->part_bits].nr_sects = new->size;


From dwmw2 at infradead.org  Fri Sep 12 05:09:39 2003
From: dwmw2 at infradead.org (David Woodhouse)
Date: Mon May 15 21:48:44 2006
Subject: mtd/util mkfs.jffs2.c,1.38,1.39
Message-ID: <E19xjvv-0008Dn-PY@phoenix.infradead.org>

Update of /home/cvs/mtd/util
In directory phoenix.infradead.org:/tmp/cvs-serv31584

Modified Files:
	mkfs.jffs2.c 
Log Message:
Observe block-boundary rules even when writing out zero-size files.


Index: mkfs.jffs2.c
===================================================================
RCS file: /home/cvs/mtd/util/mkfs.jffs2.c,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -r1.38 -r1.39
--- mkfs.jffs2.c	8 May 2003 07:35:28 -0000	1.38
+++ mkfs.jffs2.c	12 Sep 2003 09:09:37 -0000	1.39
@@ -896,6 +896,8 @@
 	}
 	if (!je32_to_cpu(ri.version)) {
 		/* Was empty file */
+		pad_block_if_less_than(sizeof(ri));
+
 		ri.version = cpu_to_je32(++ver);
 		ri.totlen = cpu_to_je32(sizeof(ri));
 		ri.hdr_crc = cpu_to_je32(crc32(0, 


From dwmw2 at infradead.org  Mon Sep 15 11:13:45 2003
From: dwmw2 at infradead.org (David Woodhouse)
Date: Mon May 15 21:48:44 2006
Subject: mtd/fs/jffs2 os-linux.h,1.31,1.32
Message-ID: <E19yv2v-0008No-LI@phoenix.infradead.org>

Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv32205

Modified Files:
	os-linux.h 
Log Message:
make nonand build work around

Index: os-linux.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/os-linux.h,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- os-linux.h	25 Aug 2003 11:31:46 -0000	1.31
+++ os-linux.h	15 Sep 2003 15:13:43 -0000	1.32
@@ -112,13 +112,13 @@
 #define jffs2_flash_write(c, ofs, len, retlen, buf) ((c)->mtd->write((c)->mtd, ofs, len, retlen, buf))
 #define jffs2_flash_read(c, ofs, len, retlen, buf) ((c)->mtd->read((c)->mtd, ofs, len, retlen, buf))
 #define jffs2_flush_wbuf_pad(c) ({ (void)(c), 0; })
-#define jffs2_flush_wbuf_gc(c) ({ (void)(c), 0; })
+#define jffs2_flush_wbuf_gc(c, i) ({ (void)(c), (void) i, 0; })
 #define jffs2_nand_read_failcnt(c,jeb) do { ; } while(0)
 #define jffs2_write_nand_badblock(c,jeb) do { ; } while(0)
 #define jffs2_nand_flash_setup(c) (0)
 #define jffs2_nand_flash_cleanup(c) do {} while(0)
 #define jffs2_wbuf_dirty(c) (0)
-#define jffs2_flash_writev(a,b,c,d,e) jffs2_flash_direct_writev(a,b,c,d,e,0)
+#define jffs2_flash_writev(a,b,c,d,e,f) jffs2_flash_direct_writev(a,b,c,d,e)
 #define jffs2_wbuf_timeout NULL
 #define jffs2_wbuf_process NULL
 


From tharbaugh at lnxi.com  Wed Sep 17 18:18:00 2003
From: tharbaugh at lnxi.com (Thayne Harbaugh)
Date: Mon May 15 21:48:44 2006
Subject: mtd/drivers/mtd/chips cfi_cmdset_0002.c,1.76,1.77
Message-ID: <E19zkca-0001jO-CD@phoenix.infradead.org>

Update of /home/cvs/mtd/drivers/mtd/chips
In directory phoenix.infradead.org:/tmp/cvs-serv6645/drivers/mtd/chips

Modified Files:
	cfi_cmdset_0002.c 
Log Message:
command sequences should attempt to be atomic - wrap with cli()/sti()
Some flash chips are sensitive to these sequences being interlaced
with other LPC activity - even activity that isn't addressed for
the flash device.  At times other LPC activity can cause an LPC
bus reset which may cause some flash devices to abort command
sequences.

Index: cfi_cmdset_0002.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0002.c,v
retrieving revision 1.76
retrieving revision 1.77
diff -u -r1.76 -r1.77
--- cfi_cmdset_0002.c	22 Jul 2003 13:23:38 -0000	1.76
+++ cfi_cmdset_0002.c	17 Sep 2003 22:17:57 -0000	1.77
@@ -588,6 +588,23 @@
 	       __func__, adr, datum );
 
 	ENABLE_VPP(map);
+	/*
+	 * This sequence needs to be atomic - or as near as can be (SMP may
+	 * have problems here).  If the sequence isn't atomic then some
+	 * other LPC access may occur which can cause some flash chips to
+	 * abort the operation.
+	 * What has been identified is that __SLOW_DOWN_IO from
+	 * include/asm-i386/io.h writes to port 0x80, nothing is at 0x80
+	 * and an LPC reset is generated.  When this traffic is during
+	 * a setup sequence for an erase or program then the SST49LF040
+	 * aborts the operation.  It's most likely that the SST49LF040
+	 * is sensitive to the LPC reset rather than the port 0x80 write.
+	 * It is unknown if other flash chips behave in the same manner.
+	 * It is known that some flash chips ignore the LPC traffic
+	 * that is destined for other devices - the Pm49FL004 is known
+	 * to ignore the extra traffic and LPC reset.
+	 */
+	cli();
 	if (fast) { /* Unlock bypass */
 		cfi_send_gen_cmd(0xA0, 0, chip->start, map, cfi, cfi->device_type, NULL);
 	}
@@ -597,6 +614,7 @@
 	        cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	}
 	cfi_write(map, datum, adr);
+	sti();
 
 	cfi_spin_unlock(chip->mutex);
 	cfi_udelay(chip->word_write_time);
@@ -795,9 +813,12 @@
 	
 	if (cfi->fast_prog) {
 		/* Go into unlock bypass mode */
+		/* This sequence needs to be atomic */
+		cli();
 		cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
 		cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
 		cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
+		sti();
 	}
 
 	/* We are now aligned, write as much as possible */
@@ -818,8 +839,11 @@
 		if (ret) {
 			if (cfi->fast_prog){
 				/* Get out of unlock bypass mode */
+				/* This sequence needs to be atomic */
+				cli();
 				cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL);
 				cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL);
+				sti();
 			}
 			return ret;
 		}
@@ -832,8 +856,11 @@
 		if (ofs >> cfi->chipshift) {
 			if (cfi->fast_prog){
 				/* Get out of unlock bypass mode */
+				/* This sequence needs to be atomic */
+				cli();
 				cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL);
 				cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL);
+				sti();
 			}
 
 			chipnum ++; 
@@ -843,17 +870,23 @@
 			chipstart = cfi->chips[chipnum].start;
 			if (cfi->fast_prog){
 				/* Go into unlock bypass mode for next set of chips */
+				/* This sequence needs to be atomic */
+				cli();
 				cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
 				cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
 				cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
+				sti();
 			}
 		}
 	}
 
 	if (cfi->fast_prog){
 		/* Get out of unlock bypass mode */
+		/* This sequence needs to be atomic */
+		cli();
 		cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL);
 		cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL);
+		sti();
 	}
 
 	/* Write the trailing bytes if any */
@@ -925,12 +958,15 @@
 	 * the chip erase command.
 	 */
 	ENABLE_VPP(map);
+	/* This sequence needs to be atomic */
+	cli();
 	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0x10, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	sti();
 	timeo = jiffies + (HZ*20);
 	adr = cfi->addr_unlock1;
 
@@ -1104,6 +1140,8 @@
 	       __func__, adr );
 
 	ENABLE_VPP(map);
+	/* This sequence needs to be atomic */
+	cli();
 	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
@@ -1111,6 +1149,7 @@
 	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 
 	cfi_write(map, CMD(0x30), adr);
+	sti();
 	
 	timeo = jiffies + (HZ*20);
 


From tharbaugh at lnxi.com  Wed Sep 17 19:05:10 2003
From: tharbaugh at lnxi.com (Thayne Harbaugh)
Date: Mon May 15 21:48:44 2006
Subject: mtd/drivers/mtd/chips cfi_cmdset_0002.c,1.77,1.78
Message-ID: <E19zlME-000257-NH@phoenix.infradead.org>

Update of /home/cvs/mtd/drivers/mtd/chips
In directory phoenix.infradead.org:/tmp/cvs-serv7991

Modified Files:
	cfi_cmdset_0002.c 
Log Message:
phoey!  not paying attention and breaking 2.6

Index: cfi_cmdset_0002.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0002.c,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -r1.77 -r1.78
--- cfi_cmdset_0002.c	17 Sep 2003 22:17:57 -0000	1.77
+++ cfi_cmdset_0002.c	17 Sep 2003 23:05:08 -0000	1.78
@@ -588,23 +588,6 @@
 	       __func__, adr, datum );
 
 	ENABLE_VPP(map);
-	/*
-	 * This sequence needs to be atomic - or as near as can be (SMP may
-	 * have problems here).  If the sequence isn't atomic then some
-	 * other LPC access may occur which can cause some flash chips to
-	 * abort the operation.
-	 * What has been identified is that __SLOW_DOWN_IO from
-	 * include/asm-i386/io.h writes to port 0x80, nothing is at 0x80
-	 * and an LPC reset is generated.  When this traffic is during
-	 * a setup sequence for an erase or program then the SST49LF040
-	 * aborts the operation.  It's most likely that the SST49LF040
-	 * is sensitive to the LPC reset rather than the port 0x80 write.
-	 * It is unknown if other flash chips behave in the same manner.
-	 * It is known that some flash chips ignore the LPC traffic
-	 * that is destined for other devices - the Pm49FL004 is known
-	 * to ignore the extra traffic and LPC reset.
-	 */
-	cli();
 	if (fast) { /* Unlock bypass */
 		cfi_send_gen_cmd(0xA0, 0, chip->start, map, cfi, cfi->device_type, NULL);
 	}
@@ -614,7 +597,6 @@
 	        cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	}
 	cfi_write(map, datum, adr);
-	sti();
 
 	cfi_spin_unlock(chip->mutex);
 	cfi_udelay(chip->word_write_time);
@@ -813,12 +795,9 @@
 	
 	if (cfi->fast_prog) {
 		/* Go into unlock bypass mode */
-		/* This sequence needs to be atomic */
-		cli();
 		cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
 		cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
 		cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
-		sti();
 	}
 
 	/* We are now aligned, write as much as possible */
@@ -839,11 +818,8 @@
 		if (ret) {
 			if (cfi->fast_prog){
 				/* Get out of unlock bypass mode */
-				/* This sequence needs to be atomic */
-				cli();
 				cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL);
 				cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL);
-				sti();
 			}
 			return ret;
 		}
@@ -856,11 +832,8 @@
 		if (ofs >> cfi->chipshift) {
 			if (cfi->fast_prog){
 				/* Get out of unlock bypass mode */
-				/* This sequence needs to be atomic */
-				cli();
 				cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL);
 				cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL);
-				sti();
 			}
 
 			chipnum ++; 
@@ -870,23 +843,17 @@
 			chipstart = cfi->chips[chipnum].start;
 			if (cfi->fast_prog){
 				/* Go into unlock bypass mode for next set of chips */
-				/* This sequence needs to be atomic */
-				cli();
 				cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
 				cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
 				cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
-				sti();
 			}
 		}
 	}
 
 	if (cfi->fast_prog){
 		/* Get out of unlock bypass mode */
-		/* This sequence needs to be atomic */
-		cli();
 		cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL);
 		cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL);
-		sti();
 	}
 
 	/* Write the trailing bytes if any */
@@ -958,15 +925,12 @@
 	 * the chip erase command.
 	 */
 	ENABLE_VPP(map);
-	/* This sequence needs to be atomic */
-	cli();
 	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0x10, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-	sti();
 	timeo = jiffies + (HZ*20);
 	adr = cfi->addr_unlock1;
 
@@ -1140,8 +1104,6 @@
 	       __func__, adr );
 
 	ENABLE_VPP(map);
-	/* This sequence needs to be atomic */
-	cli();
 	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
@@ -1149,7 +1111,6 @@
 	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 
 	cfi_write(map, CMD(0x30), adr);
-	sti();
 	
 	timeo = jiffies + (HZ*20);
 


From trini at infradead.org  Mon Sep 22 12:56:37 2003
From: trini at infradead.org (trini@infradead.org)
Date: Mon May 15 21:48:44 2006
Subject: mtd/drivers/mtd/maps Kconfig,1.13,1.14 Config.in,1.55,1.56
Message-ID: <E1A1TzI-0006nG-Uz@phoenix.infradead.org>

Update of /home/cvs/mtd/drivers/mtd/maps
In directory phoenix.infradead.org:/tmp/cvs-serv26083/drivers/mtd/maps

Modified Files:
	Kconfig Config.in 
Log Message:
Now that the D-Box2 is supported in the kernel (or will be soon),
test for that board before asking about it's map file.


Index: Kconfig
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/maps/Kconfig,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- Kconfig	2 Sep 2003 17:59:41 -0000	1.13
+++ Kconfig	22 Sep 2003 16:56:32 -0000	1.14
@@ -265,7 +265,7 @@
 
 config MTD_DBOX2
 	tristate "CFI Flash device mapped on D-Box2"
-	depends on PPC32 && 8xx && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD
+	depends on PPC32 && 8xx && DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD
 	help
 	  This enables access routines for the flash chips on the Nokia/Sagem
 	  D-Box 2 board. If you have one of these boards and would like to use

Index: Config.in
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/maps/Config.in,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -r1.55 -r1.56
--- Config.in	2 Sep 2003 17:59:41 -0000	1.55
+++ Config.in	22 Sep 2003 16:56:33 -0000	1.56
@@ -50,7 +50,9 @@
     if [ "$CONFIG_MBX" = "y" ]; then
       dep_tristate '  System flash on MBX860 board' CONFIG_MTD_MBX860 $CONFIG_MTD_CFI
     fi
-    dep_tristate '  CFI Flash device mapped on D-Box2' CONFIG_MTD_DBOX2 $CONFIG_MTD_CFI
+    if [ "$CONFIG_DBOX2" = "y" ]; then
+      dep_tristate '  CFI Flash device mapped on D-Box2' CONFIG_MTD_DBOX2 $CONFIG_MTD_CFI
+    fi
     dep_tristate '  CFI Flash device mapping on FlagaDM' CONFIG_MTD_CFI_FLAGADM $CONFIG_MTD_CFI
   fi
   if [ "$CONFIG_4xx" = "y" ]; then


From tharbaugh at lnxi.com  Thu Sep 25 10:40:37 2003
From: tharbaugh at lnxi.com (Thayne Harbaugh)
Date: Mon May 15 21:48:44 2006
Subject: mtd/drivers/mtd/chips Config.in,1.16,1.17 Kconfig,1.3,1.4
	Makefile.common,1.2,1.3 cfi_cmdset_0002.c,1.78,1.79
	cfi_util.c,1.1,1.2
Message-ID: <E1A2XIK-0003m2-Vx@phoenix.infradead.org>

Update of /home/cvs/mtd/drivers/mtd/chips
In directory phoenix.infradead.org:/tmp/cvs-serv14496

Modified Files:
	Config.in Kconfig Makefile.common cfi_cmdset_0002.c cfi_util.c 
Log Message:
- Add CONFIG_MTD_CFI_AMDSTD_RETRY for dealing with broken flash chips.
  Unfortunately this is for the SST49LF0*0 series using an LPC interface.
  These SST chips have a horribly broken LPC interface that don't
  filter out traffic for other devices on the LPC bus.  Did I mention
  how horribly broken the SST chips are?

- Tied the CONFIG_MTD_CFI_AMDSTD_RETRY options into the kernel config
  mechanism, added documentation, and did some minor cleanup of the
  config files.

- Fixed cfi_util so that it is an individual module that can be used
  by cfi_cmdset_* without requiring cfi_probe - there is a different
  setup through jedec_probe.  This had some accompanying changes in
  the config files.

Index: Config.in
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/Config.in,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- Config.in	3 Sep 2002 13:30:43 -0000	1.16
+++ Config.in	25 Sep 2003 14:40:34 -0000	1.17
@@ -11,13 +11,12 @@
 
 if [ "$CONFIG_MTD_CFI" = "y" -o "$CONFIG_MTD_JEDECPROBE" = "y" ]; then
    define_bool CONFIG_MTD_GEN_PROBE y
+elif [ "$CONFIG_MTD_CFI" = "m" -o "$CONFIG_MTD_JEDECPROBE" = "m" ]; then
+   define_bool CONFIG_MTD_GEN_PROBE m
 else
-   if [ "$CONFIG_MTD_CFI" = "m" -o "$CONFIG_MTD_JEDECPROBE" = "m" ]; then
-      define_bool CONFIG_MTD_GEN_PROBE m
-   else
-      define_bool CONFIG_MTD_GEN_PROBE n
-   fi
+   define_bool CONFIG_MTD_GEN_PROBE n
 fi
+
 if [ "$CONFIG_MTD_GEN_PROBE" = "y" -o "$CONFIG_MTD_GEN_PROBE" = "m" ]; then
    bool '  Flash chip driver advanced configuration options' CONFIG_MTD_CFI_ADV_OPTIONS
    if [ "$CONFIG_MTD_CFI_ADV_OPTIONS" = "y" ]; then
@@ -44,7 +43,26 @@
 fi
 dep_tristate '  Support for Intel/Sharp flash chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_GEN_PROBE
 dep_tristate '  Support for AMD/Fujitsu flash chips' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_GEN_PROBE
+if [ "$CONFIG_MTD_CFI_AMDSTD" = "y" -o "$CONFIG_MTD_CFI_AMDSTD" = "m" ]; then
+   bool '   Retry failed commands (erase/program)' CONFIG_MTD_CFI_AMDSTD_RETRY n
+   if [ "$CONFIG_MTD_CFI_AMDSTD_RETRY" = "y" ]; then
+      int '    Max retries of failed commands (erase/program)' CONFIG_MTD_CFI_AMDSTD_RETRY_MAX 0
+   fi
+fi
+
 dep_tristate '  Support for ST (Advanced Architecture) flash chips' CONFIG_MTD_CFI_STAA $CONFIG_MTD_GEN_PROBE
+
+if [ "$CONFIG_MTD_CFI_INTELEXT" = "y" \
+	-o "$CONFIG_MTD_CFI_AMDSTD" = "y" \
+	-o "$CONFIG_MTD_CFI_STAA" = "y" ]; then
+   define_bool CONFIG_MTD_CFI_UTIL y
+elif [ "$CONFIG_MTD_CFI_INTELEXT" = "m" \
+	-o "$CONFIG_MTD_CFI_AMDSTD" = "m" \
+	-o "$CONFIG_MTD_CFI_STAA" = "m" ]; then
+   define_bool CONFIG_MTD_CFI_UTIL m
+else
+   define_bool CONFIG_MTD_CFI_UTIL n
+fi
 
 dep_tristate '  Support for RAM chips in bus mapping' CONFIG_MTD_RAM $CONFIG_MTD
 dep_tristate '  Support for ROM chips in bus mapping' CONFIG_MTD_ROM $CONFIG_MTD

Index: Kconfig
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/Kconfig,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Kconfig	28 May 2003 15:13:24 -0000	1.3
+++ Kconfig	25 Sep 2003 14:40:34 -0000	1.4
@@ -160,6 +160,25 @@
 	  provides support for one of those command sets, used on chips 
 	  including the AMD Am29LV320.
 
+config MTD_CFI_AMDSTD_RETRY
+	int "Retry failed commands (erase/program)"
+	depends on MTD_CFI_AMDSTD
+	help
+	  Some chips, when attached to a shared bus, don't properly filter
+	  bus traffic that is destined to other devices.  This broken
+	  behavior causes erase and program sequences to be aborted when
+	  the sequences are mixed with traffic for other devices.
+
+	  SST49LF040 (and related) chips are know to be broken.
+
+config MTD_CFI_AMDSTD_RETRY_MAX
+	int "Max retries of failed commands (erase/program)"
+	depends on MTD_CFI_AMDSTD_RETRY
+	help
+	  If you have an SST49LF040 (or related chip) then this value should
+	  be set to at least 1.  This can also be adjusted at driver load
+	  time with the retry_cmd_max module parameter.
+
 config MTD_CFI_STAA
 	tristate "Support for ST (Advanced Architecture) flash chips"
 	depends on MTD_GEN_PROBE
@@ -167,6 +186,11 @@
 	  The Common Flash Interface defines a number of different command
 	  sets which a CFI-compliant chip may claim to implement. This code
 	  provides support for one of those command sets.
+
+config MTD_UTIL
+	tristate
+	default y if MTD_CFI_INTELEXT=y || MTD_CFI_AMDSTD=y || MTD_CFI_STAA=y
+	default m if MTD_CFI_INTELEXT=m || MTD_CFI_AMDSTD=m || MTD_CFI_STAA=m
 
 config MTD_RAM
 	tristate "Support for RAM chips in bus mapping"

Index: Makefile.common
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/Makefile.common,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Makefile.common	22 Jul 2003 13:23:38 -0000	1.2
+++ Makefile.common	25 Sep 2003 14:40:34 -0000	1.3
@@ -5,7 +5,7 @@
 
 ifeq ($(PATCHLEVEL),4)
 O_TARGET	:= chipslink.o
-export-objs	:= chipreg.o gen_probe.o
+export-objs	:= chipreg.o gen_probe.o cfi_util.o
 endif
 
 #                       *** BIG UGLY NOTE ***
@@ -17,7 +17,8 @@
 
 obj-$(CONFIG_MTD)		+= chipreg.o
 obj-$(CONFIG_MTD_AMDSTD)	+= amd_flash.o 
-obj-$(CONFIG_MTD_CFI)		+= cfi_probe.o cfi_util.o
+obj-$(CONFIG_MTD_CFI)		+= cfi_probe.o
+obj-$(CONFIG_MTD_CFI_UTIL)	+= cfi_util.o
 obj-$(CONFIG_MTD_CFI_STAA)	+= cfi_cmdset_0020.o
 obj-$(CONFIG_MTD_CFI_AMDSTD)	+= cfi_cmdset_0002.o
 obj-$(CONFIG_MTD_CFI_INTELEXT)	+= cfi_cmdset_0001.o

Index: cfi_cmdset_0002.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0002.c,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -r1.78 -r1.79
--- cfi_cmdset_0002.c	17 Sep 2003 23:05:08 -0000	1.78
+++ cfi_cmdset_0002.c	25 Sep 2003 14:40:34 -0000	1.79
@@ -12,6 +12,7 @@
  *
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -31,6 +32,52 @@
 
 #define AMD_BOOTLOC_BUG
 
+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
+
+#ifndef CONFIG_MTD_CFI_AMDSTD_RETRY_MAX
+#define CONFIG_MTD_CFI_AMDSTD_RETRY_MAX 0
+#endif
+
+static int retry_cmd_max = CONFIG_MTD_CFI_AMDSTD_RETRY_MAX;
+
+#define HANDLE_WACKY_STATE \
+do { \
+	if ( retry_cmd_cnt == retry_cmd_max ) { \
+		printk(KERN_WARNING \
+		       "MTD %s(): Wacky!  Unable to decode failure status\n" \
+		       "Possible buggy device - try setting driver" \
+		       " retry_cmd_max\n", \
+		       __func__ ); \
+		printk(KERN_WARNING \
+		       "MTD %s(): 0x%.8lx(0x%.8x): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", \
+		       __func__, adr, datum, \
+		       prev_oldstatus, prev_status, \
+		       oldstatus, status); \
+	} \
+} while (0)
+
+#else /* CONFIG_MTD_CFI_AMDSTD_RETRY */
+
+#define HANDLE_WACKY_STATE \
+do { \
+	printk(KERN_WARNING \
+	       "MTD %s(): Wacky!  Unable to decode failure status\n" \
+	       "Possible buggy device - try enabling" \
+	       " CONFIG_MTD_CFI_AMDSTD_RETRY\n" \
+	       "in your kernel config and setting driver retry_cmd_max\n", \
+	       __func__ ); \
+	printk(KERN_WARNING \
+	       "MTD %s(): 0x%.8lx(0x%.8x): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", \
+	       __func__, adr, datum, \
+	       prev_oldstatus, prev_status, \
+	       oldstatus, status); \
+} while (0)
+
+#endif /* !defined(CONFIG_MTD_CFI_AMDSTD_RETRY) */
+
+
+
+
 static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int cfi_amdstd_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
 static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *);
@@ -185,7 +232,7 @@
 		}
 		/*
 		 * FIXME - These might already be setup (more correctly)
-		 * buy jedec_probe.c.
+		 * by jedec_probe.c.
 		 */
 		switch (cfi->device_type) {
 		case CFI_DEVICETYPE_X8:
@@ -556,6 +603,9 @@
 	DECLARE_WAITQUEUE(wait, current);
 	int ret = 0;
 	int ta = 0;
+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
+	int retry_cmd_cnt = 0;
+#endif
 
  retry:
 	cfi_spin_lock(chip->mutex);
@@ -584,6 +634,9 @@
 	chip->state = FL_WRITING;
 
 	adr += chip->start;
+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
+ retry_cmd:
+#endif
 	DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8x)\n",
 	       __func__, adr, datum );
 
@@ -691,7 +744,7 @@
 
 	if ( oldstatus == datum && status == datum ) {
 		/* success - do nothing */
-		goto write_done;
+		goto op_done;
 	}
 
 	if ( ta ) {
@@ -707,7 +760,7 @@
 				"MTD %s(): Software timed out during write.\n",
 				__func__ );
 		}
-		goto write_failed;
+		goto op_failed;
 	}
 
 	/*
@@ -715,23 +768,32 @@
 	 * is wrong and it's not a timeout.  Something
 	 * is seriously wacky!  Dump some debug info.
 	 */
-	printk(KERN_WARNING
-	       "MTD %s(): Wacky!  Unable to decode failure status\n",
-	       __func__ );
-
-	printk(KERN_WARNING
-	       "MTD %s(): 0x%.8lx(0x%.8x): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
-	       __func__, adr, datum,
-	       prev_oldstatus, prev_status,
-	       oldstatus, status);
+	/*
+	 * Found a clue about the chips that reach this state.
+	 * Some flash chips (SST >cough<)
+	 * are horribly broken.  They do not ignore traffic that is
+	 * destined to other devices.  This happens because some solutions
+	 * are on shared busses, the erase and program sequences have
+	 * have multiple commands, and the sequence is interspersed with
+	 * commands destined to other devices.  A good flash chip will
+	 * examine the command and destination address and will ignore
+	 * commands that are for other devices.
+	 */
+	HANDLE_WACKY_STATE;
 
- write_failed:
-	ret = -EIO;
+ op_failed:
 	/* reset on all failures. */
 	cfi_write( map, CMD(0xF0), chip->start );
 	/* FIXME - should have reset delay before continuing */
+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
+	retry_cmd_cnt++;
+	if (retry_cmd_cnt <= retry_cmd_max) {
+		goto retry_cmd;
+	}
+#endif
+	ret = -EIO;
 
- write_done:
+ op_done:
 	DISABLE_VPP(map);
 	chip->state = FL_READY;
 	wake_up(&chip->wq);
@@ -885,6 +947,11 @@
 	return 0;
 }
 
+
+/*
+ * Handle devices with one erase region, that only implement
+ * the chip erase command.
+ */
 static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
 {
 	unsigned int oldstatus, status, prev_oldstatus, prev_status;
@@ -895,7 +962,10 @@
 	DECLARE_WAITQUEUE(wait, current);
 	int ret = 0;
 	int ta = 0;
-	cfi_word ones = 0;
+	cfi_word datum = 0;
+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
+	int retry_cmd_cnt = 0;
+#endif
 
  retry:
 	cfi_spin_lock(chip->mutex);
@@ -918,12 +988,13 @@
 	}	
 
 	chip->state = FL_ERASING;
+
 	DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
 	       __func__, chip->start );
-	
-	/* Handle devices with one erase region, that only implement
-	 * the chip erase command.
-	 */
+
+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
+ retry_cmd:
+#endif
 	ENABLE_VPP(map);
 	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
@@ -966,7 +1037,7 @@
 			add_wait_queue(&chip->wq, &wait);
 			
 			cfi_spin_unlock(chip->mutex);
-			printk("erase suspended. Sleeping\n");
+			printk(KERN_DEBUG "erase suspended. Sleeping\n");
 			
 			schedule();
 			remove_wait_queue(&chip->wq, &wait);
@@ -1010,19 +1081,19 @@
 	       __func__, oldstatus, status );
 
 	if ( cfi_buswidth_is_1() ) {
-		ones =  (__u8)~0;
+		datum =  (__u8)~0;
 	} else if ( cfi_buswidth_is_2() ) {
-		ones = (__u16)~0;
+		datum = (__u16)~0;
 	} else if ( cfi_buswidth_is_4() ) {
-		ones = (__u32)~0;
+		datum = (__u32)~0;
 	} else {
 		printk(KERN_WARNING "Unsupported buswidth\n");
-		goto erase_failed;
+		goto op_failed;
 	}
-	
-	if ( oldstatus == ones && status == ones ) {
+
+	if ( oldstatus == datum && status == datum ) {
 		/* success - do nothing */
-		goto erase_done;
+		goto op_done;
 	}
 
 	if ( ta ) {
@@ -1038,26 +1109,24 @@
 				"MTD %s(): Software timed out during write.\n",
 				__func__ );
 		}
-		goto erase_failed;
+		goto op_failed;
 	}
 
-	printk(KERN_WARNING
-	       "MTD %s(): Wacky!  Unable to decode failure status\n",
-	       __func__ );
-
-	printk(KERN_WARNING
-	       "MTD %s(): 0x%.8lx(0x%.8x): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
-	       __func__, adr, ones,
-	       prev_oldstatus, prev_status,
-	       oldstatus, status);
+	HANDLE_WACKY_STATE;
 
- erase_failed:
-	ret = -EIO;
+ op_failed:
 	/* reset on all failures. */
 	cfi_write( map, CMD(0xF0), chip->start );
 	/* FIXME - should have reset delay before continuing */
+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
+	retry_cmd_cnt++;
+	if (retry_cmd_cnt <= retry_cmd_max) {
+		goto retry_cmd;
+	}
+#endif
+	ret = -EIO;
 
- erase_done:
+ op_done:
 	DISABLE_VPP(map);
 	chip->state = FL_READY;
 	wake_up(&chip->wq);
@@ -1075,7 +1144,10 @@
 	DECLARE_WAITQUEUE(wait, current);
 	int ret = 0;
 	int ta = 0;
-	cfi_word ones = 0;
+	cfi_word datum = 0;
+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
+	int retry_cmd_cnt = 0;
+#endif
 
  retry:
 	cfi_spin_lock(chip->mutex);
@@ -1098,11 +1170,14 @@
 	}	
 
 	chip->state = FL_ERASING;
-
 	adr += chip->start;
+
 	DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
 	       __func__, adr );
 
+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
+ retry_cmd:
+#endif
 	ENABLE_VPP(map);
 	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
 	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
@@ -1167,9 +1242,9 @@
 			
 			/* Latency issues. Drop the lock, wait a while and retry */
 			cfi_spin_unlock(chip->mutex);
-			
+
 			cfi_udelay(1);
-		
+
 			cfi_spin_lock(chip->mutex);
 			oldstatus = cfi_read(map, adr);
 			status = cfi_read(map, adr);
@@ -1190,19 +1265,19 @@
 	       __func__, oldstatus, status );
 
 	if ( cfi_buswidth_is_1() ) {
-		ones =  (__u8)~0;
+		datum =  (__u8)~0;
 	} else if ( cfi_buswidth_is_2() ) {
-		ones = (__u16)~0;
+		datum = (__u16)~0;
 	} else if ( cfi_buswidth_is_4() ) {
-		ones = (__u32)~0;
+		datum = (__u32)~0;
 	} else {
 		printk(KERN_WARNING "Unsupported buswidth\n");
-		goto erase_failed;
+		goto op_failed;
 	}
 
-	if ( oldstatus == ones && status == ones ) {
+	if ( oldstatus == datum && status == datum ) {
 		/* success - do nothing */
-		goto erase_done;
+		goto op_done;
 	}
 
 	if ( ta ) {
@@ -1218,26 +1293,24 @@
 				"MTD %s(): Software timed out during write.\n",
 				__func__ );
 		}
-		goto erase_failed;
+		goto op_failed;
 	}
 
-	printk(KERN_WARNING
-	       "MTD %s(): Wacky!  Unable to decode failure status\n",
-	       __func__ );
+	HANDLE_WACKY_STATE;
 
-	printk(KERN_WARNING
-	       "MTD %s(): 0x%.8lx(0x%.8x): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
-	       __func__, adr, ones,
-	       prev_oldstatus, prev_status,
-	       oldstatus, status);
-
- erase_failed:
-	ret = -EIO;
+ op_failed:
 	/* reset on all failures. */
 	cfi_write( map, CMD(0xF0), chip->start );
 	/* FIXME - should have reset delay before continuing */
+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
+	retry_cmd_cnt++;
+	if (retry_cmd_cnt <= retry_cmd_max) {
+		goto retry_cmd;
+	}
+#endif
+	ret = -EIO;
 
- erase_done:
+ op_done:
 	DISABLE_VPP(map);
 	chip->state = FL_READY;
 	wake_up(&chip->wq);
@@ -1573,3 +1646,7 @@
 MODULE_AUTHOR("Crossnet Co. <info@crossnet.co.jp> et al.");
 MODULE_DESCRIPTION("MTD chip driver for AMD/Fujitsu flash chips");
 
+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
+MODULE_PARM(retry_cmd_max, "i");
+MODULE_PARM_DESC(retry_cmd_max, "Number of times to retry an erase or program command if it fails - should only be needed by buggy hardware: default 0");
+#endif

Index: cfi_util.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_util.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- cfi_util.c	22 Jul 2003 13:23:38 -0000	1.1
+++ cfi_util.c	25 Sep 2003 14:40:34 -0000	1.2
@@ -71,6 +71,8 @@
 	return extp;
 }
 
+EXPORT_SYMBOL(cfi_read_pri);
+
 void cfi_fixup(struct map_info *map, struct cfi_fixup* fixups)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
@@ -83,3 +85,5 @@
 		}
 	}
 }
+
+EXPORT_SYMBOL(cfi_fixup);


From dwmw2 at infradead.org  Mon Sep 29 06:17:43 2003
From: dwmw2 at infradead.org (David Woodhouse)
Date: Mon May 15 21:48:45 2006
Subject: mtd/html index.html,1.29,1.30
Message-ID: <E1A3v67-0001CC-Bl@phoenix.infradead.org>

Update of /home/cvs/mtd/html
In directory phoenix.infradead.org:/tmp/cvs-serv4577

Modified Files:
	index.html 
Log Message:
Update main web page. Remove ancient changelogs, update hardware support list slightly, mention IRC channel.


Index: index.html
===================================================================
RCS file: /home/cvs/mtd/html/index.html,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- index.html	8 Mar 2003 18:32:20 -0000	1.29
+++ index.html	29 Sep 2003 10:17:40 -0000	1.30
@@ -25,14 +25,16 @@
     </P>
 
     <HR size=2>
-    <H2>Mailing list</H2>
-    <P>There is a majordomo-managed mailing list: 
-      <B><I>lists-mtd@lists.infradead.org</i></B> - Full archives are available
-      at <A HREF="http://lists.infradead.org/pipermail/linux-mtd/">
-	http://lists.infradead.org/pipermail/linux-mtd/</A>. Now that I've
-      finally managed to get Mailman to display them properly, this includes
-      all the previous messages from before the changeover to Mailman.
+    <H2>Mailing list and IRC</H2>
+
 
+    <P>There is a mailing list for discussion of MTD development: <B><I><A
+    HREF="http://www.infradead.org/~dwmw2/email.html">linux-mtd@lists.infradead.org</A></i></B>. Please
+    do not post to the mailing list without first reading my <A
+    HREF="http://www.infradead.org/~dwmw2/email.html">notes on
+    etiquette</A>. Full archives are available
+      at <A HREF="http://lists.infradead.org/pipermail/linux-mtd/">
+	http://lists.infradead.org/pipermail/linux-mtd/</A>. 
       </P><P>
 
       To subscribe, go <A 
@@ -47,6 +49,9 @@
 	  HREF="mailto:linux-mtd-request@lists.infradead.org">
 	  linux-mtd-request@lists.infradead.org</A>
 	AS THE ABOVE SAYS.</B></P>
+
+    <P>There is also an IRC channel: <TT>#mtd</TT> on <TT>irc.ipv6.freenode.net</TT> or <tt>irc.freenode.net</tt></P>
+
     <HR size=2>
     <H2>Download and CVS</H2>
 
@@ -123,187 +128,6 @@
       used on it, along with a first-stage loader to load Grub itself into
       memory from the DiskOnChip, are in the CVS repository.</P>
 
-    <HR size=2>
-    <H2>TODO</H2>
-    <P>I'm impressed. The TODO list is getting much shorter.</P>
-    <uL>
-      <LI>Add an MTD driver for PCMCIA memory cards</LI>
-      <LI>Make the FFS2 code work on 2.3 kernels.</LI>
-      <LI>Implement XIP support in the 'map' layer and a read-only filesystem to use it.</LI>
-      <LI>Decrease the amount of flash space reserved by JFFS2 garbage collection
-    </uL>
-
-    <HR SIZE=2>
-    <h2>Changelog</H2>
-    <UL>  
-      <LI><B>Latest CVS</B><BR>
-	<UL>
-	  <LI>JFFS v2 -
-	    <UL>
-	      <LI>Compression</LI>
-	      <LI>Improved wear levelling - we deal with individual erase blocks now</LI>
-	      <LI>Improved concurrency - no longer all under one big semaphore</LI>
-	      <LI>Smaller RAM footprint - at least theoretically. And we forget stuff under memory pressure to be nice</LI>
-	      <LI>Hard link support</LI>
-	    </UL>
-	  </LI>
-	      
-	  <LI>New 'mtdblock' driver which allows you to use any normal
-	    filesystem on flash chips, albeit rather non-robust if you're
-	    writing to it. See <A HREF="#mtdblock">below</A> for more 
-	    information.</LI>
-	  <LI>New map drivers, including the Itsy (and iPAQ) driver.</LI>
-	  <LI>Massive NFTL overhaul. ECC, bad block handling, journalling fixes, etc.</LI>
-	  <LI>Verified DiskOnChip 2000 and Millennium support - some wonderful
-	    person seems to have gone through the code and the docs and ensured
-	    that we meet all the timing constraints that I ignored when I 
-	    threw the original code together.</LI>
-	  <LI>Support all sensible geometries for AMD/Fujitsu command set CFI flash</LI>
-	  <LI>Start (most?) of JFFS support for NAND flash</LI>
-	  <LI>Hardware support for a handful of NAND flash chips</LI>
-	  <LI>Beat JFFS up till it actually passes filesystem stress tests</LI>
-	  <LI>Allow CFI reads to suspend in-progress erases.</LI>
-	  <LI>Merged DiskOnChip 2000 and Millennium driver into one</LI>
-	  <LI>Partitioning of flash chips into multiple devices</LI>
-	  <LI>Map area drivers for various SBC boards</LI>
-	  <LI>New DiskOnChip Millennium driver, contributed by Ollie Lho</LI>
-	  <LI>Assorted JFFS fixes</LI>
-	  <LI>CFI code for AMD/Fujitsu Standard command set, mapped in 2x16 mode, contributed by Masami Komiya</LI>
-	</UL>
-	<BR>
-      </LI>
-      <LI><B>mtd-20000704</B><BR>
-	Patch: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-20000704.diff">mtd-20000704.diff</A><BR>
-	Tarball: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-20000704.tar.gz">mtd-20000704.tar.gz</A><BR>
-	<UL>
-	  <LI>Kernel patches for both 2.2.16 and 2.4.0 kernels to add MTD support, and
-	    a script file to move the source files into the right place.</LI>
-	  <LI>New <TT>map</TT> architecture for making mmap'd areas 
-	    available for use by generic chipset drivers</LI>
-	  <LI>Probe code for Common Flash Interface devices</LI>
-	  <LI>Run-time address alias detection for CFI chips</LI>
-	  <LI>Driver code for Intel Extended Command Set devices - connected
-	    any way you like as long as it's in 16-bit mode and not
-	    interleaved</LI>
-	  <LI>JFFS ported to 2.2 kernel</LI>
-	  <LI>Remove the /dev/mtd<I>x</I> character device driver from
-	    <TT>mtd.o</TT> and make it separately configurable as 
-	    <TT>mtdchar.o</TT></LI>
-	  <LI>Rename <TT>mtd.o</TT> to <TT>mtdcore.o</TT> just in case I
-	    didn't confuse enough people with the above</LI>
-	  <LI>Split the DiskOnChip probe routine into a separate file,
-	    allowing DiskOnChip 2000 and DiskOnChip Millennium drivers to
-	    be developed separately.</LI>
-	  <LI>Separate <TT>CONFIG_NFTL_RW</TT> option allowing you to
-	    compile safe read-only drivers (by turning it off)</LI>
-	  <LI>Imported Axis' <A 
-	      HREF="http://www.developer.axis.com/software/jffs/">Journalling
-	      Flash File System (JFFS)</A></LI>
-	  <LI>Updated FTL driver to the latest version from David Hinds' 
-	    <A HREF="http://pcmcia.sourceforge.org/">PCMCIA</A> code. Still
-	    some elusive bugs which cause it to corrupt the FTL - must get
-	    some PCMCIA flash hardware and check it worked <B>before</B> I
-	    started playing with it.</LI>
-	  <LI>Litter FTL driver with cpu_to_le16() et al calls in an 
-	    attempt to make it work on big-endian hardware</LI>
-	  <LI>Some cleanups to make the code conform to the <A HREF="tech/">new
-	      rules</A>.</LI>
-	  <LI>Add <TT>get_mtd_device()</TT> and <TT>put_mtd_device</TT> back
-	    again, having gone over the locking rules with a fine tooth
-	    comb and decided that they were OK if done properly.</LI>
-	  <LI>Added patch to GNU Grub which teaches it about the DiskOnChip.
-	    When it can also decode NFTL, it'll be more useful.</LI>
-	</UL>
-	<BR>
-      </LI>
-      <LI><B>mtd-20000131</B><BR>
-	Patch: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-20000131.diff">mtd-20000131.diff</A><BR>
-	Tarball: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-20000131.tar.gz">mtd-20000131.tar.gz</A><BR>
-	Complete patch against 2.3.41 kernel: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-20000131-against-2.3.41.diff.gz">
-	  mtd-20000131-against-2.3.41.diff.gz</A><BR>
-	<UL>
-	  <LI>Updated to work with 2.3.recent kernel. Apart from the obvious
-	    changes, this also includes turning off the block device request
-	    merging code, which seems to be duplicating requests rather than
-	    just merging them.</LI>
-	  <LI>Remove the byteorder workaround - there's a patch included which
-	    should fix the kernel.</LI>
-	  <LI>Added Grub loader for DiskOnChip - now someone just has to add
-	    DiskOnChip support to Grub itself.</LI>
-	</UL>
-	<BR>
-      </LI>
-      <LI><B>mtd-20000119</B><BR>
-	Patch: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-20000119.diff">mtd-20000119.diff</A><BR>
-	Tarball: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-20000119.tar.gz">mtd-20000119.tar.gz</A><BR>
-	<UL>
-	  <LI>NFTL now registers the block device <I>before</I> asking the 
-	    gendisk code to scan it for partitions - it works better like 
-	    that :)</LI>
-	  <LI>Various code cleanups, fixes for PPC and older kernels - mostly
-	  thanks to Pavel Roskin.</LI>
-	  <LI>No patch against 2.2 or 2.3.current kernels - I'll resume that 
-	    practice as soon as I've got more time to look after it.</LI>
-	</UL>
-	<BR>
-      </LI>
-      <LI><B>mtd-19991025</B><BR>
-	Patch: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-19991025.diff">mtd-19991025.diff</A><BR>
-	Tarball: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-19991025.tar.gz">mtd-19991025.tar.gz</A><BR>
-	Complete patch against 2.3.23 kernel: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-19991025-against-2.3.23.diff.gz">
-	  mtd-19991025-against-2.3.23.diff.gz</A><BR>
-	<UL>
-	  <LI>Ported to 2.3 kernels (still compiles with 2.2)</LI>
-	  <LI>NFTL write support seems fairly reliable and interoperates with
-	    M-Systems' own drivers - more testing required</LI>
-	  <LI>Various bugfixes</LI>
-	</UL>
-	<BR>
-      </LI>
-      <LI><B>mtd-19990820</B><BR>
-	Patch: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-19990820.diff">mtd-19990820.diff</A><BR>
-	Tarball: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-19990820.tar.gz">mtd-19990820.tar.gz</A><BR>
-	<UL>
-	  <LI>Add <TT>nftl_format</TT> program 
-	    <I>(M-Systems' own drivers don't like the resulting NFTL yet)</I></LI>
-	  <LI>First version of write support for NFTL <I>(Likewise)</I></LI>
-	</UL>
-	<BR>
-      </LI>
-      <LI><B>mtd-19990817</B><BR>
-	Patch: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-19990817.diff">mtd-19990817.diff</A><BR>
-	Tarball: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-19990817.tar.gz">mtd-19990817.tar.gz</A><BR>
-	<UL>
-	  <LI>Support ECC for NFTL on DiskOnChip</LI>
-	  <LI>Behave correctly with multiple DiskOnChip</LI>
-	  <LI>Add primitive MAKEDEV script</LI>
-	  <LI>Move include directory to make it easier to compile into kernel</LI>
-	  <LI>Add <TT>/proc/mtd</TT> support</LI>
-      </UL>
-	<BR>
-      </LI>
-      <LI><B>mtd-19990810</B><BR>
-	Patch: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-19990810.diff">mtd-19990810.diff</A><BR>
-	Tarball: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-19990810.tar.gz">mtd-19990810.tar.gz</A><BR>
-	<UL>
-	  <LI>Various endianness and wordsize fixes</LI>
-	  <LI>Compile fixes for Linux/Alpha - DiskOnChip &amp; NFTL now works</LI>
-	  <LI>Sanity checks in NFTL driver to prevent oopsen on certain MTDs</LI>
-      </UL>
-	<BR>
-      </LI>
-      <LI><B>mtd-19990809</B><BR>
-	Tarball: <A HREF="ftp://ftp.linux-mtd.infradead.org/pub/mtd/mtd-19990809.tar.gz">mtd-19990809.tar.gz</A><BR>
-	<B>Large merge, including:</B>
-	<UL>
-	  <LI>Preliminary drivers for DiskOnChip 2000 and NFTL filesystem</LI>
-	  <LI>Microsoft FFS2 filesystem</LI>
-	  <LI>Octagon-5066 and vmax301 drivers for SBC boards</LI>
-	  <LI>Various other improvements from jgg.</LI>
-	  <LI>Boot loader code</LI>
-	</UL>
-      </LI>
-    </UL>
 
     <HR size=2>
 
@@ -342,18 +166,10 @@
 	working for both reading and writing, but could probably do with 
 	some more field testing before being used on production systems. 
       </LI>
-      <LI><B>Microsoft Flash Filing System</B><BR>
-	This provides a filesystem directly from the flash, rather than the 
-	less efficient filesystem-on-FTL-on-flash setup. The current driver is
-	in alpha-testing, but should allow read-only access to such 
-	filesystems.
-      </LI>
-      <LI><B>Journalling Flash File System</B><BR>
-	This was developed by <A HREF="http://www.axis.com/">Axis 
-	  Communications</A>, and provides a filesystem directly on the 
+      <LI><B>Journalling Flash File System, v2</B><BR>
+	This provides a filesystem directly on the 
 	flash, rather than emulating a block device. For more information,
-	see <A HREF="http://www.developer.axis.com/software/jffs/">Axis'
-	  developer pages</A>.
+	see <A HREF="http://sources.redhat.com/jffs2/">sources.redhat.com</A>.
       </LI>
     </UL>
     <HR SIZE=2>
@@ -367,47 +183,25 @@
 	memory with the linux-mtd system.
       </LI>
       <LI><B>PCMCIA devices</B><BR>
-	There are already a number of PCMCIA memory devices supported by Linux.
-	The MTD device subsystem is being designed with compatibility in mind,
-	so that the <A 
-	  HREF="http://hyper.stanford.edu/~dhinds/pcmcia/home.html">existing 
-	  PCMCIA drivers</A> can cleanly interface to the new MTD
-	subsystem. This work has not yet been undertaken, though.</LI>
+	PCMCIA flash (not CompactFlash but <em>real</em> flash) cards are
+	now supported by the <TT>pcmciamtd</TT> driver in CVS.
       <LI><B>Common Flash Interface (<A 
 	    HREF="http://www.pentium.com/design/flcomp/technote/cfi_1_1.htm">CFI</A>)
-	  onboard memory</B><BR>
-	This is one of the most interesting options for small embedded systems.
-	With a filesystem directly on the flash, rather than through an extra
-	layer like FTL, we can get execute-in-place (XIP) of programs and 
-	libraries on the flash, without needing to use up valuable system 
-	memory as a cache for the executable code.<BR>
-	A patch to the Linux kernel which supports this is available, and it 
-	should shortly be ported to the generic MTD system as a hardware
-	driver.</LI>
-      <LI><B>M-Systems' ISA Flash cards and DiskOnChip 1000</B><BR>
-	These devices are very simple - they seem to consist of a large array
-	of Intel flash memory, with a simple paging mechanism reminiscent of 
-	EMS, which allows different pages of the flash to be mapped into the 
-	device's 8K memory window. While working for Nortel a couple of years
-	ago, I developed drivers for these devices.<BR>
-	Unfortunately, I don't think the Disk-On-Chip 1000 is available any 
-	more.</LI>
+	  onboard NOR flash</B><BR>
+	This is a common solution and is well-tested and supported, most
+	often using JFFS2 or cramfs file systems.
+      </LI>
+      <LI><B>Onboard NAND flash</B><BR>
+	NAND flash is rapidly overtaking NOR flash due to its larger size 
+	and lower cost; JFFS2 support for NAND flash is approaching production
+	quality.
+      </LI>
       <LI><B>M-Systems' DiskOnChip 2000 and Millennium</B><BR>
-	M-Systems have now provided me with full documentation for the 
-	DiskOnChip 2000 and Millennium. The current driver is capable of
-	full operation on a DiskOnChip 2000, and I have received a
-	sample DiskOnChip Millennium from M-Systems, so I should get round to
-	adding Millennium support soon. The write support for NFTL appears
-	to pass my simple tests for interoperability - after I mount it with
-	my drivers, thrash it for a while, and unmount it, the NFTL is still
-	recognised by M-Systems' own drivers. More testing of this would be
-	very much appreciated.
-	<BR>
-	<I>The <A HREF="doc2000.html">Linux and Disk-On-Chip
-	  2000 page</A> is available here. Please note that, now that 
-	M-Systems have provided me with complete specifications with which to
-	write a free driver for the device, there is no longer any reason 
-	to avoid using it with Linux systems.</I>
+	The DiskOnChip 2000, Millennium and Millennium Plus devices should
+	be fully supported, using their native NFTL and INFTL 'translation
+	layers'. Support for JFFS2 on DiskOnChip 2000 and Millennium is 
+	also operational although lacking proper support for bad block 
+	handling.
 	<HR>
 	</LI>
 


From tharbaugh at lnxi.com  Mon Sep 29 12:50:05 2003
From: tharbaugh at lnxi.com (Thayne Harbaugh)
Date: Mon May 15 21:48:45 2006
Subject: mtd/drivers/mtd/chips cfi_cmdset_0002.c,1.79,1.80
	jedec_probe.c,1.29,1.30
Message-ID: <E1A41Dp-0003RQ-5V@phoenix.infradead.org>

Update of /home/cvs/mtd/drivers/mtd/chips
In directory phoenix.infradead.org:/tmp/cvs-serv13211/drivers/mtd/chips

Modified Files:
	cfi_cmdset_0002.c jedec_probe.c 
Log Message:

- Add SST49LF004B - still needs work before it can erase and program

- Lots of cleanup inspired by Carolyn J. Smith's 4 x 16 work

  - Added 64 bit support in 'case 8' and cfi_buswidth_is_8()

  - All of those cfi_send_gen_cmd(. . . , CFI_DEVICETYPE_X8, . . .)
    seem somewhat crufty and can be replaced by the cfi->device_type
    which will be correct when the device_type != CFI_DEVICETYPE_X8

  - All of the read and write datatypes should be cfi_word and not
    unsigned int



Index: cfi_cmdset_0002.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0002.c,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -r1.79 -r1.80
--- cfi_cmdset_0002.c	25 Sep 2003 14:40:34 -0000	1.79
+++ cfi_cmdset_0002.c	29 Sep 2003 16:50:01 -0000	1.80
@@ -6,6 +6,8 @@
  *
  * 2_by_8 routines added by Simon Munton
  *
+ * 4_by_16 work by Carolyn J. Smith
+ *
  * This code is GPL
  *
  * $Id$
@@ -344,6 +346,9 @@
 	case 1:
 	case 2:
 	case 4:
+#ifdef CFI_WORD_64
+	case 8:
+#endif
 #if 1
 		if (mtd->numeraseregions > 1)
 			mtd->erase = cfi_amdstd_erase_varsize;
@@ -588,8 +593,8 @@
 static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, cfi_word datum, int fast)
 {
 	unsigned long timeo = jiffies + HZ;
-	unsigned int oldstatus, status, prev_oldstatus, prev_status;
-	unsigned int dq6;
+	cfi_word oldstatus, status, prev_oldstatus, prev_status;
+	cfi_word dq6;
 	struct cfi_private *cfi = map->fldrv_priv;
     /* We use a 1ms + 1 jiffies generic timeout for writes (most devices have
        a max write time of a few hundreds usec). However, we should use the
@@ -645,9 +650,9 @@
 		cfi_send_gen_cmd(0xA0, 0, chip->start, map, cfi, cfi->device_type, NULL);
 	}
 	else {
-	        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-	        cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-	        cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
+	        cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
+	        cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
 	}
 	cfi_write(map, datum, adr);
 
@@ -830,10 +835,15 @@
 		while (len && i < CFIDEV_BUSWIDTH)
 			tmp_buf[i++] = buf[n++], len--;
 
+		/* already know that buswidth > 1 */
 		if (cfi_buswidth_is_2()) {
 			datum = *(__u16*)tmp_buf;
 		} else if (cfi_buswidth_is_4()) {
 			datum = *(__u32*)tmp_buf;
+#ifdef CFI_WORD_64
+		} else if (cfi_buswidth_is_8()) {
+			datum = *(__u64*)tmp_buf;
+#endif
 		} else {
 			return -EINVAL;  /* should never happen, but be safe */
 		}
@@ -857,9 +867,9 @@
 	
 	if (cfi->fast_prog) {
 		/* Go into unlock bypass mode */
-		cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
-		cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
-		cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
+		cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, cfi->device_type, NULL);
+		cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, cfi->device_type, NULL);
+		cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, cfi->device_type, NULL);
 	}
 
 	/* We are now aligned, write as much as possible */
@@ -872,6 +882,10 @@
 			datum = *(__u16*)buf;
 		} else if (cfi_buswidth_is_4()) {
 			datum = *(__u32*)buf;
+#ifdef CFI_WORD_64
+		} else if (cfi_buswidth_is_8()) {
+			datum = *(__u64*)buf;
+#endif
 		} else {
 			return -EINVAL;
 		}
@@ -905,9 +919,9 @@
 			chipstart = cfi->chips[chipnum].start;
 			if (cfi->fast_prog){
 				/* Go into unlock bypass mode for next set of chips */
-				cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
-				cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
-				cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
+				cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, cfi->device_type, NULL);
+				cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, cfi->device_type, NULL);
+				cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, cfi->device_type, NULL);
 			}
 		}
 	}
@@ -932,6 +946,10 @@
 			datum = *(__u16*)tmp_buf;
 		} else if (cfi_buswidth_is_4()) {
 			datum = *(__u32*)tmp_buf;
+#ifdef CFI_WORD_64
+		} else if (cfi_buswidth_is_8()) {
+			datum = *(__u64*)tmp_buf;
+#endif
 		} else {
 			return -EINVAL;  /* should never happen, but be safe */
 		}
@@ -996,12 +1014,12 @@
  retry_cmd:
 #endif
 	ENABLE_VPP(map);
-	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0x10, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x10, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
 	timeo = jiffies + (HZ*20);
 	adr = cfi->addr_unlock1;
 
@@ -1086,6 +1104,10 @@
 		datum = (__u16)~0;
 	} else if ( cfi_buswidth_is_4() ) {
 		datum = (__u32)~0;
+#ifdef CFI_WORD_64
+	} else if ( cfi_buswidth_is_8() ) {
+		datum = (__u64)~0;
+#endif
 	} else {
 		printk(KERN_WARNING "Unsupported buswidth\n");
 		goto op_failed;
@@ -1137,8 +1159,8 @@
 
 static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
 {
-	unsigned int oldstatus, status, prev_oldstatus, prev_status;
-	unsigned int dq6;
+	cfi_word oldstatus, status, prev_oldstatus, prev_status;
+	cfi_word dq6;
 	unsigned long timeo = jiffies + HZ;
 	struct cfi_private *cfi = map->fldrv_priv;
 	DECLARE_WAITQUEUE(wait, current);
@@ -1179,11 +1201,11 @@
  retry_cmd:
 #endif
 	ENABLE_VPP(map);
-	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
 
 	cfi_write(map, CMD(0x30), adr);
 	
@@ -1270,6 +1292,10 @@
 		datum = (__u16)~0;
 	} else if ( cfi_buswidth_is_4() ) {
 		datum = (__u32)~0;
+#ifdef CFI_WORD_64
+	} else if ( cfi_buswidth_is_8() ) {
+		datum = (__u64)~0;
+#endif
 	} else {
 		printk(KERN_WARNING "Unsupported buswidth\n");
 		goto op_failed;

Index: jedec_probe.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/jedec_probe.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- jedec_probe.c	28 May 2003 13:57:46 -0000	1.29
+++ jedec_probe.c	29 Sep 2003 16:50:01 -0000	1.30
@@ -119,6 +119,7 @@
 #define SST39LF040	0x00D7
 #define SST39SF010A	0x00B5
 #define SST39SF020A	0x00B6
+#define SST49LF004B	0x0060
 #define SST49LF030A	0x001C
 #define SST49LF040A	0x0051
 #define SST49LF080A	0x005B
@@ -1114,6 +1115,19 @@
 		}
 	}, {
 		.mfr_id		= MANUFACTURER_SST,
+		.dev_id		= SST49LF004B,
+		.name		= "SST 49LF004B",
+ 		.uaddr		= {
+			[0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
+		},
+		.DevSize	= SIZE_512KiB,
+		.CmdSet		= P_ID_AMD_STD,
+		.NumEraseRegions= 1,
+		.regions	= {
+			ERASEINFO(0x01000,128),
+		}
+	}, {
+		.mfr_id		= MANUFACTURER_SST,
 		.dev_id		= SST49LF030A,
 		.name		= "SST 49LF030A",
  		.uaddr		= {
@@ -1538,10 +1552,10 @@
 	 */
 	DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ );
 	if(cfi->addr_unlock1) {
-		cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
-		cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+		cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
+		cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
 	}
-	cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
 	/* FIXME - should have a delay before continuing */
 
  match_done:	
@@ -1613,10 +1627,10 @@
 
 	/* Autoselect Mode */
 	if(cfi->addr_unlock1) {
-		cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
-		cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+		cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
+		cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
 	}
-	cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+	cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
 	/* FIXME - should have a delay before continuing */
 
 	if (!cfi->numchips) {


From tharbaugh at lnxi.com  Mon Sep 29 19:10:13 2003
From: tharbaugh at lnxi.com (Thayne Harbaugh)
Date: Mon May 15 21:48:45 2006
Subject: mtd/drivers/mtd/chips cfi_cmdset_0002.c,1.80,1.81
	jedec_probe.c,1.30,1.31
Message-ID: <E1A479h-0005PV-Ja@phoenix.infradead.org>

Update of /home/cvs/mtd/drivers/mtd/chips
In directory phoenix.infradead.org:/tmp/cvs-serv20788/drivers/mtd/chips

Modified Files:
	cfi_cmdset_0002.c jedec_probe.c 
Log Message:

- Make 'unsupported' messages more informative

- Don't reinitialize unlock addresses if they are alread setup

- Iterate through the list of unlock addresses instead of guessing
  the addresses with seeds



Index: cfi_cmdset_0002.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0002.c,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -r1.80 -r1.81
--- cfi_cmdset_0002.c	29 Sep 2003 16:50:01 -0000	1.80
+++ cfi_cmdset_0002.c	29 Sep 2003 23:10:10 -0000	1.81
@@ -233,30 +233,34 @@
 			}
 		}
 		/*
-		 * FIXME - These might already be setup (more correctly)
-		 * by jedec_probe.c.
+		 * These might already be setup (more correctly) by
+		 * jedec_probe.c - still need it for cfi_probe.c path.
 		 */
-		switch (cfi->device_type) {
-		case CFI_DEVICETYPE_X8:
-			cfi->addr_unlock1 = 0x555; 
-			cfi->addr_unlock2 = 0x2aa; 
-			break;
-		case CFI_DEVICETYPE_X16:
-			cfi->addr_unlock1 = 0xaaa;
-			if (map->buswidth == cfi->interleave) {
-				/* X16 chip(s) in X8 mode */
-				cfi->addr_unlock2 = 0x555;
-			} else {
-				cfi->addr_unlock2 = 0x554;
+		if ( ! (cfi->addr_unlock1 && cfi->addr_unlock2) ) {
+			switch (cfi->device_type) {
+			case CFI_DEVICETYPE_X8:
+				cfi->addr_unlock1 = 0x555; 
+				cfi->addr_unlock2 = 0x2aa; 
+				break;
+			case CFI_DEVICETYPE_X16:
+				cfi->addr_unlock1 = 0xaaa;
+				if (map->buswidth == cfi->interleave) {
+					/* X16 chip(s) in X8 mode */
+					cfi->addr_unlock2 = 0x555;
+				} else {
+					cfi->addr_unlock2 = 0x554;
+				}
+				break;
+			case CFI_DEVICETYPE_X32:
+				cfi->addr_unlock1 = 0x1555; 
+				cfi->addr_unlock2 = 0xaaa; 
+				break;
+			default:
+				printk(KERN_WARNING
+				       "MTD %s(): Unsupported device type %d\n",
+				       __func__, cfi->device_type);
+				return NULL;
 			}
-			break;
-		case CFI_DEVICETYPE_X32:
-			cfi->addr_unlock1 = 0x1555; 
-			cfi->addr_unlock2 = 0xaaa; 
-			break;
-		default:
-			printk(KERN_NOTICE "Eep. Unknown cfi_cmdset_0002 device type %d\n", cfi->device_type);
-			return NULL;
 		}
 
 		/* Install our own private info structure */
@@ -363,7 +367,8 @@
 		break;
 
 	default:
-	        printk(KERN_WARNING "Unsupported buswidth\n");
+	        printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
+		       __func__, CFIDEV_BUSWIDTH);
 		goto setup_err;
 		break;
 	}
@@ -845,7 +850,9 @@
 			datum = *(__u64*)tmp_buf;
 #endif
 		} else {
-			return -EINVAL;  /* should never happen, but be safe */
+			printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
+			       __func__, CFIDEV_BUSWIDTH);
+			return -EINVAL;
 		}
 
 		ret = do_write_oneword(map, &cfi->chips[chipnum], 
@@ -887,6 +894,8 @@
 			datum = *(__u64*)buf;
 #endif
 		} else {
+			printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
+			       __func__, CFIDEV_BUSWIDTH);
 			return -EINVAL;
 		}
 		ret = do_write_oneword(map, &cfi->chips[chipnum],
@@ -951,7 +960,9 @@
 			datum = *(__u64*)tmp_buf;
 #endif
 		} else {
-			return -EINVAL;  /* should never happen, but be safe */
+			printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
+			       __func__, CFIDEV_BUSWIDTH);
+			return -EINVAL;
 		}
 
 		ret = do_write_oneword(map, &cfi->chips[chipnum], 

Index: jedec_probe.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/jedec_probe.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- jedec_probe.c	29 Sep 2003 16:50:01 -0000	1.30
+++ jedec_probe.c	29 Sep 2003 23:10:11 -0000	1.31
@@ -1485,8 +1485,35 @@
 	u32 mfr, id;
 	__u8 uaddr;
 
-	/* The ID's must match */
-	if ( cfi->mfr != finfo->mfr_id || cfi->id != finfo->dev_id ) {
+	/*
+	 * The IDs must match.  For X16 and X32 devices operating in
+	 * a lower width ( X8 or X16 ), the device ID's are usually just
+	 * the lower byte(s) of the larger device ID for wider mode.  If
+	 * a part is found that doesn't fit this assumption (device id for
+	 * smaller width mode is completely unrealated to full-width mode)
+	 * then the jedec_table[] will have to be augmented with the IDs
+	 * for different widths.
+	 */
+	switch (cfi->device_type) {
+	case CFI_DEVICETYPE_X8:
+		mfr = (__u8)finfo->mfr_id;
+		id = (__u8)finfo->dev_id;
+		break;
+	case CFI_DEVICETYPE_X16:
+		mfr = (__u16)finfo->mfr_id;
+		id = (__u16)finfo->dev_id;
+		break;
+	case CFI_DEVICETYPE_X32:
+		mfr = (__u16)finfo->mfr_id;
+		id = (__u32)finfo->dev_id;
+		break;
+	default:
+		printk(KERN_WARNING
+		       "MTD %s(): Unsupported device type %d\n",
+		       __func__, cfi->device_type);
+		goto match_done;
+	}
+	if ( cfi->mfr != mfr || cfi->id != id ) {
 		goto match_done;
 	}
 
@@ -1567,38 +1594,19 @@
 			      struct flchip *chips, struct cfi_private *cfi)
 {
 	int i;
-	int unlockpass = 0;
+	enum uaddr uaddr_idx = MTD_UADDR_NOT_SUPPORTED;
 
-	/*
-	 * FIXME - eventually replace these unlock address seeds with
-	 * information from unlock_addrs[].
-	 */
+ retry:
 	if (!cfi->numchips) {
-		switch (cfi->device_type) {
-		case CFI_DEVICETYPE_X8:
-			cfi->addr_unlock1 = 0x555;
-			cfi->addr_unlock2 = 0x2aa;
-			break;
-		case CFI_DEVICETYPE_X16:
-			cfi->addr_unlock1 = 0xaaa;
-			if (map->buswidth == cfi->interleave) {
-				/* X16 chip(s) in X8 mode */
-				cfi->addr_unlock2 = 0x555;
-			} else {
-				cfi->addr_unlock2 = 0x554;
-			}
-			break;
-		case CFI_DEVICETYPE_X32:
-			cfi->addr_unlock1 = 0x1555; 
-			cfi->addr_unlock2 = 0xaaa; 
-			break;
-		default:
-			printk(KERN_NOTICE "Eep. Unknown jedec_probe device type %d\n", cfi->device_type);
-		return 0;
-		}
+		uaddr_idx++;
+
+		if (MTD_UADDR_UNNECESSARY == uaddr_idx)
+			return 0;
+
+		cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1;
+		cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2;
 	}
 
- retry:
 	/* Make certain we aren't probing past the end of map */
 	if (base >= map->size) {
 		printk(KERN_NOTICE
@@ -1652,16 +1660,7 @@
 				goto ok_out;
 			}
 		}
-		switch(unlockpass++) {
-		case 0:
-			cfi->addr_unlock1 |= cfi->addr_unlock1 << 4;
-			cfi->addr_unlock2 |= cfi->addr_unlock2 << 4;
-			goto retry;
-		case 1:
-			cfi->addr_unlock1 = cfi->addr_unlock2 = 0;
-			goto retry;
-		}
-		return 0;
+		goto retry;
 	} else {
 		__u16 mfr;
 		__u16 id;


From tharbaugh at lnxi.com  Tue Sep 30 10:08:03 2003
From: tharbaugh at lnxi.com (Thayne Harbaugh)
Date: Mon May 15 21:48:45 2006
Subject: mtd/drivers/mtd/chips cfi_cmdset_0002.c,1.81,1.82
Message-ID: <E1A4LAZ-0000uP-Af@phoenix.infradead.org>

Update of /home/cvs/mtd/drivers/mtd/chips
In directory phoenix.infradead.org:/tmp/cvs-serv3484

Modified Files:
	cfi_cmdset_0002.c 
Log Message:
Missed some changes of int -> cfi_word

Index: cfi_cmdset_0002.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0002.c,v
retrieving revision 1.81
retrieving revision 1.82
diff -u -r1.81 -r1.82
--- cfi_cmdset_0002.c	29 Sep 2003 23:10:10 -0000	1.81
+++ cfi_cmdset_0002.c	30 Sep 2003 14:08:00 -0000	1.82
@@ -758,7 +758,7 @@
 	}
 
 	if ( ta ) {
-		int dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1;
+		cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1;
 		if ( status & dq5mask ) {
 			/* dq5 asserted - decode interleave chips */
 			printk( KERN_WARNING
@@ -983,8 +983,8 @@
  */
 static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
 {
-	unsigned int oldstatus, status, prev_oldstatus, prev_status;
-	unsigned int dq6;
+	cfi_word oldstatus, status, prev_oldstatus, prev_status;
+	cfi_word dq6;
 	unsigned long timeo = jiffies + HZ;
 	unsigned long int adr;
 	struct cfi_private *cfi = map->fldrv_priv;
@@ -1130,7 +1130,7 @@
 	}
 
 	if ( ta ) {
-		int dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1;
+		cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1;
 		if ( status & dq5mask ) {
 			/* dq5 asserted - decode interleave chips */
 			printk( KERN_WARNING
@@ -1318,7 +1318,7 @@
 	}
 
 	if ( ta ) {
-		int dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1;
+		cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1;
 		if ( status & dq5mask ) {
 			/* dq5 asserted - decode interleave chips */
 			printk( KERN_WARNING


From tharbaugh at lnxi.com  Tue Sep 30 12:15:07 2003
From: tharbaugh at lnxi.com (Thayne Harbaugh)
Date: Mon May 15 21:48:45 2006
Subject: mtd/drivers/mtd/maps sbc8240.c,NONE,1.1 Config.in,1.56,1.57
	Makefile.common,1.3,1.4
Message-ID: <E1A4N9X-0001VN-IB@phoenix.infradead.org>

Update of /home/cvs/mtd/drivers/mtd/maps
In directory phoenix.infradead.org:/tmp/cvs-serv5777

Modified Files:
	Config.in Makefile.common 
Added Files:
	sbc8240.c 
Log Message:
sbc8240 map driver contributed by Carolyn J Smith

--- NEW FILE sbc8240.c ---
/*
 * Handle mapping of the flash memory access routines on the SBC8240 board.
 *
 * Carolyn Smith, Tektronix, Inc.
 *
 * This code is GPLed
 *
 */

/*
 * The SBC8240 has 2 flash banks.
 * Bank 0 is a 512 KB AMD AM29F040B; 8 x 64 KB sectors.
 * It contains the U-Boot code (7 sectors) and the environment (1 sector).
 * Bank 1 is 4 x 1 MB AMD AM29LV800BT; 15 x 64 KB sectors, 1 x 32 KB sector,
 * 2 x 8 KB sectors, 1 x 16 KB sectors.
 * Both parts are JEDEC compatible.
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <asm/io.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/cfi.h>

#ifdef CONFIG_MTD_PARTITIONS
#include <linux/mtd/partitions.h>
#endif

#define	DEBUG

#ifdef	DEBUG
# define debugk(fmt,args...)	printk(fmt ,##args)
#else
# define debugk(fmt,args...)
#endif


#define WINDOW_ADDR0	0xFFF00000		/* 512 KB */
#define WINDOW_SIZE0	0x00080000
#define BUSWIDTH0	1

#define WINDOW_ADDR1	0xFF000000		/* 4 MB */
#define WINDOW_SIZE1	0x00400000
#define BUSWIDTH1	8

#define MSG_PREFIX "sbc8240:"	/* prefix for our printk()'s */
#define MTDID	   "sbc8240-%d"	/* for mtdparts= partitioning */


static __u8 sbc8240_read8 (struct map_info *map, unsigned long ofs)
{
	return __raw_readb(map->map_priv_1 + ofs);
}

static __u16 sbc8240_read16 (struct map_info *map, unsigned long ofs)
{
	return __raw_readw(map->map_priv_1 + ofs);
}

static __u32 sbc8240_read32 (struct map_info *map, unsigned long ofs)
{
	return __raw_readl(map->map_priv_1 + ofs);
}

unsigned long long result64;

static __u64 sbc8240_read64 (struct map_info *map, unsigned long ofs)
{
    unsigned long flags, msr, saved_msr;
    volatile long saved_fr[2];
    volatile unsigned long long result;
    volatile unsigned long *p;

    save_flags(flags);
    cli();

    /* turn off floating point unavailable exceptions */

    __asm__ __volatile__ (
        "mfmsr %0" 
	: "=r" (msr) :);

    saved_msr = msr;
    msr |= MSR_FP;
    msr &= ~(MSR_FE0 | MSR_FE1);

    __asm__ __volatile__ (
        "mtmsr %0\n"
	"isync\n"
	: : "r" (msr));

    /* read the data via a floating point register */

    ofs = map->map_priv_1 + ofs;
    p = (unsigned long *) &result64;

    __asm__ __volatile__ (
        "lfd  1,0(%1)\n"
        "stfd 1,0(%0)\n"
        : : "r" (p), "r" (ofs)
    );

    /* restore state */

    __asm__ __volatile__ (
	"mtmsr %0\n"
        "isync\n"
	: : "r" (saved_msr));

    restore_flags(flags);

    p = (unsigned long *) &result64;
    debugk("sbc8240_read64 ofs 0x%x result 0x%08x%08x\n", ofs, *p, *(p+1));

    return result64;
}

static void sbc8240_copy_from (struct map_info *map,
			      void *to, unsigned long from, ssize_t len)
{
	memcpy_fromio (to, (void *) (map->map_priv_1 + from), len);
}

static void sbc8240_write8 (struct map_info *map, __u8 d, unsigned long adr)
{
	__raw_writeb(d, map->map_priv_1 + adr);
	mb();
}

static void sbc8240_write16 (struct map_info *map, __u16 d,
			   unsigned long adr)
{
	__raw_writew(d, map->map_priv_1 + adr);
	mb();
}

static void sbc8240_write32 (struct map_info *map, __u32 d,
			   unsigned long adr)
{
	__raw_writel(d, map->map_priv_1 + adr);
	mb();
}

static void sbc8240_write64 (struct map_info *map, __u64 data,
			   unsigned long adr)
{
    unsigned long long tmp;
    unsigned long flags, msr, saved_msr, *p;
    volatile long saved_fr[2];

    save_flags(flags);
    cli();

    /* turn off floating point unavailable exceptions */

    __asm__ __volatile__ (
        "mfmsr %0" 
	: "=r" (msr) :);

    saved_msr = msr;
    msr |= MSR_FP;
    msr &= ~(MSR_FE0 | MSR_FE1);

    __asm__ __volatile__ (
        "mtmsr %0\n"
	"isync\n"
	: : "r" (msr));


    /* write the data via a floating point register */

    tmp = data;
    p = (unsigned long *) &tmp;
    adr = map->map_priv_1 + adr;
    debugk("sbc8240_write64 adr 0x%x data 0x%08x%08x\n", adr, *p, *(p+1));

    __asm__ __volatile__ (
	"stfd 1,0(%2)\n"
        "lfd  1,0(%0)\n"
        "stfd 1,0(%1)\n"
	"lfd  1,0(%2)\n"
        : : "r" (p), "r" (adr), "b" (saved_fr)
    );

    /* restore state */

    __asm__ __volatile__ (
	"mtmsr %0\n"
        "isync\n"
	: : "r" (saved_msr));

    restore_flags(flags);
}

static void sbc8240_copy_to (struct map_info *map,
			   unsigned long to, const void *from, ssize_t len)
{
	memcpy_toio ((void *) (map->map_priv_1 + to), from, len);
}

static struct map_info sbc8240_map[2] = {
    {
	name:	   "sbc8240 Flash Bank #0",
	size:	   WINDOW_SIZE0,
	buswidth:  BUSWIDTH0,
	read8:	   sbc8240_read8,
	read16:	   sbc8240_read16,
	read32:	   sbc8240_read32,
	read64:	   sbc8240_read64,
	copy_from: sbc8240_copy_from,
	write8:	   sbc8240_write8,
	write16:   sbc8240_write16,
	write32:   sbc8240_write32,
	write64:   sbc8240_write64,
	copy_to:   sbc8240_copy_to
    },
    {
	name:	   "sbc8240 Flash Bank #1",
	size:	   WINDOW_SIZE1,
	buswidth:  BUSWIDTH1,
	read8:	   sbc8240_read8,
	read16:	   sbc8240_read16,
	read32:	   sbc8240_read32,
	read64:	   sbc8240_read64,
	copy_from: sbc8240_copy_from,
	write8:	   sbc8240_write8,
	write16:   sbc8240_write16,
	write32:   sbc8240_write32,
	write64:   sbc8240_write64,
	copy_to:   sbc8240_copy_to
    }
};

#define NUM_FLASH_BANKS	(sizeof(sbc8240_map) / sizeof(struct map_info))

/*
 * The following defines the partition layout of SBC8240 boards.
 *
 * See include/linux/mtd/partitions.h for definition of the
 * mtd_partition structure.
 *
 * The *_max_flash_size is the maximum possible mapped flash size
 * which is not necessarily the actual flash size. It must correspond
 * to the value specified in the mapping definition defined by the
 * "struct map_desc *_io_desc" for the corresponding machine.
 */

#ifdef CONFIG_MTD_PARTITIONS

static struct mtd_partition sbc8240_uboot_partitions [] = {
  /* Bank 0 */
    {
	name:	"U-boot",			/* U-Boot Firmware	*/
	offset:	0,
	size:	0x00070000,			/*  7 x 64 KB sectors 	*/
	mask_flags: MTD_WRITEABLE,		/*  force read-only	*/
    },
    {
	name:	"environment",			/* U-Boot environment	*/
	offset:	0x00070000,
	size:	0x00010000,			/*  1 x 64 KB sector	*/
    },
};

static struct mtd_partition sbc8240_fs_partitions [] = {
    {
	name:	"jffs",				/* JFFS  filesystem	*/
	offset:	0,
	size:	0x003C0000,			/*  4 * 15 * 64KB	*/
    },
    {
	name:	"tmp32",
	offset:	0x003C0000,
	size:	0x00020000,			/*  4 * 32KB		*/
    },
    {
	name:	"tmp8a",
	offset:	0x003E0000,
	size:	0x00008000,			/*  4 * 8KB		*/
    },
    {
	name:	"tmp8b",
	offset:	0x003E8000,
	size:	0x00008000,			/*  4 * 8KB		*/
    },
    {
	name:	"tmp16",
	offset:	0x003F0000,
	size:	0x00010000,			/*  4 * 16KB		*/
    }
};

#define NB_OF(x) (sizeof (x) / sizeof (x[0]))

/* trivial struct to describe partition information */
struct mtd_part_def
{
	int nums;
	unsigned char *type;
	struct mtd_partition* mtd_part;
};

static struct mtd_info *sbc8240_mtd[NUM_FLASH_BANKS];
static struct mtd_part_def sbc8240_part_banks[NUM_FLASH_BANKS];


#endif	/* CONFIG_MTD_PARTITIONS */


int __init init_sbc8240_mtd (void)
{
	static struct _cjs {
		u_long addr;
		u_long size;
	} pt[NUM_FLASH_BANKS] = {
		{ WINDOW_ADDR0, WINDOW_SIZE0 },
		{ WINDOW_ADDR1, WINDOW_SIZE1 },
	};

	int devicesfound = 0;
	int i;

	for (i = 0; i < NUM_FLASH_BANKS; i++) {
		printk (KERN_NOTICE MSG_PREFIX
			"Probing 0x%08lx at 0x%08lx\n", pt[i].size, pt[i].addr);

		sbc8240_map[i].map_priv_1 =
				(unsigned long) ioremap (pt[i].addr, pt[i].size);
		if (!sbc8240_map[i].map_priv_1) {
			printk (MSG_PREFIX "failed to ioremap\n");
			return -EIO;
		}

		sbc8240_mtd[i] = do_map_probe("jedec_probe", &sbc8240_map[i]);

		if (sbc8240_mtd[i]) {
			sbc8240_mtd[i]->module = THIS_MODULE;
			devicesfound++;
		}
	}

	if (!devicesfound) {
		printk(KERN_NOTICE MSG_PREFIX
			"No suppported flash chips found!\n");
		return -ENXIO;
	}

#ifdef CONFIG_MTD_PARTITIONS
	sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions;
	sbc8240_part_banks[0].type = "static image";
	sbc8240_part_banks[0].nums = NB_OF(sbc8240_uboot_partitions);
	sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions;
	sbc8240_part_banks[1].type = "static file system";
	sbc8240_part_banks[1].nums = NB_OF(sbc8240_fs_partitions);

	for (i = 0; i < NUM_FLASH_BANKS; i++) {

		if (!sbc8240_mtd[i]) continue;
		if (sbc8240_part_banks[i].nums == 0) {
			printk (KERN_NOTICE MSG_PREFIX
				"No partition info available, registering whole device\n");
			add_mtd_device(sbc8240_mtd[i]);
		} else {
			printk (KERN_NOTICE MSG_PREFIX
				"Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name);
			add_mtd_partitions (sbc8240_mtd[i], 
					sbc8240_part_banks[i].mtd_part,
				       	sbc8240_part_banks[i].nums);
		}
	}
#else
	printk(KERN_NOTICE MSG_PREFIX
		"Registering %d flash banks at once\n", devicesfound);

	for (i = 0; i < devicesfound; i++) {
		add_mtd_device(sbc8240_mtd[i]);
	}
#endif	/* CONFIG_MTD_PARTITIONS */

	return devicesfound == 0 ? -ENXIO : 0;
}

static void __exit cleanup_sbc8240_mtd (void)
{
	int i;

	for (i = 0; i < NUM_FLASH_BANKS; i++) {
		if (sbc8240_mtd[i]) {
			del_mtd_device (sbc8240_mtd[i]);
			map_destroy (sbc8240_mtd[i]);
		}
		if (sbc8240_map[i].map_priv_1) {
			iounmap ((void *) sbc8240_map[i].map_priv_1);
			sbc8240_map[i].map_priv_1 = 0;
		}
	}
}

module_init (init_sbc8240_mtd);
module_exit (cleanup_sbc8240_mtd);

MODULE_LICENSE ("GPL");
MODULE_AUTHOR ("Carolyn Smith <carolyn.smith@tektronix.com>");
MODULE_DESCRIPTION ("MTD map driver for SBC8240 boards");


Index: Config.in
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/maps/Config.in,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -r1.56 -r1.57
--- Config.in	22 Sep 2003 16:56:33 -0000	1.56
+++ Config.in	30 Sep 2003 16:15:05 -0000	1.57
@@ -40,6 +40,9 @@
 fi
 
 if [ "$CONFIG_PPC32" = "y" ]; then
+  if [ "$CLASSIC_PPC" = "y" ]; then
+    dep_tristate '  CFI Flash device mapped on SBC8240' CONFIG_MTD_SBC8240 $CONFIG_MTD_JEDECPROBE
+  fi
   if [ "$CONFIG_8xx" = "y" ]; then
     if [ "$CONFIG_TQM8xxL" = "y" ]; then
       dep_tristate '  CFI Flash device mapped on TQM8XXL' CONFIG_MTD_TQM8XXL $CONFIG_MTD_CFI

Index: Makefile.common
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/maps/Makefile.common,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Makefile.common	28 Aug 2003 06:50:24 -0000	1.3
+++ Makefile.common	30 Sep 2003 16:15:05 -0000	1.4
@@ -62,5 +62,6 @@
 obj-$(CONFIG_MTD_BEECH)		+= beech-mtd.o
 obj-$(CONFIG_MTD_ARCTIC)	+= arctic-mtd.o
 obj-$(CONFIG_MTD_H720X)		+= h720x-flash.o
+obj-$(CONFIG_MTD_SBC8240)	+= sbc8240.o
 
 -include $(TOPDIR)/Rules.make


From tharbaugh at lnxi.com  Tue Sep 30 15:37:03 2003
From: tharbaugh at lnxi.com (Thayne Harbaugh)
Date: Mon May 15 21:48:45 2006
Subject: mtd/drivers/mtd/maps sbc8240.c,1.1,1.2
Message-ID: <E1A4QIx-0002RA-6w@phoenix.infradead.org>

Update of /home/cvs/mtd/drivers/mtd/maps
In directory phoenix.infradead.org:/tmp/cvs-serv9359

Modified Files:
	sbc8240.c 
Log Message:
beautification: Id, KB -> KiB, MB -> MiB, C99 initializers

Index: sbc8240.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/maps/sbc8240.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- sbc8240.c	30 Sep 2003 16:15:05 -0000	1.1
+++ sbc8240.c	30 Sep 2003 19:37:00 -0000	1.2
@@ -5,14 +5,16 @@
  *
  * This code is GPLed
  *
+ * $Id$
+ *
  */
 
 /*
  * The SBC8240 has 2 flash banks.
- * Bank 0 is a 512 KB AMD AM29F040B; 8 x 64 KB sectors.
+ * Bank 0 is a 512 KiB AMD AM29F040B; 8 x 64 KiB sectors.
  * It contains the U-Boot code (7 sectors) and the environment (1 sector).
- * Bank 1 is 4 x 1 MB AMD AM29LV800BT; 15 x 64 KB sectors, 1 x 32 KB sector,
- * 2 x 8 KB sectors, 1 x 16 KB sectors.
+ * Bank 1 is 4 x 1 MiB AMD AM29LV800BT; 15 x 64 KiB sectors, 1 x 32 KiB sector,
+ * 2 x 8 KiB sectors, 1 x 16 KiB sectors.
  * Both parts are JEDEC compatible.
  */
 
@@ -39,11 +41,11 @@
 #endif
 
 
-#define WINDOW_ADDR0	0xFFF00000		/* 512 KB */
+#define WINDOW_ADDR0	0xFFF00000		/* 512 KiB */
 #define WINDOW_SIZE0	0x00080000
 #define BUSWIDTH0	1
 
-#define WINDOW_ADDR1	0xFF000000		/* 4 MB */
+#define WINDOW_ADDR1	0xFF000000		/* 4 MiB */
 #define WINDOW_SIZE1	0x00400000
 #define BUSWIDTH1	8
 
@@ -70,57 +72,57 @@
 
 static __u64 sbc8240_read64 (struct map_info *map, unsigned long ofs)
 {
-    unsigned long flags, msr, saved_msr;
-    volatile long saved_fr[2];
-    volatile unsigned long long result;
-    volatile unsigned long *p;
+	unsigned long flags, msr, saved_msr;
+	volatile long saved_fr[2];
+	volatile unsigned long long result;
+	volatile unsigned long *p;
 
-    save_flags(flags);
-    cli();
+	save_flags(flags);
+	cli();
 
-    /* turn off floating point unavailable exceptions */
+	/* turn off floating point unavailable exceptions */
 
-    __asm__ __volatile__ (
-        "mfmsr %0" 
-	: "=r" (msr) :);
+	__asm__ __volatile__ (
+		"mfmsr %0" 
+		: "=r" (msr) :);
 
-    saved_msr = msr;
-    msr |= MSR_FP;
-    msr &= ~(MSR_FE0 | MSR_FE1);
+	saved_msr = msr;
+	msr |= MSR_FP;
+	msr &= ~(MSR_FE0 | MSR_FE1);
 
-    __asm__ __volatile__ (
-        "mtmsr %0\n"
-	"isync\n"
-	: : "r" (msr));
+	__asm__ __volatile__ (
+		"mtmsr %0\n"
+		"isync\n"
+		: : "r" (msr));
 
-    /* read the data via a floating point register */
+	/* read the data via a floating point register */
 
-    ofs = map->map_priv_1 + ofs;
-    p = (unsigned long *) &result64;
+	ofs = map->map_priv_1 + ofs;
+	p = (unsigned long *) &result64;
 
-    __asm__ __volatile__ (
-        "lfd  1,0(%1)\n"
-        "stfd 1,0(%0)\n"
-        : : "r" (p), "r" (ofs)
-    );
+	__asm__ __volatile__ (
+		"lfd  1,0(%1)\n"
+		"stfd 1,0(%0)\n"
+		: : "r" (p), "r" (ofs)
+		);
 
-    /* restore state */
+	/* restore state */
 
-    __asm__ __volatile__ (
-	"mtmsr %0\n"
-        "isync\n"
-	: : "r" (saved_msr));
+	__asm__ __volatile__ (
+		"mtmsr %0\n"
+		"isync\n"
+		: : "r" (saved_msr));
 
-    restore_flags(flags);
+	restore_flags(flags);
 
-    p = (unsigned long *) &result64;
-    debugk("sbc8240_read64 ofs 0x%x result 0x%08x%08x\n", ofs, *p, *(p+1));
+	p = (unsigned long *) &result64;
+	debugk("sbc8240_read64 ofs 0x%x result 0x%08x%08x\n", ofs, *p, *(p+1));
 
-    return result64;
+	return result64;
 }
 
 static void sbc8240_copy_from (struct map_info *map,
-			      void *to, unsigned long from, ssize_t len)
+			       void *to, unsigned long from, ssize_t len)
 {
 	memcpy_fromio (to, (void *) (map->map_priv_1 + from), len);
 }
@@ -132,107 +134,107 @@
 }
 
 static void sbc8240_write16 (struct map_info *map, __u16 d,
-			   unsigned long adr)
+			     unsigned long adr)
 {
 	__raw_writew(d, map->map_priv_1 + adr);
 	mb();
 }
 
 static void sbc8240_write32 (struct map_info *map, __u32 d,
-			   unsigned long adr)
+			     unsigned long adr)
 {
 	__raw_writel(d, map->map_priv_1 + adr);
 	mb();
 }
 
 static void sbc8240_write64 (struct map_info *map, __u64 data,
-			   unsigned long adr)
+			     unsigned long adr)
 {
-    unsigned long long tmp;
-    unsigned long flags, msr, saved_msr, *p;
-    volatile long saved_fr[2];
+	unsigned long long tmp;
+	unsigned long flags, msr, saved_msr, *p;
+	volatile long saved_fr[2];
 
-    save_flags(flags);
-    cli();
+	save_flags(flags);
+	cli();
 
-    /* turn off floating point unavailable exceptions */
+	/* turn off floating point unavailable exceptions */
 
-    __asm__ __volatile__ (
-        "mfmsr %0" 
-	: "=r" (msr) :);
+	__asm__ __volatile__ (
+		"mfmsr %0" 
+		: "=r" (msr) :);
 
-    saved_msr = msr;
-    msr |= MSR_FP;
-    msr &= ~(MSR_FE0 | MSR_FE1);
+	saved_msr = msr;
+	msr |= MSR_FP;
+	msr &= ~(MSR_FE0 | MSR_FE1);
 
-    __asm__ __volatile__ (
-        "mtmsr %0\n"
-	"isync\n"
-	: : "r" (msr));
+	__asm__ __volatile__ (
+		"mtmsr %0\n"
+		"isync\n"
+		: : "r" (msr));
 
 
-    /* write the data via a floating point register */
+	/* write the data via a floating point register */
 
-    tmp = data;
-    p = (unsigned long *) &tmp;
-    adr = map->map_priv_1 + adr;
-    debugk("sbc8240_write64 adr 0x%x data 0x%08x%08x\n", adr, *p, *(p+1));
+	tmp = data;
+	p = (unsigned long *) &tmp;
+	adr = map->map_priv_1 + adr;
+	debugk("sbc8240_write64 adr 0x%x data 0x%08x%08x\n", adr, *p, *(p+1));
 
-    __asm__ __volatile__ (
-	"stfd 1,0(%2)\n"
-        "lfd  1,0(%0)\n"
-        "stfd 1,0(%1)\n"
-	"lfd  1,0(%2)\n"
-        : : "r" (p), "r" (adr), "b" (saved_fr)
-    );
+	__asm__ __volatile__ (
+		"stfd 1,0(%2)\n"
+		"lfd  1,0(%0)\n"
+		"stfd 1,0(%1)\n"
+		"lfd  1,0(%2)\n"
+		: : "r" (p), "r" (adr), "b" (saved_fr)
+		);
 
-    /* restore state */
+	/* restore state */
 
-    __asm__ __volatile__ (
-	"mtmsr %0\n"
-        "isync\n"
-	: : "r" (saved_msr));
+	__asm__ __volatile__ (
+		"mtmsr %0\n"
+		"isync\n"
+		: : "r" (saved_msr));
 
-    restore_flags(flags);
+	restore_flags(flags);
 }
 
 static void sbc8240_copy_to (struct map_info *map,
-			   unsigned long to, const void *from, ssize_t len)
+			     unsigned long to, const void *from, ssize_t len)
 {
 	memcpy_toio ((void *) (map->map_priv_1 + to), from, len);
 }
 
 static struct map_info sbc8240_map[2] = {
-    {
-	name:	   "sbc8240 Flash Bank #0",
-	size:	   WINDOW_SIZE0,
-	buswidth:  BUSWIDTH0,
-	read8:	   sbc8240_read8,
-	read16:	   sbc8240_read16,
-	read32:	   sbc8240_read32,
-	read64:	   sbc8240_read64,
-	copy_from: sbc8240_copy_from,
-	write8:	   sbc8240_write8,
-	write16:   sbc8240_write16,
-	write32:   sbc8240_write32,
-	write64:   sbc8240_write64,
-	copy_to:   sbc8240_copy_to
-    },
-    {
-	name:	   "sbc8240 Flash Bank #1",
-	size:	   WINDOW_SIZE1,
-	buswidth:  BUSWIDTH1,
-	read8:	   sbc8240_read8,
-	read16:	   sbc8240_read16,
-	read32:	   sbc8240_read32,
-	read64:	   sbc8240_read64,
-	copy_from: sbc8240_copy_from,
-	write8:	   sbc8240_write8,
-	write16:   sbc8240_write16,
-	write32:   sbc8240_write32,
-	write64:   sbc8240_write64,
-	copy_to:   sbc8240_copy_to
-    }
+	{
+		.name           = "sbc8240 Flash Bank #0",
+		.size           = WINDOW_SIZE0,
+		.buswidth       = BUSWIDTH0,
+		.read8          = sbc8240_read8,
+		.read16         = sbc8240_read16,
+		.read32         = sbc8240_read32,
+		.read64         = sbc8240_read64,
+		.copy_from      = sbc8240_copy_from,
+		.write8         = sbc8240_write8,
+		.write16        = sbc8240_write16,
+		.write32        = sbc8240_write32,
+		.write64        = sbc8240_write64,
+		.copy_to        = sbc8240_copy_to
+	},
+	{
+		.name           = "sbc8240 Flash Bank #1",
+		.size           = WINDOW_SIZE1,
+		.buswidth       = BUSWIDTH1,
+		.read8          = sbc8240_read8,
+		.read16         = sbc8240_read16,
+		.read32         = sbc8240_read32,
+		.read64         = sbc8240_read64,
+		.copy_from      = sbc8240_copy_from,
+		.write8         = sbc8240_write8,
+		.write16        = sbc8240_write16,
+		.write32        = sbc8240_write32,
+		.write64        = sbc8240_write64,
+		.copy_to        = sbc8240_copy_to
+	}
 };
 
 #define NUM_FLASH_BANKS	(sizeof(sbc8240_map) / sizeof(struct map_info))
@@ -252,46 +254,46 @@
 #ifdef CONFIG_MTD_PARTITIONS
 
 static struct mtd_partition sbc8240_uboot_partitions [] = {
-  /* Bank 0 */
-    {
-	name:	"U-boot",			/* U-Boot Firmware	*/
-	offset:	0,
-	size:	0x00070000,			/*  7 x 64 KB sectors 	*/
-	mask_flags: MTD_WRITEABLE,		/*  force read-only	*/
-    },
-    {
-	name:	"environment",			/* U-Boot environment	*/
-	offset:	0x00070000,
-	size:	0x00010000,			/*  1 x 64 KB sector	*/
-    },
+	/* Bank 0 */
+	{
+		.name =	"U-boot",			/* U-Boot Firmware	*/
+		.offset =	0,
+		.size =	0x00070000,			/*  7 x 64 KiB sectors 	*/
+		.mask_flags = MTD_WRITEABLE,		/*  force read-only	*/
+	},
+	{
+		.name =	"environment",			/* U-Boot environment	*/
+		.offset =	0x00070000,
+		.size =	0x00010000,			/*  1 x 64 KiB sector	*/
+	},
 };
 
 static struct mtd_partition sbc8240_fs_partitions [] = {
-    {
-	name:	"jffs",				/* JFFS  filesystem	*/
-	offset:	0,
-	size:	0x003C0000,			/*  4 * 15 * 64KB	*/
-    },
-    {
-	name:	"tmp32",
-	offset:	0x003C0000,
-	size:	0x00020000,			/*  4 * 32KB		*/
-    },
-    {
-	name:	"tmp8a",
-	offset:	0x003E0000,
-	size:	0x00008000,			/*  4 * 8KB		*/
-    },
-    {
-	name:	"tmp8b",
-	offset:	0x003E8000,
-	size:	0x00008000,			/*  4 * 8KB		*/
-    },
-    {
-	name:	"tmp16",
-	offset:	0x003F0000,
-	size:	0x00010000,			/*  4 * 16KB		*/
-    }
+	{
+		.name =	"jffs",				/* JFFS  filesystem	*/
+		.offset =	0,
+		.size =	0x003C0000,			/*  4 * 15 * 64KiB	*/
+	},
+	{
+		.name =	"tmp32",
+		.offset =	0x003C0000,
+		.size =	0x00020000,			/*  4 * 32KiB		*/
+	},
+	{
+		.name =	"tmp8a",
+		.offset =	0x003E0000,
+		.size =	0x00008000,			/*  4 * 8KiB		*/
+	},
+	{
+		.name =	"tmp8b",
+		.offset =	0x003E8000,
+		.size =	0x00008000,			/*  4 * 8KiB		*/
+	},
+	{
+		.name =	"tmp16",
+		.offset =	0x003F0000,
+		.size =	0x00010000,			/*  4 * 16KiB		*/
+	}
 };
 
 #define NB_OF(x) (sizeof (x) / sizeof (x[0]))
@@ -317,8 +319,14 @@
 		u_long addr;
 		u_long size;
 	} pt[NUM_FLASH_BANKS] = {
-		{ WINDOW_ADDR0, WINDOW_SIZE0 },
-		{ WINDOW_ADDR1, WINDOW_SIZE1 },
+		{
+			.addr = WINDOW_ADDR0,
+			.size = WINDOW_SIZE0
+		},
+		{
+			.addr = WINDOW_ADDR1,
+			.size = WINDOW_SIZE1
+		},
 	};
 
 	int devicesfound = 0;
@@ -329,7 +337,7 @@
 			"Probing 0x%08lx at 0x%08lx\n", pt[i].size, pt[i].addr);
 
 		sbc8240_map[i].map_priv_1 =
-				(unsigned long) ioremap (pt[i].addr, pt[i].size);
+			(unsigned long) ioremap (pt[i].addr, pt[i].size);
 		if (!sbc8240_map[i].map_priv_1) {
 			printk (MSG_PREFIX "failed to ioremap\n");
 			return -EIO;
@@ -345,17 +353,17 @@
 
 	if (!devicesfound) {
 		printk(KERN_NOTICE MSG_PREFIX
-			"No suppported flash chips found!\n");
+		       "No suppported flash chips found!\n");
 		return -ENXIO;
 	}
 
 #ifdef CONFIG_MTD_PARTITIONS
-	sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions;
-	sbc8240_part_banks[0].type = "static image";
-	sbc8240_part_banks[0].nums = NB_OF(sbc8240_uboot_partitions);
-	sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions;
-	sbc8240_part_banks[1].type = "static file system";
-	sbc8240_part_banks[1].nums = NB_OF(sbc8240_fs_partitions);
+	sbc8240_part_banks[0].mtd_part   = sbc8240_uboot_partitions;
+	sbc8240_part_banks[0].type       = "static image";
+	sbc8240_part_banks[0].nums       = NB_OF(sbc8240_uboot_partitions);
+	sbc8240_part_banks[1].mtd_part   = sbc8240_fs_partitions;
+	sbc8240_part_banks[1].type       = "static file system";
+	sbc8240_part_banks[1].nums       = NB_OF(sbc8240_fs_partitions);
 
 	for (i = 0; i < NUM_FLASH_BANKS; i++) {
 
@@ -368,13 +376,13 @@
 			printk (KERN_NOTICE MSG_PREFIX
 				"Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name);
 			add_mtd_partitions (sbc8240_mtd[i], 
-					sbc8240_part_banks[i].mtd_part,
-				       	sbc8240_part_banks[i].nums);
+					    sbc8240_part_banks[i].mtd_part,
+					    sbc8240_part_banks[i].nums);
 		}
 	}
 #else
 	printk(KERN_NOTICE MSG_PREFIX
-		"Registering %d flash banks at once\n", devicesfound);
+	       "Registering %d flash banks at once\n", devicesfound);
 
 	for (i = 0; i < devicesfound; i++) {
 		add_mtd_device(sbc8240_mtd[i]);


