For OF-enabled platforms with aliases, device file naming is pretty much solved: If there is mmc2 = &something, then we have a mmc2 device and a /dev/mmc2 device file. For other platforms like x86, EFI-provided devices are harder to get ahold of. Add a command to make this straight-forward to do in scripts. The main use of this is probably to access parameters like nt_signature or guid: devlookup /dev/disk0 guid This would print to console, but we have no output capture yet, so add an optional -v VARIABLE parameter as well to allow easy use from scripts. Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> --- v1 -> v2: - fix typo in commit message (Michael) - accept cdev without /dev/ prefix (Sascha) - early exit on cdev without dev, e.g. /dev/zero --- commands/Kconfig | 13 ++++++++ commands/Makefile | 1 + commands/devlookup.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 commands/devlookup.c diff --git a/commands/Kconfig b/commands/Kconfig index c5505321cfd9..037b41155695 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -75,6 +75,19 @@ config CMD_DEVINFO If called with a device path being the argument, devinfo shows more default information about this device and its parameters. +config CMD_DEVLOOKUP + tristate + prompt "devlookup" + help + Look up device behind device file and its parameters + + devlookup [-v VAR] /dev/DEVICE [parameter] + + Detects the device behind a device file and outputs it, + unless a second argument is given. In that case the device + parameter with that name is looked up. Specifying -v VARIABLE + will write output to VARIABLE instead of printing it. + config CMD_DEVUNBIND tristate prompt "devunbind" diff --git a/commands/Makefile b/commands/Makefile index b3b7bafe6b64..0aae8893d696 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -110,6 +110,7 @@ obj-$(CONFIG_CMD_DETECT) += detect.o obj-$(CONFIG_CMD_BOOT) += boot.o obj-$(CONFIG_CMD_DEVINFO) += devinfo.o obj-$(CONFIG_CMD_DEVUNBIND) += devunbind.o +obj-$(CONFIG_CMD_DEVLOOKUP) += devlookup.o obj-$(CONFIG_CMD_DRVINFO) += drvinfo.o obj-$(CONFIG_CMD_READF) += readf.o obj-$(CONFIG_CMD_MENUTREE) += menutree.o diff --git a/commands/devlookup.c b/commands/devlookup.c new file mode 100644 index 000000000000..c361d5b58860 --- /dev/null +++ b/commands/devlookup.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include <common.h> +#include <command.h> +#include <fs.h> +#include <getopt.h> +#include <malloc.h> +#include <linux/stat.h> +#include <linux/ctype.h> +#include <environment.h> + +static int report(const char *variable, const char *val) +{ + if (!val) + return -(errno ?: EINVAL); + + if (variable) + return setenv(variable, val); + + printf("%s\n", val); + return 0; +} + +static int do_devlookup(int argc, char *argv[]) +{ + const char *variable = NULL, *devicefile, *paramname; + struct cdev *cdev; + int opt; + + while ((opt = getopt(argc, argv, "v:")) > 0) { + switch(opt) { + case 'v': + variable = optarg; + break; + } + } + + if (argc - optind == 0 || argc - optind > 2) + return COMMAND_ERROR_USAGE; + + devicefile = argv[optind]; + paramname = argv[optind+1]; + + if (strstarts(devicefile, "/dev/")) + devicefile += sizeof("/dev/") - 1; + + cdev = cdev_by_name(devicefile); + if (!cdev) { + printf("devlookup: cdev %s not found\n", devicefile); + return -ENOENT; + } + + if (!cdev->dev) { + printf("devlookup: cdev %s not associated with a device\n", devicefile); + return -ENODEV; + } + + if (paramname) + return report(variable, dev_get_param(cdev->dev, paramname)); + + return report(variable, dev_name(cdev->dev)); +} + +BAREBOX_CMD_HELP_START(devlookup) +BAREBOX_CMD_HELP_TEXT("Detects the device behind a device file and outputs it,") +BAREBOX_CMD_HELP_TEXT("unless a second argument is given. In that case the device") +BAREBOX_CMD_HELP_TEXT("parameter with that name is looked up. Specifying -v VARIABLE") +BAREBOX_CMD_HELP_TEXT("will write output to VARIABLE instead of printing it") +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] /dev/DEVICE [parameter]") + BAREBOX_CMD_GROUP(CMD_GRP_SCRIPT) + BAREBOX_CMD_HELP(cmd_devlookup_help) +BAREBOX_CMD_END + -- 2.30.2