* [PATCH 1/3] cfi_cmdset_0001: Do not allow read/write to suspend erase block.
[not found] <20180301133941.19660-1-joakim.tjernlund@infinera.com>
@ 2018-03-01 13:39 ` Joakim Tjernlund
2018-03-22 14:14 ` Richard Weinberger
2018-04-24 15:45 ` Boris Brezillon
2018-03-01 13:39 ` [PATCH 2/3] cfi_cmdset_0001: Workaround Micron Erase suspend bug Joakim Tjernlund
2018-03-01 13:39 ` [PATCH 3/3] cfi_cmdset_0002: Do not allow read/write to suspend erase block Joakim Tjernlund
2 siblings, 2 replies; 10+ messages in thread
From: Joakim Tjernlund @ 2018-03-01 13:39 UTC (permalink / raw)
To: linux-mtd @ lists . infradead . org
Cc: Joakim Tjernlund, Joakim Tjernlund, stable
From: Joakim Tjernlund <joakim.tjernlund@transmode.se>
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.
Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
Cc: <stable@vger.kernel.org>
---
drivers/mtd/chips/cfi_cmdset_0001.c | 16 +++++++++++-----
include/linux/mtd/flashchip.h | 1 +
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 60d5d19e347f..b59872304ae7 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -849,21 +849,25 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
(mode == FL_WRITING && (cfip->SuspendCmdSupport & 1))))
goto sleep;
+ /* 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 */
- map_write(map, CMD(0xB0), adr);
+ map_write(map, CMD(0xB0), chip->in_progress_block_addr);
/* If the flash has finished erasing, then 'erase suspend'
* appears to make some (28F320) flash devices switch to
* 'read' mode. Make sure that we switch to 'read status'
* mode so we get the right data. --rmk
*/
- map_write(map, CMD(0x70), adr);
+ map_write(map, CMD(0x70), chip->in_progress_block_addr);
chip->oldstate = FL_ERASING;
chip->state = FL_ERASE_SUSPENDING;
chip->erase_suspended = 1;
for (;;) {
- status = map_read(map, adr);
+ status = map_read(map, chip->in_progress_block_addr);
if (map_word_andequal(map, status, status_OK, status_OK))
break;
@@ -1059,8 +1063,8 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
sending the 0x70 (Read Status) command to an erasing
chip and expecting it to be ignored, that's what we
do. */
- map_write(map, CMD(0xd0), adr);
- map_write(map, CMD(0x70), adr);
+ map_write(map, CMD(0xd0), chip->in_progress_block_addr);
+ map_write(map, CMD(0x70), chip->in_progress_block_addr);
chip->oldstate = FL_READY;
chip->state = FL_ERASING;
break;
@@ -1951,6 +1955,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
map_write(map, CMD(0xD0), adr);
chip->state = FL_ERASING;
chip->erase_suspended = 0;
+ chip->in_progress_block_addr = adr;
+ chip->in_progress_block_mask = ~(len - 1);
ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
adr, len,
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
index b63fa457febd..3529683f691e 100644
--- a/include/linux/mtd/flashchip.h
+++ b/include/linux/mtd/flashchip.h
@@ -85,6 +85,7 @@ struct flchip {
unsigned int write_suspended:1;
unsigned int erase_suspended:1;
unsigned long in_progress_block_addr;
+ unsigned long in_progress_block_mask;
struct mutex mutex;
wait_queue_head_t wq; /* Wait on here when we're waiting for the chip
--
2.13.6
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/3] cfi_cmdset_0001: Workaround Micron Erase suspend bug.
[not found] <20180301133941.19660-1-joakim.tjernlund@infinera.com>
2018-03-01 13:39 ` [PATCH 1/3] cfi_cmdset_0001: Do not allow read/write to suspend erase block Joakim Tjernlund
@ 2018-03-01 13:39 ` Joakim Tjernlund
2018-03-20 23:06 ` Richard Weinberger
2018-03-01 13:39 ` [PATCH 3/3] cfi_cmdset_0002: Do not allow read/write to suspend erase block Joakim Tjernlund
2 siblings, 1 reply; 10+ messages in thread
From: Joakim Tjernlund @ 2018-03-01 13:39 UTC (permalink / raw)
To: linux-mtd @ lists . infradead . org
Cc: Joakim Tjernlund, Joakim Tjernlund, stable
From: Joakim Tjernlund <joakim.tjernlund@transmode.se>
Some Micron chips does not work well wrt Erase suspend for
boot blocks. This avoids the issue by not allowing Erase suspend
for the boot blocks for the 28F00AP30(1GBit) chip.
Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
Cc: <stable@vger.kernel.org>
---
drivers/mtd/chips/cfi_cmdset_0001.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index b59872304ae7..64ae65dab877 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -45,6 +45,7 @@
#define I82802AB 0x00ad
#define I82802AC 0x00ac
#define PF38F4476 0x881c
+#define M28F00AP30 0x8963
/* STMicroelectronics chips */
#define M50LPW080 0x002F
#define M50FLW080A 0x0080
@@ -375,6 +376,17 @@ static void cfi_fixup_major_minor(struct cfi_private *cfi,
extp->MinorVersion = '1';
}
+static int cfi_is_micron_28F00AP30(struct cfi_private *cfi, struct flchip *chip)
+{
+ /*
+ * Micron(was Numonyx) 1Gbit bottom boot are buggy w.r.t
+ * Erase Supend for their small Erase Blocks(0x8000)
+ */
+ if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30)
+ return 1;
+ return 0;
+}
+
static inline struct cfi_pri_intelext *
read_pri_intelext(struct map_info *map, __u16 adr)
{
@@ -854,6 +866,11 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
chip->in_progress_block_addr)
goto sleep;
+ /* do not suspend small EBs, buggy Micron Chips */
+ if (cfi_is_micron_28F00AP30(cfi, chip) &&
+ (chip->in_progress_block_mask == ~(0x8000-1)))
+ goto sleep;
+
/* Erase suspend */
map_write(map, CMD(0xB0), chip->in_progress_block_addr);
--
2.13.6
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] cfi_cmdset_0002: Do not allow read/write to suspend erase block.
[not found] <20180301133941.19660-1-joakim.tjernlund@infinera.com>
2018-03-01 13:39 ` [PATCH 1/3] cfi_cmdset_0001: Do not allow read/write to suspend erase block Joakim Tjernlund
2018-03-01 13:39 ` [PATCH 2/3] cfi_cmdset_0001: Workaround Micron Erase suspend bug Joakim Tjernlund
@ 2018-03-01 13:39 ` Joakim Tjernlund
2018-03-22 14:21 ` Richard Weinberger
2 siblings, 1 reply; 10+ messages in thread
From: Joakim Tjernlund @ 2018-03-01 13:39 UTC (permalink / raw)
To: linux-mtd @ lists . infradead . org; +Cc: Joakim Tjernlund, stable
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.
Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
Cc: <stable@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,
--
2.13.6
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] cfi_cmdset_0001: Workaround Micron Erase suspend bug.
2018-03-01 13:39 ` [PATCH 2/3] cfi_cmdset_0001: Workaround Micron Erase suspend bug Joakim Tjernlund
@ 2018-03-20 23:06 ` Richard Weinberger
2018-03-21 0:02 ` Joakim Tjernlund
0 siblings, 1 reply; 10+ messages in thread
From: Richard Weinberger @ 2018-03-20 23:06 UTC (permalink / raw)
To: Joakim Tjernlund
Cc: linux-mtd @ lists . infradead . org, Joakim Tjernlund, stable,
Boris Brezillon, Brian Norris, David Woodhouse, Marek Vasut
Joakim,
On Thu, Mar 1, 2018 at 2:39 PM, Joakim Tjernlund
<joakim.tjernlund@infinera.com> wrote:
> From: Joakim Tjernlund <joakim.tjernlund@transmode.se>
>
> Some Micron chips does not work well wrt Erase suspend for
> boot blocks. This avoids the issue by not allowing Erase suspend
> for the boot blocks for the 28F00AP30(1GBit) chip.
Is this bug documented somewhere?
> Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
> Cc: <stable@vger.kernel.org>
> ---
> drivers/mtd/chips/cfi_cmdset_0001.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
> index b59872304ae7..64ae65dab877 100644
> --- a/drivers/mtd/chips/cfi_cmdset_0001.c
> +++ b/drivers/mtd/chips/cfi_cmdset_0001.c
> @@ -45,6 +45,7 @@
> #define I82802AB 0x00ad
> #define I82802AC 0x00ac
> #define PF38F4476 0x881c
> +#define M28F00AP30 0x8963
> /* STMicroelectronics chips */
> #define M50LPW080 0x002F
> #define M50FLW080A 0x0080
> @@ -375,6 +376,17 @@ static void cfi_fixup_major_minor(struct cfi_private *cfi,
> extp->MinorVersion = '1';
> }
>
> +static int cfi_is_micron_28F00AP30(struct cfi_private *cfi, struct flchip *chip)
> +{
> + /*
> + * Micron(was Numonyx) 1Gbit bottom boot are buggy w.r.t
> + * Erase Supend for their small Erase Blocks(0x8000)
> + */
> + if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30)
> + return 1;
> + return 0;
> +}
> +
> static inline struct cfi_pri_intelext *
> read_pri_intelext(struct map_info *map, __u16 adr)
> {
> @@ -854,6 +866,11 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
> chip->in_progress_block_addr)
> goto sleep;
>
> + /* do not suspend small EBs, buggy Micron Chips */
> + if (cfi_is_micron_28F00AP30(cfi, chip) &&
> + (chip->in_progress_block_mask == ~(0x8000-1)))
> + goto sleep;
> +
> /* Erase suspend */
> map_write(map, CMD(0xB0), chip->in_progress_block_addr);
>
> --
> 2.13.6
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
--
Thanks,
//richard
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] cfi_cmdset_0001: Workaround Micron Erase suspend bug.
2018-03-20 23:06 ` Richard Weinberger
@ 2018-03-21 0:02 ` Joakim Tjernlund
0 siblings, 0 replies; 10+ messages in thread
From: Joakim Tjernlund @ 2018-03-21 0:02 UTC (permalink / raw)
To: richard.weinberger@gmail.com
Cc: boris.brezillon@free-electrons.com, computersforpeace@gmail.com,
joakim.tjernlund@transmode.se, stable@vger.kernel.org,
linux-mtd@lists.infradead.org, dwmw2@infradead.org,
marek.vasut@gmail.com
On Wed, 2018-03-21 at 00:06 +0100, Richard Weinberger wrote:
>
> Joakim,
>
> On Thu, Mar 1, 2018 at 2:39 PM, Joakim Tjernlund
> <joakim.tjernlund@infinera.com> wrote:
> > From: Joakim Tjernlund <joakim.tjernlund@transmode.se>
> >
> > Some Micron chips does not work well wrt Erase suspend for
> > boot blocks. This avoids the issue by not allowing Erase suspend
> > for the boot blocks for the 28F00AP30(1GBit) chip.
>
> Is this bug documented somewhere?
One would hope but no. We got confirmation of the problem from the supplier though
but nothing written.
Jocke
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] cfi_cmdset_0001: Do not allow read/write to suspend erase block.
2018-03-01 13:39 ` [PATCH 1/3] cfi_cmdset_0001: Do not allow read/write to suspend erase block Joakim Tjernlund
@ 2018-03-22 14:14 ` Richard Weinberger
2018-03-22 14:26 ` Joakim Tjernlund
2018-04-24 15:45 ` Boris Brezillon
1 sibling, 1 reply; 10+ messages in thread
From: Richard Weinberger @ 2018-03-22 14:14 UTC (permalink / raw)
To: Joakim Tjernlund
Cc: linux-mtd @ lists . infradead . org, Joakim Tjernlund, stable
On Thu, Mar 1, 2018 at 2:39 PM, Joakim Tjernlund
<joakim.tjernlund@infinera.com> wrote:
> From: Joakim Tjernlund <joakim.tjernlund@transmode.se>
>
> 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.
>
> Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
> Cc: <stable@vger.kernel.org>
> ---
> drivers/mtd/chips/cfi_cmdset_0001.c | 16 +++++++++++-----
> include/linux/mtd/flashchip.h | 1 +
> 2 files changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
> index 60d5d19e347f..b59872304ae7 100644
> --- a/drivers/mtd/chips/cfi_cmdset_0001.c
> +++ b/drivers/mtd/chips/cfi_cmdset_0001.c
> @@ -849,21 +849,25 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
> (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1))))
> goto sleep;
>
> + /* 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 */
> - map_write(map, CMD(0xB0), adr);
> + map_write(map, CMD(0xB0), chip->in_progress_block_addr);
>
> /* If the flash has finished erasing, then 'erase suspend'
> * appears to make some (28F320) flash devices switch to
> * 'read' mode. Make sure that we switch to 'read status'
> * mode so we get the right data. --rmk
> */
> - map_write(map, CMD(0x70), adr);
> + map_write(map, CMD(0x70), chip->in_progress_block_addr);
Why do you change to chip->in_progress_block_addr here?
> chip->oldstate = FL_ERASING;
> chip->state = FL_ERASE_SUSPENDING;
> chip->erase_suspended = 1;
> for (;;) {
> - status = map_read(map, adr);
> + status = map_read(map, chip->in_progress_block_addr);
> if (map_word_andequal(map, status, status_OK, status_OK))
> break;
>
> @@ -1059,8 +1063,8 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
> sending the 0x70 (Read Status) command to an erasing
> chip and expecting it to be ignored, that's what we
> do. */
> - map_write(map, CMD(0xd0), adr);
> - map_write(map, CMD(0x70), adr);
> + map_write(map, CMD(0xd0), chip->in_progress_block_addr);
> + map_write(map, CMD(0x70), chip->in_progress_block_addr);
> chip->oldstate = FL_READY;
> chip->state = FL_ERASING;
> break;
> @@ -1951,6 +1955,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
> map_write(map, CMD(0xD0), adr);
> chip->state = FL_ERASING;
> chip->erase_suspended = 0;
> + chip->in_progress_block_addr = adr;
> + chip->in_progress_block_mask = ~(len - 1);
>
> ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
> adr, len,
> diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
> index b63fa457febd..3529683f691e 100644
> --- a/include/linux/mtd/flashchip.h
> +++ b/include/linux/mtd/flashchip.h
> @@ -85,6 +85,7 @@ struct flchip {
> unsigned int write_suspended:1;
> unsigned int erase_suspended:1;
> unsigned long in_progress_block_addr;
> + unsigned long in_progress_block_mask;
>
> struct mutex mutex;
> wait_queue_head_t wq; /* Wait on here when we're waiting for the chip
> --
> 2.13.6
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
--
Thanks,
//richard
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] cfi_cmdset_0002: Do not allow read/write to suspend erase block.
2018-03-01 13:39 ` [PATCH 3/3] cfi_cmdset_0002: Do not allow read/write to suspend erase block Joakim Tjernlund
@ 2018-03-22 14:21 ` Richard Weinberger
2018-03-22 14:27 ` Joakim Tjernlund
0 siblings, 1 reply; 10+ messages in thread
From: Richard Weinberger @ 2018-03-22 14:21 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: linux-mtd @ lists . infradead . org, stable
Joakim,
On Thu, Mar 1, 2018 at 2:39 PM, Joakim Tjernlund
<joakim.tjernlund@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@infinera.com>
> Cc: <stable@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@nod.at>
--
Thanks,
//richard
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] cfi_cmdset_0001: Do not allow read/write to suspend erase block.
2018-03-22 14:14 ` Richard Weinberger
@ 2018-03-22 14:26 ` Joakim Tjernlund
0 siblings, 0 replies; 10+ messages in thread
From: Joakim Tjernlund @ 2018-03-22 14:26 UTC (permalink / raw)
To: richard.weinberger@gmail.com
Cc: joakim.tjernlund@transmode.se, stable@vger.kernel.org,
linux-mtd@lists.infradead.org
On Thu, 2018-03-22 at 15:14 +0100, Richard Weinberger wrote:
>
> On Thu, Mar 1, 2018 at 2:39 PM, Joakim Tjernlund
> <joakim.tjernlund@infinera.com> wrote:
> > From: Joakim Tjernlund <joakim.tjernlund@transmode.se>
> >
> > 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.
> >
> > Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
> > Cc: <stable@vger.kernel.org>
> > ---
> > drivers/mtd/chips/cfi_cmdset_0001.c | 16 +++++++++++-----
> > include/linux/mtd/flashchip.h | 1 +
> > 2 files changed, 12 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
> > index 60d5d19e347f..b59872304ae7 100644
> > --- a/drivers/mtd/chips/cfi_cmdset_0001.c
> > +++ b/drivers/mtd/chips/cfi_cmdset_0001.c
> > @@ -849,21 +849,25 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
> > (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1))))
> > goto sleep;
> >
> > + /* 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 */
> > - map_write(map, CMD(0xB0), adr);
> > + map_write(map, CMD(0xB0), chip->in_progress_block_addr);
> >
> > /* If the flash has finished erasing, then 'erase suspend'
> > * appears to make some (28F320) flash devices switch to
> > * 'read' mode. Make sure that we switch to 'read status'
> > * mode so we get the right data. --rmk
> > */
> > - map_write(map, CMD(0x70), adr);
> > + map_write(map, CMD(0x70), chip->in_progress_block_addr);
>
> Why do you change to chip->in_progress_block_addr here?
To be consistent, in_progress_block_addr is the block in progress. adr will work too
but it looks odd to mix adr and in_progress_block_addr so change it for clarity.
>
> > chip->oldstate = FL_ERASING;
> > chip->state = FL_ERASE_SUSPENDING;
> > chip->erase_suspended = 1;
> > for (;;) {
> > - status = map_read(map, adr);
> > + status = map_read(map, chip->in_progress_block_addr);
> > if (map_word_andequal(map, status, status_OK, status_OK))
> > break;
> >
> > @@ -1059,8 +1063,8 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
> > sending the 0x70 (Read Status) command to an erasing
> > chip and expecting it to be ignored, that's what we
> > do. */
> > - map_write(map, CMD(0xd0), adr);
> > - map_write(map, CMD(0x70), adr);
> > + map_write(map, CMD(0xd0), chip->in_progress_block_addr);
> > + map_write(map, CMD(0x70), chip->in_progress_block_addr);
> > chip->oldstate = FL_READY;
> > chip->state = FL_ERASING;
> > break;
> > @@ -1951,6 +1955,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
> > map_write(map, CMD(0xD0), adr);
> > chip->state = FL_ERASING;
> > chip->erase_suspended = 0;
> > + chip->in_progress_block_addr = adr;
> > + chip->in_progress_block_mask = ~(len - 1);
> >
> > ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
> > adr, len,
> > diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
> > index b63fa457febd..3529683f691e 100644
> > --- a/include/linux/mtd/flashchip.h
> > +++ b/include/linux/mtd/flashchip.h
> > @@ -85,6 +85,7 @@ struct flchip {
> > unsigned int write_suspended:1;
> > unsigned int erase_suspended:1;
> > unsigned long in_progress_block_addr;
> > + unsigned long in_progress_block_mask;
> >
> > struct mutex mutex;
> > wait_queue_head_t wq; /* Wait on here when we're waiting for the chip
> > --
> > 2.13.6
> >
> >
> > ______________________________________________________
> > Linux MTD discussion mailing list
> > http://lists.infradead.org/mailman/listinfo/linux-mtd/
>
>
>
> --
> Thanks,
> //richard
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] cfi_cmdset_0002: Do not allow read/write to suspend erase block.
2018-03-22 14:21 ` Richard Weinberger
@ 2018-03-22 14:27 ` Joakim Tjernlund
0 siblings, 0 replies; 10+ messages in thread
From: Joakim Tjernlund @ 2018-03-22 14:27 UTC (permalink / raw)
To: richard.weinberger@gmail.com
Cc: stable@vger.kernel.org, linux-mtd@lists.infradead.org
On Thu, 2018-03-22 at 15:21 +0100, Richard Weinberger wrote:
>
> Joakim,
>
> On Thu, Mar 1, 2018 at 2:39 PM, Joakim Tjernlund
> <joakim.tjernlund@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?
Dunno, but my guess is yes.
Jocke
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] cfi_cmdset_0001: Do not allow read/write to suspend erase block.
2018-03-01 13:39 ` [PATCH 1/3] cfi_cmdset_0001: Do not allow read/write to suspend erase block Joakim Tjernlund
2018-03-22 14:14 ` Richard Weinberger
@ 2018-04-24 15:45 ` Boris Brezillon
1 sibling, 0 replies; 10+ messages in thread
From: Boris Brezillon @ 2018-04-24 15:45 UTC (permalink / raw)
To: Joakim Tjernlund
Cc: linux-mtd @ lists . infradead . org, Joakim Tjernlund, stable
On Thu, 1 Mar 2018 14:39:39 +0100
Joakim Tjernlund <joakim.tjernlund@infinera.com> wrote:
> From: Joakim Tjernlund <joakim.tjernlund@transmode.se>
>
> 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.
>
> Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
> Cc: <stable@vger.kernel.org>
Applied the patch series to mtd/master after changing the subject
prefix for "mtd: cfi: cmdset_xxx: ".
I'll send a fixes PR to Linus later this week.
Thanks,
Boris
> ---
> drivers/mtd/chips/cfi_cmdset_0001.c | 16 +++++++++++-----
> include/linux/mtd/flashchip.h | 1 +
> 2 files changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
> index 60d5d19e347f..b59872304ae7 100644
> --- a/drivers/mtd/chips/cfi_cmdset_0001.c
> +++ b/drivers/mtd/chips/cfi_cmdset_0001.c
> @@ -849,21 +849,25 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
> (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1))))
> goto sleep;
>
> + /* 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 */
> - map_write(map, CMD(0xB0), adr);
> + map_write(map, CMD(0xB0), chip->in_progress_block_addr);
>
> /* If the flash has finished erasing, then 'erase suspend'
> * appears to make some (28F320) flash devices switch to
> * 'read' mode. Make sure that we switch to 'read status'
> * mode so we get the right data. --rmk
> */
> - map_write(map, CMD(0x70), adr);
> + map_write(map, CMD(0x70), chip->in_progress_block_addr);
> chip->oldstate = FL_ERASING;
> chip->state = FL_ERASE_SUSPENDING;
> chip->erase_suspended = 1;
> for (;;) {
> - status = map_read(map, adr);
> + status = map_read(map, chip->in_progress_block_addr);
> if (map_word_andequal(map, status, status_OK, status_OK))
> break;
>
> @@ -1059,8 +1063,8 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
> sending the 0x70 (Read Status) command to an erasing
> chip and expecting it to be ignored, that's what we
> do. */
> - map_write(map, CMD(0xd0), adr);
> - map_write(map, CMD(0x70), adr);
> + map_write(map, CMD(0xd0), chip->in_progress_block_addr);
> + map_write(map, CMD(0x70), chip->in_progress_block_addr);
> chip->oldstate = FL_READY;
> chip->state = FL_ERASING;
> break;
> @@ -1951,6 +1955,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
> map_write(map, CMD(0xD0), adr);
> chip->state = FL_ERASING;
> chip->erase_suspended = 0;
> + chip->in_progress_block_addr = adr;
> + chip->in_progress_block_mask = ~(len - 1);
>
> ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
> adr, len,
> diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
> index b63fa457febd..3529683f691e 100644
> --- a/include/linux/mtd/flashchip.h
> +++ b/include/linux/mtd/flashchip.h
> @@ -85,6 +85,7 @@ struct flchip {
> unsigned int write_suspended:1;
> unsigned int erase_suspended:1;
> unsigned long in_progress_block_addr;
> + unsigned long in_progress_block_mask;
>
> struct mutex mutex;
> wait_queue_head_t wq; /* Wait on here when we're waiting for the chip
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2018-04-24 15:45 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20180301133941.19660-1-joakim.tjernlund@infinera.com>
2018-03-01 13:39 ` [PATCH 1/3] cfi_cmdset_0001: Do not allow read/write to suspend erase block Joakim Tjernlund
2018-03-22 14:14 ` Richard Weinberger
2018-03-22 14:26 ` Joakim Tjernlund
2018-04-24 15:45 ` Boris Brezillon
2018-03-01 13:39 ` [PATCH 2/3] cfi_cmdset_0001: Workaround Micron Erase suspend bug Joakim Tjernlund
2018-03-20 23:06 ` Richard Weinberger
2018-03-21 0:02 ` Joakim Tjernlund
2018-03-01 13:39 ` [PATCH 3/3] cfi_cmdset_0002: Do not allow read/write to suspend erase block Joakim Tjernlund
2018-03-22 14:21 ` Richard Weinberger
2018-03-22 14:27 ` Joakim Tjernlund
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).