Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6c24e4161e80a5c03e9d969b5db73d8553846037
Commit:     6c24e4161e80a5c03e9d969b5db73d8553846037
Parent:     5f4d47d5d1060a93be83e33a167a53a7f8c08b20
Author:     Alexander Belyakov <[EMAIL PROTECTED]>
AuthorDate: Wed Nov 7 11:58:07 2007 +0300
Committer:  David Woodhouse <[EMAIL PROTECTED]>
CommitDate: Mon Nov 26 15:54:16 2007 +0000

    [MTD] [NOR] Prevent erase command invocation on suspended chip
    
    while running stress tests we have met cfi_cmdset_0001.c driver issue.
    Working on multipartitional devices with erase suspend on write
    feature enabled it is possible to get erase operation invoked on chip
    with suspended erase. get_chip() looses information about earlier
    suspended erase and new erase operation gets issued. New erase
    operations report successful completion, but blocks remain dirty
    causing, for example, JFFS2 error messages like:
    
    ...
    Newly-erased block contained word 0x20031985 at offset 0x00200000
    Newly-erased block contained word 0x20031985 at offset 0x00280000
    Newly-erased block contained word 0x20031985 at offset 0x00240000
    ...
    
    The patch below fixes that issue.
    
    Signed-off-by: Alexander Belyakov <[EMAIL PROTECTED]>
    Acked-by: Nicolas Pitre <[EMAIL PROTECTED]>
    Signed-off-by: David Woodhouse <[EMAIL PROTECTED]>
---
 drivers/mtd/chips/cfi_cmdset_0001.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c 
b/drivers/mtd/chips/cfi_cmdset_0001.c
index ed5ce41..350671e 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -795,6 +795,7 @@ static int chip_ready (struct map_info *map, struct flchip 
*chip, unsigned long
 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long 
adr, int mode)
 {
        int ret;
+       DECLARE_WAITQUEUE(wait, current);
 
  retry:
        if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING
@@ -851,6 +852,20 @@ static int get_chip(struct map_info *map, struct flchip 
*chip, unsigned long adr
                        spin_unlock(contender->mutex);
                }
 
+               /* Check if we already have suspended erase
+                * on this chip. Sleep. */
+               if (mode == FL_ERASING && shared->erasing
+                   && shared->erasing->oldstate == FL_ERASING) {
+                       spin_unlock(&shared->lock);
+                       set_current_state(TASK_UNINTERRUPTIBLE);
+                       add_wait_queue(&chip->wq, &wait);
+                       spin_unlock(chip->mutex);
+                       schedule();
+                       remove_wait_queue(&chip->wq, &wait);
+                       spin_lock(chip->mutex);
+                       goto retry;
+               }
+
                /* We now own it */
                shared->writing = chip;
                if (mode == FL_ERASING)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to