diff mbox series

[mtd-utils,1/2] libmtd: Add function to get MTD info by device name

Message ID 20221212180158.57833-2-brandon.maier@collins.com
State Accepted
Delegated to: David Oberhollenzer
Headers show
Series Support referencing MTD devices by name | expand

Commit Message

Brandon Maier Dec. 12, 2022, 6:01 p.m. UTC
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>
---
 include/libmtd.h    | 13 ++++++++-
 lib/libmtd.c        | 68 ++++++++++++++++++++++++++++++++++++++++++++-
 lib/libmtd_int.h    |  1 +
 lib/libmtd_legacy.c | 38 +++++++++++++++++++++++++
 4 files changed, 118 insertions(+), 2 deletions(-)
diff mbox series

Patch

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
@@ -151,6 +151,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
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.
@@ -476,6 +476,58 @@  static int dev_node2num(struct libmtd *lib, const char *node, int *mtd_num)
 	return -1;
 }
 
+/**
+ * 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);
+}