Hi On Thu, Dec 5, 2024 at 10:24 AM <dinesh.mani...@intel.com> wrote: > > From: Dinesh Maniyam <dinesh.mani...@intel.com> > > Leverage linux code to support hardware ECC interface > to verify nand bad block. > > Signed-off-by: Dinesh Maniyam <dinesh.mani...@intel.com> > > --- > v2: > - remove the "this patch is to" commit phrases > --- > --- > drivers/mtd/nand/raw/nand_base.c | 71 +++++++++++++++++++++----------- > include/linux/mtd/rawnand.h | 13 ++++++ > 2 files changed, 60 insertions(+), 24 deletions(-) > > diff --git a/drivers/mtd/nand/raw/nand_base.c > b/drivers/mtd/nand/raw/nand_base.c > index 4401bdcdb9..9b1b2d1f85 100644 > --- a/drivers/mtd/nand/raw/nand_base.c > +++ b/drivers/mtd/nand/raw/nand_base.c > @@ -9,6 +9,8 @@ > * Copyright (C) 2000 Steven J. Hill (sjh...@realitydiluted.com) > * 2002-2006 Thomas Gleixner (t...@linutronix.de) > * > + * Copyright (C) 2024 Intel Corporation <www.intel.com> > + *
Drop it. I don't think that because you add a function here, you can add any copyright > * Credits: > * David Woodhouse for adding multichip support > * > @@ -306,6 +308,35 @@ void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, > int len) > ioread16_rep(chip->IO_ADDR_R, p, len >> 1); > } > > +/* > + * nand_bbm_get_next_page - Get the next page for bad block markers > + * @chip: The NAND chip > + * @page: First page to start checking for bad block marker usage > + * > + * Returns an integer that corresponds to the page offset within a block, for > + * a page that is used to store bad block markers. If no more pages are > + * available, -EINVAL is returned. > + */ > +int nand_bbm_get_next_page(struct nand_chip *chip, int page) > +{ > + struct mtd_info *mtd = nand_to_mtd(chip); > + int last_page = ((mtd->erasesize - mtd->writesize) >> > + chip->page_shift) & chip->pagemask; > + unsigned int bbm_flags = NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE > + | NAND_BBM_LASTPAGE; > + > + if (page == 0 && !(chip->options & bbm_flags)) > + return 0; > + if (page == 0 && chip->options & NAND_BBM_FIRSTPAGE) > + return 0; > + if (page <= 1 && chip->options & NAND_BBM_SECONDPAGE) > + return 1; > + if (page <= last_page && chip->options & NAND_BBM_LASTPAGE) > + return last_page; > + > + return -EINVAL; > +} > + > /** > * nand_block_bad - [DEFAULT] Read bad block marker from the chip > * @mtd: MTD device structure > @@ -315,40 +346,32 @@ void nand_read_buf16(struct mtd_info *mtd, uint8_t > *buf, int len) > */ > static int nand_block_bad(struct mtd_info *mtd, loff_t ofs) > { > - int page, res = 0, i = 0; > struct nand_chip *chip = mtd_to_nand(mtd); > - u16 bad; > + int first_page, page_offset; > + int res; > + u8 bad; > > - if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) > - ofs += mtd->erasesize - mtd->writesize; > + first_page = (int)(ofs >> chip->page_shift) & chip->pagemask; > + page_offset = nand_bbm_get_next_page(chip, 0); > > - page = (int)(ofs >> chip->page_shift) & chip->pagemask; > + while (page_offset >= 0) { > + res = chip->ecc.read_oob(mtd, chip, first_page + page_offset); > + if (res < 0) > + return res; > > - do { > - if (chip->options & NAND_BUSWIDTH_16) { > - chip->cmdfunc(mtd, NAND_CMD_READOOB, > - chip->badblockpos & 0xFE, page); > - bad = cpu_to_le16(chip->read_word(mtd)); > - if (chip->badblockpos & 0x1) > - bad >>= 8; > - else > - bad &= 0xFF; > - } else { > - chip->cmdfunc(mtd, NAND_CMD_READOOB, > chip->badblockpos, > - page); > - bad = chip->read_byte(mtd); > - } > + bad = chip->oob_poi[chip->badblockpos]; > > if (likely(chip->badblockbits == 8)) > res = bad != 0xFF; > else > res = hweight8(bad) < chip->badblockbits; > - ofs += mtd->writesize; > - page = (int)(ofs >> chip->page_shift) & chip->pagemask; > - i++; > - } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE)); > + if (res) > + return res; > > - return res; > + page_offset = nand_bbm_get_next_page(chip, page_offset + 1); > + } > + > + return 0; > } > > /** > diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h > index 14f93dab0a..35eb3b5678 100644 > --- a/include/linux/mtd/rawnand.h > +++ b/include/linux/mtd/rawnand.h > @@ -4,6 +4,8 @@ > * Steven J. Hill <sjh...@realitydiluted.com> > * Thomas Gleixner <t...@linutronix.de> > * > + * Copyright (C) 2024 Intel Corporation <www.intel.com> > + * Drop here > * Info: > * Contains standard defines and IDs for NAND flash devices > * > @@ -131,6 +133,17 @@ void nand_wait_ready(struct mtd_info *mtd); > > #define NAND_DATA_IFACE_CHECK_ONLY -1 > > +/* > + * There are different places where the manufacturer stores the factory bad > + * block markers. > + * > + * Position within the block: Each of these pages needs to be checked for a > + * bad block marking pattern. > + */ > +#define NAND_BBM_FIRSTPAGE BIT(24) > +#define NAND_BBM_SECONDPAGE BIT(25) > +#define NAND_BBM_LASTPAGE BIT(26) > + > /* > * Constants for ECC_MODES > */ > -- > 2.19.0 > Reviewed-by: Michael Trimarchi <mich...@amarulasolutions.com> -- Michael Nazzareno Trimarchi Co-Founder & Chief Executive Officer M. +39 347 913 2170 mich...@amarulasolutions.com __________________________________ Amarula Solutions BV Joop Geesinkweg 125, 1114 AB, Amsterdam, NL T. +31 (0)85 111 9172 i...@amarulasolutions.com www.amarulasolutions.com