From f7f8c1756e9a5f1258a7cc6b663f8451b724900f Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 5 Jul 2017 08:51:09 +0200 Subject: nand: fix wrong default oob layout for small pages using soft ecc When using soft ecc, if no ooblayout is given, the core automatically uses one of the nand_ooblayout_{sp,lp}*() functions to determine the layout inside the out of band data. Until kernel version 4.6, struct nand_ecclayout was used for that purpose. During the migration from 4.6 to 4.7, an error shown up in the small page layout, in the case oob section is only 8 bytes long. The layout was using three bytes (0, 1, 2) for ecc, two bytes (3, 4) as free bytes, one byte (5) for bad block marker and finally two bytes (6, 7) as free bytes, as shown there: [linux-4.6] drivers/mtd/nand/nand_base.c:52 static struct nand_ecclayout nand_oob_8 = { .eccbytes = 3, .eccpos = {0, 1, 2}, .oobfree = { {.offset = 3, .length = 2}, {.offset = 6, .length = 2} } }; This fixes the current implementation which is incoherent. It references bit 3 at the same time as an ecc byte and a free byte. Furthermore, it is clear with the previous implementation that there is only one ecc section with 8 bytes oob sections. We shall return -ERANGE in the nand_ooblayout_ecc_sp() function when asked for the second section. Signed-off-by: Miquel Raynal Fixes: 41b207a70d3a ("mtd: nand: implement the default mtd_ooblayout_ops") Cc: Signed-off-by: Boris Brezillon --- drivers/mtd/nand/nand_base.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/mtd/nand/nand_base.c') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 5fa5ddc94834..7b3826b42447 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -65,8 +65,14 @@ static int nand_ooblayout_ecc_sp(struct mtd_info *mtd, int section, if (!section) { oobregion->offset = 0; - oobregion->length = 4; + if (mtd->oobsize == 16) + oobregion->length = 4; + else + oobregion->length = 3; } else { + if (mtd->oobsize == 8) + return -ERANGE; + oobregion->offset = 6; oobregion->length = ecc->total - 4; } -- cgit v1.2.3 From cb25fae18207330caac848d850e11f9cdb500dbf Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Sun, 30 Jul 2017 16:18:03 -0600 Subject: mtd: nand: Fix a docs build warning Commit 0b4773fd1649 (mtd: nand: Drop unused cached programming support) removed the "cached" parameter from nand_write_page(), but did not update the kerneldoc comments, creating this docs build warning: ./drivers/mtd/nand/nand_base.c:2751: warning: Excess function parameter 'cached' description in 'nand_write_page' Remove the offending line so we can have a little peace and quiet. Signed-off-by: Jonathan Corbet Signed-off-by: Boris Brezillon --- drivers/mtd/nand/nand_base.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/mtd/nand/nand_base.c') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 7b3826b42447..5b7c8d05360f 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2747,7 +2747,6 @@ static int nand_write_page_syndrome(struct mtd_info *mtd, * @buf: the data to write * @oob_required: must write chip->oob_poi to OOB * @page: page number to write - * @cached: cached programming * @raw: use _raw version of write_page */ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, -- cgit v1.2.3 From a11bf5ed951f8900d244d09eb03a888b59c7fc82 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 31 Jul 2017 10:29:56 +0200 Subject: mtd: nand: Fix timing setup for NANDs that do not support SET FEATURES Some ONFI NANDs do not support the SET/GET FEATURES commands, which, according to the spec, is perfectly valid. On these NANDs we can't set a specific timing mode using the "timing mode" feature, and we should assume the NAND does not require any setup to enter a specific timing mode. Signed-off-by: Boris Brezillon Fixes: d8e725dd8311 ("mtd: nand: automate NAND timings selection") Reported-by: Alexander Dahl Cc: Tested-by: Alexander Dahl Signed-off-by: Boris Brezillon --- drivers/mtd/nand/nand_base.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/mtd/nand/nand_base.c') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 5b7c8d05360f..c6c18b82f8f4 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -1131,7 +1131,9 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr) * Ensure the timing mode has been changed on the chip side * before changing timings on the controller side. */ - if (chip->onfi_version) { + if (chip->onfi_version && + (le16_to_cpu(chip->onfi_params.opt_cmd) & + ONFI_OPT_CMD_SET_GET_FEATURES)) { u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = { chip->onfi_timing_mode_default, }; -- cgit v1.2.3