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 /* 27 * For machines that support the openprom, fetch and print the list 28 * of devices that the kernel has fetched from the prom or conjured up. 29 */ 30 31 #include <stdio.h> 32 #include <string.h> 33 #include <stdlib.h> 34 #include <fcntl.h> 35 #include <stdarg.h> 36 #include <libdevinfo.h> 37 38 static char *progname = "sysdef"; 39 extern int devflag; /* SunOS4.x devinfo compatible output */ 40 extern int drvname_flag; /* print out the driver name too */ 41 42 static int _error(char *opt_noperror, ...); 43 static int dump_node(di_node_t node, void *arg); 44 45 void 46 sysdef_devinfo(void) 47 { 48 di_node_t root_node; 49 50 /* take a snapshot of kernel devinfo tree */ 51 if ((root_node = di_init("/", DINFOSUBTREE)) == DI_NODE_NIL) { 52 exit(_error("di_init() failed.")); 53 } 54 55 /* 56 * ...and call di_walk_node to report it out... 57 */ 58 di_walk_node(root_node, DI_WALK_CLDFIRST, NULL, dump_node); 59 60 di_fini(root_node); 61 } 62 63 /* 64 * print out information about this node 65 */ 66 static int 67 dump_node(di_node_t node, void *arg) 68 { 69 int i; 70 char *driver_name; 71 di_node_t tmp; 72 int indent_level = 0; 73 74 /* find indent level */ 75 tmp = node; 76 while ((tmp = di_parent_node(tmp)) != DI_NODE_NIL) 77 indent_level++; 78 79 /* we would start at 0, except that we skip the root node */ 80 if (!devflag) 81 indent_level--; 82 83 for (i = 0; i < indent_level; i++) 84 (void) putchar('\t'); 85 86 if (indent_level >= 0) { 87 if (devflag) { 88 /* 89 * 4.x devinfo(8) compatible.. 90 */ 91 (void) printf("Node '%s', unit #%d", 92 di_node_name(node), 93 di_instance(node)); 94 if (drvname_flag) { 95 if (driver_name = di_driver_name(node)) { 96 (void) printf(" (driver name: %s)", 97 driver_name); 98 } 99 } else if (di_state(node) & DI_DRIVER_DETACHED) { 100 (void) printf(" (no driver)"); 101 } 102 } else { 103 /* 104 * prtconf(8) compatible.. 105 */ 106 (void) printf("%s", di_node_name(node)); 107 if (di_instance(node) >= 0) 108 (void) printf(", instance #%d", 109 di_instance(node)); 110 if (drvname_flag) { 111 if (driver_name = di_driver_name(node)) { 112 (void) printf(" (driver name: %s)", 113 driver_name); 114 } 115 } else if (di_state(node) & DI_DRIVER_DETACHED) { 116 (void) printf(" (driver not attached)"); 117 } 118 } 119 (void) printf("\n"); 120 } 121 return (DI_WALK_CONTINUE); 122 } 123 124 /* 125 * utility routines 126 */ 127 128 /* _error([no_perror, ] fmt [, arg ...]) */ 129 static int 130 _error(char *opt_noperror, ...) 131 { 132 int saved_errno; 133 va_list ap; 134 int no_perror = 0; 135 char *fmt; 136 extern int errno, _doprnt(); 137 138 saved_errno = errno; 139 140 if (progname) 141 (void) fprintf(stderr, "%s: ", progname); 142 143 va_start(ap, opt_noperror); 144 if (opt_noperror == NULL) { 145 no_perror = 1; 146 fmt = va_arg(ap, char *); 147 } else 148 fmt = opt_noperror; 149 (void) _doprnt(fmt, ap, stderr); 150 va_end(ap); 151 152 if (no_perror) 153 (void) fprintf(stderr, "\n"); 154 else { 155 (void) fprintf(stderr, ": "); 156 errno = saved_errno; 157 perror(""); 158 } 159 160 return (1); 161 } 162