To allow easier observability into the newly added cdev alias
functionality, extend devlookup to be able to resolve them.

Signed-off-by: Ahmad Fatoum <a.fat...@pengutronix.de>
---
 commands/Kconfig     |  2 +-
 commands/devlookup.c | 50 +++++++++++++++++++++++++++++++++++++-------
 include/stringlist.h |  6 ++++++
 3 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/commands/Kconfig b/commands/Kconfig
index ca3f13d7e0cc..7eff747ffdb6 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -92,7 +92,7 @@ config CMD_DEVLOOKUP
        help
          Look up device behind device file and its parameters
 
-         devlookup [-v VAR] /dev/DEVICE [parameter]
+         devlookup [-v VAR] [-ka] /dev/DEVICE [parameter]
 
          Detects the device behind a device file and outputs it,
          unless a second argument is given. In that case the device
diff --git a/commands/devlookup.c b/commands/devlookup.c
index 0d4c6e808b60..5877d5f1b82c 100644
--- a/commands/devlookup.c
+++ b/commands/devlookup.c
@@ -9,17 +9,25 @@
 #include <linux/ctype.h>
 #include <environment.h>
 #include <block.h>
+#include <stringlist.h>
+
+static int devlookup_process(struct cdev *cdev, void *sl)
+{
+       string_list_add(sl, cdev->name);
+       return 1;
+}
 
 static int do_devlookup(int argc, char *argv[])
 {
        const char *variable = NULL, *devicefile, *paramname;
-       struct cdev *cdev;
+       struct cdev *cdev = NULL;
        int opt, ret;
-       bool kernelopt = false;
+       bool alias = false, kernelopt = false;
        const char *val;
-       char *buf = NULL;
+       char *aliasbuf = NULL, *buf = NULL;
+       struct string_list sl;
 
-       while ((opt = getopt(argc, argv, "v:k")) > 0) {
+       while ((opt = getopt(argc, argv, "v:ka")) > 0) {
                switch(opt) {
                case 'v':
                        variable = optarg;
@@ -27,6 +35,9 @@ static int do_devlookup(int argc, char *argv[])
                case 'k':
                        kernelopt = true;
                        break;
+               case 'a':
+                       alias = true;
+                       break;
                }
        }
 
@@ -39,12 +50,33 @@ static int do_devlookup(int argc, char *argv[])
        devicefile = argv[0];
        paramname  = argv[1];
 
+       string_list_init(&sl);
+
+       ret = cdev_alias_resolve_for_each(devicefile, devlookup_process, &sl);
+       if (ret < 0)
+               goto out;
+       else if (ret > 1) {
+               aliasbuf = string_list_join(&sl, " ");
+               if (string_list_count(&sl) > 1 && (kernelopt || paramname)) {
+                       printf("Option not supported for multi cdev alias\n");
+                       return COMMAND_ERROR;
+               }
+
+               if (alias) {
+                       ret = cmd_export_val(variable, aliasbuf);
+                       goto out;
+               }
+
+               devicefile = aliasbuf;
+       }
+
        devicefile = devpath_to_name(devicefile);
 
        cdev = cdev_open_by_name(devicefile, O_RDONLY);
        if (!cdev) {
                printf("devlookup: cdev %s not found\n", devicefile);
-               return -ENOENT;
+               ret = -ENOENT;
+               goto out;
        }
 
        if (!cdev->dev) {
@@ -62,8 +94,11 @@ static int do_devlookup(int argc, char *argv[])
 
        ret = cmd_export_val(variable, val);
 out:
+       string_list_free(&sl);
+       free(aliasbuf);
        free(buf);
-       cdev_close(cdev);
+       if (cdev)
+               cdev_close(cdev);
 
        return ret;
 }
@@ -76,12 +111,13 @@ BAREBOX_CMD_HELP_TEXT("")
 BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT ("-v",  "write output to VARIABLE instead of printing it")
 BAREBOX_CMD_HELP_OPT ("-k",  "output kernel rootarg line")
+BAREBOX_CMD_HELP_OPT ("-a",  "output resolution of cdev alias")
 BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(devlookup)
        .cmd            = do_devlookup,
        BAREBOX_CMD_DESC("look up device behind device file and its parameters")
-       BAREBOX_CMD_OPTS("[-v VAR] [-k] /dev/DEVICE [parameter]")
+       BAREBOX_CMD_OPTS("[-v VAR] [-ka] /dev/DEVICE [parameter]")
        BAREBOX_CMD_GROUP(CMD_GRP_SCRIPT)
        BAREBOX_CMD_HELP(cmd_devlookup_help)
 BAREBOX_CMD_END
diff --git a/include/stringlist.h b/include/stringlist.h
index dcfd33c6e064..b964fabd2320 100644
--- a/include/stringlist.h
+++ b/include/stringlist.h
@@ -3,6 +3,7 @@
 #define __STRINGLIST_H
 
 #include <linux/list.h>
+#include <linux/string.h>
 #include <malloc.h>
 
 struct string_list {
@@ -24,6 +25,11 @@ static inline void string_list_init(struct string_list *sl)
        sl->str = NULL;
 }
 
+static inline size_t string_list_count(struct string_list *sl)
+{
+       return list_count_nodes(&sl->list);
+}
+
 static inline void string_list_free(struct string_list *sl)
 {
        struct string_list *entry, *safe;
-- 
2.39.5


Reply via email to