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

Thayne Harbaugh tharbaugh at lnxi.com
Thu Sep 25 10:40:37 EDT 2003


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 at 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);




More information about the linux-mtd-cvs mailing list