From patchwork Wed Jul 31 00:52:56 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Norris X-Patchwork-Id: 263548 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 6B1EC2C00AD for ; Wed, 31 Jul 2013 10:54:23 +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 1V4Kg2-0005fl-NE; Wed, 31 Jul 2013 00:54:07 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1V4Kfw-0007jk-Dy; Wed, 31 Jul 2013 00:54:00 +0000 Received: from mail-pb0-x22f.google.com ([2607:f8b0:400e:c01::22f]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1V4Kfg-0007e9-QK for linux-mtd@lists.infradead.org; Wed, 31 Jul 2013 00:53:57 +0000 Received: by mail-pb0-f47.google.com with SMTP id rr13so94148pbb.34 for ; Tue, 30 Jul 2013 17:53:23 -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=1z2r7fOtqhYpAsePhPUdspcqWOc8d2WbzP1BP3GOSiU=; b=FDvOlyQ8IlRPPXFK4c82RoWOCFj6f02rRUGykCiyd25SkZWo3yTbLzdXVBGA1Qr3Si He1x0bcI5pl9qNHdgQpRUFDvVHPz18NqOGuS9gMCSd96af7GsLzURKraLw5RyKfYm2SS U/M/dVEekkr9w+IE+yD12rFSWyLHVDHTWj/xs9QK9WhD+cFcrKtUxNcFvuySak7ogUXF Xipolzh4Rw6QS/Z6pQ73mbv+Jvd7UcFyR3uMcsUmyw+HEa/kyhZlsvcfJpilTqZnObtD m1z1ewifAMj1/8ZMyi+pEKsWHyTWcOf/UYNJBaLFTVKk2mELpSiWXNiiJQM9MCdfV+3T wGRA== X-Received: by 10.68.130.234 with SMTP id oh10mr77021241pbb.129.1375232003371; Tue, 30 Jul 2013 17:53:23 -0700 (PDT) Received: from localhost.localdomain (pv154241.reshsg.uci.edu. [169.234.154.241]) by mx.google.com with ESMTPSA id y6sm85709572pbl.23.2013.07.30.17.53.22 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 30 Jul 2013 17:53:22 -0700 (PDT) From: Brian Norris To: Subject: [PATCH v2 2/6] mtd: nand: remove multiplied-by-2 block logic Date: Tue, 30 Jul 2013 17:52:56 -0700 Message-Id: <1375231980-13721-3-git-send-email-computersforpeace@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1375231980-13721-1-git-send-email-computersforpeace@gmail.com> References: <1374647279-14083-1-git-send-email-computersforpeace@gmail.com> <1375231980-13721-1-git-send-email-computersforpeace@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130730_205345_163464_CFDE991F X-CRM114-Status: GOOD ( 21.96 ) 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 , Ezequiel Garcia , 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 The previous patch makes the following comment obsolete: /* * Note that numblocks is 2 * (real numblocks) here, see i+=2 * below as it makes shifting and masking less painful */ I don't think it ever could have been "less painful" to have to shift an extra bit (or 2, or 3) at various points in nand_bbt.c (and even outside, since we leak our in-memory format). But now it is certainly more painful, since we have nice macros and functions to retrieve the relevant portions of the BBT. This patch removes any points where the block number is doubled/halved/otherwise-shifted, instead representing the block number in its most natural form: as the actual block number. Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_bbt.c | 83 ++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 48 deletions(-) diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 4c57a9b..3ff9d36 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -181,7 +181,7 @@ static u32 add_marker_len(struct nand_bbt_descr *td) * @page: the starting page * @num: the number of bbt descriptors to read * @td: the bbt describtion table - * @offs: offset in the memory table + * @offs: block number offset in the table * * Read the bad block table starting from page. */ @@ -231,15 +231,15 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, /* Analyse data */ for (i = 0; i < len; i++) { uint8_t dat = buf[i]; - for (j = 0; j < 8; j += bits, act += 2) { + for (j = 0; j < 8; j += bits, act++) { uint8_t tmp = (dat >> j) & msk; if (tmp == msk) continue; if (reserved_block_code && (tmp == reserved_block_code)) { pr_info("nand_read_bbt: reserved block at 0x%012llx\n", - (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); - bbt_mark_entry(this, (offs << 2) + - (act >> 1), + (loff_t)(offs + act) << + this->bbt_erase_shift); + bbt_mark_entry(this, offs + act, BBT_BLOCK_RESERVED); mtd->ecc_stats.bbtblocks++; continue; @@ -249,15 +249,14 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, * move this message to pr_debug. */ pr_info("nand_read_bbt: bad block at 0x%012llx\n", - (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); + (loff_t)(offs + act) << + this->bbt_erase_shift); /* Factory marked bad or worn out? */ if (tmp == 0) - bbt_mark_entry(this, (offs << 2) + - (act >> 1), + bbt_mark_entry(this, offs + act, BBT_BLOCK_FACTORY_BAD); else - bbt_mark_entry(this, (offs << 2) + - (act >> 1), + bbt_mark_entry(this, offs + act, BBT_BLOCK_WORN); mtd->ecc_stats.badblocks++; } @@ -293,7 +292,7 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc td, offs); if (res) return res; - offs += this->chipsize >> (this->bbt_erase_shift + 2); + offs += this->chipsize >> this->bbt_erase_shift; } } else { res = read_bbt(mtd, buf, td->pages[0], @@ -517,11 +516,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, } if (chip == -1) { - /* - * Note that numblocks is 2 * (real numblocks) here, see i+=2 - * below as it makes shifting and masking less painful - */ - numblocks = mtd->size >> (this->bbt_erase_shift - 1); + numblocks = mtd->size >> this->bbt_erase_shift; startblock = 0; from = 0; } else { @@ -530,16 +525,16 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, chip + 1, this->numchips); return -EINVAL; } - numblocks = this->chipsize >> (this->bbt_erase_shift - 1); + numblocks = this->chipsize >> this->bbt_erase_shift; startblock = chip * numblocks; numblocks += startblock; - from = (loff_t)startblock << (this->bbt_erase_shift - 1); + from = (loff_t)startblock << this->bbt_erase_shift; } if (this->bbt_options & NAND_BBT_SCANLASTPAGE) from += mtd->erasesize - (mtd->writesize * numpages); - for (i = startblock; i < numblocks;) { + for (i = startblock; i < numblocks; i++) { int ret; BUG_ON(bd->options & NAND_BBT_NO_OOB); @@ -554,13 +549,12 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, return ret; if (ret) { - bbt_mark_entry(this, i >> 1, BBT_BLOCK_FACTORY_BAD); + bbt_mark_entry(this, i, BBT_BLOCK_FACTORY_BAD); pr_warn("Bad eraseblock %d at 0x%012llx\n", - i >> 1, (unsigned long long)from); + i, (unsigned long long)from); mtd->ecc_stats.badblocks++; } - i += 2; from += (1 << this->bbt_erase_shift); } return 0; @@ -683,9 +677,9 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, { struct nand_chip *this = mtd->priv; struct erase_info einfo; - int i, j, res, chip = 0; + int i, res, chip = 0; int bits, startblock, dir, page, offs, numblocks, sft, sftmsk; - int nrchips, bbtoffs, pageoffs, ooboffs; + int nrchips, pageoffs, ooboffs; uint8_t msk[4]; uint8_t rcode = td->reserved_block_code; size_t retlen, len = 0; @@ -775,8 +769,6 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, default: return -EINVAL; } - bbtoffs = chip * (numblocks >> 2); - to = ((loff_t)page) << this->page_shift; /* Must we save the block contents? */ @@ -841,16 +833,12 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, buf[ooboffs + td->veroffs] = td->version[chip]; /* Walk through the memory table */ - for (i = 0; i < numblocks;) { + for (i = 0; i < numblocks; i++) { uint8_t dat; - dat = bbt_get_entry(this, (bbtoffs << 2) + i); - for (j = 0; j < 4; j++, i++) { - int sftcnt = (i << (3 - sft)) & sftmsk; - /* Do not store the reserved bbt blocks! */ - buf[offs + (i >> sft)] &= - ~(msk[dat & 0x03] << sftcnt); - dat >>= 2; - } + int sftcnt = (i << (3 - sft)) & sftmsk; + dat = bbt_get_entry(this, chip * numblocks + i); + /* Do not store the reserved bbt blocks! */ + buf[offs + (i >> sft)] &= ~(msk[dat] << sftcnt); } memset(&einfo, 0, sizeof(einfo)); @@ -1053,12 +1041,12 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) if (td->pages[i] == -1) continue; block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); - block <<= 1; - oldval = bbt_get_entry(this, block >> 1); - bbt_mark_entry(this, block >> 1, BBT_BLOCK_RESERVED); + oldval = bbt_get_entry(this, block); + bbt_mark_entry(this, block, BBT_BLOCK_RESERVED); if ((oldval != BBT_BLOCK_RESERVED) && td->reserved_block_code) - nand_update_bbt(mtd, (loff_t)block << (this->bbt_erase_shift - 1)); + nand_update_bbt(mtd, (loff_t)block << + this->bbt_erase_shift); continue; } update = 0; @@ -1066,13 +1054,12 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) block = ((i + 1) * nrblocks) - td->maxblocks; else block = i * nrblocks; - block <<= 1; for (j = 0; j < td->maxblocks; j++) { - oldval = bbt_get_entry(this, block >> 1); - bbt_mark_entry(this, block >> 1, BBT_BLOCK_RESERVED); + oldval = bbt_get_entry(this, block); + bbt_mark_entry(this, block, BBT_BLOCK_RESERVED); if (oldval != BBT_BLOCK_RESERVED) update = 1; - block += 2; + block++; } /* * If we want reserved blocks to be recorded to flash, and some @@ -1080,7 +1067,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) * bbts. This should only happen once. */ if (update && td->reserved_block_code) - nand_update_bbt(mtd, (loff_t)(block - 2) << (this->bbt_erase_shift - 1)); + nand_update_bbt(mtd, (loff_t)(block - 1) << + this->bbt_erase_shift); } } @@ -1385,13 +1373,12 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) int block; uint8_t res; - /* Get block number * 2 */ - block = (int)(offs >> (this->bbt_erase_shift - 1)); - res = bbt_get_entry(this, block >> 1); + block = (int)(offs >> this->bbt_erase_shift); + res = bbt_get_entry(this, block); pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: " "(block %d) 0x%02x\n", - (unsigned int)offs, block >> 1, res); + (unsigned int)offs, block, res); switch ((int)res) { case BBT_BLOCK_GOOD: