// 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 corrected bitflip count,
 * -EBADMSG for ecc error, other negative values 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 >= 0)
			return ret;

		nmbm_reset_chip(ni);
	}

	if (ret != -EBADMSG)
		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;

	if (ni->lower.flags & NMBM_F_READ_ONLY) {
		nlog_err(ni, "%s called with NMBM_F_READ_ONLY set\n", addr);
		return false;
	}

	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_panic_write_phys_page - Panic 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
 *
 * Write a page for at most NMBM_TRY_COUNT times.
 */
static bool nmbm_panic_write_phys_page(struct nmbm_instance *ni, uint64_t addr,
				       const void *data)
{
	int tries, ret;

	if (ni->lower.flags & NMBM_F_READ_ONLY) {
		nlog_err(ni, "%s called with NMBM_F_READ_ONLY set\n", addr);
		return false;
	}

	for (tries = 0; tries < NMBM_TRY_COUNT; tries++) {
		ret = ni->lower.panic_write_page(ni->lower.arg, addr, data);
		if (!ret)
			return true;

		nmbm_reset_chip(ni);
	}

	nlog_err(ni, "Panic 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;

	if (ni->lower.flags & NMBM_F_READ_ONLY) {
		nlog_err(ni, "%s called with NMBM_F_READ_ONLY set\n", addr);
		return false;
	}

	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_RAW);
	if (ret < 0 && ret != -EBADMSG)
		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;

	if (ni->lower.flags & NMBM_F_READ_ONLY) {
		nlog_err(ni, "%s called with NMBM_F_READ_ONLY set\n", addr);
		return false;
	}

	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_block_and_check - Erase a block and check its usability
 * @ni: NMBM instance structure
 * @ba: block address to be erased
 *
 * Erase a block anc check its usability
 *
 * Return true if the block is usable, false if erasure failure or the block
 * has too many bitflips.
 */
static bool nmbm_erase_block_and_check(struct nmbm_instance *ni, uint32_t ba)
{
	uint64_t addr, off;
	bool success;
	int ret;

	success = nmbm_erase_phys_block(ni, ba2addr(ni, ba));
	if (!success)
		return false;

	if (!(ni->lower.flags & NMBM_F_EMPTY_PAGE_ECC_OK))
		return true;

	/* Check every page to make sure there aren't too many bitflips */

	addr = ba2addr(ni, ba);

	for (off = 0; off < ni->lower.erasesize; off += ni->lower.writesize) {
		WATCHDOG_RESET();

		ret = nmbm_read_phys_page(ni, addr + off, ni->page_cache, NULL,
					  NMBM_MODE_PLACE_OOB);
		if (ret == -EBADMSG) {
			/*
			 * NMBM_F_EMPTY_PAGE_ECC_OK means the empty page is
			 * still protected by ECC. So reading pages with ECC
			 * enabled and -EBADMSG means there are too many
			 * bitflips that can't be recovered, and the block
			 * containing the page should be marked bad.
			 */
			nlog_err(ni,
				 "Too many bitflips in empty page at 0x%llx\n",
				 addr + off);
			return false;
		}
	}

	return true;
}

/*
 * 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;

		/* Insurance to detect unexpected bad block marked by user */
		if (nmbm_check_bad_phys_block(ni, ba)) {
			nmbm_set_block_state(ni, ba, BLOCK_ST_BAD);
			goto next_block;
		}

		success = nmbm_erase_block_and_check(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 < 0)
			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;

		/* Insurance to detect unexpected bad block marked by user */
		if (nmbm_check_bad_phys_block(ni, ba)) {
			nmbm_set_block_state(ni, ba, BLOCK_ST_BAD);
			goto next_block;
		}

		success = nmbm_erase_block_and_check(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 corrected bitflip count,
 * -EBADMSG for ecc error, other negative values 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 < 0)
				return ret;
		} else {
			ret = nmbm_read_phys_page(ni, off - leading,
						  ni->page_cache, NULL,
						  NMBM_MODE_PLACE_OOB);
			if (ret < 0)
				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 < 0)
			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;

		/* Insurance to detect unexpected bad block marked by user */
		if (nmbm_check_bad_phys_block(ni, ba)) {
			nmbm_set_block_state(ni, ba, BLOCK_ST_BAD);
			goto next_block;
		}

		success = nmbm_erase_block_and_check(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);

	if (ni->lower.flags & NMBM_F_READ_ONLY) {
		nlog_info(ni, "NMBM has been initialized in read-only mode\n");
		return true;
	}

	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 (ni->lower.flags & NMBM_F_READ_ONLY)
		return true;

	/*
	 * 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 %s\n",
			  (ni->lower.flags & NMBM_F_READ_ONLY) ? "in read-only mode" : "");
		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);

	if (ni->lower.flags & NMBM_F_READ_ONLY) {
		nlog_info(ni, "NMBM has been initialized in read-only mode\n");
		return true;
	}

	/* 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) {
		nmbm_log_lower(nld, NMBM_LOG_ERR,
			       "Page spare size %u is not valid\n", nld->oobsize);
		return false;
	}

	if (!nld->read_page) {
		nmbm_log_lower(nld, NMBM_LOG_ERR, "read_page() is required\n");
		return false;
	}

	if (!(nld->flags & NMBM_F_READ_ONLY) && (!nld->write_page || !nld->erase_block)) {
		nmbm_log_lower(nld, NMBM_LOG_ERR,
			       "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;

	if (!(ni->lower.flags & NMBM_F_READ_ONLY))
		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;

	/* Insurance to detect unexpected bad block marked by user */
	if (nmbm_check_bad_phys_block(ni, pb)) {
		nlog_warn(ni, "Found unexpected bad block possibly marked by user\n");
		nmbm_set_block_state(ni, pb, BLOCK_ST_BAD);
		goto remap_logic_block;
	}

	success = nmbm_erase_block_and_check(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 || (ni->lower.flags & NMBM_F_READ_ONLY)) {
		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
 *
 * Return 0 for success, positive value for corrected bitflip count,
 * -EBADMSG for ecc error, other negative values for other errors
 */
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;

	/* 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;

	return nmbm_read_phys_page(ni, paddr, data, oob, mode);
}

/*
 * 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
 *
 * Return 0 for success, positive value for corrected bitflip count,
 * -EBADMSG for ecc error, other negative values for other errors
 */
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
 *
 * Return 0 for success, positive value for corrected bitflip count,
 * -EBADMSG for ecc error, other negative values for other errors
 */
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;
	bool has_ecc_err = false;
	int ret, max_bitflips = 0;

	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 < 0 && ret != -EBADMSG)
				break;
		} else {
			ret = nmbm_read_logic_page(ni, off - leading,
							ni->page_cache, NULL,
							mode);
			if (ret < 0 && ret != -EBADMSG)
				break;

			memcpy(ptr, ni->page_cache + leading, chunksize);
		}

		if (ret == -EBADMSG)
			has_ecc_err = true;

		if (ret > max_bitflips)
			max_bitflips = ret;

		off += chunksize;
		ptr += chunksize;
		sizeremain -= chunksize;
	}

	if (retlen)
		*retlen = size - sizeremain;

	if (ret < 0 && ret != -EBADMSG)
		return ret;

	if (has_ecc_err)
		return -EBADMSG;

	return max_bitflips;
}

