[MTD] [NOR] Fix -ETIMEO errors in CFI driver

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Fri Jul 25 10:59:02 EDT 2008


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=998453fbf2e0709bf65ac419718ad284401b2b4f
Commit:     998453fbf2e0709bf65ac419718ad284401b2b4f
Parent:     55679df30dfa37886cd9e22d8dea0e6974a552df
Author:     Alexey Korolev <akorolev at infradead.org>
AuthorDate: Wed Jul 16 15:28:56 2008 +0100
Committer:  David Woodhouse <David.Woodhouse at intel.com>
CommitDate: Fri Jul 25 09:48:42 2008 -0400

    [MTD] [NOR] Fix -ETIMEO errors in CFI driver
    
    Existing CFI driver has problems with excessive writes during erase.
    If CFI driver does many writes during one erase cycle we may face the
    messages with -ETIMEO error on erase operation.  It may cause the
    following data corruption and kernel panics.
    
    The reason of the issue is related to specifics of suspend operation:
    if we write to flash during erase, suspend operation will cost some time
    to erase procedure (for P30 it could be significant). In current version of
    cfi driver the problem of many suspends is partially workarounded by adding
    some time reserv to any operation (8xerase_time) but if we have many writes
    during one erase the problem appears.
    
    This patch detects the suspend and resets timer if suspend occured. It
    has been well verified on different chips. No problems were found.
    Could you please include the patch as it is simple and fixes bad issue.
    
    Signed-off-by: Alexey Korolev <akorolev at infradead.org>
    Signed-off-by: David Woodhouse <David.Woodhouse at intel.com>
---
 drivers/mtd/chips/cfi_cmdset_0001.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 324ff82..5f1b472 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -1149,7 +1149,7 @@ static int inval_cache_and_wait_for_operation(
 	struct cfi_private *cfi = map->fldrv_priv;
 	map_word status, status_OK = CMD(0x80);
 	int chip_state = chip->state;
-	unsigned int timeo, sleep_time;
+	unsigned int timeo, sleep_time, reset_timeo;
 
 	spin_unlock(chip->mutex);
 	if (inval_len)
@@ -1160,6 +1160,7 @@ static int inval_cache_and_wait_for_operation(
 	timeo = chip_op_time * 8;
 	if (!timeo)
 		timeo = 500000;
+	reset_timeo = timeo;
 	sleep_time = chip_op_time / 2;
 
 	for (;;) {
@@ -1201,6 +1202,12 @@ static int inval_cache_and_wait_for_operation(
 			remove_wait_queue(&chip->wq, &wait);
 			spin_lock(chip->mutex);
 		}
+		if (chip->erase_suspended || chip->write_suspended)  {
+			/* Suspend has occured while sleep: reset timeout */
+			timeo = reset_timeo;
+			chip->erase_suspended = 0;
+			chip->write_suspended = 0;
+		}
 	}
 
 	/* Done and happy. */



More information about the linux-mtd-cvs mailing list