// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Amlogic reserved information management
 *
 * Copyright (C) 2018 Amlogic Corporation
 *
 * Licensed under the GPL-2 or later.
 *
 */

#include <common.h>
#include <malloc.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/mtd/mtd.h>
#include <amlogic/aml_rsv.h>
#include <amlogic/aml_mtd.h>
#include <partition_table.h>
#include <amlogic/storage.h>

#undef pr_info
#define pr_info	printf

extern int info_disprotect;
static struct meson_rsv_handler_t *rsv_handler;

static struct free_node_t *get_free_node(struct meson_rsv_info_t *rsv_info)
{
	struct meson_rsv_handler_t *handler = rsv_info->handler;
	u32 index;

	index =
		find_first_zero_bit((void *)&handler->fn_bitmask,
				    NAND_RSV_BLOCK_NUM);
	if (index > NAND_RSV_BLOCK_NUM) {
		pr_info("%s %d index :%d is greater than max rsv block num\n",
			__func__, __LINE__, index);
		return NULL;
	}
	WARN_ON(test_and_set_bit(index, (void *)&handler->fn_bitmask));

	return handler->free_node[index];
}

static void release_free_node(struct meson_rsv_info_t *rsv_info,
			      struct free_node_t *free_node)
{
	struct meson_rsv_handler_t *handler = rsv_info->handler;
	u32 index = free_node->index;

	pr_info("%s %d: bitmask = 0x%llx\n",
		__func__, __LINE__, handler->fn_bitmask);
	if (index > NAND_RSV_BLOCK_NUM) {
		pr_info("%s %d index :%d is greater than max rsv block num\n",
			__func__, __LINE__, index);
		return;
	}
	WARN_ON(!test_and_clear_bit(index, (void *)&handler->fn_bitmask));
	memset(free_node, 0, sizeof(struct free_node_t));
	free_node->index = index;
	pr_info("%s %d: bitmask = 0x%llx\n",
		__func__, __LINE__, handler->fn_bitmask);
}

int meson_rsv_erase_protect(struct meson_rsv_handler_t *handler,
			    u32 block_addr)
{
	if (handler->key && handler->key->valid) {
		if (!(info_disprotect & DISPROTECT_KEY) &&
		    block_addr >= handler->key->start &&
		    block_addr < handler->key->end)
			return -1;
	}
	if (handler->bbt && handler->bbt->valid) {
		if ((!(info_disprotect & DISPROTECT_FBBT)) &&
			(block_addr >= handler->bbt->start) &&
			(block_addr < handler->bbt->end))
			return -1;
	}
	return 0;
}

int meson_rsv_free(struct meson_rsv_info_t *rsv_info)
{
	struct mtd_info *mtd = rsv_info->mtd;
	struct free_node_t *tmp_node, *next_node = NULL;
	int error = 0;
	loff_t addr = 0;
	struct erase_info erase_info;

	pr_info("free %s\n", rsv_info->name);

	if (rsv_info->valid) {
		addr = rsv_info->nvalid->blk_addr;
		addr *= mtd->erasesize;
		memset(&erase_info, 0, sizeof(struct erase_info));
		erase_info.mtd = mtd;
		erase_info.addr = addr;
		erase_info.len = mtd->erasesize;
		error = mtd->_erase(mtd, &erase_info);
		pr_info("erasing valid info block: %llx\n", addr);
		rsv_info->nvalid->blk_addr = -1;
		rsv_info->nvalid->ec = -1;
		rsv_info->nvalid->page_addr = 0;
		rsv_info->nvalid->timestamp = 0;
		rsv_info->nvalid->status = 0;
		rsv_info->valid = 0;
	}
	tmp_node = rsv_info->nfree;
	while (tmp_node) {
		next_node = tmp_node->next;
		release_free_node(rsv_info, tmp_node);
		tmp_node = next_node;
	}
	rsv_info->nfree = NULL;

	return error;
}

int meson_rsv_save(struct meson_rsv_info_t *rsv_info, u_char *buf)
{
	struct mtd_info *mtd = rsv_info->mtd;
	struct free_node_t *free_node, *temp_node;
	struct erase_info erase_info;
	int ret = 0, i = 1, pages_per_blk;
	loff_t offset = 0;

	pages_per_blk = 1 << (mtd->erasesize_shift - mtd->writesize_shift);
	if ((rsv_info->nvalid->status & POWER_ABNORMAL_FLAG) ||
	    (rsv_info->nvalid->status & ECC_ABNORMAL_FLAG))
		rsv_info->nvalid->page_addr = pages_per_blk;
	if (mtd->writesize < rsv_info->size)
		i = (rsv_info->size + mtd->writesize - 1) / mtd->writesize;
	pr_info("%s %d: %s, valid = %d, pages = %d\n", __func__, __LINE__,
		rsv_info->name, rsv_info->valid, i);
RE_SEARCH:
	if (rsv_info->valid) {
		rsv_info->nvalid->page_addr += i;
		if ((rsv_info->nvalid->page_addr + i) > pages_per_blk) {
			if ((rsv_info->nvalid->page_addr - i) ==
				pages_per_blk) {
				offset = rsv_info->nvalid->blk_addr;
				offset *= mtd->erasesize;
				erase_info.mtd = mtd;
				erase_info.addr = offset;
				erase_info.len = mtd->erasesize;
				ret = mtd_erase(mtd, &erase_info);
				rsv_info->nvalid->ec++;
				pr_info("%s %d: erasing bad info block:0x%llx\n",
					__func__, __LINE__, offset);
			}
			free_node = get_free_node(rsv_info);
			if (!free_node)
				return -ENOMEM;
			/* set current valid node to free list */
			free_node->blk_addr = rsv_info->nvalid->blk_addr;
			free_node->ec = rsv_info->nvalid->ec;
			temp_node = rsv_info->nfree;
			while (temp_node->next)
				temp_node = temp_node->next;
			temp_node->next = free_node;
			/* get one node from free list and set to current */
			temp_node = rsv_info->nfree;
			rsv_info->nvalid->blk_addr = temp_node->blk_addr;
			rsv_info->nvalid->page_addr = 0;
			rsv_info->nvalid->ec = temp_node->ec;
			rsv_info->nvalid->timestamp++;
			rsv_info->nfree = temp_node->next;
			release_free_node(rsv_info, temp_node);
		}
	} else {
		temp_node = rsv_info->nfree;
		rsv_info->nvalid->blk_addr = temp_node->blk_addr;
		rsv_info->nvalid->page_addr = 0;
		rsv_info->nvalid->ec = temp_node->ec;
		rsv_info->nvalid->timestamp++;
		rsv_info->nfree = temp_node->next;
		release_free_node(rsv_info, temp_node);
	}
	offset = rsv_info->nvalid->blk_addr;
	offset *= mtd->erasesize;
	offset += rsv_info->nvalid->page_addr * mtd->writesize;
	if (rsv_info->nvalid->page_addr == 0) {
		ret = mtd_block_isbad(mtd, offset);
		if (ret) {
			/**
			 * cause our rsv list includes bad block,
			 * so we need check it here and for fear
			 * of data lost.
			 */
			pr_info("%s %d: %s bad block here 0x%llx\n",
				__func__, __LINE__, rsv_info->name, offset);
			rsv_info->nvalid->page_addr = pages_per_blk - i;
			goto RE_SEARCH;
		}
		memset(&erase_info, 0, sizeof(struct erase_info));
		erase_info.mtd = mtd;
		erase_info.addr = offset;
		erase_info.len = mtd->erasesize;
		ret = mtd_erase(mtd, &erase_info);
		if (ret) {
			pr_info("%s %d %s erase failed at 0x%llx ,mark it bad\n",
				__func__, __LINE__, rsv_info->name, offset);
			mtd_block_markbad(mtd, offset);
			return ret;
		}
		rsv_info->nvalid->ec++;
	}
	ret = meson_rsv_write(rsv_info, buf);
	if (ret) {
		pr_info("%s %d rsv info: %s save failed!\n",
			__func__, __LINE__, rsv_info->name);
		return ret;
	}
	rsv_info->valid = 1;
	rsv_info->nvalid->status = 0;
	return ret;
}

int meson_rsv_write(struct meson_rsv_info_t *rsv_info, u_char *buf)
{
	struct mtd_info *mtd = rsv_info->mtd;
	struct oobinfo_t oobinfo;
	struct mtd_oob_ops oob_ops;
	size_t length = 0;
	loff_t offset;
	int ret = 0;

	offset = rsv_info->nvalid->blk_addr;
	offset *= mtd->erasesize;
	offset += rsv_info->nvalid->page_addr * mtd->writesize;
	pr_info("%s %d write %s to 0x%llx\n",
		__func__, __LINE__, rsv_info->name, offset);
	memcpy(oobinfo.name, rsv_info->name, strlen(rsv_info->name));
	oobinfo.ec = rsv_info->nvalid->ec;
	/* TODO: prevent the unrolling situation here */
	oobinfo.timestamp = rsv_info->nvalid->timestamp;
	while (length < rsv_info->size) {
		oob_ops.mode = MTD_OPS_AUTO_OOB;
		oob_ops.len = min_t(u32, mtd->writesize,
				    (rsv_info->size - length));
		oob_ops.ooblen = sizeof(struct oobinfo_t);
		oob_ops.ooboffs = 0;
		oob_ops.datbuf = buf + length;
		oob_ops.oobbuf = (u8 *)&oobinfo;
		ret = mtd_write_oob(mtd, offset, &oob_ops);
		if (ret) {
			pr_info("fail to write %s to 0x%llx ret:%d\n",
				rsv_info->name, offset, ret);
			return -EIO;
		}
		offset += mtd->writesize;
		length += oob_ops.len;
	}
	return ret;
}

