summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2017-01-11 14:02:04 +0100
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2017-01-12 11:02:19 +0100
commit6df83fd628ece2a44da325951bbfc5c33e3c6866 (patch)
tree1f3e5eda5346563eeb5512285b98978a34b81ce8
parent7b8981af83b2c6decad32673111dce8d416dbb2e (diff)
nandwrite: fix/cleanup bad block skipping
JFFS2 supports clustering erase blocks to virtual erase blocks. nandwrite supports this, but previously mixed up virtual and physical erase block numbers when checking for bad blocks. This patch adds a function for checking if a virtual erase block is bad and replaces the broken mtd_is_bad loop. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--nand-utils/nandwrite.c57
1 files changed, 30 insertions, 27 deletions
diff --git a/nand-utils/nandwrite.c b/nand-utils/nandwrite.c
index 22c741d..c7a53d1 100644
--- a/nand-utils/nandwrite.c
+++ b/nand-utils/nandwrite.c
@@ -235,6 +235,20 @@ static void erase_buffer(void *buffer, size_t size)
memset(buffer, kEraseByte, size);
}
+static int is_virt_block_bad(struct mtd_dev_info *mtd, int fd,
+ long long offset)
+{
+ int i, ret = 0;
+
+ for (i = 0; i < blockalign; ++i) {
+ ret = mtd_is_bad(mtd, fd, offset / mtd->eb_size + i);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
/*
* Main program
*/
@@ -246,10 +260,8 @@ int main(int argc, char * const argv[])
int ifd = -1;
int pagelen;
long long imglen = 0;
- bool baderaseblock = false;
long long blockstart = -1;
struct mtd_dev_info mtd;
- long long offs;
int ret;
bool failed = true;
/* contains all the data read from the file so far for the current eraseblock */
@@ -391,7 +403,6 @@ int main(int argc, char * const argv[])
*/
while (blockstart != (mtdoffset & (~ebsize_aligned + 1))) {
blockstart = mtdoffset & (~ebsize_aligned + 1);
- offs = blockstart;
/*
* if writebuf == filebuf, we are rewinding so we must
@@ -403,40 +414,32 @@ int main(int argc, char * const argv[])
writebuf = filebuf;
}
- baderaseblock = false;
if (!quiet)
fprintf(stdout, "Writing data to block %lld at offset 0x%llx\n",
blockstart / ebsize_aligned, blockstart);
- /* Check all the blocks in an erase block for bad blocks */
if (noskipbad)
continue;
- do {
- ret = mtd_is_bad(&mtd, fd, offs / ebsize_aligned);
- if (ret < 0) {
- sys_errmsg("%s: MTD get bad block failed", mtd_device);
- goto closeall;
- } else if (ret == 1) {
- baderaseblock = true;
- if (!quiet)
- fprintf(stderr, "Bad block at %llx, %u block(s) "
- "from %llx will be skipped\n",
- offs, blockalign, blockstart);
- }
+ ret = is_virt_block_bad(&mtd, fd, blockstart);
- if (baderaseblock) {
- mtdoffset = blockstart + ebsize_aligned;
-
- if (mtdoffset > mtd.size) {
- errmsg("too many bad blocks, cannot complete request");
- goto closeall;
- }
- }
+ if (ret < 0) {
+ sys_errmsg("%s: MTD get bad block failed", mtd_device);
+ goto closeall;
+ } else if (ret == 1) {
+ if (!quiet)
+ fprintf(stderr,
+ "Bad block at %llx, %u block(s) "
+ "will be skipped\n",
+ blockstart, blockalign);
- offs += ebsize_aligned / blockalign;
- } while (offs < blockstart + ebsize_aligned);
+ mtdoffset = blockstart + ebsize_aligned;
+ if (mtdoffset > mtd.size) {
+ errmsg("too many bad blocks, cannot complete request");
+ goto closeall;
+ }
+ }
}
/* Read more data from the input if there isn't enough in the buffer */