mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Stefan Riedmueller <s.riedmueller@phytec.de>
To: barebox@lists.infradead.org
Cc: Stefan Riedmueller <s.riedmueller@phytec.de>
Subject: [PATCH 1/2] nand: nand-mxs: Fix marking BBT blocks as bad
Date: Tue, 16 Mar 2021 13:36:25 +0100	[thread overview]
Message-ID: <20210316123626.25872-1-s.riedmueller@phytec.de> (raw)

Currently the nand-mxs driver uses a hook function to the
mtd->_block_markbad function to allow write access to the OOB bytes only
if it is to mark a block as bad.

This hook is not called when a Bad Block Table block is marked bad since
this routine directly calls nand_markbad_bbm.

The chip->legacy.block_markbad hook gives a driver the ability to
implement a custom block_markbad function. Since this is used by
nand_markbad_bbm, if it exists, replace the mtd->_block_markbad hook by
a chip->legacy.block_markbad function. The gpmi-nand Linux implementation
of this driver uses the same mechanism.

This fixes an issue where marking Bad Block Table blocks as bad fails
with:
	NXS NAND: Writing OOB isn't supported

Tested on PHYTEC phyCORE-i.MX 6Q.

Signed-off-by: Stefan Riedmueller <s.riedmueller@phytec.de>
---
 drivers/mtd/nand/nand_mxs.c | 87 +++++++++++++++----------------------
 1 file changed, 34 insertions(+), 53 deletions(-)

diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
index 434da49d3ea9..96ae71364efb 100644
--- a/drivers/mtd/nand/nand_mxs.c
+++ b/drivers/mtd/nand/nand_mxs.c
@@ -215,7 +215,6 @@ struct mxs_nand_info {
 	uint8_t		*data_buf;
 	uint8_t		*oob_buf;
 
-	uint8_t		marking_block_bad;
 	uint8_t		raw_oob_mode;
 
 	/* Functions with altered behaviour */
@@ -223,8 +222,6 @@ struct mxs_nand_info {
 				loff_t from, struct mtd_oob_ops *ops);
 	int		(*hooked_write_oob)(struct mtd_info *mtd,
 				loff_t to, struct mtd_oob_ops *ops);
-	int		(*hooked_block_markbad)(struct mtd_info *mtd,
-				loff_t ofs);
 
 	/* DMA descriptors */
 	struct mxs_dma_desc	**desc;
@@ -1073,27 +1070,6 @@ static int mxs_nand_hook_write_oob(struct mtd_info *mtd, loff_t to,
 	return ret;
 }
 
-/*
- * Mark a block bad in NAND.
- *
- * This function is a veneer that replaces the function originally installed by
- * the NAND Flash MTD code.
- */
-static int mxs_nand_hook_block_markbad(struct mtd_info *mtd, loff_t ofs)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	struct mxs_nand_info *nand_info = chip->priv;
-	int ret;
-
-	nand_info->marking_block_bad = 1;
-
-	ret = nand_info->hooked_block_markbad(mtd, ofs);
-
-	nand_info->marking_block_bad = 0;
-
-	return ret;
-}
-
 /*
  * There are several places in this driver where we have to handle the OOB and
  * block marks. This is the function where things are the most complicated, so
@@ -1177,36 +1153,14 @@ static int mxs_nand_ecc_read_oob(struct nand_chip *chip, int page)
  */
 static int mxs_nand_ecc_write_oob(struct nand_chip *chip, int page)
 {
-	struct mtd_info *mtd = nand_to_mtd(chip);
-	struct mxs_nand_info *nand_info = chip->priv;
-	int column;
-	uint8_t block_mark = 0;
-
 	/*
 	 * There are fundamental incompatibilities between the i.MX GPMI NFC and
 	 * the NAND Flash MTD model that make it essentially impossible to write
 	 * the out-of-band bytes.
-	 *
-	 * We permit *ONE* exception. If the *intent* of writing the OOB is to
-	 * mark a block bad, we can do that.
 	 */
 
-	if (!nand_info->marking_block_bad) {
-		printf("NXS NAND: Writing OOB isn't supported\n");
-		return -EIO;
-	}
-
-	column = nand_info->version == GPMI_VERSION_TYPE_MX23 ? 0 : mtd->writesize;
-	/* Write the block mark. */
-	chip->legacy.cmdfunc(chip, NAND_CMD_SEQIN, column, page);
-	chip->legacy.write_buf(chip, &block_mark, 1);
-	chip->legacy.cmdfunc(chip, NAND_CMD_PAGEPROG, -1, -1);
-
-	/* Check if it worked. */
-	if (chip->legacy.waitfunc(chip) & NAND_STATUS_FAIL)
-		return -EIO;
-
-	return 0;
+	printf("MXS NAND: Writing OOB isn't supported\n");
+	return -EIO;
 }
 
 /*
@@ -1227,6 +1181,37 @@ static int mxs_nand_block_bad(struct nand_chip *chip , loff_t ofs)
 	return 0;
 }
 
+/*
+ * Mark a block as bad in NAND.
+ */
+static int mxs_nand_block_markbad(struct nand_chip *chip , loff_t ofs)
+{
+	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct mxs_nand_info *nand_info = chip->priv;
+	int column, page, chipnr, status;
+	uint8_t block_mark = 0;
+
+	chipnr = (int)(ofs >> chip->chip_shift);
+	nand_select_target(chip, chipnr);
+
+	column = nand_info->version == GPMI_VERSION_TYPE_MX23 ? 0 : mtd->writesize;
+	page = (int)(ofs >> chip->page_shift);
+	/* Write the block mark. */
+	chip->legacy.cmdfunc(chip, NAND_CMD_SEQIN, column, page);
+	chip->legacy.write_buf(chip, &block_mark, 1);
+	chip->legacy.cmdfunc(chip, NAND_CMD_PAGEPROG, -1, -1);
+
+	/* Check if it worked. */
+	status = chip->legacy.waitfunc(chip);
+
+	nand_deselect_target(chip);
+
+	if (status & NAND_STATUS_FAIL)
+		return -EIO;
+
+	return 0;
+}
+
 /*
  * Nominally, the purpose of this function is to look for or create the bad
  * block table. In fact, since the we call this function at the very end of
@@ -1273,11 +1258,6 @@ static int mxs_nand_scan_bbt(struct nand_chip *chip)
 		mtd->_write_oob = mxs_nand_hook_write_oob;
 	}
 
-	if (mtd->_block_markbad != mxs_nand_hook_block_markbad) {
-		nand_info->hooked_block_markbad = mtd->_block_markbad;
-		mtd->_block_markbad = mxs_nand_hook_block_markbad;
-	}
-
 	/* We use the reference implementation for bad block management. */
 	return nand_create_bbt(chip);
 }
@@ -2201,6 +2181,7 @@ static int mxs_nand_probe(struct device_d *dev)
 	chip->legacy.dev_ready		= mxs_nand_device_ready;
 	chip->legacy.select_chip	= mxs_nand_select_chip;
 	chip->legacy.block_bad		= mxs_nand_block_bad;
+	chip->legacy.block_markbad	= mxs_nand_block_markbad;
 
 	chip->legacy.read_byte		= mxs_nand_read_byte;
 
-- 
2.25.1


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


             reply	other threads:[~2021-03-16 12:37 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-16 12:36 Stefan Riedmueller [this message]
2021-03-16 12:36 ` [PATCH 2/2] mtd: nand_bbt: Skip bad blocks when searching for the BBT in NAND Stefan Riedmueller
2021-03-17  9:41   ` Sascha Hauer
2021-03-17 17:14     ` Stefan Riedmüller
2021-03-22  5:59       ` sha
2021-03-29  7:20         ` Stefan Riedmüller
2021-04-14 13:18           ` Stefan Riedmüller
2021-04-14 14:36             ` sha
2021-04-20  6:29               ` Stefan Riedmüller
2021-05-07  7:52                 ` sha
2021-03-22  5:57 ` [PATCH 1/2] nand: nand-mxs: Fix marking BBT blocks as bad Sascha Hauer

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=20210316123626.25872-1-s.riedmueller@phytec.de \
    --to=s.riedmueller@phytec.de \
    --cc=barebox@lists.infradead.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox