1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright (c) 1990 - 1997, Sun Microsystems, Inc.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 /*
29 * For machines that support the openprom, fetch and print the list
30 * of devices that the kernel has fetched from the prom or conjured up.
31 */
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <fcntl.h>
37 #include <stdarg.h>
38 #include <libdevinfo.h>
39
40 static char *progname = "sysdef";
41 extern int devflag; /* SunOS4.x devinfo compatible output */
42 extern int drvname_flag; /* print out the driver name too */
43
44 static int _error(char *opt_noperror, ...);
45 static int dump_node(di_node_t node, void *arg);
46
47 void
sysdef_devinfo(void)48 sysdef_devinfo(void)
49 {
50 di_node_t root_node;
51
52 /* take a snapshot of kernel devinfo tree */
53 if ((root_node = di_init("/", DINFOSUBTREE)) == DI_NODE_NIL) {
54 exit(_error("di_init() failed."));
55 }
56
57 /*
58 * ...and call di_walk_node to report it out...
59 */
60 di_walk_node(root_node, DI_WALK_CLDFIRST, NULL, dump_node);
61
62 di_fini(root_node);
63 }
64
65 /*
66 * print out information about this node
67 */
68 static int
dump_node(di_node_t node,void * arg)69 dump_node(di_node_t node, void *arg)
70 {
71 int i;
72 char *driver_name;
73 di_node_t tmp;
74 int indent_level = 0;
75
76 /* find indent level */
77 tmp = node;
78 while ((tmp = di_parent_node(tmp)) != DI_NODE_NIL)
79 indent_level++;
80
81 /* we would start at 0, except that we skip the root node */
82 if (!devflag)
83 indent_level--;
84
85 for (i = 0; i < indent_level; i++)
86 (void) putchar('\t');
87
88 if (indent_level >= 0) {
89 if (devflag) {
90 /*
91 * 4.x devinfo(8) compatible..
92 */
93 (void) printf("Node '%s', unit #%d",
94 di_node_name(node),
95 di_instance(node));
96 if (drvname_flag) {
97 if (driver_name = di_driver_name(node)) {
98 (void) printf(" (driver name: %s)",
99 driver_name);
100 }
101 } else if (di_state(node) & DI_DRIVER_DETACHED) {
102 (void) printf(" (no driver)");
103 }
104 } else {
105 /*
106 * prtconf(1M) compatible..
107 */
108 (void) printf("%s", di_node_name(node));
109 if (di_instance(node) >= 0)
110 (void) printf(", instance #%d",
111 di_instance(node));
112 if (drvname_flag) {
113 if (driver_name = di_driver_name(node)) {
114 (void) printf(" (driver name: %s)",
115 driver_name);
116 }
117 } else if (di_state(node) & DI_DRIVER_DETACHED) {
118 (void) printf(" (driver not attached)");
119 }
120 }
121 (void) printf("\n");
122 }
123 return (DI_WALK_CONTINUE);
124 }
125
126 /*
127 * utility routines
128 */
129
130 /* _error([no_perror, ] fmt [, arg ...]) */
131 static int
_error(char * opt_noperror,...)132 _error(char *opt_noperror, ...)
133 {
134 int saved_errno;
135 va_list ap;
136 int no_perror = 0;
137 char *fmt;
138 extern int errno, _doprnt();
139
140 saved_errno = errno;
141
142 if (progname)
143 (void) fprintf(stderr, "%s: ", progname);
144
145 va_start(ap, opt_noperror);
146 if (opt_noperror == NULL) {
147 no_perror = 1;
148 fmt = va_arg(ap, char *);
149 } else
150 fmt = opt_noperror;
151 (void) _doprnt(fmt, ap, stderr);
152 va_end(ap);
153
154 if (no_perror)
155 (void) fprintf(stderr, "\n");
156 else {
157 (void) fprintf(stderr, ": ");
158 errno = saved_errno;
159 perror("");
160 }
161
162 return (1);
163 }
164