164 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From 6e2630a0fc872d0db34157972f6dc3941f6d66dd Mon Sep 17 00:00:00 2001
 | 
						|
From: Daniel Golle <daniel@makrotopia.org>
 | 
						|
Date: Mon, 19 May 2014 21:38:01 +0200
 | 
						|
Subject: [PATCH] tools/env: add support for env in ubi volume chardev
 | 
						|
 | 
						|
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
						|
---
 | 
						|
 tools/env/Makefile |  5 ++++
 | 
						|
 tools/env/fw_env.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++-------
 | 
						|
 2 files changed, 71 insertions(+), 10 deletions(-)
 | 
						|
 | 
						|
--- a/tools/env/Makefile
 | 
						|
+++ b/tools/env/Makefile
 | 
						|
@@ -24,6 +24,13 @@ ifeq ($(MTD_VERSION),old)
 | 
						|
 HOST_EXTRACFLAGS += -DMTD_OLD
 | 
						|
 endif
 | 
						|
 
 | 
						|
+ifeq ($(UBI),y)
 | 
						|
+HOST_EXTRACFLAGS += -DUBI
 | 
						|
+HOST_LOADLIBES = "-Wl,--gc-sections,-lubi-utils"
 | 
						|
+else
 | 
						|
+HOST_LOADLIBES = "-Wl,--gc-sections"
 | 
						|
+endif
 | 
						|
+
 | 
						|
 always := fw_printenv
 | 
						|
 hostprogs-y := fw_printenv
 | 
						|
 
 | 
						|
--- a/tools/env/fw_env.c
 | 
						|
+++ b/tools/env/fw_env.c
 | 
						|
@@ -31,6 +31,9 @@
 | 
						|
 # include <mtd/mtd-user.h>
 | 
						|
 #endif
 | 
						|
 
 | 
						|
+#ifdef UBI
 | 
						|
+# include <libubi.h>
 | 
						|
+#endif
 | 
						|
 #include "fw_env.h"
 | 
						|
 
 | 
						|
 #include <aes.h>
 | 
						|
