mtd: rawnand: Deprecate ->block_{bad,markbad}() hooks
authorBoris Brezillon <boris.brezillon@bootlin.com>
Thu, 6 Sep 2018 22:38:38 +0000 (00:38 +0200)
committerMiquel Raynal <miquel.raynal@bootlin.com>
Wed, 3 Oct 2018 09:12:25 +0000 (11:12 +0200)
Those hooks have been overloaded by some drivers for bad reasons:
either the driver was not fitting in the NAND framework and should
have been an MTD driver (docg4), or it was not properly implementing
the OOB read/write request or had a weird layout where BBM are trashed.
In any case, we should discourage people from overloading those
methods and encourage them to fix their driver instead.

Move the ->block_{bad,markbad}() hooks to the nand_legacy struct to
make it clear.

Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
drivers/mtd/nand/raw/cafe_nand.c
drivers/mtd/nand/raw/diskonchip.c
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
drivers/mtd/nand/raw/nand_base.c
drivers/mtd/nand/raw/nand_bbt.c
drivers/mtd/nand/raw/qcom_nandc.c
drivers/mtd/nand/raw/sm_common.c
include/linux/mtd/rawnand.h

index 738af0f..db62b12 100644 (file)
@@ -719,7 +719,7 @@ static int cafe_nand_probe(struct pci_dev *pdev,
 
        if (skipbbt) {
                cafe->nand.options |= NAND_SKIP_BBTSCAN;
-               cafe->nand.block_bad = cafe_nand_block_bad;
+               cafe->nand.legacy.block_bad = cafe_nand_block_bad;
        }
 
        if (numtimings && numtimings != 3) {
index c3a7936..16fdfd0 100644 (file)
@@ -1572,7 +1572,7 @@ static int __init doc_probe(unsigned long physadr)
        nand->legacy.cmd_ctrl           = doc200x_hwcontrol;
        nand->legacy.dev_ready  = doc200x_dev_ready;
        nand->legacy.waitfunc   = doc200x_wait;
-       nand->block_bad         = doc200x_block_bad;
+       nand->legacy.block_bad  = doc200x_block_bad;
        nand->ecc.hwctl         = doc200x_enable_hwecc;
        nand->ecc.calculate     = doc200x_calculate_ecc;
        nand->ecc.correct       = doc200x_correct_data;
index dc62919..94c2b75 100644 (file)
@@ -1774,7 +1774,7 @@ static int mx23_boot_init(struct gpmi_nand_data  *this)
                 */
                if (block_mark != 0xff) {
                        dev_dbg(dev, "Transcribing mark in block %u\n", block);
-                       ret = chip->block_markbad(chip, byte);
+                       ret = chip->legacy.block_markbad(chip, byte);
                        if (ret)
                                dev_err(dev,
                                        "Failed to mark block bad with ret %d\n",
@@ -1908,7 +1908,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this)
        chip->legacy.read_buf   = gpmi_read_buf;
        chip->legacy.write_buf  = gpmi_write_buf;
        chip->badblock_pattern  = &gpmi_bbt_descr;
-       chip->block_markbad     = gpmi_block_markbad;
+       chip->legacy.block_markbad = gpmi_block_markbad;
        chip->options           |= NAND_NO_SUBPAGE_WRITE;
 
        /* Set up swap_block_mark, must be set before the gpmi_set_geometry() */
index 30b55a4..d71a3d3 100644 (file)
@@ -476,13 +476,34 @@ static int nand_default_block_markbad(struct nand_chip *chip, loff_t ofs)
 }
 
 /**
+ * nand_markbad_bbm - mark a block by updating the BBM
+ * @chip: NAND chip object
+ * @ofs: offset of the block to mark bad
+ */
+int nand_markbad_bbm(struct nand_chip *chip, loff_t ofs)
+{
+       if (chip->legacy.block_markbad)
+               return chip->legacy.block_markbad(chip, ofs);
+
+       return nand_default_block_markbad(chip, ofs);
+}
+
+static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs)
+{
+       if (chip->legacy.block_bad)
+               return chip->legacy.block_bad(chip, ofs);
+
+       return nand_block_bad(chip, ofs);
+}
+
+/**
  * nand_block_markbad_lowlevel - mark a block bad
  * @mtd: MTD device structure
  * @ofs: offset from device start
  *
  * This function performs the generic NAND bad block marking steps (i.e., bad
  * block table(s) and/or marker(s)). We only allow the hardware driver to
- * specify how to write bad block markers to OOB (chip->block_markbad).
+ * specify how to write bad block markers to OOB (chip->legacy.block_markbad).
  *
  * We try operations in the following order:
  *
@@ -510,7 +531,7 @@ static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs)
 
                /* Write bad block marker to OOB */
                nand_get_device(mtd, FL_WRITING);
-               ret = chip->block_markbad(chip, ofs);
+               ret = nand_markbad_bbm(chip, ofs);
                nand_release_device(mtd);
        }
 
@@ -582,11 +603,11 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int allowbbt)
 {
        struct nand_chip *chip = mtd_to_nand(mtd);
 
-       if (!chip->bbt)
-               return chip->block_bad(chip, ofs);
-
        /* Return info from the table */
-       return nand_isbad_bbt(chip, ofs, allowbbt);
+       if (chip->bbt)
+               return nand_isbad_bbt(chip, ofs, allowbbt);
+
+       return nand_isbad_bbm(chip, ofs);
 }
 
 /**
@@ -4942,10 +4963,6 @@ static void nand_set_defaults(struct nand_chip *chip)
        /* If called twice, pointers that depend on busw may need to be reset */
        if (!chip->legacy.read_byte || chip->legacy.read_byte == nand_read_byte)
                chip->legacy.read_byte = busw ? nand_read_byte16 : nand_read_byte;
-       if (!chip->block_bad)
-               chip->block_bad = nand_block_bad;
-       if (!chip->block_markbad)
-               chip->block_markbad = nand_default_block_markbad;
        if (!chip->legacy.write_buf || chip->legacy.write_buf == nand_write_buf)
                chip->legacy.write_buf = busw ? nand_write_buf16 : nand_write_buf;
        if (!chip->legacy.write_byte || chip->legacy.write_byte == nand_write_byte)
index 9d73e08..b838ecd 100644 (file)
@@ -689,7 +689,7 @@ static void mark_bbt_block_bad(struct nand_chip *this,
        bbt_mark_entry(this, block, BBT_BLOCK_WORN);
 
        to = (loff_t)block << this->bbt_erase_shift;
-       res = this->block_markbad(this, to);
+       res = nand_markbad_bbm(this, to);
        if (res)
                pr_warn("nand_bbt: error %d while marking block %d bad\n",
                        res, block);
index bd18713..79342e2 100644 (file)
@@ -2819,8 +2819,8 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc,
         * and block_markbad helpers until we permanently switch to using
         * MTD_OPS_RAW for all drivers (with the help of badblockbits)
         */
-       chip->block_bad         = qcom_nandc_block_bad;
-       chip->block_markbad     = qcom_nandc_block_markbad;
+       chip->legacy.block_bad          = qcom_nandc_block_bad;
+       chip->legacy.block_markbad      = qcom_nandc_block_markbad;
 
        chip->controller = &nandc->controller;
        chip->options |= NAND_NO_SUBPAGE_WRITE | NAND_USE_BOUNCE_BUFFER |
index bf143e0..6f063ef 100644 (file)
@@ -168,7 +168,7 @@ static int sm_attach_chip(struct nand_chip *chip)
        /* Bad block marker position */
        chip->badblockpos = 0x05;
        chip->badblockbits = 7;
-       chip->block_markbad = sm_block_markbad;
+       chip->legacy.block_markbad = sm_block_markbad;
 
        /* ECC layout */
        if (mtd->writesize == SM_SECTOR_SIZE)
index 15642c0..aa3e931 100644 (file)
@@ -1187,6 +1187,8 @@ int nand_op_parser_exec_op(struct nand_chip *chip,
  *            If set to NULL no access to ready/busy is available and the
  *            ready/busy information is read from the chip status register.
  * @waitfunc: hardware specific function for wait on ready.
+ * @block_bad: check if a block is bad, using OOB markers
+ * @block_markbad: mark a block bad
  *
  * If you look at this structure you're already wrong. These fields/hooks are
  * all deprecated.
@@ -1203,6 +1205,8 @@ struct nand_legacy {
                        int page_addr);
        int (*dev_ready)(struct nand_chip *chip);
        int (*waitfunc)(struct nand_chip *chip);
+       int (*block_bad)(struct nand_chip *chip, loff_t ofs);
+       int (*block_markbad)(struct nand_chip *chip, loff_t ofs);
 };
 
 /**
@@ -1214,8 +1218,6 @@ struct nand_legacy {
  *                     fields/hooks, you should consider reworking the driver
  *                     avoid using them.
  * @select_chip:       [REPLACEABLE] select chip nr
- * @block_bad:         [REPLACEABLE] check if a block is bad, using OOB markers
- * @block_markbad:     [REPLACEABLE] mark a block bad
  * @exec_op:           controller specific method to execute NAND operations.
  *                     This method replaces ->cmdfunc(),
  *                     ->legacy.{read,write}_{buf,byte,word}(),
@@ -1303,8 +1305,6 @@ struct nand_chip {
        struct nand_legacy legacy;
 
        void (*select_chip)(struct nand_chip *chip, int cs);
-       int (*block_bad)(struct nand_chip *chip, loff_t ofs);
-       int (*block_markbad)(struct nand_chip *chip, loff_t ofs);
        int (*exec_op)(struct nand_chip *chip,
                       const struct nand_operation *op,
                       bool check_only);
@@ -1556,6 +1556,7 @@ extern const struct nand_manufacturer_ops macronix_nand_manuf_ops;
 
 int nand_create_bbt(struct nand_chip *chip);
 int nand_markbad_bbt(struct nand_chip *chip, loff_t offs);
+int nand_markbad_bbm(struct nand_chip *chip, loff_t ofs);
 int nand_isreserved_bbt(struct nand_chip *chip, loff_t offs);
 int nand_isbad_bbt(struct nand_chip *chip, loff_t offs, int allowbbt);
 int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr,