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.brezil...@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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to