From patchwork Wed Jul 24 06:27:58 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Norris X-Patchwork-Id: 261290 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from casper.infradead.org (unknown [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 9EB5D2C00A4 for ; Wed, 24 Jul 2013 16:29:40 +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 1V1sZc-0007Z8-08; Wed, 24 Jul 2013 06:29:20 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1V1sZR-00022x-3K; Wed, 24 Jul 2013 06:29:09 +0000 Received: from mail-pb0-x234.google.com ([2607:f8b0:400e:c01::234]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1V1sZ8-0001y0-R8 for linux-mtd@lists.infradead.org; Wed, 24 Jul 2013 06:29:01 +0000 Received: by mail-pb0-f52.google.com with SMTP id xa12so9281763pbc.25 for ; Tue, 23 Jul 2013 23:28:29 -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:x-mailer:in-reply-to:references; bh=2XIg6XJ/EoZwqAiM4WChTFnlo5Z4jgEkC4w7ROsRi1I=; b=UZW/B6854ZbtRc4K6TefQh3cPOunFPRM4XNJUNSQiY8m6vfU3j+/p4xRvZYNi2/LhL AjzKJUUmrefYQqshGAI7Cr8UnfMuF9d60epVS7CVBOCRSod4TFzm+nxiqqc3ToOH/CJ0 DZ3Qb5c9s2EX+EJA6iHTbdX/ZQdX/oeRCE7EqaYWKX5/+HUNNAsOYuEzIpn7rBwsiHZU Y+RYV7Pqs7AL93lX7x3DpNHFQFYcAkarhqEVsVjF0BPMiDXYCLQ1w1OIBXd4xoL9kKV4 0HcAIsoteUixDUzdNGnEJoTSHXnH/15BNfs8ylIfDFz8UUQoNAOgrf8r+LE48TLhII/0 gnqw== X-Received: by 10.68.191.231 with SMTP id hb7mr38674662pbc.82.1374647309296; Tue, 23 Jul 2013 23:28:29 -0700 (PDT) Received: from ld-irv-0074.broadcom.com (5520-maca-inet1-outside.broadcom.com. [216.31.211.11]) by mx.google.com with ESMTPSA id ry2sm45816723pbc.41.2013.07.23.23.28.28 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 23 Jul 2013 23:28:28 -0700 (PDT) From: Brian Norris To: Subject: [PATCH 3/4] mtd: nand: hide in-memory BBT implementation details Date: Tue, 23 Jul 2013 23:27:58 -0700 Message-Id: <1374647279-14083-4-git-send-email-computersforpeace@gmail.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1374647279-14083-1-git-send-email-computersforpeace@gmail.com> References: <1374647279-14083-1-git-send-email-computersforpeace@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130724_022851_112963_DBD8D927 X-CRM114-Status: GOOD ( 19.68 ) X-Spam-Score: -2.0 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (computersforpeace[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -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 -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature Cc: Brian Norris , David Woodhouse , Artem Bityutskiy 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: , MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org nand_base.c shouldn't have to know the implementation details of nand_bbt's in-memory BBT. Specifically, nand_base shouldn't perform the bit masking and shifting to isolate a BBT entry. Instead, just move some of the BBT code into a new nand_markbad_bbt() interface. This interface allows external users (i.e., nand_base) to mark a single block as bad in the BBT. Then nand_bbt will take care of modifying the in-memory BBT and updating the flash-based BBT (if applicable). Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_base.c | 32 +++++++++++--------------------- drivers/mtd/nand/nand_bbt.c | 28 ++++++++++++++++++++++++++-- include/linux/mtd/nand.h | 2 +- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index a9119f7..da3ba77 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -374,22 +374,20 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) * block table(s) and/or marker(s)). We only allow the hardware driver to * specify how to write bad block markers to OOB (chip->block_markbad). * - * We try operations in the following order, according to our bbt_options - * (NAND_BBT_NO_OOB_BBM and NAND_BBT_USE_FLASH): + * We try operations in the following order: * (1) erase the affected block, to allow OOB marker to be written cleanly - * (2) update in-memory BBT - * (3) write bad block marker to OOB area of affected block - * (4) update flash-based BBT - * Note that we retain the first error encountered in (3) or (4), finish the + * (2) write bad block marker to OOB area of affected block (unless flag + * NAND_BBT_NO_OOB_BBM is present) + * (3) update the BBT + * Note that we retain the first error encountered in (2) or (3), finish the * procedures, and dump the error in the end. */ static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs) { struct nand_chip *chip = mtd->priv; - int block, res, ret = 0; - int write_oob = !(chip->bbt_options & NAND_BBT_NO_OOB_BBM); + int res, ret = 0; - if (write_oob) { + if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) { struct erase_info einfo; /* Attempt erase before marking OOB */ @@ -398,24 +396,16 @@ static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs) einfo.addr = ofs; einfo.len = 1 << chip->phys_erase_shift; nand_erase_nand(mtd, &einfo, 0); - } - - /* Get block number */ - block = (int)(ofs >> chip->bbt_erase_shift); - /* Mark block bad in memory-based BBT */ - if (chip->bbt) - chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); - /* Write bad block marker to OOB */ - if (write_oob) { + /* Write bad block marker to OOB */ nand_get_device(mtd, FL_WRITING); ret = chip->block_markbad(mtd, ofs); nand_release_device(mtd); } - /* Update flash-based bad block table */ - if (chip->bbt_options & NAND_BBT_USE_FLASH) { - res = nand_update_bbt(mtd, ofs); + /* Mark block bad in BBT */ + if (chip->bbt) { + res = nand_markbad_bbt(mtd, ofs); if (!ret) ret = res; } diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index bac481a..ae3fb58 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -79,6 +79,8 @@ #define BBT_ENTRY_MASK 0x03 #define BBT_ENTRY_SHIFT 2 +static int nand_update_bbt(struct mtd_info *mtd, loff_t offs); + static inline uint8_t bbt_get_entry(struct nand_chip *chip, int block) { uint8_t entry = chip->bbt[block >> BBT_ENTRY_SHIFT]; @@ -1194,13 +1196,13 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) } /** - * nand_update_bbt - [NAND Interface] update bad block table(s) + * nand_update_bbt - update bad block table(s) * @mtd: MTD device structure * @offs: the offset of the newly marked block * * The function updates the bad block table(s). */ -int nand_update_bbt(struct mtd_info *mtd, loff_t offs) +static int nand_update_bbt(struct mtd_info *mtd, loff_t offs) { struct nand_chip *this = mtd->priv; int len, res = 0; @@ -1390,5 +1392,27 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) return 1; } +/** + * nand_markbad_bbt - [NAND Interface] Mark a block bad in the BBT + * @mtd: MTD device structure + * @offs: offset of the bad block + */ +int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs) +{ + struct nand_chip *this = mtd->priv; + int block, ret = 0; + + block = (int)(offs >> this->bbt_erase_shift); + + /* Mark bad block in memory */ + bbt_mark_entry(this, block, BBT_BLOCK_WORN); + + /* Update flash-based bad block table */ + if (this->bbt_options & NAND_BBT_USE_FLASH) + ret = nand_update_bbt(mtd, offs); + + return ret; +} + EXPORT_SYMBOL(nand_scan_bbt); EXPORT_SYMBOL(nand_default_bbt); diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 0745a42..9f7b248 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -628,8 +628,8 @@ extern struct nand_flash_dev nand_flash_ids[]; extern struct nand_manufacturers nand_manuf_ids[]; extern int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd); -extern int nand_update_bbt(struct mtd_info *mtd, loff_t offs); extern int nand_default_bbt(struct mtd_info *mtd); +extern int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs); extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt); extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, int allowbbt);