]> git.karo-electronics.de Git - karo-tx-uboot.git/blobdiff - tools/env/fw_env.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / tools / env / fw_env.c
index 37b60b80a7624566d9ecefdd04c0658134bd654d..577ce2de4725249ba4989d02f78c57595d6f93c6 100644 (file)
@@ -5,23 +5,7 @@
  * (C) Copyright 2008
  * Guennadi Liakhovetski, DENX Software Engineering, lg@denx.de.
  *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <errno.h>
@@ -743,27 +727,39 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
                                   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 +830,18 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
                        continue;
                }
 
-               erase.start = blockstart;
-               ioctl (fd, MEMUNLOCK, &erase);
-
-               /* Dataflash does 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 (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,
@@ -863,7 +860,8 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,
                        return -1;
                }
 
-               ioctl (fd, MEMLOCK, &erase);
+               if (mtd_type != MTD_ABSENT)
+                       ioctl(fd, MEMLOCK, &erase);
 
                processed  += blocklen;
                block_seek = 0;
@@ -949,19 +947,34 @@ static int flash_write (int fd_current, int fd_target, int dev_target)
 static int flash_read (int fd)
 {
        struct mtd_info_user mtdinfo;
+       struct stat st;
        int rc;
 
-       rc = ioctl (fd, MEMGETINFO, &mtdinfo);
+       rc = fstat(fd, &st);
        if (rc < 0) {
-               perror ("Cannot get MTD information");
+               fprintf(stderr, "Cannot stat the file %s\n",
+                       DEVNAME(dev_current));
                return -1;
        }
 
-       if (mtdinfo.type != MTD_NORFLASH &&
-           mtdinfo.type != MTD_NANDFLASH &&
-           mtdinfo.type != MTD_DATAFLASH) {
-               fprintf (stderr, "Unsupported flash type %u\n", mtdinfo.type);
-               return -1;
+       if (S_ISCHR(st.st_mode)) {
+               rc = ioctl(fd, MEMGETINFO, &mtdinfo);
+               if (rc < 0) {
+                       fprintf(stderr, "Cannot get MTD information for %s\n",
+                               DEVNAME(dev_current));
+                       return -1;
+               }
+               if (mtdinfo.type != MTD_NORFLASH &&
+                   mtdinfo.type != MTD_NANDFLASH &&
+                   mtdinfo.type != MTD_DATAFLASH &&
+                   mtdinfo.type != MTD_UBIVOLUME) {
+                       fprintf (stderr, "Unsupported flash type %u on %s\n",
+                                mtdinfo.type, DEVNAME(dev_current));
+                       return -1;
+               }
+       } else {
+               memset(&mtdinfo, 0, sizeof(mtdinfo));
+               mtdinfo.type = MTD_ABSENT;
        }
 
        DEVTYPE(dev_current) = mtdinfo.type;
@@ -1134,6 +1147,12 @@ int fw_env_open(void)
                } else if (DEVTYPE(dev_current) == MTD_DATAFLASH &&
                           DEVTYPE(!dev_current) == MTD_DATAFLASH) {
                        environment.flag_scheme = FLAG_BOOLEAN;
+               } else if (DEVTYPE(dev_current) == MTD_UBIVOLUME &&
+                          DEVTYPE(!dev_current) == MTD_UBIVOLUME) {
+                       environment.flag_scheme = FLAG_INCREMENTAL;
+               } else if (DEVTYPE(dev_current) == MTD_ABSENT &&
+                          DEVTYPE(!dev_current) == MTD_ABSENT) {
+                       environment.flag_scheme = FLAG_INCREMENTAL;
                } else {
                        fprintf (stderr, "Incompatible flash types!\n");
                        return -1;