aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/devinfo/devinfo.c
diff options
context:
space:
mode:
authorMike Smith <msmith@FreeBSD.org>2001-04-21 00:13:25 +0000
committerMike Smith <msmith@FreeBSD.org>2001-04-21 00:13:25 +0000
commitce7894ee6de119e317ba7b5dec14443b9c7569d1 (patch)
tree558a49eb441f38c75c37d27302c5ca2458da910d /usr.sbin/devinfo/devinfo.c
parentbd2bae03edef4300809bfca0d5208ec75c2b297e (diff)
downloadsrc-ce7894ee6de119e317ba7b5dec14443b9c7569d1.tar.gz
src-ce7894ee6de119e317ba7b5dec14443b9c7569d1.zip
Simple tool to print the device tree and resource usage by devices. Also
serves as an example of libdevinfo usage.
Notes
Notes: svn path=/head/; revision=75752
Diffstat (limited to 'usr.sbin/devinfo/devinfo.c')
-rw-r--r--usr.sbin/devinfo/devinfo.c214
1 files changed, 214 insertions, 0 deletions
diff --git a/usr.sbin/devinfo/devinfo.c b/usr.sbin/devinfo/devinfo.c
new file mode 100644
index 000000000000..6f9bc5b15adf
--- /dev/null
+++ b/usr.sbin/devinfo/devinfo.c
@@ -0,0 +1,214 @@
+/*-
+ * Copyright (c) 2000, 2001 Michael Smith
+ * Copyright (c) 2000 BSDi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Print information about system device configuration.
+ */
+
+#include <sys/types.h>
+#include <err.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "devinfo.h"
+
+int rflag;
+
+struct indent_arg
+{
+ int indent;
+ void *arg;
+};
+
+/*
+ * Print a resource.
+ */
+void
+print_resource(struct devinfo_res *res)
+{
+ struct devinfo_rman *rman;
+ int hexmode;
+
+ rman = devinfo_handle_to_rman(res->dr_rman);
+ hexmode = (rman->dm_size > 100) || (rman->dm_size == 0);
+ printf(hexmode ? "0x%lx" : "%lu", res->dr_start);
+ if (res->dr_size > 1)
+ printf(hexmode ? "-0x%lx" : "-%lu",
+ res->dr_start + res->dr_size - 1);
+}
+
+/*
+ * Print resource information if this resource matches the
+ * given device.
+ *
+ * If the given indent is 0, return an indicator that a matching
+ * resource exists.
+ */
+int
+print_device_matching_resource(struct devinfo_res *res, void *arg)
+{
+ struct indent_arg *ia = (struct indent_arg *)arg;
+ struct devinfo_dev *dev = (struct devinfo_dev *)ia->arg;
+ int i;
+
+ if (devinfo_handle_to_device(res->dr_device) == dev) {
+ /* in 'detect' mode, found a match */
+ if (ia->indent == 0)
+ return(1);
+ for (i = 0; i < ia->indent; i++)
+ printf(" ");
+ print_resource(res);
+ printf("\n");
+ }
+ return(0);
+}
+
+/*
+ * Print resource information for this device and resource manager.
+ */
+int
+print_device_rman_resources(struct devinfo_rman *rman, void *arg)
+{
+ struct indent_arg *ia = (struct indent_arg *)arg;
+ struct devinfo_dev *dev;
+ int indent, i;
+
+ indent = ia->indent;
+ dev = (struct devinfo_dev *)ia->arg;
+
+ /* check whether there are any resources matching this device */
+ ia->indent = 0;
+ if (devinfo_foreach_rman_resource(rman,
+ print_device_matching_resource, ia) != 0) {
+
+ /* there are, print header */
+ for (i = 0; i < indent; i++)
+ printf(" ");
+ printf("%s:\n", rman->dm_desc);
+
+ /* print resources */
+ ia->indent = indent + 4;
+ devinfo_foreach_rman_resource(rman,
+ print_device_matching_resource, ia);
+ }
+ ia->indent = indent;
+ return(0);
+}
+
+/*
+ * Print information about a device.
+ */
+int
+print_device(struct devinfo_dev *dev, void *arg)
+{
+ struct indent_arg ia;
+ int i, indent;
+
+ if (dev->dd_name[0] != 0) {
+ indent = (int)arg;
+ for (i = 0; i < indent; i++)
+ printf(" ");
+ printf("%s\n", dev->dd_name);
+ if (rflag) {
+ ia.indent = indent + 4;
+ ia.arg = dev;
+ devinfo_foreach_rman(print_device_rman_resources,
+ (void *)&ia);
+ }
+ }
+
+ return(devinfo_foreach_device_child(dev, print_device,
+ (void *)(indent + 2)));
+}
+
+/*
+ * Print information about a resource under a resource manager.
+ */
+int
+print_rman_resource(struct devinfo_res *res, void *arg)
+{
+ struct devinfo_dev *dev;
+
+ printf(" ");
+ print_resource(res);
+ dev = devinfo_handle_to_device(res->dr_device);
+ if ((dev != NULL) && (dev->dd_name[0] != 0)) {
+ printf(" (%s)", dev->dd_name);
+ } else {
+ printf(" ----");
+ }
+ printf("\n");
+ return(0);
+}
+
+/*
+ * Print information about a resource manager.
+ */
+int
+print_rman(struct devinfo_rman *rman, void *arg)
+{
+ printf("%s:\n", rman->dm_desc);
+ devinfo_foreach_rman_resource(rman, print_rman_resource, 0);
+ return(0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct devinfo_dev *root;
+ int c, uflag;
+
+ uflag = 0;
+ while ((c = getopt(argc, argv, "ru")) != -1) {
+ switch(c) {
+ case 'r':
+ rflag++;
+ break;
+ case 'u':
+ uflag++;
+ break;
+ default:
+ errx(1, "usage: %s [-ru]", argv[0]);
+ }
+ }
+
+ 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) {
+ devinfo_foreach_rman(print_rman, NULL);
+ } else {
+ /* print device hierarchy */
+ devinfo_foreach_device_child(root, print_device, (void *)0);
+ }
+ return(0);
+}