diff options
author | Richard Genoud <richard.genoud@gmail.com> | 2013-09-28 15:55:13 +0200 |
---|---|---|
committer | Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 2013-10-03 19:42:50 +0300 |
commit | c22301ad4fa0f4cf71e9c877d072e6f07a0bf682 (patch) | |
tree | 193c29c2ae335240e9fddb24c4b1177ee3a59eb3 /drivers/mtd/ubi/fastmap.c | |
parent | 4b3e0a25aa5518892ec8dbfafdd6a57789aa0c22 (diff) | |
download | op-kernel-dev-c22301ad4fa0f4cf71e9c877d072e6f07a0bf682.zip op-kernel-dev-c22301ad4fa0f4cf71e9c877d072e6f07a0bf682.tar.gz |
UBI: fastmap: fix backward compatibility with image_seq
Some old UBI implementations (e.g. U-Boot) have not implemented the image
sequence feature.
So, when erase blocks are written, the image sequence in the ec header
is lost (set to zero).
UBI scan_all() takes this case into account (commits
32bc4820287a1a03982979515949e8ea56eac641 and
2eadaad67b2b6bd132eda105128d2d466298b8e3)
But fastmap scan functions (ubi_scan_fastmap() and scan_pool()) didn't.
This patch fixes the issue.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'drivers/mtd/ubi/fastmap.c')
-rw-r--r-- | drivers/mtd/ubi/fastmap.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 9b42add..05067f5 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -407,6 +407,7 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, */ for (i = 0; i < pool_size; i++) { int scrub = 0; + int image_seq; pnum = be32_to_cpu(pebs[i]); @@ -425,7 +426,13 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, } else if (ret == UBI_IO_BITFLIPS) scrub = 1; - if (be32_to_cpu(ech->image_seq) != ubi->image_seq) { + /* + * Older UBI implementations have image_seq set to zero, so + * we shouldn't fail if image_seq == 0. + */ + image_seq = be32_to_cpu(ech->image_seq); + + if (image_seq && (image_seq != ubi->image_seq)) { ubi_err("bad image seq: 0x%x, expected: 0x%x", be32_to_cpu(ech->image_seq), ubi->image_seq); ret = UBI_BAD_FASTMAP; @@ -923,6 +930,8 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, } for (i = 0; i < used_blocks; i++) { + int image_seq; + pnum = be32_to_cpu(fmsb->block_loc[i]); if (ubi_io_is_bad(ubi, pnum)) { @@ -940,10 +949,17 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, } else if (ret == UBI_IO_BITFLIPS) fm->to_be_tortured[i] = 1; + image_seq = be32_to_cpu(ech->image_seq); if (!ubi->image_seq) - ubi->image_seq = be32_to_cpu(ech->image_seq); + ubi->image_seq = image_seq; - if (be32_to_cpu(ech->image_seq) != ubi->image_seq) { + /* + * Older UBI implementations have image_seq set to zero, so + * we shouldn't fail if image_seq == 0. + */ + if (image_seq && (image_seq != ubi->image_seq)) { + ubi_err("wrong image seq:%d instead of %d", + be32_to_cpu(ech->image_seq), ubi->image_seq); ret = UBI_BAD_FASTMAP; goto free_hdr; } |