]> www.infradead.org Git - mtd-utils.git/commitdiff
ubi-utils: add ubiattach and ubidetach
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Wed, 26 Dec 2007 13:12:26 +0000 (15:12 +0200)
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Wed, 26 Dec 2007 14:23:04 +0000 (16:23 +0200)
Add 2 new utilities to attach and detach UBI devices.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
16 files changed:
include/mtd/ubi-user.h
tests/ubi-tests/Makefile
tests/ubi-tests/rmvol.c [deleted file]
tests/ubi-tests/runtests.sh
tests/ubi-tests/volrefcnt.c [new file with mode: 0644]
ubi-utils/Makefile
ubi-utils/inc/libubi.h
ubi-utils/src/libubi.c
ubi-utils/src/libubi_int.h
ubi-utils/src/ubiattach.c [new file with mode: 0644]
ubi-utils/src/ubicrc32.c
ubi-utils/src/ubidetach.c [new file with mode: 0644]
ubi-utils/src/ubimkvol.c
ubi-utils/src/ubinfo.c
ubi-utils/src/ubirmvol.c
ubi-utils/src/ubiupdate.c

index bb0aca6e750e3850a81d0a86b8f39ce327748328..4d184a7f80a847bc4c0ba49069198897662b2dd0 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
- * Author: Artem B. Bityutskiy
+ * Author: Artem Bityutskiy (Битюцкий Артём)
  */
 
 #ifndef __UBI_USER_H__
 #define __UBI_USER_H__
 
 /*
+ * UBI device creation (the same as MTD device attachment)
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * MTD devices may be attached using %UBI_IOCATT ioctl command of the UBI
+ * control device. The caller has to properly fill and pass
+ * &struct ubi_attach_req object - UBI will attach the MTD device specified in
+ * the request and return the newly created UBI device number as the ioctl
+ * return value.
+ *
+ * UBI device deletion (the same as MTD device detachment)
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * An UBI device maybe deleted with %UBI_IOCDET ioctl command of the UBI
+ * control device.
+ *
  * UBI volume creation
  * ~~~~~~~~~~~~~~~~~~~
  *
  */
 
 /*
- * When a new volume is created, users may either specify the volume number they
- * want to create or to let UBI automatically assign a volume number using this
- * constant.
+ * When a new UBI volume or UBI device is created, users may either specify the
+ * volume/device number they want to create or to let UBI automatically assign
+ * the number using these constants.
  */
 #define UBI_VOL_NUM_AUTO (-1)
+#define UBI_DEV_NUM_AUTO (-1)
 
 /* Maximum volume name length */
 #define UBI_MAX_VOLUME_NAME 127
 /* Re-size an UBI volume */
 #define UBI_IOCRSVOL _IOW(UBI_IOC_MAGIC, 2, struct ubi_rsvol_req)
 
+/* IOCTL commands of the UBI control character device */
+
+#define UBI_CTRL_IOC_MAGIC 'o'
+
+/* Attach an MTD device */
+#define UBI_IOCATT _IOW(UBI_CTRL_IOC_MAGIC, 64, struct ubi_attach_req)
+/* Detach an MTD device */
+#define UBI_IOCDET _IOW(UBI_CTRL_IOC_MAGIC, 65, int32_t)
+
 /* IOCTL commands of UBI volume character devices */
 
 #define UBI_VOL_IOC_MAGIC 'O'
 /* An eraseblock erasure command, used for debugging, disabled by default */
 #define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 1, int32_t)
 
