|
|
@@ -0,0 +1,106 @@
|
|
|
+tools/fw_env: fix writing environment for mtd devices
|
|
|
+
|
|
|
+Signed-off-by: Oliver Metz <[email protected]>
|
|
|
+---
|
|
|
+ tools/env/fw_env.c | 71 ++++++++++++++++++++++++++++++++----------------------
|
|
|
+ 1 file changed, 42 insertions(+), 29 deletions(-)
|
|
|
+
|
|
|
+--- a/tools/env/fw_env.c
|
|
|
++++ b/tools/env/fw_env.c
|
|
|
+@@ -743,27 +743,39 @@ static int flash_write_buf (int dev, int
|
|
|
+ MEMGETBADBLOCK needs 64 bits */
|
|
|
+ int rc;
|
|
|
+
|
|
|
+- blocklen = DEVESIZE (dev);
|
|
|
++ /*
|
|
|
++ * For mtd devices only offset and size of the environment do matter
|
|
|
++ */
|
|
|
++ if (mtd_type == MTD_ABSENT) {
|
|
|
++ blocklen = count;
|
|
|
++ top_of_range = offset + count;
|
|
|
++ erase_len = blocklen;
|
|
|
++ blockstart = offset;
|
|
|
++ block_seek = 0;
|
|
|
++ write_total = blocklen;
|
|
|
++ } else {
|
|
|
++ blocklen = DEVESIZE (dev);
|
|
|
+
|
|
|
+- top_of_range = ((DEVOFFSET(dev) / blocklen) +
|
|
|
+- ENVSECTORS (dev)) * blocklen;
|
|
|
++ top_of_range = ((DEVOFFSET(dev) / blocklen) +
|
|
|
++ ENVSECTORS (dev)) * blocklen;
|
|
|
+
|
|
|
+- erase_offset = (offset / blocklen) * blocklen;
|
|
|
++ erase_offset = (offset / blocklen) * blocklen;
|
|
|
+
|
|
|
+- /* Maximum area we may use */
|
|
|
+- erase_len = top_of_range - erase_offset;
|
|
|
++ /* Maximum area we may use */
|
|
|
++ erase_len = top_of_range - erase_offset;
|
|
|
+
|
|
|
+- blockstart = erase_offset;
|
|
|
+- /* Offset inside a block */
|
|
|
+- block_seek = offset - erase_offset;
|
|
|
++ blockstart = erase_offset;
|
|
|
++ /* Offset inside a block */
|
|
|
++ block_seek = offset - erase_offset;
|
|
|
+
|
|
|
+- /*
|
|
|
+- * Data size we actually have to write: from the start of the block
|
|
|
+- * to the start of the data, then count bytes of data, and to the
|
|
|
+- * end of the block
|
|
|
+- */
|
|
|
+- write_total = ((block_seek + count + blocklen - 1) /
|
|
|
+- blocklen) * blocklen;
|
|
|
++ /*
|
|
|
++ * Data size we actually write: from the start of the block
|
|
|
++ * to the start of the data, then count bytes of data, and to the
|
|
|
++ * end of the block
|
|
|
++ */
|
|
|
++ write_total = ((block_seek + count + blocklen - 1) /
|
|
|
++ blocklen) * blocklen;
|
|
|
++ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Support data anywhere within erase sectors: read out the complete
|
|
|
+@@ -834,17 +846,18 @@ static int flash_write_buf (int dev, int
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+- erase.start = blockstart;
|
|
|
+- ioctl (fd, MEMUNLOCK, &erase);
|
|
|
+- /* These do not need an explicit erase cycle */
|
|
|
+- if (mtd_type != MTD_ABSENT &&
|
|
|
+- mtd_type != MTD_DATAFLASH)
|
|
|
+- if (ioctl (fd, MEMERASE, &erase) != 0) {
|
|
|
+- fprintf (stderr, "MTD erase error on %s: %s\n",
|
|
|
+- DEVNAME (dev),
|
|
|
+- strerror (errno));
|
|
|
+- return -1;
|
|
|
+- }
|
|
|
++ if (mtd_type != MTD_ABSENT) {
|
|
|
++ erase.start = blockstart;
|
|
|
++ ioctl (fd, MEMUNLOCK, &erase);
|
|
|
++ /* These do not need an explicit erase cycle */
|
|
|
++ if (mtd_type != MTD_DATAFLASH)
|
|
|
++ if (ioctl (fd, MEMERASE, &erase) != 0) {
|
|
|
++ fprintf (stderr, "MTD erase error on %s: %s\n",
|
|
|
++ DEVNAME (dev),
|
|
|
++ strerror (errno));
|
|
|
++ return -1;
|
|
|
++ }
|
|
|
++ }
|
|
|
+
|
|
|
+ if (lseek (fd, blockstart, SEEK_SET) == -1) {
|
|
|
+ fprintf (stderr,
|
|
|
+@@ -862,8 +875,8 @@ static int flash_write_buf (int dev, int
|
|
|
+ DEVNAME (dev), strerror (errno));
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+-
|
|
|
+- ioctl (fd, MEMLOCK, &erase);
|
|
|
++ if (mtd_type != MTD_ABSENT)
|
|
|
++ ioctl (fd, MEMLOCK, &erase);
|
|
|
+
|
|
|
+ processed += blocklen;
|
|
|
+ block_seek = 0;
|