mtd/drivers/mtd/chips cfi_cmdset_0002.c,1.114,1.115

ebiederman at lnxi.com ebiederman at lnxi.com
Thu May 19 23:28:26 EDT 2005


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

Modified Files:
	cfi_cmdset_0002.c 
Log Message:
- Check for errors besides infinite loops when writing and erasing.


Index: cfi_cmdset_0002.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0002.c,v
retrieving revision 1.114
retrieving revision 1.115
diff -u -r1.114 -r1.115
--- cfi_cmdset_0002.c	11 Dec 2004 15:43:53 -0000	1.114
+++ cfi_cmdset_0002.c	20 May 2005 03:28:23 -0000	1.115
@@ -43,6 +43,7 @@
 #define MANUFACTURER_AMD	0x0001
 #define MANUFACTURER_SST	0x00BF
 #define SST49LF004B	        0x0060
+#define SST49LF008A		0x005a
 
 static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
@@ -191,6 +192,7 @@
 };
 static struct cfi_fixup jedec_fixup_table[] = {
 	{ MANUFACTURER_SST, SST49LF004B, fixup_use_fwh_lock, NULL, },
+	{ MANUFACTURER_SST, SST49LF008A, fixup_use_fwh_lock, NULL, },
 	{ 0, 0, NULL, NULL }
 };
 
@@ -401,6 +403,32 @@
 	return map_word_equal(map, d, t);
 }
 
+/*
+ * Return true if the chip is ready and has the correct value.
+ *
+ * Ready is one of: read mode, query mode, erase-suspend-read mode (in any
+ * non-suspended sector) and it is indicated by no bits toggling.
+ *
+ * Error are indicated by toggling bits or bits held with the wrong value,
+ * or with bits toggling.
+ *
+ * Note that anything more complicated than checking if no bits are toggling
+ * (including checking DQ5 for an error status) is tricky to get working
+ * correctly and is therefore not done	(particulary with interleaved chips
+ * as each chip must be checked independantly of the others).
+ *
+ */
+static int chip_good(struct map_info *map, unsigned long addr, map_word expected)
+{
+	map_word oldd, curd;
+
+	oldd = map_read(map, addr);
+	curd = map_read(map, addr);
+
+	return	map_word_equal(map, oldd, curd) && 
+		map_word_equal(map, curd, expected);
+}
+
 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
 {
 	DECLARE_WAITQUEUE(wait, current);
@@ -765,26 +793,29 @@
 		}
 
 		if (chip_ready(map, adr))
-			goto op_done;
+			break;
 
-		if (time_after(jiffies, timeo))
+		if (time_after(jiffies, timeo)) {
+			printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
                         break;
+		}
 
 		/* Latency issues. Drop the lock, wait a while and retry */
 		cfi_spin_unlock(chip->mutex);
 		cfi_udelay(1);
 		cfi_spin_lock(chip->mutex);
 	}
+	/* Did we succeed? */
+	if (!chip_good(map, adr, datum)) {
+		/* reset on all failures. */
+		map_write( map, CMD(0xF0), chip->start );
+		/* FIXME - should have reset delay before continuing */
 
-	printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
-
-	/* reset on all failures. */
-	map_write( map, CMD(0xF0), chip->start );
-	/* FIXME - should have reset delay before continuing */
-	if (++retry_cnt <= MAX_WORD_RETRIES) 
-		goto retry;
+		if (++retry_cnt <= MAX_WORD_RETRIES) 
+			goto retry;
 
-	ret = -EIO;
+		ret = -EIO;
+	}
  op_done:
 	chip->state = FL_READY;
 	put_chip(map, chip, adr);
@@ -1187,10 +1218,13 @@
 		}
 
 		if (chip_ready(map, adr))
-			goto op_done;
+			break;
 
-		if (time_after(jiffies, timeo))
+		if (time_after(jiffies, timeo)) {
+			printk(KERN_WARNING "MTD %s(): software timeout\n",
+				__func__ );
 			break;
+		}
 
 		/* Latency issues. Drop the lock, wait a while and retry */
 		cfi_spin_unlock(chip->mutex);
@@ -1198,16 +1232,15 @@
 		schedule_timeout(1);
 		cfi_spin_lock(chip->mutex);
 	}
+	/* Did we succeed? */
+	if (!chip_good(map, adr, map_word_ff(map))) {
+		/* reset on all failures. */
+		map_write( map, CMD(0xF0), chip->start );
+		/* FIXME - should have reset delay before continuing */
 
-	printk(KERN_WARNING "MTD %s(): software timeout\n",
-	       __func__ );
-
-	/* reset on all failures. */
-	map_write( map, CMD(0xF0), chip->start );
-	/* FIXME - should have reset delay before continuing */
+		ret = -EIO;
+	}
 
-	ret = -EIO;
- op_done:
 	chip->state = FL_READY;
 	put_chip(map, chip, adr);
 	cfi_spin_unlock(chip->mutex);
@@ -1272,10 +1305,13 @@
 		}
 
 		if (chip_ready(map, adr))
-			goto op_done;
+			break;
 
-		if (time_after(jiffies, timeo))
+		if (time_after(jiffies, timeo)) {
+			printk(KERN_WARNING "MTD %s(): software timeout\n",
+				__func__ );
 			break;
+		}
 
 		/* Latency issues. Drop the lock, wait a while and retry */
 		cfi_spin_unlock(chip->mutex);
@@ -1283,16 +1319,15 @@
 		schedule_timeout(1);
 		cfi_spin_lock(chip->mutex);
 	}
-	
-	printk(KERN_WARNING "MTD %s(): software timeout\n",
-	       __func__ );
-	
-	/* reset on all failures. */
-	map_write( map, CMD(0xF0), chip->start );
-	/* FIXME - should have reset delay before continuing */
+	/* Did we succeed? */
+	if (chip_good(map, adr, map_word_ff(map))) {
+		/* reset on all failures. */
+		map_write( map, CMD(0xF0), chip->start );
+		/* FIXME - should have reset delay before continuing */
+
+		ret = -EIO;
+	}
 
-	ret = -EIO;
- op_done:
 	chip->state = FL_READY;
 	put_chip(map, chip, adr);
 	cfi_spin_unlock(chip->mutex);





More information about the linux-mtd-cvs mailing list