+/* Maximum MTD device name length supported by UBI */
+#define MAX_UBI_MTD_NAME_LEN 127
+
 /*
  * UBI volume type constants.
  *
  */
 enum {
        UBI_DYNAMIC_VOLUME = 3,
-       UBI_STATIC_VOLUME = 4
+       UBI_STATIC_VOLUME = 4,
+};
+
+/**
+ * struct ubi_attach_req - attach MTD device request.
+ * @ubi_num: UBI device number to create
+ * @mtd_num: MTD device number to attach
+ * @vid_hdr_offset: VID header offset (use defaults if %0)
+ * @padding: reserved for future, not used, has to be zeroed
+ *
+ * This data structure is used to specify MTD device UBI has to attach and the
+ * parameters it has to use. The number which should be assigned to the new UBI
+ * device is passed in @ubi_num. UBI may automatically assing the number if
+ * @UBI_DEV_NUM_AUTO is passed. In this case, the device number is returned in
+ * @ubi_num.
+ *
+ * Most applications should pass %0 in @vid_hdr_offset to make UBI use default
+ * offset of the VID header within physical eraseblocks. The default offset is
+ * the next min. I/O unit after the EC header. For example, it will be offset
+ * 512 in case of a 512 bytes page NAND flash with no sub-page support. Or
+ * it will be 512 in case of a 2KiB page NAND flash with 4 512-byte sub-pages.
+ *
+ * But in rare cases, if this optimizes things, the VID header may be placed to
+ * a different offset. For example, the boot-loader might do things faster if the
+ * VID header sits at the end of the first 2KiB NAND page with 4 sub-pages. As
+ * the boot-loader would not normally need to read EC headers (unless it needs
+ * UBI in RW mode), it might be faster to calculate ECC. This is weird example,
+ * but it real-life example. So, in this example, @vid_hdr_offer would be
+ * 2KiB-64 bytes = 1984. Note, that this position is not even 512-bytes
+ * aligned, which is OK, as UBI is clever enough to realize this is 4th sub-page
+ * of the first page and add needed padding.
+ */
+struct ubi_attach_req {
+       int32_t ubi_num;
+       int32_t mtd_num;
+       int32_t vid_hdr_offset;
+       uint8_t padding[12];
 };
 
 /**
  * struct ubi_mkvol_req - volume description data structure used in
- * volume creation requests.
+ *                        volume creation requests.
  * @vol_id: volume number
  * @alignment: volume alignment
  * @bytes: volume size in bytes
  * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
- * @padding1: reserved for future, not used
+ * @padding1: reserved for future, not used, has to be zeroed
  * @name_len: volume name length
- * @padding2: reserved for future, not used
+ * @padding2: reserved for future, not used, has to be zeroed
  * @name: volume name
  *
  * This structure is used by userspace programs when creating new volumes. The
@@ -139,7 +203,7 @@ struct ubi_mkvol_req {
        int8_t padding1;
        int16_t name_len;
        int8_t padding2[4];
-       char name[UBI_MAX_VOLUME_NAME+1];
+       char name[UBI_MAX_VOLUME_NAME + 1];
 } __attribute__ ((packed));
 
 /**
index a15d93cdb1337c6fbc6c408794d0cc6807cfba6d..157aa552898c0b976eb2a288593b210250dd4816 100644 (file)
@@ -5,7 +5,7 @@ UBIUTILS_PATH=../../ubi-utils/
 
 CC := $(CROSS)gcc
 
-TESTS=io_update rmvol integ io_paral io_read io_basic \
+TESTS=io_update volrefcnt integ io_paral io_read io_basic \
           mkvol_basic mkvol_bad mkvol_paral rsvol
 
 HELPER_NAMES=ubiupdatevol
@@ -15,13 +15,13 @@ HELPERS=$(addprefix helpers/, $(HELPER_NAMES))
 # it removes the. If you want to prevent the removal, uncomment the below
 #.SECONDARY: $(addsuffix .o, $(TESTS)) $(addsuffix .o, $(HELPERS))
 
-CFLAGS += -Wall -I$(LIBUBI_HEADER_PATH) -L $(LIBUBI_PATH) -O0 -ggdb
+CFLAGS += -Wall -I$(LIBUBI_HEADER_PATH) -L. -O2
 
 all: ubi-utils libubi $(TESTS) $(HELPERS)
 
 # Compile ubilib with the udevsettle hack
 libubi: $(LIBUBI_SRC_PATH)/libubi.c  $(LIBUBI_HEADER_PATH)/libubi.h  $(LIBUBI_SRC_PATH)/libubi_int.h
-       $(CC) $(CFLAGS) -I $(LIBUBI_SRC_PATH) -DUDEV_SETTLE_HACK -c $(LIBUBI_SRC_PATH)/libubi.c -o libubi.o
+       $(CC) $(CFLAGS) -I $(LIBUBI_SRC_PATH) -I../../include -DUDEV_SETTLE_HACK -c $(LIBUBI_SRC_PATH)/libubi.c -o libubi.o
        ar cr libubi.a libubi.o
 
 # The below cancels existing implicite rule to make programs from .c files,
diff --git a/tests/ubi-tests/rmvol.c b/tests/ubi-tests/rmvol.c
deleted file mode 100644 (file)
index 6c52319..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (c) Nokia Corporation, 2007
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Author: Artem B. Bityutskiy
- *
- * Test volume reference counting - create a volume, open a sysfs file
- * belonging to the volume, delete the volume but do not close the file, make
- * sure the file cannot be read, make sure the volume cannot be open, close the
- * file, make sure the volume disappeard, make sure its sysfs subtree
- * disappeared.
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "libubi.h"
-#define TESTNAME "rmvol"
-#include "common.h"
-
-#define SYSFS_FILE "/sys/class/ubi/ubi%d_%d/usable_leb_size"
-
-int main(int argc, char * const argv[])
-{
-       int ret, fd;
-       char fname[sizeof(SYSFS_FILE) + 20];
-       const char *node;
-       libubi_t libubi;
-       struct ubi_dev_info dev_info;
-       struct ubi_mkvol_request req;
-       char tmp[100];
-
-       if (initial_check(argc, argv))
-               return 1;
-
-       node = argv[1];
-
-       libubi = libubi_open();
-       if (libubi == NULL) {
-               failed("libubi_open");
-               return 1;
-       }
-
-       if (ubi_get_dev_info(libubi, node, &dev_info)) {
-               failed("ubi_get_dev_info");
-               goto out_libubi;
-       }
-
-       /* Create a small dynamic volume */
-       req.vol_id = UBI_VOL_NUM_AUTO;
-       req.alignment = dev_info.min_io_size;
-       req.bytes = dev_info.leb_size;
-       req.vol_type = UBI_DYNAMIC_VOLUME;
-       req.name = "rmvol";
-
-       if (ubi_mkvol(libubi, node, &req)) {
-               failed("ubi_mkvol");
-               perror("ubi_mkvol");
-               goto out_libubi;
-       }
-
-       /* Open volume-related sysfs file */
-       sprintf(fname, SYSFS_FILE, dev_info.dev_num, req.vol_id);
-       fd = open(fname, O_RDONLY);
-       if (fd == -1) {
-               failed("open");
-               perror("open");
-               goto out_rmvol;
-       }
-
-       /* Remove the volume, but do not close the file */
-       if (ubi_rmvol(libubi, node, req.vol_id)) {
-               failed("ubi_rmvol");
-               perror("ubi_rmvol");
-               goto out_close;
-       }
-
-       /* Try to read from the file, this should fail */
-       ret = read(fd, tmp, 100);
-       if (ret != -1) {
-               failed("read");
-               err_msg("read returned %d, expected -1", ret);
-               goto out_close;
-       }
-
-       /* Close the file and try to open it again, should fail */
-       close(fd);
-       fd = open(fname, O_RDONLY);
-       if (fd != -1) {
-               failed("open");
-               err_msg("opened %s again, open returned %d, expected -1",
-                       fname, fd);
-               goto out_libubi;
-       }
-
-       libubi_close(libubi);
-       return 0;
-
-out_rmvol:
-       ubi_rmvol(libubi, node, req.vol_id);
-out_libubi:
-       libubi_close(libubi);
-       return 1;
-
-out_close:
-       close(fd);
-       libubi_close(libubi);
-       return 1;
-}
-
-#if 0
-/**
- * mkvol_alignment - create volumes with different alignments.
- *
- * Thus function returns %0 in case of success and %-1 in case of failure.
- */
-static int mkvol_alignment(void)
-{
-       struct ubi_mkvol_request req;
-       int i, vol_id, ebsz;
-       const char *name = TESTNAME ":mkvol_alignment()";
-       int alignments[] = ALIGNMENTS(dev_info.leb_size);
-
-       for (i = 0; i < sizeof(alignments)/sizeof(int); i++) {
-               req.vol_id = UBI_VOL_NUM_AUTO;
-
-               /* Alignment should actually be multiple of min. I/O size */
-               req.alignment = alignments[i];
-               req.alignment -= req.alignment % dev_info.min_io_size;
-               if (req.alignment == 0)
-                       req.alignment = dev_info.min_io_size;
-
-               /* Bear in mind alignment reduces EB size */
-               ebsz = dev_info.leb_size - dev_info.leb_size % req.alignment;
-               req.bytes = dev_info.avail_lebs * ebsz;
-
-               req.vol_type = UBI_DYNAMIC_VOLUME;
-               req.name = name;
-
-               if (ubi_mkvol(libubi, node, &req)) {
-                       failed("ubi_mkvol");
-                       err_msg("alignment %d", req.alignment);
-                       return -1;
-               }
-
-               vol_id = req.vol_id;
-               if (check_volume(vol_id, &req))
-                       goto remove;
-
-               if (ubi_rmvol(libubi, node, vol_id)) {
-                       failed("ubi_rmvol");
-                       return -1;
-               }
-       }
-
-       return 0;
-
-remove:
-       ubi_rmvol(libubi, node, vol_id);
-       return -1;
-}
-
-/**
- * mkvol_basic - simple test that checks basic volume creation capability.
- *
- * Thus function returns %0 in case of success and %-1 in case of failure.
- */
-static int mkvol_basic(void)
-{
-       struct ubi_mkvol_request req;
-       struct ubi_vol_info vol_info;
-       int vol_id, ret;
-       const char *name = TESTNAME ":mkvol_basic()";
-
-       /* Create dynamic volume of maximum size */
-       req.vol_id = UBI_VOL_NUM_AUTO;
-       req.alignment = 1;
-       req.bytes = dev_info.avail_bytes;
-       req.vol_type = UBI_DYNAMIC_VOLUME;
-       req.name = name;
-
-       if (ubi_mkvol(libubi, node, &req)) {
-               failed("ubi_mkvol");
-               return -1;
-       }
-
-       vol_id = req.vol_id;
-       if (check_volume(vol_id, &req))
-               goto remove;
-
-       if (ubi_rmvol(libubi, node, vol_id)) {
-               failed("ubi_rmvol");
-               return -1;
-       }
-
-       /* Create static volume of maximum size */
-       req.vol_id = UBI_VOL_NUM_AUTO;
-       req.alignment = 1;
-       req.bytes = dev_info.avail_bytes;
-       req.vol_type = UBI_STATIC_VOLUME;
-       req.name = name;
-
-       if (ubi_mkvol(libubi, node, &req)) {
-               failed("ubi_mkvol");
-               return -1;
-       }
-
-       vol_id = req.vol_id;
-       if (check_volume(vol_id, &req))
-               goto remove;
-
-       if (ubi_rmvol(libubi, node, vol_id)) {
-               failed("ubi_rmvol");
-               return -1;
-       }
-
-       /* Make sure volume does not exist */
-       ret = ubi_get_vol_info1(libubi, dev_info.dev_num, vol_id, &vol_info);
-       if (ret == 0) {
-               err_msg("removed volume %d exists", vol_id);
-               goto remove;
-       }
-
-       return 0;
-
-remove:
-       ubi_rmvol(libubi, node, vol_id);
-       return -1;
-}
-
-/**
- * mkvol_multiple - test multiple volumes creation
- *
- * Thus function returns %0 if the test passed and %-1 if not.
- */
-static int mkvol_multiple(void)
-{
-       struct ubi_mkvol_request req;
-       int i, ret, max = dev_info.max_vol_count;
-       const char *name = TESTNAME ":mkvol_multiple()";
-
-       /* Create maximum number of volumes */
-       for (i = 0; i < max; i++) {
-               char nm[strlen(name) + 50];
-
-               req.vol_id = UBI_VOL_NUM_AUTO;
-               req.alignment = 1;
-               req.bytes = 1;
-               req.vol_type = UBI_STATIC_VOLUME;
-
-               sprintf(&nm[0], "%s:%d", name, i);
-               req.name = &nm[0];
-
-               if (ubi_mkvol(libubi, node, &req)) {
-                       if (errno == ENFILE) {
-                               max = i;
-                               break;
-                       }
-                       failed("ubi_mkvol");
-                       err_msg("vol_id %d", i);
-                       goto remove;
-               }
-
-               if (check_volume(req.vol_id, &req)) {
-                       err_msg("vol_id %d", i);
-                       goto remove;
-               }
-       }
-
-       for (i = 0; i < max; i++) {
-               struct ubi_vol_info vol_info;
-
-               if (ubi_rmvol(libubi, node, i)) {
-                       failed("ubi_rmvol");
-                       return -1;
-               }
-
-               /* Make sure volume does not exist */
-               ret = ubi_get_vol_info1(libubi, dev_info.dev_num, i, &vol_info);
-               if (ret == 0) {
-                       err_msg("removed volume %d exists", i);
-                       goto remove;
-               }
-       }
-
-       return 0;
-
-remove:
-       for (i = 0; i < dev_info.max_vol_count + 1; i++)
-               ubi_rmvol(libubi, node, i);
-       return -1;
-}
-#endif
index 7072e03eed94eaf89d950df960fb37ce5caabe44..fa10c3e2b041039529775d5eaa8b887fe6d91984 100755 (executable)
@@ -2,7 +2,7 @@
 
 ubidev="$1"
 tests="mkvol_basic mkvol_bad mkvol_paral rsvol io_basic io_read io_update
