From linux-mtd at lists.infradead.org Thu Jun 1 11:59:01 2017 From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List) Date: Thu, 01 Jun 2017 18:59:01 +0000 Subject: mtd: nand: don't leak buffers when ->scan_bbt() fails Message-ID: Gitweb: http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=44d4182e23c555cbfa8b8a0ad2d94664d23850d3 Commit: 44d4182e23c555cbfa8b8a0ad2d94664d23850d3 Parent: 08332893e37af6ae779367e78e444f8f9571511d Author: Brian Norris AuthorDate: Mon May 1 17:04:50 2017 -0700 Committer: Boris Brezillon CommitDate: Mon May 22 09:42:29 2017 +0200 mtd: nand: don't leak buffers when ->scan_bbt() fails This bug seems to have been here forever, although we came close to fixing all of them in [1]! [1] 11eaf6df1cce ("mtd: nand: Remove BUG() abuse in nand_scan_tail") Signed-off-by: Brian Norris Acked-by: Ezequiel Garcia Signed-off-by: Boris Brezillon --- drivers/mtd/nand/nand_base.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index d474378..6678229 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -4842,7 +4842,11 @@ int nand_scan_tail(struct mtd_info *mtd) return 0; /* Build bad block table */ - return chip->scan_bbt(mtd); + ret = chip->scan_bbt(mtd); + if (ret) + goto err_free; + return 0; + err_free: if (nbuf) { kfree(nbuf->databuf); From linux-mtd at lists.infradead.org Thu Jun 1 11:59:01 2017 From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List) Date: Thu, 01 Jun 2017 18:59:01 +0000 Subject: mtd: nand: drop unneeded module.h include Message-ID: Gitweb: http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=0545c1720277dd246bd682b23aee425f3830a14f Commit: 0545c1720277dd246bd682b23aee425f3830a14f Parent: 44d4182e23c555cbfa8b8a0ad2d94664d23850d3 Author: Brian Norris AuthorDate: Mon May 1 17:04:52 2017 -0700 Committer: Boris Brezillon CommitDate: Mon May 22 09:42:29 2017 +0200 mtd: nand: drop unneeded module.h include nand_ids isn't a separate module anymore and doesn't need this header. Signed-off-by: Brian Norris Signed-off-by: Boris Brezillon --- drivers/mtd/nand/nand_ids.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index 9d5ca0e..92e2cf8 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c @@ -6,7 +6,6 @@ * published by the Free Software Foundation. * */ -#include #include #include From linux-mtd at lists.infradead.org Thu Jun 1 11:59:01 2017 From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List) Date: Thu, 01 Jun 2017 18:59:01 +0000 Subject: mtd: nand: free vendor-specific resources in init failure paths Message-ID: Gitweb: http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=787710492911e21148975e1d1914c7409fb32c7e Commit: 787710492911e21148975e1d1914c7409fb32c7e Parent: 0545c1720277dd246bd682b23aee425f3830a14f Author: Brian Norris AuthorDate: Mon May 1 17:04:53 2017 -0700 Committer: Boris Brezillon CommitDate: Mon May 22 09:42:29 2017 +0200 mtd: nand: free vendor-specific resources in init failure paths If we fail any time after calling nand_detect(), then we don't call the vendor-specific ->cleanup() callback, and we'll leak any resources the vendor-specific code might have allocated. Mark the "fix" against the first commit that started allocating anything in ->init(). Fixes: 626994e07480 ("mtd: nand: hynix: Add read-retry support for 1x nm MLC NANDs") Signed-off-by: Brian Norris Signed-off-by: Boris Brezillon --- drivers/mtd/nand/nand_base.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 6678229..81f77f9 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -4361,7 +4361,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, /* Initialize the ->data_interface field. */ ret = nand_init_data_interface(chip); if (ret) - return ret; + goto err_nand_init; /* * Setup the data interface correctly on the chip and controller side. @@ -4373,7 +4373,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, */ ret = nand_setup_data_interface(chip); if (ret) - return ret; + goto err_nand_init; nand_maf_id = chip->id.data[0]; nand_dev_id = chip->id.data[1]; @@ -4404,6 +4404,12 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, mtd->size = i * chip->chipsize; return 0; + +err_nand_init: + /* Free manufacturer priv data. */ + nand_manufacturer_cleanup(chip); + + return ret; } EXPORT_SYMBOL(nand_scan_ident); @@ -4574,18 +4580,23 @@ int nand_scan_tail(struct mtd_info *mtd) /* New bad blocks should be marked in OOB, flash-based BBT, or both */ if (WARN_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) && - !(chip->bbt_options & NAND_BBT_USE_FLASH))) - return -EINVAL; + !(chip->bbt_options & NAND_BBT_USE_FLASH))) { + ret = -EINVAL; + goto err_ident; + } if (invalid_ecc_page_accessors(chip)) { pr_err("Invalid ECC page accessors setup\n"); - return -EINVAL; + ret = -EINVAL; + goto err_ident; } if (!(chip->options & NAND_OWN_BUFFERS)) { nbuf = kzalloc(sizeof(*nbuf), GFP_KERNEL); - if (!nbuf) - return -ENOMEM; + if (!nbuf) { + ret = -ENOMEM; + goto err_ident; + } nbuf->ecccalc = kmalloc(mtd->oobsize, GFP_KERNEL); if (!nbuf->ecccalc) { @@ -4608,8 +4619,10 @@ int nand_scan_tail(struct mtd_info *mtd) chip->buffers = nbuf; } else { - if (!chip->buffers) - return -ENOMEM; + if (!chip->buffers) { + ret = -ENOMEM; + goto err_ident; + } } /* Set the internal oob buffer location, just after the page data */ @@ -4854,6 +4867,13 @@ err_free: kfree(nbuf->ecccalc); kfree(nbuf); } + +err_ident: + /* Clean up nand_scan_ident(). */ + + /* Free manufacturer priv data. */ + nand_manufacturer_cleanup(chip); + return ret; } EXPORT_SYMBOL(nand_scan_tail); From linux-mtd at lists.infradead.org Thu Jun 1 11:59:01 2017 From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List) Date: Thu, 01 Jun 2017 18:59:01 +0000 Subject: mtd: nand: samsung: warn about un-parseable ECC info Message-ID: Gitweb: http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=d24197907454b902908e025bce4b8bc677d3ba6b Commit: d24197907454b902908e025bce4b8bc677d3ba6b Parent: 787710492911e21148975e1d1914c7409fb32c7e Author: Brian Norris AuthorDate: Mon May 1 17:04:55 2017 -0700 Committer: Boris Brezillon CommitDate: Mon May 22 09:42:29 2017 +0200 mtd: nand: samsung: warn about un-parseable ECC info We don't handle cases larger than 7. We probably shouldn't pretend we know the ECC step size in this case, and it's probably also good to WARN() like we do in many other similar cases. Fixes: 8fc82d456e40 ("mtd: nand: samsung: Retrieve ECC requirements from extended ID") Signed-off-by: Brian Norris Signed-off-by: Boris Brezillon --- drivers/mtd/nand/nand_samsung.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/nand_samsung.c index 9cfc403..1e07559 100644 --- a/drivers/mtd/nand/nand_samsung.c +++ b/drivers/mtd/nand/nand_samsung.c @@ -84,6 +84,9 @@ static void samsung_nand_decode_id(struct nand_chip *chip) case 7: chip->ecc_strength_ds = 60; break; + default: + WARN(1, "Could not decode ECC info"); + chip->ecc_step_ds = 0; } } } else { From linux-mtd at lists.infradead.org Thu Jun 1 11:59:01 2017 From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List) Date: Thu, 01 Jun 2017 18:59:01 +0000 Subject: mtd: nand: tango: Export OF device ID table as module aliases Message-ID: Gitweb: http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=2761b4f12b017f6d3e5add386733a700a490df47 Commit: 2761b4f12b017f6d3e5add386733a700a490df47 Parent: d24197907454b902908e025bce4b8bc677d3ba6b Author: Andres Galacho AuthorDate: Mon May 1 16:30:15 2017 -0400 Committer: Boris Brezillon CommitDate: Mon May 22 09:42:29 2017 +0200 mtd: nand: tango: Export OF device ID table as module aliases The device table is required to load modules based on modaliases. After adding MODULE_DEVICE_TABLE, below entries for example will be added to module.alias: alias: of:N*T*Csigma,smp8758-nandC* alias: of:N*T*Csigma,smp8758-nand Fixes: 6956e2385a16 ("mtd: nand: add tango NAND flash controller support") Cc: stable at vger.kernel.org Signed-off-by: Andres Galacho Acked-by: Brian Norris Signed-off-by: Boris Brezillon --- drivers/mtd/nand/tango_nand.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/nand/tango_nand.c b/drivers/mtd/nand/tango_nand.c index 05b6e10..82fea9b 100644 --- a/drivers/mtd/nand/tango_nand.c +++ b/drivers/mtd/nand/tango_nand.c @@ -663,6 +663,7 @@ static const struct of_device_id tango_nand_ids[] = { { .compatible = "sigma,smp8758-nand" }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, tango_nand_ids); static struct platform_driver tango_nand_driver = { .probe = tango_nand_probe, From linux-mtd at lists.infradead.org Thu Jun 1 11:59:01 2017 From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List) Date: Thu, 01 Jun 2017 18:59:01 +0000 Subject: mtd: nand: tango: Update ecc_stats.corrected Message-ID: Gitweb: http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=60cf0ce14b09b54e7ee79dc3ef498de6ef0e41e9 Commit: 60cf0ce14b09b54e7ee79dc3ef498de6ef0e41e9 Parent: 2761b4f12b017f6d3e5add386733a700a490df47 Author: Marc Gonzalez AuthorDate: Fri May 12 17:34:01 2017 +0200 Committer: Boris Brezillon CommitDate: Mon May 22 09:42:29 2017 +0200 mtd: nand: tango: Update ecc_stats.corrected According to Boris, some user-space tools expect MTD drivers to update ecc_stats.corrected, and it's better to provide a lower bound than to provide no information at all. Fixes: 6956e2385a16 ("mtd: nand: add tango NAND flash controller support") Cc: stable at vger.kernel.org Reported-by: Pavel Machek Signed-off-by: Marc Gonzalez Signed-off-by: Boris Brezillon --- drivers/mtd/nand/tango_nand.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/tango_nand.c b/drivers/mtd/nand/tango_nand.c index 82fea9b..49b286c 100644 --- a/drivers/mtd/nand/tango_nand.c +++ b/drivers/mtd/nand/tango_nand.c @@ -55,10 +55,10 @@ * byte 1 for other packets in the page (PKT_N, for N > 0) * ERR_COUNT_PKT_N is the max error count over all but the first packet. */ -#define DECODE_OK_PKT_0(v) ((v) & BIT(7)) -#define DECODE_OK_PKT_N(v) ((v) & BIT(15)) #define ERR_COUNT_PKT_0(v) (((v) >> 0) & 0x3f) #define ERR_COUNT_PKT_N(v) (((v) >> 8) & 0x3f) +#define DECODE_FAIL_PKT_0(v) (((v) & BIT(7)) == 0) +#define DECODE_FAIL_PKT_N(v) (((v) & BIT(15)) == 0) /* Offsets relative to pbus_base */ #define PBUS_CS_CTRL 0x83c @@ -193,6 +193,8 @@ static int check_erased_page(struct nand_chip *chip, u8 *buf) chip->ecc.strength); if (res < 0) mtd->ecc_stats.failed++; + else + mtd->ecc_stats.corrected += res; bitflips = max(res, bitflips); buf += pkt_size; @@ -202,9 +204,11 @@ static int check_erased_page(struct nand_chip *chip, u8 *buf) return bitflips; } -static int decode_error_report(struct tango_nfc *nfc) +static int decode_error_report(struct nand_chip *chip) { u32 status, res; + struct mtd_info *mtd = nand_to_mtd(chip); + struct tango_nfc *nfc = to_tango_nfc(chip->controller); status = readl_relaxed(nfc->reg_base + NFC_XFER_STATUS); if (status & PAGE_IS_EMPTY) @@ -212,10 +216,14 @@ static int decode_error_report(struct tango_nfc *nfc) res = readl_relaxed(nfc->mem_base + ERROR_REPORT); - if (DECODE_OK_PKT_0(res) && DECODE_OK_PKT_N(res)) - return max(ERR_COUNT_PKT_0(res), ERR_COUNT_PKT_N(res)); + if (DECODE_FAIL_PKT_0(res) || DECODE_FAIL_PKT_N(res)) + return -EBADMSG; + + /* ERR_COUNT_PKT_N is max, not sum, but that's all we have */ + mtd->ecc_stats.corrected += + ERR_COUNT_PKT_0(res) + ERR_COUNT_PKT_N(res); - return -EBADMSG; + return max(ERR_COUNT_PKT_0(res), ERR_COUNT_PKT_N(res)); } static void tango_dma_callback(void *arg) @@ -282,7 +290,7 @@ static int tango_read_page(struct mtd_info *mtd, struct nand_chip *chip, if (err) return err; - res = decode_error_report(nfc); + res = decode_error_report(chip); if (res < 0) { chip->ecc.read_oob_raw(mtd, chip, page); res = check_erased_page(chip, buf); From linux-mtd at lists.infradead.org Thu Jun 1 11:59:02 2017 From: linux-mtd at lists.infradead.org (Linux-MTD Mailing List) Date: Thu, 01 Jun 2017 18:59:02 +0000 Subject: mtd: nand: make nand_ooblayout_lp_hamming_ops static Message-ID: Gitweb: http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=d4ed3b9015b5eebc90d629579d9e7944607cbae5 Commit: d4ed3b9015b5eebc90d629579d9e7944607cbae5 Parent: 60cf0ce14b09b54e7ee79dc3ef498de6ef0e41e9 Author: Colin Ian King AuthorDate: Thu May 4 13:11:00 2017 +0100 Committer: Boris Brezillon CommitDate: Mon May 22 09:42:29 2017 +0200 mtd: nand: make nand_ooblayout_lp_hamming_ops static nand_ooblayout_lp_hamming_ops can be made static as it does not need to be in global scope. Signed-off-by: Colin Ian King Acked-by: Boris Brezillon Signed-off-by: Boris Brezillon --- drivers/mtd/nand/nand_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 81f77f9..b1dd127 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -202,7 +202,7 @@ static int nand_ooblayout_free_lp_hamming(struct mtd_info *mtd, int section, return 0; } -const struct mtd_ooblayout_ops nand_ooblayout_lp_hamming_ops = { +static const struct mtd_ooblayout_ops nand_ooblayout_lp_hamming_ops = { .ecc = nand_ooblayout_ecc_lp_hamming, .free = nand_ooblayout_free_lp_hamming, };