[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>
This commit is contained in:
parent
5f4d47d5d1
commit
6c24e4161e
1 changed files with 15 additions and 0 deletions
|
@ -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)
|
static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
DECLARE_WAITQUEUE(wait, current);
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING
|
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);
|
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 */
|
/* We now own it */
|
||||||
shared->writing = chip;
|
shared->writing = chip;
|
||||||
if (mode == FL_ERASING)
|
if (mode == FL_ERASING)
|
||||||
|
|
Loading…
Reference in a new issue