xref: /illumos-gate/usr/src/lib/fm/topo/libtopo/common/topo_subr.c (revision a07094369b21309434206d9b3601d162693466fc)
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