-io_paral rmvol"
+io_paral volrefcnt"
 
 if test -z "$ubidev";
 then
diff --git a/tests/ubi-tests/volrefcnt.c b/tests/ubi-tests/volrefcnt.c
new file mode 100644 (file)
index 0000000..a56deae
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) Nokia Corporation, 2007
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Artem B. Bityutskiy
+ *
+ * Test volume reference counting - create a volume, open a sysfs file
+ * belonging to the volume, delete the volume but do not close the file, make
+ * sure the file cannot be read, close the file, make sure the volume
+ * disappeard, make sure its sysfs subtree disappeared.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "libubi.h"
+#define TESTNAME "rmvol"
+#include "common.h"
+
+#define SYSFS_FILE "/sys/class/ubi/ubi%d_%d/usable_eb_size"
+
+int main(int argc, char * const argv[])
+{
+       int ret, fd;
+       char fname[sizeof(SYSFS_FILE) + 20];
+       const char *node;
+       libubi_t libubi;
+       struct ubi_dev_info dev_info;
+       struct ubi_mkvol_request req;
+       char tmp[100];
+
+       if (initial_check(argc, argv))
+               return 1;
+
+       node = argv[1];
+
+       libubi = libubi_open();
+       if (libubi == NULL) {
+               failed("libubi_open");
+               return 1;
+       }
+
+       if (ubi_get_dev_info(libubi, node, &dev_info)) {
+               failed("ubi_get_dev_info");
+               goto out_libubi;
+       }
+
+       /* Create a small dynamic volume */
+       req.vol_id = UBI_VOL_NUM_AUTO;
+       req.alignment = dev_info.min_io_size;
+       req.bytes = dev_info.leb_size;
+       req.vol_type = UBI_DYNAMIC_VOLUME;
+       req.name = "rmvol";
+
+       if (ubi_mkvol(libubi, node, &req)) {
+               failed("ubi_mkvol");
+               goto out_libubi;
+       }
+
+       /* Open volume-related sysfs file */
+       sprintf(fname, SYSFS_FILE, dev_info.dev_num, req.vol_id);
+       fd = open(fname, O_RDONLY);
+       if (fd == -1) {
+               err_msg("cannot open %s", fname);
+               failed("open");
+               goto out_rmvol;
+       }
+
+       /* Remove the volume, but do not close the file */
+       if (ubi_rmvol(libubi, node, req.vol_id)) {
+               failed("ubi_rmvol");
+               perror("ubi_rmvol");
+               goto out_close;
+       }
+
+       /* Try to read from the file, this should fail */
+       ret = read(fd, tmp, 100);
+       if (ret != -1) {
+               err_msg("read returned %d, expected -1", ret);
+               failed("read");
+               goto out_close;
+       }
+
+       /* Close the file and try to open it again, should fail */
+       close(fd);
+       fd = open(fname, O_RDONLY);
+       if (fd != -1) {
+               err_msg("opened %s again, open returned %d, expected -1",
+                       fname, fd);
+               failed("open");
+               goto out_libubi;
+       }
+
+       libubi_close(libubi);
+       return 0;
+
+out_rmvol:
+       ubi_rmvol(libubi, node, req.vol_id);
+out_libubi:
+       libubi_close(libubi);
+       return 1;
+
+out_close:
+       close(fd);
+       libubi_close(libubi);
+       return 1;
+}
index abd5dc4e9db1be5a92ee21032c0784f949c0d0b2..9fd862d69b80b559a4047f38bb8efea86263d880 100644 (file)
@@ -15,7 +15,8 @@ CFLAGS := -I./inc -I./src -I$(KERNELHDR) $(OPTFLAGS) -Werror \
 
 PERLPROGS = mkpfi ubicrc32.pl
 TARGETS = ubiupdate ubimkvol ubirmvol pfiflash pddcustomize ubimirror \