int meson_rsv_read(struct meson_rsv_info_t *rsv_info, u_char *buf)
{
	struct mtd_info *mtd = rsv_info->mtd;
	struct oobinfo_t oobinfo;
	struct mtd_oob_ops oob_ops;
	size_t length = 0;
	loff_t offset;
	int ret = 0;

READ_RSV_AGAIN:
	offset = rsv_info->nvalid->blk_addr;
	offset *= mtd->erasesize;
	offset += rsv_info->nvalid->page_addr * mtd->writesize;
	pr_info("%s %d read %s from 0x%llx\n",
		__func__, __LINE__, rsv_info->name, offset);
	memset(buf, 0, rsv_info->size);
	while (length < rsv_info->size) {
		oob_ops.mode = MTD_OPS_AUTO_OOB;
		oob_ops.len = min_t(u32, mtd->writesize,
				    (rsv_info->size - length));
		oob_ops.ooblen = sizeof(struct oobinfo_t);
		oob_ops.ooboffs = 0;
		oob_ops.datbuf = buf + length;
		oob_ops.oobbuf = (u8 *)&oobinfo;

		memset((u8 *)&oobinfo, 0, oob_ops.ooblen);
		ret = mtd_read_oob(mtd, offset, &oob_ops);
		if (ret && (ret != -EUCLEAN)) {
			pr_info("blk good but read failed: %llx, %d\n",
				(u64)offset, ret);
			ret = meson_rsv_scan(rsv_info);
			if (ret)
				return -EIO;
			goto READ_RSV_AGAIN;
		}
		if (memcmp(oobinfo.name, rsv_info->name,
			   strlen(oobinfo.name)))
			pr_info("invalid %s info in %llx:%s\n",
				rsv_info->name, offset, oobinfo.name);
		offset += mtd->writesize;
		length += oob_ops.len;
	}
	return ret;
}

int meson_rsv_erase(struct meson_rsv_info_t *rsv_info)
{
	struct mtd_info *mtd = rsv_info->mtd;
	struct free_node_t *temp_node = NULL;
	int ret = 0;
	struct erase_info erase_info;


	printf("%s %d rsv erasing %s\n",
			__func__, __LINE__, rsv_info->name);

	if (rsv_info->valid) {
		memset(&erase_info, 0, sizeof(struct erase_info));
		erase_info.mtd = mtd;
		erase_info.addr = rsv_info->nvalid->blk_addr* mtd->erasesize;
		erase_info.len = mtd->erasesize;
		ret = mtd_erase(mtd, &erase_info);

		printk("erasing valid info block: %llx \n", erase_info.addr);
		rsv_info->nvalid->ec++;
		rsv_info->nvalid->page_addr = 0;
		rsv_info->nvalid->timestamp = 1;
	}

	temp_node = rsv_info->nfree;
	while (temp_node) {
		memset(&erase_info,	0, sizeof(struct erase_info));
		erase_info.mtd = mtd;
		erase_info.addr = temp_node->blk_addr* mtd->erasesize;
		erase_info.len = mtd->erasesize;
		ret = mtd_erase(mtd, &erase_info);

		printk("erasing valid info block: %llx \n", erase_info.addr);
		rsv_info->nvalid->ec = -1;
		temp_node->dirty_flag = 0;
		temp_node = temp_node->next;
	}
	return ret;
}

