summaryrefslogtreecommitdiff
path: root/ubi-utils/src/libubi.c
diff options
context:
space:
mode:
Diffstat (limited to 'ubi-utils/src/libubi.c')
-rw-r--r--ubi-utils/src/libubi.c123
1 files changed, 115 insertions, 8 deletions
diff --git a/ubi-utils/src/libubi.c b/ubi-utils/src/libubi.c
index 32d988e..855aa82 100644
--- a/ubi-utils/src/libubi.c
+++ b/ubi-utils/src/libubi.c
@@ -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;