From: Richard Genoud Date: Tue, 17 Mar 2026 14:24:31 +0000 (+0100) Subject: mtd: rawnand: sunxi: do not count BBM bytes twice X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8fa72836be11ea70cbfa43f7f2253fa57ccc6ecd;p=thirdparty%2Fkernel%2Fstable.git mtd: rawnand: sunxi: do not count BBM bytes twice BBM is already part of USER_DATA section, so we should not remove it twice This was working ok because we are on the safe size, advertising that there was 2 bytes less available than in reality. But we can't change old platforms, since it may lead to a different ECC strength, so, introduce a legacy flag for old platforms, and switch the new platforms to the correct count. Signed-off-by: Richard Genoud Signed-off-by: Miquel Raynal --- diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 8af449e548d4..d126dc18ef27 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -275,6 +275,8 @@ static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand) * @has_ecc_block_512: If the ECC can handle 512B or only 1024B chuncks * @has_ecc_clk: If the controller needs an ECC clock. * @has_mbus_clk: If the controller needs a mbus clock. + * @legacy_max_strength:If the maximize strength function was off by 2 bytes + * NB: this should not be used in new controllers * @reg_io_data: I/O data register * @reg_ecc_err_cnt: ECC error counter register * @reg_user_data: User data register @@ -304,6 +306,7 @@ struct sunxi_nfc_caps { bool has_ecc_block_512; bool has_ecc_clk; bool has_mbus_clk; + bool legacy_max_strength; unsigned int reg_io_data; unsigned int reg_ecc_err_cnt; unsigned int reg_user_data; @@ -1805,10 +1808,22 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand, ecc->size = 1024; nsectors = mtd->writesize / ecc->size; - /* Reserve 2 bytes for the BBM */ - bytes = (mtd->oobsize - 2) / nsectors; + /* + * The 2 BBM bytes should not be removed from the grand total, + * because they are part of the USER_DATA_SZ. + * But we can't modify that for older platform since it may + * result in a stronger ECC at the end, and break the + * compatibility. + */ + if (nfc->caps->legacy_max_strength) + bytes = (mtd->oobsize - 2) / nsectors; + else + bytes = mtd->oobsize / nsectors; - /* 4 non-ECC bytes are added before each ECC bytes section */ + /* + * USER_DATA_SZ non-ECC bytes are added before each ECC bytes + * section, they contain the 2 BBM bytes + */ bytes -= USER_DATA_SZ; /* and bytes has to be even. */ @@ -2373,6 +2388,7 @@ static const u8 sunxi_user_data_len_h6[] = { static const struct sunxi_nfc_caps sunxi_nfc_a10_caps = { .has_ecc_block_512 = true, + .legacy_max_strength = true, .reg_io_data = NFC_REG_A10_IO_DATA, .reg_ecc_err_cnt = NFC_REG_A10_ECC_ERR_CNT, .reg_user_data = NFC_REG_A10_USER_DATA, @@ -2394,6 +2410,7 @@ static const struct sunxi_nfc_caps sunxi_nfc_a10_caps = { static const struct sunxi_nfc_caps sunxi_nfc_a23_caps = { .has_mdma = true, .has_ecc_block_512 = true, + .legacy_max_strength = true, .reg_io_data = NFC_REG_A23_IO_DATA, .reg_ecc_err_cnt = NFC_REG_A10_ECC_ERR_CNT, .reg_user_data = NFC_REG_A10_USER_DATA,