All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tokunori Ikegami <ikegami.t@gmail.com>
To: Ahmad Fatoum <a.fatoum@pengutronix.de>,
	Thorsten Leemhuis <regressions@leemhuis.info>,
	linux-mtd@lists.infradead.org, Joakim.Tjernlund@infinera.com,
	miquel.raynal@bootlin.com, vigneshr@ti.com, richard@nod.at,
	"regressions@lists.linux.dev" <regressions@lists.linux.dev>
Cc: Chris Packham <chris.packham@alliedtelesis.co.nz>,
	Brian Norris <computersforpeace@gmail.com>,
	David Woodhouse <dwmw2@infradead.org>,
	marek.vasut@gmail.com, cyrille.pitchen@wedev4u.fr,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Pengutronix Kernel Team <kernel@pengutronix.de>,
	linuxppc-dev@lists.ozlabs.org
Subject: Re: [BUG] mtd: cfi_cmdset_0002: write regression since v4.17-rc1
Date: Mon, 7 Mar 2022 00:49:39 +0900	[thread overview]
Message-ID: <9621c512-06f2-17b2-5c68-943b1f0981eb@gmail.com> (raw)
In-Reply-To: <f9e46b61-37e5-a280-edb0-27f8e81a8680@pengutronix.de>

[-- Attachment #1: Type: text/plain, Size: 2554 bytes --]

Hi,

On 2022/03/04 20:11, Ahmad Fatoum wrote:
> Hello Tokunori-san,
>
> On 20.02.22 13:22, Tokunori Ikegami wrote:
>> Hi Ahmad-san,
>>
>> Could you please try the version 2 patch attached for the error case?
>> This version is to check the DQ true data 0xFF by chip_good().
> I had a similar patch locally as well at first. I just tested yours
> and I can't reproduce the issue.
Thanks for your support.
Sorry if possible could you please retest the attached the patch again 
since this fixed the version 1 patch maintainer review comments?
>
>> But I am not sure if this works or not since the error is possible to be caused by Hi-Z 0xff on floating bus or etc.
> That it works for me could be because of Hi-Z 0xff, which is why
> decided against it.
I see.
>
>>>>>> What seems to work for me is checking if chip_good or chip_ready
>>>>>> and map_word is equal to 0xFF. I can't justify why this is ok though.
>>>>>> (Worst case bus is floating at this point of time and Hi-Z is read
>>>>>> as 0xff on CPU data lines...)
>>>>> Sorry I am not sure about this.
>>>>> I thought the chip_ready() itself is correct as implemented as the data sheet in the past.
>>>>> But it did not work correctly so changed to use chip_good() instead as it is also correct.
>>>> What exactly in the datasheet makes you believe chip_good is not appropriate?
>>> I just mentioned about the actual issue behaviors as not worked chip_good() on S29GL964N and not worked chip_ready() on MX29GL512FHT2I-11G before etc.
>>> Anyway let me recheck the data sheet details as just checked it again quickly but needed more investigation to understand.
>> As far as I checked still both chip_good() and chip_ready() seem correct but still the root cause is unknown.
>> If as you mentioned the issue was cased by the DQ true data 0xFF I am not sure why the read work without any error after the write operation.
>> Also if the error was caused by the Hi-Z 0xff on floating bus as mentioned I am not sure why the read work without any error after the write operation with chip_ready().
>> Sorry anyway the root cause is also unknown when the write operation was changed to use chip_good() instead of chip_ready().
> I've be ok with v1 then. Restores working behavior for me and shouldn't break others.

Noted but still I am thinking the version 2 patch to check 0xff seems 
better than to use chip_ready() so let me consider this again later.

Regards,
Ikegami

>
> Cheers and thanks again,
> Ahmad
>
>> Regards,
>> Ikegami
>>
>>> Regards,
>>> Ikegami
>>>
>>>> Cheers,
>>>> Ahmad
>>>>
>>>>
>

[-- Attachment #2: v2-0001-mtd-cfi_cmdset_0002-Use-chip_ready-for-write-on-S.patch --]
[-- Type: text/x-patch, Size: 6844 bytes --]

From 306f7266cb2b6d07bbc5882b3b977264483ad128 Mon Sep 17 00:00:00 2001
From: Tokunori Ikegami <ikegami.t@gmail.com>
Date: Mon, 14 Feb 2022 01:08:02 +0900
Subject: [PATCH v2] mtd: cfi_cmdset_0002: Use chip_ready() for write on
 S29GL064N

The regression issue has been caused on S29GL064N and reported it.
Also the change mentioned is to use chip_good() for buffered write.
So disable the change on S29GL064N and use chip_ready() as before.

Fixes: dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to check correct value")
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
Cc: Miquel Raynal <miquel.raynal@bootlin.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Vignesh Raghavendra <vigneshr@ti.com>
Cc: linux-mtd@lists.infradead.org
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/b687c259-6413-26c9-d4c9-b3afa69ea124@pengutronix.de/
---
 drivers/mtd/chips/cfi_cmdset_0002.c | 89 +++++++++++++++--------------
 1 file changed, 47 insertions(+), 42 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index a761134fd3be..5e14b60e8638 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -48,6 +48,7 @@
 #define SST49LF040B		0x0050
 #define SST49LF008A		0x005a
 #define AT49BV6416		0x00d6
+#define S29GL064N_MN12		0x0c01
 
 /*
  * Status Register bit description. Used by flash devices that don't
@@ -462,7 +463,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
 	{ CFI_MFR_AMD, 0x0056, fixup_use_secsi },
 	{ CFI_MFR_AMD, 0x005C, fixup_use_secsi },
 	{ CFI_MFR_AMD, 0x005F, fixup_use_secsi },
-	{ CFI_MFR_AMD, 0x0c01, fixup_s29gl064n_sectors },
+	{ CFI_MFR_AMD, S29GL064N_MN12, fixup_s29gl064n_sectors },
 	{ CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors },
 	{ CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors },
 	{ CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors },
@@ -801,22 +802,12 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
 	return NULL;
 }
 
-/*
- * Return true if the chip is ready.
- *
- * Ready is one of: read mode, query mode, erase-suspend-read mode (in any
- * non-suspended sector) and is indicated by no toggle bits toggling.
- *
- * Note that anything more complicated than checking if no bits are toggling
- * (including checking DQ5 for an error status) is tricky to get working
- * correctly and is therefore not done	(particularly with interleaved chips
- * as each chip must be checked independently of the others).
- */
-static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
-			       unsigned long addr)
+static int __xipram chip_check(struct map_info *map, struct flchip *chip,
+			       unsigned long addr, map_word *expected)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
-	map_word d, t;
+	map_word oldd, curd;
+	int ret;
 
 	if (cfi_use_status_reg(cfi)) {
 		map_word ready = CMD(CFI_SR_DRB);
@@ -826,17 +817,35 @@ static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
 		 */
 		cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
 				 cfi->device_type, NULL);
-		d = map_read(map, addr);
+		curd = map_read(map, addr);
 
-		return map_word_andequal(map, d, ready, ready);
+		return map_word_andequal(map, curd, ready, ready);
 	}
 
