diff --git a/commands/ubi.c b/commands/ubi.c index 94da799b8..218eda083 100644 --- a/commands/ubi.c +++ b/commands/ubi.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -58,14 +59,37 @@ BAREBOX_CMD_START(ubimkvol) BAREBOX_CMD_HELP(cmd_ubimkvol_help) BAREBOX_CMD_END +static struct mtd_info *get_mtd_info(const char *path) +{ + int fd; + struct mtd_info_user user; + int ret; + + fd = open(path, O_RDWR); + if (fd < 0) { + perror("open"); + return ERR_PTR(fd); + } + + ret = ioctl(fd, MEMGETINFO, &user); + + close(fd); + + if (ret) { + printf("MEMGETINFO failed: %s\n", strerror(-ret)); + return ERR_PTR(ret); + } + + return user.mtd; +} static int do_ubiattach(int argc, char *argv[]) { int opt; - struct mtd_info_user user; - int fd, ret; + int ret; int vid_hdr_offset = 0; int devnum = UBI_DEV_NUM_AUTO; + struct mtd_info *mtd; while((opt = getopt(argc, argv, "d:O:")) > 0) { switch(opt) { @@ -83,25 +107,15 @@ static int do_ubiattach(int argc, char *argv[]) if (optind == argc) return COMMAND_ERROR_USAGE; - fd = open(argv[optind], O_RDWR); - if (fd < 0) { - perror("open"); - return 1; - } + mtd = get_mtd_info(argv[optind]); + if (IS_ERR(mtd)) + return PTR_ERR(mtd); - ret = ioctl(fd, MEMGETINFO, &user); - if (ret) { - printf("MEMGETINFO failed: %s\n", strerror(-ret)); - goto err; - } - - ret = ubi_attach_mtd_dev(user.mtd, devnum, vid_hdr_offset, 20); + ret = ubi_attach_mtd_dev(mtd, devnum, vid_hdr_offset, 20); if (ret < 0) printf("failed to attach: %s\n", strerror(-ret)); else ret = 0; -err: - close(fd); return ret ? 1 : 0; } @@ -122,13 +136,17 @@ BAREBOX_CMD_END static int do_ubidetach(int argc, char *argv[]) { - int ubi_num, ret; + int ret; + struct mtd_info *mtd; if (argc != 2) return COMMAND_ERROR_USAGE; - ubi_num = simple_strtoul(argv[1], NULL, 0); - ret = ubi_detach_mtd_dev(ubi_num, 1); + mtd = get_mtd_info(argv[1]); + if (IS_ERR(mtd)) + return PTR_ERR(mtd); + + ret = ubi_detach_mtd_dev(mtd, 1); if (ret) printf("failed to detach: %s\n", strerror(-ret)); @@ -138,8 +156,8 @@ static int do_ubidetach(int argc, char *argv[]) BAREBOX_CMD_START(ubidetach) .cmd = do_ubidetach, - BAREBOX_CMD_DESC("detach an UBI device") - BAREBOX_CMD_OPTS("UBINUM") + BAREBOX_CMD_DESC("detach mtd device from UBI") + BAREBOX_CMD_OPTS("UBIDEV") BAREBOX_CMD_GROUP(CMD_GRP_PART) BAREBOX_CMD_END diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index b02880eb7..396497bdc 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -683,6 +683,20 @@ out_free: return err; } +static struct ubi_device *ubi_find_mtd(struct mtd_info *mtd) +{ + struct ubi_device *ubi; + int i; + + for (i = 0; i < UBI_MAX_DEVICES; i++) { + ubi = ubi_devices[i]; + if (ubi && ubi->mtd == mtd) + return ubi; + } + + return NULL; +} + /** * ubi_detach_mtd_dev - detach an MTD device. * @ubi_num: UBI device number to detach from @@ -696,13 +710,17 @@ out_free: * Note, the invocations of this function has to be serialized by the * @ubi_devices_mutex. */ -int ubi_detach_mtd_dev(int ubi_num, int anyway) +int ubi_detach_mtd_dev(struct mtd_info *mtd, int anyway) { struct ubi_device *ubi; + int ubi_num; - if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES) + ubi = ubi_find_mtd(mtd); + if (!ubi) return -EINVAL; + ubi_num = ubi->ubi_num; + ubi = ubi_get_device(ubi_num); if (!ubi) return -EINVAL; diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h index 2000ef2fd..14f309afd 100644 --- a/include/mtd/ubi-user.h +++ b/include/mtd/ubi-user.h @@ -406,6 +406,6 @@ struct ubi_set_vol_prop_req { int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset, int max_beb_per1024); -int ubi_detach_mtd_dev(int ubi_num, int anyway); +int ubi_detach_mtd_dev(struct mtd_info *mtd, int anyway); #endif /* __UBI_USER_H__ */