aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorAlexey Korolev <akorolev@infradead.org>2008-04-04 17:30:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-04 17:46:26 -0400
commitfb6d080c6f75dfd7e23d5a3575334785aa8738eb (patch)
treead416f53e71a9f00d7dc4bcf0a24d035cb89ad1f /drivers/mtd
parent4077960e2a38ec59096ff993cd080056e17f3707 (diff)
mtd: fix broken state in CFI driver caused by FL_SHUTDOWN
THe CFI driver in 2.6.24 kernel is broken. Not so intensive read/write operations cause incomplete writes which lead to kernel panics in JFFS2. We investigated the issue - it is caused by bug in FL_SHUTDOWN parsing code. Sometimes chip returns -EIO as if it is in FL_SHUTDOWN state when it should wait in FL_PONT (error in order of conditions). The following patch fixes the bug in state parsing code of CFI. Also I've added comments to notify developers if they want to add new case in future. Signed-off-by: Alexey Korolev <akorolev@infradead.org> Reviewed-by: Joern Engel <joern@logfs.org> Cc: David Woodhouse <dwmw2@infradead.org> Cc: <stable@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 47794d23a42e..0080452531d6 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -718,7 +718,7 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
718 /* Someone else might have been playing with it. */ 718 /* Someone else might have been playing with it. */
719 return -EAGAIN; 719 return -EAGAIN;
720 } 720 }
721 721 /* Fall through */
722 case FL_READY: 722 case FL_READY:
723 case FL_CFI_QUERY: 723 case FL_CFI_QUERY:
724 case FL_JEDEC_QUERY: 724 case FL_JEDEC_QUERY:
@@ -778,14 +778,14 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
778 chip->state = FL_READY; 778 chip->state = FL_READY;
779 return 0; 779 return 0;
780 780
781 case FL_SHUTDOWN:
782 /* The machine is rebooting now,so no one can get chip anymore */
783 return -EIO;
781 case FL_POINT: 784 case FL_POINT:
782 /* Only if there's no operation suspended... */ 785 /* Only if there's no operation suspended... */
783 if (mode == FL_READY && chip->oldstate == FL_READY) 786 if (mode == FL_READY && chip->oldstate == FL_READY)
784 return 0; 787 return 0;
785 788 /* Fall through */
786 case FL_SHUTDOWN:
787 /* The machine is rebooting now,so no one can get chip anymore */
788 return -EIO;
789 default: 789 default:
790 sleep: 790 sleep:
791 set_current_state(TASK_UNINTERRUPTIBLE); 791 set_current_state(TASK_UNINTERRUPTIBLE);