xref: /illumos-gate/usr/src/lib/fm/topo/libtopo/common/topo_subr.c (revision c559157643fef9f9afb0414e00a3579407ba3052)
17aec1d6eScindi /*
27aec1d6eScindi  * CDDL HEADER START
37aec1d6eScindi  *
47aec1d6eScindi  * The contents of this file are subject to the terms of the
574a31ce6Stimh  * Common Development and Distribution License (the "License").
674a31ce6Stimh  * You may not use this file except in compliance with the License.
77aec1d6eScindi  *
87aec1d6eScindi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97aec1d6eScindi  * or http://www.opensolaris.org/os/licensing.
107aec1d6eScindi  * See the License for the specific language governing permissions
117aec1d6eScindi  * and limitations under the License.
127aec1d6eScindi  *
137aec1d6eScindi  * When distributing Covered Code, include this CDDL HEADER in each
147aec1d6eScindi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157aec1d6eScindi  * If applicable, add the following below this CDDL HEADER, with the
167aec1d6eScindi  * fields enclosed by brackets "[]" replaced with your own identifying
177aec1d6eScindi  * information: Portions Copyright [yyyy] [name of copyright owner]
187aec1d6eScindi  *
197aec1d6eScindi  * CDDL HEADER END
207aec1d6eScindi  */
217aec1d6eScindi 
227aec1d6eScindi /*
238393544eSHyon Kim  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
247aec1d6eScindi  */
258522c52aSRob Johnston /*
26*c5591576SRob Johnston  * Copyright 2020 Joyent, Inc.
278522c52aSRob Johnston  */
287aec1d6eScindi 
297aec1d6eScindi #include <alloca.h>
300eb822a1Scindi #include <ctype.h>
310eb822a1Scindi #include <limits.h>
327aec1d6eScindi #include <syslog.h>
337aec1d6eScindi #include <strings.h>
340eb822a1Scindi #include <unistd.h>
358522c52aSRob Johnston #include <sys/fm/protocol.h>
368522c52aSRob Johnston #include <sys/systeminfo.h>
378522c52aSRob Johnston #include <sys/utsname.h>
387aec1d6eScindi 
397aec1d6eScindi #include <topo_error.h>
40*c5591576SRob Johnston #include <topo_digraph.h>
417aec1d6eScindi #include <topo_subr.h>
427aec1d6eScindi 
437aec1d6eScindi void
447aec1d6eScindi topo_hdl_lock(topo_hdl_t *thp)
457aec1d6eScindi {
467aec1d6eScindi 	(void) pthread_mutex_lock(&thp->th_lock);
477aec1d6eScindi }
487aec1d6eScindi 
497aec1d6eScindi void
507aec1d6eScindi topo_hdl_unlock(topo_hdl_t *thp)
517aec1d6eScindi {
527aec1d6eScindi 	(void) pthread_mutex_unlock(&thp->th_lock);
537aec1d6eScindi }
547aec1d6eScindi 
557aec1d6eScindi const char *
560eb822a1Scindi topo_stability2name(topo_stability_t s)
577aec1d6eScindi {
587aec1d6eScindi 	switch (s) {
590eb822a1Scindi 	case TOPO_STABILITY_INTERNAL:	return (TOPO_STABSTR_INTERNAL);
600eb822a1Scindi 	case TOPO_STABILITY_PRIVATE:	return (TOPO_STABSTR_PRIVATE);
610eb822a1Scindi 	case TOPO_STABILITY_OBSOLETE:	return (TOPO_STABSTR_OBSOLETE);
620eb822a1Scindi 	case TOPO_STABILITY_EXTERNAL:	return (TOPO_STABSTR_EXTERNAL);
630eb822a1Scindi 	case TOPO_STABILITY_UNSTABLE:	return (TOPO_STABSTR_UNSTABLE);
640eb822a1Scindi 	case TOPO_STABILITY_EVOLVING:	return (TOPO_STABSTR_EVOLVING);
650eb822a1Scindi 	case TOPO_STABILITY_STABLE:	return (TOPO_STABSTR_STABLE);
660eb822a1Scindi 	case TOPO_STABILITY_STANDARD:	return (TOPO_STABSTR_STANDARD);
670eb822a1Scindi 	default:			return (TOPO_STABSTR_UNKNOWN);
687aec1d6eScindi 	}
697aec1d6eScindi }
707aec1d6eScindi 
710eb822a1Scindi topo_stability_t
720eb822a1Scindi topo_name2stability(const char *name)
730eb822a1Scindi {
740eb822a1Scindi 	if (strcmp(name, TOPO_STABSTR_INTERNAL) == 0)
750eb822a1Scindi 		return (TOPO_STABILITY_INTERNAL);
760eb822a1Scindi 	else if (strcmp(name, TOPO_STABSTR_PRIVATE) == 0)
770eb822a1Scindi 		return (TOPO_STABILITY_PRIVATE);
780eb822a1Scindi 	else if (strcmp(name, TOPO_STABSTR_OBSOLETE) == 0)
790eb822a1Scindi 		return (TOPO_STABILITY_OBSOLETE);
800eb822a1Scindi 	else if (strcmp(name, TOPO_STABSTR_EXTERNAL) == 0)
810eb822a1Scindi 		return (TOPO_STABILITY_EXTERNAL);
820eb822a1Scindi 	else if (strcmp(name, TOPO_STABSTR_UNSTABLE) == 0)
830eb822a1Scindi 		return (TOPO_STABILITY_UNSTABLE);
840eb822a1Scindi 	else if (strcmp(name, TOPO_STABSTR_EVOLVING) == 0)
850eb822a1Scindi 		return (TOPO_STABILITY_EVOLVING);
860eb822a1Scindi 	else if (strcmp(name, TOPO_STABSTR_STABLE) == 0)
870eb822a1Scindi 		return (TOPO_STABILITY_STABLE);
880eb822a1Scindi 	else if (strcmp(name, TOPO_STABSTR_STANDARD) == 0)
890eb822a1Scindi 		return (TOPO_STABILITY_STANDARD);
900eb822a1Scindi 
910eb822a1Scindi 	return (TOPO_STABILITY_UNKNOWN);
920eb822a1Scindi }
930eb822a1Scindi 
947aec1d6eScindi static const topo_debug_mode_t _topo_dbout_modes[] = {
957aec1d6eScindi 	{ "stderr", "send debug messages to stderr", TOPO_DBOUT_STDERR },
967aec1d6eScindi 	{ "syslog", "send debug messages to syslog", TOPO_DBOUT_SYSLOG },
977aec1d6eScindi 	{ NULL, NULL, 0 }
987aec1d6eScindi };
997aec1d6eScindi 
1000eb822a1Scindi static const topo_debug_mode_t _topo_dbflag_modes[] = {
1010eb822a1Scindi 	{ "error", "error handling debug messages enabled", TOPO_DBG_ERR },
1020eb822a1Scindi 	{ "module", "module debug messages enabled", TOPO_DBG_MOD },
1030eb822a1Scindi 	{ "modulesvc", "module services debug messages enabled",
1040eb822a1Scindi 	    TOPO_DBG_MODSVC },
1050eb822a1Scindi 	{ "walk", "walker subsystem debug messages enabled", TOPO_DBG_WALK },
1060eb822a1Scindi 	{ "xml", "xml file parsing messages enabled", TOPO_DBG_XML },
1078393544eSHyon Kim 	{ "devinfoforce", "devinfo DINFOFORCE snapshot used", TOPO_DBG_FORCE },
1080eb822a1Scindi 	{ "all", "all debug modes enabled", TOPO_DBG_ALL},
1090eb822a1Scindi 	{ NULL, NULL, 0 }
1100eb822a1Scindi };
1110eb822a1Scindi 
1127aec1d6eScindi void
1130eb822a1Scindi env_process_value(topo_hdl_t *thp, const char *begin, const char *end)
1147aec1d6eScindi {
1150eb822a1Scindi 	char buf[MAXNAMELEN];
1160eb822a1Scindi 	size_t count;
1170eb822a1Scindi 	topo_debug_mode_t *dbp;
1180eb822a1Scindi 
1190eb822a1Scindi 	while (begin < end && isspace(*begin))
1200eb822a1Scindi 		begin++;
1210eb822a1Scindi 
1220eb822a1Scindi 	while (begin < end && isspace(*(end - 1)))
1230eb822a1Scindi 		end--;
1240eb822a1Scindi 
1250eb822a1Scindi 	if (begin >= end)
1260eb822a1Scindi 		return;
1270eb822a1Scindi 
1280eb822a1Scindi 	count = end - begin;
1290eb822a1Scindi 	count += 1;
1300eb822a1Scindi 
1310eb822a1Scindi 	if (count > sizeof (buf))
1320eb822a1Scindi 		return;
1330eb822a1Scindi 
1340eb822a1Scindi 	(void) snprintf(buf, count, "%s", begin);
1350eb822a1Scindi 
1360eb822a1Scindi 	for (dbp = (topo_debug_mode_t *)_topo_dbflag_modes;
1370eb822a1Scindi 	    dbp->tdm_name != NULL; ++dbp) {
1380eb822a1Scindi 		if (strcmp(buf, dbp->tdm_name) == 0)
1390eb822a1Scindi 			thp->th_debug |= dbp->tdm_mode;
1400eb822a1Scindi 	}
1410eb822a1Scindi }
1420eb822a1Scindi 
1430eb822a1Scindi void
1440eb822a1Scindi topo_debug_set(topo_hdl_t *thp, const char *dbmode, const char *dout)
1450eb822a1Scindi {
1460eb822a1Scindi 	char *end, *value, *next;
1470eb822a1Scindi 	topo_debug_mode_t *dbp;
1480eb822a1Scindi 
1490eb822a1Scindi 	topo_hdl_lock(thp);
1500eb822a1Scindi 	value = (char *)dbmode;
1510eb822a1Scindi 
1520eb822a1Scindi 	for (end = (char *)dbmode; *end != '\0'; value = next) {
1530eb822a1Scindi 		end = strchr(value, ',');
1540eb822a1Scindi 		if (end != NULL)
1550eb822a1Scindi 			next = end + 1;	/* skip the comma */
1560eb822a1Scindi 		else
1570eb822a1Scindi 			next = end = value + strlen(value);
1580eb822a1Scindi 
1590eb822a1Scindi 		env_process_value(thp, value, end);
1600eb822a1Scindi 	}
1610eb822a1Scindi 
1620eb822a1Scindi 	if (dout == NULL) {
1630eb822a1Scindi 		topo_hdl_unlock(thp);
1640eb822a1Scindi 		return;
1657aec1d6eScindi 	}
1660eb822a1Scindi 
1670eb822a1Scindi 	for (dbp = (topo_debug_mode_t *)_topo_dbout_modes;
1680eb822a1Scindi 	    dbp->tdm_name != NULL; ++dbp) {
1690eb822a1Scindi 		if (strcmp(dout, dbp->tdm_name) == 0)
1701e95bfe1SRob Johnston 			thp->th_dbout = dbp->tdm_mode;
1710eb822a1Scindi 	}
1720eb822a1Scindi 	topo_hdl_unlock(thp);
1737aec1d6eScindi }
1747aec1d6eScindi 
1757aec1d6eScindi void
1761de1e652SRob Johnston topo_vdprintf(topo_hdl_t *thp, const char *mod, const char *format, va_list ap)
1777aec1d6eScindi {
1787aec1d6eScindi 	char *msg;
1797aec1d6eScindi 	size_t len;
1807aec1d6eScindi 	char c;
1817aec1d6eScindi 
1827aec1d6eScindi 	len = vsnprintf(&c, 1, format, ap);
1837aec1d6eScindi 	msg = alloca(len + 2);
1847aec1d6eScindi 	(void) vsnprintf(msg, len + 1, format, ap);
1857aec1d6eScindi 
1867aec1d6eScindi 	if (msg[len - 1] != '\n')
1877aec1d6eScindi 		(void) strcpy(&msg[len], "\n");
1887aec1d6eScindi 
1890eb822a1Scindi 	if (thp->th_dbout == TOPO_DBOUT_SYSLOG) {
1900eb822a1Scindi 		if (mod == NULL) {
1910eb822a1Scindi 			syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s", msg);
1920eb822a1Scindi 		} else {
1930eb822a1Scindi 			syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s: %s",
1940eb822a1Scindi 			    mod, msg);
1950eb822a1Scindi 		}
1960eb822a1Scindi 	} else {
1970eb822a1Scindi 		if (mod == NULL) {
1980eb822a1Scindi 			(void) fprintf(stderr, "libtopo DEBUG: %s", msg);
1990eb822a1Scindi 		} else {
2000eb822a1Scindi 			(void) fprintf(stderr, "libtopo DEBUG: %s: %s", mod,
2010eb822a1Scindi 			    msg);
2020eb822a1Scindi 		}
2030eb822a1Scindi 	}
2047aec1d6eScindi }
2057aec1d6eScindi 
2060eb822a1Scindi /*PRINTFLIKE3*/
2077aec1d6eScindi void
2080eb822a1Scindi topo_dprintf(topo_hdl_t *thp, int mask, const char *format, ...)
2097aec1d6eScindi {
2107aec1d6eScindi 	va_list ap;
2117aec1d6eScindi 
2121de1e652SRob Johnston 	if (!(thp->th_debug & mask))
2131de1e652SRob Johnston 		return;
2141de1e652SRob Johnston 
2157aec1d6eScindi 	va_start(ap, format);
2161de1e652SRob Johnston 	topo_vdprintf(thp, NULL, format, ap);
2177aec1d6eScindi 	va_end(ap);
2187aec1d6eScindi }
2197aec1d6eScindi 
2207aec1d6eScindi tnode_t *
2217aec1d6eScindi topo_hdl_root(topo_hdl_t *thp, const char *scheme)
2227aec1d6eScindi {
2237aec1d6eScindi 	ttree_t *tp;
224*c5591576SRob Johnston 	topo_digraph_t *tdg;
2257aec1d6eScindi 
2267aec1d6eScindi 	for (tp = topo_list_next(&thp->th_trees); tp != NULL;
2277aec1d6eScindi 	    tp = topo_list_next(tp)) {
2287aec1d6eScindi 		if (strcmp(scheme, tp->tt_scheme) == 0)
2297aec1d6eScindi 			return (tp->tt_root);
2307aec1d6eScindi 	}
231*c5591576SRob Johnston 	for (tdg = topo_list_next(&thp->th_digraphs); tdg != NULL;
232*c5591576SRob Johnston 	    tdg = topo_list_next(tdg)) {
233*c5591576SRob Johnston 		if (strcmp(scheme, tdg->tdg_scheme) == 0)
234*c5591576SRob Johnston 			return (tdg->tdg_rootnode);
235*c5591576SRob Johnston 	}
2367aec1d6eScindi 
2377aec1d6eScindi 	return (NULL);
2387aec1d6eScindi }
23974a31ce6Stimh 
24074a31ce6Stimh /*
24174a31ce6Stimh  * buf_append -- Append str to buf (if it's non-NULL).  Place prepend
24274a31ce6Stimh  * in buf in front of str and append behind it (if they're non-NULL).
24374a31ce6Stimh  * Continue to update size even if we run out of space to actually
24474a31ce6Stimh  * stuff characters in the buffer.
24574a31ce6Stimh  */
24674a31ce6Stimh void
24774a31ce6Stimh topo_fmristr_build(ssize_t *sz, char *buf, size_t buflen, char *str,
24874a31ce6Stimh     char *prepend, char *append)
24974a31ce6Stimh {
25074a31ce6Stimh 	ssize_t left;
25174a31ce6Stimh 
25274a31ce6Stimh 	if (str == NULL)
25374a31ce6Stimh 		return;
25474a31ce6Stimh 
25574a31ce6Stimh 	if (buflen == 0 || (left = buflen - *sz) < 0)
25674a31ce6Stimh 		left = 0;
25774a31ce6Stimh 
25874a31ce6Stimh 	if (buf != NULL && left != 0)
25974a31ce6Stimh 		buf += *sz;
26074a31ce6Stimh 
26174a31ce6Stimh 	if (prepend == NULL && append == NULL)
26274a31ce6Stimh 		*sz += snprintf(buf, left, "%s", str);
26374a31ce6Stimh 	else if (append == NULL)
26474a31ce6Stimh 		*sz += snprintf(buf, left, "%s%s", prepend, str);
26574a31ce6Stimh 	else if (prepend == NULL)
26674a31ce6Stimh 		*sz += snprintf(buf, left, "%s%s", str, append);
26774a31ce6Stimh 	else
26874a31ce6Stimh 		*sz += snprintf(buf, left, "%s%s%s", prepend, str, append);
26974a31ce6Stimh }
2700eb822a1Scindi 
2710eb822a1Scindi #define	TOPO_PLATFORM_PATH	"%s/usr/platform/%s/lib/fm/topo/%s"
2720eb822a1Scindi #define	TOPO_COMMON_PATH	"%s/usr/lib/fm/topo/%s"
2730eb822a1Scindi 
2740eb822a1Scindi char *
2750eb822a1Scindi topo_search_path(topo_mod_t *mod, const char *rootdir, const char *file)
2760eb822a1Scindi {
2770eb822a1Scindi 	char *pp, sp[PATH_MAX];
2780eb822a1Scindi 	topo_hdl_t *thp = mod->tm_hdl;
2790eb822a1Scindi 
2800eb822a1Scindi 	/*
2810eb822a1Scindi 	 * Search for file name in order of platform, machine and common
2820eb822a1Scindi 	 * topo directories
2830eb822a1Scindi 	 */
2840eb822a1Scindi 	(void) snprintf(sp, PATH_MAX, TOPO_PLATFORM_PATH, rootdir,
2850eb822a1Scindi 	    thp->th_platform, file);
2860eb822a1Scindi 	if (access(sp, F_OK) != 0) {
2870eb822a1Scindi 		(void) snprintf(sp, PATH_MAX, TOPO_PLATFORM_PATH,
2880eb822a1Scindi 		    thp->th_rootdir, thp->th_machine, file);
2890eb822a1Scindi 		if (access(sp, F_OK) != 0) {
2900eb822a1Scindi 			(void) snprintf(sp, PATH_MAX, TOPO_COMMON_PATH,
2910eb822a1Scindi 			    thp->th_rootdir, file);
2920eb822a1Scindi 			if (access(sp, F_OK) != 0) {
2930eb822a1Scindi 				return (NULL);
2940eb822a1Scindi 			}
2950eb822a1Scindi 		}
2960eb822a1Scindi 	}
2970eb822a1Scindi 
2980eb822a1Scindi 	pp = topo_mod_strdup(mod, sp);
2990eb822a1Scindi 
3000eb822a1Scindi 	return (pp);
3010eb822a1Scindi }
30224db4641Seschrock 
30324db4641Seschrock /*
30424db4641Seschrock  * SMBIOS serial numbers can contain characters (particularly ':' and ' ')
30524db4641Seschrock  * that are invalid for the authority and can break FMRI parsing.  We translate
30624db4641Seschrock  * any invalid characters to a safe '-', as well as trimming any leading or
30720c794b3Sgavinm  * trailing whitespace.  Similarly, '/' can be found in some product names
30820c794b3Sgavinm  * so we translate that to '-'.
30924db4641Seschrock  */
31024db4641Seschrock char *
311e3d60c9bSAdrian Frost topo_cleanup_auth_str(topo_hdl_t *thp, const char *begin)
31224db4641Seschrock {
31324db4641Seschrock 	char buf[MAXNAMELEN];
314e3d60c9bSAdrian Frost 	const char *end, *cp;
315e3d60c9bSAdrian Frost 	char *pp;
316e3d60c9bSAdrian Frost 	char c;
317e3d60c9bSAdrian Frost 	int i;
31824db4641Seschrock 
31924db4641Seschrock 	end = begin + strlen(begin);
32024db4641Seschrock 
32124db4641Seschrock 	while (begin < end && isspace(*begin))
32224db4641Seschrock 		begin++;
32324db4641Seschrock 	while (begin < end && isspace(*(end - 1)))
32424db4641Seschrock 		end--;
32524db4641Seschrock 
32624db4641Seschrock 	if (begin >= end)
32724db4641Seschrock 		return (NULL);
32824db4641Seschrock 
329e3d60c9bSAdrian Frost 	cp = begin;
330e3d60c9bSAdrian Frost 	for (i = 0; i < MAXNAMELEN - 1; i++) {
331e3d60c9bSAdrian Frost 		if (cp >= end)
332e3d60c9bSAdrian Frost 			break;
333e3d60c9bSAdrian Frost 		c = *cp;
334e3d60c9bSAdrian Frost 		if (c == ':' || c == '=' || c == '/' || isspace(c) ||
335e3d60c9bSAdrian Frost 		    !isprint(c))
336e3d60c9bSAdrian Frost 			buf[i] = '-';
337e3d60c9bSAdrian Frost 		else
338e3d60c9bSAdrian Frost 			buf[i] = c;
339e3d60c9bSAdrian Frost 		cp++;
340e3d60c9bSAdrian Frost 	}
341e3d60c9bSAdrian Frost 	buf[i] = 0;
34224db4641Seschrock 
34324db4641Seschrock 	pp = topo_hdl_strdup(thp, buf);
34424db4641Seschrock 	return (pp);
34524db4641Seschrock }
346825ba0f2Srobj 
347825ba0f2Srobj void
348825ba0f2Srobj topo_sensor_type_name(uint32_t type, char *buf, size_t len)
349825ba0f2Srobj {
350825ba0f2Srobj 	topo_name_trans_t *ntp;
351825ba0f2Srobj 
352825ba0f2Srobj 	for (ntp = &topo_sensor_type_table[0]; ntp->int_name != NULL; ntp++) {
353825ba0f2Srobj 		if (ntp->int_value == type) {
354825ba0f2Srobj 			(void) strlcpy(buf, ntp->int_name, len);
355825ba0f2Srobj 			return;
356825ba0f2Srobj 		}
357825ba0f2Srobj 	}
358825ba0f2Srobj 
359825ba0f2Srobj 	(void) snprintf(buf, len, "0x%02x", type);
360825ba0f2Srobj }
361825ba0f2Srobj 
362825ba0f2Srobj void
363825ba0f2Srobj topo_sensor_units_name(uint8_t type, char *buf, size_t len)
364825ba0f2Srobj {
365825ba0f2Srobj 	topo_name_trans_t *ntp;
366825ba0f2Srobj 
367825ba0f2Srobj 	for (ntp = &topo_units_type_table[0]; ntp->int_name != NULL; ntp++) {
368825ba0f2Srobj 		if (ntp->int_value == type) {
369825ba0f2Srobj 			(void) strlcpy(buf, ntp->int_name, len);
370825ba0f2Srobj 			return;
371825ba0f2Srobj 		}
372825ba0f2Srobj 	}
373825ba0f2Srobj 
374825ba0f2Srobj 	(void) snprintf(buf, len, "0x%02x", type);
375825ba0f2Srobj }
376825ba0f2Srobj 
377825ba0f2Srobj void
378825ba0f2Srobj topo_led_type_name(uint8_t type, char *buf, size_t len)
379825ba0f2Srobj {
380825ba0f2Srobj 	topo_name_trans_t *ntp;
381825ba0f2Srobj 
382825ba0f2Srobj 	for (ntp = &topo_led_type_table[0]; ntp->int_name != NULL; ntp++) {
383825ba0f2Srobj 		if (ntp->int_value == type) {
384825ba0f2Srobj 			(void) strlcpy(buf, ntp->int_name, len);
385825ba0f2Srobj 			return;
386825ba0f2Srobj 		}
387825ba0f2Srobj 	}
388825ba0f2Srobj 
389825ba0f2Srobj 	(void) snprintf(buf, len, "0x%02x", type);
390825ba0f2Srobj }
391825ba0f2Srobj 
392825ba0f2Srobj void
393825ba0f2Srobj topo_led_state_name(uint8_t type, char *buf, size_t len)
394825ba0f2Srobj {
395825ba0f2Srobj 	topo_name_trans_t *ntp;
396825ba0f2Srobj 
397825ba0f2Srobj 	for (ntp = &topo_led_states_table[0]; ntp->int_name != NULL; ntp++) {
398825ba0f2Srobj 		if (ntp->int_value == type) {
399825ba0f2Srobj 			(void) strlcpy(buf, ntp->int_name, len);
400825ba0f2Srobj 			return;
401825ba0f2Srobj 		}
402825ba0f2Srobj 	}
403825ba0f2Srobj 
404825ba0f2Srobj 	(void) snprintf(buf, len, "0x%02x", type);
405825ba0f2Srobj }
406825ba0f2Srobj 
407825ba0f2Srobj void
408825ba0f2Srobj topo_sensor_state_name(uint32_t sensor_type, uint8_t state, char *buf,
4098522c52aSRob Johnston     size_t len)
410825ba0f2Srobj {
411825ba0f2Srobj 	topo_name_trans_t *ntp;
412825ba0f2Srobj 
413825ba0f2Srobj 	switch (sensor_type) {
414825ba0f2Srobj 		case TOPO_SENSOR_TYPE_PHYSICAL:
415825ba0f2Srobj 			ntp = &topo_sensor_states_physical_table[0];
416825ba0f2Srobj 			break;
417825ba0f2Srobj 		case TOPO_SENSOR_TYPE_PLATFORM:
418825ba0f2Srobj 			ntp = &topo_sensor_states_platform_table[0];
419825ba0f2Srobj 			break;
420825ba0f2Srobj 		case TOPO_SENSOR_TYPE_PROCESSOR:
421825ba0f2Srobj 			ntp = &topo_sensor_states_processor_table[0];
422825ba0f2Srobj 			break;
423825ba0f2Srobj 		case TOPO_SENSOR_TYPE_POWER_SUPPLY:
424825ba0f2Srobj 			ntp = &topo_sensor_states_power_supply_table[0];
425825ba0f2Srobj 			break;
426825ba0f2Srobj 		case TOPO_SENSOR_TYPE_POWER_UNIT:
427825ba0f2Srobj 			ntp = &topo_sensor_states_power_unit_table[0];
428825ba0f2Srobj 			break;
429825ba0f2Srobj 		case TOPO_SENSOR_TYPE_MEMORY:
430825ba0f2Srobj 			ntp = &topo_sensor_states_memory_table[0];
431825ba0f2Srobj 			break;
432825ba0f2Srobj 		case TOPO_SENSOR_TYPE_BAY:
433825ba0f2Srobj 			ntp = &topo_sensor_states_bay_table[0];
434825ba0f2Srobj 			break;
435825ba0f2Srobj 		case TOPO_SENSOR_TYPE_FIRMWARE:
436825ba0f2Srobj 			ntp = &topo_sensor_states_firmware_table[0];
437825ba0f2Srobj 			break;
438825ba0f2Srobj 		case TOPO_SENSOR_TYPE_EVENT_LOG:
439825ba0f2Srobj 			ntp = &topo_sensor_states_event_log_table[0];
440825ba0f2Srobj 			break;
441825ba0f2Srobj 		case TOPO_SENSOR_TYPE_WATCHDOG1:
442825ba0f2Srobj 			ntp = &topo_sensor_states_watchdog1_table[0];
443825ba0f2Srobj 			break;
444825ba0f2Srobj 		case TOPO_SENSOR_TYPE_SYSTEM:
445825ba0f2Srobj 			ntp = &topo_sensor_states_system_table[0];
446825ba0f2Srobj 			break;
447825ba0f2Srobj 		case TOPO_SENSOR_TYPE_CRITICAL:
448825ba0f2Srobj 			ntp = &topo_sensor_states_critical_table[0];
449825ba0f2Srobj 			break;
450825ba0f2Srobj 		case TOPO_SENSOR_TYPE_BUTTON:
451825ba0f2Srobj 			ntp = &topo_sensor_states_button_table[0];
452825ba0f2Srobj 			break;
453825ba0f2Srobj 		case TOPO_SENSOR_TYPE_CABLE:
454825ba0f2Srobj 			ntp = &topo_sensor_states_cable_table[0];
455825ba0f2Srobj 			break;
456825ba0f2Srobj 		case TOPO_SENSOR_TYPE_BOOT_STATE:
457825ba0f2Srobj 			ntp = &topo_sensor_states_boot_state_table[0];
458825ba0f2Srobj 			break;
459825ba0f2Srobj 		case TOPO_SENSOR_TYPE_BOOT_ERROR:
460825ba0f2Srobj 			ntp = &topo_sensor_states_boot_error_table[0];
461825ba0f2Srobj 			break;
462825ba0f2Srobj 		case TOPO_SENSOR_TYPE_BOOT_OS:
463825ba0f2Srobj 			ntp = &topo_sensor_states_boot_os_table[0];
464825ba0f2Srobj 			break;
465825ba0f2Srobj 		case TOPO_SENSOR_TYPE_OS_SHUTDOWN:
466825ba0f2Srobj 			ntp = &topo_sensor_states_os_table[0];
467825ba0f2Srobj 			break;
468825ba0f2Srobj 		case TOPO_SENSOR_TYPE_SLOT:
469825ba0f2Srobj 			ntp = &topo_sensor_states_slot_table[0];
470825ba0f2Srobj 			break;
471825ba0f2Srobj 		case TOPO_SENSOR_TYPE_ACPI:
472825ba0f2Srobj 			ntp = &topo_sensor_states_acpi_table[0];
473825ba0f2Srobj 			break;
474825ba0f2Srobj 		case TOPO_SENSOR_TYPE_WATCHDOG2:
475825ba0f2Srobj 			ntp = &topo_sensor_states_watchdog2_table[0];
476825ba0f2Srobj 			break;
477825ba0f2Srobj 		case TOPO_SENSOR_TYPE_ALERT:
478825ba0f2Srobj 			ntp = &topo_sensor_states_alert_table[0];
479825ba0f2Srobj 			break;
480825ba0f2Srobj 		case TOPO_SENSOR_TYPE_PRESENCE:
481825ba0f2Srobj 			ntp = &topo_sensor_states_presence_table[0];
482825ba0f2Srobj 			break;
483825ba0f2Srobj 		case TOPO_SENSOR_TYPE_LAN:
484825ba0f2Srobj 			ntp = &topo_sensor_states_lan_table[0];
485825ba0f2Srobj 			break;
486825ba0f2Srobj 		case TOPO_SENSOR_TYPE_HEALTH:
487825ba0f2Srobj 			ntp = &topo_sensor_states_health_table[0];
488825ba0f2Srobj 			break;
489825ba0f2Srobj 		case TOPO_SENSOR_TYPE_BATTERY:
490825ba0f2Srobj 			ntp = &topo_sensor_states_battery_table[0];
491825ba0f2Srobj 			break;
492825ba0f2Srobj 		case TOPO_SENSOR_TYPE_AUDIT:
493825ba0f2Srobj 			ntp = &topo_sensor_states_audit_table[0];
494825ba0f2Srobj 			break;
495825ba0f2Srobj 		case TOPO_SENSOR_TYPE_VERSION:
496825ba0f2Srobj 			ntp = &topo_sensor_states_version_table[0];
497825ba0f2Srobj 			break;
498825ba0f2Srobj 		case TOPO_SENSOR_TYPE_FRU_STATE:
499825ba0f2Srobj 			ntp = &topo_sensor_states_fru_state_table[0];
500825ba0f2Srobj 			break;
501825ba0f2Srobj 		case TOPO_SENSOR_TYPE_THRESHOLD_STATE:
502825ba0f2Srobj 			ntp = &topo_sensor_states_thresh_table[0];
503825ba0f2Srobj 			break;
504825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_USAGE:
505825ba0f2Srobj 			ntp = &topo_sensor_states_generic_usage_table[0];
506825ba0f2Srobj 			break;
507825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_STATE:
508825ba0f2Srobj 			ntp = &topo_sensor_states_generic_state_table[0];
509825ba0f2Srobj 			break;
510825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_PREDFAIL:
511825ba0f2Srobj 			ntp = &topo_sensor_states_generic_predfail_table[0];
512825ba0f2Srobj 			break;
513825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_LIMIT:
514825ba0f2Srobj 			ntp = &topo_sensor_states_generic_limit_table[0];
515825ba0f2Srobj 			break;
516825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_PERFORMANCE:
517825ba0f2Srobj 			ntp = &topo_sensor_states_generic_perf_table[0];
518825ba0f2Srobj 			break;
519825ba0f2Srobj 		case TOPO_SENSOR_TYPE_SEVERITY:
520825ba0f2Srobj 			ntp = &topo_sensor_states_severity_table[0];
521825ba0f2Srobj 			break;
522825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_PRESENCE:
523825ba0f2Srobj 			ntp = &topo_sensor_states_generic_presence_table[0];
524825ba0f2Srobj 			break;
525825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_AVAILABILITY:
526825ba0f2Srobj 			ntp = &topo_sensor_states_generic_avail_table[0];
527825ba0f2Srobj 			break;
528825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_STATUS:
529825ba0f2Srobj 			ntp = &topo_sensor_states_generic_status_table[0];
530825ba0f2Srobj 			break;
531825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_ACPI:
532825ba0f2Srobj 			ntp = &topo_sensor_states_generic_acpi_pwr_table[0];
533825ba0f2Srobj 			break;
534e5dcf7beSRobert Johnston 		case TOPO_SENSOR_TYPE_GENERIC_FAILURE:
535e5dcf7beSRobert Johnston 			ntp = &topo_sensor_states_generic_failure_table[0];
536e5dcf7beSRobert Johnston 			break;
537e5dcf7beSRobert Johnston 		case TOPO_SENSOR_TYPE_GENERIC_OK:
538e5dcf7beSRobert Johnston 			ntp = &topo_sensor_states_generic_ok_table[0];
539e5dcf7beSRobert Johnston 			break;
540825ba0f2Srobj 		default:
541825ba0f2Srobj 			(void) snprintf(buf, len, "0x%02x", state);
542825ba0f2Srobj 			return;
543825ba0f2Srobj 	}
544881aaecdSRob Johnston 	if (state == 0) {
545881aaecdSRob Johnston 		(void) snprintf(buf, len, "NO_STATES_ASSERTED");
546881aaecdSRob Johnston 		return;
547881aaecdSRob Johnston 	}
548881aaecdSRob Johnston 	buf[0] = '\0';
549825ba0f2Srobj 	for (; ntp->int_name != NULL; ntp++) {
550881aaecdSRob Johnston 		if (state & ntp->int_value) {
551881aaecdSRob Johnston 			if (buf[0] != '\0')
552881aaecdSRob Johnston 				(void) strlcat(buf, "|", len);
553881aaecdSRob Johnston 			(void) strlcat(buf, ntp->int_name, len);
554825ba0f2Srobj 		}
555825ba0f2Srobj 	}
556825ba0f2Srobj 
557881aaecdSRob Johnston 	if (buf[0] == '\0')
558881aaecdSRob Johnston 		(void) snprintf(buf, len, "0x%02x", state);
559825ba0f2Srobj }
5608522c52aSRob Johnston 
5618522c52aSRob Johnston static const topo_pgroup_info_t sys_pgroup = {
5628522c52aSRob Johnston 	TOPO_PGROUP_SYSTEM,
5638522c52aSRob Johnston 	TOPO_STABILITY_PRIVATE,
5648522c52aSRob Johnston 	TOPO_STABILITY_PRIVATE,
5658522c52aSRob Johnston 	1
5668522c52aSRob Johnston };
5678522c52aSRob Johnston static const topo_pgroup_info_t auth_pgroup = {
5688522c52aSRob Johnston 	FM_FMRI_AUTHORITY,
5698522c52aSRob Johnston 	TOPO_STABILITY_PRIVATE,
5708522c52aSRob Johnston 	TOPO_STABILITY_PRIVATE,
5718522c52aSRob Johnston 	1
5728522c52aSRob Johnston };
5738522c52aSRob Johnston 
5748522c52aSRob Johnston void
5758522c52aSRob Johnston topo_pgroup_hcset(tnode_t *node, nvlist_t *auth)
5768522c52aSRob Johnston {
5778522c52aSRob Johnston 	int err;
5788522c52aSRob Johnston 	char isa[MAXNAMELEN];
5798522c52aSRob Johnston 	struct utsname uts;
5808522c52aSRob Johnston 	char *prod, *psn, *csn, *server;
5818522c52aSRob Johnston 
5828522c52aSRob Johnston 	if (auth == NULL)
5838522c52aSRob Johnston 		return;
5848522c52aSRob Johnston 
5858522c52aSRob Johnston 	if (topo_pgroup_create(node, &auth_pgroup, &err) != 0) {
5868522c52aSRob Johnston 		if (err != ETOPO_PROP_DEFD)
5878522c52aSRob Johnston 			return;
5888522c52aSRob Johnston 	}
5898522c52aSRob Johnston 
5908522c52aSRob Johnston 	/*
5918522c52aSRob Johnston 	 * Inherit if we can, it saves memory
5928522c52aSRob Johnston 	 */
5938522c52aSRob Johnston 	if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT,
5948522c52aSRob Johnston 	    &err) != 0) && (err != ETOPO_PROP_DEFD)) {
5958522c52aSRob Johnston 		if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT, &prod) ==
5968522c52aSRob Johnston 		    0)
5978522c52aSRob Johnston 			(void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
5988522c52aSRob Johnston 			    FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod,
5998522c52aSRob Johnston 			    &err);
6008522c52aSRob Johnston 	}
6018522c52aSRob Johnston 	if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT_SN,
6028522c52aSRob Johnston 	    &err) != 0) && (err != ETOPO_PROP_DEFD)) {
6038522c52aSRob Johnston 		if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN, &psn) ==
6048522c52aSRob Johnston 		    0)
6058522c52aSRob Johnston 			(void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
6068522c52aSRob Johnston 			    FM_FMRI_AUTH_PRODUCT_SN, TOPO_PROP_IMMUTABLE, psn,
6078522c52aSRob Johnston 			    &err);
6088522c52aSRob Johnston 	}
6098522c52aSRob Johnston 	if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS,
6108522c52aSRob Johnston 	    &err) != 0) && (err != ETOPO_PROP_DEFD)) {
6118522c52aSRob Johnston 		if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &csn) == 0)
6128522c52aSRob Johnston 			(void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
6138522c52aSRob Johnston 			    FM_FMRI_AUTH_CHASSIS, TOPO_PROP_IMMUTABLE, csn,
6148522c52aSRob Johnston 			    &err);
6158522c52aSRob Johnston 	}
6168522c52aSRob Johnston 	if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_SERVER,
6178522c52aSRob Johnston 	    &err) != 0) && (err != ETOPO_PROP_DEFD)) {
6188522c52aSRob Johnston 		if (nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER, &server) ==
6198522c52aSRob Johnston 		    0)
6208522c52aSRob Johnston 			(void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
6218522c52aSRob Johnston 			    FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server,
6228522c52aSRob Johnston 			    &err);
6238522c52aSRob Johnston 	}
6248522c52aSRob Johnston 
6258522c52aSRob Johnston 	if (topo_pgroup_create(node, &sys_pgroup, &err) != 0)
6268522c52aSRob Johnston 		return;
6278522c52aSRob Johnston 
6288522c52aSRob Johnston 	if (sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)) != -1)
6298522c52aSRob Johnston 		(void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM,
6308522c52aSRob Johnston 		    TOPO_PROP_ISA, TOPO_PROP_IMMUTABLE, isa, &err);
6318522c52aSRob Johnston 
6328522c52aSRob Johnston 	if (uname(&uts) != -1)
6338522c52aSRob Johnston 		(void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM,
6348522c52aSRob Johnston 		    TOPO_PROP_MACHINE, TOPO_PROP_IMMUTABLE, uts.machine, &err);
6358522c52aSRob Johnston }
636