-	d = map_read(map, addr);
-	t = map_read(map, addr);
+	oldd = map_read(map, addr);
+	curd = map_read(map, addr);
+
+	ret = map_word_equal(map, oldd, curd);
 
-	return map_word_equal(map, d, t);
+	if (!ret || !expected)
+		return ret;
+
+	return map_word_equal(map, curd, *expected);
 }
 
+/*
+ * Return true if the chip is ready.
+ *
+ * Ready is one of: read mode, query mode, erase-suspend-read mode (in any
+ * non-suspended sector) and is indicated by no toggle bits toggling.
+ *
+ * Note that anything more complicated than checking if no bits are toggling
+ * (including checking DQ5 for an error status) is tricky to get working
+ * correctly and is therefore not done	(particularly with interleaved chips
+ * as each chip must be checked independently of the others).
+ */
+#define chip_ready(map, chip, addr) chip_check(map, chip, addr, NULL)
+
 /*
  * Return true if the chip is ready and has the correct value.
  *
@@ -855,28 +864,24 @@ static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
 static int __xipram chip_good(struct map_info *map, struct flchip *chip,
 			      unsigned long addr, map_word expected)
 {
-	struct cfi_private *cfi = map->fldrv_priv;
-	map_word oldd, curd;
-
-	if (cfi_use_status_reg(cfi)) {
-		map_word ready = CMD(CFI_SR_DRB);
+	return chip_check(map, chip, addr, &expected);
+}
 
-		/*
-		 * For chips that support status register, check device
-		 * ready bit
-		 */
-		cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
-				 cfi->device_type, NULL);
-		curd = map_read(map, addr);
+static bool cfi_use_chip_ready_for_write(struct map_info *map)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
 
-		return map_word_andequal(map, curd, ready, ready);
-	}
+	return cfi->mfr == CFI_MFR_AMD && cfi->id == S29GL064N_MN12;
+}
 
-	oldd = map_read(map, addr);
-	curd = map_read(map, addr);
+static int __xipram chip_good_for_write(struct map_info *map,
+					struct flchip *chip, unsigned long addr,
+					map_word expected)
+{
+	if (cfi_use_chip_ready_for_write(map))
+		return chip_ready(map, chip, addr);
 
-	return	map_word_equal(map, oldd, curd) &&
-		map_word_equal(map, curd, expected);
+	return chip_good(map, chip, addr, expected);
 }
 
 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
