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 /* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 #include <alloca.h> 31 #include <syslog.h> 32 #include <strings.h> 33 34 #include <topo_error.h> 35 #include <topo_subr.h> 36 37 struct _rwlock; 38 struct _lwp_mutex; 39 40 int _topo_debug = 0; /* debug messages enabled (off) */ 41 int _topo_dbout = 0; /* debug messages output mode */ 42 43 int 44 topo_rw_read_held(pthread_rwlock_t *lock) 45 { 46 extern int _rw_read_held(struct _rwlock *); 47 return (_rw_read_held((struct _rwlock *)lock)); 48 } 49 50 int 51 topo_rw_write_held(pthread_rwlock_t *lock) 52 { 53 extern int _rw_write_held(struct _rwlock *); 54 return (_rw_write_held((struct _rwlock *)lock)); 55 } 56 57 int 58 topo_mutex_held(pthread_mutex_t *lock) 59 { 60 extern int _mutex_held(struct _lwp_mutex *); 61 return (_mutex_held((struct _lwp_mutex *)lock)); 62 } 63 64 void 65 topo_hdl_lock(topo_hdl_t *thp) 66 { 67 (void) pthread_mutex_lock(&thp->th_lock); 68 } 69 70 void 71 topo_hdl_unlock(topo_hdl_t *thp) 72 { 73 (void) pthread_mutex_unlock(&thp->th_lock); 74 } 75 76 const char * 77 topo_stability_name(topo_stability_t s) 78 { 79 switch (s) { 80 case TOPO_STABILITY_INTERNAL: return ("Internal"); 81 case TOPO_STABILITY_PRIVATE: return ("Private"); 82 case TOPO_STABILITY_OBSOLETE: return ("Obsolete"); 83 case TOPO_STABILITY_EXTERNAL: return ("External"); 84 case TOPO_STABILITY_UNSTABLE: return ("Unstable"); 85 case TOPO_STABILITY_EVOLVING: return ("Evolving"); 86 case TOPO_STABILITY_STABLE: return ("Stable"); 87 case TOPO_STABILITY_STANDARD: return ("Standard"); 88 default: return (NULL); 89 } 90 } 91 92 static const topo_debug_mode_t _topo_dbout_modes[] = { 93 { "stderr", "send debug messages to stderr", TOPO_DBOUT_STDERR }, 94 { "syslog", "send debug messages to syslog", TOPO_DBOUT_SYSLOG }, 95 { NULL, NULL, 0 } 96 }; 97 98 void 99 topo_debug_set(topo_hdl_t *thp, int mask, char *dout) 100 { 101 int i; 102 103 for (i = 0; i < 2; ++i) { 104 if (strcmp(_topo_dbout_modes[i].tdm_name, dout) == 0) { 105 thp->th_dbout = _topo_dbout = 106 _topo_dbout_modes[i].tdm_mode; 107 thp->th_debug = _topo_debug = mask; 108 topo_dprintf(mask, _topo_dbout_modes[i].tdm_desc); 109 } 110 } 111 } 112 113 void 114 topo_vdprintf(int mask, const char *format, va_list ap) 115 { 116 char *msg; 117 size_t len; 118 char c; 119 120 if (!(_topo_debug & mask)) 121 return; 122 123 len = vsnprintf(&c, 1, format, ap); 124 msg = alloca(len + 2); 125 (void) vsnprintf(msg, len + 1, format, ap); 126 127 if (msg[len - 1] != '\n') 128 (void) strcpy(&msg[len], "\n"); 129 130 if (_topo_dbout == TOPO_DBOUT_STDERR) 131 (void) fprintf(stderr, "libtopo DEBUG: %s", msg); 132 133 if (_topo_dbout == TOPO_DBOUT_SYSLOG) 134 syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s", msg); 135 } 136 137 /*PRINTFLIKE2*/ 138 void 139 topo_dprintf(int mask, const char *format, ...) 140 { 141 va_list ap; 142 143 if (!(_topo_debug & mask)) 144 return; 145 146 va_start(ap, format); 147 topo_vdprintf(mask, format, ap); 148 va_end(ap); 149 } 150 151 tnode_t * 152 topo_hdl_root(topo_hdl_t *thp, const char *scheme) 153 { 154 ttree_t *tp; 155 156 for (tp = topo_list_next(&thp->th_trees); tp != NULL; 157 tp = topo_list_next(tp)) { 158 if (strcmp(scheme, tp->tt_scheme) == 0) 159 return (tp->tt_root); 160 } 161 162 return (NULL); 163 } 164