aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Maier <brandon.maier@collins.com>2022-12-12 12:01:57 -0600
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-05-30 11:12:12 +0200
commita527b22f0a30d66d4674624d16f4bb0ffe2e94d0 (patch)
tree6b1433247e68ac7a184d864704c6622b7c979760
parentce791de8e9ded220f39fbfe4cc5a0bd93b1e985f (diff)
libmtd: Add function to get MTD info by device name
This is a convenience function for end users. In some situations it's easier to reference MTD device's by their name then by MTD number, as the name may be more reliable if device partitioning is dynamic or for porting between systems. Signed-off-by: Brandon Maier <brandon.maier@collins.com> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--include/libmtd.h13
-rw-r--r--lib/libmtd.c68
-rw-r--r--lib/libmtd_int.h1
-rw-r--r--lib/libmtd_legacy.c38
4 files changed, 118 insertions, 2 deletions
diff --git a/include/libmtd.h b/include/libmtd.h
index 6ab0de5..f909a16 100644
--- a/include/libmtd.h
+++ b/include/libmtd.h
@@ -130,7 +130,7 @@ int mtd_get_info(libmtd_t desc, struct mtd_info *info);
/**
* mtd_get_dev_info - get information about an MTD device.
* @desc: MTD library descriptor
- * @node: name of the MTD device node
+ * @node: path of the MTD device node
* @mtd: the MTD device information is returned here
*
* This function gets information about MTD device defined by the @node device
@@ -152,6 +152,17 @@ int mtd_get_dev_info(libmtd_t desc, const char *node, struct mtd_dev_info *mtd);
int mtd_get_dev_info1(libmtd_t desc, int mtd_num, struct mtd_dev_info *mtd);
/**
+ * mtd_get_dev_info2 - get information about an MTD device.
+ * @desc: MTD library descriptor
+ * @name: name of the MTD device
+ * @mtd: the MTD device information is returned here
+ *
+ * This function is identical to 'mtd_get_dev_info()' except that it accepts
+ * MTD device's name, not MTD character device.
+ */
+int mtd_get_dev_info2(libmtd_t desc, const char *name, struct mtd_dev_info *mtd);
+
+/**
* mtd_lock - lock eraseblocks.
* @desc: MTD library descriptor
* @mtd: MTD device description object
diff --git a/lib/libmtd.c b/lib/libmtd.c
index 4aee947..f588e09 100644
--- a/lib/libmtd.c
+++ b/lib/libmtd.c
@@ -427,7 +427,7 @@ static int type_str2int(const char *str)
/**
* dev_node2num - find MTD device number by its character device node.
* @lib: MTD library descriptor
- * @node: name of the MTD device node
+ * @node: path of the MTD device node
* @mtd_num: MTD device number is returned here
*
* This function returns %0 in case of success and %-1 in case of failure.
@@ -477,6 +477,58 @@ static int dev_node2num(struct libmtd *lib, const char *node, int *mtd_num)
}
/**
+ * dev_name2num - find MTD device number by its MTD name
+ * @lib: MTD library descriptor
+ * @name: name of the MTD device
+ * @mtd_num: MTD device number is returned here
+ *
+ * This function returns %0 in case of success and %-1 in case of failure.
+ */
+static int dev_name2num(struct libmtd *lib, const char *name, int *mtd_num)
+{
+ struct mtd_info info;
+ char name2[MTD_NAME_MAX + 1];
+ int i, mtd_num_tmp = -1;
+
+ if (mtd_get_info((libmtd_t *)lib, &info))
+ return -1;
+
+ for (i = info.lowest_mtd_num; i <= info.highest_mtd_num; i++) {
+ int ret;
+
+ ret = dev_read_data(lib->mtd_name, i, name2,
+ MTD_NAME_MAX + 1);
+ if (ret < 0) {
+ if (errno == ENOENT)
+ continue;
+ if (!errno)
+ break;
+ return -1;
+ }
+ name2[ret - 1] = '\0';
+
+ if (!strcmp(name, name2)) {
+ // Device name collision
+ if (mtd_num_tmp >= 0) {
+ errmsg("Multiple MTD's found matching name %s", name);
+ errno = ENODEV;
+ return -1;
+ }
+
+ mtd_num_tmp = i;
+ }
+ }
+
+ if (mtd_num_tmp < 0) {
+ errno = ENODEV;
+ return -1;
+ }
+
+ *mtd_num = mtd_num_tmp;
+ return 0;
+}
+
+/**
* sysfs_is_supported - check whether the MTD sub-system supports MTD.
* @lib: MTD library descriptor
*
@@ -817,6 +869,20 @@ int mtd_get_dev_info(libmtd_t desc, const char *node, struct mtd_dev_info *mtd)
return mtd_get_dev_info1(desc, mtd_num, mtd);
}
+int mtd_get_dev_info2(libmtd_t desc, const char *name, struct mtd_dev_info *mtd)
+{
+ int mtd_num;
+ struct libmtd *lib = (struct libmtd *)desc;
+
+ if (!lib->sysfs_supported)
+ return legacy_get_dev_info2(name, mtd);
+
+ if (dev_name2num(lib, name, &mtd_num))
+ return -1;
+
+ return mtd_get_dev_info1(desc, mtd_num, mtd);
+}
+
static inline int mtd_ioctl_error(const struct mtd_dev_info *mtd, int eb,
const char *sreq)
{
diff --git a/lib/libmtd_int.h b/lib/libmtd_int.h
index c0514d2..79200f7 100644
--- a/lib/libmtd_int.h
+++ b/lib/libmtd_int.h
@@ -106,6 +106,7 @@ int legacy_dev_present(int mtd_num);
int legacy_mtd_get_info(struct mtd_info *info);
int legacy_get_dev_info(const char *node, struct mtd_dev_info *mtd);
int legacy_get_dev_info1(int dev_num, struct mtd_dev_info *mtd);
+int legacy_get_dev_info2(const char *name, struct mtd_dev_info *mtd);
int legacy_get_mtd_oobavail(const char *node);
int legacy_get_mtd_oobavail1(int mtd_num);
diff --git a/lib/libmtd_legacy.c b/lib/libmtd_legacy.c
index 4eb4a70..e0ecf49 100644
--- a/lib/libmtd_legacy.c
+++ b/lib/libmtd_legacy.c
@@ -428,3 +428,41 @@ int legacy_get_dev_info1(int mtd_num, struct mtd_dev_info *mtd)
sprintf(node, MTD_DEV_PATT, mtd_num);
return legacy_get_dev_info(node, mtd);
}
+
+/**
+ * legacy_get_dev_info2 - legacy version of `mtd_get_dev_info2()`
+ * @name: name of the MTD device
+ * @mtd: the MTD device information is returned here
+ *
+ * This function is similar to 'mtd_get_dev_info2()' and has the same
+ * conventions.
+ */
+int legacy_get_dev_info2(const char *name, struct mtd_dev_info *mtd)
+{
+ struct proc_parse_info pi;
+ int ret, mtd_num = -1;
+
+ ret = proc_parse_start(&pi);
+ if (ret)
+ return -1;
+
+ while (proc_parse_next(&pi)) {
+ if (!strcmp(name, pi.name)) {
+ // Device name collision
+ if (mtd_num >= 0) {
+ errmsg("Multiple MTD's found matching name %s", name);
+ errno = ENODEV;
+ return -1;
+ }
+
+ mtd_num = pi.mtd_num;
+ }
+ }
+
+ if (mtd_num < 0) {
+ errno = ENODEV;
+ return -1;
+ }
+
+ return legacy_get_dev_info1(mtd_num, mtd);
+}