mtd: Unconditionally update ->fail_addr and ->addr in part_erase()
->fail_addr and ->addr can be updated no matter the result of parent->_erase(), we just need to remove the code doing the same thing in mtd_erase_callback() to avoid adjusting those fields twice. Note that this can be done because all MTD users have been converted to not pass an erase_info->callback() and are thus only taking the ->addr_fail and ->addr fields into account after part_erase() has returned. While we're at it, get rid of the erase_info->mtd field which was only needed to let mtd_erase_callback() get the partition device back. Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> Reviewed-by: Richard Weinberger <richard@nod.at>
This commit is contained in:
parent
884cfd9023
commit
8f347c4232
|
@ -342,7 +342,6 @@ static int erase_xfer(partition_t *part,
|
||||||
if (!erase)
|
if (!erase)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
erase->mtd = part->mbd.mtd;
|
|
||||||
erase->addr = xfer->Offset;
|
erase->addr = xfer->Offset;
|
||||||
erase->len = 1 << part->header.EraseUnitSize;
|
erase->len = 1 << part->header.EraseUnitSize;
|
||||||
|
|
||||||
|
|
|
@ -208,8 +208,6 @@ static int find_boot_record(struct INFTLrecord *inftl)
|
||||||
if (ip->Reserved0 != ip->firstUnit) {
|
if (ip->Reserved0 != ip->firstUnit) {
|
||||||
struct erase_info *instr = &inftl->instr;
|
struct erase_info *instr = &inftl->instr;
|
||||||
|
|
||||||
instr->mtd = inftl->mbd.mtd;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Most likely this is using the
|
* Most likely this is using the
|
||||||
* undocumented qiuck mount feature.
|
* undocumented qiuck mount feature.
|
||||||
|
@ -385,7 +383,6 @@ int INFTL_formatblock(struct INFTLrecord *inftl, int block)
|
||||||
_first_? */
|
_first_? */
|
||||||
|
|
||||||
/* Use async erase interface, test return code */
|
/* Use async erase interface, test return code */
|
||||||
instr->mtd = inftl->mbd.mtd;
|
|
||||||
instr->addr = block * inftl->EraseSize;
|
instr->addr = block * inftl->EraseSize;
|
||||||
instr->len = inftl->mbd.mtd->erasesize;
|
instr->len = inftl->mbd.mtd->erasesize;
|
||||||
/* Erase one physical eraseblock at a time, even though the NAND api
|
/* Erase one physical eraseblock at a time, even though the NAND api
|
||||||
|
|
|
@ -65,7 +65,6 @@ static int erase_write (struct mtd_info *mtd, unsigned long pos,
|
||||||
/*
|
/*
|
||||||
* First, let's erase the flash block.
|
* First, let's erase the flash block.
|
||||||
*/
|
*/
|
||||||
erase.mtd = mtd;
|
|
||||||
erase.addr = pos;
|
erase.addr = pos;
|
||||||
erase.len = len;
|
erase.len = len;
|
||||||
|
|
||||||
|
|
|
@ -726,7 +726,6 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
|
||||||
erase->addr = einfo32.start;
|
erase->addr = einfo32.start;
|
||||||
erase->len = einfo32.length;
|
erase->len = einfo32.length;
|
||||||
}
|
}
|
||||||
erase->mtd = mtd;
|
|
||||||
|
|
||||||
ret = mtd_erase(mtd, erase);
|
ret = mtd_erase(mtd, erase);
|
||||||
kfree(erase);
|
kfree(erase);
|
||||||
|
|
|
@ -427,7 +427,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||||
erase->len = length;
|
erase->len = length;
|
||||||
|
|
||||||
length -= erase->len;
|
length -= erase->len;
|
||||||
erase->mtd = subdev;
|
|
||||||
if ((err = mtd_erase(subdev, erase))) {
|
if ((err = mtd_erase(subdev, erase))) {
|
||||||
/* sanity check: should never happen since
|
/* sanity check: should never happen since
|
||||||
* block alignment has been checked above */
|
* block alignment has been checked above */
|
||||||
|
|
|
@ -94,7 +94,6 @@ static int mtdoops_erase_block(struct mtdoops_context *cxt, int offset)
|
||||||
int ret;
|
int ret;
|
||||||
int page;
|
int page;
|
||||||
|
|
||||||
erase.mtd = mtd;
|
|
||||||
erase.addr = offset;
|
erase.addr = offset;
|
||||||
erase.len = mtd->erasesize;
|
erase.len = mtd->erasesize;
|
||||||
|
|
||||||
|
|
|
@ -205,23 +205,15 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||||
|
|
||||||
instr->addr += part->offset;
|
instr->addr += part->offset;
|
||||||
ret = part->parent->_erase(part->parent, instr);
|
ret = part->parent->_erase(part->parent, instr);
|
||||||
if (ret) {
|
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
||||||
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
instr->fail_addr -= part->offset;
|
||||||
instr->fail_addr -= part->offset;
|
instr->addr -= part->offset;
|
||||||
instr->addr -= part->offset;
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mtd_erase_callback(struct erase_info *instr)
|
void mtd_erase_callback(struct erase_info *instr)
|
||||||
{
|
{
|
||||||
if (instr->mtd->_erase == part_erase) {
|
|
||||||
struct mtd_part *part = mtd_to_part(instr->mtd);
|
|
||||||
|
|
||||||
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
|
||||||
instr->fail_addr -= part->offset;
|
|
||||||
instr->addr -= part->offset;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mtd_erase_callback);
|
EXPORT_SYMBOL_GPL(mtd_erase_callback);
|
||||||
|
|
||||||
|
|
|
@ -549,8 +549,6 @@ static int mtdswap_erase_block(struct mtdswap_dev *d, struct swap_eb *eb)
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
memset(&erase, 0, sizeof(struct erase_info));
|
memset(&erase, 0, sizeof(struct erase_info));
|
||||||
|
|
||||||
erase.mtd = mtd;
|
|
||||||
erase.addr = mtdswap_eb_offset(d, eb);
|
erase.addr = mtdswap_eb_offset(d, eb);
|
||||||
erase.len = mtd->erasesize;
|
erase.len = mtd->erasesize;
|
||||||
|
|
||||||
|
|
|
@ -527,7 +527,6 @@ static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs)
|
||||||
|
|
||||||
/* Attempt erase before marking OOB */
|
/* Attempt erase before marking OOB */
|
||||||
memset(&einfo, 0, sizeof(einfo));
|
memset(&einfo, 0, sizeof(einfo));
|
||||||
einfo.mtd = mtd;
|
|
||||||
einfo.addr = ofs;
|
einfo.addr = ofs;
|
||||||
einfo.len = 1ULL << chip->phys_erase_shift;
|
einfo.len = 1ULL << chip->phys_erase_shift;
|
||||||
nand_erase_nand(mtd, &einfo, 0);
|
nand_erase_nand(mtd, &einfo, 0);
|
||||||
|
|
|
@ -852,7 +852,6 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&einfo, 0, sizeof(einfo));
|
memset(&einfo, 0, sizeof(einfo));
|
||||||
einfo.mtd = mtd;
|
|
||||||
einfo.addr = to;
|
einfo.addr = to;
|
||||||
einfo.len = 1 << this->bbt_erase_shift;
|
einfo.len = 1 << this->bbt_erase_shift;
|
||||||
res = nand_erase_nand(mtd, &einfo, 1);
|
res = nand_erase_nand(mtd, &einfo, 1);
|
||||||
|
|
|
@ -328,7 +328,6 @@ int NFTL_formatblock(struct NFTLrecord *nftl, int block)
|
||||||
memset(instr, 0, sizeof(struct erase_info));
|
memset(instr, 0, sizeof(struct erase_info));
|
||||||
|
|
||||||
/* XXX: use async erase interface, XXX: test return code */
|
/* XXX: use async erase interface, XXX: test return code */
|
||||||
instr->mtd = nftl->mbd.mtd;
|
|
||||||
instr->addr = block * nftl->EraseSize;
|
instr->addr = block * nftl->EraseSize;
|
||||||
instr->len = nftl->EraseSize;
|
instr->len = nftl->EraseSize;
|
||||||
if (mtd_erase(mtd, instr)) {
|
if (mtd_erase(mtd, instr)) {
|
||||||
|
|
|
@ -275,7 +275,6 @@ static int erase_block(struct partition *part, int block)
|
||||||
if (!erase)
|
if (!erase)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
erase->mtd = part->mbd.mtd;
|
|
||||||
erase->addr = part->blocks[block].offset;
|
erase->addr = part->blocks[block].offset;
|
||||||
erase->len = part->block_size;
|
erase->len = part->block_size;
|
||||||
|
|
||||||
|
|
|
@ -460,7 +460,6 @@ static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
|
||||||
struct mtd_info *mtd = ftl->trans->mtd;
|
struct mtd_info *mtd = ftl->trans->mtd;
|
||||||
struct erase_info erase;
|
struct erase_info erase;
|
||||||
|
|
||||||
erase.mtd = mtd;
|
|
||||||
erase.addr = sm_mkoffset(ftl, zone_num, block, 0);
|
erase.addr = sm_mkoffset(ftl, zone_num, block, 0);
|
||||||
erase.len = ftl->block_size;
|
erase.len = ftl->block_size;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ int mtdtest_erase_eraseblock(struct mtd_info *mtd, unsigned int ebnum)
|
||||||
loff_t addr = (loff_t)ebnum * mtd->erasesize;
|
loff_t addr = (loff_t)ebnum * mtd->erasesize;
|
||||||
|
|
||||||
memset(&ei, 0, sizeof(struct erase_info));
|
memset(&ei, 0, sizeof(struct erase_info));
|
||||||
ei.mtd = mtd;
|
|
||||||
ei.addr = addr;
|
ei.addr = addr;
|
||||||
ei.len = mtd->erasesize;
|
ei.len = mtd->erasesize;
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,6 @@ static int multiblock_erase(int ebnum, int blocks)
|
||||||
loff_t addr = (loff_t)ebnum * mtd->erasesize;
|
loff_t addr = (loff_t)ebnum * mtd->erasesize;
|
||||||
|
|
||||||
memset(&ei, 0, sizeof(struct erase_info));
|
memset(&ei, 0, sizeof(struct erase_info));
|
||||||
ei.mtd = mtd;
|
|
||||||
ei.addr = addr;
|
ei.addr = addr;
|
||||||
ei.len = mtd->erasesize * blocks;
|
ei.len = mtd->erasesize * blocks;
|
||||||
|
|
||||||
|
|
|
@ -333,7 +333,6 @@ static int do_sync_erase(struct ubi_device *ubi, int pnum)
|
||||||
retry:
|
retry:
|
||||||
memset(&ei, 0, sizeof(struct erase_info));
|
memset(&ei, 0, sizeof(struct erase_info));
|
||||||
|
|
||||||
ei.mtd = ubi->mtd;
|
|
||||||
ei.addr = (loff_t)pnum * ubi->peb_size;
|
ei.addr = (loff_t)pnum * ubi->peb_size;
|
||||||
ei.len = ubi->peb_size;
|
ei.len = ubi->peb_size;
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,6 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
|
||||||
|
|
||||||
memset(instr, 0, sizeof(*instr));
|
memset(instr, 0, sizeof(*instr));
|
||||||
|
|
||||||
instr->mtd = c->mtd;
|
|
||||||
instr->addr = jeb->offset;
|
instr->addr = jeb->offset;
|
||||||
instr->len = c->sector_size;
|
instr->len = c->sector_size;
|
||||||
|
|
||||||
|
|
|
@ -38,13 +38,14 @@
|
||||||
|
|
||||||
#define MTD_FAIL_ADDR_UNKNOWN -1LL
|
#define MTD_FAIL_ADDR_UNKNOWN -1LL
|
||||||
|
|
||||||
|
struct mtd_info;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the erase fails, fail_addr might indicate exactly which block failed. If
|
* If the erase fails, fail_addr might indicate exactly which block failed. If
|
||||||
* fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level
|
* fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level
|
||||||
* or was not specific to any particular block.
|
* or was not specific to any particular block.
|
||||||
*/
|
*/
|
||||||
struct erase_info {
|
struct erase_info {
|
||||||
struct mtd_info *mtd;
|
|
||||||
uint64_t addr;
|
uint64_t addr;
|
||||||
uint64_t len;
|
uint64_t len;
|
||||||
uint64_t fail_addr;
|
uint64_t fail_addr;
|
||||||
|
|
Loading…
Reference in New Issue