int meson_rsv_scan(struct meson_rsv_info_t *rsv_info)
{
	struct mtd_info *mtd = rsv_info->mtd;
	struct mtd_oob_ops oob_ops;
	struct oobinfo_t oobinfo;
	struct free_node_t *free_node, *temp_node;
	loff_t offset;
	u32 start, end;
	int ret = 0, error, rsv_status, i, k;

	u8 scan_status;
	u8 good_addr[256] = {0};
	u32 page_num, pages_per_blk;

RE_RSV_INFO_EXT:
	start = rsv_info->start;
	end = rsv_info->end;
	pr_info("%s:info size = 0x%x, start blk = %d, end blk = %d\n",
		rsv_info->name, rsv_info->size, start, end);
	do {
		offset = start;
		offset *= mtd->erasesize;
		scan_status = 0;
RE_RSV_INFO:
		oob_ops.mode = MTD_OPS_AUTO_OOB;
		oob_ops.len = 0;
		oob_ops.ooblen = sizeof(struct oobinfo_t);
		oob_ops.ooboffs = 0;
		oob_ops.datbuf = NULL;
		oob_ops.oobbuf = (u8 *)&oobinfo;
		memset((u8 *)&oobinfo, 0, sizeof(struct oobinfo_t));
		error = mtd_read_oob(mtd, offset, &oob_ops);
		if (error && (error != -EUCLEAN)) {
			pr_info("%s %d blk check good but read failed: %llx, %d\n",
				__func__, __LINE__, (u64)offset, error);
			offset += rsv_info->size;
			if ((scan_status++ > 6) ||
			    (!(offset % mtd->erasesize))) {
				pr_info("ECC error, scan ONE block exit\n");
				scan_status = 0;
				continue;
			}
			goto RE_RSV_INFO;
		}
		rsv_info->init = 1;
		rsv_info->nvalid->status = 0;
		if (!memcmp(oobinfo.name, rsv_info->name,
			    strlen(oobinfo.name))) {
			rsv_info->valid = 1;
			if (rsv_info->nvalid->blk_addr >= 0) {
				free_node = get_free_node(rsv_info);
				if (!free_node)
					return -ENOMEM;
				free_node->dirty_flag = 1;
				if (oobinfo.timestamp >
				    rsv_info->nvalid->timestamp) {
					free_node->blk_addr =
						rsv_info->nvalid->blk_addr;
					free_node->ec = rsv_info->nvalid->ec;
					rsv_info->nvalid->blk_addr = start;
					rsv_info->nvalid->page_addr = 0;
					rsv_info->nvalid->ec = oobinfo.ec;
					rsv_info->nvalid->timestamp =
						oobinfo.timestamp;
				} else {
					free_node->blk_addr = start;
					free_node->ec = oobinfo.ec;
				}
				if (!rsv_info->nfree) {
					rsv_info->nfree = free_node;
				} else {
					temp_node = rsv_info->nfree;
					while (temp_node->next)
						temp_node = temp_node->next;
					temp_node->next = free_node;
				}
			} else {
				rsv_info->nvalid->blk_addr = start;
				rsv_info->nvalid->page_addr = 0;
				rsv_info->nvalid->ec = oobinfo.ec;
				rsv_info->nvalid->timestamp = oobinfo.timestamp;
			}
		} else {
			free_node = get_free_node(rsv_info);
			if (!free_node)
				return -ENOMEM;
			free_node->blk_addr = start;
			free_node->ec = oobinfo.ec;
			if (!rsv_info->nfree) {
				rsv_info->nfree = free_node;
			} else {
				temp_node = rsv_info->nfree;
				while (temp_node->next)
					temp_node = temp_node->next;
				temp_node->next = free_node;
			}
		}
	} while ((++start) < end);

	printf("%s blk = %d, ec = %d, page = %d, timestamp = %d\n",
			rsv_info->name, rsv_info->nvalid->blk_addr, rsv_info->nvalid->ec,
			rsv_info->nvalid->page_addr, rsv_info->nvalid->timestamp);
	printf("%s free list: \n", rsv_info->name);
	temp_node = rsv_info->nfree;
	while (temp_node) {
		pr_info("block num = %d, ec = %d, dirty_flag = %d\n",
			temp_node->blk_addr,
			temp_node->ec,
			temp_node->dirty_flag);
		temp_node = temp_node->next;
	}
	/**
	 * step 2, find the newest in the block
	 * watch out here, cause erase size and write size must be
	 * power of 2, and write size must equal page size.
	 */
	pages_per_blk = 1 << (mtd->erasesize_shift - mtd->writesize_shift);
	page_num = rsv_info->size >> mtd->writesize_shift;
	if (!page_num)
		page_num++;
	if (rsv_info->valid == 1) {
		pr_info("%s %d selecting in block: %d\n",
			__func__, __LINE__, rsv_info->nvalid->blk_addr);
		oob_ops.mode = MTD_OPS_AUTO_OOB;
		oob_ops.len = 0;
		oob_ops.ooblen = sizeof(struct oobinfo_t);
		oob_ops.ooboffs = 0;
		oob_ops.datbuf = NULL;
		oob_ops.oobbuf = (u8 *)&oobinfo;
		for (i = 0; i < pages_per_blk; i++) {
			memset((u8 *)&oobinfo, 0, oob_ops.ooblen);
			offset = rsv_info->nvalid->blk_addr;
			offset *= mtd->erasesize;
			offset += mtd->writesize * i;
			error = mtd_read_oob(mtd, offset, &oob_ops);
			if (error && error != -EUCLEAN) {
				pr_info("%s %d blk good but read failed:%llx, %d\n",
					__func__, __LINE__, (u64)offset, error);
				rsv_info->nvalid->status |= ECC_ABNORMAL_FLAG;
				ret = -1;
				continue;
			}
			if (!memcmp(oobinfo.name, rsv_info->name,
				    strlen(oobinfo.name))) {
				good_addr[i] = 1;
				rsv_info->nvalid->page_addr = i;
			} else {
				break;
			}
		}
	}
	if (mtd->writesize < rsv_info->size &&
	    rsv_info->valid == 1) {
		i = rsv_info->nvalid->page_addr;
		if (((i + 1) % page_num) != 0) {
			ret = -1;
			rsv_info->nvalid->status |= POWER_ABNORMAL_FLAG;
			pr_info("find %s incomplete\n", rsv_info->name);
		}
		pr_info("%s %d page_num %d\n", __func__, __LINE__, page_num);
		if (ret == -1) {
			for (i = 0; i < (pages_per_blk / page_num); i++) {
				rsv_status = 0;
				for (k = 0; k < page_num; k++) {
					if (!good_addr[k + i * page_num]) {
						rsv_status = 1;
						break;
					}
				}
				if (!rsv_status) {
					pr_info("find %d page ok\n",
						i * page_num);
					rsv_info->nvalid->page_addr =
						k + i * page_num - 1;
					ret = 0;
				}
			}
		}
		if (ret == -1) {
			rsv_info->nvalid->status = 0;
			meson_rsv_free(rsv_info);
			goto RE_RSV_INFO_EXT;
		}
		i = (rsv_info->size + mtd->writesize - 1) / mtd->writesize;
		rsv_info->nvalid->page_addr -= (i - 1);
	}
	if (rsv_info->valid != 1)
		ret = -1;
	offset = rsv_info->nvalid->blk_addr;
	offset *= mtd->erasesize;
	offset += rsv_info->nvalid->page_addr * mtd->writesize;
	pr_info("%s valid address 0x%llx\n", rsv_info->name, offset);
	return ret;
}

