[v8,1/9] mtd: cfi_cmdset_0002: Use chip_good() to retry in do_write_oneword()
diff mbox series

Message ID 20190805190326.28772-2-ikegami.t@gmail.com
State New
Delegated to: Vignesh R
Headers show
Series
  • mtd: cfi_cmdset_0002: Fix flash write issue for OpenWrt Project
Related show

Commit Message

Tokunori Ikegami Aug. 5, 2019, 7:03 p.m. UTC
As reported by the OpenWRT team, write requests sometimes fail on some
platforms.
Currently to check the state chip_ready() is used correctly as described by
the flash memory S29GL256P11TFI01 datasheet.
Also chip_good() is used to check if the write is succeeded and it was
implemented by the commit fb4a90bfcd6d8 ("[MTD] CFI-0002 - Improve error
checking").
But actually the write failure is caused on some platforms and also it can
be fixed by using chip_good() to check the state and retry instead.
Also it seems that it is caused after repeated about 1,000 times to retry
the write one word with the reset command.
By using chip_good() to check the state to be done it can be reduced the
retry with reset.
It is depended on the actual flash chip behavior so the root cause is
unknown.

Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Reported-by: Fabio Bettoni <fbettoni@gmail.com>
Cc: Chris Packham <chris.packham@alliedtelesis.co.nz>
Cc: Joakim Tjernlund <Joakim.Tjernlund@infinera.com>
Cc: linux-mtd@lists.infradead.org
Cc: stable@vger.kernel.org
---
Changes since v7:
Rebased on top of polling status register support in master.

Changes since v6:
- Change the tag of Hauke Mehrtens to Signed-off-by as confirmed with him.
- Removed the tag of Koen Vandeputte as confirmed with him.
- Address the ./scripts/checkpatch.pl issues.
- Fix to remain the file type as 100644.

Changes since v5:
- Rebased on top of Liu Jian's fixes in master.
- Change to follow Liu Jian's fixes in master for the write buffer.
- Change the email address of Tokunori Ikegami to ikegami.t@gmail.com.

Changes since v4:
- None.

Changes since v3:
- Update the commit message for the comments.
- Drop the addition of blanks lines around xip_enable().
- Delete unnecessary setting the ret variable to -EIO.
- Change the email address of Tokunori Ikegami to ikegami_to@yahoo.co.jp.

Changes since v2:
- Just update the commit message for the comment.

Changes since v1:
- Just update the commit message.

Background:
This is required for OpenWrt Project to result the flash write issue as
below patche.
<https://git.openwrt.org/?p=openwrt/openwrt.git;a=commitdiff;h=ddc11c3932c7b7b7df7d5fbd48f207e77619eaa7>

Also the original patch in OpenWRT is below.
<https://github.com/openwrt/openwrt/blob/v18.06.0/target/linux/ar71xx/patches-4.9/403-mtd_fix_cfi_cmdset_0002_status_check.patch>

The reason to use chip_good() is that just actually fix the issue.
And also in the past I had fixed the erase function also as same way by the
patch below.
  <https://patchwork.ozlabs.org/patch/922656/>
    Note: The reason for the patch for erase is same.

In my understanding the chip_ready() is just checked the value twice from
flash.
So I think that sometimes incorrect value is read twice and it is depended
on the flash device behavior but not sure..

So change to use chip_good() instead of chip_ready().

 drivers/mtd/chips/cfi_cmdset_0002.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

Comments

Sasha Levin Aug. 6, 2019, 12:43 a.m. UTC | #1
Hi,

[This is an automated email]

This commit has been processed because it contains a -stable tag.
The stable tag indicates that it's relevant for the following trees: all

The bot has tested the following trees: v5.2.6, v4.19.64, v4.14.136, v4.9.187, v4.4.187.

v5.2.6: Failed to apply! Possible dependencies:
    4844ef80305d ("mtd: cfi_cmdset_0002: Add support for polling status register")

v4.19.64: Failed to apply! Possible dependencies:
    4844ef80305d ("mtd: cfi_cmdset_0002: Add support for polling status register")
    d9b8a67b3b95 ("mtd: cfi: fix deadloop in cfi_cmdset_0002.c do_write_buffer")

v4.14.136: Failed to apply! Possible dependencies:
    4844ef80305d ("mtd: cfi_cmdset_0002: Add support for polling status register")
    c64d4419a17c ("mtd: cfi_cmdset_0002: Change erase one block to enable XIP once")
    d9b8a67b3b95 ("mtd: cfi: fix deadloop in cfi_cmdset_0002.c do_write_buffer")
    ea092fb3ce66 ("mtd: cfi_cmdset_0002: Fix coding style issues")

v4.9.187: Failed to apply! Possible dependencies:
    4844ef80305d ("mtd: cfi_cmdset_0002: Add support for polling status register")
    c64d4419a17c ("mtd: cfi_cmdset_0002: Change erase one block to enable XIP once")
    d9b8a67b3b95 ("mtd: cfi: fix deadloop in cfi_cmdset_0002.c do_write_buffer")
    ea092fb3ce66 ("mtd: cfi_cmdset_0002: Fix coding style issues")

v4.4.187: Failed to apply! Possible dependencies:
    4844ef80305d ("mtd: cfi_cmdset_0002: Add support for polling status register")
    c64d4419a17c ("mtd: cfi_cmdset_0002: Change erase one block to enable XIP once")
    d9b8a67b3b95 ("mtd: cfi: fix deadloop in cfi_cmdset_0002.c do_write_buffer")
    ea092fb3ce66 ("mtd: cfi_cmdset_0002: Fix coding style issues")


NOTE: The patch will not be queued to stable trees until it is upstream.

How should we proceed with this patch?

--
Thanks,
Sasha
Tokunori Ikegami Aug. 6, 2019, 2:30 p.m. UTC | #2
Hi,

Thanks for the mail.

On 2019/08/06 9:43, Sasha Levin wrote:
> Hi,
>
> [This is an automated email]
>
> This commit has been processed because it contains a -stable tag.
> The stable tag indicates that it's relevant for the following trees: all
>
> The bot has tested the following trees: v5.2.6, v4.19.64, v4.14.136, v4.9.187, v4.4.187.
>
> v5.2.6: Failed to apply! Possible dependencies:
>      4844ef80305d ("mtd: cfi_cmdset_0002: Add support for polling status register")
>
> v4.19.64: Failed to apply! Possible dependencies:
>      4844ef80305d ("mtd: cfi_cmdset_0002: Add support for polling status register")
>      d9b8a67b3b95 ("mtd: cfi: fix deadloop in cfi_cmdset_0002.c do_write_buffer")
>
> v4.14.136: Failed to apply! Possible dependencies:
>      4844ef80305d ("mtd: cfi_cmdset_0002: Add support for polling status register")
>      c64d4419a17c ("mtd: cfi_cmdset_0002: Change erase one block to enable XIP once")
>      d9b8a67b3b95 ("mtd: cfi: fix deadloop in cfi_cmdset_0002.c do_write_buffer")
>      ea092fb3ce66 ("mtd: cfi_cmdset_0002: Fix coding style issues")
>
> v4.9.187: Failed to apply! Possible dependencies:
>      4844ef80305d ("mtd: cfi_cmdset_0002: Add support for polling status register")
>      c64d4419a17c ("mtd: cfi_cmdset_0002: Change erase one block to enable XIP once")
>      d9b8a67b3b95 ("mtd: cfi: fix deadloop in cfi_cmdset_0002.c do_write_buffer")
>      ea092fb3ce66 ("mtd: cfi_cmdset_0002: Fix coding style issues")
>
> v4.4.187: Failed to apply! Possible dependencies:
>      4844ef80305d ("mtd: cfi_cmdset_0002: Add support for polling status register")
>      c64d4419a17c ("mtd: cfi_cmdset_0002: Change erase one block to enable XIP once")
>      d9b8a67b3b95 ("mtd: cfi: fix deadloop in cfi_cmdset_0002.c do_write_buffer")
>      ea092fb3ce66 ("mtd: cfi_cmdset_0002: Fix coding style issues")
>
>
> NOTE: The patch will not be queued to stable trees until it is upstream.
>
> How should we proceed with this patch?

Yes I will do fix the patch for the trees failed to apply if it was 
upstream.

Regards,
Ikegami

>
> --
> Thanks,
> Sasha

Patch
diff mbox series

diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index f4da7bd552e9..19787a14350b 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -1717,31 +1717,36 @@  static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
 			continue;
 		}
 
