Skip to content

Commit b135b33

Browse files
committed
mtd: rawnand: omap: Use BCH private fields in the specific OOB layout
The OMAP driver may leverage software BCH logic to locate errors while using its own hardware to detect the presence of errors. This is achieved with a "mixed" mode which initializes manually the software BCH internal logic while providing its own OOB layout. The issue here comes from the fact that the BCH driver has been updated to only use generic NAND objects, and no longer depend on raw NAND structures as it is usable from SPI-NAND as well. However, at the end of the BCH context initialization, the driver checks the validity of the OOB layout. At this stage, the raw NAND fields have not been populated yet while being used by the layout helpers, leading to an invalid layout. The chosen solution here is to include the BCH structure definition and to refer to the BCH fields directly (de-referenced as a const pointer here) to know as early as possible the number of steps and ECC bytes which have been chosen. Note: I don't know which commit exactly triggered the error, but the entire migration to a generic BCH driver got merged in one go, so this should not be a problem for stable backports. Reported-by: Adam Ford <aford173@gmail.com> Fixes: 80fe603 ("mtd: nand: ecc-bch: Stop using raw NAND structures") Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Tested-by: Adam Ford <aford173@gmail.com> #logicpd-torpedo-37xx-devkit-28.dts Link: https://lore.kernel.org/linux-mtd/20210119155510.5655-1-miquel.raynal@bootlin.com
1 parent e708789 commit b135b33

1 file changed

Lines changed: 9 additions & 6 deletions

File tree

drivers/mtd/nand/raw/omap2.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/jiffies.h>
1616
#include <linux/sched.h>
1717
#include <linux/mtd/mtd.h>
18+
#include <linux/mtd/nand-ecc-sw-bch.h>
1819
#include <linux/mtd/rawnand.h>
1920
#include <linux/mtd/partitions.h>
2021
#include <linux/omap-dma.h>
@@ -1866,26 +1867,28 @@ static const struct mtd_ooblayout_ops omap_ooblayout_ops = {
18661867
static int omap_sw_ooblayout_ecc(struct mtd_info *mtd, int section,
18671868
struct mtd_oob_region *oobregion)
18681869
{
1869-
struct nand_chip *chip = mtd_to_nand(mtd);
1870+
struct nand_device *nand = mtd_to_nanddev(mtd);
1871+
const struct nand_ecc_sw_bch_conf *engine_conf = nand->ecc.ctx.priv;
18701872
int off = BADBLOCK_MARKER_LENGTH;
18711873

1872-
if (section >= chip->ecc.steps)
1874+
if (section >= engine_conf->nsteps)
18731875
return -ERANGE;
18741876

18751877
/*
18761878
* When SW correction is employed, one OMAP specific marker byte is
18771879
* reserved after each ECC step.
18781880
*/
1879-
oobregion->offset = off + (section * (chip->ecc.bytes + 1));
1880-
oobregion->length = chip->ecc.bytes;
1881+
oobregion->offset = off + (section * (engine_conf->code_size + 1));
1882+
oobregion->length = engine_conf->code_size;
18811883

18821884
return 0;
18831885
}
18841886

18851887
static int omap_sw_ooblayout_free(struct mtd_info *mtd, int section,
18861888
struct mtd_oob_region *oobregion)
18871889
{
1888-
struct nand_chip *chip = mtd_to_nand(mtd);
1890+
struct nand_device *nand = mtd_to_nanddev(mtd);
1891+
const struct nand_ecc_sw_bch_conf *engine_conf = nand->ecc.ctx.priv;
18891892
int off = BADBLOCK_MARKER_LENGTH;
18901893

18911894
if (section)
@@ -1895,7 +1898,7 @@ static int omap_sw_ooblayout_free(struct mtd_info *mtd, int section,
18951898
* When SW correction is employed, one OMAP specific marker byte is
18961899
* reserved after each ECC step.
18971900
*/
1898-
off += ((chip->ecc.bytes + 1) * chip->ecc.steps);
1901+
off += ((engine_conf->code_size + 1) * engine_conf->nsteps);
18991902
if (off >= mtd->oobsize)
19001903
return -ERANGE;
19011904

0 commit comments

Comments
 (0)