From patchwork Thu May 16 13:35:41 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Westfahl X-Patchwork-Id: 244324 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:770:15f::2]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 1FDB62C00C0 for ; Thu, 16 May 2013 23:37:06 +1000 (EST) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UcyM3-0003Ra-Av; Thu, 16 May 2013 13:36:23 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UcyLm-0004NC-OC; Thu, 16 May 2013 13:36:06 +0000 Received: from mailserver6.natinst.com ([130.164.80.6] helo=spamkiller06.natinst.com) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UcyLk-0004Lw-KT for linux-mtd@lists.infradead.org; Thu, 16 May 2013 13:36:05 +0000 Received: from US-AUS-MAIL4.amer.corp.natinst.com (nb-chan1-1338.natinst.com [130.164.19.134]) by spamkiller06.natinst.com (8.14.5/8.14.5) with ESMTP id r4GDZfH6002539 for ; Thu, 16 May 2013 08:35:41 -0500 To: linux-mtd@lists.infradead.org MIME-Version: 1.0 Subject: [RESEND PATCH] mtd: nand: nand_bbt: scan for next free bbt block if writing bbt fails X-KeepSent: 488B7050:CCC82AE1-86257B6D:004A7953; type=4; name=$KeepSent X-Mailer: Lotus Notes Release 8.5.3FP1 March 08, 2012 From: Jeff Westfahl Message-ID: Date: Thu, 16 May 2013 08:35:41 -0500 X-MIMETrack: Serialize by Router on US-AUS-MAIL4/AUS/M/NIC(Release 8.5.3FP2 HF169|September 14, 2012) at 05/16/2013 08:35:41 AM, Serialize complete at 05/16/2013 08:35:41 AM X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.10.8626, 1.0.431, 0.0.0000 definitions=2013-05-16_04:2013-05-16, 2013-05-16, 1970-01-01 signatures=0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130516_093604_785035_D56A4511 X-CRM114-Status: GOOD ( 14.36 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: jeff.westfahl@ni.com X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org If erasing or writing the BBT fails, we should mark the current BBT block as bad and use the BBT descriptor to scan for the next available unused block in the BBT. We should only return a failure if there isn't any space left. Signed-off-by: Jeff Westfahl --- drivers/mtd/nand/nand_bbt.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) * Automatic placement of the bad block table. Search direction @@ -831,14 +832,26 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, einfo.addr = to; einfo.len = 1 << this->bbt_erase_shift; res = nand_erase_nand(mtd, &einfo, 1); - if (res < 0) - goto outerr; + if (res < 0) { + /* This block is bad. Mark it as such and see if there's + another available in the BBT area. */ + int block = page >> + (this->bbt_erase_shift - this->page_shift); + this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); + goto next; + } res = scan_write_bbt(mtd, to, len, buf, td->options & NAND_BBT_NO_OOB ? NULL : &buf[len]); - if (res < 0) - goto outerr; + if (res < 0) { + /* This block is bad. Mark it as such and see if there's + another available in the BBT area. */ + int block = page >> + (this->bbt_erase_shift - this->page_shift); + this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); + goto next; + } pr_info("Bad block table written to 0x%012llx, version 0x%02X\n", (unsigned long long)to, td->version[chip]); diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 2672643..900bda1 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -697,6 +697,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, page = td->pages[chip]; goto write; } + next: /*