xref: /illumos-gate/usr/src/lib/fm/topo/libtopo/common/topo_subr.c (revision 8522c52a00ba4f8cc5ba2e372ae5b66fd0bb7c26)
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  */
25*8522c52aSRob Johnston /*
26*8522c52aSRob Johnston  * Copyright (c) 2018, Joyent, Inc.
27*8522c52aSRob 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>
35*8522c52aSRob Johnston #include <sys/fm/protocol.h>
36*8522c52aSRob Johnston #include <sys/systeminfo.h>
37*8522c52aSRob Johnston #include <sys/utsname.h>
387aec1d6eScindi 
397aec1d6eScindi #include <topo_error.h>
407aec1d6eScindi #include <topo_subr.h>
417aec1d6eScindi 
427aec1d6eScindi void
437aec1d6eScindi topo_hdl_lock(topo_hdl_t *thp)
447aec1d6eScindi {
457aec1d6eScindi 	(void) pthread_mutex_lock(&thp->th_lock);
467aec1d6eScindi }
477aec1d6eScindi 
487aec1d6eScindi void
497aec1d6eScindi topo_hdl_unlock(topo_hdl_t *thp)
507aec1d6eScindi {
517aec1d6eScindi 	(void) pthread_mutex_unlock(&thp->th_lock);
527aec1d6eScindi }
537aec1d6eScindi 
547aec1d6eScindi const char *
550eb822a1Scindi topo_stability2name(topo_stability_t s)
567aec1d6eScindi {
577aec1d6eScindi 	switch (s) {
580eb822a1Scindi 	case TOPO_STABILITY_INTERNAL:	return (TOPO_STABSTR_INTERNAL);
590eb822a1Scindi 	case TOPO_STABILITY_PRIVATE:	return (TOPO_STABSTR_PRIVATE);
600eb822a1Scindi 	case TOPO_STABILITY_OBSOLETE:	return (TOPO_STABSTR_OBSOLETE);
610eb822a1Scindi 	case TOPO_STABILITY_EXTERNAL:	return (TOPO_STABSTR_EXTERNAL);
620eb822a1Scindi 	case TOPO_STABILITY_UNSTABLE:	return (TOPO_STABSTR_UNSTABLE);
630eb822a1Scindi 	case TOPO_STABILITY_EVOLVING:	return (TOPO_STABSTR_EVOLVING);
640eb822a1Scindi 	case TOPO_STABILITY_STABLE:	return (TOPO_STABSTR_STABLE);
650eb822a1Scindi 	case TOPO_STABILITY_STANDARD:	return (TOPO_STABSTR_STANDARD);
660eb822a1Scindi 	default:			return (TOPO_STABSTR_UNKNOWN);
677aec1d6eScindi 	}
687aec1d6eScindi }
697aec1d6eScindi 
700eb822a1Scindi topo_stability_t
710eb822a1Scindi topo_name2stability(const char *name)
720eb822a1Scindi {
730eb822a1Scindi 	if (strcmp(name, TOPO_STABSTR_INTERNAL) == 0)
740eb822a1Scindi 		return (TOPO_STABILITY_INTERNAL);
750eb822a1Scindi 	else if (strcmp(name, TOPO_STABSTR_PRIVATE) == 0)
760eb822a1Scindi 		return (TOPO_STABILITY_PRIVATE);
770eb822a1Scindi 	else if (strcmp(name, TOPO_STABSTR_OBSOLETE) == 0)
780eb822a1Scindi 		return (TOPO_STABILITY_OBSOLETE);
790eb822a1Scindi 	else if (strcmp(name, TOPO_STABSTR_EXTERNAL) == 0)
800eb822a1Scindi 		return (TOPO_STABILITY_EXTERNAL);
810eb822a1Scindi 	else if (strcmp(name, TOPO_STABSTR_UNSTABLE) == 0)
820eb822a1Scindi 		return (TOPO_STABILITY_UNSTABLE);
830eb822a1Scindi 	else if (strcmp(name, TOPO_STABSTR_EVOLVING) == 0)
840eb822a1Scindi 		return (TOPO_STABILITY_EVOLVING);
850eb822a1Scindi 	else if (strcmp(name, TOPO_STABSTR_STABLE) == 0)
860eb822a1Scindi 		return (TOPO_STABILITY_STABLE);
870eb822a1Scindi 	else if (strcmp(name, TOPO_STABSTR_STANDARD) == 0)
880eb822a1Scindi 		return (TOPO_STABILITY_STANDARD);
890eb822a1Scindi 
900eb822a1Scindi 	return (TOPO_STABILITY_UNKNOWN);
910eb822a1Scindi }
920eb822a1Scindi 
937aec1d6eScindi static const topo_debug_mode_t _topo_dbout_modes[] = {
947aec1d6eScindi 	{ "stderr", "send debug messages to stderr", TOPO_DBOUT_STDERR },
957aec1d6eScindi 	{ "syslog", "send debug messages to syslog", TOPO_DBOUT_SYSLOG },
967aec1d6eScindi 	{ NULL, NULL, 0 }
977aec1d6eScindi };
987aec1d6eScindi 
990eb822a1Scindi static const topo_debug_mode_t _topo_dbflag_modes[] = {
1000eb822a1Scindi 	{ "error", "error handling debug messages enabled", TOPO_DBG_ERR },
1010eb822a1Scindi 	{ "module", "module debug messages enabled", TOPO_DBG_MOD },
1020eb822a1Scindi 	{ "modulesvc", "module services debug messages enabled",
1030eb822a1Scindi 	    TOPO_DBG_MODSVC },
1040eb822a1Scindi 	{ "walk", "walker subsystem debug messages enabled", TOPO_DBG_WALK },
1050eb822a1Scindi 	{ "xml", "xml file parsing messages enabled", TOPO_DBG_XML },
1068393544eSHyon Kim 	{ "devinfoforce", "devinfo DINFOFORCE snapshot used", TOPO_DBG_FORCE },
1070eb822a1Scindi 	{ "all", "all debug modes enabled", TOPO_DBG_ALL},
1080eb822a1Scindi 	{ NULL, NULL, 0 }
1090eb822a1Scindi };
1100eb822a1Scindi 
1117aec1d6eScindi void
1120eb822a1Scindi env_process_value(topo_hdl_t *thp, const char *begin, const char *end)
1137aec1d6eScindi {
1140eb822a1Scindi 	char buf[MAXNAMELEN];
1150eb822a1Scindi 	size_t count;
1160eb822a1Scindi 	topo_debug_mode_t *dbp;
1170eb822a1Scindi 
1180eb822a1Scindi 	while (begin < end && isspace(*begin))
1190eb822a1Scindi 		begin++;
1200eb822a1Scindi 
1210eb822a1Scindi 	while (begin < end && isspace(*(end - 1)))
1220eb822a1Scindi 		end--;
1230eb822a1Scindi 
1240eb822a1Scindi 	if (begin >= end)
1250eb822a1Scindi 		return;
1260eb822a1Scindi 
1270eb822a1Scindi 	count = end - begin;
1280eb822a1Scindi 	count += 1;
1290eb822a1Scindi 
1300eb822a1Scindi 	if (count > sizeof (buf))
1310eb822a1Scindi 		return;
1320eb822a1Scindi 
1330eb822a1Scindi 	(void) snprintf(buf, count, "%s", begin);
1340eb822a1Scindi 
1350eb822a1Scindi 	for (dbp = (topo_debug_mode_t *)_topo_dbflag_modes;
1360eb822a1Scindi 	    dbp->tdm_name != NULL; ++dbp) {
1370eb822a1Scindi 		if (strcmp(buf, dbp->tdm_name) == 0)
1380eb822a1Scindi 			thp->th_debug |= dbp->tdm_mode;
1390eb822a1Scindi 	}
1400eb822a1Scindi }
1410eb822a1Scindi 
1420eb822a1Scindi void
1430eb822a1Scindi topo_debug_set(topo_hdl_t *thp, const char *dbmode, const char *dout)
1440eb822a1Scindi {
1450eb822a1Scindi 	char *end, *value, *next;
1460eb822a1Scindi 	topo_debug_mode_t *dbp;
1470eb822a1Scindi 
1480eb822a1Scindi 	topo_hdl_lock(thp);
1490eb822a1Scindi 	value = (char *)dbmode;
1500eb822a1Scindi 
1510eb822a1Scindi 	for (end = (char *)dbmode; *end != '\0'; value = next) {
1520eb822a1Scindi 		end = strchr(value, ',');
1530eb822a1Scindi 		if (end != NULL)
1540eb822a1Scindi 			next = end + 1;	/* skip the comma */
1550eb822a1Scindi 		else
1560eb822a1Scindi 			next = end = value + strlen(value);
1570eb822a1Scindi 
1580eb822a1Scindi 		env_process_value(thp, value, end);
1590eb822a1Scindi 	}
1600eb822a1Scindi 
1610eb822a1Scindi 	if (dout == NULL) {
1620eb822a1Scindi 		topo_hdl_unlock(thp);
1630eb822a1Scindi 		return;
1647aec1d6eScindi 	}
1650eb822a1Scindi 
1660eb822a1Scindi 	for (dbp = (topo_debug_mode_t *)_topo_dbout_modes;
1670eb822a1Scindi 	    dbp->tdm_name != NULL; ++dbp) {
1680eb822a1Scindi 		if (strcmp(dout, dbp->tdm_name) == 0)
1690eb822a1Scindi 		thp->th_dbout = dbp->tdm_mode;
1700eb822a1Scindi 	}
1710eb822a1Scindi 	topo_hdl_unlock(thp);
1727aec1d6eScindi }
1737aec1d6eScindi 
1747aec1d6eScindi void
1750eb822a1Scindi topo_vdprintf(topo_hdl_t *thp, int mask, const char *mod, const char *format,
1760eb822a1Scindi     va_list ap)
1777aec1d6eScindi {
1787aec1d6eScindi 	char *msg;
1797aec1d6eScindi 	size_t len;
1807aec1d6eScindi 	char c;
1817aec1d6eScindi 
1820eb822a1Scindi 	if (!(thp->th_debug & mask))
1837aec1d6eScindi 		return;
1847aec1d6eScindi 
1857aec1d6eScindi 	len = vsnprintf(&c, 1, format, ap);
1867aec1d6eScindi 	msg = alloca(len + 2);
1877aec1d6eScindi 	(void) vsnprintf(msg, len + 1, format, ap);
1887aec1d6eScindi 
1897aec1d6eScindi 	if (msg[len - 1] != '\n')
1907aec1d6eScindi 		(void) strcpy(&msg[len], "\n");
1917aec1d6eScindi 
1920eb822a1Scindi 	if (thp->th_dbout == TOPO_DBOUT_SYSLOG) {
1930eb822a1Scindi 		if (mod == NULL) {
1940eb822a1Scindi 			syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s", msg);
1950eb822a1Scindi 		} else {
1960eb822a1Scindi 			syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s: %s",
1970eb822a1Scindi 			    mod, msg);
1980eb822a1Scindi 		}
1990eb822a1Scindi 	} else {
2000eb822a1Scindi 		if (mod == NULL) {
2010eb822a1Scindi 			(void) fprintf(stderr, "libtopo DEBUG: %s", msg);
2020eb822a1Scindi 		} else {
2030eb822a1Scindi 			(void) fprintf(stderr, "libtopo DEBUG: %s: %s", mod,
2040eb822a1Scindi 			    msg);
2050eb822a1Scindi 		}
2060eb822a1Scindi 	}
2077aec1d6eScindi }
2087aec1d6eScindi 
2090eb822a1Scindi /*PRINTFLIKE3*/
2107aec1d6eScindi void
2110eb822a1Scindi topo_dprintf(topo_hdl_t *thp, int mask, const char *format, ...)
2127aec1d6eScindi {
2137aec1d6eScindi 	va_list ap;
2147aec1d6eScindi 
2157aec1d6eScindi 	va_start(ap, format);
2160eb822a1Scindi 	topo_vdprintf(thp, mask, 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;
2247aec1d6eScindi 
2257aec1d6eScindi 	for (tp = topo_list_next(&thp->th_trees); tp != NULL;
2267aec1d6eScindi 	    tp = topo_list_next(tp)) {
2277aec1d6eScindi 		if (strcmp(scheme, tp->tt_scheme) == 0)
2287aec1d6eScindi 			return (tp->tt_root);
2297aec1d6eScindi 	}
2307aec1d6eScindi 
2317aec1d6eScindi 	return (NULL);
2327aec1d6eScindi }
23374a31ce6Stimh 
23474a31ce6Stimh /*
23574a31ce6Stimh  * buf_append -- Append str to buf (if it's non-NULL).  Place prepend
23674a31ce6Stimh  * in buf in front of str and append behind it (if they're non-NULL).
23774a31ce6Stimh  * Continue to update size even if we run out of space to actually
23874a31ce6Stimh  * stuff characters in the buffer.
23974a31ce6Stimh  */
24074a31ce6Stimh void
24174a31ce6Stimh topo_fmristr_build(ssize_t *sz, char *buf, size_t buflen, char *str,
24274a31ce6Stimh     char *prepend, char *append)
24374a31ce6Stimh {
24474a31ce6Stimh 	ssize_t left;
24574a31ce6Stimh 
24674a31ce6Stimh 	if (str == NULL)
24774a31ce6Stimh 		return;
24874a31ce6Stimh 
24974a31ce6Stimh 	if (buflen == 0 || (left = buflen - *sz) < 0)
25074a31ce6Stimh 		left = 0;
25174a31ce6Stimh 
25274a31ce6Stimh 	if (buf != NULL && left != 0)
25374a31ce6Stimh 		buf += *sz;
25474a31ce6Stimh 
25574a31ce6Stimh 	if (prepend == NULL && append == NULL)
25674a31ce6Stimh 		*sz += snprintf(buf, left, "%s", str);
25774a31ce6Stimh 	else if (append == NULL)
25874a31ce6Stimh 		*sz += snprintf(buf, left, "%s%s", prepend, str);
25974a31ce6Stimh 	else if (prepend == NULL)
26074a31ce6Stimh 		*sz += snprintf(buf, left, "%s%s", str, append);
26174a31ce6Stimh 	else
26274a31ce6Stimh 		*sz += snprintf(buf, left, "%s%s%s", prepend, str, append);
26374a31ce6Stimh }
2640eb822a1Scindi 
2650eb822a1Scindi #define	TOPO_PLATFORM_PATH	"%s/usr/platform/%s/lib/fm/topo/%s"
2660eb822a1Scindi #define	TOPO_COMMON_PATH	"%s/usr/lib/fm/topo/%s"
2670eb822a1Scindi 
2680eb822a1Scindi char *
2690eb822a1Scindi topo_search_path(topo_mod_t *mod, const char *rootdir, const char *file)
2700eb822a1Scindi {
2710eb822a1Scindi 	char *pp, sp[PATH_MAX];
2720eb822a1Scindi 	topo_hdl_t *thp = mod->tm_hdl;
2730eb822a1Scindi 
2740eb822a1Scindi 	/*
2750eb822a1Scindi 	 * Search for file name in order of platform, machine and common
2760eb822a1Scindi 	 * topo directories
2770eb822a1Scindi 	 */
2780eb822a1Scindi 	(void) snprintf(sp, PATH_MAX, TOPO_PLATFORM_PATH, rootdir,
2790eb822a1Scindi 	    thp->th_platform, file);
2800eb822a1Scindi 	if (access(sp, F_OK) != 0) {
2810eb822a1Scindi 		(void) snprintf(sp, PATH_MAX, TOPO_PLATFORM_PATH,
2820eb822a1Scindi 		    thp->th_rootdir, thp->th_machine, file);
2830eb822a1Scindi 		if (access(sp, F_OK) != 0) {
2840eb822a1Scindi 			(void) snprintf(sp, PATH_MAX, TOPO_COMMON_PATH,
2850eb822a1Scindi 			    thp->th_rootdir, file);
2860eb822a1Scindi 			if (access(sp, F_OK) != 0) {
2870eb822a1Scindi 				return (NULL);
2880eb822a1Scindi 			}
2890eb822a1Scindi 		}
2900eb822a1Scindi 	}
2910eb822a1Scindi 
2920eb822a1Scindi 	pp = topo_mod_strdup(mod, sp);
2930eb822a1Scindi 
2940eb822a1Scindi 	return (pp);
2950eb822a1Scindi }
29624db4641Seschrock 
29724db4641Seschrock /*
29824db4641Seschrock  * SMBIOS serial numbers can contain characters (particularly ':' and ' ')
29924db4641Seschrock  * that are invalid for the authority and can break FMRI parsing.  We translate
30024db4641Seschrock  * any invalid characters to a safe '-', as well as trimming any leading or
30120c794b3Sgavinm  * trailing whitespace.  Similarly, '/' can be found in some product names
30220c794b3Sgavinm  * so we translate that to '-'.
30324db4641Seschrock  */
30424db4641Seschrock char *
305e3d60c9bSAdrian Frost topo_cleanup_auth_str(topo_hdl_t *thp, const char *begin)
30624db4641Seschrock {
30724db4641Seschrock 	char buf[MAXNAMELEN];
308e3d60c9bSAdrian Frost 	const char *end, *cp;
309e3d60c9bSAdrian Frost 	char *pp;
310e3d60c9bSAdrian Frost 	char c;
311e3d60c9bSAdrian Frost 	int i;
31224db4641Seschrock 
31324db4641Seschrock 	end = begin + strlen(begin);
31424db4641Seschrock 
31524db4641Seschrock 	while (begin < end && isspace(*begin))
31624db4641Seschrock 		begin++;
31724db4641Seschrock 	while (begin < end && isspace(*(end - 1)))
31824db4641Seschrock 		end--;
31924db4641Seschrock 
32024db4641Seschrock 	if (begin >= end)
32124db4641Seschrock 		return (NULL);
32224db4641Seschrock 
323e3d60c9bSAdrian Frost 	cp = begin;
324e3d60c9bSAdrian Frost 	for (i = 0; i < MAXNAMELEN - 1; i++) {
325e3d60c9bSAdrian Frost 		if (cp >= end)
326e3d60c9bSAdrian Frost 			break;
327e3d60c9bSAdrian Frost 		c = *cp;
328e3d60c9bSAdrian Frost 		if (c == ':' || c == '=' || c == '/' || isspace(c) ||
329e3d60c9bSAdrian Frost 		    !isprint(c))
330e3d60c9bSAdrian Frost 			buf[i] = '-';
331e3d60c9bSAdrian Frost 		else
332e3d60c9bSAdrian Frost 			buf[i] = c;
333e3d60c9bSAdrian Frost 		cp++;
334e3d60c9bSAdrian Frost 	}
335e3d60c9bSAdrian Frost 	buf[i] = 0;
33624db4641Seschrock 
33724db4641Seschrock 	pp = topo_hdl_strdup(thp, buf);
33824db4641Seschrock 	return (pp);
33924db4641Seschrock }
340825ba0f2Srobj 
341825ba0f2Srobj void
342825ba0f2Srobj topo_sensor_type_name(uint32_t type, char *buf, size_t len)
343825ba0f2Srobj {
344825ba0f2Srobj 	topo_name_trans_t *ntp;
345825ba0f2Srobj 
346825ba0f2Srobj 	for (ntp = &topo_sensor_type_table[0]; ntp->int_name != NULL; ntp++) {
347825ba0f2Srobj 		if (ntp->int_value == type) {
348825ba0f2Srobj 			(void) strlcpy(buf, ntp->int_name, len);
349825ba0f2Srobj 			return;
350825ba0f2Srobj 		}
351825ba0f2Srobj 	}
352825ba0f2Srobj 
353825ba0f2Srobj 	(void) snprintf(buf, len, "0x%02x", type);
354825ba0f2Srobj }
355825ba0f2Srobj 
356825ba0f2Srobj void
357825ba0f2Srobj topo_sensor_units_name(uint8_t type, char *buf, size_t len)
358825ba0f2Srobj {
359825ba0f2Srobj 	topo_name_trans_t *ntp;
360825ba0f2Srobj 
361825ba0f2Srobj 	for (ntp = &topo_units_type_table[0]; ntp->int_name != NULL; ntp++) {
362825ba0f2Srobj 		if (ntp->int_value == type) {
363825ba0f2Srobj 			(void) strlcpy(buf, ntp->int_name, len);
364825ba0f2Srobj 			return;
365825ba0f2Srobj 		}
366825ba0f2Srobj 	}
367825ba0f2Srobj 
368825ba0f2Srobj 	(void) snprintf(buf, len, "0x%02x", type);
369825ba0f2Srobj }
370825ba0f2Srobj 
371825ba0f2Srobj void
372825ba0f2Srobj topo_led_type_name(uint8_t type, char *buf, size_t len)
373825ba0f2Srobj {
374825ba0f2Srobj 	topo_name_trans_t *ntp;
375825ba0f2Srobj 
376825ba0f2Srobj 	for (ntp = &topo_led_type_table[0]; ntp->int_name != NULL; ntp++) {
377825ba0f2Srobj 		if (ntp->int_value == type) {
378825ba0f2Srobj 			(void) strlcpy(buf, ntp->int_name, len);
379825ba0f2Srobj 			return;
380825ba0f2Srobj 		}
381825ba0f2Srobj 	}
382825ba0f2Srobj 
383825ba0f2Srobj 	(void) snprintf(buf, len, "0x%02x", type);
384825ba0f2Srobj }
385825ba0f2Srobj 
386825ba0f2Srobj void
387825ba0f2Srobj topo_led_state_name(uint8_t type, char *buf, size_t len)
388825ba0f2Srobj {
389825ba0f2Srobj 	topo_name_trans_t *ntp;
390825ba0f2Srobj 
391825ba0f2Srobj 	for (ntp = &topo_led_states_table[0]; ntp->int_name != NULL; ntp++) {
392825ba0f2Srobj 		if (ntp->int_value == type) {
393825ba0f2Srobj 			(void) strlcpy(buf, ntp->int_name, len);
394825ba0f2Srobj 			return;
395825ba0f2Srobj 		}
396825ba0f2Srobj 	}
397825ba0f2Srobj 
398825ba0f2Srobj 	(void) snprintf(buf, len, "0x%02x", type);
399825ba0f2Srobj }
400825ba0f2Srobj 
401825ba0f2Srobj void
402825ba0f2Srobj topo_sensor_state_name(uint32_t sensor_type, uint8_t state, char *buf,
403*8522c52aSRob Johnston     size_t len)
404825ba0f2Srobj {
405825ba0f2Srobj 	topo_name_trans_t *ntp;
406825ba0f2Srobj 
407825ba0f2Srobj 	switch (sensor_type) {
408825ba0f2Srobj 		case TOPO_SENSOR_TYPE_PHYSICAL:
409825ba0f2Srobj 			ntp = &topo_sensor_states_physical_table[0];
410825ba0f2Srobj 			break;
411825ba0f2Srobj 		case TOPO_SENSOR_TYPE_PLATFORM:
412825ba0f2Srobj 			ntp = &topo_sensor_states_platform_table[0];
413825ba0f2Srobj 			break;
414825ba0f2Srobj 		case TOPO_SENSOR_TYPE_PROCESSOR:
415825ba0f2Srobj 			ntp = &topo_sensor_states_processor_table[0];
416825ba0f2Srobj 			break;
417825ba0f2Srobj 		case TOPO_SENSOR_TYPE_POWER_SUPPLY:
418825ba0f2Srobj 			ntp = &topo_sensor_states_power_supply_table[0];
419825ba0f2Srobj 			break;
420825ba0f2Srobj 		case TOPO_SENSOR_TYPE_POWER_UNIT:
421825ba0f2Srobj 			ntp = &topo_sensor_states_power_unit_table[0];
422825ba0f2Srobj 			break;
423825ba0f2Srobj 		case TOPO_SENSOR_TYPE_MEMORY:
424825ba0f2Srobj 			ntp = &topo_sensor_states_memory_table[0];
425825ba0f2Srobj 			break;
426825ba0f2Srobj 		case TOPO_SENSOR_TYPE_BAY:
427825ba0f2Srobj 			ntp = &topo_sensor_states_bay_table[0];
428825ba0f2Srobj 			break;
429825ba0f2Srobj 		case TOPO_SENSOR_TYPE_FIRMWARE:
430825ba0f2Srobj 			ntp = &topo_sensor_states_firmware_table[0];
431825ba0f2Srobj 			break;
432825ba0f2Srobj 		case TOPO_SENSOR_TYPE_EVENT_LOG:
433825ba0f2Srobj 			ntp = &topo_sensor_states_event_log_table[0];
434825ba0f2Srobj 			break;
435825ba0f2Srobj 		case TOPO_SENSOR_TYPE_WATCHDOG1:
436825ba0f2Srobj 			ntp = &topo_sensor_states_watchdog1_table[0];
437825ba0f2Srobj 			break;
438825ba0f2Srobj 		case TOPO_SENSOR_TYPE_SYSTEM:
439825ba0f2Srobj 			ntp = &topo_sensor_states_system_table[0];
440825ba0f2Srobj 			break;
441825ba0f2Srobj 		case TOPO_SENSOR_TYPE_CRITICAL:
442825ba0f2Srobj 			ntp = &topo_sensor_states_critical_table[0];
443825ba0f2Srobj 			break;
444825ba0f2Srobj 		case TOPO_SENSOR_TYPE_BUTTON:
445825ba0f2Srobj 			ntp = &topo_sensor_states_button_table[0];
446825ba0f2Srobj 			break;
447825ba0f2Srobj 		case TOPO_SENSOR_TYPE_CABLE:
448825ba0f2Srobj 			ntp = &topo_sensor_states_cable_table[0];
449825ba0f2Srobj 			break;
450825ba0f2Srobj 		case TOPO_SENSOR_TYPE_BOOT_STATE:
451825ba0f2Srobj 			ntp = &topo_sensor_states_boot_state_table[0];
452825ba0f2Srobj 			break;
453825ba0f2Srobj 		case TOPO_SENSOR_TYPE_BOOT_ERROR:
454825ba0f2Srobj 			ntp = &topo_sensor_states_boot_error_table[0];
455825ba0f2Srobj 			break;
456825ba0f2Srobj 		case TOPO_SENSOR_TYPE_BOOT_OS:
457825ba0f2Srobj 			ntp = &topo_sensor_states_boot_os_table[0];
458825ba0f2Srobj 			break;
459825ba0f2Srobj 		case TOPO_SENSOR_TYPE_OS_SHUTDOWN:
460825ba0f2Srobj 			ntp = &topo_sensor_states_os_table[0];
461825ba0f2Srobj 			break;
462825ba0f2Srobj 		case TOPO_SENSOR_TYPE_SLOT:
463825ba0f2Srobj 			ntp = &topo_sensor_states_slot_table[0];
464825ba0f2Srobj 			break;
465825ba0f2Srobj 		case TOPO_SENSOR_TYPE_ACPI:
466825ba0f2Srobj 			ntp = &topo_sensor_states_acpi_table[0];
467825ba0f2Srobj 			break;
468825ba0f2Srobj 		case TOPO_SENSOR_TYPE_WATCHDOG2:
469825ba0f2Srobj 			ntp = &topo_sensor_states_watchdog2_table[0];
470825ba0f2Srobj 			break;
471825ba0f2Srobj 		case TOPO_SENSOR_TYPE_ALERT:
472825ba0f2Srobj 			ntp = &topo_sensor_states_alert_table[0];
473825ba0f2Srobj 			break;
474825ba0f2Srobj 		case TOPO_SENSOR_TYPE_PRESENCE:
475825ba0f2Srobj 			ntp = &topo_sensor_states_presence_table[0];
476825ba0f2Srobj 			break;
477825ba0f2Srobj 		case TOPO_SENSOR_TYPE_LAN:
478825ba0f2Srobj 			ntp = &topo_sensor_states_lan_table[0];
479825ba0f2Srobj 			break;
480825ba0f2Srobj 		case TOPO_SENSOR_TYPE_HEALTH:
481825ba0f2Srobj 			ntp = &topo_sensor_states_health_table[0];
482825ba0f2Srobj 			break;
483825ba0f2Srobj 		case TOPO_SENSOR_TYPE_BATTERY:
484825ba0f2Srobj 			ntp = &topo_sensor_states_battery_table[0];
485825ba0f2Srobj 			break;
486825ba0f2Srobj 		case TOPO_SENSOR_TYPE_AUDIT:
487825ba0f2Srobj 			ntp = &topo_sensor_states_audit_table[0];
488825ba0f2Srobj 			break;
489825ba0f2Srobj 		case TOPO_SENSOR_TYPE_VERSION:
490825ba0f2Srobj 			ntp = &topo_sensor_states_version_table[0];
491825ba0f2Srobj 			break;
492825ba0f2Srobj 		case TOPO_SENSOR_TYPE_FRU_STATE:
493825ba0f2Srobj 			ntp = &topo_sensor_states_fru_state_table[0];
494825ba0f2Srobj 			break;
495825ba0f2Srobj 		case TOPO_SENSOR_TYPE_THRESHOLD_STATE:
496825ba0f2Srobj 			ntp = &topo_sensor_states_thresh_table[0];
497825ba0f2Srobj 			break;
498825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_USAGE:
499825ba0f2Srobj 			ntp = &topo_sensor_states_generic_usage_table[0];
500825ba0f2Srobj 			break;
501825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_STATE:
502825ba0f2Srobj 			ntp = &topo_sensor_states_generic_state_table[0];
503825ba0f2Srobj 			break;
504825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_PREDFAIL:
505825ba0f2Srobj 			ntp = &topo_sensor_states_generic_predfail_table[0];
506825ba0f2Srobj 			break;
507825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_LIMIT:
508825ba0f2Srobj 			ntp = &topo_sensor_states_generic_limit_table[0];
509825ba0f2Srobj 			break;
510825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_PERFORMANCE:
511825ba0f2Srobj 			ntp = &topo_sensor_states_generic_perf_table[0];
512825ba0f2Srobj 			break;
513825ba0f2Srobj 		case TOPO_SENSOR_TYPE_SEVERITY:
514825ba0f2Srobj 			ntp = &topo_sensor_states_severity_table[0];
515825ba0f2Srobj 			break;
516825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_PRESENCE:
517825ba0f2Srobj 			ntp = &topo_sensor_states_generic_presence_table[0];
518825ba0f2Srobj 			break;
519825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_AVAILABILITY:
520825ba0f2Srobj 			ntp = &topo_sensor_states_generic_avail_table[0];
521825ba0f2Srobj 			break;
522825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_STATUS:
523825ba0f2Srobj 			ntp = &topo_sensor_states_generic_status_table[0];
524825ba0f2Srobj 			break;
525825ba0f2Srobj 		case TOPO_SENSOR_TYPE_GENERIC_ACPI:
526825ba0f2Srobj 			ntp = &topo_sensor_states_generic_acpi_pwr_table[0];
527825ba0f2Srobj 			break;
528e5dcf7beSRobert Johnston 		case TOPO_SENSOR_TYPE_GENERIC_FAILURE:
529e5dcf7beSRobert Johnston 			ntp = &topo_sensor_states_generic_failure_table[0];
530e5dcf7beSRobert Johnston 			break;
531e5dcf7beSRobert Johnston 		case TOPO_SENSOR_TYPE_GENERIC_OK:
532e5dcf7beSRobert Johnston 			ntp = &topo_sensor_states_generic_ok_table[0];
533e5dcf7beSRobert Johnston 			break;
534825ba0f2Srobj 		default:
535825ba0f2Srobj 			(void) snprintf(buf, len, "0x%02x", state);
536825ba0f2Srobj 			return;
537825ba0f2Srobj 	}
538825ba0f2Srobj 	for (; ntp->int_name != NULL; ntp++) {
539825ba0f2Srobj 		if (ntp->int_value == state) {
540825ba0f2Srobj 			(void) strlcpy(buf, ntp->int_name, len);
541825ba0f2Srobj 			return;
542825ba0f2Srobj 		}
543825ba0f2Srobj 	}
544825ba0f2Srobj 
545825ba0f2Srobj 	(void) snprintf(buf, len, "0x%02x", state);
546825ba0f2Srobj }
547*8522c52aSRob Johnston 
548*8522c52aSRob Johnston static const topo_pgroup_info_t sys_pgroup = {
549*8522c52aSRob Johnston 	TOPO_PGROUP_SYSTEM,
550*8522c52aSRob Johnston 	TOPO_STABILITY_PRIVATE,
551*8522c52aSRob Johnston 	TOPO_STABILITY_PRIVATE,
552*8522c52aSRob Johnston 	1
553*8522c52aSRob Johnston };
554*8522c52aSRob Johnston static const topo_pgroup_info_t auth_pgroup = {
555*8522c52aSRob Johnston 	FM_FMRI_AUTHORITY,
556*8522c52aSRob Johnston 	TOPO_STABILITY_PRIVATE,
557*8522c52aSRob Johnston 	TOPO_STABILITY_PRIVATE,
558*8522c52aSRob Johnston 	1
559*8522c52aSRob Johnston };
560*8522c52aSRob Johnston 
561*8522c52aSRob Johnston void
562*8522c52aSRob Johnston topo_pgroup_hcset(tnode_t *node, nvlist_t *auth)
563*8522c52aSRob Johnston {
564*8522c52aSRob Johnston 	int err;
565*8522c52aSRob Johnston 	char isa[MAXNAMELEN];
566*8522c52aSRob Johnston 	struct utsname uts;
567*8522c52aSRob Johnston 	char *prod, *psn, *csn, *server;
568*8522c52aSRob Johnston 
569*8522c52aSRob Johnston 	if (auth == NULL)
570*8522c52aSRob Johnston 		return;
571*8522c52aSRob Johnston 
572*8522c52aSRob Johnston 	if (topo_pgroup_create(node, &auth_pgroup, &err) != 0) {
573*8522c52aSRob Johnston 		if (err != ETOPO_PROP_DEFD)
574*8522c52aSRob Johnston 			return;
575*8522c52aSRob Johnston 	}
576*8522c52aSRob Johnston 
577*8522c52aSRob Johnston 	/*
578*8522c52aSRob Johnston 	 * Inherit if we can, it saves memory
579*8522c52aSRob Johnston 	 */
580*8522c52aSRob Johnston 	if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT,
581*8522c52aSRob Johnston 	    &err) != 0) && (err != ETOPO_PROP_DEFD)) {
582*8522c52aSRob Johnston 		if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT, &prod) ==
583*8522c52aSRob Johnston 		    0)
584*8522c52aSRob Johnston 			(void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
585*8522c52aSRob Johnston 			    FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod,
586*8522c52aSRob Johnston 			    &err);
587*8522c52aSRob Johnston 	}
588*8522c52aSRob Johnston 	if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT_SN,
589*8522c52aSRob Johnston 	    &err) != 0) && (err != ETOPO_PROP_DEFD)) {
590*8522c52aSRob Johnston 		if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN, &psn) ==
591*8522c52aSRob Johnston 		    0)
592*8522c52aSRob Johnston 			(void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
593*8522c52aSRob Johnston 			    FM_FMRI_AUTH_PRODUCT_SN, TOPO_PROP_IMMUTABLE, psn,
594*8522c52aSRob Johnston 			    &err);
595*8522c52aSRob Johnston 	}
596*8522c52aSRob Johnston 	if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS,
597*8522c52aSRob Johnston 	    &err) != 0) && (err != ETOPO_PROP_DEFD)) {
598*8522c52aSRob Johnston 		if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &csn) == 0)
599*8522c52aSRob Johnston 			(void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
600*8522c52aSRob Johnston 			    FM_FMRI_AUTH_CHASSIS, TOPO_PROP_IMMUTABLE, csn,
601*8522c52aSRob Johnston 			    &err);
602*8522c52aSRob Johnston 	}
603*8522c52aSRob Johnston 	if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_SERVER,
604*8522c52aSRob Johnston 	    &err) != 0) && (err != ETOPO_PROP_DEFD)) {
605*8522c52aSRob Johnston 		if (nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER, &server) ==
606*8522c52aSRob Johnston 		    0)
607*8522c52aSRob Johnston 			(void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
608*8522c52aSRob Johnston 			    FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server,
609*8522c52aSRob Johnston 			    &err);
610*8522c52aSRob Johnston 	}
611*8522c52aSRob Johnston 
612*8522c52aSRob Johnston 	if (topo_pgroup_create(node, &sys_pgroup, &err) != 0)
613*8522c52aSRob Johnston 		return;
614*8522c52aSRob Johnston 
615*8522c52aSRob Johnston 	if (sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)) != -1)
616*8522c52aSRob Johnston 		(void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM,
617*8522c52aSRob Johnston 		    TOPO_PROP_ISA, TOPO_PROP_IMMUTABLE, isa, &err);
618*8522c52aSRob Johnston 
619*8522c52aSRob Johnston 	if (uname(&uts) != -1)
620*8522c52aSRob Johnston 		(void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM,
621*8522c52aSRob Johnston 		    TOPO_PROP_MACHINE, TOPO_PROP_IMMUTABLE, uts.machine, &err);
622*8522c52aSRob Johnston }
623