From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752902AbcHLV6K (ORCPT ); Fri, 12 Aug 2016 17:58:10 -0400 Received: from skprod2.natinst.com ([130.164.80.23]:59847 "EHLO ni.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752295AbcHLV6I (ORCPT ); Fri, 12 Aug 2016 17:58:08 -0400 From: Kyle Roeschley To: boris.brezillon@free-electrons.com, richard@nod.at Cc: dwmw2@infradead.org, computersforpeace@gmail.com, beanhuo@micron.com, linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org, nathan.sullivan@ni.com, xander.huff@ni.com, peterpansjtu@gmail.com Subject: [PATCH v7 2/2] mtd: nand_bbt: scan for next free bbt block if writing bbt fails Date: Fri, 12 Aug 2016 16:58:23 -0500 Message-Id: <1471039103-6745-2-git-send-email-kyle.roeschley@ni.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1471039103-6745-1-git-send-email-kyle.roeschley@ni.com> References: <1471039103-6745-1-git-send-email-kyle.roeschley@ni.com> X-MIMETrack: Itemize by SMTP Server on US-AUS-MGWOut1/AUS/H/NIC(Release 8.5.3FP6 HF1218|December 12, 2014) at 08/12/2016 04:57:14 PM, Serialize by Router on US-AUS-MGWOut1/AUS/H/NIC(Release 8.5.3FP6 HF1218|December 12, 2014) at 08/12/2016 04:57:14 PM, Serialize complete at 08/12/2016 04:57:14 PM X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2016-08-12_09:,, signatures=0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.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: Kyle Roeschley Signed-off-by: Boris Brezillon Suggested-by: Jeff Westfahl Tested-by: Kyle Roeschley --- drivers/mtd/nand/nand_bbt.c | 47 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 918db24..7695efe 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -668,6 +668,37 @@ static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td, } /** + * mark_bbt_block_bad - Mark one of the block reserved for BBT bad + * @this: the NAND device + * @td: the BBT description + * @chip: the CHIP selector + * @block: the BBT block to mark + * + * Blocks reserved for BBT can become bad. This functions is an helper to mark + * such blocks as bad. It takes care of updating the in-memory BBT, marking the + * block as bad using a bad block marker and invalidating the associated + * td->pages[] entry. + */ +static void mark_bbt_block_bad(struct nand_chip *this, + struct nand_bbt_descr *td, + int chip, int block) +{ + struct mtd_info *mtd = nand_to_mtd(this); + loff_t to; + int res; + + bbt_mark_entry(this, block, BBT_BLOCK_WORN); + + to = (loff_t)block << this->bbt_erase_shift; + res = this->block_markbad(mtd, to); + if (res) + pr_warn("nand_bbt: error %d while marking block %d bad\n", + res, block); + + td->pages[chip] = -1; +} + +/** * write_bbt - [GENERIC] (Re)write the bad block table * @mtd: MTD device structure * @buf: temporary buffer @@ -825,14 +856,22 @@ 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) { + pr_warn("nand_bbt: error while erasing BBT block %d\n", + res); + mark_bbt_block_bad(this, td, chip, block); + continue; + } 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) { + pr_warn("nand_bbt: error while writing BBT block %d\n", + res); + mark_bbt_block_bad(this, td, chip, block); + continue; + } pr_info("Bad block table written to 0x%012llx, version 0x%02X\n", (unsigned long long)to, td->version[chip]); -- 2.8.1