int meson_rsv_check(struct meson_rsv_info_t *rsv_info)
{
	int ret = 0;

	ret = meson_rsv_scan(rsv_info);
	if (ret)
		pr_info("%s %d %s info check failed ret %d\n",
			__func__, __LINE__, rsv_info->name, ret);
	if (!rsv_info->valid) {
		pr_info("%s %d no %s info exist\n",
			__func__, __LINE__, rsv_info->name);
		ret = 1;
	}
	return ret;
}

int meson_rsv_init(struct mtd_info *mtd,
		   struct meson_rsv_handler_t *handler)
{
	int i, ret = 0;
	u32 pages_per_blk_shift, start, vernier;

	pages_per_blk_shift = mtd->erasesize_shift - mtd->writesize_shift;
	start = BOOT_TOTAL_PAGES >> pages_per_blk_shift;
	start += NAND_GAP_BLOCK_NUM;
	vernier = start;
	handler->fn_bitmask = 0;
	for (i = 0; i < NAND_RSV_BLOCK_NUM; i++) {
		handler->free_node[i] =
			kzalloc(sizeof(struct free_node_t), GFP_KERNEL);
		if (!handler->free_node[i]) {
			ret = -ENOMEM;
			goto error;
		}
		memset(handler->free_node[i], 0, sizeof(struct free_node_t));
		handler->free_node[i]->index = i;
	}

