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 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 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 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