diff options
Diffstat (limited to 'commands/ubi.c')
-rw-r--r-- | commands/ubi.c | 116 |
1 files changed, 107 insertions, 9 deletions
diff --git a/commands/ubi.c b/commands/ubi.c index 26b521f374..4c445d2216 100644 --- a/commands/ubi.c +++ b/commands/ubi.c @@ -9,6 +9,7 @@ #include <linux/kernel.h> #include <linux/stat.h> #include <linux/mtd/mtd-abi.h> +#include <linux/mtd/ubi.h> #include <mtd/ubi-user.h> #include <mtd/ubi-media.h> @@ -104,6 +105,7 @@ static int do_ubimkvol(int argc, char *argv[]) struct ubi_mkvol_req req; int fd, ret; uint64_t size; + uint32_t ubinum; req.vol_type = UBI_DYNAMIC_VOLUME; @@ -140,9 +142,14 @@ static int do_ubimkvol(int argc, char *argv[]) return 1; } - ret = ioctl(fd, UBI_IOCMKVOL, &req); - if (ret) - printf("failed to create: %s\n", strerror(-ret)); + ret = ioctl(fd, UBI_IOCGETUBINUM, &ubinum); + if (ret) { + printf("failed to get ubinum: %s\n", strerror(-ret)); + goto err; + } + + ret = ubi_api_create_volume(ubinum, &req); +err: close(fd); return ret ? 1 : 0; @@ -272,24 +279,38 @@ BAREBOX_CMD_END static int do_ubirmvol(int argc, char *argv[]) { - struct ubi_mkvol_req req; + struct ubi_volume_desc *desc; + uint32_t ubinum; int fd, ret; if (argc != 3) return COMMAND_ERROR_USAGE; - strncpy(req.name, argv[2], UBI_VOL_NAME_MAX); - req.name[UBI_VOL_NAME_MAX] = 0; - fd = open(argv[1], O_WRONLY); if (fd < 0) { perror("open"); return 1; } - ret = ioctl(fd, UBI_IOCRMVOL, &req); + ret = ioctl(fd, UBI_IOCGETUBINUM, &ubinum); + if (ret) { + printf("failed to get ubinum: %s\n", strerror(-ret)); + goto err; + } + + desc = ubi_open_volume_nm(ubinum, argv[2], UBI_EXCLUSIVE); + if (IS_ERR(desc)) { + ret = PTR_ERR(desc); + printf("failed to open volume %s: %s\n", argv[2], strerror(-ret)); + goto err; + } + + ret = ubi_api_remove_volume(desc, 0); if (ret) - printf("failed to delete: %s\n", strerror(-ret)); + printf("failed to remove volume %s: %s\n", argv[2], strerror(-ret)); + + ubi_close_volume(desc); +err: close(fd); return ret ? 1 : 0; @@ -306,3 +327,80 @@ BAREBOX_CMD_START(ubirmvol) BAREBOX_CMD_GROUP(CMD_GRP_PART) BAREBOX_CMD_HELP(cmd_ubirmvol_help) BAREBOX_CMD_END + +static int get_vol_id(u32 ubi_num, const char *name) +{ + struct ubi_volume_desc *desc; + struct ubi_volume_info vi; + + desc = ubi_open_volume_nm(ubi_num, name, UBI_READONLY); + if(IS_ERR(desc)) + return PTR_ERR(desc); + + ubi_get_volume_info(desc, &vi); + ubi_close_volume(desc); + + return vi.vol_id; +}; + +static int do_ubirename(int argc, char *argv[]) +{ + struct ubi_rnvol_req req; + u32 ubi_num; + int i, j, fd, ret; + + if ((argc < 4) || (argc % 2)) + return COMMAND_ERROR_USAGE; + + req.count = (argc / 2) - 1; + if (req.count > UBI_MAX_RNVOL) { + printf("too many volume renames. (max: %u)\n", UBI_MAX_RNVOL); + return COMMAND_ERROR_USAGE; + } + + fd = open(argv[1], O_WRONLY); + if (fd < 0) { + perror("unable to open the UBI device"); + return 1; + } + + ret = ioctl(fd, UBI_IOCGETUBINUM, &ubi_num); + + close(fd); + + if (ret) { + printf("failed to get ubi num for %s: %s\n", argv[1], strerror(-ret)); + return 1; + } + + for (i = 2, j = 0; i < argc; ++j, i += 2) { + req.ents[j].vol_id = get_vol_id(ubi_num, argv[i]); + + if (req.ents[j].vol_id < 0) { + printf("Volume '%s' does not exist on %s\n", argv[i], argv[1]); + ret = -EINVAL; + goto err; + } + + strncpy(req.ents[j].name, argv[i + 1], UBI_MAX_VOLUME_NAME); + req.ents[j].name_len = strlen(req.ents[j].name); + } + + ret = ubi_api_rename_volumes(ubi_num, &req); + if (ret) + printf("failed to rename: %s", strerror(-ret)); +err: + return ret ? 1 : 0; +}; + +BAREBOX_CMD_HELP_START(ubirename) +BAREBOX_CMD_HELP_TEXT("Rename UBI volume(s) from UBIDEV") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(ubirename) + .cmd = do_ubirename, + BAREBOX_CMD_DESC("rename UBI volume(s)") + BAREBOX_CMD_OPTS("UBIDEV OLD_NAME NEW_NAME [OLD_NAME NEW_NAME ...]") + BAREBOX_CMD_GROUP(CMD_GRP_PART) + BAREBOX_CMD_HELP(cmd_ubirename_help) +BAREBOX_CMD_END |