-       bin2nand nand2bin ubigen mkbootenv unubi pfi2bin ubicrc32 ubinfo
+       bin2nand nand2bin ubigen mkbootenv unubi pfi2bin ubicrc32 ubinfo \
+       ubiattach ubidetach
 
 vpath   %.c ./src
 
@@ -31,11 +32,17 @@ IGNORE=${wildcard .*.c.dep}
 -include ${IGNORE}
 
 clean:
-       rm -rf *.o $(TARGETS) .*.c.dep
+       rm -rf *.o $(TARGETS) .*.c.dep libubi.a
 
 libubi: libubi.o
        ar cr libubi.a libubi.o
 
+ubidetach: ubidetach.o common.o libubi.o
+       $(CC) $(LDFLAGS) -o $@ $^
+
+ubiattach: ubiattach.o common.o libubi.o
+       $(CC) $(LDFLAGS) -o $@ $^
+
 ubinfo: ubinfo.o common.o libubi.o
        $(CC) $(LDFLAGS) -o $@ $^
 
index b83f6c6f6e59686ef59b91fc3e0815c9d0f4e850..0cdb67c06eaf70a4bb6b6a27855bb1fdae2dba38 100644 (file)
@@ -38,6 +38,22 @@ extern "C" {
 /* UBI library descriptor */
 typedef void * libubi_t;
 
+/**
+ * struct ubi_attach_request - MTD device attachement request.
+ * @dev_num: number to assigne to the newly created UBI device
+ *           (%UBI_DEV_NUM_AUTO should be used to automatically assign the
+ *           number)
+ * @mtd_num: MTD device number to attach
+ * @vid_hdr_offset: VID header offset (%0 means default offset and this is what
+ *                  most of the users want)
+ */
+struct ubi_attach_request
+{
+       int dev_num;
+       int mtd_num;
+       int vid_hdr_offset;
+};
+
 /**
  * struct ubi_mkvol_request - volume creation request.
  * @vol_id: ID to assign to the new volume (%UBI_VOL_NUM_AUTO should be used to
@@ -167,14 +183,50 @@ void libubi_close(libubi_t desc);
 
 /**
  * ubi_get_info - get general UBI information.
- * @info: pointer to the &struct ubi_info object to fill
  * @desc: UBI library descriptor
+ * @info: pointer to the &struct ubi_info object to fill
  *
  * This function fills the passed @info object with general UBI information and
  * returns %0 in case of success and %-1 in case of failure.
  */
 int ubi_get_info(libubi_t desc, struct ubi_info *info);
 
+/**
+ * ubi_attach_mtd - attach MTD device to UBI.
+ * @desc: UBI library descriptor
+ * @node: name of the UBI control character device node
+ * @req: MTD attach request.
+ *
+ * This function creates a new UBI device by attaching an MTD device as
+ * described by @req. Returns %0 in case of success and %-1 in case of failure.
+ * The newly created UBI device number is returned in @req->dev_num.
+ */
+int ubi_attach_mtd(libubi_t desc, const char *node,
+                  struct ubi_attach_request *req);
+
+/**
+ * ubi_detach_mtd - detach an MTD device.
+ * @desc: UBI library descriptor
+ * @node: name of the UBI control character device node
+ * @mtd_num: MTD device number to detach
+ *
+ * This function detaches MTD device number @mtd_num from UBI, which means the
+ * corresponding UBI device is removed. Returns zero in case of success and %-1
+ * in case of failure.
+ */
+int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num);
+
+/**
+ * ubi_remove_dev - remove an UBI device.
+ * @desc: UBI library descriptor
+ * @node: name of the UBI control character device node
+ * @ubi_dev: UBI device number to remove
+ *
+ * This function removes UBI device number @ubi_dev and returns zero in case of
+ * success and %-1 in case of failure.
+ */
+int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev);
+
 /**
  * ubi_mkvol - create an UBI volume.
  * @desc: UBI library descriptor
index 32d988ee45904aca77c464beb73018da7fdfa2fc..855aa82d8c2f3b569e488d8a89451f197258cfd9 100644 (file)
@@ -434,7 +434,7 @@ static int vol_node2nums(struct libubi *lib, const char *node, int *dev_num,
        }
 
        if (i > info.highest_dev_num) {
-               errno = ENOENT;
+               errno = ENODEV;
                return -1;
        }
 
@@ -442,12 +442,13 @@ static int vol_node2nums(struct libubi *lib, const char *node, int *dev_num,
        sprintf(file, lib->ubi_vol, i, minor - 1);
        fd = open(file, O_RDONLY);
        if (fd == -1) {
-               errno = ENOENT;
+               errno = ENODEV;
                return -1;
        }
 
        *dev_num = i;
        *vol_id = minor - 1;
+       errno = 0;
        return 0;
 }
 
@@ -503,12 +504,40 @@ static int dev_node2num(struct libubi *lib, const char *node, int *dev_num)
                                errno = EINVAL;
                                return -1;
                        }
+                       errno = 0;
                        *dev_num = i;
                        return 0;
                }
        }
 
-       errno = ENOENT;
+       errno = ENODEV;
+       return -1;
+}
+
+static int mtd_num2ubi_dev(struct libubi *lib, int mtd_num, int *dev_num)
+{
+       struct ubi_info info;
+       int i, ret, mtd_num1;
+
+       if (ubi_get_info((libubi_t *)lib, &info))
+               return -1;
+
+       for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) {
+               ret = dev_read_int(lib->dev_mtd_num, i, &mtd_num1);
+               if (ret) {
+                       if (errno == ENOENT)
+                               continue;
+                       return -1;
+               }
+
+               if (mtd_num1 == mtd_num) {
+                       errno = 0;
+                       *dev_num = i;
+                       return 0;
+               }
+       }
+
+       errno = ENODEV;
        return -1;
 }
 
@@ -596,6 +625,10 @@ libubi_t libubi_open(void)
        if (!lib->dev_min_io_size)
                goto out_error;
 
+       lib->dev_mtd_num = mkpath(lib->ubi_dev, DEV_MTD_NUM);
+       if (!lib->dev_mtd_num)
+               goto out_error;
+
        lib->ubi_vol = mkpath(lib->sysfs_ubi, UBI_VOL_NAME_PATT);
        if (!lib->ubi_vol)
                goto out_error;
@@ -661,6 +694,7 @@ void libubi_close(libubi_t desc)
        free(lib->vol_dev);
        free(lib->vol_type);
        free(lib->ubi_vol);
+       free(lib->dev_mtd_num);
        free(lib->dev_min_io_size);
        free(lib->dev_max_vols);
        free(lib->dev_bad_rsvd);
@@ -679,6 +713,74 @@ void libubi_close(libubi_t desc)
        free(lib);
 }
 
+int ubi_attach_mtd(libubi_t desc, const char *node,
+                  struct ubi_attach_request *req)
+{
+       int fd, ret;
+       struct ubi_attach_req r;
+
+       memset(&r, sizeof(struct ubi_attach_req), '\0');
+
+       desc = desc;
+       r.ubi_num = req->dev_num;
+       r.mtd_num = req->mtd_num;
+       r.vid_hdr_offset = req->vid_hdr_offset;
+
+       fd = open(node, O_RDONLY);
+       if (fd == -1)
+               return -1;
+
+       ret = ioctl(fd, UBI_IOCATT, &r);
+       close(fd);
+       if (ret == -1)
+               return -1;
+
+       req->dev_num = r.ubi_num;
+
+#ifdef UDEV_SETTLE_HACK
+       if (system("udevsettle") == -1)
+               return -1;
+       if (system("udevsettle") == -1)
+               return -1;
+#endif
+
+       return ret;
+}
+
+int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num)
+{
+       int ret, ubi_dev;
+
+       ret = mtd_num2ubi_dev(desc, mtd_num, &ubi_dev);
+       if (ret == -1)
+               return ret;
+
+       return ubi_remove_dev(desc, node, ubi_dev);
+}
+
+int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev)
+{
+       int fd, ret;
+
+       desc = desc;
+
+       fd = open(node, O_RDONLY);
+       if (fd == -1)
+               return -1;
+       ret = ioctl(fd, UBI_IOCDET, &ubi_dev);
+       if (ret == -1)
+               goto out_close;
+
+#ifdef UDEV_SETTLE_HACK
+       if (system("udevsettle") == -1)
+               return -1;
+#endif
+
+out_close:
+       close(fd);
+       return ret;
+}
+
 int ubi_node_type(libubi_t desc, const char *node)
 {
        struct stat st;
@@ -842,16 +944,18 @@ int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req)
                return -1;
 
        ret = ioctl(fd, UBI_IOCMKVOL, &r);
-       if (ret == 0)
-               req->vol_id = r.vol_id;
+       if (ret == -1)
+               goto out_close;
 
-       close(fd);
+       req->vol_id = r.vol_id;
 
 #ifdef UDEV_SETTLE_HACK
        if (system("udevsettle") == -1)
                return -1;
 #endif
 
+out_close:
+       close(fd);
        return ret;
 }
 
@@ -865,13 +969,16 @@ int ubi_rmvol(libubi_t desc, const char *node, int vol_id)
                return -1;
 
        ret = ioctl(fd, UBI_IOCRMVOL, &vol_id);
-       close(fd);
+       if (ret == -1)
+               goto out_close;
 
 #ifdef UDEV_SETTLE_HACK
        if (system("udevsettle") == -1)
                return -1;
 #endif
 
+out_close:
+       close(fd);
        return ret;
 }
 
@@ -880,7 +987,7 @@ int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes)
        int fd, ret;
        struct ubi_rsvol_req req;
 
-               desc = desc;
+       desc = desc;
        fd = open(node, O_RDONLY);
        if (fd == -1)
                return -1;
index 4c26eb5cb70be6a5b6ff8a8b6f6c8e0820a2ecfd..649086443ca094bc0c24648f1878ee57fd3ccd7d 100644 (file)
@@ -58,6 +58,7 @@ extern "C" {
 #define DEV_MAX_RSVD      "reserved_for_bad"
 #define DEV_MAX_VOLS      "max_vol_count"
 #define DEV_MIN_IO_SIZE   "min_io_size"
+#define DEV_MTD_NUM       "mtd_num"
 
 #define UBI_VOL_NAME_PATT "ubi%d_%d"
 #define VOL_TYPE          "type"
@@ -114,6 +115,7 @@ struct libubi
        char *dev_bad_rsvd;
        char *dev_max_vols;
        char *dev_min_io_size;
+       char *dev_mtd_num;
        char *ubi_vol;
        char *vol_type;
        char *vol_dev;
diff --git a/ubi-utils/src/ubiattach.c b/ubi-utils/src/ubiattach.c
new file mode 100644 (file)
index 0000000..3476a3d
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * An utility to attach MTD devices to UBI.
+ *
+ * Author: Artem Bityutskiy
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <libubi.h>
+#include "common.h"
+
+#define PROGRAM_VERSION "1.0"
+#define PROGRAM_NAME    "ubiattach"
+
+/* The variables below are set by command line arguments */
+struct args {
+       int devn;
+       int mtdn;
+       int vidoffs;
+       const char *node;
+};
+
+static struct args myargs = {
+       .devn = UBI_DEV_NUM_AUTO,
+       .mtdn = -1,
+       .vidoffs = 0,
+       .node = NULL,
+};
+
+static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION
+                        " - a tool to attach MTD device to UBI.";
+
+static const char *optionsstr =
+"-d, --devn=<UBI device number>  the number to assign to the newly created UBI device\n"
+"                                (the number is assigned automatically if this is not\n"
+"                                specified\n"
+"-m, --mtdn=<MTD device number>  MTD device number to attach\n"
+"-o, --vid-hdr-offset            VID header offset (do not specify this unless you\n"
+"                                really know what you do and the optimal defaults wukk\n"
+"                                be used)\n"
+"-h, --help                      print help message\n"
+"-V, --version                   print program version";
+
+static const char *usage =
+"Usage: " PROGRAM_NAME "<UBI control device node file name> [-m <MTD device number>] [-d <UBI device number>]\n"
+"\t\t[--mtdn=<MTD device number>] [--devn <UBI device number>]\n"
+"Example 1: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 - attach MTD device 0 (mtd0) to UBI\n"
+"Example 2: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 -d 3 - attach MTD device 0 (mtd0) to UBI and\n"
+"           and create UBI device number 3 (ubi3)";
+
+static const struct option long_options[] = {
+       { .name = "devn",           .has_arg = 1, .flag = NULL, .val = 'd' },
+       { .name = "mtdn",           .has_arg = 1, .flag = NULL, .val = 'm' },
+       { .name = "vid-hdr-offset", .has_arg = 1, .flag = NULL, .val = 'o' },
+       { .name = "help",           .has_arg = 0, .flag = NULL, .val = 'h' },
+       { .name = "version",        .has_arg = 0, .flag = NULL, .val = 'V' },
+       { NULL, 0, NULL, 0},
+};
+
+static int parse_opt(int argc, char * const argv[])
+{
+       while (1) {
+               int key;
+               char *endp;
+
+               key = getopt_long(argc, argv, "m:d:ohV", long_options, NULL);
+               if (key == -1)
+                       break;
+
+               switch (key) {
+               case 'd':
+                       myargs.devn = strtoul(optarg, &endp, 0);
+                       if (*endp != '\0' || endp == optarg || myargs.devn < 0) {
+                               errmsg("bad UBI device number: \"%s\"", optarg);
+                               return -1;
+                       }
+
+                       break;
+
+               case 'm':
+                       myargs.mtdn = strtoul(optarg, &endp, 0);
+                       if (*endp != '\0' || endp == optarg || myargs.mtdn < 0) {
+                               errmsg("bad MTD device number: \"%s\"", optarg);
+                               return -1;
+                       }
+
+                       break;
+
+               case 'o':
+                       myargs.vidoffs = strtoul(optarg, &endp, 0);
+                       if (*endp != '\0' || endp == optarg || myargs.vidoffs <= 0) {
+                               errmsg("bad VID header offset: \"%s\"", optarg);
+                               return -1;
+                       }
+
+                       break;
+
+               case 'h':
+                       fprintf(stderr, "%s\n\n", doc);
+                       fprintf(stderr, "%s\n\n", usage);
+                       fprintf(stderr, "%s\n", optionsstr);
+                       exit(0);
+
+               case 'V':
+                       fprintf(stderr, "%s\n", PROGRAM_VERSION);
+                       exit(0);
+
+               case ':':
+                       errmsg("parameter is missing");
+                       return -1;
+
+               default:
+                       fprintf(stderr, "Use -h for help\n");
+                       exit(-1);
+               }
+       }
+
+       if (optind == argc) {
+               errmsg("UBI control device name was not specified (use -h for help)");
+               return -1;
+       } else if (optind != argc - 1) {
+               errmsg("more then one UBI control device specified (use -h for help)");
+               return -1;
+       }
+
+       if (myargs.mtdn == -1) {
+               errmsg("MTD device number was not specified (use -h for help)");
+               return -1;
+       }
+
+       myargs.node = argv[optind];
+       return 0;
+}
+
+int main(int argc, char * const argv[])
+{
+       int err;
+       libubi_t libubi;
+       struct ubi_info ubi_info;
+       struct ubi_dev_info dev_info;
+       struct ubi_attach_request req;
+
+       err = parse_opt(argc, argv);
+       if (err)
+               return -1;
+
+       libubi = libubi_open();
+       if (libubi == NULL) {
+               errmsg("cannot open libubi");
+               perror("libubi_open");
+               return -1;
+       }
+
+       /*
+        * Make sure the kernel is fresh enough and this feature is supported.
+        */
+       err = ubi_get_info(libubi, &ubi_info);
+       if (err) {
+               errmsg("cannot get UBI information");
+               perror("ubi_get_info");
+               goto out_libubi;
+       }
+
+       if (ubi_info.ctrl_major == -1) {
+               errmsg("MTD attach/detach feature is not supported by your kernel");
+               goto out_libubi;
+       }
+
+       req.dev_num = myargs.devn;
+       req.mtd_num = myargs.mtdn;
+       req.vid_hdr_offset = myargs.vidoffs;
+
+       err = ubi_attach_mtd(libubi, myargs.node, &req);
+       if (err) {
+               errmsg("cannot attach mtd%d", myargs.mtdn);
+               perror("ubi_attach_mtd");
+               goto out_libubi;
+       }
+
+       /* Print some information about the new UBI device */
+       err = ubi_get_dev_info1(libubi, req.dev_num, &dev_info);
+       if (err) {
+               errmsg("cannot get information about newly created UBI device");
+               perror("ubi_get_dev_info1");
+               goto out_libubi;
+       }
+
+       printf("UBI device number %d, total %d LEBs (", dev_info.dev_num, dev_info.total_lebs);
+       ubiutils_print_bytes(dev_info.total_bytes, 0);
+       printf("), available %d LEBs (", dev_info.avail_lebs);
+       ubiutils_print_bytes(dev_info.avail_bytes, 0);
+       printf("), LEB size ");
+       ubiutils_print_bytes(dev_info.leb_size, 1);
+       printf("\n");
+
+       libubi_close(libubi);
+       return 0;
+
+out_libubi:
+       libubi_close(libubi);
+       return -1;
+}
index 034cb101f5cee8d214827d9c15fa0fc66b7d8f1b..cde3104b9d1962a190005940e06f3622dbbd2404 100644 (file)
@@ -39,8 +39,8 @@
 #define PROGRAM_VERSION "1.2"
 #define PROGRAM_NAME    "ubicrc32"
 
