xref: /illumos-gate/usr/src/lib/fm/topo/libtopo/common/topo_subr.c (revision 7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fe)
1*7aec1d6eScindi /*
2*7aec1d6eScindi  * CDDL HEADER START
3*7aec1d6eScindi  *
4*7aec1d6eScindi  * The contents of this file are subject to the terms of the
5*7aec1d6eScindi  * Common Development and Distribution License, Version 1.0 only
6*7aec1d6eScindi  * (the "License").  You may not use this file except in compliance
7*7aec1d6eScindi  * with the License.
8*7aec1d6eScindi  *
9*7aec1d6eScindi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7aec1d6eScindi  * or http://www.opensolaris.org/os/licensing.
11*7aec1d6eScindi  * See the License for the specific language governing permissions
12*7aec1d6eScindi  * and limitations under the License.
13*7aec1d6eScindi  *
14*7aec1d6eScindi  * When distributing Covered Code, include this CDDL HEADER in each
15*7aec1d6eScindi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7aec1d6eScindi  * If applicable, add the following below this CDDL HEADER, with the
17*7aec1d6eScindi  * fields enclosed by brackets "[]" replaced with your own identifying
18*7aec1d6eScindi  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7aec1d6eScindi  *
20*7aec1d6eScindi  * CDDL HEADER END
21*7aec1d6eScindi  */
22*7aec1d6eScindi 
23*7aec1d6eScindi /*
24*7aec1d6eScindi  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
25*7aec1d6eScindi  * Use is subject to license terms.
26*7aec1d6eScindi  */
27*7aec1d6eScindi 
28*7aec1d6eScindi #pragma ident	"%Z%%M%	%I%	%E% SMI"
29*7aec1d6eScindi 
30*7aec1d6eScindi #include <alloca.h>
31*7aec1d6eScindi #include <syslog.h>
32*7aec1d6eScindi #include <strings.h>
33*7aec1d6eScindi 
34*7aec1d6eScindi #include <topo_error.h>
35*7aec1d6eScindi #include <topo_subr.h>
36*7aec1d6eScindi 
37*7aec1d6eScindi struct _rwlock;
38*7aec1d6eScindi struct _lwp_mutex;
39*7aec1d6eScindi 
40*7aec1d6eScindi int _topo_debug = 0;	/* debug messages enabled (off) */
41*7aec1d6eScindi int _topo_dbout = 0;	/* debug messages output mode */
42*7aec1d6eScindi 
43*7aec1d6eScindi int
44*7aec1d6eScindi topo_rw_read_held(pthread_rwlock_t *lock)
45*7aec1d6eScindi {
46*7aec1d6eScindi 	extern int _rw_read_held(struct _rwlock *);
47*7aec1d6eScindi 	return (_rw_read_held((struct _rwlock *)lock));
48*7aec1d6eScindi }
49*7aec1d6eScindi 
50*7aec1d6eScindi int
51*7aec1d6eScindi topo_rw_write_held(pthread_rwlock_t *lock)
52*7aec1d6eScindi {
53*7aec1d6eScindi 	extern int _rw_write_held(struct _rwlock *);
54*7aec1d6eScindi 	return (_rw_write_held((struct _rwlock *)lock));
55*7aec1d6eScindi }
56*7aec1d6eScindi 
57*7aec1d6eScindi int
58*7aec1d6eScindi topo_mutex_held(pthread_mutex_t *lock)
59*7aec1d6eScindi {
60*7aec1d6eScindi 	extern int _mutex_held(struct _lwp_mutex *);
61*7aec1d6eScindi 	return (_mutex_held((struct _lwp_mutex *)lock));
62*7aec1d6eScindi }
63*7aec1d6eScindi 
64*7aec1d6eScindi void
65*7aec1d6eScindi topo_hdl_lock(topo_hdl_t *thp)
66*7aec1d6eScindi {
67*7aec1d6eScindi 	(void) pthread_mutex_lock(&thp->th_lock);
68*7aec1d6eScindi }
69*7aec1d6eScindi 
70*7aec1d6eScindi void
71*7aec1d6eScindi topo_hdl_unlock(topo_hdl_t *thp)
72*7aec1d6eScindi {
73*7aec1d6eScindi 	(void) pthread_mutex_unlock(&thp->th_lock);
74*7aec1d6eScindi }
75*7aec1d6eScindi 
76*7aec1d6eScindi const char *
77*7aec1d6eScindi topo_stability_name(topo_stability_t s)
78*7aec1d6eScindi {
79*7aec1d6eScindi 	switch (s) {
80*7aec1d6eScindi 	case TOPO_STABILITY_INTERNAL:	return ("Internal");
81*7aec1d6eScindi 	case TOPO_STABILITY_PRIVATE:	return ("Private");
82*7aec1d6eScindi 	case TOPO_STABILITY_OBSOLETE:	return ("Obsolete");
83*7aec1d6eScindi 	case TOPO_STABILITY_EXTERNAL:	return ("External");
84*7aec1d6eScindi 	case TOPO_STABILITY_UNSTABLE:	return ("Unstable");
85*7aec1d6eScindi 	case TOPO_STABILITY_EVOLVING:	return ("Evolving");
86*7aec1d6eScindi 	case TOPO_STABILITY_STABLE:	return ("Stable");
87*7aec1d6eScindi 	case TOPO_STABILITY_STANDARD:	return ("Standard");
88*7aec1d6eScindi 	default:			return (NULL);
89*7aec1d6eScindi 	}
90*7aec1d6eScindi }
91*7aec1d6eScindi 
92*7aec1d6eScindi static const topo_debug_mode_t _topo_dbout_modes[] = {
93*7aec1d6eScindi 	{ "stderr", "send debug messages to stderr", TOPO_DBOUT_STDERR },
94*7aec1d6eScindi 	{ "syslog", "send debug messages to syslog", TOPO_DBOUT_SYSLOG },
95*7aec1d6eScindi 	{ NULL, NULL, 0 }
96*7aec1d6eScindi };
97*7aec1d6eScindi 
98*7aec1d6eScindi void
99*7aec1d6eScindi topo_debug_set(topo_hdl_t *thp, int mask, char *dout)
100*7aec1d6eScindi {
101*7aec1d6eScindi 	int i;
102*7aec1d6eScindi 
103*7aec1d6eScindi 	for (i = 0; i < 2; ++i) {
104*7aec1d6eScindi 		if (strcmp(_topo_dbout_modes[i].tdm_name, dout) == 0) {
105*7aec1d6eScindi 			thp->th_dbout = _topo_dbout =
106*7aec1d6eScindi 			    _topo_dbout_modes[i].tdm_mode;
107*7aec1d6eScindi 			thp->th_debug = _topo_debug = mask;
108*7aec1d6eScindi 			topo_dprintf(mask, _topo_dbout_modes[i].tdm_desc);
109*7aec1d6eScindi 		}
110*7aec1d6eScindi 	}
111*7aec1d6eScindi }
112*7aec1d6eScindi 
113*7aec1d6eScindi void
114*7aec1d6eScindi topo_vdprintf(int mask, const char *format, va_list ap)
115*7aec1d6eScindi {
116*7aec1d6eScindi 	char *msg;
117*7aec1d6eScindi 	size_t len;
118*7aec1d6eScindi 	char c;
119*7aec1d6eScindi 
120*7aec1d6eScindi 	if (!(_topo_debug & mask))
121*7aec1d6eScindi 		return;
122*7aec1d6eScindi 
123*7aec1d6eScindi 	len = vsnprintf(&c, 1, format, ap);
124*7aec1d6eScindi 	msg = alloca(len + 2);
125*7aec1d6eScindi 	(void) vsnprintf(msg, len + 1, format, ap);
126*7aec1d6eScindi 
127*7aec1d6eScindi 	if (msg[len - 1] != '\n')
128*7aec1d6eScindi 		(void) strcpy(&msg[len], "\n");
129*7aec1d6eScindi 
130*7aec1d6eScindi 	if (_topo_dbout == TOPO_DBOUT_STDERR)
131*7aec1d6eScindi 		(void) fprintf(stderr, "libtopo DEBUG: %s", msg);
132*7aec1d6eScindi 
133*7aec1d6eScindi 	if (_topo_dbout == TOPO_DBOUT_SYSLOG)
134*7aec1d6eScindi 		syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s", msg);
135*7aec1d6eScindi }
136*7aec1d6eScindi 
137*7aec1d6eScindi /*PRINTFLIKE2*/
138*7aec1d6eScindi void
139*7aec1d6eScindi topo_dprintf(int mask, const char *format, ...)
140*7aec1d6eScindi {
141*7aec1d6eScindi 	va_list ap;
142*7aec1d6eScindi 
143*7aec1d6eScindi 	if (!(_topo_debug & mask))
144*7aec1d6eScindi 		return;
145*7aec1d6eScindi 
146*7aec1d6eScindi 	va_start(ap, format);
147*7aec1d6eScindi 	topo_vdprintf(mask, format, ap);
148*7aec1d6eScindi 	va_end(ap);
149*7aec1d6eScindi }
150*7aec1d6eScindi 
151*7aec1d6eScindi tnode_t *
152*7aec1d6eScindi topo_hdl_root(topo_hdl_t *thp, const char *scheme)
153*7aec1d6eScindi {
154*7aec1d6eScindi 	ttree_t *tp;
155*7aec1d6eScindi 
156*7aec1d6eScindi 	for (tp = topo_list_next(&thp->th_trees); tp != NULL;
157*7aec1d6eScindi 	    tp = topo_list_next(tp)) {
158*7aec1d6eScindi 		if (strcmp(scheme, tp->tt_scheme) == 0)
159*7aec1d6eScindi 			return (tp->tt_root);
160*7aec1d6eScindi 	}
161*7aec1d6eScindi 
162*7aec1d6eScindi 	return (NULL);
163*7aec1d6eScindi }
164