@@ -1699,7 +1704,7 @@ static int __xipram do_write_oneword_once(struct map_info *map,
 		 * "chip_good" to avoid the failure due to scheduling.
 		 */
 		if (time_after(jiffies, timeo) &&
-		    !chip_good(map, chip, adr, datum)) {
+		    !chip_good_for_write(map, chip, adr, datum)) {
 			xip_enable(map, chip, adr);
 			printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
 			xip_disable(map, chip, adr);
@@ -1707,7 +1712,7 @@ static int __xipram do_write_oneword_once(struct map_info *map,
 			break;
 		}
 
-		if (chip_good(map, chip, adr, datum)) {
+		if (chip_good_for_write(map, chip, adr, datum)) {
 			if (cfi_check_err_status(map, chip, adr))
 				ret = -EIO;
 			break;
@@ -1979,14 +1984,14 @@ static int __xipram do_write_buffer_wait(struct map_info *map,
 		 * "chip_good" to avoid the failure due to scheduling.
 		 */
 		if (time_after(jiffies, timeo) &&
-		    !chip_good(map, chip, adr, datum)) {
+		    !chip_good_for_write(map, chip, adr, datum)) {
 			pr_err("MTD %s(): software timeout, address:0x%.8lx.\n",
 			       __func__, adr);
 			ret = -EIO;
 			break;
 		}
 
-		if (chip_good(map, chip, adr, datum)) {
+		if (chip_good_for_write(map, chip, adr, datum)) {
 			if (cfi_check_err_status(map, chip, adr))
 				ret = -EIO;
 			break;
-- 
2.32.0


WARNING: multiple messages have this Message-ID (diff)
From: Tokunori Ikegami <ikegami.t@gmail.com>
To: Ahmad Fatoum <a.fatoum@pengutronix.de>,
	Thorsten Leemhuis <regressions@leemhuis.info>,
	linux-mtd@lists.infradead.org, Joakim.Tjernlund@infinera.com,
	miquel.raynal@bootlin.com, vigneshr@ti.com, richard@nod.at,
	"regressions@lists.linux.dev" <regressions@lists.linux.dev>
Cc: linuxppc-dev@lists.ozlabs.org,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	marek.vasut@gmail.com,
	Chris Packham <chris.packham@alliedtelesis.co.nz>,
	Pengutronix Kernel Team <kernel@pengutronix.de>,
	cyrille.pitchen@wedev4u.fr,
	Brian Norris <computersforpeace@gmail.com>,
	David Woodhouse <dwmw2@infradead.org>
Subject: Re: [BUG] mtd: cfi_cmdset_0002: write regression since v4.17-rc1
Date: Mon, 7 Mar 2022 00:49:39 +0900	[thread overview]
Message-ID: <9621c512-06f2-17b2-5c68-943b1f0981eb@gmail.com> (raw)
In-Reply-To: <f9e46b61-37e5-a280-edb0-27f8e81a8680@pengutronix.de>

[-- Attachment #1: Type: text/plain, Size: 2554 bytes --]

Hi,

On 2022/03/04 20:11, Ahmad Fatoum wrote:
> Hello Tokunori-san,
>
> On 20.02.22 13:22, Tokunori Ikegami wrote:
>> Hi Ahmad-san,
>>
>> Could you please try the version 2 patch attached for the error case?
>> This version is to check the DQ true data 0xFF by chip_good().
> I had a similar patch locally as well at first. I just tested yours
> and I can't reproduce the issue.
Thanks for your support.
Sorry if possible could you please retest the attached the patch again 
since this fixed the version 1 patch maintainer review comments?
>
>> But I am not sure if this works or not since the error is possible to be caused by Hi-Z 0xff on floating bus or etc.
> That it works for me could be because of Hi-Z 0xff, which is why
> decided against it.
I see.
>
>>>>>> What seems to work for me is checking if chip_good or chip_ready
>>>>>> and map_word is equal to 0xFF. I can't justify why this is ok though.
>>>>>> (Worst case bus is floating at this point of time and Hi-Z is read
>>>>>> as 0xff on CPU data lines...)
>>>>> Sorry I am not sure about this.
>>>>> I thought the chip_ready() itself is correct as implemented as the data sheet in the past.
>>>>> But it did not work correctly so changed to use chip_good() instead as it is also correct.
>>>> What exactly in the datasheet makes you believe chip_good is not appropriate?
>>> I just mentioned about the actual issue behaviors as not worked chip_good() on S29GL964N and not worked chip_ready() on MX29GL512FHT2I-11G before etc.
>>> Anyway let me recheck the data sheet details as just checked it again quickly but needed more investigation to understand.
>> As far as I checked still both chip_good() and chip_ready() seem correct but still the root cause is unknown.
>> If as you mentioned the issue was cased by the DQ true data 0xFF I am not sure why the read work without any error after the write operation.
>> Also if the error was caused by the Hi-Z 0xff on floating bus as mentioned I am not sure why the read work without any error after the write operation with chip_ready().
>> Sorry anyway the root cause is also unknown when the write operation was changed to use chip_good() instead of chip_ready().
> I've be ok with v1 then. Restores working behavior for me and shouldn't break others.

Noted but still I am thinking the version 2 patch to check 0xff seems 
better than to use chip_ready() so let me consider this again later.

Regards,
Ikegami

>
> Cheers and thanks again,
> Ahmad
>
>> Regards,
>> Ikegami
>>
>>> Regards,
>>> Ikegami
>>>
>>>> Cheers,
>>>> Ahmad
>>>>
>>>>
>

[-- Attachment #2: v2-0001-mtd-cfi_cmdset_0002-Use-chip_ready-for-write-on-S.patch --]
[-- Type: text/x-patch, Size: 6844 bytes --]

From 306f7266cb2b6d07bbc5882b3b977264483ad128 Mon Sep 17 00:00:00 2001
From: Tokunori Ikegami <ikegami.t@gmail.com>
Date: Mon, 14 Feb 2022 01:08:02 +0900
Subject: [PATCH v2] mtd: cfi_cmdset_0002: Use chip_ready() for write on
 S29GL064N

The regression issue has been caused on S29GL064N and reported it.
Also the change mentioned is to use chip_good() for buffered write.
So disable the change on S29GL064N and use chip_ready() as before.

Fixes: dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to check correct value")
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
Cc: Miquel Raynal <miquel.raynal@bootlin.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Vignesh Raghavendra <vigneshr@ti.com>
Cc: linux-mtd@lists.infradead.org
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/b687c259-6413-26c9-d4c9-b3afa69ea124@pengutronix.de/
---
 drivers/mtd/chips/cfi_cmdset_0002.c | 89 +++++++++++++++--------------
 1 file changed, 47 insertions(+), 42 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index a761134fd3be..5e14b60e8638 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -48,6 +48,7 @@
 #define SST49LF040B		0x0050
 #define SST49LF008A		0x005a
 #define AT49BV6416		0x00d6
+#define S29GL064N_MN12		0x0c01
 
 /*
  * Status Register bit description. Used by flash devices that don't
@@ -462,7 +463,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
 	{ CFI_MFR_AMD, 0x0056, fixup_use_secsi },
 	{ CFI_MFR_AMD, 0x005C, fixup_use_secsi },
 	{ CFI_MFR_AMD, 0x005F, fixup_use_secsi },
-	{ CFI_MFR_AMD, 0x0c01, fixup_s29gl064n_sectors },
+	{ CFI_MFR_AMD, S29GL064N_MN12, fixup_s29gl064n_sectors },
 	{ CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors },
 	{ CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors },
 	{ CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors },
@@ -801,22 +802,12 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
 	return NULL;
 }
 
-/*
- * Return true if the chip is ready.
- *
- * Ready is one of: read mode, query mode, erase-suspend-read mode (in any
- * non-suspended sector) and is indicated by no toggle bits toggling.
- *
- * Note that anything more complicated than checking if no bits are toggling
- * (including checking DQ5 for an error status) is tricky to get working
- * correctly and is therefore not done	(particularly with interleaved chips
- * as each chip must be checked independently of the others).
- */
-static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
-			       unsigned long addr)
+static int __xipram chip_check(struct map_info *map, struct flchip *chip,
+			       unsigned long addr, map_word *expected)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
-	map_word d, t;
+	map_word oldd, curd;
+	int ret;
 
 	if (cfi_use_status_reg(cfi)) {
 		map_word ready = CMD(CFI_SR_DRB);
@@ -826,17 +817,35 @@ static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
 		 */
 		cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
 				 cfi->device_type, NULL);
-		d = map_read(map, addr);
+		curd = map_read(map, addr);
 
-		return map_word_andequal(map, d, ready, ready);
+		return map_word_andequal(map, curd, ready, ready);
 	}
 
-	d = map_read(map, addr);
-	t = map_read(map, addr);
+	oldd = map_read(map, addr);
+	curd = map_read(map, addr);
+
+	ret = map_word_equal(map, oldd, curd);
 
-	return map_word_equal(map, d, t);
+	if (!ret || !expected)
+		return ret;
+
+	return map_word_equal(map, curd, *expected);
 }
 
+/*
+ * Return true if the chip is ready.
+ *
+ * Ready is one of: read mode, query mode, erase-suspend-read mode (in any
+ * non-suspended sector) and is indicated by no toggle bits toggling.
+ *
+ * Note that anything more complicated than checking if no bits are toggling
+ * (including checking DQ5 for an error status) is tricky to get working
+ * correctly and is therefore not done	(particularly with interleaved chips
+ * as each chip must be checked independently of the others).
+ */
+#define chip_ready(map, chip, addr) chip_check(map, chip, addr, NULL)
+
 /*
  * Return true if the chip is ready and has the correct value.
  *
@@ -855,28 +864,24 @@ static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
 static int __xipram chip_good(struct map_info *map, struct flchip *chip,
 			      unsigned long addr, map_word expected)
 {
-	struct cfi_private *cfi = map->fldrv_priv;
-	map_word oldd, curd;
-
-	if (cfi_use_status_reg(cfi)) {
-		map_word ready = CMD(CFI_SR_DRB);
+	return chip_check(map, chip, addr, &expected);
+}
 
-		/*
-		 * For chips that support status register, check device
-		 * ready bit
-		 */
-		cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
-				 cfi->device_type, NULL);
-		curd = map_read(map, addr);
+static bool cfi_use_chip_ready_for_write(struct map_info *map)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
 
-		return map_word_andequal(map, curd, ready, ready);
-	}
+	return cfi->mfr == CFI_MFR_AMD && cfi->id == S29GL064N_MN12;
+}
 
-	oldd = map_read(map, addr);
-	curd = map_read(map, addr);
+static int __xipram chip_good_for_write(struct map_info *map,
+					struct flchip *chip, unsigned long addr,
+					map_word expected)
+{
+	if (cfi_use_chip_ready_for_write(map))
+		return chip_ready(map, chip, addr);
 
-	return	map_word_equal(map, oldd, curd) &&
-		map_word_equal(map, curd, expected);
+	return chip_good(map, chip, addr, expected);
 }
 
 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
@@ -1699,7 +1704,7 @@ static int __xipram do_write_oneword_once(struct map_info *map,
 		 * "chip_good" to avoid the failure due to scheduling.
 		 */
 		if (time_after(jiffies, timeo) &&
-		    !chip_good(map, chip, adr, datum)) {
+		    !chip_good_for_write(map, chip, adr, datum)) {
 			xip_enable(map, chip, adr);
 			printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
 			xip_disable(map, chip, adr);
@@ -1707,7 +1712,7 @@ static int __xipram do_write_oneword_once(struct map_info *map,
 			break;
 		}
 
-		if (chip_good(map, chip, adr, datum)) {
+		if (chip_good_for_write(map, chip, adr, datum)) {
 			if (cfi_check_err_status(map, chip, adr))
 				ret = -EIO;
 			break;
@@ -1979,14 +1984,14 @@ static int __xipram do_write_buffer_wait(struct map_info *map,
 		 * "chip_good" to avoid the failure due to scheduling.
 		 */
 		if (time_after(jiffies, timeo) &&
-		    !chip_good(map, chip, adr, datum)) {
+		    !chip_good_for_write(map, chip, adr, datum)) {
 			pr_err("MTD %s(): software timeout, address:0x%.8lx.\n",
 			       __func__, adr);
 			ret = -EIO;
 			break;
 		}
 
-		if (chip_good(map, chip, adr, datum)) {
+		if (chip_good_for_write(map, chip, adr, datum)) {
 			if (cfi_check_err_status(map, chip, adr))
 				ret = -EIO;
 			break;
-- 
2.32.0


WARNING: multiple messages have this Message-ID (diff)
From: Tokunori Ikegami <ikegami.t@gmail.com>
To: Ahmad Fatoum <a.fatoum@pengutronix.de>,
	Thorsten Leemhuis <regressions@leemhuis.info>,
	linux-mtd@lists.infradead.org, Joakim.Tjernlund@infinera.com,
	miquel.raynal@bootlin.com, vigneshr@ti.com, richard@nod.at,
	"regressions@lists.linux.dev" <regressions@lists.linux.dev>
Cc: Chris Packham <chris.packham@alliedtelesis.co.nz>,
	Brian Norris <computersforpeace@gmail.com>,
	David Woodhouse <dwmw2@infradead.org>,
	marek.vasut@gmail.com, cyrille.pitchen@wedev4u.fr,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Pengutronix Kernel Team <kernel@pengutronix.de>,
	linuxppc-dev@lists.ozlabs.org
Subject: Re: [BUG] mtd: cfi_cmdset_0002: write regression since v4.17-rc1
Date: Mon, 7 Mar 2022 00:49:39 +0900	[thread overview]
Message-ID: <9621c512-06f2-17b2-5c68-943b1f0981eb@gmail.com> (raw)
In-Reply-To: <f9e46b61-37e5-a280-edb0-27f8e81a8680@pengutronix.de>

[-- Attachment #1: Type: text/plain, Size: 2554 bytes --]

Hi,

On 2022/03/04 20:11, Ahmad Fatoum wrote:
> Hello Tokunori-san,
>
> On 20.02.22 13:22, Tokunori Ikegami wrote:
>> Hi Ahmad-san,
>>
>> Could you please try the version 2 patch attached for the error case?
>> This version is to check the DQ true data 0xFF by chip_good().
> I had a similar patch locally as well at first. I just tested yours
> and I can't reproduce the issue.
Thanks for your support.
Sorry if possible could you please retest the attached the patch again 
since this fixed the version 1 patch maintainer review comments?
>
>> But I am not sure if this works or not since the error is possible to be caused by Hi-Z 0xff on floating bus or etc.
> That it works for me could be because of Hi-Z 0xff, which is why
> decided against it.
I see.
>
>>>>>> What seems to work for me is checking if chip_good or chip_ready
>>>>>> and map_word is equal to 0xFF. I can't justify why this is ok though.
>>>>>> (Worst case bus is floating at this point of time and Hi-Z is read
>>>>>> as 0xff on CPU data lines...)
>>>>> Sorry I am not sure about this.
>>>>> I thought the chip_ready() itself is correct as implemented as the data sheet in the past.
>>>>> But it did not work correctly so changed to use chip_good() instead as it is also correct.
>>>> What exactly in the datasheet makes you believe chip_good is not appropriate?
>>> I just mentioned about the actual issue behaviors as not worked chip_good() on S29GL964N and not worked chip_ready() on MX29GL512FHT2I-11G before etc.
>>> Anyway let me recheck the data sheet details as just checked it again quickly but needed more investigation to understand.
>> As far as I checked still both chip_good() and chip_ready() seem correct but still the root cause is unknown.
>> If as you mentioned the issue was cased by the DQ true data 0xFF I am not sure why the read work without any error after the write operation.
>> Also if the error was caused by the Hi-Z 0xff on floating bus as mentioned I am not sure why the read work without any error after the write operation with chip_ready().
>> Sorry anyway the root cause is also unknown when the write operation was changed to use chip_good() instead of chip_ready().
> I've be ok with v1 then. Restores working behavior for me and shouldn't break others.

Noted but still I am thinking the version 2 patch to check 0xff seems 
better than to use chip_ready() so let me consider this again later.

Regards,
Ikegami

>
> Cheers and thanks again,
> Ahmad
>
>> Regards,
>> Ikegami
>>
>>> Regards,
>>> Ikegami
>>>
>>>> Cheers,
>>>> Ahmad
>>>>
>>>>
>

[-- Attachment #2: v2-0001-mtd-cfi_cmdset_0002-Use-chip_ready-for-write-on-S.patch --]
[-- Type: text/x-patch, Size: 6844 bytes --]

From 306f7266cb2b6d07bbc5882b3b977264483ad128 Mon Sep 17 00:00:00 2001
From: Tokunori Ikegami <ikegami.t@gmail.com>
Date: Mon, 14 Feb 2022 01:08:02 +0900
Subject: [PATCH v2] mtd: cfi_cmdset_0002: Use chip_ready() for write on
 S29GL064N

The regression issue has been caused on S29GL064N and reported it.
Also the change mentioned is to use chip_good() for buffered write.
So disable the change on S29GL064N and use chip_ready() as before.

Fixes: dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to check correct value")
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
Cc: Miquel Raynal <miquel.raynal@bootlin.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Vignesh Raghavendra <vigneshr@ti.com>
Cc: linux-mtd@lists.infradead.org
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/b687c259-6413-26c9-d4c9-b3afa69ea124@pengutronix.de/
---
 drivers/mtd/chips/cfi_cmdset_0002.c | 89 +++++++++++++++--------------
 1 file changed, 47 insertions(+), 42 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index a761134fd3be..5e14b60e8638 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -48,6 +48,7 @@
 #define SST49LF040B		0x0050
 #define SST49LF008A		0x005a
 #define AT49BV6416		0x00d6
+#define S29GL064N_MN12		0x0c01
 
 /*
  * Status Register bit description. Used by flash devices that don't
@@ -462,7 +463,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
 	{ CFI_MFR_AMD, 0x0056, fixup_use_secsi },
 	{ CFI_MFR_AMD, 0x005C, fixup_use_secsi },
 	{ CFI_MFR_AMD, 0x005F, fixup_use_secsi },
-	{ CFI_MFR_AMD, 0x0c01, fixup_s29gl064n_sectors },
+	{ CFI_MFR_AMD, S29GL064N_MN12, fixup_s29gl064n_sectors },
 	{ CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors },
 	{ CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors },
 	{ CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors },
@@ -801,22 +802,12 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
 	return NULL;
 }
 
-/*
- * Return true if the chip is ready.
- *
- * Ready is one of: read mode, query mode, erase-suspend-read mode (in any
- * non-suspended sector) and is indicated by no toggle bits toggling.
- *
- * Note that anything more complicated than checking if no bits are toggling
- * (including checking DQ5 for an error status) is tricky to get working
- * correctly and is therefore not done	(particularly with interleaved chips
- * as each chip must be checked independently of the others).
- */
-static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
-			       unsigned long addr)
+static int __xipram chip_check(struct map_info *map, struct flchip *chip,
+			       unsigned long addr, map_word *expected)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
-	map_word d, t;
+	map_word oldd, curd;
+	int ret;
 
 	if (cfi_use_status_reg(cfi)) {
 		map_word ready = CMD(CFI_SR_DRB);
@@ -826,17 +817,35 @@ static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
 		 */
 		cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
 				 cfi->device_type, NULL);
-		d = map_read(map, addr);
+		curd = map_read(map, addr);
 
-		return map_word_andequal(map, d, ready, ready);
+		return map_word_andequal(map, curd, ready, ready);
 	}
 
-	d = map_read(map, addr);
-	t = map_read(map, addr);
+	oldd = map_read(map, addr);
+	curd = map_read(map, addr);
+
+	ret = map_word_equal(map, oldd, curd);
 
-	return map_word_equal(map, d, t);
+	if (!ret || !expected)
+		return ret;
+
+	return map_word_equal(map, curd, *expected);
 }
 
+/*
+ * Return true if the chip is ready.
+ *
+ * Ready is one of: read mode, query mode, erase-suspend-read mode (in any
+ * non-suspended sector) and is indicated by no toggle bits toggling.
+ *
+ * Note that anything more complicated than checking if no bits are toggling
+ * (including checking DQ5 for an error status) is tricky to get working
+ * correctly and is therefore not done	(particularly with interleaved chips
+ * as each chip must be checked independently of the others).
+ */
+#define chip_ready(map, chip, addr) chip_check(map, chip, addr, NULL)
+
 /*
  * Return true if the chip is ready and has the correct value.
  *
@@ -855,28 +864,24 @@ static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
 static int __xipram chip_good(struct map_info *map, struct flchip *chip,
 			      unsigned long addr, map_word expected)
 {
-	struct cfi_private *cfi = map->fldrv_priv;
-	map_word oldd, curd;
-
-	if (cfi_use_status_reg(cfi)) {
-		map_word ready = CMD(CFI_SR_DRB);
+	return chip_check(map, chip, addr, &expected);
+}
 
-		/*
-		 * For chips that support status register, check device
-		 * ready bit
-		 */
-		cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
-				 cfi->device_type, NULL);
-		curd = map_read(map, addr);
+static bool cfi_use_chip_ready_for_write(struct map_info *map)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
 
-		return map_word_andequal(map, curd, ready, ready);
-	}
+	return cfi->mfr == CFI_MFR_AMD && cfi->id == S29GL064N_MN12;
+}
 
-	oldd = map_read(map, addr);
-	curd = map_read(map, addr);
+static int __xipram chip_good_for_write(struct map_info *map,
+					struct flchip *chip, unsigned long addr,
+					map_word expected)
+{
+	if (cfi_use_chip_ready_for_write(map))
+		return chip_ready(map, chip, addr);
 
-	return	map_word_equal(map, oldd, curd) &&
-		map_word_equal(map, curd, expected);
+	return chip_good(map, chip, addr, expected);
 }
 
 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
@@ -1699,7 +1704,7 @@ static int __xipram do_write_oneword_once(struct map_info *map,
 		 * "chip_good" to avoid the failure due to scheduling.
 		 */
 		if (time_after(jiffies, timeo) &&
-		    !chip_good(map, chip, adr, datum)) {
+		    !chip_good_for_write(map, chip, adr, datum)) {
 			xip_enable(map, chip, adr);
 			printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
 			xip_disable(map, chip, adr);
@@ -1707,7 +1712,7 @@ static int __xipram do_write_oneword_once(struct map_info *map,
 			break;
 		}
 
-		if (chip_good(map, chip, adr, datum)) {
+		if (chip_good_for_write(map, chip, adr, datum)) {
 			if (cfi_check_err_status(map, chip, adr))
 				ret = -EIO;
 			break;
@@ -1979,14 +1984,14 @@ static int __xipram do_write_buffer_wait(struct map_info *map,
 		 * "chip_good" to avoid the failure due to scheduling.
 		 */
 		if (time_after(jiffies, timeo) &&
-		    !chip_good(map, chip, adr, datum)) {
+		    !chip_good_for_write(map, chip, adr, datum)) {
 			pr_err("MTD %s(): software timeout, address:0x%.8lx.\n",
 			       __func__, adr);
 			ret = -EIO;
 			break;
 		}
 
-		if (chip_good(map, chip, adr, datum)) {
+		if (chip_good_for_write(map, chip, adr, datum)) {
 			if (cfi_check_err_status(map, chip, adr))
 				ret = -EIO;
 			break;
-- 
2.32.0


[-- Attachment #3: Type: text/plain, Size: 144 bytes --]

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

  reply	other threads:[~2022-03-06 15:49 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-13 13:24 [BUG] mtd: cfi_cmdset_0002: write regression since v4.17-rc1 Ahmad Fatoum
2021-12-13 13:24 ` Ahmad Fatoum
2021-12-13 13:24 ` Ahmad Fatoum
2021-12-14  7:23 ` Thorsten Leemhuis
2021-12-14  7:23   ` Thorsten Leemhuis
2021-12-14  7:23   ` Thorsten Leemhuis
2021-12-15 17:34   ` Tokunori Ikegami
2021-12-15 17:34     ` Tokunori Ikegami
2021-12-15 17:34     ` Tokunori Ikegami
2022-01-20 13:00     ` Thorsten Leemhuis
2022-01-20 13:00       ` Thorsten Leemhuis
2022-01-20 13:00       ` Thorsten Leemhuis
2022-01-28 12:55     ` Ahmad Fatoum
2022-01-28 12:55       ` Ahmad Fatoum
2022-01-28 12:55       ` Ahmad Fatoum
2022-01-29 18:01       ` Tokunori Ikegami
2022-01-29 18:01         ` Tokunori Ikegami
2022-01-29 18:01         ` Tokunori Ikegami
2022-02-07 14:28         ` Ahmad Fatoum
2022-02-07 14:28           ` Ahmad Fatoum
2022-02-07 14:28           ` Ahmad Fatoum
2022-02-13 16:47           ` Tokunori Ikegami
2022-02-13 16:47             ` Tokunori Ikegami
2022-02-13 16:47             ` Tokunori Ikegami
2022-02-14 16:22             ` Ahmad Fatoum
2022-02-14 16:22               ` Ahmad Fatoum
2022-02-14 16:22               ` Ahmad Fatoum
2022-02-14 18:46               ` Tokunori Ikegami
2022-02-14 18:46                 ` Tokunori Ikegami
2022-02-14 18:46                 ` Tokunori Ikegami
2022-02-20 12:22                 ` Tokunori Ikegami
2022-02-20 12:22                   ` Tokunori Ikegami
2022-02-20 12:22                   ` Tokunori Ikegami
2022-03-04 11:11                   ` Ahmad Fatoum
2022-03-04 11:11                     ` Ahmad Fatoum
2022-03-04 11:11                     ` Ahmad Fatoum
2022-03-06 15:49                     ` Tokunori Ikegami [this message]
2022-03-06 15:49                       ` Tokunori Ikegami
2022-03-06 15:49                       ` Tokunori Ikegami
2022-03-08  9:44                       ` Ahmad Fatoum
2022-03-08  9:44                         ` Ahmad Fatoum
2022-03-08  9:44                         ` Ahmad Fatoum
2022-03-08 16:13                         ` Tokunori Ikegami
2022-03-08 16:13                           ` Tokunori Ikegami
2022-03-08 16:13                           ` Tokunori Ikegami
2022-03-08 16:23                           ` Ahmad Fatoum
2022-03-08 16:23                             ` Ahmad Fatoum
2022-03-08 16:23                             ` Ahmad Fatoum
2022-03-08 16:40                             ` Tokunori Ikegami
2022-03-08 16:40                               ` Tokunori Ikegami
2022-03-08 16:40                               ` Tokunori Ikegami

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9621c512-06f2-17b2-5c68-943b1f0981eb@gmail.com \
    --to=ikegami.t@gmail.com \
    --cc=Joakim.Tjernlund@infinera.com \
    --cc=a.fatoum@pengutronix.de \
    --cc=chris.packham@alliedtelesis.co.nz \
    --cc=computersforpeace@gmail.com \
    --cc=cyrille.pitchen@wedev4u.fr \
    --cc=dwmw2@infradead.org \
    --cc=kernel@pengutronix.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=marek.vasut@gmail.com \
    --cc=miquel.raynal@bootlin.com \
    --cc=regressions@leemhuis.info \
    --cc=regressions@lists.linux.dev \
    --cc=richard@nod.at \
    --cc=vigneshr@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.