-static const char *doc = "Version " PROGRAM_VERSION "\n"
-       PROGRAM_NAME " - a tool to calculate CRC32 with UBI start value (0xFFFFFFFF)";
+static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION
+                        " - a tool to calculate CRC32 with UBI start value (0xFFFFFFFF)";
 
 static const char *optionsstr =
 "-h, --help                    print help message\n"
diff --git a/ubi-utils/src/ubidetach.c b/ubi-utils/src/ubidetach.c
new file mode 100644 (file)
index 0000000..cde21d0
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * An utility to delete UBI devices (detach MTD devices from UBI).
+ *
+ * Author: Artem Bityutskiy
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <libubi.h>
+#include "common.h"
+
+#define PROGRAM_VERSION "1.0"
+#define PROGRAM_NAME    "ubidetach"
+
+/* The variables below are set by command line arguments */
+struct args {
+       int devn;
+       int mtdn;
+       const char *node;
+};
+
+static struct args myargs = {
+       .devn = UBI_DEV_NUM_AUTO,
+       .mtdn = -1,
+       .node = NULL,
+};
+
+static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION
+" - a tool to remove UBI devices (detach MTD devices from UBI)";
+
+static const char *optionsstr =
+"-d, --devn=<UBI device number>  UBI device number to delete\n"
+"-m, --mtdn=<MTD device number>  or altrnatively, MTD device number to detach -\n"
+"                                this will delete corresponding UBI device\n"
+"-h, --help                      print help message\n"
+"-V, --version                   print program version";
+
+static const char *usage =
+"Usage: " PROGRAM_NAME "<UBI control device node file name> [-d <UBI device number>] [-m <MTD device number>]\n"
+"\t\t[--devn <UBI device number>] [--mtdn=<MTD device number>]\n"
+"Example 1: " PROGRAM_NAME " /dev/ubi_ctrl -d 2 - delete UBI device 2 (ubi2)\n"
+"Example 2: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 - detach MTD device 0 (mtd0)";
+
+static const struct option long_options[] = {
+       { .name = "devn",    .has_arg = 1, .flag = NULL, .val = 'd' },
+       { .name = "mtdn",    .has_arg = 1, .flag = NULL, .val = 'm' },
+       { .name = "help",    .has_arg = 0, .flag = NULL, .val = 'h' },
+       { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' },
+       { NULL, 0, NULL, 0},
+};
+
+static int parse_opt(int argc, char * const argv[])
+{
+       while (1) {
+               int key;
+               char *endp;
+
+               key = getopt_long(argc, argv, "m:d:hV", long_options, NULL);
+               if (key == -1)
+                       break;
+
+               switch (key) {
+               case 'd':
+                       myargs.devn = strtoul(optarg, &endp, 0);
+                       if (*endp != '\0' || endp == optarg || myargs.devn < 0) {
+                               errmsg("bad UBI device number: \"%s\"", optarg);
+                               return -1;
+                       }
+
+                       break;
+
+               case 'm':
+                       myargs.mtdn = strtoul(optarg, &endp, 0);
+                       if (*endp != '\0' || endp == optarg || myargs.mtdn < 0) {
+                               errmsg("bad MTD device number: \"%s\"", optarg);
+                               return -1;
+                       }
+
+                       break;
+
+               case 'h':
+                       fprintf(stderr, "%s\n\n", doc);
+                       fprintf(stderr, "%s\n\n", usage);
+                       fprintf(stderr, "%s\n", optionsstr);
+                       exit(0);
+
+               case 'V':
+                       fprintf(stderr, "%s\n", PROGRAM_VERSION);
+                       exit(0);
+
+               case ':':
+                       errmsg("parameter is missing");
+                       return -1;
+
+               default:
+                       fprintf(stderr, "Use -h for help\n");
+                       exit(-1);
+               }
+       }
+
+       if (optind == argc) {
+               errmsg("UBI control device name was not specified (use -h for help)");
+               return -1;
+       } else if (optind != argc - 1) {
+               errmsg("more then one UBI control device specified (use -h for help)");
+               return -1;
+       }
+
+       if (myargs.mtdn == -1 && myargs.devn == -1) {
+               errmsg("neither MTD nor UBI devices were specified (use -h for help)");
+               return -1;
+       }
+
+       if (myargs.mtdn != -1 && myargs.devn != -1) {
+               errmsg("specify either MTD or UBI device (use -h for help)");
+               return -1;
+       }
+
+       myargs.node = argv[optind];
+       return 0;
+}
+
+int main(int argc, char * const argv[])
+{
+       int err;
+       libubi_t libubi;
+       struct ubi_info ubi_info;
+
+       err = parse_opt(argc, argv);
+       if (err)
+               return -1;
+
+       libubi = libubi_open();
+       if (libubi == NULL) {
+               errmsg("cannot open libubi");
+               perror("libubi_open");
+               return -1;
+       }
+
+       /*
+        * Make sure the kernel is fresh enough and this feature is supported.
+        */
+       err = ubi_get_info(libubi, &ubi_info);
+       if (err) {
+               errmsg("cannot get UBI information");
+               perror("ubi_get_info");
+               goto out_libubi;
+       }
+
+       if (ubi_info.ctrl_major == -1) {
+               errmsg("MTD detach/detach feature is not supported by your kernel");
+               goto out_libubi;
+       }
+
+       if (myargs.devn != -1) {
+               err = ubi_remove_dev(libubi, myargs.node, myargs.devn);
+               if (err) {
+                       errmsg("cannot remove ubi%d", myargs.devn);
+                       perror("ubi_remove_dev");
+                       goto out_libubi;
+               }
+       } else {
+               err = ubi_detach_mtd(libubi, myargs.node, myargs.mtdn);
+               if (err) {
+                       errmsg("cannot detach mtd%d", myargs.mtdn);
+                       perror("ubi_detach_mtd");
+                       goto out_libubi;
+               }
+       }
+
+       libubi_close(libubi);
+       return 0;
+
+out_libubi:
+       libubi_close(libubi);
+       return -1;
+}
+
index 38c737d2890a4816b322b64b98780c208a719f22..42b61b8960afa2811d31b3e978aa56afd0ff74b5 100644 (file)
@@ -36,7 +36,7 @@
 #define PROGRAM_VERSION "1.6"
 #define PROGRAM_NAME    "ubimkvol"
 
-/* The variables below is set by command line arguments */
+/* The variables below are set by command line arguments */
 struct args {
        int vol_id;
        int vol_type;
@@ -61,8 +61,8 @@ static struct args myargs = {
        .maxavs = 0,
 };
 
-static const char *doc = "Version " PROGRAM_VERSION "\n"
-       PROGRAM_NAME " - a tool to create UBI volumes.";
+static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION
+                        " - a tool to create UBI volumes.";
 
 static const char *optionsstr =
 "-a, --alignment=<alignment>   volume alignment (default is 1)\n"
@@ -228,7 +228,7 @@ static int parse_opt(int argc, char * const argv[])
                errmsg("UBI device name was not specified (use -h for help)");
                return -1;
        } else if (optind != argc - 1) {
-               errmsg("more then one UBI devices specified (use -h for help)");
+               errmsg("more then one UBI device specified (use -h for help)");
                return -1;
        }
 
index c907335f10a84e7c042bf5fd34d3acf187aa2791..35c70a12a9d72a275d45ad66a99e8d888cedc234 100644 (file)
@@ -34,7 +34,7 @@
 #define PROGRAM_VERSION "1.0"
 #define PROGRAM_NAME    "ubinfo"
 
-/* The variables below is set by command line arguments */
+/* The variables below are set by command line arguments */
 struct args {
        int devn;
        int vol_id;
@@ -49,8 +49,8 @@ static struct args myargs = {
        .node = NULL,
 };
 
-static const char *doc = "Version " PROGRAM_VERSION "\n"
-       PROGRAM_NAME " - a tool to print UBI information.";
+static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION
+                        " - a tool to print UBI information.";
 
 static const char *optionsstr =
 "-d, --devn=<UBI device number>  UBI device number to get information about\n"
index 5f3552505acd6f8605c7ee38273182b06803a250..60bcdc09d491d6dc0ce1e4a76b1a215a83bfdb59 100644 (file)
@@ -36,7 +36,7 @@
 #define PROGRAM_VERSION "1.5"
 #define PROGRAM_NAME    "ubirmvol"
 
-/* The variables below is set by command line arguments */
+/* The variables below are set by command line arguments */
 struct args {
        int vol_id;
        const char *node;
@@ -47,8 +47,8 @@ static struct args myargs = {
        .node = NULL,
 };
 
-static const char *doc = "Version: " PROGRAM_VERSION "\n"
-       PROGRAM_NAME " - a tool to remove UBI volumes.";
+static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION
+                        " - a tool to remove UBI volumes.";
 
 static const char *optionsstr =
 "  -n, --vol_id=<volume id>   volume ID to remove\n"
@@ -121,7 +121,7 @@ static int parse_opt(int argc, char * const argv[])
                errmsg("UBI device name was not specified (use -h for help)");
                return -1;
        } else if (optind != argc - 1) {
-               errmsg("more then one UBI devices specified (use -h for help)");
+               errmsg("more then one UBI device specified (use -h for help)");
                return -1;
        }
 
index 1b9188e3ebed777dff1ca100e0371a87d228457f..75222d4303d7da5edabbe6d54f63acc58ba1bd79 100644 (file)
@@ -53,8 +53,8 @@ static struct args myargs = {
        .img = NULL,
 };
 
-static const char *doc = "Version " PROGRAM_VERSION "\n"
-       PROGRAM_NAME " - a tool to write data to UBI volumes.";
+static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION
+                        " - a tool to write data to UBI volumes.";
 
 static const char *optionsstr =
 "-n, --vol_id=<volume id>   ID of UBI volume to update\n"