Instead of requiring gluebi to update u-boot environments from
Linux, directly support writing to an UBI device.  The
fw_env.config file will look something like this:

Device          Offset  Envsize         LEB Size        Count
/dev/ubi0_0     0       0x10000         0x1f000         1

It is important to use LEB size instead of PEB size when using
UBI.

Signed-off-by: Kevin Smith <[email protected]>
Cc: Michael Heimpold <[email protected]>
Cc: Joe Hershberger <[email protected]>
---
 tools/env/fw_env.c | 71 ++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 48 insertions(+), 23 deletions(-)

diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c
index ba11f77..af7a8ae 100644
--- a/tools/env/fw_env.c
+++ b/tools/env/fw_env.c
@@ -13,6 +13,7 @@
 #include <errno.h>
 #include <env_flags.h>
 #include <fcntl.h>
+#include <limits.h>
 #include <linux/stringify.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -29,6 +30,7 @@
 #else
 # define  __user       /* nothing */
 # include <mtd/mtd-user.h>
+# include <mtd/ubi-user.h>
 #endif
 
 #include "fw_env.h"
@@ -54,6 +56,8 @@ struct envdev_s {
        uint8_t mtd_type;               /* type of the MTD device */
 };
 
+#define UBI_TYPE                       UCHAR_MAX
+
 static struct envdev_s envdevices[2] =
 {
        {
@@ -943,7 +947,7 @@ static int flash_write_buf (int dev, int fd, void *buf, 
size_t count,
                        continue;
                }
 
-               if (mtd_type != MTD_ABSENT) {
+               if (mtd_type != MTD_ABSENT && mtd_type != UBI_TYPE) {
                        erase.start = blockstart;
                        ioctl(fd, MEMUNLOCK, &erase);
                        /* These do not need an explicit erase cycle */
@@ -956,11 +960,21 @@ static int flash_write_buf (int dev, int fd, void *buf, 
size_t count,
                                }
                }
 
-               if (lseek (fd, blockstart, SEEK_SET) == -1) {
-                       fprintf (stderr,
-                                "Seek error on %s: %s\n",
-                                DEVNAME (dev), strerror (errno));
-                       return -1;
+               if (mtd_type == UBI_TYPE) {
+                       uint64_t updatesize = erasesize;
+                       if (ioctl(fd, UBI_IOCVOLUP, &updatesize) != 0) {
+                               fprintf(stderr,
+                                       "Error updating UBI volume: %s\n",
+                                       strerror(errno));
+                               return -1;
+                       }
+               } else {
+                       if (lseek (fd, blockstart, SEEK_SET) == -1) {
+                               fprintf (stderr,
+                                        "Seek error on %s: %s\n",
+                                        DEVNAME (dev), strerror (errno));
+                               return -1;
+                       }
                }
 
 #ifdef DEBUG
@@ -973,7 +987,7 @@ static int flash_write_buf (int dev, int fd, void *buf, 
size_t count,
                        return -1;
                }
 
-               if (mtd_type != MTD_ABSENT)
+               if (mtd_type != MTD_ABSENT && mtd_type != UBI_TYPE)
                        ioctl(fd, MEMLOCK, &erase);
 
                processed  += erasesize;
@@ -1084,6 +1098,7 @@ static int flash_read (int fd)
 {
        struct mtd_info_user mtdinfo;
        struct stat st;
+       int32_t lnum;
        int rc;
 
        rc = fstat(fd, &st);
@@ -1095,28 +1110,38 @@ static int flash_read (int fd)
 
        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 (rc >= 0) {
+                       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;
+                       }
+                       DEVTYPE(dev_current) = mtdinfo.type;
+                       goto read;
                }
-               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;
+
+               /* Check for an UBI-type device */
+               lnum = 0;
+               rc = ioctl(fd, UBI_IOCEBISMAP, &lnum);
+               if (rc >= 0) {
+                       DEVTYPE(dev_current) = UBI_TYPE;
+                       goto read;
                }
+
+               fprintf(stderr, "Cannot get MTD information for %s\n",
+                       DEVNAME(dev_current));
+               return -1;
        } else {
-               memset(&mtdinfo, 0, sizeof(mtdinfo));
-               mtdinfo.type = MTD_ABSENT;
+               DEVTYPE(dev_current) = MTD_ABSENT;
        }
 
-       DEVTYPE(dev_current) = mtdinfo.type;
-
+read:
        rc = flash_read_buf(dev_current, fd, environment.image, CUR_ENVSIZE,
-                            DEVOFFSET (dev_current), mtdinfo.type);
+                            DEVOFFSET (dev_current), DEVTYPE (dev_current));
        if (rc != CUR_ENVSIZE)
                return -1;
 
-- 
2.8.0
_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to