From 48d5de6f84325f2895ae66830d82ce23e827ff6e Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Sun, 10 Jan 2010 01:33:31 +0200 Subject: ubiformat: always initialize seq number For some reasons sequence number was set to 0 in some case, which is wrong. Signed-off-by: Artem Bityutskiy --- ubi-utils/src/ubiformat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'ubi-utils') diff --git a/ubi-utils/src/ubiformat.c b/ubi-utils/src/ubiformat.c index 3b0f49b..80f3a6d 100644 --- a/ubi-utils/src/ubiformat.c +++ b/ubi-utils/src/ubiformat.c @@ -912,7 +912,8 @@ int main(int argc, char * const argv[]) printf("yes\n"); } else ubigen_info_init(&ui, mtd.eb_size, mtd.min_io_size, 0, - si->vid_hdr_offs, args.ubi_ver, 0); + si->vid_hdr_offs, args.ubi_ver, + args.image_seq); normsg("use offsets %d and %d", ui.vid_hdr_offs, ui.data_offs); } -- cgit v1.2.3 From 2caf2c6fda66f1f09502245229230743dc20295b Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Sun, 10 Jan 2010 01:39:24 +0200 Subject: ubiformat: be consistent with sequence numbers This commit fixes a stupid an nasty bug. When we flash an UBI image, we do not change its sequence numbers. But when we format the rest of the PEBs (beyond the flashed image), we use a random (or specified via cmdline) sequence number. As a result, we have a broken flash format and UBI refuses it, because half of it has one sequence number, another half has a different one. What we have to do instead, we have to substitute image's sequence number with ours. Reported-by: Jeff Angielski Signed-off-by: Artem Bityutskiy Tested-by: Jeff Angielski --- ubi-utils/src/ubiformat.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'ubi-utils') diff --git a/ubi-utils/src/ubiformat.c b/ubi-utils/src/ubiformat.c index 80f3a6d..2316d67 100644 --- a/ubi-utils/src/ubiformat.c +++ b/ubi-utils/src/ubiformat.c @@ -295,7 +295,8 @@ static void print_bad_eraseblocks(const struct mtd_dev_info *mtd, printf("\n"); } -static int change_ec(struct ubi_ec_hdr *hdr, long long ec) +static int change_ech(struct ubi_ec_hdr *hdr, uint32_t image_seq, + long long ec) { uint32_t crc; @@ -309,6 +310,7 @@ static int change_ec(struct ubi_ec_hdr *hdr, long long ec) return errmsg("bad CRC %#08x, should be %#08x\n", crc, be32_to_cpu(hdr->hdr_crc)); + hdr->image_seq = cpu_to_be32(image_seq); hdr->ec = cpu_to_be64(ec); crc = crc32(UBI_CRC32_INIT, hdr, UBI_EC_HDR_SIZE_CRC); hdr->hdr_crc = cpu_to_be32(crc); @@ -438,7 +440,8 @@ static int mark_bad(const struct mtd_dev_info *mtd, struct ubi_scan_info *si, in return consecutive_bad_check(eb); } -static int flash_image(const struct mtd_dev_info *mtd, struct ubi_scan_info *si) +static int flash_image(const struct mtd_dev_info *mtd, const struct ubigen_info *ui, + struct ubi_scan_info *si) { int fd, img_ebs, eb, written_ebs = 0, divisor; off_t st_size; @@ -518,7 +521,7 @@ static int flash_image(const struct mtd_dev_info *mtd, struct ubi_scan_info *si) fflush(stdout); } - err = change_ec((struct ubi_ec_hdr *)buf, ec); + err = change_ech((struct ubi_ec_hdr *)buf, ui->image_seq, ec); if (err) { errmsg("bad EC header at eraseblock %d of \"%s\"", written_ebs, args.image); @@ -918,7 +921,7 @@ int main(int argc, char * const argv[]) } if (args.image) { - err = flash_image(&mtd, si); + err = flash_image(&mtd, &ui, si); if (err < 0) goto out_free; -- cgit v1.2.3 From a67747b7a314e685085b62e8239442ea54959dbc Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Fri, 15 Jan 2010 19:04:21 +0200 Subject: ubiformat: boost version to 1.5 We fixed the sequence numbers bug, which is quite serious. Signed-off-by: Artem Bityutskiy --- ubi-utils/src/ubiformat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ubi-utils') diff --git a/ubi-utils/src/ubiformat.c b/ubi-utils/src/ubiformat.c index 2316d67..8ad5051 100644 --- a/ubi-utils/src/ubiformat.c +++ b/ubi-utils/src/ubiformat.c @@ -44,7 +44,7 @@ #include "crc32.h" #include "common.h" -#define PROGRAM_VERSION "1.4" +#define PROGRAM_VERSION "1.5" #define PROGRAM_NAME "ubiformat" /* The variables below are set by command line arguments */ -- cgit v1.2.3 From 90184ffb43dfc0e8071d7bb4c33095fea47e541e Mon Sep 17 00:00:00 2001 From: Jon Ringle Date: Tue, 23 Mar 2010 11:16:12 -0400 Subject: ubinfo: add -N option to get info by name of ubi volume Signed-off-by: Jon Ringle Signed-off-by: Artem Bityutskiy --- ubi-utils/src/ubinfo.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'ubi-utils') diff --git a/ubi-utils/src/ubinfo.c b/ubi-utils/src/ubinfo.c index 8c5a1a9..cd011c5 100644 --- a/ubi-utils/src/ubinfo.c +++ b/ubi-utils/src/ubinfo.c @@ -39,6 +39,7 @@ struct args { int vol_id; int all; const char *node; + const char *vol_name; }; static struct args args = { @@ -46,6 +47,7 @@ static struct args args = { .devn = -1, .all = 0, .node = NULL, + .vol_name = NULL, }; static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION @@ -87,7 +89,7 @@ static int parse_opt(int argc, char * const argv[]) int key; char *endp; - key = getopt_long(argc, argv, "an:d:hV", long_options, NULL); + key = getopt_long(argc, argv, "an:N:d:hV", long_options, NULL); if (key == -1) break; @@ -102,6 +104,10 @@ static int parse_opt(int argc, char * const argv[]) return errmsg("bad volume ID: " "\"%s\"", optarg); break; + case 'N': + args.vol_name = optarg; + break; + case 'd': args.devn = strtoul(optarg, &endp, 0); if (*endp != '\0' || endp == optarg || args.devn < 0) @@ -174,6 +180,20 @@ static int translate_dev(libubi_t libubi, const char *node) return 0; } +static int get_vol_id_by_name(libubi_t libubi, int dev_num, const char *name) +{ + int err; + struct ubi_vol_info vol_info; + + err = ubi_get_vol_info1_nm(libubi, dev_num, name, &vol_info); + if (err) + return sys_errmsg("cannot get information about volume \"%s\" on ubi%d\n", name, dev_num); + + args.vol_id = vol_info.vol_id; + + return 0; +} + static int print_vol_info(libubi_t libubi, int dev_num, int vol_id) { int err; @@ -377,6 +397,12 @@ int main(int argc, char * const argv[]) goto out_libubi; } + if (args.vol_name) { + err = get_vol_id_by_name(libubi, args.devn, args.vol_name); + if (err) + goto out_libubi; + } + if (args.vol_id != -1 && args.devn == -1) { errmsg("volume ID is specified, but UBI device number is not " "(use -h for help)\n"); -- cgit v1.2.3 From 22b7a6d1263a479234b04932d9b8870946be769a Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 8 Apr 2010 11:48:08 +0300 Subject: ubinfo: document the new -N option Signed-off-by: Artem Bityutskiy --- ubi-utils/src/ubinfo.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'ubi-utils') diff --git a/ubi-utils/src/ubinfo.c b/ubi-utils/src/ubinfo.c index cd011c5..8f84382 100644 --- a/ubi-utils/src/ubinfo.c +++ b/ubi-utils/src/ubinfo.c @@ -56,6 +56,7 @@ static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION static const char *optionsstr = "-d, --devn= UBI device number to get information about\n" "-n, --vol_id= ID of UBI volume to print information about\n" +"-N, --name= name of UBI volume to print information about\n" "-a, --all print information about all devices and volumes,\n" " or about all volumes if the UBI device was\n" " specified\n" @@ -63,8 +64,8 @@ static const char *optionsstr = "-V, --version print program version"; static const char *usage = -"Usage 1: " PROGRAM_NAME " [-d ] [-n ] [-a] [-h] [-V] [--vol_id=]\n" -"\t\t[--devn ] [--all] [--help] [--version]\n" +"Usage 1: " PROGRAM_NAME " [-d ] [-n | -N ] [-a] [-h] [-V]\n" +"\t\t[--vol_id= | --name ] [--devn ] [--all] [--help] [--version]\n" "Usage 2: " PROGRAM_NAME " [-a] [-h] [-V] [--all] [--help] [--version]\n" "Usage 3: " PROGRAM_NAME " [-h] [-V] [--help] [--version]\n\n" "Example 1: " PROGRAM_NAME " - (no arguments) print general UBI information\n" @@ -77,6 +78,7 @@ static const char *usage = static const struct option long_options[] = { { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, + { .name = "name", .has_arg = 1, .flag = NULL, .val = 'N' }, { .name = "all", .has_arg = 0, .flag = NULL, .val = 'a' }, { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, -- cgit v1.2.3 From 5960d463ff659b0af6774be8aef833032036e9c8 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 1 Feb 2010 10:03:47 +0100 Subject: libubi: add support to attach/detach by MTD device path struct ubi_attach_request now has additional field 'dev' that can contain path to the MTD device node in the filesystem. Also there are two new functions that are able to handle path to the MTD device node: ubi_attach() - attach MTD device by number or by path ubi_detach() - detach MTD device by path ubi_attach() works like ubi_attach_mtd() when it is passed empty req->dev, otherwise it looks up correct MTD device number based on the given device node path. Signed-off-by: Mika Westerberg Signed-off-by: Artem Bityutskiy --- ubi-utils/include/libubi.h | 30 +++++++++++ ubi-utils/src/libubi.c | 127 ++++++++++++++++++++++++++++++++++++++++----- ubi-utils/src/libubi_int.h | 1 + 3 files changed, 145 insertions(+), 13 deletions(-) (limited to 'ubi-utils') diff --git a/ubi-utils/include/libubi.h b/ubi-utils/include/libubi.h index f52904d..64b5eed 100644 --- a/ubi-utils/include/libubi.h +++ b/ubi-utils/include/libubi.h @@ -44,6 +44,7 @@ typedef void * libubi_t; * (%UBI_DEV_NUM_AUTO should be used to automatically assign the * number) * @mtd_num: MTD device number to attach + * @dev: path to device node to attach * @vid_hdr_offset: VID header offset (%0 means default offset and this is what * most of the users want) */ @@ -51,6 +52,7 @@ struct ubi_attach_request { int dev_num; int mtd_num; + const char *dev; int vid_hdr_offset; }; @@ -218,6 +220,23 @@ int mtd_num2ubi_dev(libubi_t desc, int mtd_num, int *dev_num); int ubi_attach_mtd(libubi_t desc, const char *node, struct ubi_attach_request *req); +/** + * ubi_attach - attach an MTD device by its node path. + * @desc: UBI library descriptor + * @node: name of the UBI control character device node + * @req: MTD attach request + * + * This function creates new UBI device by attaching an MTD device described by + * @req. If @req->dev is given it should contain path to the MTD device node. + * Otherwise functionality is similar than in function 'ubi_attach_mtd()' where + * @req->mtd_num is used. + * + * Returns %0 in case of success and %-1 in case of failure (errno is set). The + * newly created UBI device number is returned in @req->dev_num. + */ +int ubi_attach(libubi_t desc, const char *node, + struct ubi_attach_request *req); + /** * ubi_detach_mtd - detach an MTD device. * @desc: UBI library descriptor @@ -230,6 +249,17 @@ int ubi_attach_mtd(libubi_t desc, const char *node, */ int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num); +/** + * ubi_detach - detach an MTD device by its node path. + * @desc: UBI library descriptor + * @node: name of the UBI control character device node + * @dev: path to an MTD device node + * + * This function detaches an MTD device @dev from UBI. Returns zero in case of + * success and %-1 in case of failure. + */ +int ubi_detach(libubi_t desc, const char *node, const char *dev); + /** * ubi_remove_dev - remove an UBI device. * @desc: UBI library descriptor diff --git a/ubi-utils/src/libubi.c b/ubi-utils/src/libubi.c index fd97774..2f19bd7 100644 --- a/ubi-utils/src/libubi.c +++ b/ubi-utils/src/libubi.c @@ -677,35 +677,120 @@ void libubi_close(libubi_t desc) free(lib); } -int ubi_attach_mtd(libubi_t desc, const char *node, - struct ubi_attach_request *req) +/** + * do_attach - perform the actual attach operation. + * @node: name of the UBI control character device node + * @r: attach request + * + * This function performs the actual UBI attach operation. Returns %0 in case of + * success and %-1 in case of failure. @r->ubi_num contains newly created UBI + * device number. + */ +static int do_attach(const char *node, const struct ubi_attach_req *r) { int fd, ret; - struct ubi_attach_req r; - - memset(&r, 0, sizeof(struct ubi_attach_req)); - - 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 sys_errmsg("cannot open \"%s\"", node); - ret = ioctl(fd, UBI_IOCATT, &r); + 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; usleep(100000); #endif + return ret; +} + +int ubi_attach_mtd(libubi_t desc, const char *node, + struct ubi_attach_request *req) +{ + struct ubi_attach_req r; + int ret; + + (void)desc; + + memset(&r, 0, sizeof(struct ubi_attach_req)); + r.ubi_num = req->dev_num; + r.mtd_num = req->mtd_num; + r.vid_hdr_offset = req->vid_hdr_offset; + + ret = do_attach(node, &r); + if (ret == 0) + req->dev_num = r.ubi_num; + + return ret; +} + +#ifndef MTD_CHAR_MAJOR +/* + * This is taken from kernel and is unlikely to change anytime + * soon. + */ +#define MTD_CHAR_MAJOR 90 +#endif + +/** + * dev_to_mtdnum - converts device node to MTD number. + * @dev: path to device node to convert + * + * This function converts given @dev to MTD device number. @dev should contain + * path to the MTD device node. Returns MTD device number in case of success and + * %-1 in case of failure (errno is set). + */ +static int dev_to_mtdnum(const char *dev) +{ + int major, minor; + struct stat sb; + + if (stat(dev, &sb) < 0) + return sys_errmsg("cannot stat \"%s\"", dev); + + if (!S_ISCHR(sb.st_mode)) { + errno = EINVAL; + return sys_errmsg("\"%s\" is not a character device", dev); + } + + major = major(sb.st_rdev); + minor = minor(sb.st_rdev); + + if (major != MTD_CHAR_MAJOR) { + errno = EINVAL; + return sys_errmsg("\"%s\" is not an MTD device", dev); + } + + return minor / 2; +} + +int ubi_attach(libubi_t desc, const char *node, struct ubi_attach_request *req) +{ + struct ubi_attach_req r; + int ret; + + if (!req->dev) + /* Fallback to opening by mtd_num */ + return ubi_attach_mtd(desc, node, req); + + memset(&r, 0, sizeof(struct ubi_attach_req)); + r.ubi_num = req->dev_num; + r.vid_hdr_offset = req->vid_hdr_offset; + + /* + * User has passed path to device node. Lets find out MTD device number + * of the device and pass it to the kernel. + */ + r.mtd_num = dev_to_mtdnum(req->dev); + if (r.mtd_num == -1) + return -1; + + ret = do_attach(node, &r); + if (ret == 0) + req->dev_num = r.ubi_num; return ret; } @@ -723,6 +808,22 @@ int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num) return ubi_remove_dev(desc, node, ubi_dev); } +int ubi_detach(libubi_t desc, const char *node, const char *dev) +{ + int mtd_num; + + if (!dev) { + errno = EINVAL; + return -1; + } + + mtd_num = dev_to_mtdnum(dev); + if (mtd_num == -1) + return -1; + + return ubi_detach_mtd(desc, node, mtd_num); +} + int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev) { int fd, ret; diff --git a/ubi-utils/src/libubi_int.h b/ubi-utils/src/libubi_int.h index 6d17d57..c3aa37a 100644 --- a/ubi-utils/src/libubi_int.h +++ b/ubi-utils/src/libubi_int.h @@ -83,6 +83,7 @@ extern "C" { * handling * @dev_max_vols: maximum volumes number count sysfs path pattern * @dev_min_io_size: minimum I/O unit size sysfs path pattern + * @dev_mtd_num: MTD device number * @ubi_vol: UBI volume sysfs directory pattern * @vol_type: volume type sysfs path pattern * @vol_dev: volume major/minor numbers file pattern -- cgit v1.2.3 From 4bb55d5b619f8ab8be0b301e9c3b1205ddd20d3c Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 1 Feb 2010 10:03:48 +0100 Subject: ubiattach/ubidetach: add support to attach/detach by path Now there is a new option '-p' (or '--dev-path') that can be used to pass path to a MTD device node. Signed-off-by: Mika Westerberg Signed-off-by: Artem Bityutskiy --- ubi-utils/src/ubiattach.c | 35 ++++++++++++++++++++--------- ubi-utils/src/ubidetach.c | 57 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 64 insertions(+), 28 deletions(-) (limited to 'ubi-utils') diff --git a/ubi-utils/src/ubiattach.c b/ubi-utils/src/ubiattach.c index a935b42..67f8c85 100644 --- a/ubi-utils/src/ubiattach.c +++ b/ubi-utils/src/ubiattach.c @@ -39,6 +39,7 @@ struct args { int mtdn; int vidoffs; const char *node; + const char *dev; }; static struct args args = { @@ -46,6 +47,7 @@ static struct args args = { .mtdn = -1, .vidoffs = 0, .node = NULL, + .dev = NULL, }; static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION @@ -55,7 +57,9 @@ static const char *optionsstr = "-d, --devn= 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 to attach\n" +"-p, --dev-path= path to MTD device node to attach\n" +"-m, --mtdn= MTD device number to attach (alternative method, e.g\n" +" if the character device node does not exist)\n" "-O, --vid-hdr-offset VID header offset (do not specify this unless you\n" " really know what you do and the optimal defaults will\n" " be used)\n" @@ -63,14 +67,18 @@ static const char *optionsstr = "-V, --version print program version"; static const char *usage = -"Usage: " PROGRAM_NAME " [-m ] [-d ]\n" -"\t\t[--mtdn=] [--devn ]\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" +"Usage: " PROGRAM_NAME " \n" +"\t[-m ] [-d ] [-p ]\n" +"\t[--mtdn=] [--devn=]\n" +"\t[--dev-path=]\n" +"Example 1: " PROGRAM_NAME " /dev/ubi_ctrl -p /dev/mtd0 - attach /dev/mtd0 to UBI\n" +"Example 2: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 - attach MTD device 0 (mtd0) to UBI\n" +"Example 3: " 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 = "dev-path", .has_arg = 1, .flag = NULL, .val = 'p' }, { .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' }, @@ -84,11 +92,14 @@ static int parse_opt(int argc, char * const argv[]) int key; char *endp; - key = getopt_long(argc, argv, "m:d:O:hV", long_options, NULL); + key = getopt_long(argc, argv, "p:m:d:O:hV", long_options, NULL); if (key == -1) break; switch (key) { + case 'p': + args.dev = optarg; + break; case 'd': args.devn = strtoul(optarg, &endp, 0); if (*endp != '\0' || endp == optarg || args.devn < 0) @@ -134,8 +145,8 @@ static int parse_opt(int argc, char * const argv[]) else if (optind != argc - 1) return errmsg("more then one UBI control device specified (use -h for help)"); - if (args.mtdn == -1) - return errmsg("MTD device number was not specified (use -h for help)"); + if (args.mtdn == -1 && args.dev == NULL) + return errmsg("MTD device to attach was not specified (use -h for help)"); args.node = argv[optind]; return 0; @@ -177,10 +188,14 @@ int main(int argc, char * const argv[]) req.dev_num = args.devn; req.mtd_num = args.mtdn; req.vid_hdr_offset = args.vidoffs; + req.dev = args.dev; - err = ubi_attach_mtd(libubi, args.node, &req); + err = ubi_attach(libubi, args.node, &req); if (err) { - sys_errmsg("cannot attach mtd%d", args.mtdn); + if (args.dev) + sys_errmsg("cannot attach \"%s\"", args.dev); + else + sys_errmsg("cannot attach mtd%d", args.mtdn); goto out_libubi; } diff --git a/ubi-utils/src/ubidetach.c b/ubi-utils/src/ubidetach.c index 83584cd..335486d 100644 --- a/ubi-utils/src/ubidetach.c +++ b/ubi-utils/src/ubidetach.c @@ -38,12 +38,14 @@ struct args { int devn; int mtdn; const char *node; + const char *dev; }; static struct args args = { .devn = UBI_DEV_NUM_AUTO, .mtdn = -1, .node = NULL, + .dev = NULL, }; static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION @@ -51,22 +53,26 @@ static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION static const char *optionsstr = "-d, --devn= UBI device number to delete\n" -"-m, --mtdn= or altrnatively, MTD device number to detach -\n" -" this will delete corresponding UBI device\n" +"-p, --dev-path= or alternatively, MTD device node path to detach\n" +"-m, --mtdn= or alternatively, MTD device number to detach\n" "-h, --help print help message\n" "-V, --version print program version"; static const char *usage = -"Usage: " PROGRAM_NAME " [-d ] [-m ]\n" -"\t\t[--devn ] [--mtdn=]\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)"; +"Usage: " PROGRAM_NAME " \n" +"\t[-d ] [-m ] [-p ]\n" +"\t[--devn=] [--mtdn=]\n" +"\t[--dev-path=]\n" +"Example 1: " PROGRAM_NAME " /dev/ubi_ctrl -p /dev/mtd0 - detach MTD device /dev/mtd0\n" +"Example 2: " PROGRAM_NAME " /dev/ubi_ctrl -d 2 - delete UBI device 2 (ubi2)\n" +"Example 3: " 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' }, + { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, + { .name = "dev-path", .has_arg = 1, .flag = NULL, .val = 'p' }, + { .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}, }; @@ -76,11 +82,14 @@ static int parse_opt(int argc, char * const argv[]) int key; char *endp; - key = getopt_long(argc, argv, "m:d:hV", long_options, NULL); + key = getopt_long(argc, argv, "p:m:d:hV", long_options, NULL); if (key == -1) break; switch (key) { + case 'p': + args.dev = optarg; + break; case 'd': args.devn = strtoul(optarg, &endp, 0); if (*endp != '\0' || endp == optarg || args.devn < 0) @@ -119,11 +128,15 @@ static int parse_opt(int argc, char * const argv[]) else if (optind != argc - 1) return errmsg("more then one UBI control device specified (use -h for help)"); - if (args.mtdn == -1 && args.devn == -1) + if (args.mtdn == -1 && args.devn == -1 && args.dev == NULL) return errmsg("neither MTD nor UBI devices were specified (use -h for help)"); - if (args.mtdn != -1 && args.devn != -1) - return errmsg("specify either MTD or UBI device (use -h for help)"); + if (args.devn != -1) { + if (args.mtdn != -1 || args.dev != NULL) + return errmsg("specify either MTD or UBI device (use -h for help)"); + + } else if (args.mtdn != -1 && args.dev != NULL) + return errmsg("specify either MTD number or device node (use -h for help)"); args.node = argv[optind]; return 0; @@ -167,10 +180,18 @@ int main(int argc, char * const argv[]) goto out_libubi; } } else { - err = ubi_detach_mtd(libubi, args.node, args.mtdn); - if (err) { - sys_errmsg("cannot detach mtd%d", args.mtdn); - goto out_libubi; + if (args.dev != NULL) { + err = ubi_detach(libubi, args.node, args.dev); + if (err) { + sys_errmsg("cannot detach \"%s\"", args.dev); + goto out_libubi; + } + } else { + err = ubi_detach_mtd(libubi, args.node, args.mtdn); + if (err) { + sys_errmsg("cannot detach mtd%d", args.mtdn); + goto out_libubi; + } } } -- cgit v1.2.3