All of lore.kernel.org
 help / color / mirror / Atom feed
From: Miquel Raynal <miquel.raynal@bootlin.com>
To: Richard Weinberger <richard@nod.at>,
	Vignesh Raghavendra <vigneshr@ti.com>,
	Tudor Ambarus <Tudor.Ambarus@microchip.com>,
	<linux-mtd@lists.infradead.org>
Cc: Julien Su <juliensu@mxic.com.tw>,
	ycllin@mxic.com.tw,
	Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
	Miquel Raynal <miquel.raynal@bootlin.com>
Subject: [PATCH 01/20] mtd: nand: ecc: Add an I/O request tweaking mechanism
Date: Wed, 30 Sep 2020 01:01:05 +0200	[thread overview]
Message-ID: <20200929230124.31491-2-miquel.raynal@bootlin.com> (raw)
In-Reply-To: <20200929230124.31491-1-miquel.raynal@bootlin.com>

Currently, BCH and Hamming engine are sharing the same
tweaking/restoring I/O mechanism: they need the I/O request to fully
cover the main/OOB area. Let's make this code generic as sharing the
code between two drivers is already a win. Maybe other ECC engine
drivers will need it too.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/mtd/nand/ecc.c   | 106 +++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/nand.h |  32 ++++++++++++
 2 files changed, 138 insertions(+)

diff --git a/drivers/mtd/nand/ecc.c b/drivers/mtd/nand/ecc.c
index 4a56e6c0da67..86bbc4ecc58a 100644
--- a/drivers/mtd/nand/ecc.c
+++ b/drivers/mtd/nand/ecc.c
@@ -95,6 +95,7 @@
 
 #include <linux/module.h>
 #include <linux/mtd/nand.h>
+#include <linux/slab.h>
 
 /**
  * nand_ecc_init_ctx - Init the ECC engine context
@@ -479,6 +480,111 @@ bool nand_ecc_is_strong_enough(struct nand_device *nand)
 }
 EXPORT_SYMBOL(nand_ecc_is_strong_enough);
 
+/* ECC engine driver internal helpers */
+int nand_ecc_init_req_tweaking(struct nand_ecc_req_tweak_ctx *ctx,
+			       struct nand_device *nand)
+{
+	unsigned int total_buffer_size;
+
+	ctx->nand = nand;
+
+	/* Let the user decide the exact length of each buffer */
+	if (!ctx->page_buffer_size)
+		ctx->page_buffer_size = nanddev_page_size(nand);
+	if (!ctx->oob_buffer_size)
+		ctx->oob_buffer_size = nanddev_per_page_oobsize(nand);
+
+	total_buffer_size = ctx->page_buffer_size + ctx->oob_buffer_size;
+
+	ctx->spare_databuf = kzalloc(total_buffer_size, GFP_KERNEL);
+	if (!ctx->spare_databuf)
+		return -ENOMEM;
+
+	ctx->spare_oobbuf = ctx->spare_databuf + ctx->page_buffer_size;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(nand_ecc_init_req_tweaking);
+
+void nand_ecc_cleanup_req_tweaking(struct nand_ecc_req_tweak_ctx *ctx)
+{
+	kfree(ctx->spare_databuf);
+}
+EXPORT_SYMBOL_GPL(nand_ecc_cleanup_req_tweaking);
+
+/*
+ * Ensure data and OOB area is fully read/written otherwise the correction might
+ * not work as expected.
+ */
+void nand_ecc_tweak_req(struct nand_ecc_req_tweak_ctx *ctx,
+			struct nand_page_io_req *req)
+{
+	struct nand_device *nand = ctx->nand;
+	struct nand_page_io_req *orig, *tweak;
+
+	/* Save the original request */
+	ctx->orig_req = *req;
+	ctx->bounce_data = false;
+	ctx->bounce_oob = false;
+	orig = &ctx->orig_req;
+	tweak = req;
+
+	/* Ensure the request covers the entire page */
+	if (true) {//todo (orig->datalen < nanddev_page_size(nand)) {
+		ctx->bounce_data = true;
+		tweak->dataoffs = 0;
+		tweak->datalen = nanddev_page_size(nand);
+		tweak->databuf.in = ctx->spare_databuf;
+		memset(tweak->databuf.in, 0xFF, ctx->page_buffer_size);
+	}
+
+	if (true) {//todo (orig->ooblen < nanddev_per_page_oobsize(nand)) {
+		ctx->bounce_oob = true;
+		tweak->ooboffs = 0;
+		tweak->ooblen = nanddev_per_page_oobsize(nand);
+		tweak->oobbuf.in = ctx->spare_oobbuf;
+		memset(tweak->oobbuf.in, 0xFF, ctx->oob_buffer_size);
+	}
+
+	/* Copy the data that must be writen in the bounce buffers, if needed */
+	if (orig->type == NAND_PAGE_WRITE) {
+		if (ctx->bounce_data)
+			memcpy((void *)tweak->databuf.out + orig->dataoffs,
+			       orig->databuf.out, orig->datalen);
+
+		if (ctx->bounce_oob)
+			memcpy((void *)tweak->oobbuf.out + orig->ooboffs,
+			       orig->oobbuf.out, orig->ooblen);
+	}
+}
+EXPORT_SYMBOL_GPL(nand_ecc_tweak_req);
+
+void nand_ecc_restore_req(struct nand_ecc_req_tweak_ctx *ctx,
+			  struct nand_page_io_req *req)
+{
+	struct nand_page_io_req *orig, *tweak;
+
+	orig = &ctx->orig_req;
+	tweak = req;
+
+	/* Restore the data read from the bounce buffers, if needed */
+	if (orig->type == NAND_PAGE_READ) {
+		if (ctx->bounce_data)
+			memcpy(orig->databuf.in,
+			       tweak->databuf.in + orig->dataoffs,
+			       orig->datalen);
+
+		if (ctx->bounce_oob)
+			memcpy(orig->oobbuf.in,
+			       tweak->oobbuf.in + orig->ooboffs,
+			       orig->ooblen);
+	}
+
+	/* Ensure the original request is restored */
+	*req = *orig;
+}
+EXPORT_SYMBOL_GPL(nand_ecc_restore_req);
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
 MODULE_DESCRIPTION("Generic ECC engine");
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 697ea2474a7c..36e4fe08d0ea 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -278,6 +278,38 @@ int nand_ecc_finish_io_req(struct nand_device *nand,
 			   struct nand_page_io_req *req);
 bool nand_ecc_is_strong_enough(struct nand_device *nand);
 
+/**
+ * struct nand_ecc_req_tweak_ctx - Help for automatically tweaking requests
+ * @orig_req: Pointer to the original IO request
+ * @nand: Related NAND device, to have access to its memory organization
+ * @page_buffer_size: Real size of the page buffer to use (can be set by the
+ *                    user before the tweaking mechanism initialization)
+ * @oob_buffer_size: Real size of the OOB buffer to use (can be set by the
+ *                   user before the tweaking mechanism initialization)
+ * @spare_databuf: Data bounce buffer
+ * @spare_oobbuf: OOB bounce buffer
+ * @bounce_data: Flag indicating a data bounce buffer is used
+ * @bounce_oob: Flag indicating an OOB bounce buffer is used
+ */
+struct nand_ecc_req_tweak_ctx {
+	struct nand_page_io_req orig_req;
+	struct nand_device *nand;
+	unsigned int page_buffer_size;
+	unsigned int oob_buffer_size;
+	void *spare_databuf;
+	void *spare_oobbuf;
+	bool bounce_data;
+	bool bounce_oob;
+};
+
+int nand_ecc_init_req_tweaking(struct nand_ecc_req_tweak_ctx *ctx,
+			       struct nand_device *nand);
+void nand_ecc_cleanup_req_tweaking(struct nand_ecc_req_tweak_ctx *ctx);
+void nand_ecc_tweak_req(struct nand_ecc_req_tweak_ctx *ctx,
+			struct nand_page_io_req *req);
+void nand_ecc_restore_req(struct nand_ecc_req_tweak_ctx *ctx,
+			  struct nand_page_io_req *req);
+
 /**
  * struct nand_ecc - Information relative to the ECC
  * @defaults: Default values, depend on the underlying subsystem
-- 
2.20.1


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

  reply	other threads:[~2020-09-29 23:02 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-29 23:01 [PATCH 00/20] Create generic software ECC engines Miquel Raynal
2020-09-29 23:01 ` Miquel Raynal [this message]
2020-09-30  7:53   ` [PATCH 01/20] mtd: nand: ecc: Add an I/O request tweaking mechanism Thomas Petazzoni
2020-09-30  8:16     ` Miquel Raynal
2020-10-30 17:30   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 02/20] mtd: nand: ecc-bch: Move BCH code to the generic NAND layer Miquel Raynal
2020-10-30 17:30   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 03/20] mtd: nand: ecc-bch: Cleanup and style fixes Miquel Raynal
2020-10-30 17:30   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 04/20] mtd: nand: ecc-bch: Stop exporting the private structure Miquel Raynal
2021-01-09 14:46   ` Adam Ford
2021-01-09 14:46     ` Adam Ford
2021-01-11 10:20     ` Miquel Raynal
2021-01-11 10:20       ` Miquel Raynal
2021-01-12 14:35       ` Miquel Raynal
2021-01-12 14:35         ` Miquel Raynal
2021-01-12 16:01         ` Adam Ford
2021-01-12 16:01           ` Adam Ford
2021-01-12 17:20           ` Adam Ford
2021-01-12 17:20             ` Adam Ford
2021-01-14 15:42             ` Miquel Raynal
2021-01-14 15:42               ` Miquel Raynal
2021-01-15 12:23               ` Adam Ford
2021-01-15 12:23                 ` Adam Ford
2021-01-15 16:06                 ` Adam Ford
2021-01-15 16:06                   ` Adam Ford
2021-01-15 16:17                   ` Miquel Raynal
2021-01-15 16:17                     ` Miquel Raynal
2021-01-15 16:28                     ` Adam Ford
2021-01-15 16:28                       ` Adam Ford
2021-01-19 11:56                       ` Miquel Raynal
2021-01-19 11:56                         ` Miquel Raynal
2021-01-19 14:21                         ` Adam Ford
2021-01-19 14:21                           ` Adam Ford
2021-01-19 14:36                           ` Miquel Raynal
2021-01-19 14:36                             ` Miquel Raynal
2021-01-19 15:49                             ` Adam Ford
2021-01-19 15:49                               ` Adam Ford
2021-01-19 15:53                               ` Miquel Raynal
2021-01-19 15:53                                 ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 05/20] mtd: nand: ecc-bch: Return only valid error codes Miquel Raynal
2020-10-30 17:29   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 06/20] mtd: nand: ecc-bch: Drop mtd_nand_has_bch() Miquel Raynal
2020-10-30 17:29   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 07/20] mtd: nand: ecc-bch: Update the prototypes to be more generic Miquel Raynal
2020-10-30 17:29   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 08/20] mtd: nand: ecc-bch: Stop using raw NAND structures Miquel Raynal
2020-09-29 23:01 ` [PATCH 09/20] mtd: nand: ecc-bch: Create the software BCH engine Miquel Raynal
2020-10-30 17:29   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 10/20] mtd: rawnand: Get rid of chip->ecc.priv Miquel Raynal
2020-10-30 17:29   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 11/20] mtd: nand: ecc-hamming: Move Hamming code to the generic NAND layer Miquel Raynal
2020-09-29 23:01 ` [PATCH 12/20] mtd: nand: ecc-hamming: Clarify the driver descriptions Miquel Raynal
2020-10-30 17:29   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 13/20] mtd: nand: ecc-hamming: Drop/fix the kernel doc Miquel Raynal
2020-10-30 17:29   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 14/20] mtd: nand: ecc-hamming: Cleanup and style fixes Miquel Raynal
2020-10-30 17:29   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 15/20] mtd: nand: ecc-hamming: Rename the exported functions Miquel Raynal
2020-10-30 17:29   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 16/20] mtd: nand: ecc-hamming: Stop using raw NAND structures Miquel Raynal
2020-10-30 17:29   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 17/20] mtd: nand: ecc-hamming: Remove useless includes Miquel Raynal
2020-09-29 23:01 ` [PATCH 18/20] mtd: nand: ecc-hamming: Let the software Hamming ECC engine be unselected Miquel Raynal
2020-10-30 17:29   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 19/20] mtd: nand: ecc-hamming: Create the software Hamming engine Miquel Raynal
2020-10-30 17:28   ` Miquel Raynal
2020-09-29 23:01 ` [PATCH 20/20] mtd: nand: Let software ECC engines be retrieved from the NAND core Miquel Raynal
2020-10-30 17:28   ` Miquel Raynal

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=20200929230124.31491-2-miquel.raynal@bootlin.com \
    --to=miquel.raynal@bootlin.com \
    --cc=Tudor.Ambarus@microchip.com \
    --cc=juliensu@mxic.com.tw \
    --cc=linux-mtd@lists.infradead.org \
    --cc=richard@nod.at \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=vigneshr@ti.com \
    --cc=ycllin@mxic.com.tw \
    /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.