From patchwork Thu Feb 24 06:10:16 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh KUMAR X-Patchwork-Id: 84322 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id EBF19B7192 for ; Thu, 24 Feb 2011 17:13:32 +1100 (EST) Received: from canuck.infradead.org ([2001:4978:20e::1]) by bombadil.infradead.org with esmtps (Exim 4.72 #1 (Red Hat Linux)) id 1PsUQI-0003Ci-Cq; Thu, 24 Feb 2011 06:11:34 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.72 #1 (Red Hat Linux)) id 1PsUQE-0008Uc-Of; Thu, 24 Feb 2011 06:11:30 +0000 Received: from eu1sys200aog106.obsmtp.com ([207.126.144.121]) by canuck.infradead.org with smtps (Exim 4.72 #1 (Red Hat Linux)) id 1PsUQ6-0008UE-T0 for linux-mtd@lists.infradead.org; Thu, 24 Feb 2011 06:11:27 +0000 Received: from source ([138.198.100.35]) (using TLSv1) by eu1sys200aob106.postini.com ([207.126.147.11]) with SMTP ID DSNKTWX2gYe/0mEuC5IM3zfB89hvfQHbiJzQ@postini.com; Thu, 24 Feb 2011 06:11:22 UTC Received: from zeta.dmz-ap.st.com (ns6.st.com [138.198.234.13]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id F1105D2; Thu, 24 Feb 2011 06:10:55 +0000 (GMT) Received: from Webmail-ap.st.com (eapex1hubcas1.st.com [10.80.176.8]) by zeta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 93758ABF; Thu, 24 Feb 2011 06:10:55 +0000 (GMT) Received: from localhost (10.199.7.86) by Webmail-ap.st.com (10.80.176.7) with Microsoft SMTP Server (TLS) id 8.2.234.1; Thu, 24 Feb 2011 14:10:54 +0800 From: Viresh Kumar To: , , Subject: [PATCH] Newly erased page read workaround Date: Thu, 24 Feb 2011 11:40:16 +0530 Message-ID: X-Mailer: git-send-email 1.7.2.2 MIME-Version: 1.0 X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110224_011123_190018_20F75550 X-CRM114-Status: GOOD ( 17.94 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [207.126.144.121 listed in list.dnswl.org] Cc: Vipin Kumar , Viresh Kumar X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Vipin Kumar A newly erased page contains ff in data as well as spare area. While reading an erased page, the read out ecc from spare area does not match the ecc generated by fsmc ecc hardware accelarator. This is because ecc of data ff ff is not ff ff. This leads to errors when jffs2 fs erases and reads back the pages to ensure consistency. This patch adds a software workaround to ensure that the ecc check is not performed for erased pages. An erased page is checked by checking data as ff ff. Signed-off-by: Vipin Kumar Signed-off-by: Viresh Kumar Acked-by: Linus Walleij --- drivers/mtd/nand/fsmc_nand.c | 28 ++++++++++++++++++++++------ 1 files changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 205b10b..7df270a 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -420,7 +420,7 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, struct fsmc_nand_data *host = container_of(mtd, struct fsmc_nand_data, mtd); struct fsmc_eccplace *ecc_place = host->ecc_place; - int i, j, s, stat, eccsize = chip->ecc.size; + int i, j, k, s, stat, eccsize = chip->ecc.size; int eccbytes = chip->ecc.bytes; int eccsteps = chip->ecc.steps; uint8_t *p = buf; @@ -460,11 +460,27 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, memcpy(&ecc_code[i], oob, 13); chip->ecc.calculate(mtd, p, &ecc_calc[i]); - stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); - if (stat < 0) - mtd->ecc_stats.failed++; - else - mtd->ecc_stats.corrected += stat; + /* + * This is a temporary erase check. A newly erased page read + * would result in an ecc error because the oob data is also + * erased to FF and the calculated ecc for an FF data is not + * FF..FF. + * This is a workaround to skip performing correction in case + * data is FF..FF + */ + for (k = 0; k < eccsize; k++) { + if (*(p + k) != 0xff) + break; + } + + if (k < eccsize) { + stat = chip->ecc.correct(mtd, p, &ecc_code[i], + &ecc_calc[i]); + if (stat < 0) + mtd->ecc_stats.failed++; + else + mtd->ecc_stats.corrected += stat; + } } return 0;