-		if (time_after(jiffies, timeo) &&
-		    !chip_ready(map, chip, adr)) {
+		/*
+		 * We check "time_after" and "!chip_good" before checking
+		 * "chip_good" to avoid the failure due to scheduling.
+		 */
+		if (time_after(jiffies, timeo) && !chip_good(map, chip, adr, datum)) {
 			xip_enable(map, chip, adr);
 			printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
 			xip_disable(map, chip, adr);
+			ret = -EIO;
 			break;
 		}
 
-		if (chip_ready(map, chip, adr))
+		if (chip_good(map, chip, adr, datum))
 			break;
 
 		/* Latency issues. Drop the lock, wait a while and retry */
 		UDELAY(map, chip, adr, 1);
 	}
+
 	/* Did we succeed? */
-	if (!chip_good(map, chip, adr, datum)) {
+	if (ret) {
 		/* reset on all failures. */
 		cfi_check_err_status(map, chip, adr);
 		map_write(map, CMD(0xF0), chip->start);
 		/* FIXME - should have reset delay before continuing */
 
-		if (++retry_cnt <= MAX_RETRIES)
+		if (++retry_cnt <= MAX_RETRIES) {
+			ret = 0;
 			goto retry;
-
-		ret = -EIO;
+		}
 	}
 	xip_enable(map, chip, adr);
  op_done: