From patchwork Thu Jun 9 21:17:54 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kamal Dasu X-Patchwork-Id: 633237 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3rQdW844ygz9sDX for ; Fri, 10 Jun 2016 07:20:20 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=k+4vFoyD; dkim-atps=neutral Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1bB7LX-0004dS-6r; Thu, 09 Jun 2016 21:18:35 +0000 Received: from mail-pa0-x243.google.com ([2607:f8b0:400e:c03::243]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1bB7LT-0004at-6K for linux-mtd@lists.infradead.org; Thu, 09 Jun 2016 21:18:31 +0000 Received: by mail-pa0-x243.google.com with SMTP id fg1so3546518pad.3 for ; Thu, 09 Jun 2016 14:18:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=PrpIMEtYbYsCnU7/HzYGii4oJcIuzxgRrLia7S9BB4w=; b=k+4vFoyDBCOVVS6I67uW3XEkFj+wo+Lq9PO+esDI5DiAiblrEm+7IZwRG6v+/TyaLD 6QiBRMViFEN2FVGka9zZeayXx5VqLekauZkL9CO7Pr02rUO/hrlFNCRwW6G1VjxQY3Zc 99GbQEERjBWObSpLXqgLjK0Lk5wBjp6neYyt/5XnP43dWcENPML37gVAewhRVbtWu/fX /yJO5Zhp0D9CmaUqUVvF46ss3Yflkojm9XfZTEC9jSPbPswNqQqoeeMlGp/xxJS06F4V kOHpWMnYWJKieUx6WQLH960IS1kgKHT+l45x/hL1x50RAyfN6g0IT+GR/26Za6gZkdC3 A17w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=PrpIMEtYbYsCnU7/HzYGii4oJcIuzxgRrLia7S9BB4w=; b=UOK46h+JOxUmwFqQWKBxUEMWn4bTlR6qRkRlTpFwdOTlcYyfIHtmYkLJjIG7HUtSXF HLNsseDOonaXmYAspe4viGT05mJ+qFU+YiESaOLhXl64nYO4jLytZ1ltdjvcruNAnRyz 3yyYXUMj6+I226qXamoVQvcc/F3VYKH/eS4GbujZkZkFbYnB+VPYib/TDGV++JV3wdJy qQpAMmRgUk8pfcWbrULN9M9f7pM8N6sEVmqnbLtOyr4WgcXfgMLqNI00OLPuVomOcV53 6+ZYmN48qzOBn9PiKTwezYTdMpj03CJw9sWiZQi9o92TGw+s+vizFE27ROSV+WCr+/7r abFA== X-Gm-Message-State: ALyK8tIDYFVrROLiq0tkhVgp8aUEipKhoyUE9r2uddPqV3Zw+I5GSsHUYfvMESiqc8NGjA== X-Received: by 10.66.167.6 with SMTP id zk6mr14609402pab.146.1465507090105; Thu, 09 Jun 2016 14:18:10 -0700 (PDT) Received: from mail.broadcom.com ([216.31.219.19]) by smtp.gmail.com with ESMTPSA id y2sm12241340pfi.39.2016.06.09.14.18.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 09 Jun 2016 14:18:08 -0700 (PDT) From: Kamal Dasu To: linux-mtd@lists.infradead.org, computersforpeace@gmail.com, boris.brezillon@free-electrons.com Subject: [V3, 1/2] mtd: brcmnand: Add check for erased page bitflips Date: Thu, 9 Jun 2016 17:17:54 -0400 Message-Id: <1465507075-9447-1-git-send-email-kdasu.kdev@gmail.com> X-Mailer: git-send-email 1.9.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160609_141831_349299_89188988 X-CRM114-Status: GOOD ( 15.46 ) X-Spam-Score: -2.7 (--) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-2.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [2607:f8b0:400e:c03:0:0:0:243 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (kdasu.kdev[at]gmail.com) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: f.fainelli@gmail.com, bcm-kernel-feedback-list@broadcom.com, Kamal Dasu MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Check for erased page bitflips in a page. And if well within threshold return data as all 0xff. Apply sw check for controller version < 7.2. Controller vesion >= 7.2 has hw support. Signed-off-by: Kamal Dasu --- V3 changes Return the max bitflips from a sector within a page V2 changes Added use of nand_check_erased_ecc_chunk Restrict change to older controller < 7.2 --- drivers/mtd/nand/brcmnand/brcmnand.c | 62 ++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index b76ad7c..7ee9617 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -1545,6 +1545,56 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip, return ret; } +/* + * Check a page to see if it is erased (w/ bitflips) after an uncorrectable ECC + * error + * + * Because the HW ECC signals an ECC error if an erase paged has even a single + * bitflip, we must check each ECC error to see if it is actually an erased + * page with bitflips, not a truly corrupted page. + * + * On a real error, return a negative error code (-EBADMSG for ECC error), and + * buf will contain raw data. + * Otherwise, buf gets filled with 0xffs and return the maximum number of + * bitflips-per-ECC-sector to the caller. + * + */ +static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd, + struct nand_chip *chip, void *buf, u64 addr) +{ + int i, sas; + void *oob = chip->oob_poi; + int bitflips = 0; + int page = addr >> chip->page_shift; + int ret; + + if (!buf) { + buf = chip->buffers->databuf; + /* Invalidate page cache */ + chip->pagebuf = -1; + } + + sas = mtd->oobsize / chip->ecc.steps; + + /* read without ecc for verification */ + chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); + ret = chip->ecc.read_page_raw(mtd, chip, buf, true, page); + if (ret) + return ret; + + for (i = 0; i < chip->ecc.steps; i++, oob += sas) { + ret = nand_check_erased_ecc_chunk(buf, chip->ecc.size, + oob, sas, NULL, 0, + chip->ecc.strength); + if (ret < 0) + return ret; + + bitflips = max(bitflips, ret); + } + + return bitflips; +} + static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip, u64 addr, unsigned int trans, u32 *buf, u8 *oob) { @@ -1575,6 +1625,18 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip, } if (mtd_is_eccerr(err)) { + /* + * Controller version 7.2 has hw encoder to detect erased page + * bitflips, apply sw verification for older controllers only + */ + if (ctrl->nand_version < 0x0702) { + err = brcmstb_nand_verify_erased_page(mtd, chip, buf, + addr); + /* erased page bitflips corrected */ + if (err > 0) + return err; + } + dev_dbg(ctrl->dev, "uncorrectable error at 0x%llx\n", (unsigned long long)err_addr); mtd->ecc_stats.failed++;