diff --git a/target/linux/generic/files-5.4/drivers/mtd/nmbm/nmbm-core.c b/target/linux/generic/files-5.4/drivers/mtd/nmbm/nmbm-core.c
new file mode 100644
index 0000000..9419832
--- /dev/null
+++ b/target/linux/generic/files-5.4/drivers/mtd/nmbm/nmbm-core.c
@@ -0,0 +1,2814 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Copyright (C) 2021 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include "nmbm-private.h"
+
+#include "nmbm-debug.h"
+
+#define NMBM_VER_MAJOR			1
+#define NMBM_VER_MINOR			0
+#define NMBM_VER			NMBM_VERSION_MAKE(NMBM_VER_MAJOR, \
+							  NMBM_VER_MINOR)
+
+#define NMBM_ALIGN(v, a)		(((v) + (a) - 1) & ~((a) - 1))
+
+/*****************************************************************************/
+/* Logging related functions */
+/*****************************************************************************/
+
+/*
+ * nmbm_log_lower - Print log using OS specific routine
+ * @nld: NMBM lower device structure
+ * @level: log level
+ * @fmt: format string
+ */
+static void nmbm_log_lower(struct nmbm_lower_device *nld,
+			   enum nmbm_log_category level, const char *fmt, ...)
+{
+	va_list ap;
+
+	if (!nld->logprint)
+		return;
+
+	va_start(ap, fmt);
+	nld->logprint(nld->arg, level, fmt, ap);
+	va_end(ap);
+}
+
+/*
+ * nmbm_log - Print log using OS specific routine
+ * @ni: NMBM instance structure
+ * @level: log level
+ * @fmt: format string
+ */
+static void nmbm_log(struct nmbm_instance *ni, enum nmbm_log_category level,
+		     const char *fmt, ...)
+{
+	va_list ap;
+
+	if (!ni)
+		return;
+
+	if (!ni->lower.logprint || level < ni->log_display_level)
+		return;
+
+	va_start(ap, fmt);
+	ni->lower.logprint(ni->lower.arg, level, fmt, ap);
+	va_end(ap);
+}
+
+/*
+ * nmbm_set_log_level - Set log display level
+ * @ni: NMBM instance structure
+ * @level: log display level
+ */
+enum nmbm_log_category nmbm_set_log_level(struct nmbm_instance *ni,
+					  enum nmbm_log_category level)
+{
+	enum nmbm_log_category old;
+
+	if (!ni)
+		return __NMBM_LOG_MAX;
+
+	old = ni->log_display_level;
+	ni->log_display_level = level;
+	return old;
+}
+
+/*
+ * nlog_table_creation - Print log of table creation event
+ * @ni: NMBM instance structure
+ * @main_table: whether the table is main info table
+ * @start_ba: start block address of the table
+ * @end_ba: block address after the end of the table
+ */
+static void nlog_table_creation(struct nmbm_instance *ni, bool main_table,
+			       uint32_t start_ba, uint32_t end_ba)
+{
+	if (start_ba == end_ba - 1)
+		nlog_info(ni, "%s info table has been written to block %u\n",
+			 main_table ? "Main" : "Backup", start_ba);
+	else
+		nlog_info(ni, "%s info table has been written to block %u-%u\n",
+			 main_table ? "Main" : "Backup", start_ba, end_ba - 1);
+
+	nmbm_mark_block_color_info_table(ni, start_ba, end_ba - 1);
+}
+
+/*
+ * nlog_table_update - Print log of table update event
+ * @ni: NMBM instance structure
+ * @main_table: whether the table is main info table
+ * @start_ba: start block address of the table
+ * @end_ba: block address after the end of the table
+ */
+static void nlog_table_update(struct nmbm_instance *ni, bool main_table,
+			     uint32_t start_ba, uint32_t end_ba)
+{
+	if (start_ba == end_ba - 1)
+		nlog_debug(ni, "%s info table has been updated in block %u\n",
+			  main_table ? "Main" : "Backup", start_ba);
+	else
+		nlog_debug(ni, "%s info table has been updated in block %u-%u\n",
+			  main_table ? "Main" : "Backup", start_ba, end_ba - 1);
+
+	nmbm_mark_block_color_info_table(ni, start_ba, end_ba - 1);
+}
+
+/*
+ * nlog_table_found - Print log of table found event
+ * @ni: NMBM instance structure
+ * @first_table: whether the table is first found info table
+ * @write_count: write count of the info table
+ * @start_ba: start block address of the table
+ * @end_ba: block address after the end of the table
+ */
+static void nlog_table_found(struct nmbm_instance *ni, bool first_table,
+			    uint32_t write_count, uint32_t start_ba,
+			    uint32_t end_ba)
+{
+	if (start_ba == end_ba - 1)
+		nlog_info(ni, "%s info table with writecount %u found in block %u\n",
+			 first_table ? "First" : "Second", write_count,
+			 start_ba);
+	else
+		nlog_info(ni, "%s info table with writecount %u found in block %u-%u\n",
+			 first_table ? "First" : "Second", write_count,
+			 start_ba, end_ba - 1);
+
+	nmbm_mark_block_color_info_table(ni, start_ba, end_ba - 1);
+}
+
+/*****************************************************************************/
+/* Address conversion functions */
+/*****************************************************************************/
+
+/*
+ * addr2ba - Convert a linear address to block address
+ * @ni: NMBM instance structure
+ * @addr: Linear address
+ */
+static uint32_t addr2ba(struct nmbm_instance *ni, uint64_t addr)
+{
+	return addr >> ni->erasesize_shift;
+}
+
+/*
+ * ba2addr - Convert a block address to linear address
+ * @ni: NMBM instance structure
+ * @ba: Block address
+ */
+static uint64_t ba2addr(struct nmbm_instance *ni, uint32_t ba)
+{
+	return (uint64_t)ba << ni->erasesize_shift;
+}
+/*
+ * size2blk - Get minimum required blocks for storing specific size of data
+ * @ni: NMBM instance structure
+ * @size: size for storing
+ */
+static uint32_t size2blk(struct nmbm_instance *ni, uint64_t size)
+{
+	return (size + ni->lower.erasesize - 1) >> ni->erasesize_shift;
+}
+
+/*****************************************************************************/
+/* High level NAND chip APIs */
+/*****************************************************************************/
+
+/*
+ * nmbm_reset_chip - Reset NAND device
+ * @nld: Lower NAND chip structure
+ */
+static void nmbm_reset_chip(struct nmbm_instance *ni)
+{
+	if (ni->lower.reset_chip)
+		ni->lower.reset_chip(ni->lower.arg);
+}
+
+/*
+ * nmbm_read_phys_page - Read page with retry
+ * @ni: NMBM instance structure
+ * @addr: linear address where the data will be read from
+ * @data: the main data to be read
+ * @oob: the oob data to be read
+ * @mode: mode for processing oob data
+ *
+ * Read a page for at most NMBM_TRY_COUNT times.
+ *
+ * Return 0 for success, positive value for ecc error,
+ * negative value for other errors
+ */
+static int nmbm_read_phys_page(struct nmbm_instance *ni, uint64_t addr,
+			       void *data, void *oob, enum nmbm_oob_mode mode)
+{
+	int tries, ret;
+
+	for (tries = 0; tries < NMBM_TRY_COUNT; tries++) {
+		ret = ni->lower.read_page(ni->lower.arg, addr, data, oob, mode);
+		if (!ret)
+			return 0;
+
+		nmbm_reset_chip(ni);
+	}
+
+	if (ret < 0)
+		nlog_err(ni, "Page read failed at address 0x%08llx\n", addr);
+
+	return ret;
+}
+
+/*
+ * nmbm_write_phys_page - Write page with retry
+ * @ni: NMBM instance structure
+ * @addr: linear address where the data will be written to
+ * @data: the main data to be written
+ * @oob: the oob data to be written
+ * @mode: mode for processing oob data
+ *
+ * Write a page for at most NMBM_TRY_COUNT times.
+ */
+static bool nmbm_write_phys_page(struct nmbm_instance *ni, uint64_t addr,
+				 const void *data, const void *oob,
+				 enum nmbm_oob_mode mode)
+{
+	int tries, ret;
+
+	for (tries = 0; tries < NMBM_TRY_COUNT; tries++) {
+		ret = ni->lower.write_page(ni->lower.arg, addr, data, oob, mode);
+		if (!ret)
+			return true;
+
+		nmbm_reset_chip(ni);
+	}
+
+	nlog_err(ni, "Page write failed at address 0x%08llx\n", addr);
+
+	return false;
+}
+
+/*
+ * nmbm_erase_phys_block - Erase a block with retry
+ * @ni: NMBM instance structure
+ * @addr: Linear address
+ *
+ * Erase a block for at most NMBM_TRY_COUNT times.
+ */
+static bool nmbm_erase_phys_block(struct nmbm_instance *ni, uint64_t addr)
+{
+	int tries, ret;
+
+	for (tries = 0; tries < NMBM_TRY_COUNT; tries++) {
+		ret = ni->lower.erase_block(ni->lower.arg, addr);
+		if (!ret)
+			return true;
+
+		nmbm_reset_chip(ni);
+	}
+
+	nlog_err(ni, "Block erasure failed at address 0x%08llx\n", addr);
+
+	return false;
+}
+
+/*
+ * nmbm_check_bad_phys_block - Check whether a block is marked bad in OOB
+ * @ni: NMBM instance structure
+ * @ba: block address
+ */
+static bool nmbm_check_bad_phys_block(struct nmbm_instance *ni, uint32_t ba)
+{
+	uint64_t addr = ba2addr(ni, ba);
+	int ret;
+
+	if (ni->lower.is_bad_block)
+		return ni->lower.is_bad_block(ni->lower.arg, addr);
+
+	/* Treat ECC error as read success */
+	ret = nmbm_read_phys_page(ni, addr, NULL,
+				  ni->page_cache + ni->lower.writesize,
+				  NMBM_MODE_PLACE_OOB);
+	if (ret < 0)
+		return true;
+
+	return ni->page_cache[ni->lower.writesize] != 0xff;
+}
+
+/*
+ * nmbm_mark_phys_bad_block - Mark a block bad
+ * @ni: NMBM instance structure
+ * @addr: Linear address
+ */
+static int nmbm_mark_phys_bad_block(struct nmbm_instance *ni, uint32_t ba)
+{
+	uint64_t addr = ba2addr(ni, ba);
+	enum nmbm_log_category level;
+	uint32_t off;
+
+	nlog_info(ni, "Block %u [0x%08llx] will be marked bad\n", ba, addr);
+
+	if (ni->lower.mark_bad_block)
+		return ni->lower.mark_bad_block(ni->lower.arg, addr);
+
+	/* Whole page set to 0x00 */
+	memset(ni->page_cache, 0, ni->rawpage_size);
+
+	/* Write to all pages within this block, disable all errors */
+	level = nmbm_set_log_level(ni, __NMBM_LOG_MAX);
+
+	for (off = 0; off < ni->lower.erasesize; off += ni->lower.writesize) {
+		nmbm_write_phys_page(ni, addr + off, ni->page_cache,
+				     ni->page_cache + ni->lower.writesize,
+				     NMBM_MODE_RAW);
+	}
+
+	nmbm_set_log_level(ni, level);
+
+	return 0;
+}
+
+/*****************************************************************************/
+/* NMBM related functions */
+/*****************************************************************************/
+
+/*
+ * nmbm_check_header - Check whether a NMBM structure is valid
+ * @data: pointer to a NMBM structure with a NMBM header at beginning
+ * @size: Size of the buffer pointed by @header
+ *
+ * The size of the NMBM structure may be larger than NMBM header,
+ * e.g. block mapping table and block state table.
+ */
+static bool nmbm_check_header(const void *data, uint32_t size)
+{
+	const struct nmbm_header *header = data;
+	struct nmbm_header nhdr;
+	uint32_t new_checksum;
+
+	/*
+	 * Make sure expected structure size is equal or smaller than
+	 * buffer size.
+	 */
+	if (header->size > size)
+		return false;
+
+	memcpy(&nhdr, data, sizeof(nhdr));
+
+	nhdr.checksum = 0;
+	new_checksum = nmbm_crc32(0, &nhdr, sizeof(nhdr));
+	if (header->size > sizeof(nhdr))
+		new_checksum = nmbm_crc32(new_checksum,
+			(const uint8_t *)data + sizeof(nhdr),
+			header->size - sizeof(nhdr));
+
+	if (header->checksum != new_checksum)
+		return false;
+
+	return true;
+}
+
+/*
+ * nmbm_update_checksum - Update checksum of a NMBM structure
+ * @header: pointer to a NMBM structure with a NMBM header at beginning
+ *
+ * The size of the NMBM structure must be specified by @header->size
+ */
+static void nmbm_update_checksum(struct nmbm_header *header)
+{
+	header->checksum = 0;
+	header->checksum = nmbm_crc32(0, header, header->size);
+}
+
+/*
+ * nmbm_get_spare_block_count - Calculate number of blocks should be reserved
+ * @block_count: number of blocks of data
+ *
+ * Calculate number of blocks should be reserved for data
+ */
+static uint32_t nmbm_get_spare_block_count(uint32_t block_count)
+{
+	uint32_t val;
+
+	val = (block_count + NMBM_SPARE_BLOCK_DIV / 2) / NMBM_SPARE_BLOCK_DIV;
+	val *= NMBM_SPARE_BLOCK_MULTI;
+
+	if (val < NMBM_SPARE_BLOCK_MIN)
+		val = NMBM_SPARE_BLOCK_MIN;
+
+	return val;
+}
+
+/*
+ * nmbm_get_block_state_raw - Get state of a block from raw block state table
+ * @block_state: pointer to raw block state table (bitmap)
+ * @ba: block address
+ */
+static uint32_t nmbm_get_block_state_raw(nmbm_bitmap_t *block_state,
+					 uint32_t ba)
+{
+	uint32_t unit, shift;
+
+	unit = ba / NMBM_BITMAP_BLOCKS_PER_UNIT;
+	shift = (ba % NMBM_BITMAP_BLOCKS_PER_UNIT) * NMBM_BITMAP_BITS_PER_BLOCK;
+
+	return (block_state[unit] >> shift) & BLOCK_ST_MASK;
+}
+
+/*
+ * nmbm_get_block_state - Get state of a block from block state table
+ * @ni: NMBM instance structure
+ * @ba: block address
+ */
+static uint32_t nmbm_get_block_state(struct nmbm_instance *ni, uint32_t ba)
+{
+	return nmbm_get_block_state_raw(ni->block_state, ba);
+}
+
+/*
+ * nmbm_set_block_state - Set state of a block to block state table
+ * @ni: NMBM instance structure
+ * @ba: block address
+ * @state: block state
+ *
+ * Set state of a block. If the block state changed, ni->block_state_changed
+ * will be increased.
+ */
+static bool nmbm_set_block_state(struct nmbm_instance *ni, uint32_t ba,
+				 uint32_t state)
+{
+	uint32_t unit, shift, orig;
+	nmbm_bitmap_t uv;
+
+	unit = ba / NMBM_BITMAP_BLOCKS_PER_UNIT;
+	shift = (ba % NMBM_BITMAP_BLOCKS_PER_UNIT) * NMBM_BITMAP_BITS_PER_BLOCK;
+
+	orig = (ni->block_state[unit] >> shift) & BLOCK_ST_MASK;
+	state &= BLOCK_ST_MASK;
+
+	uv = ni->block_state[unit] & (~(BLOCK_ST_MASK << shift));
+	uv |= state << shift;
+	ni->block_state[unit] = uv;
+
+	if (state == BLOCK_ST_BAD)
+		nmbm_mark_block_color_bad(ni, ba);
+
+	if (orig != state) {
+		ni->block_state_changed++;
+		return true;
+	}
+
+	return false;
+}
+
+/*
+ * nmbm_block_walk_asc - Skip specified number of good blocks, ascending addr.
+ * @ni: NMBM instance structure
+ * @ba: start physical block address
+ * @nba: return physical block address after walk
+ * @count: number of good blocks to be skipped
+ * @limit: highest block address allowed for walking
+ *
+ * Start from @ba, skipping any bad blocks, counting @count good blocks, and
+ * return the next good block address.
+ *
+ * If no enough good blocks counted while @limit reached, false will be returned.
+ *
+ * If @count == 0, nearest good block address will be returned.
+ * @limit is not counted in walking.
+ */
+static bool nmbm_block_walk_asc(struct nmbm_instance *ni, uint32_t ba,
+				uint32_t *nba, uint32_t count,
+				uint32_t limit)
+{
+	int32_t nblock = count;
+
+	if (limit >= ni->block_count)
+		limit = ni->block_count - 1;
+
+	while (ba < limit) {
+		if (nmbm_get_block_state(ni, ba) == BLOCK_ST_GOOD)
+			nblock--;
+
+		if (nblock < 0) {
+			*nba = ba;
+			return true;
+		}
+
+		ba++;
+	}
+
+	return false;
+}
+
+/*
+ * nmbm_block_walk_desc - Skip specified number of good blocks, descending addr
+ * @ni: NMBM instance structure
+ * @ba: start physical block address
+ * @nba: return physical block address after walk
+ * @count: number of good blocks to be skipped
+ * @limit: lowest block address allowed for walking
+ *
+ * Start from @ba, skipping any bad blocks, counting @count good blocks, and
+ * return the next good block address.
+ *
+ * If no enough good blocks counted while @limit reached, false will be returned.
+ *
+ * If @count == 0, nearest good block address will be returned.
+ * @limit is not counted in walking.
+ */
+static bool nmbm_block_walk_desc(struct nmbm_instance *ni, uint32_t ba,
+				 uint32_t *nba, uint32_t count, uint32_t limit)
+{
+	int32_t nblock = count;
+
+	if (limit >= ni->block_count)
+		limit = ni->block_count - 1;
+
+	while (ba > limit) {
+		if (nmbm_get_block_state(ni, ba) == BLOCK_ST_GOOD)
+			nblock--;
+
+		if (nblock < 0) {
+			*nba = ba;
+			return true;
+		}
+
+		ba--;
+	}
+
+	return false;
+}
+
+/*
+ * nmbm_block_walk - Skip specified number of good blocks from curr. block addr
+ * @ni: NMBM instance structure
+ * @ascending: whether to walk ascending
+ * @ba: start physical block address
+ * @nba: return physical block address after walk
+ * @count: number of good blocks to be skipped
+ * @limit: highest/lowest block address allowed for walking
+ *
+ * Start from @ba, skipping any bad blocks, counting @count good blocks, and
+ * return the next good block address.
+ *
+ * If no enough good blocks counted while @limit reached, false will be returned.
+ *
+ * If @count == 0, nearest good block address will be returned.
+ * @limit can be set to negative if no limit required.
+ * @limit is not counted in walking.
+ */
+static bool nmbm_block_walk(struct nmbm_instance *ni, bool ascending,
+			    uint32_t ba, uint32_t *nba, int32_t count,
+			    int32_t limit)
+{
+	if (ascending)
+		return nmbm_block_walk_asc(ni, ba, nba, count, limit);
+
+	return nmbm_block_walk_desc(ni, ba, nba, count, limit);
+}
+
+/*
+ * nmbm_scan_badblocks - Scan and record all bad blocks
+ * @ni: NMBM instance structure
+ *
+ * Scan the entire lower NAND chip and record all bad blocks in to block state
+ * table.
+ */
+static void nmbm_scan_badblocks(struct nmbm_instance *ni)
+{
+	uint32_t ba;
+
+	for (ba = 0; ba < ni->block_count; ba++) {
+		if (nmbm_check_bad_phys_block(ni, ba)) {
+			nmbm_set_block_state(ni, ba, BLOCK_ST_BAD);
+			nlog_info(ni, "Bad block %u [0x%08llx]\n", ba,
+				 ba2addr(ni, ba));
+		}
+	}
+}
+
+/*
+ * nmbm_build_mapping_table - Build initial block mapping table
+ * @ni: NMBM instance structure
+ *
+ * The initial mapping table will be compatible with the stratage of
+ * factory production.
+ */
+static void nmbm_build_mapping_table(struct nmbm_instance *ni)
+{
+	uint32_t pb, lb;
+
+	for (pb = 0, lb = 0; pb < ni->mgmt_start_ba; pb++) {
+		if (nmbm_get_block_state(ni, pb) == BLOCK_ST_BAD)
+			continue;
+
+		/* Always map to the next good block */
+		ni->block_mapping[lb++] = pb;
+	}
+
+	ni->data_block_count = lb;
+
+	/* Unusable/Management blocks */
+	for (pb = lb; pb < ni->block_count; pb++)
+		ni->block_mapping[pb] = -1;
+}
+
+/*
+ * nmbm_erase_range - Erase a range of blocks
+ * @ni: NMBM instance structure
+ * @ba: block address where the erasure will start
+ * @limit: top block address allowed for erasure
+ *
+ * Erase blocks within the specific range. Newly-found bad blocks will be
+ * marked.
+ *
+ * @limit is not counted into the allowed erasure address.
+ */
+static void nmbm_erase_range(struct nmbm_instance *ni, uint32_t ba,
+			     uint32_t limit)
+{
+	bool success;
+
+	while (ba < limit) {
+		WATCHDOG_RESET();
+
+		if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD)
+			goto next_block;
+
+		success = nmbm_erase_phys_block(ni, ba2addr(ni, ba));
+		if (success)
+			goto next_block;
+
+		nmbm_mark_phys_bad_block(ni, ba);
+		nmbm_set_block_state(ni, ba, BLOCK_ST_BAD);
+
+	next_block:
+		ba++;
+	}
+}
+
+/*
+ * nmbm_write_repeated_data - Write critical data to a block with retry
+ * @ni: NMBM instance structure
+ * @ba: block address where the data will be written to
+ * @data: the data to be written
+ * @size: size of the data
+ *
+ * Write data to every page of the block. Success only if all pages within
+ * this block have been successfully written.
+ *
+ * Make sure data size is not bigger than one page.
+ *
+ * This function will write and verify every page for at most
+ * NMBM_TRY_COUNT times.
+ */
+static bool nmbm_write_repeated_data(struct nmbm_instance *ni, uint32_t ba,
+				     const void *data, uint32_t size)
+{
+	uint64_t addr, off;
+	bool success;
+	int ret;
+
+	if (size > ni->lower.writesize)
+		return false;
+
+	addr = ba2addr(ni, ba);
+
+	for (off = 0; off < ni->lower.erasesize; off += ni->lower.writesize) {
+		WATCHDOG_RESET();
+
+		/* Prepare page data. fill 0xff to unused region */
+		memcpy(ni->page_cache, data, size);
+		memset(ni->page_cache + size, 0xff, ni->rawpage_size - size);
+
+		success = nmbm_write_phys_page(ni, addr + off, ni->page_cache,
+					       NULL, NMBM_MODE_PLACE_OOB);
+		if (!success)
+			return false;
+
+		/* Verify the data just written. ECC error indicates failure */
+		ret = nmbm_read_phys_page(ni, addr + off, ni->page_cache, NULL,
+					  NMBM_MODE_PLACE_OOB);
+		if (ret)
+			return false;
+
+		if (memcmp(ni->page_cache, data, size))
+			return false;
+	}
+
+	return true;
+}
+
+/*
+ * nmbm_write_signature - Write signature to NAND chip
+ * @ni: NMBM instance structure
+ * @limit: top block address allowed for writing
+ * @signature: the signature to be written
+ * @signature_ba: the actual block address where signature is written to
+ *
+ * Write signature within a specific range, from chip bottom to limit.
+ * At most one block will be written.
+ *
+ * @limit is not counted into the allowed write address.
+ */
+static bool nmbm_write_signature(struct nmbm_instance *ni, uint32_t limit,
+				 const struct nmbm_signature *signature,
+				 uint32_t *signature_ba)
+{
+	uint32_t ba = ni->block_count - 1;
+	bool success;
+
+	while (ba > limit) {
+		WATCHDOG_RESET();
+
+		if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD)
+			goto next_block;
+
+		success = nmbm_erase_phys_block(ni, ba2addr(ni, ba));
+		if (!success)
+			goto skip_bad_block;
+
+		success = nmbm_write_repeated_data(ni, ba, signature,
+						   sizeof(*signature));
+		if (success) {
+			*signature_ba = ba;
+			return true;
+		}
+
+	skip_bad_block:
+		nmbm_mark_phys_bad_block(ni, ba);
+		nmbm_set_block_state(ni, ba, BLOCK_ST_BAD);
+
+	next_block:
+		ba--;
+	};
+
+	return false;
+}
+
+/*
+ * nmbn_read_data - Read data
+ * @ni: NMBM instance structure
+ * @addr: linear address where the data will be read from
+ * @data: the data to be read
+ * @size: the size of data
+ *
+ * Read data range.
+ * Every page will be tried for at most NMBM_TRY_COUNT times.
+ *
+ * Return 0 for success, positive value for ecc error,
+ * negative value for other errors
+ */
+static int nmbn_read_data(struct nmbm_instance *ni, uint64_t addr, void *data,
+			  uint32_t size)
+{
+	uint64_t off = addr;
+	uint8_t *ptr = data;
+	uint32_t sizeremain = size, chunksize, leading;
+	int ret;
+
+	while (sizeremain) {
+		WATCHDOG_RESET();
+
+		leading = off & ni->writesize_mask;
+		chunksize = ni->lower.writesize - leading;
+		if (chunksize > sizeremain)
+			chunksize = sizeremain;
+
+		if (chunksize == ni->lower.writesize) {
+			ret = nmbm_read_phys_page(ni, off - leading, ptr, NULL,
+						  NMBM_MODE_PLACE_OOB);
+			if (ret)
+				return ret;
+		} else {
+			ret = nmbm_read_phys_page(ni, off - leading,
+						  ni->page_cache, NULL,
+						  NMBM_MODE_PLACE_OOB);
+			if (ret)
+				return ret;
+
+			memcpy(ptr, ni->page_cache + leading, chunksize);
+		}
+
+		off += chunksize;
+		ptr += chunksize;
+		sizeremain -= chunksize;
+	}
+
+	return 0;
+}
+
+/*
+ * nmbn_write_verify_data - Write data with validation
+ * @ni: NMBM instance structure
+ * @addr: linear address where the data will be written to
+ * @data: the data to be written
+ * @size: the size of data
+ *
+ * Write data and verify.
+ * Every page will be tried for at most NMBM_TRY_COUNT times.
+ */
+static bool nmbn_write_verify_data(struct nmbm_instance *ni, uint64_t addr,
+				   const void *data, uint32_t size)
+{
+	uint64_t off = addr;
+	const uint8_t *ptr = data;
+	uint32_t sizeremain = size, chunksize, leading;
+	bool success;
+	int ret;
+
+	while (sizeremain) {
+		WATCHDOG_RESET();
+
+		leading = off & ni->writesize_mask;
+		chunksize = ni->lower.writesize - leading;
+		if (chunksize > sizeremain)
+			chunksize = sizeremain;
+
+		/* Prepare page data. fill 0xff to unused region */
+		memset(ni->page_cache, 0xff, ni->rawpage_size);
+		memcpy(ni->page_cache + leading, ptr, chunksize);
+
+		success = nmbm_write_phys_page(ni, off - leading,
+					       ni->page_cache, NULL,
+					       NMBM_MODE_PLACE_OOB);
+		if (!success)
+			return false;
+
+		/* Verify the data just written. ECC error indicates failure */
+		ret = nmbm_read_phys_page(ni, off - leading, ni->page_cache,
+					  NULL, NMBM_MODE_PLACE_OOB);
+		if (ret)
+			return false;
+
+		if (memcmp(ni->page_cache + leading, ptr, chunksize))
+			return false;
+
+		off += chunksize;
+		ptr += chunksize;
+		sizeremain -= chunksize;
+	}
+
+	return true;
+}
+
+/*
+ * nmbm_write_mgmt_range - Write management data into NAND within a range
+ * @ni: NMBM instance structure
+ * @addr: preferred start block address for writing
+ * @limit: highest block address allowed for writing
+ * @data: the data to be written
+ * @size: the size of data
+ * @actual_start_ba: actual start block address of data
+ * @actual_end_ba: block address after the end of data
+ *
+ * @limit is not counted into the allowed write address.
+ */
+static bool nmbm_write_mgmt_range(struct nmbm_instance *ni, uint32_t ba,
+				  uint32_t limit, const void *data,
+				  uint32_t size, uint32_t *actual_start_ba,
+				  uint32_t *actual_end_ba)
+{
+	const uint8_t *ptr = data;
+	uint32_t sizeremain = size, chunksize;
+	bool success;
+
+	while (sizeremain && ba < limit) {
+		WATCHDOG_RESET();
+
+		chunksize = sizeremain;
+		if (chunksize > ni->lower.erasesize)
+			chunksize = ni->lower.erasesize;
+
+		if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD)
+			goto next_block;
+
+		success = nmbm_erase_phys_block(ni, ba2addr(ni, ba));
+		if (!success)
+			goto skip_bad_block;
+
+		success = nmbn_write_verify_data(ni, ba2addr(ni, ba), ptr,
+						 chunksize);
+		if (!success)
+			goto skip_bad_block;
+
+		if (sizeremain == size)
+			*actual_start_ba = ba;
+
+		ptr += chunksize;
+		sizeremain -= chunksize;
+
+		goto next_block;
+
+	skip_bad_block:
+		nmbm_mark_phys_bad_block(ni, ba);
+		nmbm_set_block_state(ni, ba, BLOCK_ST_BAD);
+
+	next_block:
+		ba++;
+	}
+
+	if (sizeremain)
+		return false;
+
+	*actual_end_ba = ba;
+
+	return true;
+}
+
+/*
+ * nmbm_generate_info_table_cache - Generate info table cache data
+ * @ni: NMBM instance structure
+ *
+ * Generate info table cache data to be written into flash.
+ */
+static bool nmbm_generate_info_table_cache(struct nmbm_instance *ni)
+{
+	bool changed = false;
+
+	memset(ni->info_table_cache, 0xff, ni->info_table_size);
+
+	memcpy(ni->info_table_cache + ni->info_table.state_table_off,
+	       ni->block_state, ni->state_table_size);
+
+	memcpy(ni->info_table_cache + ni->info_table.mapping_table_off,
+		ni->block_mapping, ni->mapping_table_size);
+
+	ni->info_table.header.magic = NMBM_MAGIC_INFO_TABLE;
+	ni->info_table.header.version = NMBM_VER;
+	ni->info_table.header.size = ni->info_table_size;
+
+	if (ni->block_state_changed || ni->block_mapping_changed) {
+		ni->info_table.write_count++;
+		changed = true;
+	}
+
+	memcpy(ni->info_table_cache, &ni->info_table, sizeof(ni->info_table));
+
+	nmbm_update_checksum((struct nmbm_header *)ni->info_table_cache);
+
+	return changed;
+}
+
+/*
+ * nmbm_write_info_table - Write info table into NAND within a range
+ * @ni: NMBM instance structure
+ * @ba: preferred start block address for writing
+ * @limit: highest block address allowed for writing
+ * @actual_start_ba: actual start block address of info table
+ * @actual_end_ba: block address after the end of info table
+ *
+ * @limit is counted into the allowed write address.
+ */
+static bool nmbm_write_info_table(struct nmbm_instance *ni, uint32_t ba,
+				  uint32_t limit, uint32_t *actual_start_ba,
+				  uint32_t *actual_end_ba)
+{
+	return nmbm_write_mgmt_range(ni, ba, limit, ni->info_table_cache,
+				     ni->info_table_size, actual_start_ba,
+				     actual_end_ba);
+}
+
+/*
+ * nmbm_mark_tables_clean - Mark info table `clean'
+ * @ni: NMBM instance structure
+ */
+static void nmbm_mark_tables_clean(struct nmbm_instance *ni)
+{
+	ni->block_state_changed = 0;
+	ni->block_mapping_changed = 0;
+}
+
+/*
+ * nmbm_try_reserve_blocks - Reserve blocks with compromisation
+ * @ni: NMBM instance structure
+ * @ba: start physical block address
+ * @nba: return physical block address after reservation
+ * @count: number of good blocks to be skipped
+ * @min_count: minimum number of good blocks to be skipped
+ * @limit: highest/lowest block address allowed for walking
+ *
+ * Reserve specific blocks. If failed, try to reserve as many as possible.
+ */
+static bool nmbm_try_reserve_blocks(struct nmbm_instance *ni, uint32_t ba,
+				    uint32_t *nba, uint32_t count,
+				    int32_t min_count, int32_t limit)
+{
+	int32_t nblocks = count;
+	bool success;
+
+	while (nblocks >= min_count) {
+		success = nmbm_block_walk(ni, true, ba, nba, nblocks, limit);
+		if (success)
+			return true;
+
+		nblocks--;
+	}
+
+	return false;
+}
+
+/*
+ * nmbm_rebuild_info_table - Build main & backup info table from scratch
+ * @ni: NMBM instance structure
+ * @allow_no_gap: allow no spare blocks between two tables
+ */
+static bool nmbm_rebuild_info_table(struct nmbm_instance *ni)
+{
+	uint32_t table_start_ba, table_end_ba, next_start_ba;
+	uint32_t main_table_end_ba;
+	bool success;
+
+	/* Set initial value */
+	ni->main_table_ba = 0;
+	ni->backup_table_ba = 0;
+	ni->mapping_blocks_ba = ni->mapping_blocks_top_ba;
+
+	/* Write main table */
+	success = nmbm_write_info_table(ni, ni->mgmt_start_ba,
+					ni->mapping_blocks_top_ba,
+					&table_start_ba, &table_end_ba);
+	if (!success) {
+		/* Failed to write main table, data will be lost */
+		nlog_emerg(ni, "Unable to write at least one info table!\n");
+		nlog_emerg(ni, "Please save your data before power off!\n");
+		ni->protected = 1;
+		return false;
+	}
+
+	/* Main info table is successfully written, record its offset */
+	ni->main_table_ba = table_start_ba;
+	main_table_end_ba = table_end_ba;
+
+	/* Adjust mapping_blocks_ba */
+	ni->mapping_blocks_ba = table_end_ba;
+
+	nmbm_mark_tables_clean(ni);
+
+	nlog_table_creation(ni, true, table_start_ba, table_end_ba);
+
+	/* Reserve spare blocks for main info table. */
+	success = nmbm_try_reserve_blocks(ni, table_end_ba,
+					  &next_start_ba,
+					  ni->info_table_spare_blocks, 0,
+					  ni->mapping_blocks_top_ba -
+					  size2blk(ni, ni->info_table_size));
+	if (!success) {
+		/* There is no spare block. */
+		nlog_debug(ni, "No room for backup info table\n");
+		return true;
+	}
+
+	/* Write backup info table. */
+	success = nmbm_write_info_table(ni, next_start_ba,
+					ni->mapping_blocks_top_ba,
+					&table_start_ba, &table_end_ba);
+	if (!success) {
+		/* There is no enough blocks for backup table. */
+		nlog_debug(ni, "No room for backup info table\n");
+		return true;
+	}
+
+	/* Backup table is successfully written, record its offset */
+	ni->backup_table_ba = table_start_ba;
+
+	/* Adjust mapping_blocks_off */
+	ni->mapping_blocks_ba = table_end_ba;
+
+	/* Erase spare blocks of main table to clean possible interference data */
+	nmbm_erase_range(ni, main_table_end_ba, ni->backup_table_ba);
+
+	nlog_table_creation(ni, false, table_start_ba, table_end_ba);
+
+	return true;
+}
+
+/*
+ * nmbm_rescue_single_info_table - Rescue when there is only one info table
+ * @ni: NMBM instance structure
+ *
+ * This function is called when there is only one info table exists.
+ * This function may fail if we can't write new info table
+ */
+static bool nmbm_rescue_single_info_table(struct nmbm_instance *ni)
+{
+	uint32_t table_start_ba, table_end_ba, write_ba;
+	bool success;
+
+	/* Try to write new info table in front of existing table */
+	success = nmbm_write_info_table(ni, ni->mgmt_start_ba,
+					ni->main_table_ba,
+					&table_start_ba,
+					&table_end_ba);
+	if (success) {
+		/*
+		 * New table becomes the main table, existing table becomes
+		 * the backup table.
+		 */
+		ni->backup_table_ba = ni->main_table_ba;
+		ni->main_table_ba = table_start_ba;
+
+		nmbm_mark_tables_clean(ni);
+
+		/* Erase spare blocks of main table to clean possible interference data */
+		nmbm_erase_range(ni, table_end_ba, ni->backup_table_ba);
+
+		nlog_table_creation(ni, true, table_start_ba, table_end_ba);
+
+		return true;
+	}
+
+	/* Try to reserve spare blocks for existing table */
+	success = nmbm_try_reserve_blocks(ni, ni->mapping_blocks_ba, &write_ba,
+					  ni->info_table_spare_blocks, 0,
+					  ni->mapping_blocks_top_ba -
+					  size2blk(ni, ni->info_table_size));
+	if (!success) {
+		nlog_warn(ni, "Failed to rescue single info table\n");
+		return false;
+	}
+
+	/* Try to write new info table next to the existing table */
+	while (write_ba >= ni->mapping_blocks_ba) {
+		WATCHDOG_RESET();
+
+		success = nmbm_write_info_table(ni, write_ba,
+						ni->mapping_blocks_top_ba,
+						&table_start_ba,
+						&table_end_ba);
+		if (success)
+			break;
+
+		write_ba--;
+	}
+
+	if (success) {
+		/* Erase spare blocks of main table to clean possible interference data */
+		nmbm_erase_range(ni, ni->mapping_blocks_ba, table_start_ba);
+
+		/* New table becomes the backup table */
+		ni->backup_table_ba = table_start_ba;
+		ni->mapping_blocks_ba = table_end_ba;
+
+		nmbm_mark_tables_clean(ni);
+
+		nlog_table_creation(ni, false, table_start_ba, table_end_ba);
+
+		return true;
+	}
+
+	nlog_warn(ni, "Failed to rescue single info table\n");
+	return false;
+}
+
+/*
+ * nmbm_update_single_info_table - Update specific one info table
+ * @ni: NMBM instance structure
+ */
+static bool nmbm_update_single_info_table(struct nmbm_instance *ni,
+					  bool update_main_table)
+{
+	uint32_t write_start_ba, write_limit, table_start_ba, table_end_ba;
+	bool success;
+
+	/* Determine the write range */
+	if (update_main_table) {
+		write_start_ba = ni->main_table_ba;
+		write_limit = ni->backup_table_ba;
+	} else {
+		write_start_ba = ni->backup_table_ba;
+		write_limit = ni->mapping_blocks_top_ba;
+	}
+
+	nmbm_mark_block_color_mgmt(ni, write_start_ba, write_limit - 1);
+
+	success = nmbm_write_info_table(ni, write_start_ba, write_limit,
+					&table_start_ba, &table_end_ba);
+	if (success) {
+		if (update_main_table) {
+			ni->main_table_ba = table_start_ba;
+		} else {
+			ni->backup_table_ba = table_start_ba;
+			ni->mapping_blocks_ba = table_end_ba;
+		}
+
+		nmbm_mark_tables_clean(ni);
+
+		nlog_table_update(ni, update_main_table, table_start_ba,
+				 table_end_ba);
+
+		return true;
+	}
+
+	if (update_main_table) {
+		/*
+		 * If failed to update main table, make backup table the new
+		 * main table, and call nmbm_rescue_single_info_table()
+		 */
+		nlog_warn(ni, "Unable to update %s info table\n",
+			 update_main_table ? "Main" : "Backup");
+
+		ni->main_table_ba = ni->backup_table_ba;
+		ni->backup_table_ba = 0;
+		return nmbm_rescue_single_info_table(ni);
+	}
+
+	/* Only one table left */
+	ni->mapping_blocks_ba = ni->backup_table_ba;
+	ni->backup_table_ba = 0;
+
+	return false;
+}
+
+/*
+ * nmbm_rescue_main_info_table - Rescue when failed to write main info table
+ * @ni: NMBM instance structure
+ *
+ * This function is called when main info table failed to be written, and
+ *    backup info table exists.
+ */
+static bool nmbm_rescue_main_info_table(struct nmbm_instance *ni)
+{
+	uint32_t tmp_table_start_ba, tmp_table_end_ba, main_table_start_ba;
+	uint32_t main_table_end_ba, write_ba;
+	uint32_t info_table_erasesize = size2blk(ni, ni->info_table_size);
+	bool success;
+
+	/* Try to reserve spare blocks for existing backup info table */
+	success = nmbm_try_reserve_blocks(ni, ni->mapping_blocks_ba, &write_ba,
+					  ni->info_table_spare_blocks, 0,
+					  ni->mapping_blocks_top_ba -
+					  info_table_erasesize);
+	if (!success) {
+		/* There is no spare block. Backup info table becomes the main table. */
+		nlog_err(ni, "No room for temporary info table\n");
+		ni->main_table_ba = ni->backup_table_ba;
+		ni->backup_table_ba = 0;
+		return true;
+	}
+
+	/* Try to write temporary info table into spare unmapped blocks */
+	while (write_ba >= ni->mapping_blocks_ba) {
+		WATCHDOG_RESET();
+
+		success = nmbm_write_info_table(ni, write_ba,
+						ni->mapping_blocks_top_ba,
+						&tmp_table_start_ba,
+						&tmp_table_end_ba);
+		if (success)
+			break;
+
+		write_ba--;
+	}
+
+	if (!success) {
+		/* Backup info table becomes the main table */
+		nlog_err(ni, "Failed to update main info table\n");
+		ni->main_table_ba = ni->backup_table_ba;
+		ni->backup_table_ba = 0;
+		return true;
+	}
+
+	/* Adjust mapping_blocks_off */
+	ni->mapping_blocks_ba = tmp_table_end_ba;
+
+	nmbm_mark_block_color_mgmt(ni, ni->backup_table_ba,
+				   tmp_table_end_ba - 1);
+
+	/*
+	 * Now write main info table at the beginning of management area.
+	 * This operation will generally destroy the original backup info
+	 * table.
+	 */
+	success = nmbm_write_info_table(ni, ni->mgmt_start_ba,
+					tmp_table_start_ba,
+					&main_table_start_ba,
+					&main_table_end_ba);
+	if (!success) {
+		/* Temporary info table becomes the main table */
+		ni->main_table_ba = tmp_table_start_ba;
+		ni->backup_table_ba = 0;
+
+		nmbm_mark_tables_clean(ni);
+
+		nlog_err(ni, "Failed to update main info table\n");
+		nmbm_mark_block_color_info_table(ni, tmp_table_start_ba,
+						 tmp_table_end_ba - 1);
+
+		return true;
+	}
+
+	/* Main info table has been successfully written, record its offset */
+	ni->main_table_ba = main_table_start_ba;
+
+	nmbm_mark_tables_clean(ni);
+
+	nlog_table_creation(ni, true, main_table_start_ba, main_table_end_ba);
+
+	/*
+	 * Temporary info table becomes the new backup info table if it's
+	 * not overwritten.
+	 */
+	if (main_table_end_ba <= tmp_table_start_ba) {
+		ni->backup_table_ba = tmp_table_start_ba;
+
+		nlog_table_creation(ni, false, tmp_table_start_ba,
+				   tmp_table_end_ba);
+
+		return true;
+	}
+
+	/* Adjust mapping_blocks_off */
+	ni->mapping_blocks_ba = main_table_end_ba;
+
+	/* Try to reserve spare blocks for new main info table */
+	success = nmbm_try_reserve_blocks(ni, main_table_end_ba, &write_ba,
+					  ni->info_table_spare_blocks, 0,
+					  ni->mapping_blocks_top_ba -
+					  info_table_erasesize);
+	if (!success) {
+		/* There is no spare block. Only main table exists. */
+		nlog_err(ni, "No room for backup info table\n");
+		ni->backup_table_ba = 0;
+		return true;
+	}
+
+	/* Write new backup info table. */
+	while (write_ba >= main_table_end_ba) {
+		WATCHDOG_RESET();
+
+		success = nmbm_write_info_table(ni, write_ba,
+						ni->mapping_blocks_top_ba,
+						&tmp_table_start_ba,
+						&tmp_table_end_ba);
+		if (success)
+			break;
+
+		write_ba--;
+	}
+
+	if (!success) {
+		nlog_err(ni, "No room for backup info table\n");
+		ni->backup_table_ba = 0;
+		return true;
+	}
+
+	/* Backup info table has been successfully written, record its offset */
+	ni->backup_table_ba = tmp_table_start_ba;
+
+	/* Adjust mapping_blocks_off */
+	ni->mapping_blocks_ba = tmp_table_end_ba;
+
+	/* Erase spare blocks of main table to clean possible interference data */
+	nmbm_erase_range(ni, main_table_end_ba, ni->backup_table_ba);
+
+	nlog_table_creation(ni, false, tmp_table_start_ba, tmp_table_end_ba);
+
+	return true;
+}
+
+/*
+ * nmbm_update_info_table_once - Update info table once
+ * @ni: NMBM instance structure
+ * @force: force update
+ *
+ * Update both main and backup info table. Return true if at least one info
+ * table has been successfully written.
+ * This function only try to update info table once regard less of the result.
+ */
+static bool nmbm_update_info_table_once(struct nmbm_instance *ni, bool force)
+{
+	uint32_t table_start_ba, table_end_ba;
+	uint32_t main_table_limit;
+	bool success;
+
+	/* Do nothing if there is no change */
+	if (!nmbm_generate_info_table_cache(ni) && !force)
+		return true;
+
+	/* Check whether both two tables exist */
+	if (!ni->backup_table_ba) {
+		main_table_limit = ni->mapping_blocks_top_ba;
+		goto write_main_table;
+	}
+
+	nmbm_mark_block_color_mgmt(ni, ni->backup_table_ba,
+				   ni->mapping_blocks_ba - 1);
+
+	/*
+	 * Write backup info table in its current range.
+	 * Note that limit is set to mapping_blocks_top_off to provide as many
+	 * spare blocks as possible for the backup table. If at last
+	 * unmapped blocks are used by backup table, mapping_blocks_off will
+	 * be adjusted.
+	 */
+	success = nmbm_write_info_table(ni, ni->backup_table_ba,
+					ni->mapping_blocks_top_ba,
+					&table_start_ba, &table_end_ba);
+	if (!success) {
+		/*
+		 * There is nothing to do if failed to write backup table.
+		 * Write the main table now.
+		 */
+		nlog_err(ni, "No room for backup table\n");
+		ni->mapping_blocks_ba = ni->backup_table_ba;
+		ni->backup_table_ba = 0;
+		main_table_limit = ni->mapping_blocks_top_ba;
+		goto write_main_table;
+	}
+
+	/* Backup table is successfully written, record its offset */
+	ni->backup_table_ba = table_start_ba;
+
+	/* Adjust mapping_blocks_off */
+	ni->mapping_blocks_ba = table_end_ba;
+
+	nmbm_mark_tables_clean(ni);
+
+	/* The normal limit of main table */
+	main_table_limit = ni->backup_table_ba;
+
+	nlog_table_update(ni, false, table_start_ba, table_end_ba);
+
+write_main_table:
+	if (!ni->main_table_ba)
+		goto rebuild_tables;
+
+	if (!ni->backup_table_ba)
+		nmbm_mark_block_color_mgmt(ni, ni->mgmt_start_ba,
+					   ni->mapping_blocks_ba - 1);
+	else
+		nmbm_mark_block_color_mgmt(ni, ni->mgmt_start_ba,
+					   ni->backup_table_ba - 1);
+
+	/* Write main info table in its current range */
+	success = nmbm_write_info_table(ni, ni->main_table_ba,
+					main_table_limit, &table_start_ba,
+					&table_end_ba);
+	if (!success) {
+		/* If failed to write main table, go rescue procedure */
+		if (!ni->backup_table_ba)
+			goto rebuild_tables;
+
+		return nmbm_rescue_main_info_table(ni);
+	}
+
+	/* Main info table is successfully written, record its offset */
+	ni->main_table_ba = table_start_ba;
+
+	/* Adjust mapping_blocks_off */
+	if (!ni->backup_table_ba)
+		ni->mapping_blocks_ba = table_end_ba;
+
+	nmbm_mark_tables_clean(ni);
+
+	nlog_table_update(ni, true, table_start_ba, table_end_ba);
+
+	return true;
+
+rebuild_tables:
+	return nmbm_rebuild_info_table(ni);
+}
+
+/*
+ * nmbm_update_info_table - Update info table
+ * @ni: NMBM instance structure
+ *
+ * Update both main and backup info table. Return true if at least one table
+ * has been successfully written.
+ * This function will try to update info table repeatedly until no new bad
+ * block found during updating.
+ */
+static bool nmbm_update_info_table(struct nmbm_instance *ni)
+{
+	bool success;
+
+	if (ni->protected)
+		return true;
+
+	while (ni->block_state_changed || ni->block_mapping_changed) {
+		success = nmbm_update_info_table_once(ni, false);
+		if (!success) {
+			nlog_err(ni, "Failed to update info table\n");
+			return false;
+		}
+	}
+
+	return true;
+}
+
+/*
+ * nmbm_map_block - Map a bad block to a unused spare block
+ * @ni: NMBM instance structure
+ * @lb: logic block addr to map
+ */
+static bool nmbm_map_block(struct nmbm_instance *ni, uint32_t lb)
+{
+	uint32_t pb;
+	bool success;
+
+	if (ni->mapping_blocks_ba == ni->mapping_blocks_top_ba) {
+		nlog_warn(ni, "No spare unmapped blocks.\n");
+		return false;
+	}
+
+	success = nmbm_block_walk(ni, false, ni->mapping_blocks_top_ba, &pb, 0,
+				  ni->mapping_blocks_ba);
+	if (!success) {
+		nlog_warn(ni, "No spare unmapped blocks.\n");
+		nmbm_update_info_table(ni);
+		ni->mapping_blocks_top_ba = ni->mapping_blocks_ba;
+		return false;
+	}
+
+	ni->block_mapping[lb] = pb;
+	ni->mapping_blocks_top_ba--;
+	ni->block_mapping_changed++;
+
+	nlog_info(ni, "Logic block %u mapped to physical blcok %u\n", lb, pb);
+	nmbm_mark_block_color_mapped(ni, pb);
+
+	return true;
+}
+
+/*
+ * nmbm_create_info_table - Create info table(s)
+ * @ni: NMBM instance structure
+ *
+ * This function assumes that the chip has no existing info table(s)
+ */
+static bool nmbm_create_info_table(struct nmbm_instance *ni)
+{
+	uint32_t lb;
+	bool success;
+
+	/* Set initial mapping_blocks_top_off  */
+	success = nmbm_block_walk(ni, false, ni->signature_ba,
+				  &ni->mapping_blocks_top_ba, 1,
+				  ni->mgmt_start_ba);
+	if (!success) {
+		nlog_err(ni, "No room for spare blocks\n");
+		return false;
+	}
+
+	/* Generate info table cache */
+	nmbm_generate_info_table_cache(ni);
+
+	/* Write info table */
+	success = nmbm_rebuild_info_table(ni);
+	if (!success) {
+		nlog_err(ni, "Failed to build info tables\n");
+		return false;
+	}
+
+	/* Remap bad block(s) at end of data area */
+	for (lb = ni->data_block_count; lb < ni->mgmt_start_ba; lb++) {
+		success = nmbm_map_block(ni, lb);
+		if (!success)
+			break;
+
+		ni->data_block_count++;
+	}
+
+	/* If state table and/or mapping table changed, update info table. */
+	success = nmbm_update_info_table(ni);
+	if (!success)
+		return false;
+
+	return true;
+}
+
+/*
+ * nmbm_create_new - Create NMBM on a new chip
+ * @ni: NMBM instance structure
+ */
+static bool nmbm_create_new(struct nmbm_instance *ni)
+{
+	bool success;
+
+	/* Determine the boundary of management blocks */
+	ni->mgmt_start_ba = ni->block_count * (NMBM_MGMT_DIV - ni->lower.max_ratio) / NMBM_MGMT_DIV;
+
+	if (ni->lower.max_reserved_blocks && ni->block_count - ni->mgmt_start_ba > ni->lower.max_reserved_blocks)
+		ni->mgmt_start_ba = ni->block_count - ni->lower.max_reserved_blocks;
+
+	nlog_info(ni, "NMBM management region starts at block %u [0x%08llx]\n",
+		  ni->mgmt_start_ba, ba2addr(ni, ni->mgmt_start_ba));
+	nmbm_mark_block_color_mgmt(ni, ni->mgmt_start_ba, ni->block_count - 1);
+
+	/* Fill block state table & mapping table */
+	nmbm_scan_badblocks(ni);
+	nmbm_build_mapping_table(ni);
+
+	/* Write signature */
+	ni->signature.header.magic = NMBM_MAGIC_SIGNATURE;
+	ni->signature.header.version = NMBM_VER;
+	ni->signature.header.size = sizeof(ni->signature);
+	ni->signature.nand_size = ni->lower.size;
+	ni->signature.block_size = ni->lower.erasesize;
+	ni->signature.page_size = ni->lower.writesize;
+	ni->signature.spare_size = ni->lower.oobsize;
+	ni->signature.mgmt_start_pb = ni->mgmt_start_ba;
+	ni->signature.max_try_count = NMBM_TRY_COUNT;
+	nmbm_update_checksum(&ni->signature.header);
+
+	success = nmbm_write_signature(ni, ni->mgmt_start_ba,
+				       &ni->signature, &ni->signature_ba);
+	if (!success) {
+		nlog_err(ni, "Failed to write signature to a proper offset\n");
+		return false;
+	}
+
+	nlog_info(ni, "Signature has been written to block %u [0x%08llx]\n",
+		 ni->signature_ba, ba2addr(ni, ni->signature_ba));
+	nmbm_mark_block_color_signature(ni, ni->signature_ba);
+
+	/* Write info table(s) */
+	success = nmbm_create_info_table(ni);
+	if (success) {
+		nlog_info(ni, "NMBM has been successfully created\n");
+		return true;
+	}
+
+	return false;
+}
+
+/*
+ * nmbm_check_info_table_header - Check if a info table header is valid
+ * @ni: NMBM instance structure
+ * @data: pointer to the info table header
+ */
+static bool nmbm_check_info_table_header(struct nmbm_instance *ni, void *data)
+{
+	struct nmbm_info_table_header *ifthdr = data;
+
+	if (ifthdr->header.magic != NMBM_MAGIC_INFO_TABLE)
+		return false;
+
+	if (ifthdr->header.size != ni->info_table_size)
+		return false;
+
+	if (ifthdr->mapping_table_off - ifthdr->state_table_off < ni->state_table_size)
+		return false;
+
+	if (ni->info_table_size - ifthdr->mapping_table_off < ni->mapping_table_size)
+		return false;
+
+	return true;
+}
+
+/*
+ * nmbm_check_info_table - Check if a whole info table is valid
+ * @ni: NMBM instance structure
+ * @start_ba: start block address of this table
+ * @end_ba: end block address of this table
+ * @data: pointer to the info table header
+ * @mapping_blocks_top_ba: return the block address of top remapped block
+ */
+static bool nmbm_check_info_table(struct nmbm_instance *ni, uint32_t start_ba,
+				  uint32_t end_ba, void *data,
+				  uint32_t *mapping_blocks_top_ba)
+{
+	struct nmbm_info_table_header *ifthdr = data;
+	int32_t *block_mapping = (int32_t *)((uintptr_t)data + ifthdr->mapping_table_off);
+	nmbm_bitmap_t *block_state = (nmbm_bitmap_t *)((uintptr_t)data + ifthdr->state_table_off);
+	uint32_t minimum_mapping_pb = ni->signature_ba;
+	uint32_t ba;
+
+	for (ba = 0; ba < ni->data_block_count; ba++) {
+		if ((block_mapping[ba] >= ni->data_block_count && block_mapping[ba] < end_ba) ||
+		    block_mapping[ba] == ni->signature_ba)
+			return false;
+
+		if (block_mapping[ba] >= end_ba && block_mapping[ba] < minimum_mapping_pb)
+			minimum_mapping_pb = block_mapping[ba];
+	}
+
+	for (ba = start_ba; ba < end_ba; ba++) {
+		if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD)
+			continue;
+
+		if (nmbm_get_block_state_raw(block_state, ba) != BLOCK_ST_GOOD)
+			return false;
+	}
+
+	*mapping_blocks_top_ba = minimum_mapping_pb - 1;
+
+	return true;
+}
+
+/*
+ * nmbm_try_load_info_table - Try to load info table from a address
+ * @ni: NMBM instance structure
+ * @ba: start block address of the info table
+ * @eba: return the block address after end of the table
+ * @write_count: return the write count of this table
+ * @mapping_blocks_top_ba: return the block address of top remapped block
+ * @table_loaded: used to record whether ni->info_table has valid data
+ */
+static bool nmbm_try_load_info_table(struct nmbm_instance *ni, uint32_t ba,
+				     uint32_t *eba, uint32_t *write_count,
+				     uint32_t *mapping_blocks_top_ba,
+				     bool table_loaded)
+{
+	struct nmbm_info_table_header *ifthdr = (void *)ni->info_table_cache;
+	uint8_t *off = ni->info_table_cache;
+	uint32_t limit = ba + size2blk(ni, ni->info_table_size);
+	uint32_t start_ba = 0, chunksize, sizeremain = ni->info_table_size;
+	bool success, checkhdr = true;
+	int ret;
+
+	while (sizeremain && ba < limit) {
+		WATCHDOG_RESET();
+
+		if (nmbm_get_block_state(ni, ba) != BLOCK_ST_GOOD)
+			goto next_block;
+
+		if (nmbm_check_bad_phys_block(ni, ba)) {
+			nmbm_set_block_state(ni, ba, BLOCK_ST_BAD);
+			goto next_block;
+		}
+
+		chunksize = sizeremain;
+		if (chunksize > ni->lower.erasesize)
+			chunksize = ni->lower.erasesize;
+
+		/* Assume block with ECC error has no info table data */
+		ret = nmbn_read_data(ni, ba2addr(ni, ba), off, chunksize);
+		if (ret < 0)
+			goto skip_bad_block;
+		else if (ret > 0)
+			return false;
+
+		if (checkhdr) {
+			success = nmbm_check_info_table_header(ni, off);
+			if (!success)
+				return false;
+
+			start_ba = ba;
+			checkhdr = false;
+		}
+
+		off += chunksize;
+		sizeremain -= chunksize;
+
+		goto next_block;
+
+	skip_bad_block:
+		/* Only mark bad in memory */
+		nmbm_set_block_state(ni, ba, BLOCK_ST_BAD);
+
+	next_block:
+		ba++;
+	}
+
+	if (sizeremain)
+		return false;
+
+	success = nmbm_check_header(ni->info_table_cache, ni->info_table_size);
+	if (!success)
+		return false;
+
+	*eba = ba;
+	*write_count = ifthdr->write_count;
+
+	success = nmbm_check_info_table(ni, start_ba, ba, ni->info_table_cache,
+					mapping_blocks_top_ba);
+	if (!success)
+		return false;
+
+	if (!table_loaded || ifthdr->write_count > ni->info_table.write_count) {
+		memcpy(&ni->info_table, ifthdr, sizeof(ni->info_table));
+		memcpy(ni->block_state,
+		       (uint8_t *)ifthdr + ifthdr->state_table_off,
+		       ni->state_table_size);
+		memcpy(ni->block_mapping,
+		       (uint8_t *)ifthdr + ifthdr->mapping_table_off,
+		       ni->mapping_table_size);
+		ni->info_table.write_count = ifthdr->write_count;
+	}
+
+	return true;
+}
+
+/*
+ * nmbm_search_info_table - Search info table from specific address
+ * @ni: NMBM instance structure
+ * @ba: start block address to search
+ * @limit: highest block address allowed for searching
+ * @table_start_ba: return the start block address of this table
+ * @table_end_ba: return the block address after end of this table
+ * @write_count: return the write count of this table
+ * @mapping_blocks_top_ba: return the block address of top remapped block
+ * @table_loaded: used to record whether ni->info_table has valid data
+ */
+static bool nmbm_search_info_table(struct nmbm_instance *ni, uint32_t ba,
+				   uint32_t limit, uint32_t *table_start_ba,
+				   uint32_t *table_end_ba,
+				   uint32_t *write_count,
+				   uint32_t *mapping_blocks_top_ba,
+				   bool table_loaded)
+{
+	bool success;
+
+	while (ba < limit - size2blk(ni, ni->info_table_size)) {
+		WATCHDOG_RESET();
+
+		success = nmbm_try_load_info_table(ni, ba, table_end_ba,
+						   write_count,
+						   mapping_blocks_top_ba,
+						   table_loaded);
+		if (success) {
+			*table_start_ba = ba;
+			return true;
+		}
+
+		ba++;
+	}
+
+	return false;
+}
+
+/*
+ * nmbm_load_info_table - Load info table(s) from a chip
+ * @ni: NMBM instance structure
+ * @ba: start block address to search info table
+ * @limit: highest block address allowed for searching
+ */
+static bool nmbm_load_info_table(struct nmbm_instance *ni, uint32_t ba,
+				 uint32_t limit)
+{
+	uint32_t main_table_end_ba, backup_table_end_ba, table_end_ba;
+	uint32_t main_mapping_blocks_top_ba, backup_mapping_blocks_top_ba;
+	uint32_t main_table_write_count, backup_table_write_count;
+	uint32_t i;
+	bool success;
+
+	/* Set initial value */
+	ni->main_table_ba = 0;
+	ni->backup_table_ba = 0;
+	ni->info_table.write_count = 0;
+	ni->mapping_blocks_top_ba = ni->signature_ba - 1;
+	ni->data_block_count = ni->signature.mgmt_start_pb;
+
+	/* Find first info table */
+	success = nmbm_search_info_table(ni, ba, limit, &ni->main_table_ba,
+		&main_table_end_ba, &main_table_write_count,
+		&main_mapping_blocks_top_ba, false);
+	if (!success) {
+		nlog_warn(ni, "No valid info table found\n");
+		return false;
+	}
+
+	table_end_ba = main_table_end_ba;
+
+	nlog_table_found(ni, true, main_table_write_count, ni->main_table_ba,
+			main_table_end_ba);
+
+	/* Find second info table */
+	success = nmbm_search_info_table(ni, main_table_end_ba, limit,
+		&ni->backup_table_ba, &backup_table_end_ba,
+		&backup_table_write_count, &backup_mapping_blocks_top_ba, true);
+	if (!success) {
+		nlog_warn(ni, "Second info table not found\n");
+	} else {
+		table_end_ba = backup_table_end_ba;
+
+		nlog_table_found(ni, false, backup_table_write_count,
+				ni->backup_table_ba, backup_table_end_ba);
+	}
+
+	/* Pick mapping_blocks_top_ba */
+	if (!ni->backup_table_ba) {
+		ni->mapping_blocks_top_ba= main_mapping_blocks_top_ba;
+	} else {
+		if (main_table_write_count >= backup_table_write_count)
+			ni->mapping_blocks_top_ba = main_mapping_blocks_top_ba;
+		else
+			ni->mapping_blocks_top_ba = backup_mapping_blocks_top_ba;
+	}
+
+	/* Set final mapping_blocks_ba */
+	ni->mapping_blocks_ba = table_end_ba;
+
+	/* Set final data_block_count */
+	for (i = ni->signature.mgmt_start_pb; i > 0; i--) {
+		if (ni->block_mapping[i - 1] >= 0) {
+			ni->data_block_count = i;
+			break;
+		}
+	}
+
+	/* Debug purpose: mark mapped blocks and bad blocks */
+	for (i = 0; i < ni->data_block_count; i++) {
+		if (ni->block_mapping[i] > ni->mapping_blocks_top_ba)
+			nmbm_mark_block_color_mapped(ni, ni->block_mapping[i]);
+	}
+
+	for (i = 0; i < ni->block_count; i++) {
+		if (nmbm_get_block_state(ni, i) == BLOCK_ST_BAD)
+			nmbm_mark_block_color_bad(ni, i);
+	}
+
+	/* Regenerate the info table cache from the final selected info table */
+	nmbm_generate_info_table_cache(ni);
+
+	/*
+	 * If only one table exists, try to write another table.
+	 * If two tables have different write count, try to update info table
+	 */
+	if (!ni->backup_table_ba) {
+		success = nmbm_rescue_single_info_table(ni);
+	} else if (main_table_write_count != backup_table_write_count) {
+		/* Mark state & mapping tables changed */
+		ni->block_state_changed = 1;
+		ni->block_mapping_changed = 1;
+
+		success = nmbm_update_single_info_table(ni,
+			main_table_write_count < backup_table_write_count);
+	} else {
+		success = true;
+	}
+
+	/*
+	 * If there is no spare unmapped blocks, or still only one table
+	 * exists, set the chip to read-only
+	 */
+	if (ni->mapping_blocks_ba == ni->mapping_blocks_top_ba) {
+		nlog_warn(ni, "No spare unmapped blocks. Device is now read-only\n");
+		ni->protected = 1;
+	} else if (!success) {
+		nlog_warn(ni, "Only one info table found. Device is now read-only\n");
+		ni->protected = 1;
+	}
+
+	return true;
+}
+
+/*
+ * nmbm_load_existing - Load NMBM from a new chip
+ * @ni: NMBM instance structure
+ */
+static bool nmbm_load_existing(struct nmbm_instance *ni)
+{
+	bool success;
+
+	/* Calculate the boundary of management blocks */
+	ni->mgmt_start_ba = ni->signature.mgmt_start_pb;
+
+	nlog_debug(ni, "NMBM management region starts at block %u [0x%08llx]\n",
+		  ni->mgmt_start_ba, ba2addr(ni, ni->mgmt_start_ba));
+	nmbm_mark_block_color_mgmt(ni, ni->mgmt_start_ba,
+				   ni->signature_ba - 1);
+
+	/* Look for info table(s) */
+	success = nmbm_load_info_table(ni, ni->mgmt_start_ba,
+		ni->signature_ba);
+	if (success) {
+		nlog_info(ni, "NMBM has been successfully attached\n");
+		return true;
+	}
+
+	if (!(ni->lower.flags & NMBM_F_CREATE))
+		return false;
+
+	/* Fill block state table & mapping table */
+	nmbm_scan_badblocks(ni);
+	nmbm_build_mapping_table(ni);
+
+	/* Write info table(s) */
+	success = nmbm_create_info_table(ni);
+	if (success) {
+		nlog_info(ni, "NMBM has been successfully created\n");
+		return true;
+	}
+
+	return false;
+}
+
+/*
+ * nmbm_find_signature - Find signature in the lower NAND chip
+ * @ni: NMBM instance structure
+ * @signature_ba: used for storing block address of the signature
+ * @signature_ba: return the actual block address of signature block
+ *
+ * Find a valid signature from a specific range in the lower NAND chip,
+ * from bottom (highest address) to top (lowest address)
+ *
+ * Return true if found.
+ */
+static bool nmbm_find_signature(struct nmbm_instance *ni,
+				struct nmbm_signature *signature,
+				uint32_t *signature_ba)
+{
+	struct nmbm_signature sig;
+	uint64_t off, addr;
+	uint32_t block_count, ba, limit;
+	bool success;
+	int ret;
+
+	/* Calculate top and bottom block address */
+	block_count = ni->lower.size >> ni->erasesize_shift;
+	ba = block_count;
+	limit = (block_count / NMBM_MGMT_DIV) * (NMBM_MGMT_DIV - ni->lower.max_ratio);
+	if (ni->lower.max_reserved_blocks && block_count - limit > ni->lower.max_reserved_blocks)
+		limit = block_count - ni->lower.max_reserved_blocks;
+
+	while (ba >= limit) {
+		WATCHDOG_RESET();
+
+		ba--;
+		addr = ba2addr(ni, ba);
+
+		if (nmbm_check_bad_phys_block(ni, ba))
+			continue;
+
+		/* Check every page.
+		 * As long as at leaset one page contains valid signature,
+		 * the block is treated as a valid signature block.
+		 */
+		for (off = 0; off < ni->lower.erasesize;
+		     off += ni->lower.writesize) {
+			WATCHDOG_RESET();
+
+			ret = nmbn_read_data(ni, addr + off, &sig,
+					     sizeof(sig));
+			if (ret)
+				continue;
+
+			/* Check for header size and checksum */
+			success = nmbm_check_header(&sig, sizeof(sig));
+			if (!success)
+				continue;
+
+			/* Check for header magic */
+			if (sig.header.magic == NMBM_MAGIC_SIGNATURE) {
+				/* Found it */
+				memcpy(signature, &sig, sizeof(sig));
+				*signature_ba = ba;
+				return true;
+			}
+		}
+	};
+
+	return false;
+}
+
+/*
+ * is_power_of_2_u64 - Check whether a 64-bit integer is power of 2
+ * @n: number to check
+ */
+static bool is_power_of_2_u64(uint64_t n)
+{
+	return (n != 0 && ((n & (n - 1)) == 0));
+}
+
+/*
+ * nmbm_check_lower_members - Validate the members of lower NAND device
+ * @nld: Lower NAND chip structure
+ */
+static bool nmbm_check_lower_members(struct nmbm_lower_device *nld)
+{
+
+	if (!nld->size || !is_power_of_2_u64(nld->size)) {
+		nmbm_log_lower(nld, NMBM_LOG_ERR,
+			       "Chip size %llu is not valid\n", nld->size);
+		return false;
+	}
+
+	if (!nld->erasesize || !is_power_of_2(nld->erasesize)) {
+		nmbm_log_lower(nld, NMBM_LOG_ERR,
+			       "Block size %u is not valid\n", nld->erasesize);
+		return false;
+	}
+
+	if (!nld->writesize || !is_power_of_2(nld->writesize)) {
+		nmbm_log_lower(nld, NMBM_LOG_ERR,
+			       "Page size %u is not valid\n", nld->writesize);
+		return false;
+	}
+
+	if (!nld->oobsize || !is_power_of_2(nld->oobsize)) {
+		nmbm_log_lower(nld, NMBM_LOG_ERR,
+			       "Page spare size %u is not valid\n", nld->oobsize);
+		return false;
+	}
+
+	if (!nld->read_page || !nld->write_page || !nld->erase_block) {
+		nmbm_log_lower(nld, NMBM_LOG_ERR,
+			       "read_page(), write_page() and erase_block() are required\n");
+		return false;
+	}
+
+	/* Data sanity check */
+	if (!nld->max_ratio)
+		nld->max_ratio = 1;
+
+	if (nld->max_ratio >= NMBM_MGMT_DIV - 1) {
+		nmbm_log_lower(nld, NMBM_LOG_ERR,
+			       "max ratio %u is invalid\n", nld->max_ratio);
+		return false;
+	}
+
+	if (nld->max_reserved_blocks && nld->max_reserved_blocks < NMBM_MGMT_BLOCKS_MIN) {
+		nmbm_log_lower(nld, NMBM_LOG_ERR,
+			       "max reserved blocks %u is too small\n", nld->max_reserved_blocks);
+		return false;
+	}
+
+	return true;
+}
+
+/*
+ * nmbm_calc_structure_size - Calculate the instance structure size
+ * @nld: NMBM lower device structure
+ */
+size_t nmbm_calc_structure_size(struct nmbm_lower_device *nld)
+{
+	uint32_t state_table_size, mapping_table_size, info_table_size;
+	uint32_t block_count;
+
+	block_count = nmbm_lldiv(nld->size, nld->erasesize);
+
+	/* Calculate info table size */
+	state_table_size = ((block_count + NMBM_BITMAP_BLOCKS_PER_UNIT - 1) /
+		NMBM_BITMAP_BLOCKS_PER_UNIT) * NMBM_BITMAP_UNIT_SIZE;
+	mapping_table_size = block_count * sizeof(int32_t);
+
+	info_table_size = NMBM_ALIGN(sizeof(struct nmbm_info_table_header),
+				     nld->writesize);
+	info_table_size += NMBM_ALIGN(state_table_size, nld->writesize);
+	info_table_size += NMBM_ALIGN(mapping_table_size, nld->writesize);
+
+	return info_table_size + state_table_size + mapping_table_size +
+		nld->writesize + nld->oobsize + sizeof(struct nmbm_instance);
+}
+
+/*
+ * nmbm_init_structure - Initialize members of instance structure
+ * @ni: NMBM instance structure
+ */
+static void nmbm_init_structure(struct nmbm_instance *ni)
+{
+	uint32_t pages_per_block, blocks_per_chip;
+	uintptr_t ptr;
+
+	pages_per_block = ni->lower.erasesize / ni->lower.writesize;
+	blocks_per_chip = nmbm_lldiv(ni->lower.size, ni->lower.erasesize);
+
+	ni->rawpage_size = ni->lower.writesize + ni->lower.oobsize;
+	ni->rawblock_size = pages_per_block * ni->rawpage_size;
+	ni->rawchip_size = blocks_per_chip * ni->rawblock_size;
+
+	ni->writesize_mask = ni->lower.writesize - 1;
+	ni->erasesize_mask = ni->lower.erasesize - 1;
+
+	ni->writesize_shift = ffs(ni->lower.writesize) - 1;
+	ni->erasesize_shift = ffs(ni->lower.erasesize) - 1;
+
+	/* Calculate number of block this chip */
+	ni->block_count = ni->lower.size >> ni->erasesize_shift;
+
+	/* Calculate info table size */
+	ni->state_table_size = ((ni->block_count + NMBM_BITMAP_BLOCKS_PER_UNIT - 1) /
+		NMBM_BITMAP_BLOCKS_PER_UNIT) * NMBM_BITMAP_UNIT_SIZE;
+	ni->mapping_table_size = ni->block_count * sizeof(*ni->block_mapping);
+
+	ni->info_table_size = NMBM_ALIGN(sizeof(ni->info_table),
+					 ni->lower.writesize);
+	ni->info_table.state_table_off = ni->info_table_size;
+
+	ni->info_table_size += NMBM_ALIGN(ni->state_table_size,
+					  ni->lower.writesize);
+	ni->info_table.mapping_table_off = ni->info_table_size;
+
+	ni->info_table_size += NMBM_ALIGN(ni->mapping_table_size,
+					  ni->lower.writesize);
+
+	ni->info_table_spare_blocks = nmbm_get_spare_block_count(
+		size2blk(ni, ni->info_table_size));
+
+	/* Assign memory to members */
+	ptr = (uintptr_t)ni + sizeof(*ni);
+
+	ni->info_table_cache = (void *)ptr;
+	ptr += ni->info_table_size;
+
+	ni->block_state = (void *)ptr;
+	ptr += ni->state_table_size;
+
+	ni->block_mapping = (void *)ptr;
+	ptr += ni->mapping_table_size;
+
+	ni->page_cache = (uint8_t *)ptr;
+
+	/* Initialize block state table */
+	ni->block_state_changed = 0;
+	memset(ni->block_state, 0xff, ni->state_table_size);
+
+	/* Initialize block mapping table */
+	ni->block_mapping_changed = 0;
+}
+
+/*
+ * nmbm_attach - Attach to a lower device
+ * @nld: NMBM lower device structure
+ * @ni: NMBM instance structure
+ */
+int nmbm_attach(struct nmbm_lower_device *nld, struct nmbm_instance *ni)
+{
+	bool success;
+
+	if (!nld || !ni)
+		return -EINVAL;
+
+	/* Set default log level */
+	ni->log_display_level = NMBM_DEFAULT_LOG_LEVEL;
+
+	/* Check lower members */
+	success = nmbm_check_lower_members(nld);
+	if (!success)
+		return -EINVAL;
+
+	/* Initialize NMBM instance */
+	memcpy(&ni->lower, nld, sizeof(struct nmbm_lower_device));
+	nmbm_init_structure(ni);
+
+	success = nmbm_find_signature(ni, &ni->signature, &ni->signature_ba);
+	if (!success) {
+		if (!(nld->flags & NMBM_F_CREATE)) {
+			nlog_err(ni, "Signature not found\n");
+			return -ENODEV;
+		}
+
+		success = nmbm_create_new(ni);
+		if (!success)
+			return -ENODEV;
+
+		return 0;
+	}
+
+	nlog_info(ni, "Signature found at block %u [0x%08llx]\n",
+		 ni->signature_ba, ba2addr(ni, ni->signature_ba));
+	nmbm_mark_block_color_signature(ni, ni->signature_ba);
+
+	if (ni->signature.header.version != NMBM_VER) {
+		nlog_err(ni, "NMBM version %u.%u is not supported\n",
+			NMBM_VERSION_MAJOR_GET(ni->signature.header.version),
+			NMBM_VERSION_MINOR_GET(ni->signature.header.version));
+		return -EINVAL;
+	}
+
+	if (ni->signature.nand_size != nld->size ||
+	    ni->signature.block_size != nld->erasesize ||
+	    ni->signature.page_size != nld->writesize ||
+	    ni->signature.spare_size != nld->oobsize) {
+		nlog_err(ni, "NMBM configuration mismatch\n");
+		return -EINVAL;
+	}
+
+	success = nmbm_load_existing(ni);
+	if (!success)
+		return -ENODEV;
+
+	return 0;
+}
+
+/*
+ * nmbm_detach - Detach from a lower device, and save all tables
+ * @ni: NMBM instance structure
+ */
+int nmbm_detach(struct nmbm_instance *ni)
+{
+	if (!ni)
+		return -EINVAL;
+
+	nmbm_update_info_table(ni);
+
+	nmbm_mark_block_color_normal(ni, 0, ni->block_count - 1);
+
+	return 0;
+}
+
+/*
+ * nmbm_erase_logic_block - Erase a logic block
+ * @ni: NMBM instance structure
+ * @nmbm_erase_logic_block: logic block address
+ *
+ * Logic block will be mapped to physical block before erasing.
+ * Bad block found during erasinh will be remapped to a good block if there is
+ * still at least one good spare block available.
+ */
+static int nmbm_erase_logic_block(struct nmbm_instance *ni, uint32_t block_addr)
+{
+	uint32_t pb;
+	bool success;
+
+retry:
+	/* Map logic block to physical block */
+	pb = ni->block_mapping[block_addr];
+
+	/* Whether the logic block is good (has valid mapping) */
+	if ((int32_t)pb < 0) {
+		nlog_debug(ni, "Logic block %u is a bad block\n", block_addr);
+		return -EIO;
+	}
+
+	/* Remap logic block if current physical block is a bad block */
+	if (nmbm_get_block_state(ni, pb) == BLOCK_ST_BAD ||
+	    nmbm_get_block_state(ni, pb) == BLOCK_ST_NEED_REMAP)
+		goto remap_logic_block;
+
+	success = nmbm_erase_phys_block(ni, ba2addr(ni, pb));
+	if (success)
+		return 0;
+
+	/* Mark bad block */
+	nmbm_mark_phys_bad_block(ni, pb);
+	nmbm_set_block_state(ni, pb, BLOCK_ST_BAD);
+
+remap_logic_block:
+	/* Try to assign a new block */
+	success = nmbm_map_block(ni, block_addr);
+	if (!success) {
+		/* Mark logic block unusable, and update info table */
+		ni->block_mapping[block_addr] = -1;
+		if (nmbm_get_block_state(ni, pb) != BLOCK_ST_NEED_REMAP)
+			nmbm_set_block_state(ni, pb, BLOCK_ST_BAD);
+		nmbm_update_info_table(ni);
+		return -EIO;
+	}
+
+	/* Update info table before erasing */
+	if (nmbm_get_block_state(ni, pb) != BLOCK_ST_NEED_REMAP)
+		nmbm_set_block_state(ni, pb, BLOCK_ST_BAD);
+	nmbm_update_info_table(ni);
+
+	goto retry;
+}
+
+/*
+ * nmbm_erase_block_range - Erase logic blocks
+ * @ni: NMBM instance structure
+ * @addr: logic linear address
+ * @size: erase range
+ * @failed_addr: return failed block address if error occurs
+ */
+int nmbm_erase_block_range(struct nmbm_instance *ni, uint64_t addr,
+			   uint64_t size, uint64_t *failed_addr)
+{
+	uint32_t start_ba, end_ba;
+	int ret;
+
+	if (!ni)
+		return -EINVAL;
+
+	/* Sanity check */
+	if (ni->protected) {
+		nlog_debug(ni, "Device is forced read-only\n");
+		return -EROFS;
+	}
+
+	if (addr >= ba2addr(ni, ni->data_block_count)) {
+		nlog_err(ni, "Address 0x%llx is invalid\n", addr);
+		return -EINVAL;
+	}
+
+	if (addr + size > ba2addr(ni, ni->data_block_count)) {
+		nlog_err(ni, "Erase range 0xllxu is too large\n", size);
+		return -EINVAL;
+	}
+
+	if (!size) {
+		nlog_warn(ni, "No blocks to be erased\n");
+		return 0;
+	}
+
+	start_ba = addr2ba(ni, addr);
+	end_ba = addr2ba(ni, addr + size - 1);
+
+	while (start_ba <= end_ba) {
+		WATCHDOG_RESET();
+
+		ret = nmbm_erase_logic_block(ni, start_ba);
+		if (ret) {
+			if (failed_addr)
+				*failed_addr = ba2addr(ni, start_ba);
+			return ret;
+		}
+
+		start_ba++;
+	}
+
+	return 0;
+}
+
+/*
+ * nmbm_read_logic_page - Read page based on logic address
+ * @ni: NMBM instance structure
+ * @addr: logic linear address
+ * @data: buffer to store main data. optional.
+ * @oob: buffer to store oob data. optional.
+ * @mode: read mode
+ */
+static int nmbm_read_logic_page(struct nmbm_instance *ni, uint64_t addr,
+				void *data, void *oob, enum nmbm_oob_mode mode)
+{
+	uint32_t lb, pb, offset;
+	uint64_t paddr;
+	int ret;
+
+	/* Extract block address and in-block offset */
+	lb = addr2ba(ni, addr);
+	offset = addr & ni->erasesize_mask;
+
+	/* Map logic block to physical block */
+	pb = ni->block_mapping[lb];
+
+	/* Whether the logic block is good (has valid mapping) */
+	if ((int32_t)pb < 0) {
+		nlog_debug(ni, "Logic block %u is a bad block\n", lb);
+		return -EIO;
+	}
+
+	/* Fail if physical block is marked bad */
+	if (nmbm_get_block_state(ni, pb) == BLOCK_ST_BAD)
+		return -EIO;
+
+	/* Assemble new address */
+	paddr = ba2addr(ni, pb) + offset;
+
+	ret = nmbm_read_phys_page(ni, paddr, data, oob, mode);
+	if (!ret)
+		return 0;
+
+	/* For ECC error, return positive value only */
+	if (ret > 0)
+		return 1;
+
+	/*
+	 * Do not remap bad block here. Just mark this block in state table.
+	 * Remap this block on erasing.
+	 */
+	nmbm_set_block_state(ni, pb, BLOCK_ST_NEED_REMAP);
+	nmbm_update_info_table(ni);
+
+	return -EIO;
+}
+
+/*
+ * nmbm_read_single_page - Read one page based on logic address
+ * @ni: NMBM instance structure
+ * @addr: logic linear address
+ * @data: buffer to store main data. optional.
+ * @oob: buffer to store oob data. optional.
+ * @mode: read mode
+ */
+int nmbm_read_single_page(struct nmbm_instance *ni, uint64_t addr, void *data,
+			  void *oob, enum nmbm_oob_mode mode)
+{
+	if (!ni)
+		return -EINVAL;
+
+	/* Sanity check */
+	if (ni->protected) {
+		nlog_debug(ni, "Device is forced read-only\n");
+		return -EROFS;
+	}
+
+	if (addr >= ba2addr(ni, ni->data_block_count)) {
+		nlog_err(ni, "Address 0x%llx is invalid\n", addr);
+		return -EINVAL;
+	}
+
+	return nmbm_read_logic_page(ni, addr, data, oob, mode);
+}
+
+/*
+ * nmbm_read_range - Read data without oob
+ * @ni: NMBM instance structure
+ * @addr: logic linear address
+ * @size: data size to read
+ * @data: buffer to store main data to be read
+ * @mode: read mode
+ * @retlen: return actual data size read
+ */
+int nmbm_read_range(struct nmbm_instance *ni, uint64_t addr, size_t size,
+		    void *data, enum nmbm_oob_mode mode, size_t *retlen)
+{
+	uint64_t off = addr;
+	uint8_t *ptr = data;
+	size_t sizeremain = size, chunksize, leading;
+	int ret;
+
+	if (!ni)
+		return -EINVAL;
+
+	/* Sanity check */
+	if (ni->protected) {
+		nlog_debug(ni, "Device is forced read-only\n");
+		return -EROFS;
+	}
+
+	if (addr >= ba2addr(ni, ni->data_block_count)) {
+		nlog_err(ni, "Address 0x%llx is invalid\n", addr);
+		return -EINVAL;
+	}
+
+	if (addr + size > ba2addr(ni, ni->data_block_count)) {
+		nlog_err(ni, "Read range 0x%llx is too large\n", size);
+		return -EINVAL;
+	}
+
+	if (!size) {
+		nlog_warn(ni, "No data to be read\n");
+		return 0;
+	}
+
+	while (sizeremain) {
+		WATCHDOG_RESET();
+
+		leading = off & ni->writesize_mask;
+		chunksize = ni->lower.writesize - leading;
+		if (chunksize > sizeremain)
+			chunksize = sizeremain;
+
+		if (chunksize == ni->lower.writesize) {
+			ret = nmbm_read_logic_page(ni, off - leading, ptr,
+							NULL, mode);
+			if (ret)
+				break;
+		} else {
+			ret = nmbm_read_logic_page(ni, off - leading,
+							ni->page_cache, NULL,
+							mode);
+			if (ret)
+				break;
+
+			memcpy(ptr, ni->page_cache + leading, chunksize);
+		}
+
+		off += chunksize;
+		ptr += chunksize;
+		sizeremain -= chunksize;
+	}
+
+	if (retlen)
+		*retlen = size - sizeremain;
+
+	return ret;
+}
+
+/*
+ * nmbm_write_logic_page - Read page based on logic address
+ * @ni: NMBM instance structure
+ * @addr: logic linear address
+ * @data: buffer contains main data. optional.
+ * @oob: buffer contains oob data. optional.
+ * @mode: write mode
+ */
+static int nmbm_write_logic_page(struct nmbm_instance *ni, uint64_t addr,
+				  const void *data, const void *oob,
+				  enum nmbm_oob_mode mode)
+{
+	uint32_t lb, pb, offset;
+	uint64_t paddr;
+	bool success;
+
+	/* Extract block address and in-block offset */
+	lb = addr2ba(ni, addr);
+	offset = addr & ni->erasesize_mask;
+
+	/* Map logic block to physical block */
+	pb = ni->block_mapping[lb];
+
+	/* Whether the logic block is good (has valid mapping) */
+	if ((int32_t)pb < 0) {
+		nlog_debug(ni, "Logic block %u is a bad block\n", lb);
+		return -EIO;
+	}
+
+	/* Fail if physical block is marked bad */
+	if (nmbm_get_block_state(ni, pb) == BLOCK_ST_BAD)
+		return -EIO;
+
+	/* Assemble new address */
+	paddr = ba2addr(ni, pb) + offset;
+
+	success = nmbm_write_phys_page(ni, paddr, data, oob, mode);
+	if (success)
+		return 0;
+
+	/*
+	 * Do not remap bad block here. Just mark this block in state table.
+	 * Remap this block on erasing.
+	 */
+	nmbm_set_block_state(ni, pb, BLOCK_ST_NEED_REMAP);
+	nmbm_update_info_table(ni);
+
+	return -EIO;
+}
+
+/*
+ * nmbm_write_single_page - Write one page based on logic address
+ * @ni: NMBM instance structure
+ * @addr: logic linear address
+ * @data: buffer contains main data. optional.
+ * @oob: buffer contains oob data. optional.
+ * @mode: write mode
+ */
+int nmbm_write_single_page(struct nmbm_instance *ni, uint64_t addr,
+			   const void *data, const void *oob,
+			   enum nmbm_oob_mode mode)
+{
+	if (!ni)
+		return -EINVAL;
+
+	/* Sanity check */
+	if (ni->protected) {
+		nlog_debug(ni, "Device is forced read-only\n");
+		return -EROFS;
+	}
+
+	if (addr >= ba2addr(ni, ni->data_block_count)) {
+		nlog_err(ni, "Address 0x%llx is invalid\n", addr);
+		return -EINVAL;
+	}
+
+	return nmbm_write_logic_page(ni, addr, data, oob, mode);
+}
+
+/*
+ * nmbm_write_range - Write data without oob
+ * @ni: NMBM instance structure
+ * @addr: logic linear address
+ * @size: data size to write
+ * @data: buffer contains data to be written
+ * @mode: write mode
+ * @retlen: return actual data size written
+ */
+int nmbm_write_range(struct nmbm_instance *ni, uint64_t addr, size_t size,
+		     const void *data, enum nmbm_oob_mode mode,
+		     size_t *retlen)
+{
+	uint64_t off = addr;
+	const uint8_t *ptr = data;
+	size_t sizeremain = size, chunksize, leading;
+	int ret;
+
+	if (!ni)
+		return -EINVAL;
+
+	/* Sanity check */
+	if (ni->protected) {
+		nlog_debug(ni, "Device is forced read-only\n");
+		return -EROFS;
+	}
+
+	if (addr >= ba2addr(ni, ni->data_block_count)) {
+		nlog_err(ni, "Address 0x%llx is invalid\n", addr);
+		return -EINVAL;
+	}
+
+	if (addr + size > ba2addr(ni, ni->data_block_count)) {
+		nlog_err(ni, "Write size 0x%zx is too large\n", size);
+		return -EINVAL;
+	}
+
+	if (!size) {
+		nlog_warn(ni, "No data to be written\n");
+		return 0;
+	}
+
+	while (sizeremain) {
+		WATCHDOG_RESET();
+
+		leading = off & ni->writesize_mask;
+		chunksize = ni->lower.writesize - leading;
+		if (chunksize > sizeremain)
+			chunksize = sizeremain;
+
+		if (chunksize == ni->lower.writesize) {
+			ret = nmbm_write_logic_page(ni, off - leading, ptr,
+							 NULL, mode);
+			if (ret)
+				break;
+		} else {
+			memset(ni->page_cache, 0xff, leading);
+			memcpy(ni->page_cache + leading, ptr, chunksize);
+
+			ret = nmbm_write_logic_page(ni, off - leading,
+							 ni->page_cache, NULL,
+							 mode);
+			if (ret)
+				break;
+		}
+
+		off += chunksize;
+		ptr += chunksize;
+		sizeremain -= chunksize;
+	}
+
+	if (retlen)
+		*retlen = size - sizeremain;
+
+	return ret;
+}
+
+/*
+ * nmbm_check_bad_block - Check whether a logic block is usable
+ * @ni: NMBM instance structure
+ * @addr: logic linear address
+ */
+int nmbm_check_bad_block(struct nmbm_instance *ni, uint64_t addr)
+{
+	uint32_t lb, pb;
+
+	if (!ni)
+		return -EINVAL;
+
+	if (addr >= ba2addr(ni, ni->data_block_count)) {
+		nlog_err(ni, "Address 0x%llx is invalid\n", addr);
+		return -EINVAL;
+	}
+
+	lb = addr2ba(ni, addr);
+
+	/* Map logic block to physical block */
+	pb = ni->block_mapping[lb];
+
+	if ((int32_t)pb < 0)
+		return 1;
+
+	if (nmbm_get_block_state(ni, pb) == BLOCK_ST_BAD)
+		return 1;
+
+	return 0;
+}
+
+/*
+ * nmbm_mark_bad_block - Mark a logic block unusable
+ * @ni: NMBM instance structure
+ * @addr: logic linear address
+ */
+int nmbm_mark_bad_block(struct nmbm_instance *ni, uint64_t addr)
+{
+	uint32_t lb, pb;
+
+	if (!ni)
+		return -EINVAL;
+
+	if (addr >= ba2addr(ni, ni->data_block_count)) {
+		nlog_err(ni, "Address 0x%llx is invalid\n", addr);
+		return -EINVAL;
+	}
+
+	lb = addr2ba(ni, addr);
+
+	/* Map logic block to physical block */
+	pb = ni->block_mapping[lb];
+
+	if ((int32_t)pb < 0)
+		return 0;
+
+	ni->block_mapping[lb] = -1;
+	nmbm_mark_phys_bad_block(ni, pb);
+	nmbm_set_block_state(ni, pb, BLOCK_ST_BAD);
+	nmbm_update_info_table(ni);
+
+	return 0;
+}
+
+/*
+ * nmbm_get_avail_size - Get available user data size
+ * @ni: NMBM instance structure
+ */
+uint64_t nmbm_get_avail_size(struct nmbm_instance *ni)
+{
+	if (!ni)
+		return 0;
+
+	return (uint64_t)ni->data_block_count << ni->erasesize_shift;
+}
+
+/*
+ * nmbm_get_lower_device - Get lower device structure
+ * @ni: NMBM instance structure
+ * @nld: pointer to hold the data of lower device structure
+ */
+int nmbm_get_lower_device(struct nmbm_instance *ni, struct nmbm_lower_device *nld)
+{
+	if (!ni)
+		return -EINVAL;
+
+	if (nld)
+		memcpy(nld, &ni->lower, sizeof(*nld));
+
+	return 0;
+}
+
+#include "nmbm-debug.inl"