@@ -811,6 +814,11 @@ static int flash_write_buf (int dev, int
 | 
						|
 	off_t top_of_range;	/* end of the last block we may use */
 | 
						|
 	loff_t blockstart;	/* running start of the current block -
 | 
						|
 				   MEMGETBADBLOCK needs 64 bits */
 | 
						|
+#ifdef UBI
 | 
						|
+	libubi_t *libubi = NULL;/* pointer to libubi struct */
 | 
						|
+#else
 | 
						|
+	void *libubi = NULL;
 | 
						|
+#endif
 | 
						|
 	int rc;
 | 
						|
 
 | 
						|
 	/*
 | 
						|
@@ -916,7 +924,30 @@ static int flash_write_buf (int dev, int
 | 
						|
 			continue;
 | 
						|
 		}
 | 
						|
 
 | 
						|
-		if (mtd_type != MTD_ABSENT) {
 | 
						|
+#ifdef UBI
 | 
						|
+		if (mtd_type == MTD_UBIVOLUME) {
 | 
						|
+			struct ubi_vol_info volinfo;
 | 
						|
+			libubi = libubi_open();
 | 
						|
+			if (libubi)
 | 
						|
+				rc = ubi_get_vol_info(libubi,
 | 
						|
+					DEVNAME(dev_current), &volinfo);
 | 
						|
+			if (libubi && !rc) {
 | 
						|
+				erasesize = volinfo.leb_size;
 | 
						|
+				int leb = blockstart / erasesize;
 | 
						|
+				if (volinfo.type != UBI_STATIC_VOLUME)
 | 
						|
+					rc = ubi_leb_change_start(libubi, fd,
 | 
						|
+						leb, erasesize);
 | 
						|
+				else
 | 
						|
+					rc = ubi_update_start(libubi, fd,
 | 
						|
+						erasesize);
 | 
						|
+			}
 | 
						|
+			if (libubi && rc) {
 | 
						|
+				libubi_close(libubi);
 | 
						|
+				libubi = NULL;
 | 
						|
+			}
 | 
						|
+		}
 | 
						|
+#endif
 | 
						|
+		if (!libubi && mtd_type != MTD_ABSENT) {
 | 
						|
 			erase.start = blockstart;
 | 
						|
 			ioctl(fd, MEMUNLOCK, &erase);
 | 
						|
 			/* These do not need an explicit erase cycle */
 | 
						|
@@ -933,7 +964,8 @@ static int flash_write_buf (int dev, int
 | 
						|
 			fprintf (stderr,
 | 
						|
 				 "Seek error on %s: %s\n",
 | 
						|
 				 DEVNAME (dev), strerror (errno));
 | 
						|
-			return -1;
 | 
						|
+			processed = -1;
 | 
						|
+			goto out;
 | 
						|
 		}
 | 
						|
 
 | 
						|
 #ifdef DEBUG
 | 
						|
@@ -943,10 +975,11 @@ static int flash_write_buf (int dev, int
 | 
						|
 		if (write (fd, data + processed, erasesize) != erasesize) {
 | 
						|
 			fprintf (stderr, "Write error on %s: %s\n",
 | 
						|
 				 DEVNAME (dev), strerror (errno));
 | 
						|
-			return -1;
 | 
						|
+			processed = -1;
 | 
						|
+			goto out;
 | 
						|
 		}
 | 
						|
 
 | 
						|
-		if (mtd_type != MTD_ABSENT)
 | 
						|
+		if (!libubi && mtd_type != MTD_ABSENT)
 | 
						|
 			ioctl(fd, MEMLOCK, &erase);
 | 
						|
 
 | 
						|
 		processed  += erasesize;
 | 
						|
@@ -957,6 +990,11 @@ static int flash_write_buf (int dev, int
 | 
						|
 	if (write_total > count)
 | 
						|
 		free (data);
 | 
						|
 
 | 
						|
+out:
 | 
						|
+#ifdef UBI
 | 
						|
+	if (libubi)
 | 
						|
+		libubi_close(libubi);
 | 
						|
+#endif
 | 
						|
 	return processed;
 | 
						|
 }
 | 
						|
 
 | 
						|
@@ -1068,12 +1106,8 @@ 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 (mtdinfo.type != MTD_NORFLASH &&
 | 
						|
+		if (!rc &&
 | 
						|
+		    mtdinfo.type != MTD_NORFLASH &&
 | 
						|
 		    mtdinfo.type != MTD_NANDFLASH &&
 | 
						|
 		    mtdinfo.type != MTD_DATAFLASH &&
 | 
						|
 		    mtdinfo.type != MTD_UBIVOLUME) {
 | 
						|
@@ -1081,6 +1115,28 @@ static int flash_read (int fd)
 | 
						|
 				 mtdinfo.type, DEVNAME(dev_current));
 | 
						|
 			return -1;
 | 
						|
 		}
 | 
						|
+#ifdef UBI
 | 
						|
+		if (rc) {
 | 
						|
+			libubi_t *libubi;
 | 
						|
+			struct ubi_vol_info volinfo;
 | 
						|
+			libubi = libubi_open();
 | 
						|
+			if (!libubi)
 | 
						|
+				return -ENOMEM;
 | 
						|
+
 | 
						|
+			rc = ubi_get_vol_info(libubi, DEVNAME(dev_current),
 | 
						|
+						&volinfo);
 | 
						|
+			if (rc) {
 | 
						|
+				libubi_close(libubi);
 | 
						|
+				return -ENODEV;
 | 
						|
+			}
 | 
						|
+			memset(&mtdinfo, 0, sizeof(mtdinfo));
 | 
						|
+			mtdinfo.type = MTD_UBIVOLUME;
 | 
						|
+			mtdinfo.size = volinfo.data_bytes;
 | 
						|
+			mtdinfo.erasesize = volinfo.leb_size;
 | 
						|
+			mtdinfo.writesize = volinfo.leb_size;
 | 
						|
+			libubi_close(libubi);
 | 
						|
+		}
 | 
						|
+#endif
 | 
						|
 	} else {
 | 
						|
 		memset(&mtdinfo, 0, sizeof(mtdinfo));
 | 
						|
 		mtdinfo.type = MTD_ABSENT;
 |