9
0
Fork 0

imx-bbu-nand-fcb: erase on demand

Instead of erasing the whole partition on update entry, erase the areas
separately when we actually want to write them. This is done as a step
towards robust update.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Sascha Hauer 2016-03-04 12:53:48 +01:00
parent 14fd7e9478
commit 678617ecaf
1 changed files with 14 additions and 33 deletions

View File

@ -272,34 +272,6 @@ static int fcb_create(struct imx_nand_fcb_bbu_handler *imx_handler,
return 0;
}
static int imx_bbu_erase(struct mtd_info *mtd)
{
uint64_t offset = 0;
struct erase_info erase;
int ret;
while (offset < mtd->size) {
pr_debug("erasing at 0x%08llx\n", offset);
if (mtd_block_isbad(mtd, offset)) {
pr_debug("erase skip block @ 0x%08llx\n", offset);
offset += mtd->erasesize;
continue;
}
memset(&erase, 0, sizeof(erase));
erase.addr = offset;
erase.len = mtd->erasesize;
ret = mtd_erase(mtd, &erase);
if (ret)
return ret;
offset += mtd->erasesize;
}
return 0;
}
static int mtd_peb_write_block(struct mtd_info *mtd, void *buf, int block, int len)
{
int ret;
@ -352,13 +324,22 @@ static int imx_bbu_firmware_start_block(struct mtd_info *mtd, int num)
static int imx_bbu_write_firmware(struct mtd_info *mtd, unsigned num, void *buf,
size_t len)
{
int ret;
int ret, i;
int num_blocks = imx_bbu_firmware_max_blocks(mtd);
int block = imx_bbu_firmware_start_block(mtd, num);
pr_info("writing firmware %d to block %d (ofs 0x%08x)\n",
num, block, block * mtd->erasesize);
for (i = 0; i < num_blocks; i++) {
if (mtd_peb_is_bad(mtd, block + i))
continue;
ret = mtd_peb_erase(mtd, block + i);
if (ret && ret != -EIO)
return ret;
}
while (len > 0) {
int now = min(len, mtd->erasesize);
@ -470,6 +451,10 @@ again:
if (cpu_is_mx28())
imx28_dbbt_create(dbbt, *n_bad_blocksp);
ret = mtd_peb_erase(mtd, block);
if (ret)
return ret;
ret = raw_write_page(mtd, fcb_raw_page, block * mtd->erasesize);
if (ret) {
pr_err("Writing FCB on block %d failed with %s\n",
@ -629,10 +614,6 @@ static int imx_bbu_nand_update(struct bbu_handler *handler, struct bbu_data *dat
if (ret)
goto out;
ret = imx_bbu_erase(mtd);
if (ret)
goto out;
ret = imx_bbu_write_firmware(mtd, 0, fw, fw_size);
if (ret < 0)
goto out;