From 33860097371c3a35cb1aabf29b1af62c096c4a8f Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 21 Dec 2017 18:51:47 +0000 Subject: [PATCH] Implement "-p dev" to print the path to the given device back to the nexus. With redirection, could also be used to test if the device exists in the device tree. Sponsored by: Netflix --- usr.sbin/devinfo/devinfo.8 | 4 +++ usr.sbin/devinfo/devinfo.c | 51 ++++++++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/usr.sbin/devinfo/devinfo.8 b/usr.sbin/devinfo/devinfo.8 index a1743fff3851..876466511cdf 100644 --- a/usr.sbin/devinfo/devinfo.8 +++ b/usr.sbin/devinfo/devinfo.8 @@ -38,6 +38,8 @@ .Op Fl rv .Nm .Fl u +.Nm +.Fl p dev .Sh DESCRIPTION The .Nm @@ -62,6 +64,8 @@ the IRQ consumers together. Display all devices in the driver tree, not just those that are attached or busy. Without this flag, only those devices that have attached are reported. +.It Fl p dev +Display the path of dev back to the root of the device tree. .El .Sh SEE ALSO .Xr systat 1 , diff --git a/usr.sbin/devinfo/devinfo.c b/usr.sbin/devinfo/devinfo.c index 68804bc6ca67..5bc97fe8acef 100644 --- a/usr.sbin/devinfo/devinfo.c +++ b/usr.sbin/devinfo/devinfo.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "devinfo.h" @@ -196,15 +197,47 @@ print_rman(struct devinfo_rman *rman, void *arg __unused) return(0); } +static void __dead2 +usage(void) +{ + fprintf(stderr, "%s\n%s\n%s\n", + "usage: devinfo [-rv]", + " devinfo -u", + " devifno -p dev"); + exit(1); +} + + +static int +print_path(struct devinfo_dev *dev, void *xname) +{ + const char *name = xname; + int rv; + + if (strcmp(dev->dd_name, name) == 0) { + printf("%s", dev->dd_name); + return (1); + } + + rv = devinfo_foreach_device_child(dev, print_path, xname); + if (rv == 1) + printf(" %s", dev->dd_name[0] ? dev->dd_name : "unknown"); + return (rv); +} + int main(int argc, char *argv[]) { struct devinfo_dev *root; int c, uflag; + char *path; uflag = 0; - while ((c = getopt(argc, argv, "ruv")) != -1) { + while ((c = getopt(argc, argv, "p:ruv")) != -1) { switch(c) { + case 'p': + path = optarg; + break; case 'r': rflag++; break; @@ -215,21 +248,25 @@ main(int argc, char *argv[]) vflag++; break; default: - fprintf(stderr, "%s\n%s\n", - "usage: devinfo [-rv]", - " devinfo -u"); - exit(1); + usage(); } } + if (path && (rflag || uflag)) + usage(); + if (devinfo_init()) err(1, "devinfo_init"); if ((root = devinfo_handle_to_device(DEVINFO_ROOT_DEVICE)) == NULL) errx(1, "can't find root device"); - /* print resource usage? */ - if (uflag) { + if (path) { + if (devinfo_foreach_device_child(root, print_path, (void *)path) == 0) + errx(1, "%s: Not found", path); + printf("\n"); + } else if (uflag) { + /* print resource usage? */ devinfo_foreach_rman(print_rman, NULL); } else { /* print device hierarchy */