#include <linux/device.h>
#define ENV_NAME "nand_env"
+static DEFINE_MUTEX(env_mutex);
static dev_t uboot_env_no;
struct cdev uboot_env;
struct device *uboot_dev;
int ret = 0;
u8 *env_ptr = NULL;
- pr_info("env_store : #####\n");
env_ptr = kzalloc(CONFIG_ENV_SIZE, GFP_KERNEL);
if (env_ptr == NULL)
return -ENOMEM;
+ mutex_lock(&env_mutex);
+ pr_info("env_store : #####\n");
ret = amlnf_env_read(env_ptr, CONFIG_ENV_SIZE);
if (ret) {
pr_info("nand_env_read: nand env read failed\n");
}
pr_info("env_store : OK #####\n");
+ mutex_unlock(&env_mutex);
return count;
}
env_ptr = vmalloc(CONFIG_ENV_SIZE + 2048);
if (env_ptr == NULL)
return -ENOMEM;
+ mutex_lock(&env_mutex);
/*amlnand_get_device(aml_chip_env, CHIP_READING);*/
ret = amlnf_env_read((u8 *)env_ptr, CONFIG_ENV_SIZE);
ret = copy_to_user(buf, (env_ptr + *ppos), read_size);
*ppos += read_size;
exit:
+ mutex_unlock(&env_mutex);
/*amlnand_release_device(aml_chip_env);*/
vfree(env_ptr);
return read_size;
if (env_ptr == NULL)
return -ENOMEM;
+ mutex_lock(&env_mutex);
/*not need nand_get_device here, mtd->_read_xx will done with it*/
/*nand_get_device(mtd, FL_WRITING);*/
ret = amlnf_env_read((u8 *)env_ptr, CONFIG_ENV_SIZE);
*ppos += write_size;
exit:
+ mutex_unlock(&env_mutex);
/*nand_release_device(mtd);*/
vfree(env_ptr);
return write_size;
int aml_nand_rsv_erase_protect(struct mtd_info *mtd, unsigned int block_addr)
{
struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd);
+ unsigned int bbt_start, bbt_end, key_start, key_end;
if (!_aml_rsv_isprotect())
return 0;
+ bbt_start = aml_chip->aml_nandbbt_info->start_block;
+ bbt_end = aml_chip->aml_nandbbt_info->end_block;
+ key_start = aml_chip->aml_nandkey_info->start_block;
+ key_end = aml_chip->aml_nandkey_info->end_block;
+
#ifdef AML_NAND_UBOOT
if (aml_chip->aml_nandkey_info != NULL) {
if (aml_chip->aml_nandkey_info->valid)
if ((!(info_disprotect & DISPROTECT_KEY))
- && ((block_addr >= aml_chip->aml_nandkey_info->start_block)
- && (block_addr < aml_chip->aml_nandkey_info->end_block)))
- return -1; /*need skip key blocks*/
+ && ((block_addr >= key_start)
+ && (block_addr < key_end)))
+ return -1; /*need skip key blocks*/
}
if (aml_chip->aml_nandbbt_info != NULL) {
if (aml_chip->aml_nandbbt_info->valid)
- if ((block_addr >= aml_chip->aml_nandbbt_info->start_block)
- && (block_addr < aml_chip->aml_nandbbt_info->end_block))
- return -1; /*need skip bbt blocks*/
+ if ((block_addr >= bbt_start)
+ && (block_addr < bbt_end))
+ return -1; /*need skip bbt blocks*/
}
#else
if (aml_chip->aml_nandkey_info != NULL) {
if (aml_chip->aml_nandkey_info->valid)
- if ((block_addr >= aml_chip->aml_nandkey_info->start_block)
- && (block_addr < aml_chip->aml_nandkey_info->end_block))
- return -1; /*need skip key blocks*/
+ if ((block_addr >= key_start)
+ && (block_addr < key_end))
+ return -1; /*need skip key blocks*/
}
if (aml_chip->aml_nandbbt_info != NULL) {
if (aml_chip->aml_nandbbt_info->valid)
- if ((block_addr >= aml_chip->aml_nandbbt_info->start_block)
- && (block_addr < aml_chip->aml_nandbbt_info->end_block))
- return -1; /*need skip bbt blocks*/
+ if ((block_addr >= bbt_start)
+ && (block_addr < bbt_end))
+ return -1; /*need skip bbt blocks*/
}
#endif
return 0;
struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd);
pages_per_blk = mtd->erasesize / mtd->writesize;
+ /*solve these abnormals caused by power off and ecc error*/
+ if ((nandrsv_info->valid_node->status & POWER_ABNORMAL_FLAG)
+ || (nandrsv_info->valid_node->status & ECC_ABNORMAL_FLAG))
+ nandrsv_info->valid_node->phy_page_addr = pages_per_blk;
+
if ((mtd->writesize < nandrsv_info->size)
&& (aml_chip->aml_nandenv_info->valid == 1))
i = (nandrsv_info->size + mtd->writesize - 1) / mtd->writesize;
nandrsv_info->valid_node->phy_page_addr += i;
if ((nandrsv_info->valid_node->phy_page_addr+i) > pages_per_blk) {
if ((nandrsv_info->valid_node->phy_page_addr - i) == pages_per_blk) {
- nandrsv_info->valid_node->status = 0;
addr = nandrsv_info->valid_node->phy_blk_addr;
addr *= mtd->erasesize;
memset(&erase_info,
_aml_rsv_disprotect();
error = mtd->_erase(mtd, &erase_info);
_aml_rsv_protect();
- nandrsv_info->valid_node->status = 1;
nandrsv_info->valid_node->ec++;
pr_info("---erase bad env block:%llx\n", addr);
}
erase_info.mtd = mtd;
erase_info.addr = addr;
erase_info.len = mtd->erasesize;
- nandrsv_info->valid_node->status = 0;
_aml_rsv_disprotect();
error = mtd->_erase(mtd, &erase_info);
_aml_rsv_protect();
return error;
}
nandrsv_info->valid_node->ec++;
- nandrsv_info->valid_node->status = 1;
}
if (aml_nand_write_rsv(mtd, nandrsv_info, addr, (u_char *) buf)) {
return 1;
}
+ /* clear status when write successfully*/
+ nandrsv_info->valid_node->status = 0;
return error;
}
return -ENOMEM;
aml_chip->aml_nandbbt_info->valid_node->phy_blk_addr = -1;
- aml_chip->aml_nandbbt_info->valid_node->status = 1;
aml_chip->aml_nandbbt_info->start_block = bbt_start_block;
aml_chip->aml_nandbbt_info->end_block =
aml_chip->aml_nandbbt_info->start_block + 4;
return -ENOMEM;
aml_chip->aml_nandenv_info->valid_node->phy_blk_addr = -1;
- aml_chip->aml_nandenv_info->valid_node->status = 1;
aml_chip->aml_nandenv_info->start_block =
aml_chip->aml_nandbbt_info->end_block;
aml_chip->aml_nandenv_info->end_block =
return -ENOMEM;
aml_chip->aml_nandkey_info->valid_node->phy_blk_addr = -1;
- aml_chip->aml_nandkey_info->valid_node->status = 1;
aml_chip->aml_nandkey_info->start_block =
aml_chip->aml_nandenv_info->end_block;
aml_chip->aml_nandkey_info->end_block =
return -ENOMEM;
aml_chip->aml_nanddtb_info->valid_node->phy_blk_addr = -1;
- aml_chip->aml_nanddtb_info->valid_node->status = 1;
aml_chip->aml_nanddtb_info->start_block =
aml_chip->aml_nandkey_info->end_block;
aml_chip->aml_nanddtb_info->end_block =
/* pr_info("%s %d\n", __func__, __LINE__); */
nandrsv_info->init = 1;
+ nandrsv_info->valid_node->status = 0;
if (!memcmp(oobinfo->name, nandrsv_info->name, 4)) {
/* pr_info("%s %d\n", __func__, __LINE__); */
nandrsv_info->valid = 1;