	handler->bbt =
		kzalloc(sizeof(*handler->bbt), GFP_KERNEL);
	if (!handler->bbt) {
		ret = -ENOMEM;
		goto error;
	}
	handler->bbt->nvalid =
		kzalloc(sizeof(*handler->bbt->nvalid), GFP_KERNEL);
	if (!handler->bbt->nvalid) {
		ret = -ENOMEM;
		goto error;
	}
	handler->bbt->mtd = mtd;
	handler->bbt->start = vernier;
	handler->bbt->end = vernier + NAND_BBT_BLOCK_NUM;
	handler->bbt->nvalid->blk_addr = -1;
	handler->bbt->size = mtd->size >> mtd->erasesize_shift;
	handler->bbt->handler = handler;
	memcpy(handler->bbt->name, BBT_NAND_MAGIC, 4);
	vernier += NAND_BBT_BLOCK_NUM;
#ifndef CONFIG_ENV_IS_IN_NAND
	handler->env =
		kzalloc(sizeof(*handler->env), GFP_KERNEL);
	if (!handler->env) {
		ret = -ENOMEM;
		goto error;
	}
	handler->env->nvalid =
		kzalloc(sizeof(*handler->env->nvalid), GFP_KERNEL);
	if (!handler->env->nvalid) {
		ret = -ENOMEM;
		goto error;
	}
	handler->env->mtd = mtd;
	handler->env->start = vernier;
	handler->env->end = vernier + NAND_ENV_BLOCK_NUM;
	handler->env->nvalid->blk_addr = -1;
	handler->env->size = CONFIG_ENV_SIZE;
	handler->env->handler = handler;
	memcpy(handler->env->name, ENV_NAND_MAGIC, 4);
	vernier += NAND_ENV_BLOCK_NUM;
#endif
	handler->key =
		kzalloc(sizeof(*handler->key), GFP_KERNEL);
	if (!handler->key) {
		ret = -ENOMEM;
		goto error;
	}
	handler->key->nvalid =
		kzalloc(sizeof(*handler->key->nvalid), GFP_KERNEL);
	if (!handler->key->nvalid) {
		ret = -ENOMEM;
		goto error;
	}
	handler->key->mtd = mtd;
	handler->key->start = vernier;
	handler->key->end = vernier + NAND_KEY_BLOCK_NUM;
	handler->key->nvalid->blk_addr = -1;
	handler->key->size = 0;
	handler->key->handler = handler;
	memcpy(handler->key->name, KEY_NAND_MAGIC, 4);
	vernier += NAND_KEY_BLOCK_NUM;

	handler->dtb =
		kzalloc(sizeof(*handler->dtb), GFP_KERNEL);
	if (!handler->dtb) {
		ret = -ENOMEM;
		goto error;
	}
	handler->dtb->nvalid =
		kzalloc(sizeof(*handler->dtb->nvalid), GFP_KERNEL);
	if (!handler->dtb->nvalid) {
		ret = -ENOMEM;
		goto error;
	}
	handler->dtb->mtd = mtd;
	handler->dtb->start = vernier;
	handler->dtb->end = vernier + NAND_DTB_BLOCK_NUM;
	handler->dtb->nvalid->blk_addr = -1;
	handler->dtb->size = 0;
	handler->dtb->handler = handler;
	memcpy(handler->dtb->name, DTB_NAND_MAGIC, 4);
	vernier += NAND_DTB_BLOCK_NUM;

	if (mtd->erasesize < 0x40000) {
		handler->key->size = mtd->erasesize >> 2;
		handler->dtb->size = mtd->erasesize;
	} else {
		handler->key->size = 0x40000;
		handler->dtb->size = 0x40000;
	}

	if ((vernier - start) > NAND_RSV_BLOCK_NUM) {
		pr_info("ERROR: total blk number is over the limit\n");
		ret = -ENOMEM;
		goto error;
	}
	rsv_handler = handler;

	printf("bbt_start=%d, size:0x%x\n", handler->bbt->start,handler->bbt->size);
#ifndef CONFIG_ENV_IS_IN_NAND
	printf("env_start=%d, size:0x%x\n", handler->env->start,handler->env->size);
#endif
	printf("key_start=%d, size:0x%x\n", handler->key->start,handler->key->size);
	printf("dtb_start=%d, size:0x%x\n", handler->dtb->start,handler->dtb->size);
	printf("\n");

	return ret;
error:
	for (i = 0; i < NAND_RSV_BLOCK_NUM; i++) {
		free(handler->free_node[i]);
		handler->free_node[i] = NULL;
	}
	free(handler->bbt->nvalid);
	free(handler->bbt);
	handler->bbt = NULL;
	free(handler->env->nvalid);
	free(handler->env);
	handler->env = NULL;
	free(handler->key->nvalid);
	free(handler->key);
	handler->key = NULL;
	free(handler->dtb->nvalid);
	free(handler->dtb);
	handler->dtb = NULL;
	return ret;
}

int meson_rsv_bbt_read(u_char *dest, size_t size)
{
	u_char *temp;
	size_t len;
	int ret;

	if (!rsv_handler ||
	    !rsv_handler->bbt) {
		pr_info("%s %d rsv info not inited yet!\n",
			__func__, __LINE__);
		return 1;
	}
	if (!dest || size == 0) {
		pr_info("%s %d parameter error %p %ld\n",
			__func__, __LINE__, dest, size);
		return 1;
	}
	len = rsv_handler->bbt->size;
	temp = kzalloc(len, GFP_KERNEL);
	memset(temp, 0, len);
	ret = meson_rsv_read(rsv_handler->bbt, temp);
	memcpy(dest, temp, len > size ? size : len);
	pr_info("%s %d read 0x%lx bytes from bbt, ret %d\n",
		__func__, __LINE__, len > size ? size : len, ret);
	free(temp);
	return ret;
}

int meson_rsv_key_read(u_char *dest, size_t size)
{
	u_char *temp;
	size_t len;
	int ret;

	if (!rsv_handler ||
	    !rsv_handler->key) {
		pr_info("%s %d rsv info not inited yet!\n",
			__func__, __LINE__);
		return 1;
	}
	if (!dest || size == 0) {
		pr_info("%s %d parameter error %p %ld\n",
			__func__, __LINE__, dest, size);
		return 1;
	}
	len = rsv_handler->key->size;
	temp = kzalloc(len, GFP_KERNEL);
	memset(temp, 0, len);
	ret = meson_rsv_read(rsv_handler->key, temp);
	memcpy(dest, temp, len > size ? size : len);
	pr_info("%s %d read 0x%lx bytes from key, ret %d\n",
		__func__, __LINE__, len > size ? size : len, ret);
	free(temp);
	return ret;
}

int meson_rsv_env_read(u_char *dest, size_t size)
{
	u_char *temp;
	size_t len;
	int ret;

	if (!rsv_handler ||
	    !rsv_handler->env) {
		pr_info("%s %d rsv info not inited yet!\n",
			__func__, __LINE__);
		return 1;
	}
	if (!dest || size == 0) {
		pr_info("%s %d parameter error %p %ld\n",
			__func__, __LINE__, dest, size);
		return 1;
	}
	len = rsv_handler->env->size;
	temp = kzalloc(len, GFP_KERNEL);
	memset(temp, 0, len);
	ret = meson_rsv_read(rsv_handler->env, temp);
	memcpy(dest, temp, len > size ? size : len);
	pr_info("%s %d read 0x%lx bytes from env, ret %d\n",
		__func__, __LINE__, len > size ? size : len, ret);
	free(temp);
	return ret;
}

int meson_rsv_dtb_read(u_char *dest, size_t size)
{
	u_char *temp;
	size_t len;
	int ret;

	if (!rsv_handler ||
	    !rsv_handler->dtb) {
		pr_info("%s %d rsv info not inited yet!\n",
			__func__, __LINE__);
		return 1;
	}
	if (!dest || size == 0) {
		pr_info("%s %d parameter error %p %ld\n",
			__func__, __LINE__, dest, size);
		return 1;
	}
	len = rsv_handler->dtb->size;
	temp = kzalloc(len, GFP_KERNEL);
	memset(temp, 0, len);
	ret = meson_rsv_read(rsv_handler->dtb, temp);
	memcpy(dest, temp, len > size ? size : len);
	pr_info("%s %d read 0x%lx bytes from dtb, ret %d\n",
		__func__, __LINE__, len > size ? size : len, ret);
	free(temp);
	return ret;
}

/*update bbt*/
int meson_rsv_bbt_write(u_char *source, size_t size)
{
	u_char *temp;
	size_t len;
	int ret;

	if (!rsv_handler ||
	    !rsv_handler->bbt) {
		pr_info("%s %d rsv info not inited yet!\n",
			__func__, __LINE__);
		return 1;
	}
	if (!source || size == 0) {
		pr_info("%s %d parameter error %p %ld\n",
			__func__, __LINE__, source, size);
		return 1;
	}
	len = rsv_handler->bbt->size;
	temp = kzalloc(len, GFP_KERNEL);
	memset(temp, 0, len);
	memcpy(temp, source, len > size ? size : len);
	ret = meson_rsv_save(rsv_handler->bbt, temp);
	pr_info("%s %d write 0x%lx bytes to bbt, ret %d\n",
		__func__, __LINE__, len > size ? size : len, ret);
	free(temp);
	return ret;
}

int meson_rsv_key_write(u_char *source, size_t size)
{
	u_char *temp;
	size_t len;
	int ret;

	if (!rsv_handler ||
	    !rsv_handler->key) {
		pr_info("%s %d rsv info not inited yet!\n",
			__func__, __LINE__);
		return 1;
	}
	if (!source || size == 0) {
		pr_info("%s %d parameter error %p %ld\n",
			__func__, __LINE__, source, size);
		return 1;
	}
	len = rsv_handler->key->size;
	temp = kzalloc(len, GFP_KERNEL);
	memset(temp, 0, len);
	memcpy(temp, source, len > size ? size : len);
	ret = meson_rsv_save(rsv_handler->key, temp);
	pr_info("%s %d write 0x%lx bytes to key, ret %d\n",
		__func__, __LINE__, len > size ? size : len, ret);
	free(temp);
	return ret;
}

int meson_rsv_env_write(u_char *source, size_t size)
{
	u_char *temp;
	size_t len;
	int ret;

	if (!rsv_handler ||
	    !rsv_handler->env) {
		pr_info("%s %d rsv info has not inited yet!\n",
			__func__, __LINE__);
		return 1;
	}
	if (!source || size == 0) {
		pr_info("%s %d parameter error %p %ld\n",
			__func__, __LINE__, source, size);
		return 1;
	}
	len = rsv_handler->env->size;
	temp = kzalloc(len, GFP_KERNEL);
	memset(temp, 0, len);
	memcpy(temp, source, len > size ? size : len);
	ret = meson_rsv_save(rsv_handler->env, temp);
	pr_info("%s %d write 0x%lx bytes to env, ret %d\n",
		__func__, __LINE__, len > size ? size : len, ret);
	free(temp);
	return ret;
}

int meson_rsv_dtb_write(u_char *source, size_t size)
{
	u_char *temp;
	size_t len;
	int ret;

	if (!rsv_handler ||
	    !rsv_handler->dtb) {
		pr_info("%s %d rsv info has not inited yet!\n",
			__func__, __LINE__);
		return 1;
	}
	if (!source || size == 0) {
		pr_info("%s %d parameter error %p %ld\n",
			__func__, __LINE__, source, size);
		return 1;
	}
	len = rsv_handler->dtb->size;
	temp = kzalloc(len, GFP_KERNEL);
	memset(temp, 0, len);
	memcpy(temp, source, len > size ? size : len);
	ret = meson_rsv_save(rsv_handler->dtb, temp);
	pr_info("%s %d write 0x%lx bytes to dtb, ret %d\n",
		__func__, __LINE__, len > size ? size : len, ret);
	free(temp);
	return ret;
}

u32 meson_rsv_bbt_size(void)
{
	if (!rsv_handler ||
	    !rsv_handler->bbt) {
		pr_info("%s %d rsv info has not inited yet!\n",
			__func__, __LINE__);
		return 0;
	}
	return rsv_handler->bbt->size;
}

u32 meson_rsv_key_size(void)
{
	if (!rsv_handler ||
	    !rsv_handler->key) {
		pr_info("%s %d rsv info has not inited yet!\n",
			__func__, __LINE__);
		return 0;
	}
	return rsv_handler->key->size;
}

u32 meson_rsv_env_size(void)
{
	if (!rsv_handler ||
	    !rsv_handler->env) {
		pr_info("%s %d rsv info has not inited yet!\n",
			__func__, __LINE__);
		return 0;
	}
	return rsv_handler->env->size;
}

u32 meson_rsv_dtb_size(void)
{
	if (!rsv_handler ||
	    !rsv_handler->dtb) {
		pr_info("%s %d rsv info has not inited yet!\n",
			__func__, __LINE__);
		return 0;
	}
	return rsv_handler->dtb->size;
}

int meson_rsv_bbt_erase(void)
{
	if (!rsv_handler ||
	    !rsv_handler->bbt) {
		pr_info("%s %d rsv info has not inited yet!\n",
			__func__, __LINE__);
		return 1;
	}
	return meson_rsv_erase(rsv_handler->bbt);
}

int meson_rsv_key_erase(void)
{
	if (!rsv_handler ||
	    !rsv_handler->key) {
		pr_info("%s %d rsv info has not inited yet!\n",
			__func__, __LINE__);
		return 1;
	}
	return meson_rsv_erase(rsv_handler->key);
}

int meson_rsv_env_erase(void)
{
	if (!rsv_handler ||
	    !rsv_handler->env) {
		pr_info("%s %d rsv info has not inited yet!\n",
			__func__, __LINE__);
		return 1;
	}
	return meson_rsv_erase(rsv_handler->env);
}

int meson_rsv_dtb_erase(void)
{
	if (!rsv_handler ||
	    !rsv_handler->dtb) {
		pr_info("%s %d rsv info has not inited yet!\n",
			__func__, __LINE__);
		return 1;
	}

	return meson_rsv_erase(rsv_handler->dtb);

}
