mtd/drivers/mtd/chips cfi_cmdset_0002.c,1.65,1.66
Thayne Harbaugh
tharbaugh at lnxi.com
Fri Apr 11 18:25:20 EDT 2003
Update of /home/cvs/mtd/drivers/mtd/chips
In directory phoenix.infradead.org:/tmp/cvs-serv10212
Modified Files:
cfi_cmdset_0002.c
Log Message:
Print error information when status bits can't be decoded.
Cleanup ugly if/else nesting with easier to read goto.
Index: cfi_cmdset_0002.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0002.c,v
retrieving revision 1.65
retrieving revision 1.66
diff -u -r1.65 -r1.66
--- cfi_cmdset_0002.c 28 Mar 2003 19:47:42 -0000 1.65
+++ cfi_cmdset_0002.c 11 Apr 2003 22:25:17 -0000 1.66
@@ -457,7 +457,7 @@
static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum, int fast)
{
unsigned long timeo = jiffies + HZ;
- unsigned int oldstatus, status;
+ unsigned int oldstatus, status, prev_oldstatus, prev_status;
unsigned int dq6, dq5;
struct cfi_private *cfi = map->fldrv_priv;
/* We use a 1ms + 1 jiffies generic timeout for writes (most devices have
@@ -500,6 +500,7 @@
adr += chip->start;
ENABLE_VPP(map);
+
if (fast) { /* Unlock bypass */
cfi_send_gen_cmd(0xA0, 0, chip->start, map, cfi, cfi->device_type, NULL);
}
@@ -521,24 +522,24 @@
* This ensures that write operation is really completed,
* or tells us why it failed.
*
- * The polling and decoding of error state appears that it could
+ * It appears tha the polling and decoding of error state might
* be simplified. Don't do it unless you really know what you
* are doing. You must remember that JESD21-C 3.5.3 states that
* the status must be read back an _additional_ two times before
* a failure is determined. This is because these devices have
* internal state machines that are asynchronous to the external
- * LPC bus. During an erase or write the read-back status of the
- * polling bits might be internaling transitioning when the external
+ * data bus. During an erase or write the read-back status of the
+ * polling bits might be transitioning internaly when the external
* read-back occurs. This means that the bits aren't in the final
* state and they might appear to report an error as they transition
* and are in a weird state. This will produce infrequent errors
- * that will usually disappear then next time an erase or write
+ * that will usually disappear the next time an erase or write
* happens (Try tracking those errors down!). To ensure that
* the bits are not in transition the location must be read-back
* two more times and compared against what was written - BOTH reads
* MUST match what was written - don't think this can be simplified
- * to only the last read matching. If the comparison fails error
- * state can then be decoded with certainty.
+ * to only the last read matching. If the comparison fails, error
+ * state can then be decoded.
*
* - Thayne Harbaugh
*/
@@ -572,55 +573,82 @@
/* dq6 still toggling and dq5 still low - must be timeout */
printk( KERN_WARNING
"MTD %s(): Timed out while waiting for write to complete.\n",
- __func__ );
- /* reset */
- cfi_write( map, CMD(0xF0), chip->start );
- ret = -EIO;
- } else {
- /*
- * Either dq5 went high or dq6 finish toggling. For
- * the correct completion of certain types of writes
- * dq5 might _appear_ to go high while dq6 might
- * _appear_ to still be toggling - it depends on the
- * last state of the toggle was in and what the final
- * state will be with true data. We alread know that
- * something changed state with the last set of reads.
- * We will read two more times and use this to either
- * verify that the write completed successfully or
- * that something really went wrong. BOTH reads
- * must match what was written - this certifies that
- * the dq6 is not still toggling and have the status
- * bits erroneously match the datum that was written.
- */
- /*
- * Be optimistic and check success first - then decode any
- * failures.
- */
- oldstatus = cfi_read(map, adr);
- status = cfi_read(map, adr);
-
- if ( oldstatus == datum && status == datum ) {
- /* success - do nothing */
- } else {
- /* something has failed */
- if ( ( ( status ^ oldstatus ) & dq6 )
- && ( status & dq5 ) ) {
- printk(KERN_WARNING "MTD %s(): Internal flash device timeout occured.\n", __func__ );
- } else {
- /*
- * This state means that the write did not succeed
- * and that the usual error state of toggling dq6
- * while dq5 goes high did not happen. Something
- * is seriously wacky!
- */
- printk(KERN_WARNING "MTD %s(): Wacky! Unable to decode failure status\n", __func__ );
- }
- ret = -EIO;
- /* reset on all failures. */
- cfi_write( map, CMD(0xF0), chip->start );
- }
+ __func__ );
+ goto write_failed;
}
+ /*
+ * Either dq5 went high or dq6 finish toggling. For
+ * the correct completion of certain types of writes
+ * dq5 might _appear_ to go high while dq6 might
+ * _appear_ to still be toggling - it depends on the
+ * last toggle-state dq6 was in and what the final
+ * state will be with true data. We alread know that
+ * something changed state with the last set of reads.
+ * We will read two more times and use this to either
+ * verify that the write completed successfully or
+ * that something really went wrong. BOTH reads
+ * must match what was written - this certifies that
+ * dq6 is not still toggling and that the status
+ * bits erroneously match the datum that was written.
+ */
+ prev_oldstatus = oldstatus;
+ prev_status = status;
+
+ /*
+ * Be optimistic and check success first - then decode any
+ * failures.
+ */
+ oldstatus = cfi_read(map, adr);
+ status = cfi_read(map, adr);
+
+ if ( oldstatus == datum && status == datum ) {
+ /* success - do nothing */
+ goto write_done;
+ }
+
+ /* something has failed */
+ if ( ( ( status ^ oldstatus ) & dq6 )
+ && ( status & dq5 ) ) {
+ printk(KERN_WARNING
+ "MTD %s(): Internal flash device timeout occured.\n",
+ __func__ );
+ goto write_failed;
+ }
+
+ /*
+ * If we get to here then it means that something failed
+ * and that the usual error state of toggling dq6
+ * while dq5 goes high did not happen. 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%.2x: 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
+ __func__, datum,
+ prev_oldstatus, prev_status,
+ oldstatus, status);
+
+ printk(KERN_WARNING "MTD %s(): dq6: %d %d %d %d\n",
+ __func__,
+ prev_oldstatus & dq6 ? 1 : 0,
+ prev_status & dq6 ? 1 : 0,
+ oldstatus & dq6 ? 1 : 0,
+ status & dq6 ? 1 : 0);
+
+ printk(KERN_WARNING "MTD %s(): dq5: %d %d %d %d\n",
+ __func__,
+ prev_oldstatus & dq5 ? 1 : 0,
+ prev_status & dq5 ? 1 : 0,
+ oldstatus & dq5 ? 1 : 0,
+ status & dq5 ? 1 : 0);
+
+ write_failed:
+ ret = -EIO;
+ /* reset on all failures. */
+ cfi_write( map, CMD(0xF0), chip->start );
+
+ write_done:
DISABLE_VPP(map);
chip->state = FL_READY;
wake_up(&chip->wq);
More information about the linux-mtd-cvs
mailing list