[PATCH 3/3] cfi_cmdset_0002: Do not allow read/write to suspend erase block.

Richard Weinberger richard.weinberger at gmail.com
Thu Mar 22 07:21:46 PDT 2018


Joakim,

On Thu, Mar 1, 2018 at 2:39 PM, Joakim Tjernlund
<joakim.tjernlund at infinera.com> wrote:
> Currently it is possible to read and/or write to suspend EB's.
> Writing /dev/mtdX or /dev/mtdblockX from several processes may
> break the flash state machine.
>
> Taken from cfi_cmdset_0001 driver.

Does cfi_cmdset_0020 also need fixing?

> Signed-off-by: Joakim Tjernlund <joakim.tjernlund at infinera.com>
> Cc: <stable at vger.kernel.org>
> ---
>  drivers/mtd/chips/cfi_cmdset_0002.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
> index 56aa6b75213d..d524a64ed754 100644
> --- a/drivers/mtd/chips/cfi_cmdset_0002.c
> +++ b/drivers/mtd/chips/cfi_cmdset_0002.c
> @@ -816,9 +816,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
>                     (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))))
>                         goto sleep;
>
> -               /* We could check to see if we're trying to access the sector
> -                * that is currently being erased. However, no user will try
> -                * anything like that so we just wait for the timeout. */

:-)

> +               /* Do not allow suspend iff read/write to EB address */
> +               if ((adr & chip->in_progress_block_mask) ==
> +                   chip->in_progress_block_addr)
> +                       goto sleep;
>
>                 /* Erase suspend */
>                 /* It's harmless to issue the Erase-Suspend and Erase-Resume
> @@ -2267,6 +2268,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
>         chip->state = FL_ERASING;
>         chip->erase_suspended = 0;
>         chip->in_progress_block_addr = adr;
> +       chip->in_progress_block_mask = ~(map->size - 1);
>
>         INVALIDATE_CACHE_UDELAY(map, chip,
>                                 adr, map->size,
> @@ -2356,6 +2358,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
>         chip->state = FL_ERASING;
>         chip->erase_suspended = 0;
>         chip->in_progress_block_addr = adr;
> +       chip->in_progress_block_mask = ~(len - 1);
>
>         INVALIDATE_CACHE_UDELAY(map, chip,
>                                 adr, len,

Reviewed-by: Richard Weinberger <richard at nod.at>

-- 
Thanks,
//richard



More information about the linux-mtd mailing list