Commit 6c24e4161e80a5c03e9d969b5db73d8553846037
Committed by
David Woodhouse
1 parent
5f4d47d5d1
Exists in
master
and in
7 other branches
[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 <alexander.belyakov@intel.com> Acked-by: Nicolas Pitre <nico@cam.org> Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Showing 1 changed file with 15 additions and 0 deletions Side-by-side Diff
drivers/mtd/chips/cfi_cmdset_0001.c
... | ... | @@ -795,6 +795,7 @@ |
795 | 795 | static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) |
796 | 796 | { |
797 | 797 | int ret; |
798 | + DECLARE_WAITQUEUE(wait, current); | |
798 | 799 | |
799 | 800 | retry: |
800 | 801 | if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING |
... | ... | @@ -849,6 +850,20 @@ |
849 | 850 | } |
850 | 851 | spin_lock(&shared->lock); |
851 | 852 | spin_unlock(contender->mutex); |
853 | + } | |
854 | + | |
855 | + /* Check if we already have suspended erase | |
856 | + * on this chip. Sleep. */ | |
857 | + if (mode == FL_ERASING && shared->erasing | |
858 | + && shared->erasing->oldstate == FL_ERASING) { | |
859 | + spin_unlock(&shared->lock); | |
860 | + set_current_state(TASK_UNINTERRUPTIBLE); | |
861 | + add_wait_queue(&chip->wq, &wait); | |
862 | + spin_unlock(chip->mutex); | |
863 | + schedule(); | |
864 | + remove_wait_queue(&chip->wq, &wait); | |
865 | + spin_lock(chip->mutex); | |
866 | + goto retry; | |
852 | 867 | } |
853 | 868 | |
854 | 869 | /* We now own it */ |