/*
 * 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_panic_write_logic_page - Panic write page based on logic address
 * @ni: NMBM instance structure
 * @addr: logic linear address
 * @data: buffer contains main data. optional.
 */
static int nmbm_panic_write_logic_page(struct nmbm_instance *ni, uint64_t addr,
				       const void *data)
{
	uint32_t lb, pb, offset;
	uint64_t paddr;
	bool success;

	if (!ni->lower.panic_write_page)
		return -ENOTSUPP;

	/* 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_panic_write_phys_page(ni, paddr, data);
	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 || (ni->lower.flags & NMBM_F_READ_ONLY)) {
		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_panic_write_single_page - Panic write one page based on logic address
 * @ni: NMBM instance structure
 * @addr: logic linear address
 * @data: buffer contains main data. optional.
 */
int nmbm_panic_write_single_page(struct nmbm_instance *ni, uint64_t addr,
				 const void *data)
{
	if (!ni)
		return -EINVAL;

	/* Sanity check */
	if (ni->protected || (ni->lower.flags & NMBM_F_READ_ONLY)) {
		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_panic_write_logic_page(ni, addr, data);
}

/*
 * 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 || (ni->lower.flags & NMBM_F_READ_ONLY)) {
		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;

	/* Sanity check */
	if (ni->protected || (ni->lower.flags & NMBM_F_READ_ONLY)) {
		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;
	}

	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"
