mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 1/5] mtd: nand: Allow non page aligned length writes
@ 2020-12-11  8:15 Sascha Hauer
  2020-12-11  8:15 ` [PATCH 2/5] nand: omap: Fix BCH16 read Sascha Hauer
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Sascha Hauer @ 2020-12-11  8:15 UTC (permalink / raw)
  To: Barebox List

When copying images to nand with plain cp it can happen that the length
of the image is not page aligned. Allow misaligned image lengths as we
used to before the last NAND layer update.

Fixes: b6bcd96de5 ("mtd: nand: Update to Linux-5.9")
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/nand_base.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 2c3c0b360f..e190db7308 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -4031,7 +4031,7 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to,
 		return 0;
 
 	/* Reject writes, which are not page aligned */
-	if (NOTALIGNED(to) || NOTALIGNED(ops->len)) {
+	if (NOTALIGNED(to)) {
 		pr_notice("%s: attempt to write non page aligned data\n",
 			   __func__);
 		return -EINVAL;
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/5] nand: omap: Fix BCH16 read
  2020-12-11  8:15 [PATCH 1/5] mtd: nand: Allow non page aligned length writes Sascha Hauer
@ 2020-12-11  8:15 ` Sascha Hauer
  2020-12-11  8:15 ` [PATCH 3/5] mtd: nand: omap: print error when ELM config failed Sascha Hauer
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2020-12-11  8:15 UTC (permalink / raw)
  To: Barebox List

When reading in BCH16 mode the ECC for the first 512 byte fails. I am
pretty sure this must have worked once and I can't see why it doesn't
now. Change reading in BCH16 mode to the same way as the kernel driver
does: Instead of using wrap mode 4 to skip ECC when reading the first
OOB bytes, just use wrap mode 1 and skip reading the first OOB bytes.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/nand_omap_gpmc.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/nand_omap_gpmc.c b/drivers/mtd/nand/nand_omap_gpmc.c
index e3d36a1cf4..1d81500bce 100644
--- a/drivers/mtd/nand/nand_omap_gpmc.c
+++ b/drivers/mtd/nand/nand_omap_gpmc.c
@@ -91,6 +91,8 @@
 
 #define BCH8_MAX_ERROR	8	/* upto 8 bit correctable */
 
+#define BADBLOCK_MARKER_LENGTH 2
+
 static const uint8_t bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2,
 		0xbe, 0xcc, 0xac, 0x6b, 0xff, 0x99, 0x7b};
 static u_char bch16_vector[] = {0xf5, 0x24, 0x1c, 0xd0, 0x61, 0xb3, 0xf1, 0x55,
@@ -497,9 +499,9 @@ static void omap_enable_hwecc(struct nand_chip *nand, int mode)
 	case OMAP_ECC_BCH16_CODE_HW:
 		bch_mod = 2;
 		if (mode == NAND_ECC_READ) {
-			bch_wrapmode = 4;
-			eccsize0 = 4; /* ECC bits in nibbles per sector */
-			eccsize1 = 52;  /* non-ECC bits in nibbles per sector */
+			bch_wrapmode = 1;
+			eccsize0 = 52; /* ECC bits in nibbles per sector */
+			eccsize1 = 0;  /* non-ECC bits in nibbles per sector */
 		} else {
 			bch_wrapmode = 4;
 			eccsize0 = 4;  /* extra bits in nibbles per sector */
@@ -964,7 +966,12 @@ static int gpmc_read_page_hwecc_elm(struct nand_chip *chip, uint8_t *buf,
 	nand_read_page_op(chip, page, 0, NULL, 0);
 
 	chip->legacy.read_buf(chip, buf, mtd->writesize);
-	chip->legacy.read_buf(chip, chip->oob_poi, mtd->oobsize);
+
+	/* Read oob bytes */
+	nand_change_read_column_op(chip,
+				mtd->writesize + BADBLOCK_MARKER_LENGTH,
+				chip->oob_poi + BADBLOCK_MARKER_LENGTH,
+				chip->ecc.total, false);
 
 	ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
                                   chip->ecc.total);
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 3/5] mtd: nand: omap: print error when ELM config failed
  2020-12-11  8:15 [PATCH 1/5] mtd: nand: Allow non page aligned length writes Sascha Hauer
  2020-12-11  8:15 ` [PATCH 2/5] nand: omap: Fix BCH16 read Sascha Hauer
@ 2020-12-11  8:15 ` Sascha Hauer
  2020-12-11  8:15 ` [PATCH 4/5] mtd: nand: omap: Bail out when omap_gpmc_eccmode() fails Sascha Hauer
  2020-12-11  8:15 ` [PATCH 5/5] mtd: nand: Make write support optional Sascha Hauer
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2020-12-11  8:15 UTC (permalink / raw)
  To: Barebox List

ELM config can fail when ELM support is disabled. Let the user know
about it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/nand_omap_gpmc.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/nand_omap_gpmc.c b/drivers/mtd/nand/nand_omap_gpmc.c
index 1d81500bce..8fdfd236bd 100644
--- a/drivers/mtd/nand/nand_omap_gpmc.c
+++ b/drivers/mtd/nand/nand_omap_gpmc.c
@@ -1128,8 +1128,11 @@ static int omap_gpmc_eccmode(struct gpmc_nand_info *oinfo,
 		err = elm_config(BCH16_ECC,
 				 minfo->writesize / nand->ecc.size,
 				 nand->ecc.size, nand->ecc.bytes);
-		if (err < 0)
+		if (err < 0) {
+			dev_err(oinfo->pdev, "ELM config failed: %s\n",
+				strerror(-err));
 			return err;
+		}
 
 		nand->ecc.read_page = gpmc_read_page_hwecc_elm;
 
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 4/5] mtd: nand: omap: Bail out when omap_gpmc_eccmode() fails
  2020-12-11  8:15 [PATCH 1/5] mtd: nand: Allow non page aligned length writes Sascha Hauer
  2020-12-11  8:15 ` [PATCH 2/5] nand: omap: Fix BCH16 read Sascha Hauer
  2020-12-11  8:15 ` [PATCH 3/5] mtd: nand: omap: print error when ELM config failed Sascha Hauer
@ 2020-12-11  8:15 ` Sascha Hauer
  2020-12-11  8:15 ` [PATCH 5/5] mtd: nand: Make write support optional Sascha Hauer
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2020-12-11  8:15 UTC (permalink / raw)
  To: Barebox List

The driver can't work when omap_gpmc_eccmode() fails, so do not ignore
the error.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/nand_omap_gpmc.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/nand_omap_gpmc.c b/drivers/mtd/nand/nand_omap_gpmc.c
index 8fdfd236bd..db1ca88791 100644
--- a/drivers/mtd/nand/nand_omap_gpmc.c
+++ b/drivers/mtd/nand/nand_omap_gpmc.c
@@ -1322,7 +1322,9 @@ static int gpmc_nand_probe(struct device_d *pdev)
 			omap_gpmc_eccmode_set, NULL, (int *)&oinfo->ecc_mode,
 			ecc_mode_strings, ARRAY_SIZE(ecc_mode_strings), oinfo);
 
-	omap_gpmc_eccmode(oinfo, oinfo->ecc_mode);
+	err = omap_gpmc_eccmode(oinfo, oinfo->ecc_mode);
+	if (err)
+		goto out_release_mem;
 
 	/* We are all set to register with the system now! */
 	err = add_mtd_nand_device(minfo, "nand");
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 5/5] mtd: nand: Make write support optional
  2020-12-11  8:15 [PATCH 1/5] mtd: nand: Allow non page aligned length writes Sascha Hauer
                   ` (2 preceding siblings ...)
  2020-12-11  8:15 ` [PATCH 4/5] mtd: nand: omap: Bail out when omap_gpmc_eccmode() fails Sascha Hauer
@ 2020-12-11  8:15 ` Sascha Hauer
  3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2020-12-11  8:15 UTC (permalink / raw)
  To: Barebox List

NAND write support used to be optional and the correspoding
CONFIG_MTD_WRITE option still exists. Bail out early from the write
functions when CONFIG_MTD_WRITE is disabled like we used to before the
last NAND layer update.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/nand_base.c | 45 ++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e190db7308..5db0b5625e 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3415,6 +3415,9 @@ int nand_write_oob_std(struct nand_chip *chip, int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
 
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	return nand_prog_page_op(chip, page, mtd->writesize, chip->oob_poi,
 				 mtd->oobsize);
 }
@@ -3434,6 +3437,9 @@ static int nand_write_oob_syndrome(struct nand_chip *chip, int page)
 	int ret, i, len, pos, sndcmd = 0, steps = chip->ecc.steps;
 	const uint8_t *bufpoi = chip->oob_poi;
 
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	/*
 	 * data-ecc-data-ecc ... ecc-oob
 	 * or
@@ -3635,6 +3641,9 @@ int nand_write_page_raw(struct nand_chip *chip, const uint8_t *buf,
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	int ret;
 
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	ret = nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize);
 	if (ret)
 		return ret;
@@ -3673,6 +3682,9 @@ int nand_monolithic_write_page_raw(struct nand_chip *chip, const u8 *buf,
 	unsigned int size = mtd->writesize;
 	u8 *write_buf = (u8 *)buf;
 
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	if (oob_required) {
 		size += mtd->oobsize;
 
@@ -3705,6 +3717,9 @@ static int nand_write_page_raw_syndrome(struct nand_chip *chip,
 	uint8_t *oob = chip->oob_poi;
 	int steps, size, ret;
 
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
 	if (ret)
 		return ret;
@@ -3767,6 +3782,9 @@ static int nand_write_page_swecc(struct nand_chip *chip, const uint8_t *buf,
 	uint8_t *ecc_calc = chip->ecc.calc_buf;
 	const uint8_t *p = buf;
 
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	/* Software ECC calculation */
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
 		chip->ecc.calculate(chip, p, &ecc_calc[i]);
@@ -3796,6 +3814,9 @@ static int nand_write_page_hwecc(struct nand_chip *chip, const uint8_t *buf,
 	uint8_t *ecc_calc = chip->ecc.calc_buf;
 	const uint8_t *p = buf;
 
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
 	if (ret)
 		return ret;
@@ -3847,6 +3868,9 @@ static int nand_write_subpage_hwecc(struct nand_chip *chip, uint32_t offset,
 	int oob_bytes       = mtd->oobsize / ecc_steps;
 	int step, ret;
 
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
 	if (ret)
 		return ret;
@@ -3914,6 +3938,9 @@ static int nand_write_page_syndrome(struct nand_chip *chip, const uint8_t *buf,
 	uint8_t *oob = chip->oob_poi;
 	int ret;
 
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
 	if (ret)
 		return ret;
@@ -3980,6 +4007,9 @@ static int nand_write_page(struct nand_chip *chip, uint32_t offset,
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	int status, subpage;
 
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
 		chip->ecc.write_subpage)
 		subpage = offset || (data_len < mtd->writesize);
@@ -4026,6 +4056,9 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to,
 	int ret;
 	int oob_required = oob ? 1 : 0;
 
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	ops->retlen = 0;
 	if (!writelen)
 		return 0;
@@ -4143,6 +4176,9 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	int ret;
 
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	ops->retlen = 0;
 
 	ret = nand_get_device(chip);
@@ -4178,6 +4214,9 @@ out:
  */
 static int nand_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	return nand_erase_nand(mtd_to_nand(mtd), instr, 0);
 }
 
@@ -4197,6 +4236,9 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr,
 	int page, pages_per_block, ret, chipnr;
 	loff_t len;
 
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	pr_debug("%s: start = 0x%012llx, len = %llu\n",
 			__func__, (unsigned long long)instr->addr,
 			(unsigned long long)instr->len);
@@ -4335,6 +4377,9 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
 	int ret;
 
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
 	ret = nand_block_isbad(mtd, ofs);
 	if (ret) {
 		/* If it was bad already, return success and do nothing */
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-12-11  8:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-11  8:15 [PATCH 1/5] mtd: nand: Allow non page aligned length writes Sascha Hauer
2020-12-11  8:15 ` [PATCH 2/5] nand: omap: Fix BCH16 read Sascha Hauer
2020-12-11  8:15 ` [PATCH 3/5] mtd: nand: omap: print error when ELM config failed Sascha Hauer
2020-12-11  8:15 ` [PATCH 4/5] mtd: nand: omap: Bail out when omap_gpmc_eccmode() fails Sascha Hauer
2020-12-11  8:15 ` [PATCH 5/5] mtd: nand: Make write support optional Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox