All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boris Brezillon <boris.brezillon@free-electrons.com>
To: David Woodhouse <dwmw2@infradead.org>,
	Brian Norris <computersforpeace@gmail.com>,
	linux-mtd@lists.infradead.org
Cc: Daniel Mack <daniel@zonque.org>,
	Haojian Zhuang <haojian.zhuang@gmail.com>,
	Robert Jarzmik <robert.jarzmik@free.fr>,
	Kukjin Kim <kgene@kernel.org>,
	Krzysztof Kozlowski <k.kozlowski@samsung.com>,
	linux-samsung-soc@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	Ralf Baechle <ralf@linux-mips.org>,
	linux-mips@linux-mips.org, Josh Wu <josh.wu@atmel.com>,
	Ezequiel Garcia <ezequiel.garcia@free-electrons.com>,
	Maxime Ripard <maxime.ripard@free-electrons.com>,
	Chen-Yu Tsai <wens@csie.org>,
	linux-sunxi@googlegroups.com, Stefan Agner <stefan@agner.ch>,
	Kyungmin Park <kyungmin.park@samsung.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org,
	punnaiah choudary kalluri <punnaia@xilinx.com>,
	Boris Brezillon <boris.brezillon@free-electrons.com>
Subject: [PATCH 12/23] mtd: use mtd_eccpos() and mtd_oobfree() where appropriate
Date: Mon,  7 Dec 2015 23:26:07 +0100	[thread overview]
Message-ID: <1449527178-5930-13-git-send-email-boris.brezillon@free-electrons.com> (raw)
In-Reply-To: <1449527178-5930-1-git-send-email-boris.brezillon@free-electrons.com>

The mtd_eccpos(), mtd_oobfree() and mtd_eccbytes() helper functions have
been added to avoid direct accesses to the ecclayout, and thus allow for
future rework.
Use these helpers in all places where the oobfree[] and eccpos[] arrays
are referenced.

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
 drivers/mtd/mtdchar.c                  | 79 ++++++++++++++++++++++++--------
 drivers/mtd/mtdswap.c                  |  4 +-
 drivers/mtd/nand/atmel_nand.c          | 21 ++++-----
 drivers/mtd/nand/fsl_ifc_nand.c        |  2 +-
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |  9 ++--
 drivers/mtd/nand/lpc32xx_slc.c         |  4 +-
 drivers/mtd/nand/nand_base.c           | 83 ++++++++++++++++++----------------
 drivers/mtd/nand/nand_bch.c            |  2 +-
 drivers/mtd/nand/omap2.c               | 11 ++---
 drivers/mtd/onenand/onenand_base.c     | 61 +++++++++++++------------
 10 files changed, 163 insertions(+), 113 deletions(-)

diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 6d19835..66d0898 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -472,31 +472,78 @@ static int mtdchar_readoob(struct file *file, struct mtd_info *mtd,
  * nand_ecclayout flexibly (i.e. the struct may change size in new
  * releases without requiring major rewrites).
  */
-static int shrink_ecclayout(const struct nand_ecclayout *from,
-		struct nand_ecclayout_user *to)
+static int shrink_ecclayout(struct mtd_info *mtd,
+			    struct nand_ecclayout_user *to)
 {
 	int i;
 
-	if (!from || !to)
+	if (!mtd || !to)
 		return -EINVAL;
 
 	memset(to, 0, sizeof(*to));
 
-	to->eccbytes = min((int)from->eccbytes, MTD_MAX_ECCPOS_ENTRIES);
-	for (i = 0; i < to->eccbytes; i++)
-		to->eccpos[i] = from->eccpos[i];
+	to->eccbytes = 0;
+	for (i = 0; i < MTD_MAX_ECCPOS_ENTRIES; i++) {
+		int pos = mtd_eccpos(mtd, i);
+
+		if (pos < 0)
+			break;
+
+		to->eccpos[i] = pos;
+		to->eccbytes++;
+	}
 
 	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) {
-		if (from->oobfree[i].length == 0 &&
-				from->oobfree[i].offset == 0)
+		mtd_oobfree(mtd, i, &to->oobfree[i]);
+		if (to->oobfree[i].length == 0 &&
+		    to->oobfree[i].offset == 0)
 			break;
-		to->oobavail += from->oobfree[i].length;
-		to->oobfree[i] = from->oobfree[i];
+		to->oobavail += to->oobfree[i].length;
 	}
 
 	return 0;
 }
 
+static int get_oobinfo(struct mtd_info *mtd, struct nand_oobinfo *to)
+{
+	int i;
+
+	if (!mtd || !to)
+		return -EINVAL;
+
+	memset(to, 0, sizeof(*to));
+
+	to->eccbytes = 0;
+	for (i = 0; i < ARRAY_SIZE(to->eccpos); i++) {
+		int pos = mtd_eccpos(mtd, i);
+
+		if (pos < 0)
+			break;
+
+		to->eccpos[i] = pos;
+		to->eccbytes++;
+	}
+
+	if (i == ARRAY_SIZE(to->eccpos))
+		return -EINVAL;
+
+	for (i = 0; i < 8; i++) {
+		struct nand_oobfree oobfree;
+
+		mtd_oobfree(mtd, i, &oobfree);
+		if (oobfree.length == 0 &&
+		    oobfree.offset == 0)
+			break;
+
+		to->oobfree[i][0] = oobfree.offset;
+		to->oobfree[i][1] = oobfree.length;
+	}
+
+	to->useecc = MTD_NANDECC_AUTOPLACE;
+
+	return 0;
+}
+
 static int mtdchar_blkpg_ioctl(struct mtd_info *mtd,
 			       struct blkpg_ioctl_arg *arg)
 {
@@ -817,14 +864,10 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 
 		if (!mtd->ecclayout)
 			return -EOPNOTSUPP;
-		if (mtd->ecclayout->eccbytes > ARRAY_SIZE(oi.eccpos))
-			return -EINVAL;
 
-		oi.useecc = MTD_NANDECC_AUTOPLACE;
-		memcpy(&oi.eccpos, mtd->ecclayout->eccpos, sizeof(oi.eccpos));
-		memcpy(&oi.oobfree, mtd->ecclayout->oobfree,
-		       sizeof(oi.oobfree));
-		oi.eccbytes = mtd->ecclayout->eccbytes;
+		ret = get_oobinfo(mtd, &oi);
+		if (ret)
+			return ret;
 
 		if (copy_to_user(argp, &oi, sizeof(struct nand_oobinfo)))
 			return -EFAULT;
@@ -920,7 +963,7 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 		if (!usrlay)
 			return -ENOMEM;
 
-		shrink_ecclayout(mtd->ecclayout, usrlay);
+		shrink_ecclayout(mtd, usrlay);
 
 		if (copy_to_user(argp, usrlay, sizeof(*usrlay)))
 			ret = -EFAULT;
diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c
index d330eb1..6fe47b0 100644
--- a/drivers/mtd/mtdswap.c
+++ b/drivers/mtd/mtdswap.c
@@ -1417,7 +1417,6 @@ static void mtdswap_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
 	unsigned long part;
 	unsigned int eblocks, eavailable, bad_blocks, spare_cnt;
 	uint64_t swap_size, use_size, size_limit;
-	struct nand_ecclayout *oinfo;
 	int ret;
 
 	parts = &partitions[0];
@@ -1447,8 +1446,7 @@ static void mtdswap_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
 		return;
 	}
 
-	oinfo = mtd->ecclayout;
-	if (!oinfo) {
+	if (mtd_oobfree(mtd, 0) < 0) {
 		printk(KERN_ERR "%s: mtd%d does not have OOB\n",
 			MTDSWAP_PREFIX, mtd->index);
 		return;
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index f4e1f91..da16b1a 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -833,7 +833,7 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc,
 			err_byte = ecc[tmp];
 			ecc[tmp] ^= (1 << bit_pos);
 
-			pos = tmp + nand_chip->ecc.layout->eccpos[0];
+			pos = tmp + mtd_eccpos(mtd, 0);
 			dev_info(host->dev, "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
 				pos, bit_pos, err_byte, ecc[tmp]);
 		}
@@ -922,7 +922,6 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
 	struct atmel_nand_host *host = chip->priv;
 	int eccsize = chip->ecc.size * chip->ecc.steps;
 	uint8_t *oob = chip->oob_poi;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	uint32_t stat;
 	unsigned long end_time;
 	int bitflips = 0;
@@ -944,7 +943,8 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
 
 	stat = pmecc_readl_relaxed(host->ecc, ISR);
 	if (stat != 0) {
-		bitflips = pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]);
+		bitflips = pmecc_correction(mtd, stat, buf,
+					    &oob[mtd_eccpos(mtd, 0)]);
 		if (bitflips < 0)
 			/* uncorrectable errors */
 			return 0;
@@ -958,7 +958,6 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
 		int page)
 {
 	struct atmel_nand_host *host = chip->priv;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	int i, j;
 	unsigned long end_time;
 
@@ -981,7 +980,7 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
 			int pos;
 
 			pos = i * chip->ecc.bytes + j;
-			chip->oob_poi[eccpos[pos]] =
+			chip->oob_poi[mtd_eccpos(mtd, pos)] =
 				pmecc_readb_ecc_relaxed(host->ecc, i, j);
 		}
 	}
@@ -1044,9 +1043,9 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
 
 	ecc_layout = nand_chip->ecc.layout;
 	pmecc_writel(host->ecc, SAREA, mtd->oobsize - 1);
-	pmecc_writel(host->ecc, SADDR, ecc_layout->eccpos[0]);
+	pmecc_writel(host->ecc, SADDR, mtd_eccpos(mtd, 0));
 	pmecc_writel(host->ecc, EADDR,
-			ecc_layout->eccpos[ecc_layout->eccbytes - 1]);
+			mtd_eccpos(mtd, ecc_layout->eccbytes - 1));
 	/* See datasheet about PMECC Clock Control Register */
 	pmecc_writel(host->ecc, CLK, 2);
 	pmecc_writel(host->ecc, IDR, 0xff);
@@ -1340,7 +1339,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 {
 	int eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	int eccpos = mtd_eccpos(mtd, 0);
 	uint8_t *p = buf;
 	uint8_t *oob = chip->oob_poi;
 	uint8_t *ecc_pos;
@@ -1363,7 +1362,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 	chip->read_buf(mtd, p, eccsize);
 
 	/* move to ECC position if needed */
-	if (eccpos[0] != 0) {
+	if (eccpos != 0) {
 		/* This only works on large pages
 		 * because the ECC controller waits for
 		 * NAND_CMD_RNDOUTSTART after the
@@ -1371,11 +1370,11 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 		 * anyway, for small pages, the eccpos[0] == 0
 		 */
 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
-				mtd->writesize + eccpos[0], -1);
+				mtd->writesize + eccpos, -1);
 	}
 
 	/* the ECC controller needs to read the ECC just after the data */
-	ecc_pos = oob + eccpos[0];
+	ecc_pos = oob + eccpos;
 	chip->read_buf(mtd, ecc_pos, eccbytes);
 
 	/* check if there's an error */
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index f260831..610308e 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -266,7 +266,7 @@ static int is_blank(struct mtd_info *mtd, unsigned int bufnum)
 	}
 
 	for (i = 0; i < chip->ecc.layout->eccbytes; i++) {
-		int pos = chip->ecc.layout->eccpos[i];
+		int pos = mtd_eccpos(mtd, i);
 
 		if (__raw_readb(&oob[pos]) != 0xff)
 			return 0;
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 5a9b696..c208f5e 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1325,18 +1325,19 @@ static int gpmi_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 static int
 gpmi_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *chip, int page)
 {
-	struct nand_oobfree *of = mtd->ecclayout->oobfree;
+	struct nand_oobfree of = { };
 	int status = 0;
 
 	/* Do we have available oob area? */
-	if (!of->length)
+	mtd_oobfree(mtd, 0, &of);
+	if (!of.length)
 		return -EPERM;
 
 	if (!nand_is_slc(chip))
 		return -EPERM;
 
-	chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize + of->offset, page);
-	chip->write_buf(mtd, chip->oob_poi + of->offset, of->length);
+	chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize + of.offset, page);
+	chip->write_buf(mtd, chip->oob_poi + of.offset, of.length);
 	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
 
 	status = chip->waitfunc(mtd, chip);
diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c
index 277626e..47dcfddd 100644
--- a/drivers/mtd/nand/lpc32xx_slc.c
+++ b/drivers/mtd/nand/lpc32xx_slc.c
@@ -621,7 +621,7 @@ static int lpc32xx_nand_read_page_syndrome(struct mtd_info *mtd,
 	lpc32xx_slc_ecc_copy(tmpecc, (uint32_t *) host->ecc_buf, chip->ecc.steps);
 
 	/* Pointer to ECC data retrieved from NAND spare area */
-	oobecc = chip->oob_poi + chip->ecc.layout->eccpos[0];
+	oobecc = chip->oob_poi + mtd_eccpos(mtd, 0);
 
 	for (i = 0; i < chip->ecc.steps; i++) {
 		stat = chip->ecc.correct(mtd, buf, oobecc,
@@ -667,7 +667,7 @@ static int lpc32xx_nand_write_page_syndrome(struct mtd_info *mtd,
 					    int oob_required, int page)
 {
 	struct lpc32xx_nand_host *host = chip->priv;
-	uint8_t *pb = chip->oob_poi + chip->ecc.layout->eccpos[0];
+	uint8_t *pb = chip->oob_poi + mtd_eccpos(mtd, 0);
 	int error;
 
 	/* Write data, calculate ECC on outbound data */
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index b99b442..30a0721 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1315,7 +1315,6 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 	uint8_t *p = buf;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	uint8_t *ecc_code = chip->buffers->ecccode;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	unsigned int max_bitflips = 0;
 
 	chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
@@ -1324,7 +1323,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		ecc_code[i] = chip->oob_poi[eccpos[i]];
+		ecc_code[i] = chip->oob_poi[mtd_eccpos(mtd, i)];
 
 	eccsteps = chip->ecc.steps;
 	p = buf;
@@ -1357,7 +1356,6 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 			int page)
 {
 	int start_step, end_step, num_steps;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	uint8_t *p;
 	int data_col_addr, i, gaps = 0;
 	int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
@@ -1392,7 +1390,8 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 	 * ecc.pos. Let's make sure that there are no gaps in ECC positions.
 	 */
 	for (i = 0; i < eccfrag_len - 1; i++) {
-		if (eccpos[i + index] + 1 != eccpos[i + index + 1]) {
+		if (mtd_eccpos(mtd, i + index) + 1 !=
+		    mtd_eccpos(mtd, i + index + 1)) {
 			gaps = 1;
 			break;
 		}
@@ -1405,11 +1404,12 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 		 * Send the command to read the particular ECC bytes take care
 		 * about buswidth alignment in read_buf.
 		 */
-		aligned_pos = eccpos[index] & ~(busw - 1);
+		aligned_pos = mtd_eccpos(mtd, index) & ~(busw - 1);
 		aligned_len = eccfrag_len;
-		if (eccpos[index] & (busw - 1))
+		if (mtd_eccpos(mtd, index) & (busw - 1))
 			aligned_len++;
-		if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1))
+		if (mtd_eccpos(mtd, index + (num_steps * chip->ecc.bytes)) &
+		    (busw - 1))
 			aligned_len++;
 
 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
@@ -1418,7 +1418,8 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 	}
 
 	for (i = 0; i < eccfrag_len; i++)
-		chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + index]];
+		chip->buffers->ecccode[i] =
+				chip->oob_poi[mtd_eccpos(mtd, i + index)];
 
 	p = bufpoi + data_col_addr;
 	for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) {
@@ -1455,7 +1456,6 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	uint8_t *p = buf;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	uint8_t *ecc_code = chip->buffers->ecccode;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	unsigned int max_bitflips = 0;
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
@@ -1466,7 +1466,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		ecc_code[i] = chip->oob_poi[eccpos[i]];
+		ecc_code[i] = chip->oob_poi[mtd_eccpos(mtd, i)];
 
 	eccsteps = chip->ecc.steps;
 	p = buf;
@@ -1507,7 +1507,6 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 	int eccsteps = chip->ecc.steps;
 	uint8_t *p = buf;
 	uint8_t *ecc_code = chip->buffers->ecccode;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	unsigned int max_bitflips = 0;
 
@@ -1517,7 +1516,7 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 	chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		ecc_code[i] = chip->oob_poi[eccpos[i]];
+		ecc_code[i] = chip->oob_poi[mtd_eccpos(mtd, i)];
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
 		int stat;
@@ -1603,9 +1602,11 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
  * @ops: oob ops structure
  * @len: size of oob to transfer
  */
-static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
+static uint8_t *nand_transfer_oob(struct mtd_info *mtd, uint8_t *oob,
 				  struct mtd_oob_ops *ops, size_t len)
 {
+	struct nand_chip *chip = mtd->priv;
+
 	switch (ops->mode) {
 
 	case MTD_OPS_PLACE_OOB:
@@ -1614,24 +1615,26 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
 		return oob + len;
 
 	case MTD_OPS_AUTO_OOB: {
-		struct nand_oobfree *free = chip->ecc.layout->oobfree;
+		struct nand_oobfree free = { };
 		uint32_t boffs = 0, roffs = ops->ooboffs;
 		size_t bytes = 0;
+		int i = 0;
 
-		for (; free->length && len; free++, len -= bytes) {
+		for (mtd_oobfree(mtd, i++, &free); free.length && len;
+		     mtd_oobfree(mtd, i++, &free), len -= bytes) {
 			/* Read request not from offset 0? */
 			if (unlikely(roffs)) {
-				if (roffs >= free->length) {
-					roffs -= free->length;
+				if (roffs >= free.length) {
+					roffs -= free.length;
 					continue;
 				}
-				boffs = free->offset + roffs;
+				boffs = free.offset + roffs;
 				bytes = min_t(size_t, len,
-					      (free->length - roffs));
+					      (free.length - roffs));
 				roffs = 0;
 			} else {
-				bytes = min_t(size_t, len, free->length);
-				boffs = free->offset;
+				bytes = min_t(size_t, len, free.length);
+				boffs = free.offset;
 			}
 			memcpy(oob, chip->oob_poi + boffs, bytes);
 			oob += bytes;
@@ -1772,7 +1775,7 @@ read_retry:
 				int toread = min(oobreadlen, max_oobsize);
 
 				if (toread) {
-					oob = nand_transfer_oob(chip,
+					oob = nand_transfer_oob(mtd,
 						oob, ops, toread);
 					oobreadlen -= toread;
 				}
@@ -2073,7 +2076,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 			break;
 
 		len = min(len, readlen);
-		buf = nand_transfer_oob(chip, buf, ops, len);
+		buf = nand_transfer_oob(mtd, buf, ops, len);
 
 		if (chip->options & NAND_NEED_READRDY) {
 			/* Apply delay or wait for ready/busy pin */
@@ -2237,14 +2240,13 @@ static int nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 	int eccsteps = chip->ecc.steps;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	const uint8_t *p = buf;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 
 	/* Software ECC calculation */
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+		chip->oob_poi[mtd_eccpos(mtd, i)] = ecc_calc[i];
 
 	return chip->ecc.write_page_raw(mtd, chip, buf, 1, page);
 }
@@ -2266,7 +2268,6 @@ static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	int eccsteps = chip->ecc.steps;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	const uint8_t *p = buf;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
 		chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
@@ -2275,7 +2276,7 @@ static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	}
 
 	for (i = 0; i < chip->ecc.total; i++)
-		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+		chip->oob_poi[mtd_eccpos(mtd, i)] = ecc_calc[i];
 
 	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
@@ -2303,7 +2304,6 @@ static int nand_write_subpage_hwecc(struct mtd_info *mtd,
 	int ecc_size      = chip->ecc.size;
 	int ecc_bytes     = chip->ecc.bytes;
 	int ecc_steps     = chip->ecc.steps;
-	uint32_t *eccpos  = chip->ecc.layout->eccpos;
 	uint32_t start_step = offset / ecc_size;
 	uint32_t end_step   = (offset + data_len - 1) / ecc_size;
 	int oob_bytes       = mtd->oobsize / ecc_steps;
@@ -2336,7 +2336,7 @@ static int nand_write_subpage_hwecc(struct mtd_info *mtd,
 	/* this include masked-value(0xFF) for unwritten subpages */
 	ecc_calc = chip->buffers->ecccalc;
 	for (i = 0; i < chip->ecc.total; i++)
-		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+		chip->oob_poi[mtd_eccpos(mtd, i)] = ecc_calc[i];
 
 	/* write OOB buffer to NAND device */
 	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -2488,24 +2488,26 @@ static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
 		return oob + len;
 
 	case MTD_OPS_AUTO_OOB: {
-		struct nand_oobfree *free = chip->ecc.layout->oobfree;
+		struct nand_oobfree free = { };
 		uint32_t boffs = 0, woffs = ops->ooboffs;
 		size_t bytes = 0;
+		int i = 0;
 
-		for (; free->length && len; free++, len -= bytes) {
+		for (mtd_oobfree(mtd, i++, &free); free.length && len;
+		     mtd_oobfree(mtd, i++, &free), len -= bytes) {
 			/* Write request not from offset 0? */
 			if (unlikely(woffs)) {
-				if (woffs >= free->length) {
-					woffs -= free->length;
+				if (woffs >= free.length) {
+					woffs -= free.length;
 					continue;
 				}
-				boffs = free->offset + woffs;
+				boffs = free.offset + woffs;
 				bytes = min_t(size_t, len,
-					      (free->length - woffs));
+					      (free.length - woffs));
 				woffs = 0;
 			} else {
-				bytes = min_t(size_t, len, free->length);
-				boffs = free->offset;
+				bytes = min_t(size_t, len, free.length);
+				boffs = free.offset;
 			}
 			memcpy(chip->oob_poi + boffs, oob, bytes);
 			oob += bytes;
@@ -4087,6 +4089,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 	int i;
 	struct nand_chip *chip = mtd->priv;
 	struct nand_ecc_ctrl *ecc = &chip->ecc;
+	struct nand_oobfree oobfree = { };
 	struct nand_buffers *nbuf;
 
 	/* New bad blocks should be marked in OOB, flash-based BBT, or both */
@@ -4284,8 +4287,10 @@ int nand_scan_tail(struct mtd_info *mtd)
 	 * the out of band area.
 	 */
 	mtd->oobavail = 0;
-	for (i = 0; ecc->layout->oobfree[i].length; i++)
-		mtd->oobavail += ecc->layout->oobfree[i].length;
+	i = 0;
+	for (mtd_oobfree(mtd, i++, &oobfree); oobfree.length;
+	     mtd_oobfree(mtd, i++, &oobfree))
+		mtd->oobavail += oobfree.length;
 
 	/* ECC sanity check: warn if it's too weak */
 	if (!nand_ecc_strength_good(mtd))
diff --git a/drivers/mtd/nand/nand_bch.c b/drivers/mtd/nand/nand_bch.c
index 3456c20..9cff544 100644
--- a/drivers/mtd/nand/nand_bch.c
+++ b/drivers/mtd/nand/nand_bch.c
@@ -196,7 +196,7 @@ struct nand_bch_control *nand_bch_init(struct mtd_info *mtd)
 		printk(KERN_WARNING "eccsize %u is too large\n", eccsize);
 		goto fail;
 	}
-	if (layout->eccbytes != (eccsteps*eccbytes)) {
+	if (mtd_eccbytes(mtd) != (eccsteps*eccbytes)) {
 		printk(KERN_WARNING "invalid ecc layout\n");
 		goto fail;
 	}
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index a2f015d..6a598b1 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1509,7 +1509,6 @@ static int omap_write_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 {
 	int i;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 
 	/* Enable GPMC ecc engine */
 	chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
@@ -1521,7 +1520,7 @@ static int omap_write_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 	chip->ecc.calculate(mtd, buf, &ecc_calc[0]);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+		chip->oob_poi[mtd_eccpos(mtd, i)] = ecc_calc[i];
 
 	/* Write ecc vector to OOB area */
 	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -1548,9 +1547,9 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 {
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	uint8_t *ecc_code = chip->buffers->ecccode;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
-	uint8_t *oob = &chip->oob_poi[eccpos[0]];
-	uint32_t oob_pos = mtd->writesize + chip->ecc.layout->eccpos[0];
+	int ecc0pos = mtd_eccpos(mtd, 0);
+	uint8_t *oob = &chip->oob_poi[ecc0pos];
+	uint32_t oob_pos = mtd->writesize + ecc0pos;
 	int stat;
 	unsigned int max_bitflips = 0;
 
@@ -1567,7 +1566,7 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 	/* Calculate ecc bytes */
 	chip->ecc.calculate(mtd, buf, ecc_calc);
 
-	memcpy(ecc_code, &chip->oob_poi[eccpos[0]], chip->ecc.total);
+	memcpy(ecc_code, &chip->oob_poi[ecc0pos], chip->ecc.total);
 
 	stat = chip->ecc.correct(mtd, buf, ecc_code, ecc_calc);
 
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index d70bbfd..25e6bf2 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1024,27 +1024,29 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
 				int thislen)
 {
 	struct onenand_chip *this = mtd->priv;
-	struct nand_oobfree *free;
+	struct nand_oobfree free = { };
 	int readcol = column;
 	int readend = column + thislen;
 	int lastgap = 0;
-	unsigned int i;
+	unsigned int i = 0;
 	uint8_t *oob_buf = this->oob_buf;
 
-	free = this->ecclayout->oobfree;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
+	for (mtd_oobfree(mtd, i++, &free); free.length;
+	     mtd_oobfree(mtd, i++, &free)) {
 		if (readcol >= lastgap)
-			readcol += free->offset - lastgap;
+			readcol += free.offset - lastgap;
 		if (readend >= lastgap)
-			readend += free->offset - lastgap;
-		lastgap = free->offset + free->length;
+			readend += free.offset - lastgap;
+		lastgap = free.offset + free.length;
 	}
 	this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
-	free = this->ecclayout->oobfree;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
-		int free_end = free->offset + free->length;
-		if (free->offset < readend && free_end > readcol) {
-			int st = max_t(int,free->offset,readcol);
+	memset(&free, 0, sizeof(free));
+	i = 0;
+	for (mtd_oobfree(mtd, i++, &free); free.length;
+	     mtd_oobfree(mtd, i++, &free)) {
+		int free_end = free.offset + free.length;
+		if (free.offset < readend && free_end > readcol) {
+			int st = max_t(int,free.offset,readcol);
 			int ed = min_t(int,free_end,readend);
 			int n = ed - st;
 			memcpy(buf, oob_buf + st, n);
@@ -1816,26 +1818,27 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
 static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
 				  const u_char *buf, int column, int thislen)
 {
-	struct onenand_chip *this = mtd->priv;
-	struct nand_oobfree *free;
+	struct nand_oobfree free = { };
 	int writecol = column;
 	int writeend = column + thislen;
 	int lastgap = 0;
-	unsigned int i;
+	unsigned int i = 0;
 
-	free = this->ecclayout->oobfree;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
+	for (mtd_oobfree(mtd, i++, &free); free.length;
+	     mtd_oobfree(mtd, i++, &free)) {
 		if (writecol >= lastgap)
-			writecol += free->offset - lastgap;
+			writecol += free.offset - lastgap;
 		if (writeend >= lastgap)
-			writeend += free->offset - lastgap;
-		lastgap = free->offset + free->length;
+			writeend += free.offset - lastgap;
+		lastgap = free.offset + free.length;
 	}
-	free = this->ecclayout->oobfree;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
-		int free_end = free->offset + free->length;
-		if (free->offset < writeend && free_end > writecol) {
-			int st = max_t(int,free->offset,writecol);
+	memset(&free, 0, sizeof(free));
+	i = 0;
+	for (mtd_oobfree(mtd, i++, &free); free.length;
+	     mtd_oobfree(mtd, i++, &free)) {
+		int free_end = free.offset + free.length;
+		if (free.offset < writeend && free_end > writecol) {
+			int st = max_t(int,free.offset,writecol);
 			int ed = min_t(int,free_end,writeend);
 			int n = ed - st;
 			memcpy(oob_buf + st, buf, n);
@@ -3942,6 +3945,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 {
 	int i, ret;
 	struct onenand_chip *this = mtd->priv;
+	struct nand_oobfree oobfree = {};
 
 	if (!this->read_word)
 		this->read_word = onenand_readw;
@@ -4050,9 +4054,10 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 	 * the out of band area
 	 */
 	mtd->oobavail = 0;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES &&
-	    this->ecclayout->oobfree[i].length; i++)
-		mtd->oobavail += this->ecclayout->oobfree[i].length;
+	i = 0;
+	for (mtd_oobfree(mtd, i++, &oobfree); oobfree.length;
+	     mtd_oobfree(mtd, i++, &oobfree))
+		mtd->oobavail += oobfree.length;
 
 	mtd->ecclayout = this->ecclayout;
 	mtd->ecc_strength = 1;
-- 
2.1.4


WARNING: multiple messages have this Message-ID (diff)
From: Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
To: David Woodhouse <dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>,
	Brian Norris
	<computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Cc: Daniel Mack <daniel-cYrQPVfZoowdnm+yROfE0A@public.gmane.org>,
	Haojian Zhuang
	<haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Robert Jarzmik <robert.jarzmik-GANU6spQydw@public.gmane.org>,
	Kukjin Kim <kgene-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Krzysztof Kozlowski
	<k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	Ralf Baechle <ralf-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org>,
	linux-mips-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org,
	Josh Wu <josh.wu-AIFe0yeh4nAAvxtiuMwx3w@public.gmane.org>,
	Ezequiel Garcia
	<ezequiel.garcia-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
	Maxime Ripard
	<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
	Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org,
	Stefan Agner <stefan-XLVq0VzYD2Y@public.gmane.org>,
	Kyungmin Park
	<kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>,
	Greg Kroah-Hartman
	<gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>,
	devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	punnaiah choudary kalluri
	<punnaia-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>,
	Boris Brezillon
	<boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Subject: [PATCH 12/23] mtd: use mtd_eccpos() and mtd_oobfree() where appropriate
Date: Mon,  7 Dec 2015 23:26:07 +0100	[thread overview]
Message-ID: <1449527178-5930-13-git-send-email-boris.brezillon@free-electrons.com> (raw)
In-Reply-To: <1449527178-5930-1-git-send-email-boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>

The mtd_eccpos(), mtd_oobfree() and mtd_eccbytes() helper functions have
been added to avoid direct accesses to the ecclayout, and thus allow for
future rework.
Use these helpers in all places where the oobfree[] and eccpos[] arrays
are referenced.

Signed-off-by: Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 drivers/mtd/mtdchar.c                  | 79 ++++++++++++++++++++++++--------
 drivers/mtd/mtdswap.c                  |  4 +-
 drivers/mtd/nand/atmel_nand.c          | 21 ++++-----
 drivers/mtd/nand/fsl_ifc_nand.c        |  2 +-
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |  9 ++--
 drivers/mtd/nand/lpc32xx_slc.c         |  4 +-
 drivers/mtd/nand/nand_base.c           | 83 ++++++++++++++++++----------------
 drivers/mtd/nand/nand_bch.c            |  2 +-
 drivers/mtd/nand/omap2.c               | 11 ++---
 drivers/mtd/onenand/onenand_base.c     | 61 +++++++++++++------------
 10 files changed, 163 insertions(+), 113 deletions(-)

diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 6d19835..66d0898 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -472,31 +472,78 @@ static int mtdchar_readoob(struct file *file, struct mtd_info *mtd,
  * nand_ecclayout flexibly (i.e. the struct may change size in new
  * releases without requiring major rewrites).
  */
-static int shrink_ecclayout(const struct nand_ecclayout *from,
-		struct nand_ecclayout_user *to)
+static int shrink_ecclayout(struct mtd_info *mtd,
+			    struct nand_ecclayout_user *to)
 {
 	int i;
 
-	if (!from || !to)
+	if (!mtd || !to)
 		return -EINVAL;
 
 	memset(to, 0, sizeof(*to));
 
-	to->eccbytes = min((int)from->eccbytes, MTD_MAX_ECCPOS_ENTRIES);
-	for (i = 0; i < to->eccbytes; i++)
-		to->eccpos[i] = from->eccpos[i];
+	to->eccbytes = 0;
+	for (i = 0; i < MTD_MAX_ECCPOS_ENTRIES; i++) {
+		int pos = mtd_eccpos(mtd, i);
+
+		if (pos < 0)
+			break;
+
+		to->eccpos[i] = pos;
+		to->eccbytes++;
+	}
 
 	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) {
-		if (from->oobfree[i].length == 0 &&
-				from->oobfree[i].offset == 0)
+		mtd_oobfree(mtd, i, &to->oobfree[i]);
+		if (to->oobfree[i].length == 0 &&
+		    to->oobfree[i].offset == 0)
 			break;
-		to->oobavail += from->oobfree[i].length;
-		to->oobfree[i] = from->oobfree[i];
+		to->oobavail += to->oobfree[i].length;
 	}
 
 	return 0;
 }
 
+static int get_oobinfo(struct mtd_info *mtd, struct nand_oobinfo *to)
+{
+	int i;
+
+	if (!mtd || !to)
+		return -EINVAL;
+
+	memset(to, 0, sizeof(*to));
+
+	to->eccbytes = 0;
+	for (i = 0; i < ARRAY_SIZE(to->eccpos); i++) {
+		int pos = mtd_eccpos(mtd, i);
+
+		if (pos < 0)
+			break;
+
+		to->eccpos[i] = pos;
+		to->eccbytes++;
+	}
+
+	if (i == ARRAY_SIZE(to->eccpos))
+		return -EINVAL;
+
+	for (i = 0; i < 8; i++) {
+		struct nand_oobfree oobfree;
+
+		mtd_oobfree(mtd, i, &oobfree);
+		if (oobfree.length == 0 &&
+		    oobfree.offset == 0)
+			break;
+
+		to->oobfree[i][0] = oobfree.offset;
+		to->oobfree[i][1] = oobfree.length;
+	}
+
+	to->useecc = MTD_NANDECC_AUTOPLACE;
+
+	return 0;
+}
+
 static int mtdchar_blkpg_ioctl(struct mtd_info *mtd,
 			       struct blkpg_ioctl_arg *arg)
 {
@@ -817,14 +864,10 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 
 		if (!mtd->ecclayout)
 			return -EOPNOTSUPP;
-		if (mtd->ecclayout->eccbytes > ARRAY_SIZE(oi.eccpos))
-			return -EINVAL;
 
-		oi.useecc = MTD_NANDECC_AUTOPLACE;
-		memcpy(&oi.eccpos, mtd->ecclayout->eccpos, sizeof(oi.eccpos));
-		memcpy(&oi.oobfree, mtd->ecclayout->oobfree,
-		       sizeof(oi.oobfree));
-		oi.eccbytes = mtd->ecclayout->eccbytes;
+		ret = get_oobinfo(mtd, &oi);
+		if (ret)
+			return ret;
 
 		if (copy_to_user(argp, &oi, sizeof(struct nand_oobinfo)))
 			return -EFAULT;
@@ -920,7 +963,7 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 		if (!usrlay)
 			return -ENOMEM;
 
-		shrink_ecclayout(mtd->ecclayout, usrlay);
+		shrink_ecclayout(mtd, usrlay);
 
 		if (copy_to_user(argp, usrlay, sizeof(*usrlay)))
 			ret = -EFAULT;
diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c
index d330eb1..6fe47b0 100644
--- a/drivers/mtd/mtdswap.c
+++ b/drivers/mtd/mtdswap.c
@@ -1417,7 +1417,6 @@ static void mtdswap_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
 	unsigned long part;
 	unsigned int eblocks, eavailable, bad_blocks, spare_cnt;
 	uint64_t swap_size, use_size, size_limit;
-	struct nand_ecclayout *oinfo;
 	int ret;
 
 	parts = &partitions[0];
@@ -1447,8 +1446,7 @@ static void mtdswap_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
 		return;
 	}
 
-	oinfo = mtd->ecclayout;
-	if (!oinfo) {
+	if (mtd_oobfree(mtd, 0) < 0) {
 		printk(KERN_ERR "%s: mtd%d does not have OOB\n",
 			MTDSWAP_PREFIX, mtd->index);
 		return;
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index f4e1f91..da16b1a 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -833,7 +833,7 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc,
 			err_byte = ecc[tmp];
 			ecc[tmp] ^= (1 << bit_pos);
 
-			pos = tmp + nand_chip->ecc.layout->eccpos[0];
+			pos = tmp + mtd_eccpos(mtd, 0);
 			dev_info(host->dev, "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
 				pos, bit_pos, err_byte, ecc[tmp]);
 		}
@@ -922,7 +922,6 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
 	struct atmel_nand_host *host = chip->priv;
 	int eccsize = chip->ecc.size * chip->ecc.steps;
 	uint8_t *oob = chip->oob_poi;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	uint32_t stat;
 	unsigned long end_time;
 	int bitflips = 0;
@@ -944,7 +943,8 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
 
 	stat = pmecc_readl_relaxed(host->ecc, ISR);
 	if (stat != 0) {
-		bitflips = pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]);
+		bitflips = pmecc_correction(mtd, stat, buf,
+					    &oob[mtd_eccpos(mtd, 0)]);
 		if (bitflips < 0)
 			/* uncorrectable errors */
 			return 0;
@@ -958,7 +958,6 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
 		int page)
 {
 	struct atmel_nand_host *host = chip->priv;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	int i, j;
 	unsigned long end_time;
 
@@ -981,7 +980,7 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
 			int pos;
 
 			pos = i * chip->ecc.bytes + j;
-			chip->oob_poi[eccpos[pos]] =
+			chip->oob_poi[mtd_eccpos(mtd, pos)] =
 				pmecc_readb_ecc_relaxed(host->ecc, i, j);
 		}
 	}
@@ -1044,9 +1043,9 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
 
 	ecc_layout = nand_chip->ecc.layout;
 	pmecc_writel(host->ecc, SAREA, mtd->oobsize - 1);
-	pmecc_writel(host->ecc, SADDR, ecc_layout->eccpos[0]);
+	pmecc_writel(host->ecc, SADDR, mtd_eccpos(mtd, 0));
 	pmecc_writel(host->ecc, EADDR,
-			ecc_layout->eccpos[ecc_layout->eccbytes - 1]);
+			mtd_eccpos(mtd, ecc_layout->eccbytes - 1));
 	/* See datasheet about PMECC Clock Control Register */
 	pmecc_writel(host->ecc, CLK, 2);
 	pmecc_writel(host->ecc, IDR, 0xff);
@@ -1340,7 +1339,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 {
 	int eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	int eccpos = mtd_eccpos(mtd, 0);
 	uint8_t *p = buf;
 	uint8_t *oob = chip->oob_poi;
 	uint8_t *ecc_pos;
@@ -1363,7 +1362,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 	chip->read_buf(mtd, p, eccsize);
 
 	/* move to ECC position if needed */
-	if (eccpos[0] != 0) {
+	if (eccpos != 0) {
 		/* This only works on large pages
 		 * because the ECC controller waits for
 		 * NAND_CMD_RNDOUTSTART after the
@@ -1371,11 +1370,11 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 		 * anyway, for small pages, the eccpos[0] == 0
 		 */
 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
-				mtd->writesize + eccpos[0], -1);
+				mtd->writesize + eccpos, -1);
 	}
 
 	/* the ECC controller needs to read the ECC just after the data */
-	ecc_pos = oob + eccpos[0];
+	ecc_pos = oob + eccpos;
 	chip->read_buf(mtd, ecc_pos, eccbytes);
 
 	/* check if there's an error */
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index f260831..610308e 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -266,7 +266,7 @@ static int is_blank(struct mtd_info *mtd, unsigned int bufnum)
 	}
 
 	for (i = 0; i < chip->ecc.layout->eccbytes; i++) {
-		int pos = chip->ecc.layout->eccpos[i];
+		int pos = mtd_eccpos(mtd, i);
 
 		if (__raw_readb(&oob[pos]) != 0xff)
 			return 0;
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 5a9b696..c208f5e 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1325,18 +1325,19 @@ static int gpmi_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 static int
 gpmi_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *chip, int page)
 {
-	struct nand_oobfree *of = mtd->ecclayout->oobfree;
+	struct nand_oobfree of = { };
 	int status = 0;
 
 	/* Do we have available oob area? */
-	if (!of->length)
+	mtd_oobfree(mtd, 0, &of);
+	if (!of.length)
 		return -EPERM;
 
 	if (!nand_is_slc(chip))
 		return -EPERM;
 
-	chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize + of->offset, page);
-	chip->write_buf(mtd, chip->oob_poi + of->offset, of->length);
+	chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize + of.offset, page);
+	chip->write_buf(mtd, chip->oob_poi + of.offset, of.length);
 	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
 
 	status = chip->waitfunc(mtd, chip);
diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c
index 277626e..47dcfddd 100644
--- a/drivers/mtd/nand/lpc32xx_slc.c
+++ b/drivers/mtd/nand/lpc32xx_slc.c
@@ -621,7 +621,7 @@ static int lpc32xx_nand_read_page_syndrome(struct mtd_info *mtd,
 	lpc32xx_slc_ecc_copy(tmpecc, (uint32_t *) host->ecc_buf, chip->ecc.steps);
 
 	/* Pointer to ECC data retrieved from NAND spare area */
-	oobecc = chip->oob_poi + chip->ecc.layout->eccpos[0];
+	oobecc = chip->oob_poi + mtd_eccpos(mtd, 0);
 
 	for (i = 0; i < chip->ecc.steps; i++) {
 		stat = chip->ecc.correct(mtd, buf, oobecc,
@@ -667,7 +667,7 @@ static int lpc32xx_nand_write_page_syndrome(struct mtd_info *mtd,
 					    int oob_required, int page)
 {
 	struct lpc32xx_nand_host *host = chip->priv;
-	uint8_t *pb = chip->oob_poi + chip->ecc.layout->eccpos[0];
+	uint8_t *pb = chip->oob_poi + mtd_eccpos(mtd, 0);
 	int error;
 
 	/* Write data, calculate ECC on outbound data */
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index b99b442..30a0721 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1315,7 +1315,6 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 	uint8_t *p = buf;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	uint8_t *ecc_code = chip->buffers->ecccode;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	unsigned int max_bitflips = 0;
 
 	chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
@@ -1324,7 +1323,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		ecc_code[i] = chip->oob_poi[eccpos[i]];
+		ecc_code[i] = chip->oob_poi[mtd_eccpos(mtd, i)];
 
 	eccsteps = chip->ecc.steps;
 	p = buf;
@@ -1357,7 +1356,6 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 			int page)
 {
 	int start_step, end_step, num_steps;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	uint8_t *p;
 	int data_col_addr, i, gaps = 0;
 	int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
@@ -1392,7 +1390,8 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 	 * ecc.pos. Let's make sure that there are no gaps in ECC positions.
 	 */
 	for (i = 0; i < eccfrag_len - 1; i++) {
-		if (eccpos[i + index] + 1 != eccpos[i + index + 1]) {
+		if (mtd_eccpos(mtd, i + index) + 1 !=
+		    mtd_eccpos(mtd, i + index + 1)) {
 			gaps = 1;
 			break;
 		}
@@ -1405,11 +1404,12 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 		 * Send the command to read the particular ECC bytes take care
 		 * about buswidth alignment in read_buf.
 		 */
-		aligned_pos = eccpos[index] & ~(busw - 1);
+		aligned_pos = mtd_eccpos(mtd, index) & ~(busw - 1);
 		aligned_len = eccfrag_len;
-		if (eccpos[index] & (busw - 1))
+		if (mtd_eccpos(mtd, index) & (busw - 1))
 			aligned_len++;
-		if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1))
+		if (mtd_eccpos(mtd, index + (num_steps * chip->ecc.bytes)) &
+		    (busw - 1))
 			aligned_len++;
 
 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
@@ -1418,7 +1418,8 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 	}
 
 	for (i = 0; i < eccfrag_len; i++)
-		chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + index]];
+		chip->buffers->ecccode[i] =
+				chip->oob_poi[mtd_eccpos(mtd, i + index)];
 
 	p = bufpoi + data_col_addr;
 	for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) {
@@ -1455,7 +1456,6 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	uint8_t *p = buf;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	uint8_t *ecc_code = chip->buffers->ecccode;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	unsigned int max_bitflips = 0;
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
@@ -1466,7 +1466,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		ecc_code[i] = chip->oob_poi[eccpos[i]];
+		ecc_code[i] = chip->oob_poi[mtd_eccpos(mtd, i)];
 
 	eccsteps = chip->ecc.steps;
 	p = buf;
@@ -1507,7 +1507,6 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 	int eccsteps = chip->ecc.steps;
 	uint8_t *p = buf;
 	uint8_t *ecc_code = chip->buffers->ecccode;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	unsigned int max_bitflips = 0;
 
@@ -1517,7 +1516,7 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 	chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		ecc_code[i] = chip->oob_poi[eccpos[i]];
+		ecc_code[i] = chip->oob_poi[mtd_eccpos(mtd, i)];
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
 		int stat;
@@ -1603,9 +1602,11 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
  * @ops: oob ops structure
  * @len: size of oob to transfer
  */
-static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
+static uint8_t *nand_transfer_oob(struct mtd_info *mtd, uint8_t *oob,
 				  struct mtd_oob_ops *ops, size_t len)
 {
+	struct nand_chip *chip = mtd->priv;
+
 	switch (ops->mode) {
 
 	case MTD_OPS_PLACE_OOB:
@@ -1614,24 +1615,26 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
 		return oob + len;
 
 	case MTD_OPS_AUTO_OOB: {
-		struct nand_oobfree *free = chip->ecc.layout->oobfree;
+		struct nand_oobfree free = { };
 		uint32_t boffs = 0, roffs = ops->ooboffs;
 		size_t bytes = 0;
+		int i = 0;
 
-		for (; free->length && len; free++, len -= bytes) {
+		for (mtd_oobfree(mtd, i++, &free); free.length && len;
+		     mtd_oobfree(mtd, i++, &free), len -= bytes) {
 			/* Read request not from offset 0? */
 			if (unlikely(roffs)) {
-				if (roffs >= free->length) {
-					roffs -= free->length;
+				if (roffs >= free.length) {
+					roffs -= free.length;
 					continue;
 				}
-				boffs = free->offset + roffs;
+				boffs = free.offset + roffs;
 				bytes = min_t(size_t, len,
-					      (free->length - roffs));
+					      (free.length - roffs));
 				roffs = 0;
 			} else {
-				bytes = min_t(size_t, len, free->length);
-				boffs = free->offset;
+				bytes = min_t(size_t, len, free.length);
+				boffs = free.offset;
 			}
 			memcpy(oob, chip->oob_poi + boffs, bytes);
 			oob += bytes;
@@ -1772,7 +1775,7 @@ read_retry:
 				int toread = min(oobreadlen, max_oobsize);
 
 				if (toread) {
-					oob = nand_transfer_oob(chip,
+					oob = nand_transfer_oob(mtd,
 						oob, ops, toread);
 					oobreadlen -= toread;
 				}
@@ -2073,7 +2076,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 			break;
 
 		len = min(len, readlen);
-		buf = nand_transfer_oob(chip, buf, ops, len);
+		buf = nand_transfer_oob(mtd, buf, ops, len);
 
 		if (chip->options & NAND_NEED_READRDY) {
 			/* Apply delay or wait for ready/busy pin */
@@ -2237,14 +2240,13 @@ static int nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 	int eccsteps = chip->ecc.steps;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	const uint8_t *p = buf;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 
 	/* Software ECC calculation */
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+		chip->oob_poi[mtd_eccpos(mtd, i)] = ecc_calc[i];
 
 	return chip->ecc.write_page_raw(mtd, chip, buf, 1, page);
 }
@@ -2266,7 +2268,6 @@ static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	int eccsteps = chip->ecc.steps;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	const uint8_t *p = buf;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
 		chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
@@ -2275,7 +2276,7 @@ static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	}
 
 	for (i = 0; i < chip->ecc.total; i++)
-		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+		chip->oob_poi[mtd_eccpos(mtd, i)] = ecc_calc[i];
 
 	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
@@ -2303,7 +2304,6 @@ static int nand_write_subpage_hwecc(struct mtd_info *mtd,
 	int ecc_size      = chip->ecc.size;
 	int ecc_bytes     = chip->ecc.bytes;
 	int ecc_steps     = chip->ecc.steps;
-	uint32_t *eccpos  = chip->ecc.layout->eccpos;
 	uint32_t start_step = offset / ecc_size;
 	uint32_t end_step   = (offset + data_len - 1) / ecc_size;
 	int oob_bytes       = mtd->oobsize / ecc_steps;
@@ -2336,7 +2336,7 @@ static int nand_write_subpage_hwecc(struct mtd_info *mtd,
 	/* this include masked-value(0xFF) for unwritten subpages */
 	ecc_calc = chip->buffers->ecccalc;
 	for (i = 0; i < chip->ecc.total; i++)
-		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+		chip->oob_poi[mtd_eccpos(mtd, i)] = ecc_calc[i];
 
 	/* write OOB buffer to NAND device */
 	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -2488,24 +2488,26 @@ static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
 		return oob + len;
 
 	case MTD_OPS_AUTO_OOB: {
-		struct nand_oobfree *free = chip->ecc.layout->oobfree;
+		struct nand_oobfree free = { };
 		uint32_t boffs = 0, woffs = ops->ooboffs;
 		size_t bytes = 0;
+		int i = 0;
 
-		for (; free->length && len; free++, len -= bytes) {
+		for (mtd_oobfree(mtd, i++, &free); free.length && len;
+		     mtd_oobfree(mtd, i++, &free), len -= bytes) {
 			/* Write request not from offset 0? */
 			if (unlikely(woffs)) {
-				if (woffs >= free->length) {
-					woffs -= free->length;
+				if (woffs >= free.length) {
+					woffs -= free.length;
 					continue;
 				}
-				boffs = free->offset + woffs;
+				boffs = free.offset + woffs;
 				bytes = min_t(size_t, len,
-					      (free->length - woffs));
+					      (free.length - woffs));
 				woffs = 0;
 			} else {
-				bytes = min_t(size_t, len, free->length);
-				boffs = free->offset;
+				bytes = min_t(size_t, len, free.length);
+				boffs = free.offset;
 			}
 			memcpy(chip->oob_poi + boffs, oob, bytes);
 			oob += bytes;
@@ -4087,6 +4089,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 	int i;
 	struct nand_chip *chip = mtd->priv;
 	struct nand_ecc_ctrl *ecc = &chip->ecc;
+	struct nand_oobfree oobfree = { };
 	struct nand_buffers *nbuf;
 
 	/* New bad blocks should be marked in OOB, flash-based BBT, or both */
@@ -4284,8 +4287,10 @@ int nand_scan_tail(struct mtd_info *mtd)
 	 * the out of band area.
 	 */
 	mtd->oobavail = 0;
-	for (i = 0; ecc->layout->oobfree[i].length; i++)
-		mtd->oobavail += ecc->layout->oobfree[i].length;
+	i = 0;
+	for (mtd_oobfree(mtd, i++, &oobfree); oobfree.length;
+	     mtd_oobfree(mtd, i++, &oobfree))
+		mtd->oobavail += oobfree.length;
 
 	/* ECC sanity check: warn if it's too weak */
 	if (!nand_ecc_strength_good(mtd))
diff --git a/drivers/mtd/nand/nand_bch.c b/drivers/mtd/nand/nand_bch.c
index 3456c20..9cff544 100644
--- a/drivers/mtd/nand/nand_bch.c
+++ b/drivers/mtd/nand/nand_bch.c
@@ -196,7 +196,7 @@ struct nand_bch_control *nand_bch_init(struct mtd_info *mtd)
 		printk(KERN_WARNING "eccsize %u is too large\n", eccsize);
 		goto fail;
 	}
-	if (layout->eccbytes != (eccsteps*eccbytes)) {
+	if (mtd_eccbytes(mtd) != (eccsteps*eccbytes)) {
 		printk(KERN_WARNING "invalid ecc layout\n");
 		goto fail;
 	}
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index a2f015d..6a598b1 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1509,7 +1509,6 @@ static int omap_write_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 {
 	int i;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 
 	/* Enable GPMC ecc engine */
 	chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
@@ -1521,7 +1520,7 @@ static int omap_write_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 	chip->ecc.calculate(mtd, buf, &ecc_calc[0]);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+		chip->oob_poi[mtd_eccpos(mtd, i)] = ecc_calc[i];
 
 	/* Write ecc vector to OOB area */
 	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -1548,9 +1547,9 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 {
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	uint8_t *ecc_code = chip->buffers->ecccode;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
-	uint8_t *oob = &chip->oob_poi[eccpos[0]];
-	uint32_t oob_pos = mtd->writesize + chip->ecc.layout->eccpos[0];
+	int ecc0pos = mtd_eccpos(mtd, 0);
+	uint8_t *oob = &chip->oob_poi[ecc0pos];
+	uint32_t oob_pos = mtd->writesize + ecc0pos;
 	int stat;
 	unsigned int max_bitflips = 0;
 
@@ -1567,7 +1566,7 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 	/* Calculate ecc bytes */
 	chip->ecc.calculate(mtd, buf, ecc_calc);
 
-	memcpy(ecc_code, &chip->oob_poi[eccpos[0]], chip->ecc.total);
+	memcpy(ecc_code, &chip->oob_poi[ecc0pos], chip->ecc.total);
 
 	stat = chip->ecc.correct(mtd, buf, ecc_code, ecc_calc);
 
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index d70bbfd..25e6bf2 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1024,27 +1024,29 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
 				int thislen)
 {
 	struct onenand_chip *this = mtd->priv;
-	struct nand_oobfree *free;
+	struct nand_oobfree free = { };
 	int readcol = column;
 	int readend = column + thislen;
 	int lastgap = 0;
-	unsigned int i;
+	unsigned int i = 0;
 	uint8_t *oob_buf = this->oob_buf;
 
-	free = this->ecclayout->oobfree;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
+	for (mtd_oobfree(mtd, i++, &free); free.length;
+	     mtd_oobfree(mtd, i++, &free)) {
 		if (readcol >= lastgap)
-			readcol += free->offset - lastgap;
+			readcol += free.offset - lastgap;
 		if (readend >= lastgap)
-			readend += free->offset - lastgap;
-		lastgap = free->offset + free->length;
+			readend += free.offset - lastgap;
+		lastgap = free.offset + free.length;
 	}
 	this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
-	free = this->ecclayout->oobfree;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
-		int free_end = free->offset + free->length;
-		if (free->offset < readend && free_end > readcol) {
-			int st = max_t(int,free->offset,readcol);
+	memset(&free, 0, sizeof(free));
+	i = 0;
+	for (mtd_oobfree(mtd, i++, &free); free.length;
+	     mtd_oobfree(mtd, i++, &free)) {
+		int free_end = free.offset + free.length;
+		if (free.offset < readend && free_end > readcol) {
+			int st = max_t(int,free.offset,readcol);
 			int ed = min_t(int,free_end,readend);
 			int n = ed - st;
 			memcpy(buf, oob_buf + st, n);
@@ -1816,26 +1818,27 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
 static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
 				  const u_char *buf, int column, int thislen)
 {
-	struct onenand_chip *this = mtd->priv;
-	struct nand_oobfree *free;
+	struct nand_oobfree free = { };
 	int writecol = column;
 	int writeend = column + thislen;
 	int lastgap = 0;
-	unsigned int i;
+	unsigned int i = 0;
 
-	free = this->ecclayout->oobfree;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
+	for (mtd_oobfree(mtd, i++, &free); free.length;
+	     mtd_oobfree(mtd, i++, &free)) {
 		if (writecol >= lastgap)
-			writecol += free->offset - lastgap;
+			writecol += free.offset - lastgap;
 		if (writeend >= lastgap)
-			writeend += free->offset - lastgap;
-		lastgap = free->offset + free->length;
+			writeend += free.offset - lastgap;
+		lastgap = free.offset + free.length;
 	}
-	free = this->ecclayout->oobfree;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
-		int free_end = free->offset + free->length;
-		if (free->offset < writeend && free_end > writecol) {
-			int st = max_t(int,free->offset,writecol);
+	memset(&free, 0, sizeof(free));
+	i = 0;
+	for (mtd_oobfree(mtd, i++, &free); free.length;
+	     mtd_oobfree(mtd, i++, &free)) {
+		int free_end = free.offset + free.length;
+		if (free.offset < writeend && free_end > writecol) {
+			int st = max_t(int,free.offset,writecol);
 			int ed = min_t(int,free_end,writeend);
 			int n = ed - st;
 			memcpy(oob_buf + st, buf, n);
@@ -3942,6 +3945,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 {
 	int i, ret;
 	struct onenand_chip *this = mtd->priv;
+	struct nand_oobfree oobfree = {};
 
 	if (!this->read_word)
 		this->read_word = onenand_readw;
@@ -4050,9 +4054,10 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 	 * the out of band area
 	 */
 	mtd->oobavail = 0;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES &&
-	    this->ecclayout->oobfree[i].length; i++)
-		mtd->oobavail += this->ecclayout->oobfree[i].length;
+	i = 0;
+	for (mtd_oobfree(mtd, i++, &oobfree); oobfree.length;
+	     mtd_oobfree(mtd, i++, &oobfree))
+		mtd->oobavail += oobfree.length;
 
 	mtd->ecclayout = this->ecclayout;
 	mtd->ecc_strength = 1;
-- 
2.1.4

WARNING: multiple messages have this Message-ID (diff)
From: boris.brezillon@free-electrons.com (Boris Brezillon)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 12/23] mtd: use mtd_eccpos() and mtd_oobfree() where appropriate
Date: Mon,  7 Dec 2015 23:26:07 +0100	[thread overview]
Message-ID: <1449527178-5930-13-git-send-email-boris.brezillon@free-electrons.com> (raw)
In-Reply-To: <1449527178-5930-1-git-send-email-boris.brezillon@free-electrons.com>

The mtd_eccpos(), mtd_oobfree() and mtd_eccbytes() helper functions have
been added to avoid direct accesses to the ecclayout, and thus allow for
future rework.
Use these helpers in all places where the oobfree[] and eccpos[] arrays
are referenced.

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
 drivers/mtd/mtdchar.c                  | 79 ++++++++++++++++++++++++--------
 drivers/mtd/mtdswap.c                  |  4 +-
 drivers/mtd/nand/atmel_nand.c          | 21 ++++-----
 drivers/mtd/nand/fsl_ifc_nand.c        |  2 +-
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |  9 ++--
 drivers/mtd/nand/lpc32xx_slc.c         |  4 +-
 drivers/mtd/nand/nand_base.c           | 83 ++++++++++++++++++----------------
 drivers/mtd/nand/nand_bch.c            |  2 +-
 drivers/mtd/nand/omap2.c               | 11 ++---
 drivers/mtd/onenand/onenand_base.c     | 61 +++++++++++++------------
 10 files changed, 163 insertions(+), 113 deletions(-)

diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 6d19835..66d0898 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -472,31 +472,78 @@ static int mtdchar_readoob(struct file *file, struct mtd_info *mtd,
  * nand_ecclayout flexibly (i.e. the struct may change size in new
  * releases without requiring major rewrites).
  */
-static int shrink_ecclayout(const struct nand_ecclayout *from,
-		struct nand_ecclayout_user *to)
+static int shrink_ecclayout(struct mtd_info *mtd,
+			    struct nand_ecclayout_user *to)
 {
 	int i;
 
-	if (!from || !to)
+	if (!mtd || !to)
 		return -EINVAL;
 
 	memset(to, 0, sizeof(*to));
 
-	to->eccbytes = min((int)from->eccbytes, MTD_MAX_ECCPOS_ENTRIES);
-	for (i = 0; i < to->eccbytes; i++)
-		to->eccpos[i] = from->eccpos[i];
+	to->eccbytes = 0;
+	for (i = 0; i < MTD_MAX_ECCPOS_ENTRIES; i++) {
+		int pos = mtd_eccpos(mtd, i);
+
+		if (pos < 0)
+			break;
+
+		to->eccpos[i] = pos;
+		to->eccbytes++;
+	}
 
 	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) {
-		if (from->oobfree[i].length == 0 &&
-				from->oobfree[i].offset == 0)
+		mtd_oobfree(mtd, i, &to->oobfree[i]);
+		if (to->oobfree[i].length == 0 &&
+		    to->oobfree[i].offset == 0)
 			break;
-		to->oobavail += from->oobfree[i].length;
-		to->oobfree[i] = from->oobfree[i];
+		to->oobavail += to->oobfree[i].length;
 	}
 
 	return 0;
 }
 
+static int get_oobinfo(struct mtd_info *mtd, struct nand_oobinfo *to)
+{
+	int i;
+
+	if (!mtd || !to)
+		return -EINVAL;
+
+	memset(to, 0, sizeof(*to));
+
+	to->eccbytes = 0;
+	for (i = 0; i < ARRAY_SIZE(to->eccpos); i++) {
+		int pos = mtd_eccpos(mtd, i);
+
+		if (pos < 0)
+			break;
+
+		to->eccpos[i] = pos;
+		to->eccbytes++;
+	}
+
+	if (i == ARRAY_SIZE(to->eccpos))
+		return -EINVAL;
+
+	for (i = 0; i < 8; i++) {
+		struct nand_oobfree oobfree;
+
+		mtd_oobfree(mtd, i, &oobfree);
+		if (oobfree.length == 0 &&
+		    oobfree.offset == 0)
+			break;
+
+		to->oobfree[i][0] = oobfree.offset;
+		to->oobfree[i][1] = oobfree.length;
+	}
+
+	to->useecc = MTD_NANDECC_AUTOPLACE;
+
+	return 0;
+}
+
 static int mtdchar_blkpg_ioctl(struct mtd_info *mtd,
 			       struct blkpg_ioctl_arg *arg)
 {
@@ -817,14 +864,10 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 
 		if (!mtd->ecclayout)
 			return -EOPNOTSUPP;
-		if (mtd->ecclayout->eccbytes > ARRAY_SIZE(oi.eccpos))
-			return -EINVAL;
 
-		oi.useecc = MTD_NANDECC_AUTOPLACE;
-		memcpy(&oi.eccpos, mtd->ecclayout->eccpos, sizeof(oi.eccpos));
-		memcpy(&oi.oobfree, mtd->ecclayout->oobfree,
-		       sizeof(oi.oobfree));
-		oi.eccbytes = mtd->ecclayout->eccbytes;
+		ret = get_oobinfo(mtd, &oi);
+		if (ret)
+			return ret;
 
 		if (copy_to_user(argp, &oi, sizeof(struct nand_oobinfo)))
 			return -EFAULT;
@@ -920,7 +963,7 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 		if (!usrlay)
 			return -ENOMEM;
 
-		shrink_ecclayout(mtd->ecclayout, usrlay);
+		shrink_ecclayout(mtd, usrlay);
 
 		if (copy_to_user(argp, usrlay, sizeof(*usrlay)))
 			ret = -EFAULT;
diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c
index d330eb1..6fe47b0 100644
--- a/drivers/mtd/mtdswap.c
+++ b/drivers/mtd/mtdswap.c
@@ -1417,7 +1417,6 @@ static void mtdswap_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
 	unsigned long part;
 	unsigned int eblocks, eavailable, bad_blocks, spare_cnt;
 	uint64_t swap_size, use_size, size_limit;
-	struct nand_ecclayout *oinfo;
 	int ret;
 
 	parts = &partitions[0];
@@ -1447,8 +1446,7 @@ static void mtdswap_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
 		return;
 	}
 
-	oinfo = mtd->ecclayout;
-	if (!oinfo) {
+	if (mtd_oobfree(mtd, 0) < 0) {
 		printk(KERN_ERR "%s: mtd%d does not have OOB\n",
 			MTDSWAP_PREFIX, mtd->index);
 		return;
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index f4e1f91..da16b1a 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -833,7 +833,7 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc,
 			err_byte = ecc[tmp];
 			ecc[tmp] ^= (1 << bit_pos);
 
-			pos = tmp + nand_chip->ecc.layout->eccpos[0];
+			pos = tmp + mtd_eccpos(mtd, 0);
 			dev_info(host->dev, "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
 				pos, bit_pos, err_byte, ecc[tmp]);
 		}
@@ -922,7 +922,6 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
 	struct atmel_nand_host *host = chip->priv;
 	int eccsize = chip->ecc.size * chip->ecc.steps;
 	uint8_t *oob = chip->oob_poi;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	uint32_t stat;
 	unsigned long end_time;
 	int bitflips = 0;
@@ -944,7 +943,8 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
 
 	stat = pmecc_readl_relaxed(host->ecc, ISR);
 	if (stat != 0) {
-		bitflips = pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]);
+		bitflips = pmecc_correction(mtd, stat, buf,
+					    &oob[mtd_eccpos(mtd, 0)]);
 		if (bitflips < 0)
 			/* uncorrectable errors */
 			return 0;
@@ -958,7 +958,6 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
 		int page)
 {
 	struct atmel_nand_host *host = chip->priv;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	int i, j;
 	unsigned long end_time;
 
@@ -981,7 +980,7 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
 			int pos;
 
 			pos = i * chip->ecc.bytes + j;
-			chip->oob_poi[eccpos[pos]] =
+			chip->oob_poi[mtd_eccpos(mtd, pos)] =
 				pmecc_readb_ecc_relaxed(host->ecc, i, j);
 		}
 	}
@@ -1044,9 +1043,9 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
 
 	ecc_layout = nand_chip->ecc.layout;
 	pmecc_writel(host->ecc, SAREA, mtd->oobsize - 1);
-	pmecc_writel(host->ecc, SADDR, ecc_layout->eccpos[0]);
+	pmecc_writel(host->ecc, SADDR, mtd_eccpos(mtd, 0));
 	pmecc_writel(host->ecc, EADDR,
-			ecc_layout->eccpos[ecc_layout->eccbytes - 1]);
+			mtd_eccpos(mtd, ecc_layout->eccbytes - 1));
 	/* See datasheet about PMECC Clock Control Register */
 	pmecc_writel(host->ecc, CLK, 2);
 	pmecc_writel(host->ecc, IDR, 0xff);
@@ -1340,7 +1339,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 {
 	int eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	int eccpos = mtd_eccpos(mtd, 0);
 	uint8_t *p = buf;
 	uint8_t *oob = chip->oob_poi;
 	uint8_t *ecc_pos;
@@ -1363,7 +1362,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 	chip->read_buf(mtd, p, eccsize);
 
 	/* move to ECC position if needed */
-	if (eccpos[0] != 0) {
+	if (eccpos != 0) {
 		/* This only works on large pages
 		 * because the ECC controller waits for
 		 * NAND_CMD_RNDOUTSTART after the
@@ -1371,11 +1370,11 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 		 * anyway, for small pages, the eccpos[0] == 0
 		 */
 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
-				mtd->writesize + eccpos[0], -1);
+				mtd->writesize + eccpos, -1);
 	}
 
 	/* the ECC controller needs to read the ECC just after the data */
-	ecc_pos = oob + eccpos[0];
+	ecc_pos = oob + eccpos;
 	chip->read_buf(mtd, ecc_pos, eccbytes);
 
 	/* check if there's an error */
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index f260831..610308e 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -266,7 +266,7 @@ static int is_blank(struct mtd_info *mtd, unsigned int bufnum)
 	}
 
 	for (i = 0; i < chip->ecc.layout->eccbytes; i++) {
-		int pos = chip->ecc.layout->eccpos[i];
+		int pos = mtd_eccpos(mtd, i);
 
 		if (__raw_readb(&oob[pos]) != 0xff)
 			return 0;
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 5a9b696..c208f5e 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1325,18 +1325,19 @@ static int gpmi_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 static int
 gpmi_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *chip, int page)
 {
-	struct nand_oobfree *of = mtd->ecclayout->oobfree;
+	struct nand_oobfree of = { };
 	int status = 0;
 
 	/* Do we have available oob area? */
-	if (!of->length)
+	mtd_oobfree(mtd, 0, &of);
+	if (!of.length)
 		return -EPERM;
 
 	if (!nand_is_slc(chip))
 		return -EPERM;
 
-	chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize + of->offset, page);
-	chip->write_buf(mtd, chip->oob_poi + of->offset, of->length);
+	chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize + of.offset, page);
+	chip->write_buf(mtd, chip->oob_poi + of.offset, of.length);
 	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
 
 	status = chip->waitfunc(mtd, chip);
diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c
index 277626e..47dcfddd 100644
--- a/drivers/mtd/nand/lpc32xx_slc.c
+++ b/drivers/mtd/nand/lpc32xx_slc.c
@@ -621,7 +621,7 @@ static int lpc32xx_nand_read_page_syndrome(struct mtd_info *mtd,
 	lpc32xx_slc_ecc_copy(tmpecc, (uint32_t *) host->ecc_buf, chip->ecc.steps);
 
 	/* Pointer to ECC data retrieved from NAND spare area */
-	oobecc = chip->oob_poi + chip->ecc.layout->eccpos[0];
+	oobecc = chip->oob_poi + mtd_eccpos(mtd, 0);
 
 	for (i = 0; i < chip->ecc.steps; i++) {
 		stat = chip->ecc.correct(mtd, buf, oobecc,
@@ -667,7 +667,7 @@ static int lpc32xx_nand_write_page_syndrome(struct mtd_info *mtd,
 					    int oob_required, int page)
 {
 	struct lpc32xx_nand_host *host = chip->priv;
-	uint8_t *pb = chip->oob_poi + chip->ecc.layout->eccpos[0];
+	uint8_t *pb = chip->oob_poi + mtd_eccpos(mtd, 0);
 	int error;
 
 	/* Write data, calculate ECC on outbound data */
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index b99b442..30a0721 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1315,7 +1315,6 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 	uint8_t *p = buf;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	uint8_t *ecc_code = chip->buffers->ecccode;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	unsigned int max_bitflips = 0;
 
 	chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
@@ -1324,7 +1323,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		ecc_code[i] = chip->oob_poi[eccpos[i]];
+		ecc_code[i] = chip->oob_poi[mtd_eccpos(mtd, i)];
 
 	eccsteps = chip->ecc.steps;
 	p = buf;
@@ -1357,7 +1356,6 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 			int page)
 {
 	int start_step, end_step, num_steps;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	uint8_t *p;
 	int data_col_addr, i, gaps = 0;
 	int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
@@ -1392,7 +1390,8 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 	 * ecc.pos. Let's make sure that there are no gaps in ECC positions.
 	 */
 	for (i = 0; i < eccfrag_len - 1; i++) {
-		if (eccpos[i + index] + 1 != eccpos[i + index + 1]) {
+		if (mtd_eccpos(mtd, i + index) + 1 !=
+		    mtd_eccpos(mtd, i + index + 1)) {
 			gaps = 1;
 			break;
 		}
@@ -1405,11 +1404,12 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 		 * Send the command to read the particular ECC bytes take care
 		 * about buswidth alignment in read_buf.
 		 */
-		aligned_pos = eccpos[index] & ~(busw - 1);
+		aligned_pos = mtd_eccpos(mtd, index) & ~(busw - 1);
 		aligned_len = eccfrag_len;
-		if (eccpos[index] & (busw - 1))
+		if (mtd_eccpos(mtd, index) & (busw - 1))
 			aligned_len++;
-		if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1))
+		if (mtd_eccpos(mtd, index + (num_steps * chip->ecc.bytes)) &
+		    (busw - 1))
 			aligned_len++;
 
 		chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
@@ -1418,7 +1418,8 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 	}
 
 	for (i = 0; i < eccfrag_len; i++)
-		chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + index]];
+		chip->buffers->ecccode[i] =
+				chip->oob_poi[mtd_eccpos(mtd, i + index)];
 
 	p = bufpoi + data_col_addr;
 	for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) {
@@ -1455,7 +1456,6 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	uint8_t *p = buf;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	uint8_t *ecc_code = chip->buffers->ecccode;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	unsigned int max_bitflips = 0;
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
@@ -1466,7 +1466,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		ecc_code[i] = chip->oob_poi[eccpos[i]];
+		ecc_code[i] = chip->oob_poi[mtd_eccpos(mtd, i)];
 
 	eccsteps = chip->ecc.steps;
 	p = buf;
@@ -1507,7 +1507,6 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 	int eccsteps = chip->ecc.steps;
 	uint8_t *p = buf;
 	uint8_t *ecc_code = chip->buffers->ecccode;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	unsigned int max_bitflips = 0;
 
@@ -1517,7 +1516,7 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
 	chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		ecc_code[i] = chip->oob_poi[eccpos[i]];
+		ecc_code[i] = chip->oob_poi[mtd_eccpos(mtd, i)];
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
 		int stat;
@@ -1603,9 +1602,11 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
  * @ops: oob ops structure
  * @len: size of oob to transfer
  */
-static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
+static uint8_t *nand_transfer_oob(struct mtd_info *mtd, uint8_t *oob,
 				  struct mtd_oob_ops *ops, size_t len)
 {
+	struct nand_chip *chip = mtd->priv;
+
 	switch (ops->mode) {
 
 	case MTD_OPS_PLACE_OOB:
@@ -1614,24 +1615,26 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
 		return oob + len;
 
 	case MTD_OPS_AUTO_OOB: {
-		struct nand_oobfree *free = chip->ecc.layout->oobfree;
+		struct nand_oobfree free = { };
 		uint32_t boffs = 0, roffs = ops->ooboffs;
 		size_t bytes = 0;
+		int i = 0;
 
-		for (; free->length && len; free++, len -= bytes) {
+		for (mtd_oobfree(mtd, i++, &free); free.length && len;
+		     mtd_oobfree(mtd, i++, &free), len -= bytes) {
 			/* Read request not from offset 0? */
 			if (unlikely(roffs)) {
-				if (roffs >= free->length) {
-					roffs -= free->length;
+				if (roffs >= free.length) {
+					roffs -= free.length;
 					continue;
 				}
-				boffs = free->offset + roffs;
+				boffs = free.offset + roffs;
 				bytes = min_t(size_t, len,
-					      (free->length - roffs));
+					      (free.length - roffs));
 				roffs = 0;
 			} else {
-				bytes = min_t(size_t, len, free->length);
-				boffs = free->offset;
+				bytes = min_t(size_t, len, free.length);
+				boffs = free.offset;
 			}
 			memcpy(oob, chip->oob_poi + boffs, bytes);
 			oob += bytes;
@@ -1772,7 +1775,7 @@ read_retry:
 				int toread = min(oobreadlen, max_oobsize);
 
 				if (toread) {
-					oob = nand_transfer_oob(chip,
+					oob = nand_transfer_oob(mtd,
 						oob, ops, toread);
 					oobreadlen -= toread;
 				}
@@ -2073,7 +2076,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 			break;
 
 		len = min(len, readlen);
-		buf = nand_transfer_oob(chip, buf, ops, len);
+		buf = nand_transfer_oob(mtd, buf, ops, len);
 
 		if (chip->options & NAND_NEED_READRDY) {
 			/* Apply delay or wait for ready/busy pin */
@@ -2237,14 +2240,13 @@ static int nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 	int eccsteps = chip->ecc.steps;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	const uint8_t *p = buf;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 
 	/* Software ECC calculation */
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
 		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+		chip->oob_poi[mtd_eccpos(mtd, i)] = ecc_calc[i];
 
 	return chip->ecc.write_page_raw(mtd, chip, buf, 1, page);
 }
@@ -2266,7 +2268,6 @@ static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	int eccsteps = chip->ecc.steps;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	const uint8_t *p = buf;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 
 	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
 		chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
@@ -2275,7 +2276,7 @@ static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 	}
 
 	for (i = 0; i < chip->ecc.total; i++)
-		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+		chip->oob_poi[mtd_eccpos(mtd, i)] = ecc_calc[i];
 
 	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
 
@@ -2303,7 +2304,6 @@ static int nand_write_subpage_hwecc(struct mtd_info *mtd,
 	int ecc_size      = chip->ecc.size;
 	int ecc_bytes     = chip->ecc.bytes;
 	int ecc_steps     = chip->ecc.steps;
-	uint32_t *eccpos  = chip->ecc.layout->eccpos;
 	uint32_t start_step = offset / ecc_size;
 	uint32_t end_step   = (offset + data_len - 1) / ecc_size;
 	int oob_bytes       = mtd->oobsize / ecc_steps;
@@ -2336,7 +2336,7 @@ static int nand_write_subpage_hwecc(struct mtd_info *mtd,
 	/* this include masked-value(0xFF) for unwritten subpages */
 	ecc_calc = chip->buffers->ecccalc;
 	for (i = 0; i < chip->ecc.total; i++)
-		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+		chip->oob_poi[mtd_eccpos(mtd, i)] = ecc_calc[i];
 
 	/* write OOB buffer to NAND device */
 	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -2488,24 +2488,26 @@ static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
 		return oob + len;
 
 	case MTD_OPS_AUTO_OOB: {
-		struct nand_oobfree *free = chip->ecc.layout->oobfree;
+		struct nand_oobfree free = { };
 		uint32_t boffs = 0, woffs = ops->ooboffs;
 		size_t bytes = 0;
+		int i = 0;
 
-		for (; free->length && len; free++, len -= bytes) {
+		for (mtd_oobfree(mtd, i++, &free); free.length && len;
+		     mtd_oobfree(mtd, i++, &free), len -= bytes) {
 			/* Write request not from offset 0? */
 			if (unlikely(woffs)) {
-				if (woffs >= free->length) {
-					woffs -= free->length;
+				if (woffs >= free.length) {
+					woffs -= free.length;
 					continue;
 				}
-				boffs = free->offset + woffs;
+				boffs = free.offset + woffs;
 				bytes = min_t(size_t, len,
-					      (free->length - woffs));
+					      (free.length - woffs));
 				woffs = 0;
 			} else {
-				bytes = min_t(size_t, len, free->length);
-				boffs = free->offset;
+				bytes = min_t(size_t, len, free.length);
+				boffs = free.offset;
 			}
 			memcpy(chip->oob_poi + boffs, oob, bytes);
 			oob += bytes;
@@ -4087,6 +4089,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 	int i;
 	struct nand_chip *chip = mtd->priv;
 	struct nand_ecc_ctrl *ecc = &chip->ecc;
+	struct nand_oobfree oobfree = { };
 	struct nand_buffers *nbuf;
 
 	/* New bad blocks should be marked in OOB, flash-based BBT, or both */
@@ -4284,8 +4287,10 @@ int nand_scan_tail(struct mtd_info *mtd)
 	 * the out of band area.
 	 */
 	mtd->oobavail = 0;
-	for (i = 0; ecc->layout->oobfree[i].length; i++)
-		mtd->oobavail += ecc->layout->oobfree[i].length;
+	i = 0;
+	for (mtd_oobfree(mtd, i++, &oobfree); oobfree.length;
+	     mtd_oobfree(mtd, i++, &oobfree))
+		mtd->oobavail += oobfree.length;
 
 	/* ECC sanity check: warn if it's too weak */
 	if (!nand_ecc_strength_good(mtd))
diff --git a/drivers/mtd/nand/nand_bch.c b/drivers/mtd/nand/nand_bch.c
index 3456c20..9cff544 100644
--- a/drivers/mtd/nand/nand_bch.c
+++ b/drivers/mtd/nand/nand_bch.c
@@ -196,7 +196,7 @@ struct nand_bch_control *nand_bch_init(struct mtd_info *mtd)
 		printk(KERN_WARNING "eccsize %u is too large\n", eccsize);
 		goto fail;
 	}
-	if (layout->eccbytes != (eccsteps*eccbytes)) {
+	if (mtd_eccbytes(mtd) != (eccsteps*eccbytes)) {
 		printk(KERN_WARNING "invalid ecc layout\n");
 		goto fail;
 	}
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index a2f015d..6a598b1 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1509,7 +1509,6 @@ static int omap_write_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 {
 	int i;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
 
 	/* Enable GPMC ecc engine */
 	chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
@@ -1521,7 +1520,7 @@ static int omap_write_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 	chip->ecc.calculate(mtd, buf, &ecc_calc[0]);
 
 	for (i = 0; i < chip->ecc.total; i++)
-		chip->oob_poi[eccpos[i]] = ecc_calc[i];
+		chip->oob_poi[mtd_eccpos(mtd, i)] = ecc_calc[i];
 
 	/* Write ecc vector to OOB area */
 	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -1548,9 +1547,9 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 {
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
 	uint8_t *ecc_code = chip->buffers->ecccode;
-	uint32_t *eccpos = chip->ecc.layout->eccpos;
-	uint8_t *oob = &chip->oob_poi[eccpos[0]];
-	uint32_t oob_pos = mtd->writesize + chip->ecc.layout->eccpos[0];
+	int ecc0pos = mtd_eccpos(mtd, 0);
+	uint8_t *oob = &chip->oob_poi[ecc0pos];
+	uint32_t oob_pos = mtd->writesize + ecc0pos;
 	int stat;
 	unsigned int max_bitflips = 0;
 
@@ -1567,7 +1566,7 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 	/* Calculate ecc bytes */
 	chip->ecc.calculate(mtd, buf, ecc_calc);
 
-	memcpy(ecc_code, &chip->oob_poi[eccpos[0]], chip->ecc.total);
+	memcpy(ecc_code, &chip->oob_poi[ecc0pos], chip->ecc.total);
 
 	stat = chip->ecc.correct(mtd, buf, ecc_code, ecc_calc);
 
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index d70bbfd..25e6bf2 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1024,27 +1024,29 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
 				int thislen)
 {
 	struct onenand_chip *this = mtd->priv;
-	struct nand_oobfree *free;
+	struct nand_oobfree free = { };
 	int readcol = column;
 	int readend = column + thislen;
 	int lastgap = 0;
-	unsigned int i;
+	unsigned int i = 0;
 	uint8_t *oob_buf = this->oob_buf;
 
-	free = this->ecclayout->oobfree;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
+	for (mtd_oobfree(mtd, i++, &free); free.length;
+	     mtd_oobfree(mtd, i++, &free)) {
 		if (readcol >= lastgap)
-			readcol += free->offset - lastgap;
+			readcol += free.offset - lastgap;
 		if (readend >= lastgap)
-			readend += free->offset - lastgap;
-		lastgap = free->offset + free->length;
+			readend += free.offset - lastgap;
+		lastgap = free.offset + free.length;
 	}
 	this->read_bufferram(mtd, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);
-	free = this->ecclayout->oobfree;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
-		int free_end = free->offset + free->length;
-		if (free->offset < readend && free_end > readcol) {
-			int st = max_t(int,free->offset,readcol);
+	memset(&free, 0, sizeof(free));
+	i = 0;
+	for (mtd_oobfree(mtd, i++, &free); free.length;
+	     mtd_oobfree(mtd, i++, &free)) {
+		int free_end = free.offset + free.length;
+		if (free.offset < readend && free_end > readcol) {
+			int st = max_t(int,free.offset,readcol);
 			int ed = min_t(int,free_end,readend);
 			int n = ed - st;
 			memcpy(buf, oob_buf + st, n);
@@ -1816,26 +1818,27 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
 static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
 				  const u_char *buf, int column, int thislen)
 {
-	struct onenand_chip *this = mtd->priv;
-	struct nand_oobfree *free;
+	struct nand_oobfree free = { };
 	int writecol = column;
 	int writeend = column + thislen;
 	int lastgap = 0;
-	unsigned int i;
+	unsigned int i = 0;
 
-	free = this->ecclayout->oobfree;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
+	for (mtd_oobfree(mtd, i++, &free); free.length;
+	     mtd_oobfree(mtd, i++, &free)) {
 		if (writecol >= lastgap)
-			writecol += free->offset - lastgap;
+			writecol += free.offset - lastgap;
 		if (writeend >= lastgap)
-			writeend += free->offset - lastgap;
-		lastgap = free->offset + free->length;
+			writeend += free.offset - lastgap;
+		lastgap = free.offset + free.length;
 	}
-	free = this->ecclayout->oobfree;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) {
-		int free_end = free->offset + free->length;
-		if (free->offset < writeend && free_end > writecol) {
-			int st = max_t(int,free->offset,writecol);
+	memset(&free, 0, sizeof(free));
+	i = 0;
+	for (mtd_oobfree(mtd, i++, &free); free.length;
+	     mtd_oobfree(mtd, i++, &free)) {
+		int free_end = free.offset + free.length;
+		if (free.offset < writeend && free_end > writecol) {
+			int st = max_t(int,free.offset,writecol);
 			int ed = min_t(int,free_end,writeend);
 			int n = ed - st;
 			memcpy(oob_buf + st, buf, n);
@@ -3942,6 +3945,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 {
 	int i, ret;
 	struct onenand_chip *this = mtd->priv;
+	struct nand_oobfree oobfree = {};
 
 	if (!this->read_word)
 		this->read_word = onenand_readw;
@@ -4050,9 +4054,10 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 	 * the out of band area
 	 */
 	mtd->oobavail = 0;
-	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES &&
-	    this->ecclayout->oobfree[i].length; i++)
-		mtd->oobavail += this->ecclayout->oobfree[i].length;
+	i = 0;
+	for (mtd_oobfree(mtd, i++, &oobfree); oobfree.length;
+	     mtd_oobfree(mtd, i++, &oobfree))
+		mtd->oobavail += oobfree.length;
 
 	mtd->ecclayout = this->ecclayout;
 	mtd->ecc_strength = 1;
-- 
2.1.4

  parent reply	other threads:[~2015-12-07 22:27 UTC|newest]

Thread overview: 113+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-07 22:25 [PATCH 00/23] mtd: rework ECC layout definition Boris Brezillon
2015-12-07 22:25 ` Boris Brezillon
2015-12-07 22:25 ` Boris Brezillon
2015-12-07 22:25 ` [PATCH 01/23] mtd: kill the ecclayout->oobavail field Boris Brezillon
2015-12-07 22:25   ` Boris Brezillon
2015-12-07 22:25   ` Boris Brezillon
2015-12-08  6:43   ` [linux-sunxi] " Priit Laes
2015-12-08  6:43     ` Priit Laes
2015-12-08  6:43     ` Priit Laes
2015-12-08  8:14     ` Boris Brezillon
2015-12-08  8:14       ` Boris Brezillon
2015-12-08  8:14       ` Boris Brezillon
2015-12-07 22:25 ` [PATCH 02/23] mtd: inftl: kill unused oobinfo field Boris Brezillon
2015-12-07 22:25   ` Boris Brezillon
2015-12-07 22:25   ` Boris Brezillon
2015-12-07 22:25 ` [PATCH 03/23] mtd: nftl: " Boris Brezillon
2015-12-07 22:25   ` Boris Brezillon
2015-12-07 22:25   ` Boris Brezillon
2015-12-07 22:25 ` [PATCH 04/23] mtd: nand: s3c2410: kill the ->ecc_layout field Boris Brezillon
2015-12-07 22:25   ` Boris Brezillon
2015-12-07 22:25   ` Boris Brezillon
2015-12-08  0:38   ` Krzysztof Kozlowski
2015-12-08  0:38     ` Krzysztof Kozlowski
2015-12-08  0:38     ` Krzysztof Kozlowski
2015-12-07 22:26 ` [PATCH 05/23] mtd: nand: jz4770: " Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-08 10:30   ` Harvey Hunt
2015-12-08 10:30     ` Harvey Hunt
2015-12-08 10:30     ` Harvey Hunt
2015-12-08 10:33     ` Boris Brezillon
2015-12-08 10:33       ` Boris Brezillon
2015-12-08 10:33       ` Boris Brezillon
2015-12-08 10:33       ` Boris Brezillon
2015-12-07 22:26 ` [PATCH 06/23] mtd: nand: kill unused ->ecclayout field in platform_nand_chip struct Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26 ` [PATCH 07/23] staging: mt29f_spinand: kill unused ecclayout field Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26 ` [PATCH 08/23] mtd: nand: lpc32xx_mlc: fix ecc.size Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26 ` [PATCH 09/23] mtd: nand: vf610: remove useless mtd->ecclayout assignment Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:42   ` Stefan Agner
2015-12-07 22:42     ` Stefan Agner
2015-12-07 22:26 ` [PATCH 10/23] mtd: nand: simplify nand_bch_init() usage Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26 ` [PATCH 11/23] mtd: add mtd_eccpos(), mtd_oobfree() and mtd_eccbytes() helper functions Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26 ` Boris Brezillon [this message]
2015-12-07 22:26   ` [PATCH 12/23] mtd: use mtd_eccpos() and mtd_oobfree() where appropriate Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:48   ` kbuild test robot
2015-12-07 22:48     ` kbuild test robot
2015-12-07 22:48     ` kbuild test robot
2015-12-07 22:48     ` kbuild test robot
2015-12-07 23:36   ` kbuild test robot
2015-12-07 23:36     ` kbuild test robot
2015-12-07 23:36     ` kbuild test robot
2015-12-07 23:36     ` kbuild test robot
2015-12-07 22:26 ` [PATCH 13/23] mtd: add mtd_set_ecclayout() helper function Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26 ` [PATCH 14/23] mtd: use mtd_set_ecclayout() where appropriate Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26 ` [PATCH 15/23] mtd: create an mtd_ooblayout_ops struct to ease ECC layout definition Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26 ` [PATCH 16/23] mtd: docg3: switch to mtd_ooblayout_ops Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26 ` [PATCH 17/23] mtd: nand: implement the default mtd_ooblayout_ops Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26 ` [PATCH 18/23] mtd: nand: bch: switch to nand_ecclayout_pos Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26 ` [PATCH 19/23] mtd: nand: switch all drivers to mtd_ooblayout_ops Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-08 10:11   ` Ralf Baechle
2015-12-08 10:11     ` Ralf Baechle
2015-12-08 10:11     ` Ralf Baechle
2015-12-07 22:26 ` [PATCH 20/23] mtd: onenand: switch " Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26 ` [PATCH 21/23] staging: mt29f_spinand: " Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 23:59   ` [linux-sunxi] " Julian Calaby
2015-12-07 23:59     ` Julian Calaby
2015-12-07 23:59     ` Julian Calaby
2015-12-08  8:43     ` [linux-sunxi] " Boris Brezillon
2015-12-08  8:43       ` Boris Brezillon
2015-12-08  8:43       ` Boris Brezillon
2015-12-07 22:26 ` [PATCH 22/23] mtd: nand: kill layout field Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 23:00   ` kbuild test robot
2015-12-07 23:00     ` kbuild test robot
2015-12-07 23:00     ` kbuild test robot
2015-12-07 23:00     ` kbuild test robot
2015-12-07 22:26 ` [PATCH 23/23] mtd: kill the nand_ecclayout struct Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2015-12-07 22:26   ` Boris Brezillon
2016-01-26 19:26 ` [PATCH 00/23] mtd: rework ECC layout definition Brian Norris
2016-01-26 19:26   ` Brian Norris
2016-01-26 19:26   ` Brian Norris

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=1449527178-5930-13-git-send-email-boris.brezillon@free-electrons.com \
    --to=boris.brezillon@free-electrons.com \
    --cc=computersforpeace@gmail.com \
    --cc=daniel@zonque.org \
    --cc=devel@driverdev.osuosl.org \
    --cc=dwmw2@infradead.org \
    --cc=ezequiel.garcia@free-electrons.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=haojian.zhuang@gmail.com \
    --cc=josh.wu@atmel.com \
    --cc=k.kozlowski@samsung.com \
    --cc=kgene@kernel.org \
    --cc=kyungmin.park@samsung.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@linux-mips.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=linux-sunxi@googlegroups.com \
    --cc=maxime.ripard@free-electrons.com \
    --cc=punnaia@xilinx.com \
    --cc=ralf@linux-mips.org \
    --cc=robert.jarzmik@free.fr \
    --cc=stefan@agner.ch \
    --cc=wens@csie.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 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.