* [PATCH 1/2] mtd: peb: Add function to skip bad blocks @ 2019-01-28 13:16 Sascha Hauer 2019-01-28 13:16 ` [PATCH 2/2] usb: fastboot: ubiformat: Fix bad block handling Sascha Hauer 0 siblings, 1 reply; 2+ messages in thread From: Sascha Hauer @ 2019-01-28 13:16 UTC (permalink / raw) To: Barebox List; +Cc: Ahmad Fatoum This adds a function that given a pointer to a PEB number increases the number until the corresponding PEB is good. It also checks for the PEB number being inside the mtd device. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/mtd/peb.c | 27 +++++++++++++++++++++++++++ include/mtd/mtd-peb.h | 1 + 2 files changed, 28 insertions(+) diff --git a/drivers/mtd/peb.c b/drivers/mtd/peb.c index c35b63f2fd..388db7f587 100644 --- a/drivers/mtd/peb.c +++ b/drivers/mtd/peb.c @@ -129,6 +129,33 @@ int mtd_num_pebs(struct mtd_info *mtd) return mtd_div_by_eb(mtd->size, mtd); } +/** + * mtd_skip_bad - skip bad blocks + * @mtd: mtd device + * @pnum: The number of the block + * + * This function skips bad blocks beginning from @pnum. Returns 0 for success and + * a negative error code otherwise. on successful exit @pnum points to the next + * good block. + */ +int mtd_skip_bad(struct mtd_info *mtd, int *pnum) +{ + if (*pnum < 0) + return -EINVAL; + + while (1) { + loff_t offset = (uint64_t)mtd->erasesize * *pnum; + + if (offset >= mtd->size) + return -ENOSPC; + + if (!mtd_block_isbad(mtd, offset)) + return 0; + + *pnum = *pnum + 1; + } +} + /** * mtd_peb_mark_bad - mark a physical eraseblock as bad * @mtd: mtd device diff --git a/include/mtd/mtd-peb.h b/include/mtd/mtd-peb.h index e4fd01df90..23f89d89a8 100644 --- a/include/mtd/mtd-peb.h +++ b/include/mtd/mtd-peb.h @@ -12,6 +12,7 @@ int mtd_peb_torture(struct mtd_info *mtd, int pnum); int mtd_peb_erase(struct mtd_info *mtd, int pnum); int mtd_peb_mark_bad(struct mtd_info *mtd, int pnum); int mtd_peb_is_bad(struct mtd_info *mtd, int pnum); +int mtd_skip_bad(struct mtd_info *mtd, int *pnum); int mtd_peb_check_all_ff(struct mtd_info *mtd, int pnum, int offset, int len, int warn); int mtd_peb_verify(struct mtd_info *mtd, const void *buf, int pnum, -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH 2/2] usb: fastboot: ubiformat: Fix bad block handling 2019-01-28 13:16 [PATCH 1/2] mtd: peb: Add function to skip bad blocks Sascha Hauer @ 2019-01-28 13:16 ` Sascha Hauer 0 siblings, 0 replies; 2+ messages in thread From: Sascha Hauer @ 2019-01-28 13:16 UTC (permalink / raw) To: Barebox List; +Cc: Ahmad Fatoum When fastboot handles UBI images in sparse file format then bad blocks of the underlying mtd device are not skipped. This patch fixes this. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- common/ubiformat.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/common/ubiformat.c b/common/ubiformat.c index 0811525bd2..1968bd98f8 100644 --- a/common/ubiformat.c +++ b/common/ubiformat.c @@ -710,8 +710,10 @@ int ubiformat_write(struct mtd_info *mtd, const void *buf, size_t count, loff_t offset) { int writesize = mtd->writesize >> mtd->subpage_sft; - size_t retlen; int ret; + int peb = 0; + int n_skip_blocks = mtd_div_by_eb(offset, mtd); + int offset_in_peb = mtd_mod_by_eb(offset, mtd); if (offset & (mtd->writesize - 1)) return -EINVAL; @@ -719,27 +721,44 @@ int ubiformat_write(struct mtd_info *mtd, const void *buf, size_t count, if (count & (mtd->writesize - 1)) return -EINVAL; + /* Seek forward to the first PEB we actually want to write */ + while (1) { + ret = mtd_skip_bad(mtd, &peb); + if (ret) + return ret; + + if (!n_skip_blocks) + break; + + peb++; + n_skip_blocks--; + } + while (count) { - size_t now; + size_t now = mtd->erasesize - offset_in_peb; - now = ALIGN(offset, mtd->erasesize) - offset; if (now > count) now = count; - if (!now) { + if (!offset_in_peb) { const struct ubi_ec_hdr *ec = buf; const struct ubi_vid_hdr *vid; + ret = mtd_skip_bad(mtd, &peb); + if (ret) + return ret; + if (be32_to_cpu(ec->magic) != UBI_EC_HDR_MAGIC) { pr_err("bad UBI magic %#08x, should be %#08x", be32_to_cpu(ec->magic), UBI_EC_HDR_MAGIC); return -EINVAL; } - /* skip ec header */ - offset += writesize; + /* skip ec header in both flash and image */ + offset_in_peb = writesize; buf += writesize; count -= writesize; + now -= writesize; if (!count) break; @@ -750,19 +769,16 @@ int ubiformat_write(struct mtd_info *mtd, const void *buf, size_t count, be32_to_cpu(vid->magic), UBI_VID_HDR_MAGIC); return -EINVAL; } - - continue; } - ret = mtd_write(mtd, offset, now, &retlen, buf); + ret = mtd_peb_write(mtd, buf, peb, offset_in_peb, now); if (ret < 0) return ret; - if (retlen != now) - return -EIO; buf += now; count -= now; - offset += now; + offset_in_peb = 0; + peb++; } return 0; -- 2.20.1 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2019-01-28 13:16 UTC | newest] Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-01-28 13:16 [PATCH 1/2] mtd: peb: Add function to skip bad blocks Sascha Hauer 2019-01-28 13:16 ` [PATCH 2/2] usb: fastboot: ubiformat: Fix bad block handling Sascha Hauer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox