From: Lee Jones <lee.jones@linaro.org>
To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org
Cc: angus.clark@st.com, kernel@stlinux.com, lee.jones@linaro.org,
linux-mtd@lists.infradead.org, pekon@ti.com,
computersforpeace@gmail.com, dwmw2@infradead.org
Subject: [RFC 28/47] mtd: nand: stm_nand_bch: update flash-resident BBT(s)
Date: Tue, 25 Mar 2014 08:19:45 +0000 [thread overview]
Message-ID: <1395735604-26706-29-git-send-email-lee.jones@linaro.org> (raw)
In-Reply-To: <1395735604-26706-1-git-send-email-lee.jones@linaro.org>
Search for suitable block, erase and write table data to flash. If any
errors occur on selected block, mark it as bad and select another one.
Keep trying until both the Primary and Mirror BBTs are a) synced and
b) written successfully to flash.
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
drivers/mtd/nand/stm_nand_bch.c | 143 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 143 insertions(+)
diff --git a/drivers/mtd/nand/stm_nand_bch.c b/drivers/mtd/nand/stm_nand_bch.c
index 76ed99b..a4f3e46 100644
--- a/drivers/mtd/nand/stm_nand_bch.c
+++ b/drivers/mtd/nand/stm_nand_bch.c
@@ -59,6 +59,11 @@ static uint8_t ibbt_sigs[2][NAND_IBBT_SIGLEN] = {
{'1', 't', 'b', 'B'},
};
+static char *bbt_strs[] = {
+ "primary",
+ "mirror",
+};
+
/* IBBT header */
struct nand_ibbt_header {
uint8_t signature[4]; /* "Bbt0" or "1tbB" signature */
@@ -570,6 +575,144 @@ static int bch_write_bbt_data(struct nandi_controller *nandi,
return 0;
}
+/*
+ * Update Flash-resident BBT:
+ * erase/search suitable block, and write table data to Flash
+ */
+static int bch_update_bbt(struct nandi_controller *nandi,
+ struct nandi_bbt_info *bbt_info,
+ int bak, uint8_t vers)
+{
+ loff_t offs;
+ uint32_t block;
+ uint32_t block_lower;
+ uint32_t block_other;
+
+ block_other = bbt_info->bbt_block[(bak+1)%2];
+ block_lower = nandi->blocks_per_device - NAND_IBBT_NBLOCKS;
+
+ for (block = bbt_info->bbt_block[bak]; block >= block_lower; block--) {
+ offs = (loff_t)block << nandi->block_shift;
+
+ /* Skip if block used by other table */
+ if (block == block_other)
+ continue;
+
+ /* Skip if block is marked bad */
+ if (bbt_is_block_bad(bbt_info->bbt, block))
+ continue;
+
+ /* Erase block, mark bad and skip on failure */
+ if (bch_erase_block(nandi, offs) & NAND_STATUS_FAIL) {
+ dev_info(nandi->dev,
+ "failed to erase block [%u:0x%012llx] while updating BBT\n",
+ block, offs);
+ vers++;
+ bbt_set_block_mark(bbt_info->bbt, block,
+ BBT_MARK_BAD_WEAR);
+ continue;
+ }
+
+ /* Write BBT, mark bad and skip on failure */
+ if (bch_write_bbt_data(nandi, bbt_info, block, bak, vers)) {
+ dev_info(nandi->dev,
+ "failed to write BBT to block [%u:0x%012llx]\n",
+ block, offs);
+ vers++;
+ bbt_set_block_mark(bbt_info->bbt, block,
+ BBT_MARK_BAD_WEAR);
+ continue;
+ }
+
+ /* Success */
+ bbt_info->bbt_block[bak] = block;
+ bbt_info->bbt_vers[bak] = vers;
+ break;
+ }
+
+ /* No space in BBT area */
+ if (block < block_lower) {
+ dev_err(nandi->dev, "no space left in BBT area\n");
+ dev_err(nandi->dev, "failed to update %s BBT\n", bbt_strs[bak]);
+ return -ENOSPC;
+ }
+
+ dev_info(nandi->dev, "wrote BBT [%s:%u] at 0x%012llx [%u]\n",
+ bbt_strs[bak], vers, offs, block);
+
+ return 0;
+}
+
+#define NAND_IBBT_UPDATE_PRIMARY 0x1
+#define NAND_IBBT_UPDATE_MIRROR 0x2
+#define NAND_IBBT_UPDATE_BOTH (NAND_IBBT_UPDATE_PRIMARY | \
+ NAND_IBBT_UPDATE_MIRROR)
+static char *bbt_update_strs[] = {
+ "",
+ "primary",
+ "mirror",
+ "both",
+};
+
+/*
+ * Update Flash-resident BBT(s):
+ * incrementing 'vers' number if required, and ensuring Primary
+ * and Mirror are kept in sync
+ */
+static int bch_update_bbts(struct nandi_controller *nandi,
+ struct nandi_bbt_info *bbt_info,
+ unsigned int update, uint8_t vers)
+{
+ int err;
+
+ dev_info(nandi->dev, "updating %s BBT(s)\n", bbt_update_strs[update]);
+
+ do {
+ /* Update Primary if specified */
+ if (update & NAND_IBBT_UPDATE_PRIMARY) {
+ err = bch_update_bbt(nandi, bbt_info, NAND_IBBT_PRIMARY,
+ vers);
+ /* Bail out on error (e.g. no space left in BBT area) */
+ if (err)
+ return err;
+
+ /*
+ * If update resulted in a new BBT version
+ * (e.g. Erase/Write fail on BBT block) update version
+ * here, and force update of other table.
+ */
+ if (bbt_info->bbt_vers[NAND_IBBT_PRIMARY] != vers) {
+ vers = bbt_info->bbt_vers[NAND_IBBT_PRIMARY];
+ update = NAND_IBBT_UPDATE_MIRROR;
+ }
+ }
+
+ /* Update Mirror if specified */
+ if (update & NAND_IBBT_UPDATE_MIRROR) {
+ err = bch_update_bbt(nandi, bbt_info, NAND_IBBT_MIRROR,
+ vers);
+ /* Bail out on error (e.g. no space left in BBT area) */
+ if (err)
+ return err;
+
+ /*
+ * If update resulted in a new BBT version
+ * (e.g. Erase/Write fail on BBT block) update version
+ * here, and force update of other table.
+ */
+ if (bbt_info->bbt_vers[NAND_IBBT_MIRROR] != vers) {
+ vers = bbt_info->bbt_vers[NAND_IBBT_MIRROR];
+ update = NAND_IBBT_UPDATE_PRIMARY;
+ }
+ }
+
+ /* Continue, until Primary and Mirror versions are in sync */
+ } while (bbt_info->bbt_vers[NAND_IBBT_PRIMARY] !=
+ bbt_info->bbt_vers[NAND_IBBT_MIRROR]);
+
+ return 0;
+}
+
/* Scan block for IBBT signature */
static int bch_find_ibbt_sig(struct nandi_controller *nandi,
uint32_t block, int *bak, uint8_t *vers,
--
1.8.3.2
next prev parent reply other threads:[~2014-03-25 8:21 UTC|newest]
Thread overview: 77+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-25 8:19 [RFC 00/47] mtd: nand: Add new driver supporting ST's BCH h/w Lee Jones
2014-03-25 8:19 ` [RFC 01/47] mtd: nand: export useful functions from core driver Lee Jones
2014-03-25 12:57 ` Ezequiel Garcia
2014-03-25 14:58 ` Lee Jones
2014-03-25 8:19 ` [RFC 02/47] mtd: nand: add ONFI NAND Timing Mode Specifications Lee Jones
2014-03-25 17:01 ` Jason Gunthorpe
2014-03-25 8:19 ` [RFC 03/47] mtd: nand: add shared register defines for ST's NAND Controller drivers Lee Jones
2014-03-25 8:19 ` [RFC 04/47] mtd: nand: adding ST's BCH NAND Controller driver Lee Jones
2014-03-25 8:19 ` [RFC 05/47] mtd: nand: stm_nand_bch: IRQ support for " Lee Jones
2014-03-26 7:10 ` Gupta, Pekon
2014-03-25 8:19 ` [RFC 06/47] mtd: nand: stm_nand_bch: change between BCH and Hamming modes Lee Jones
2014-03-25 8:19 ` [RFC 07/47] mtd: nand: stm_nand_bch: initialise the BCH Controller Lee Jones
2014-03-26 10:25 ` Gupta, Pekon
2014-04-30 10:22 ` Lee Jones
2014-04-30 10:59 ` Gupta, Pekon
2014-04-30 12:29 ` Lee Jones
2014-03-25 8:19 ` [RFC 08/47] mtd: nand: stm_nand_bch: supply clock support Lee Jones
2014-03-26 7:15 ` Gupta, Pekon
2014-03-25 8:19 ` [RFC 09/47] mtd: nand: stm_nand_bch: introduce and initialise some important data structures Lee Jones
2014-03-25 8:19 ` [RFC 10/47] mtd: nand: stm_nand_bch: initialise the Hamming Controller Lee Jones
2014-03-25 8:19 ` [RFC 11/47] mtd: nand: stm_nand_bch: add Power Management Lee Jones
2014-03-25 8:19 ` [RFC 12/47] mtd: nand: stm_nand_bch: scan for NAND devices Lee Jones
2014-03-25 8:19 ` [RFC 13/47] mtd: nand: stm_nand_bch: provide Device Tree support Lee Jones
2014-03-26 9:18 ` Gupta, Pekon
2014-04-30 12:54 ` Lee Jones
2014-05-05 6:55 ` Gupta, Pekon
2014-05-09 10:03 ` Lee Jones
2014-05-09 10:32 ` Gupta, Pekon
2014-05-09 10:38 ` Lee Jones
2014-05-19 14:02 ` Lee Jones
2014-03-25 8:19 ` [RFC 14/47] mtd: nand: stm_nand_bch: configure BCH and FLEX by ONFI timing mode Lee Jones
2014-03-25 8:19 ` [RFC 15/47] mtd: nand: stm_nand_bch: add compatible page size check Lee Jones
2014-03-25 8:19 ` [RFC 16/47] mtd: nand: stm_nand_bch: derive some working variables for latter use Lee Jones
2014-03-25 8:19 ` [RFC 17/47] mtd: nand: stm_nand_bch: automatically set EEC mode if requested Lee Jones
2014-03-25 8:19 ` [RFC 18/47] mtd: nand: stm_nand_bch: ensure configuration is compatible with this driver Lee Jones
2014-03-25 8:19 ` [RFC 19/47] mtd: nand: stm_nand_bch: configure BCH read/write/erase programs Lee Jones
2014-03-25 8:19 ` [RFC 20/47] mtd: nand: stm_nand_bch: initialise working buffers Lee Jones
2014-03-25 8:19 ` [RFC 21/47] mtd: nand: stm_nand_bch: provide shared BCH operations Lee Jones
2014-03-25 8:19 ` [RFC 22/47] mtd: nand: stm_nand_bch: check erased page for zeros Lee Jones
2014-03-25 8:19 ` [RFC 23/47] mtd: nand: stm_nand_bch: read and write page (BCH) Lee Jones
2014-03-26 10:17 ` Gupta, Pekon
2014-04-30 11:19 ` Lee Jones
2014-03-25 8:19 ` [RFC 24/47] mtd: nand: stm_nand_bch: find IBBT signature Lee Jones
2014-03-25 8:19 ` [RFC 25/47] mtd: nand: stm_nand_bch: bad block marking helpers Lee Jones
2014-03-25 8:19 ` [RFC 26/47] mtd: nand: stm_nand_bch: populate IBBT BCH Header Lee Jones
2014-03-25 8:19 ` [RFC 27/47] mtd: nand: stm_nand_bch: write IBBT to Flash Lee Jones
2014-03-25 8:19 ` Lee Jones [this message]
2014-03-25 8:19 ` [RFC 29/47] mtd: nand: stm_nand_bch: add Hamming-FLEX operations Lee Jones
2014-03-25 8:19 ` [RFC 30/47] mtd: nand: stm_nand_bch: read and write raw (FLEX) Lee Jones
2014-03-25 8:19 ` [RFC 31/47] mtd: nand: stm_nand_bch: scan block for BBM(s) according to specified BBT options Lee Jones
2014-03-25 8:19 ` [RFC 32/47] mtd: nand: stm_nand_bch: scan for BBMs and build memory-resident BBT Lee Jones
2014-03-25 8:19 ` [RFC 33/47] mtd: nand: stm_nand_bch: search for and load flash-resident BBT Lee Jones
2014-03-25 8:19 ` [RFC 34/47] mtd: nand: stm_nand_bch: " Lee Jones
2014-03-25 8:19 ` [RFC 35/47] mtd: nand: stm_nand_bch: dump bad blocks Lee Jones
2014-03-25 12:53 ` Ezequiel Garcia
2014-03-25 8:19 ` [RFC 36/47] mtd: nand: stm_nand_bch: parse partitions and register an MTD device Lee Jones
2014-03-25 8:19 ` [RFC 37/47] mtd: nand: stm_nand_bch: fetch the bit-flips threshold Lee Jones
2014-03-25 8:19 ` [RFC 38/47] mtd: nand: stm_nand_bch: check WP (FLEX) Lee Jones
2014-03-25 8:19 ` [RFC 39/47] mtd: nand: stm_nand_bch: read and write ops (FLEX) Lee Jones
2014-03-25 8:19 ` [RFC 40/47] mtd: nand: stm_nand_bch: MTD erase (BCH) Lee Jones
2014-03-25 8:19 ` [RFC 41/47] mtd: nand: stm_nand_bch: MTD mark and check for bad blocks (BCH) Lee Jones
2014-03-25 8:19 ` [RFC 42/47] mtd: nand: stm_nand_bch: add read and write OOB (BCH) Lee Jones
2014-03-25 8:20 ` [RFC 43/47] mtd: nand: stm_nand_bch: read and write functions (BCH) Lee Jones
2014-03-26 10:31 ` Gupta, Pekon
2014-04-30 9:19 ` Lee Jones
2014-03-25 8:20 ` [RFC 44/47] mtd: nand: stm_nand_bch: MTD read and write (BCH) Lee Jones
2014-03-25 8:20 ` [RFC 45/47] mtd: nand: stm_nand_bch: read and write buffers (FLEX) Lee Jones
2014-03-25 8:20 ` [RFC 46/47] mtd: nand: mtd_nand_bch: add remaining FLEX functions Lee Jones
2014-03-25 8:20 ` [RFC 47/47] mtd: nand: stm_nand_bch: catch unsupported calls Lee Jones
2014-03-25 12:50 ` [RFC 00/47] mtd: nand: Add new driver supporting ST's BCH h/w Ezequiel Garcia
2014-03-25 13:11 ` Lee Jones
2014-03-25 22:00 ` Ezequiel Garcia
2014-03-26 7:28 ` Brian Norris
2014-03-27 10:28 ` Lee Jones
2014-04-01 11:29 ` Lee Jones
2014-04-10 20:00 ` Brian Norris
2014-04-30 9:57 ` Lee Jones
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1395735604-26706-29-git-send-email-lee.jones@linaro.org \
--to=lee.jones@linaro.org \
--cc=angus.clark@st.com \
--cc=computersforpeace@gmail.com \
--cc=dwmw2@infradead.org \
--cc=kernel@stlinux.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=pekon@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).