[PATCH 1/2] mtd: rawnand: vf610_nfc: fix reads on chips with more than 64 bytes of OOB
Mehmet Fide <[email protected]>
| Newsgroups | gmane.linux.kernel,gmane.linux.drivers.mtd,gmane.linux.kernel.stable |
|---|---|
| Message-ID | <[email protected]> |
From: Mehmet Fide <[email protected]> The driver only implements the 64-byte OOB layout, so attach_chip() shrinks mtd->oobsize when the chip provides more. That clamp does not survive: nand_scan_tail() runs nanddev_init() after ->attach_chip(), and it restores mtd->oobsize from the memory organization, which still holds the value detected from the chip. The driver therefore transfers writesize + the chip's full OOB size, so the hardware ECC parity ends up at a different offset than the layout the controller was set up for, and every ECC-protected read fails with -EBADMSG. Measured on a Colibri VF61 (MX30LF4G28AC, 2048-byte pages, 112 bytes of OOB): with the clamp lost, UBI cannot read the erase counter headers of the pages U-Boot has just written, and the on-flash bad block table written by an older kernel reads back with ECC errors, so the board does not boot. Kernels before commit a7ab085d7c16 ("mtd: rawnand: Initialize the nand_device object") are not affected because nothing overwrote the clamp there, which is why the same chip works with a v4.4 kernel and with U-Boot, whose copy of this driver has no memory organization to restore the value from. Edward Karpicz reported that the clamp no longer takes effect on this chip; see the link below. Clamp the memory organization as well so the driver's 64-byte layout stays in effect, and log the truncation once, as it decides which on-flash layout the system uses. Reported-by: Edward Karpicz <[email protected]> Link: https://community.toradex.com/t/colibri-vf50-vf61-on-the-current-bsp-mainline-u-boot-v2026-07-and-linux-6-18-lts/30735 Fixes: a7ab085d7c16 ("mtd: rawnand: Initialize the nand_device object") Cc: [email protected] Signed-off-by: Mehmet Fide <[email protected]> --- drivers/mtd/nand/raw/vf610_nfc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/vf610_nfc.c b/drivers/mtd/nand/raw/vf610_nfc.c index 9940681810cf..f27ef2b0884d 100644 --- a/drivers/mtd/nand/raw/vf610_nfc.c +++ b/drivers/mtd/nand/raw/vf610_nfc.c @@ -771,8 +771,14 @@ static int vf610_nfc_attach_chip(struct nand_chip *chip) } /* Only 64 byte ECC layouts known */ - if (mtd->oobsize > 64) + if (mtd->oobsize > 64) { + dev_info(nfc->dev, + "using 64 of %d OOB bytes, ECC layout is unchanged\n", + mtd->oobsize); mtd->oobsize = 64; + /* nand_scan_tail() restores mtd->oobsize from the memorg */ + nanddev_get_memorg(&chip->base)->oobsize = 64; + } /* Use default large page ECC layout defined in NAND core */ mtd_set_ooblayout(mtd, nand_get_large_page_ooblayout()); -- 2.54.0