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 /*
26c5591576SRob Johnston * Copyright 2020 Joyent, Inc.
27*9c994d58SRobert Mustacchi * Copyright 2023 Oxide Computer Company
288522c52aSRob Johnston */
297aec1d6eScindi
307aec1d6eScindi #include <alloca.h>
310eb822a1Scindi #include <ctype.h>
320eb822a1Scindi #include <limits.h>
337aec1d6eScindi #include <syslog.h>
347aec1d6eScindi #include <strings.h>
350eb822a1Scindi #include <unistd.h>
368522c52aSRob Johnston #include <sys/fm/protocol.h>
378522c52aSRob Johnston #include <sys/systeminfo.h>
388522c52aSRob Johnston #include <sys/utsname.h>
397aec1d6eScindi
407aec1d6eScindi #include <topo_error.h>
41c5591576SRob Johnston #include <topo_digraph.h>
427aec1d6eScindi #include <topo_subr.h>
437aec1d6eScindi
447aec1d6eScindi void
topo_hdl_lock(topo_hdl_t * thp)457aec1d6eScindi topo_hdl_lock(topo_hdl_t *thp)
467aec1d6eScindi {
477aec1d6eScindi (void) pthread_mutex_lock(&thp->th_lock);
487aec1d6eScindi }
497aec1d6eScindi
507aec1d6eScindi void
topo_hdl_unlock(topo_hdl_t * thp)517aec1d6eScindi topo_hdl_unlock(topo_hdl_t *thp)
527aec1d6eScindi {
537aec1d6eScindi (void) pthread_mutex_unlock(&thp->th_lock);
547aec1d6eScindi }
557aec1d6eScindi
567aec1d6eScindi const char *
topo_stability2name(topo_stability_t s)570eb822a1Scindi topo_stability2name(topo_stability_t s)
587aec1d6eScindi {
597aec1d6eScindi switch (s) {
600eb822a1Scindi case TOPO_STABILITY_INTERNAL: return (TOPO_STABSTR_INTERNAL);
610eb822a1Scindi case TOPO_STABILITY_PRIVATE: return (TOPO_STABSTR_PRIVATE);
620eb822a1Scindi case TOPO_STABILITY_OBSOLETE: return (TOPO_STABSTR_OBSOLETE);
630eb822a1Scindi case TOPO_STABILITY_EXTERNAL: return (TOPO_STABSTR_EXTERNAL);
640eb822a1Scindi case TOPO_STABILITY_UNSTABLE: return (TOPO_STABSTR_UNSTABLE);
650eb822a1Scindi case TOPO_STABILITY_EVOLVING: return (TOPO_STABSTR_EVOLVING);
660eb822a1Scindi case TOPO_STABILITY_STABLE: return (TOPO_STABSTR_STABLE);
670eb822a1Scindi case TOPO_STABILITY_STANDARD: return (TOPO_STABSTR_STANDARD);
680eb822a1Scindi default: return (TOPO_STABSTR_UNKNOWN);
697aec1d6eScindi }
707aec1d6eScindi }
717aec1d6eScindi
720eb822a1Scindi topo_stability_t
topo_name2stability(const char * name)730eb822a1Scindi topo_name2stability(const char *name)
740eb822a1Scindi {
750eb822a1Scindi if (strcmp(name, TOPO_STABSTR_INTERNAL) == 0)
760eb822a1Scindi return (TOPO_STABILITY_INTERNAL);
770eb822a1Scindi else if (strcmp(name, TOPO_STABSTR_PRIVATE) == 0)
780eb822a1Scindi return (TOPO_STABILITY_PRIVATE);
790eb822a1Scindi else if (strcmp(name, TOPO_STABSTR_OBSOLETE) == 0)
800eb822a1Scindi return (TOPO_STABILITY_OBSOLETE);
810eb822a1Scindi else if (strcmp(name, TOPO_STABSTR_EXTERNAL) == 0)
820eb822a1Scindi return (TOPO_STABILITY_EXTERNAL);
830eb822a1Scindi else if (strcmp(name, TOPO_STABSTR_UNSTABLE) == 0)
840eb822a1Scindi return (TOPO_STABILITY_UNSTABLE);
850eb822a1Scindi else if (strcmp(name, TOPO_STABSTR_EVOLVING) == 0)
860eb822a1Scindi return (TOPO_STABILITY_EVOLVING);
870eb822a1Scindi else if (strcmp(name, TOPO_STABSTR_STABLE) == 0)
880eb822a1Scindi return (TOPO_STABILITY_STABLE);
890eb822a1Scindi else if (strcmp(name, TOPO_STABSTR_STANDARD) == 0)
900eb822a1Scindi return (TOPO_STABILITY_STANDARD);
910eb822a1Scindi
920eb822a1Scindi return (TOPO_STABILITY_UNKNOWN);
930eb822a1Scindi }
940eb822a1Scindi
957aec1d6eScindi static const topo_debug_mode_t _topo_dbout_modes[] = {
967aec1d6eScindi { "stderr", "send debug messages to stderr", TOPO_DBOUT_STDERR },
977aec1d6eScindi { "syslog", "send debug messages to syslog", TOPO_DBOUT_SYSLOG },
987aec1d6eScindi { NULL, NULL, 0 }
997aec1d6eScindi };
1007aec1d6eScindi
1010eb822a1Scindi static const topo_debug_mode_t _topo_dbflag_modes[] = {
1020eb822a1Scindi { "error", "error handling debug messages enabled", TOPO_DBG_ERR },
1030eb822a1Scindi { "module", "module debug messages enabled", TOPO_DBG_MOD },
1040eb822a1Scindi { "modulesvc", "module services debug messages enabled",
1050eb822a1Scindi TOPO_DBG_MODSVC },
1060eb822a1Scindi { "walk", "walker subsystem debug messages enabled", TOPO_DBG_WALK },
1070eb822a1Scindi { "xml", "xml file parsing messages enabled", TOPO_DBG_XML },
1088393544eSHyon Kim { "devinfoforce", "devinfo DINFOFORCE snapshot used", TOPO_DBG_FORCE },
1090eb822a1Scindi { "all", "all debug modes enabled", TOPO_DBG_ALL},
1100eb822a1Scindi { NULL, NULL, 0 }
1110eb822a1Scindi };
1120eb822a1Scindi
1137aec1d6eScindi void
env_process_value(topo_hdl_t * thp,const char * begin,const char * end)1140eb822a1Scindi env_process_value(topo_hdl_t *thp, const char *begin, const char *end)
1157aec1d6eScindi {
1160eb822a1Scindi char buf[MAXNAMELEN];
1170eb822a1Scindi size_t count;
1180eb822a1Scindi topo_debug_mode_t *dbp;
1190eb822a1Scindi
1200eb822a1Scindi while (begin < end && isspace(*begin))
1210eb822a1Scindi begin++;
1220eb822a1Scindi
1230eb822a1Scindi while (begin < end && isspace(*(end - 1)))
1240eb822a1Scindi end--;
1250eb822a1Scindi
1260eb822a1Scindi if (begin >= end)
1270eb822a1Scindi return;
1280eb822a1Scindi
1290eb822a1Scindi count = end - begin;
1300eb822a1Scindi count += 1;
1310eb822a1Scindi
1320eb822a1Scindi if (count > sizeof (buf))
1330eb822a1Scindi return;
1340eb822a1Scindi
1350eb822a1Scindi (void) snprintf(buf, count, "%s", begin);
1360eb822a1Scindi
1370eb822a1Scindi for (dbp = (topo_debug_mode_t *)_topo_dbflag_modes;
1380eb822a1Scindi dbp->tdm_name != NULL; ++dbp) {
1390eb822a1Scindi if (strcmp(buf, dbp->tdm_name) == 0)
1400eb822a1Scindi thp->th_debug |= dbp->tdm_mode;
1410eb822a1Scindi }
1420eb822a1Scindi }
1430eb822a1Scindi
1440eb822a1Scindi void
topo_debug_set(topo_hdl_t * thp,const char * dbmode,const char * dout)1450eb822a1Scindi topo_debug_set(topo_hdl_t *thp, const char *dbmode, const char *dout)
1460eb822a1Scindi {
1470eb822a1Scindi char *end, *value, *next;
1480eb822a1Scindi topo_debug_mode_t *dbp;
1490eb822a1Scindi
1500eb822a1Scindi topo_hdl_lock(thp);
1510eb822a1Scindi value = (char *)dbmode;
1520eb822a1Scindi
1530eb822a1Scindi for (end = (char *)dbmode; *end != '\0'; value = next) {
1540eb822a1Scindi end = strchr(value, ',');
1550eb822a1Scindi if (end != NULL)
1560eb822a1Scindi next = end + 1; /* skip the comma */
1570eb822a1Scindi else
1580eb822a1Scindi next = end = value + strlen(value);
1590eb822a1Scindi
1600eb822a1Scindi env_process_value(thp, value, end);
1610eb822a1Scindi }
1620eb822a1Scindi
1630eb822a1Scindi if (dout == NULL) {
1640eb822a1Scindi topo_hdl_unlock(thp);
1650eb822a1Scindi return;
1667aec1d6eScindi }
1670eb822a1Scindi
1680eb822a1Scindi for (dbp = (topo_debug_mode_t *)_topo_dbout_modes;
1690eb822a1Scindi dbp->tdm_name != NULL; ++dbp) {
1700eb822a1Scindi if (strcmp(dout, dbp->tdm_name) == 0)
1711e95bfe1SRob Johnston thp->th_dbout = dbp->tdm_mode;
1720eb822a1Scindi }
1730eb822a1Scindi topo_hdl_unlock(thp);
1747aec1d6eScindi }
1757aec1d6eScindi
1767aec1d6eScindi void
topo_vdprintf(topo_hdl_t * thp,const char * mod,const char * format,va_list ap)1771de1e652SRob Johnston topo_vdprintf(topo_hdl_t *thp, const char *mod, const char *format, va_list ap)
1787aec1d6eScindi {
1797aec1d6eScindi char *msg;
1807aec1d6eScindi size_t len;
1817aec1d6eScindi char c;
1827aec1d6eScindi
1837aec1d6eScindi len = vsnprintf(&c, 1, format, ap);
1847aec1d6eScindi msg = alloca(len + 2);
1857aec1d6eScindi (void) vsnprintf(msg, len + 1, format, ap);
1867aec1d6eScindi
1877aec1d6eScindi if (msg[len - 1] != '\n')
1887aec1d6eScindi (void) strcpy(&msg[len], "\n");
1897aec1d6eScindi
1900eb822a1Scindi if (thp->th_dbout == TOPO_DBOUT_SYSLOG) {
1910eb822a1Scindi if (mod == NULL) {
1920eb822a1Scindi syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s", msg);
1930eb822a1Scindi } else {
1940eb822a1Scindi syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s: %s",
1950eb822a1Scindi mod, msg);
1960eb822a1Scindi }
1970eb822a1Scindi } else {
1980eb822a1Scindi if (mod == NULL) {
1990eb822a1Scindi (void) fprintf(stderr, "libtopo DEBUG: %s", msg);
2000eb822a1Scindi } else {
2010eb822a1Scindi (void) fprintf(stderr, "libtopo DEBUG: %s: %s", mod,
2020eb822a1Scindi msg);
2030eb822a1Scindi }
2040eb822a1Scindi }
2057aec1d6eScindi }
2067aec1d6eScindi
2070eb822a1Scindi /*PRINTFLIKE3*/
2087aec1d6eScindi void
topo_dprintf(topo_hdl_t * thp,int mask,const char * format,...)2090eb822a1Scindi topo_dprintf(topo_hdl_t *thp, int mask, const char *format, ...)
2107aec1d6eScindi {
2117aec1d6eScindi va_list ap;
2127aec1d6eScindi
2131de1e652SRob Johnston if (!(thp->th_debug & mask))
2141de1e652SRob Johnston return;
2151de1e652SRob Johnston
2167aec1d6eScindi va_start(ap, format);
2171de1e652SRob Johnston topo_vdprintf(thp, NULL, format, ap);
2187aec1d6eScindi va_end(ap);
2197aec1d6eScindi }
2207aec1d6eScindi
2217aec1d6eScindi tnode_t *
topo_hdl_root(topo_hdl_t * thp,const char * scheme)2227aec1d6eScindi topo_hdl_root(topo_hdl_t *thp, const char *scheme)
2237aec1d6eScindi {
2247aec1d6eScindi ttree_t *tp;
225c5591576SRob Johnston topo_digraph_t *tdg;
2267aec1d6eScindi
2277aec1d6eScindi for (tp = topo_list_next(&thp->th_trees); tp != NULL;
2287aec1d6eScindi tp = topo_list_next(tp)) {
2297aec1d6eScindi if (strcmp(scheme, tp->tt_scheme) == 0)
2307aec1d6eScindi return (tp->tt_root);
2317aec1d6eScindi }
232c5591576SRob Johnston for (tdg = topo_list_next(&thp->th_digraphs); tdg != NULL;
233c5591576SRob Johnston tdg = topo_list_next(tdg)) {
234c5591576SRob Johnston if (strcmp(scheme, tdg->tdg_scheme) == 0)
235c5591576SRob Johnston return (tdg->tdg_rootnode);
236c5591576SRob Johnston }
2377aec1d6eScindi
2387aec1d6eScindi return (NULL);
2397aec1d6eScindi }
24074a31ce6Stimh
24174a31ce6Stimh /*
24274a31ce6Stimh * buf_append -- Append str to buf (if it's non-NULL). Place prepend
24374a31ce6Stimh * in buf in front of str and append behind it (if they're non-NULL).
24474a31ce6Stimh * Continue to update size even if we run out of space to actually
24574a31ce6Stimh * stuff characters in the buffer.
24674a31ce6Stimh */
24774a31ce6Stimh void
topo_fmristr_build(ssize_t * sz,char * buf,size_t buflen,char * str,char * prepend,char * append)24874a31ce6Stimh topo_fmristr_build(ssize_t *sz, char *buf, size_t buflen, char *str,
24974a31ce6Stimh char *prepend, char *append)
25074a31ce6Stimh {
25174a31ce6Stimh ssize_t left;
25274a31ce6Stimh
25374a31ce6Stimh if (str == NULL)
25474a31ce6Stimh return;
25574a31ce6Stimh
25674a31ce6Stimh if (buflen == 0 || (left = buflen - *sz) < 0)
25774a31ce6Stimh left = 0;
25874a31ce6Stimh
25974a31ce6Stimh if (buf != NULL && left != 0)
26074a31ce6Stimh buf += *sz;
26174a31ce6Stimh
26274a31ce6Stimh if (prepend == NULL && append == NULL)
26374a31ce6Stimh *sz += snprintf(buf, left, "%s", str);
26474a31ce6Stimh else if (append == NULL)
26574a31ce6Stimh *sz += snprintf(buf, left, "%s%s", prepend, str);
26674a31ce6Stimh else if (prepend == NULL)
26774a31ce6Stimh *sz += snprintf(buf, left, "%s%s", str, append);
26874a31ce6Stimh else
26974a31ce6Stimh *sz += snprintf(buf, left, "%s%s%s", prepend, str, append);
27074a31ce6Stimh }
2710eb822a1Scindi
2720eb822a1Scindi #define TOPO_PLATFORM_PATH "%s/usr/platform/%s/lib/fm/topo/%s"
2730eb822a1Scindi #define TOPO_COMMON_PATH "%s/usr/lib/fm/topo/%s"
2740eb822a1Scindi
2750eb822a1Scindi char *
topo_search_path(topo_mod_t * mod,const char * rootdir,const char * file)2760eb822a1Scindi topo_search_path(topo_mod_t *mod, const char *rootdir, const char *file)
2770eb822a1Scindi {
2780eb822a1Scindi char *pp, sp[PATH_MAX];
2790eb822a1Scindi topo_hdl_t *thp = mod->tm_hdl;
2800eb822a1Scindi
2810eb822a1Scindi /*
2820eb822a1Scindi * Search for file name in order of platform, machine and common
2830eb822a1Scindi * topo directories
2840eb822a1Scindi */
2850eb822a1Scindi (void) snprintf(sp, PATH_MAX, TOPO_PLATFORM_PATH, rootdir,
2860eb822a1Scindi thp->th_platform, file);
2870eb822a1Scindi if (access(sp, F_OK) != 0) {
2880eb822a1Scindi (void) snprintf(sp, PATH_MAX, TOPO_PLATFORM_PATH,
2890eb822a1Scindi thp->th_rootdir, thp->th_machine, file);
2900eb822a1Scindi if (access(sp, F_OK) != 0) {
2910eb822a1Scindi (void) snprintf(sp, PATH_MAX, TOPO_COMMON_PATH,
2920eb822a1Scindi thp->th_rootdir, file);
2930eb822a1Scindi if (access(sp, F_OK) != 0) {
2940eb822a1Scindi return (NULL);
2950eb822a1Scindi }
2960eb822a1Scindi }
2970eb822a1Scindi }
2980eb822a1Scindi
2990eb822a1Scindi pp = topo_mod_strdup(mod, sp);
3000eb822a1Scindi
3010eb822a1Scindi return (pp);
3020eb822a1Scindi }
30324db4641Seschrock
30424db4641Seschrock /*
305*9c994d58SRobert Mustacchi * SMBIOS serial numbers (and many other strings from devices) can contain
306*9c994d58SRobert Mustacchi * characters (particularly ':' and ' ') that are invalid for the authority and
307*9c994d58SRobert Mustacchi * can break FMRI parsing. We translate any invalid characters to a safe '-',
308*9c994d58SRobert Mustacchi * as well as trimming any leading or trailing whitespace. Similarly, '/' can
309*9c994d58SRobert Mustacchi * be found in some product names so we translate that to '-'.
31024db4641Seschrock */
31124db4641Seschrock char *
topo_cleanup_strn(topo_hdl_t * thp,const char * begin,size_t max)312*9c994d58SRobert Mustacchi topo_cleanup_strn(topo_hdl_t *thp, const char *begin, size_t max)
31324db4641Seschrock {
31424db4641Seschrock char buf[MAXNAMELEN];
315e3d60c9bSAdrian Frost const char *end, *cp;
316e3d60c9bSAdrian Frost char *pp;
317e3d60c9bSAdrian Frost char c;
318*9c994d58SRobert Mustacchi size_t i;
31924db4641Seschrock
320*9c994d58SRobert Mustacchi end = begin + max;
32124db4641Seschrock
32224db4641Seschrock while (begin < end && isspace(*begin))
32324db4641Seschrock begin++;
324*9c994d58SRobert Mustacchi while (begin < end && (isspace(*(end - 1)) || *(end - 1) == '\0'))
32524db4641Seschrock end--;
32624db4641Seschrock
32724db4641Seschrock if (begin >= end)
32824db4641Seschrock return (NULL);
32924db4641Seschrock
330e3d60c9bSAdrian Frost cp = begin;
331e3d60c9bSAdrian Frost for (i = 0; i < MAXNAMELEN - 1; i++) {
332e3d60c9bSAdrian Frost if (cp >= end)
333e3d60c9bSAdrian Frost break;
334e3d60c9bSAdrian Frost c = *cp;
335e3d60c9bSAdrian Frost if (c == ':' || c == '=' || c == '/' || isspace(c) ||
336e3d60c9bSAdrian Frost !isprint(c))
337e3d60c9bSAdrian Frost buf[i] = '-';
338e3d60c9bSAdrian Frost else
339e3d60c9bSAdrian Frost buf[i] = c;
340e3d60c9bSAdrian Frost cp++;
341e3d60c9bSAdrian Frost }
342e3d60c9bSAdrian Frost buf[i] = 0;
34324db4641Seschrock
34424db4641Seschrock pp = topo_hdl_strdup(thp, buf);
34524db4641Seschrock return (pp);
34624db4641Seschrock }
347825ba0f2Srobj
348*9c994d58SRobert Mustacchi char *
topo_cleanup_auth_str(topo_hdl_t * thp,const char * begin)349*9c994d58SRobert Mustacchi topo_cleanup_auth_str(topo_hdl_t *thp, const char *begin)
350*9c994d58SRobert Mustacchi {
351*9c994d58SRobert Mustacchi return (topo_cleanup_strn(thp, begin, strlen(begin)));
352*9c994d58SRobert Mustacchi }
353*9c994d58SRobert Mustacchi
354825ba0f2Srobj void
topo_sensor_type_name(uint32_t type,char * buf,size_t len)355825ba0f2Srobj topo_sensor_type_name(uint32_t type, char *buf, size_t len)
356825ba0f2Srobj {
357825ba0f2Srobj topo_name_trans_t *ntp;
358825ba0f2Srobj
359825ba0f2Srobj for (ntp = &topo_sensor_type_table[0]; ntp->int_name != NULL; ntp++) {
360825ba0f2Srobj if (ntp->int_value == type) {
361825ba0f2Srobj (void) strlcpy(buf, ntp->int_name, len);
362825ba0f2Srobj return;
363825ba0f2Srobj }
364825ba0f2Srobj }
365825ba0f2Srobj
366825ba0f2Srobj (void) snprintf(buf, len, "0x%02x", type);
367825ba0f2Srobj }
368825ba0f2Srobj
369825ba0f2Srobj void
topo_sensor_units_name(uint8_t type,char * buf,size_t len)370825ba0f2Srobj topo_sensor_units_name(uint8_t type, char *buf, size_t len)
371825ba0f2Srobj {
372825ba0f2Srobj topo_name_trans_t *ntp;
373825ba0f2Srobj
374825ba0f2Srobj for (ntp = &topo_units_type_table[0]; ntp->int_name != NULL; ntp++) {
375825ba0f2Srobj if (ntp->int_value == type) {
376825ba0f2Srobj (void) strlcpy(buf, ntp->int_name, len);
377825ba0f2Srobj return;
378825ba0f2Srobj }
379825ba0f2Srobj }
380825ba0f2Srobj
381825ba0f2Srobj (void) snprintf(buf, len, "0x%02x", type);
382825ba0f2Srobj }
383825ba0f2Srobj
384825ba0f2Srobj void
topo_led_type_name(uint8_t type,char * buf,size_t len)385825ba0f2Srobj topo_led_type_name(uint8_t type, char *buf, size_t len)
386825ba0f2Srobj {
387825ba0f2Srobj topo_name_trans_t *ntp;
388825ba0f2Srobj
389825ba0f2Srobj for (ntp = &topo_led_type_table[0]; ntp->int_name != NULL; ntp++) {
390825ba0f2Srobj if (ntp->int_value == type) {
391825ba0f2Srobj (void) strlcpy(buf, ntp->int_name, len);
392825ba0f2Srobj return;
393825ba0f2Srobj }
394825ba0f2Srobj }
395825ba0f2Srobj
396825ba0f2Srobj (void) snprintf(buf, len, "0x%02x", type);
397825ba0f2Srobj }
398825ba0f2Srobj
399825ba0f2Srobj void
topo_led_state_name(uint8_t type,char * buf,size_t len)400825ba0f2Srobj topo_led_state_name(uint8_t type, char *buf, size_t len)
401825ba0f2Srobj {
402825ba0f2Srobj topo_name_trans_t *ntp;
403825ba0f2Srobj
404825ba0f2Srobj for (ntp = &topo_led_states_table[0]; ntp->int_name != NULL; ntp++) {
405825ba0f2Srobj if (ntp->int_value == type) {
406825ba0f2Srobj (void) strlcpy(buf, ntp->int_name, len);
407825ba0f2Srobj return;
408825ba0f2Srobj }
409825ba0f2Srobj }
410825ba0f2Srobj
411825ba0f2Srobj (void) snprintf(buf, len, "0x%02x", type);
412825ba0f2Srobj }
413825ba0f2Srobj
414825ba0f2Srobj void
topo_sensor_state_name(uint32_t sensor_type,uint8_t state,char * buf,size_t len)415825ba0f2Srobj topo_sensor_state_name(uint32_t sensor_type, uint8_t state, char *buf,
4168522c52aSRob Johnston size_t len)
417825ba0f2Srobj {
418825ba0f2Srobj topo_name_trans_t *ntp;
419825ba0f2Srobj
420825ba0f2Srobj switch (sensor_type) {
421825ba0f2Srobj case TOPO_SENSOR_TYPE_PHYSICAL:
422825ba0f2Srobj ntp = &topo_sensor_states_physical_table[0];
423825ba0f2Srobj break;
424825ba0f2Srobj case TOPO_SENSOR_TYPE_PLATFORM:
425825ba0f2Srobj ntp = &topo_sensor_states_platform_table[0];
426825ba0f2Srobj break;
427825ba0f2Srobj case TOPO_SENSOR_TYPE_PROCESSOR:
428825ba0f2Srobj ntp = &topo_sensor_states_processor_table[0];
429825ba0f2Srobj break;
430825ba0f2Srobj case TOPO_SENSOR_TYPE_POWER_SUPPLY:
431825ba0f2Srobj ntp = &topo_sensor_states_power_supply_table[0];
432825ba0f2Srobj break;
433825ba0f2Srobj case TOPO_SENSOR_TYPE_POWER_UNIT:
434825ba0f2Srobj ntp = &topo_sensor_states_power_unit_table[0];
435825ba0f2Srobj break;
436825ba0f2Srobj case TOPO_SENSOR_TYPE_MEMORY:
437825ba0f2Srobj ntp = &topo_sensor_states_memory_table[0];
438825ba0f2Srobj break;
439825ba0f2Srobj case TOPO_SENSOR_TYPE_BAY:
440825ba0f2Srobj ntp = &topo_sensor_states_bay_table[0];
441825ba0f2Srobj break;
442825ba0f2Srobj case TOPO_SENSOR_TYPE_FIRMWARE:
443825ba0f2Srobj ntp = &topo_sensor_states_firmware_table[0];
444825ba0f2Srobj break;
445825ba0f2Srobj case TOPO_SENSOR_TYPE_EVENT_LOG:
446825ba0f2Srobj ntp = &topo_sensor_states_event_log_table[0];
447825ba0f2Srobj break;
448825ba0f2Srobj case TOPO_SENSOR_TYPE_WATCHDOG1:
449825ba0f2Srobj ntp = &topo_sensor_states_watchdog1_table[0];
450825ba0f2Srobj break;
451825ba0f2Srobj case TOPO_SENSOR_TYPE_SYSTEM:
452825ba0f2Srobj ntp = &topo_sensor_states_system_table[0];
453825ba0f2Srobj break;
454825ba0f2Srobj case TOPO_SENSOR_TYPE_CRITICAL:
455825ba0f2Srobj ntp = &topo_sensor_states_critical_table[0];
456825ba0f2Srobj break;
457825ba0f2Srobj case TOPO_SENSOR_TYPE_BUTTON:
458825ba0f2Srobj ntp = &topo_sensor_states_button_table[0];
459825ba0f2Srobj break;
460825ba0f2Srobj case TOPO_SENSOR_TYPE_CABLE:
461825ba0f2Srobj ntp = &topo_sensor_states_cable_table[0];
462825ba0f2Srobj break;
463825ba0f2Srobj case TOPO_SENSOR_TYPE_BOOT_STATE:
464825ba0f2Srobj ntp = &topo_sensor_states_boot_state_table[0];
465825ba0f2Srobj break;
466825ba0f2Srobj case TOPO_SENSOR_TYPE_BOOT_ERROR:
467825ba0f2Srobj ntp = &topo_sensor_states_boot_error_table[0];
468825ba0f2Srobj break;
469825ba0f2Srobj case TOPO_SENSOR_TYPE_BOOT_OS:
470825ba0f2Srobj ntp = &topo_sensor_states_boot_os_table[0];
471825ba0f2Srobj break;
472825ba0f2Srobj case TOPO_SENSOR_TYPE_OS_SHUTDOWN:
473825ba0f2Srobj ntp = &topo_sensor_states_os_table[0];
474825ba0f2Srobj break;
475825ba0f2Srobj case TOPO_SENSOR_TYPE_SLOT:
476825ba0f2Srobj ntp = &topo_sensor_states_slot_table[0];
477825ba0f2Srobj break;
478825ba0f2Srobj case TOPO_SENSOR_TYPE_ACPI:
479825ba0f2Srobj ntp = &topo_sensor_states_acpi_table[0];
480825ba0f2Srobj break;
481825ba0f2Srobj case TOPO_SENSOR_TYPE_WATCHDOG2:
482825ba0f2Srobj ntp = &topo_sensor_states_watchdog2_table[0];
483825ba0f2Srobj break;
484825ba0f2Srobj case TOPO_SENSOR_TYPE_ALERT:
485825ba0f2Srobj ntp = &topo_sensor_states_alert_table[0];
486825ba0f2Srobj break;
487825ba0f2Srobj case TOPO_SENSOR_TYPE_PRESENCE:
488825ba0f2Srobj ntp = &topo_sensor_states_presence_table[0];
489825ba0f2Srobj break;
490825ba0f2Srobj case TOPO_SENSOR_TYPE_LAN:
491825ba0f2Srobj ntp = &topo_sensor_states_lan_table[0];
492825ba0f2Srobj break;
493825ba0f2Srobj case TOPO_SENSOR_TYPE_HEALTH:
494825ba0f2Srobj ntp = &topo_sensor_states_health_table[0];
495825ba0f2Srobj break;
496825ba0f2Srobj case TOPO_SENSOR_TYPE_BATTERY:
497825ba0f2Srobj ntp = &topo_sensor_states_battery_table[0];
498825ba0f2Srobj break;
499825ba0f2Srobj case TOPO_SENSOR_TYPE_AUDIT:
500825ba0f2Srobj ntp = &topo_sensor_states_audit_table[0];
501825ba0f2Srobj break;
502825ba0f2Srobj case TOPO_SENSOR_TYPE_VERSION:
503825ba0f2Srobj ntp = &topo_sensor_states_version_table[0];
504825ba0f2Srobj break;
505825ba0f2Srobj case TOPO_SENSOR_TYPE_FRU_STATE:
506825ba0f2Srobj ntp = &topo_sensor_states_fru_state_table[0];
507825ba0f2Srobj break;
508825ba0f2Srobj case TOPO_SENSOR_TYPE_THRESHOLD_STATE:
509825ba0f2Srobj ntp = &topo_sensor_states_thresh_table[0];
510825ba0f2Srobj break;
511825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_USAGE:
512825ba0f2Srobj ntp = &topo_sensor_states_generic_usage_table[0];
513825ba0f2Srobj break;
514825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_STATE:
515825ba0f2Srobj ntp = &topo_sensor_states_generic_state_table[0];
516825ba0f2Srobj break;
517825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_PREDFAIL:
518825ba0f2Srobj ntp = &topo_sensor_states_generic_predfail_table[0];
519825ba0f2Srobj break;
520825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_LIMIT:
521825ba0f2Srobj ntp = &topo_sensor_states_generic_limit_table[0];
522825ba0f2Srobj break;
523825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_PERFORMANCE:
524825ba0f2Srobj ntp = &topo_sensor_states_generic_perf_table[0];
525825ba0f2Srobj break;
526825ba0f2Srobj case TOPO_SENSOR_TYPE_SEVERITY:
527825ba0f2Srobj ntp = &topo_sensor_states_severity_table[0];
528825ba0f2Srobj break;
529825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_PRESENCE:
530825ba0f2Srobj ntp = &topo_sensor_states_generic_presence_table[0];
531825ba0f2Srobj break;
532825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_AVAILABILITY:
533825ba0f2Srobj ntp = &topo_sensor_states_generic_avail_table[0];
534825ba0f2Srobj break;
535825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_STATUS:
536825ba0f2Srobj ntp = &topo_sensor_states_generic_status_table[0];
537825ba0f2Srobj break;
538825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_ACPI:
539825ba0f2Srobj ntp = &topo_sensor_states_generic_acpi_pwr_table[0];
540825ba0f2Srobj break;
541e5dcf7beSRobert Johnston case TOPO_SENSOR_TYPE_GENERIC_FAILURE:
542e5dcf7beSRobert Johnston ntp = &topo_sensor_states_generic_failure_table[0];
543e5dcf7beSRobert Johnston break;
544e5dcf7beSRobert Johnston case TOPO_SENSOR_TYPE_GENERIC_OK:
545e5dcf7beSRobert Johnston ntp = &topo_sensor_states_generic_ok_table[0];
546e5dcf7beSRobert Johnston break;
547825ba0f2Srobj default:
548825ba0f2Srobj (void) snprintf(buf, len, "0x%02x", state);
549825ba0f2Srobj return;
550825ba0f2Srobj }
551881aaecdSRob Johnston if (state == 0) {
552881aaecdSRob Johnston (void) snprintf(buf, len, "NO_STATES_ASSERTED");
553881aaecdSRob Johnston return;
554881aaecdSRob Johnston }
555881aaecdSRob Johnston buf[0] = '\0';
556825ba0f2Srobj for (; ntp->int_name != NULL; ntp++) {
557881aaecdSRob Johnston if (state & ntp->int_value) {
558881aaecdSRob Johnston if (buf[0] != '\0')
559881aaecdSRob Johnston (void) strlcat(buf, "|", len);
560881aaecdSRob Johnston (void) strlcat(buf, ntp->int_name, len);
561825ba0f2Srobj }
562825ba0f2Srobj }
563825ba0f2Srobj
564881aaecdSRob Johnston if (buf[0] == '\0')
565881aaecdSRob Johnston (void) snprintf(buf, len, "0x%02x", state);
566825ba0f2Srobj }
5678522c52aSRob Johnston
5688522c52aSRob Johnston static const topo_pgroup_info_t sys_pgroup = {
5698522c52aSRob Johnston TOPO_PGROUP_SYSTEM,
5708522c52aSRob Johnston TOPO_STABILITY_PRIVATE,
5718522c52aSRob Johnston TOPO_STABILITY_PRIVATE,
5728522c52aSRob Johnston 1
5738522c52aSRob Johnston };
5748522c52aSRob Johnston static const topo_pgroup_info_t auth_pgroup = {
5758522c52aSRob Johnston FM_FMRI_AUTHORITY,
5768522c52aSRob Johnston TOPO_STABILITY_PRIVATE,
5778522c52aSRob Johnston TOPO_STABILITY_PRIVATE,
5788522c52aSRob Johnston 1
5798522c52aSRob Johnston };
5808522c52aSRob Johnston
5818522c52aSRob Johnston void
topo_pgroup_hcset(tnode_t * node,nvlist_t * auth)5828522c52aSRob Johnston topo_pgroup_hcset(tnode_t *node, nvlist_t *auth)
5838522c52aSRob Johnston {
5848522c52aSRob Johnston int err;
5858522c52aSRob Johnston char isa[MAXNAMELEN];
5868522c52aSRob Johnston struct utsname uts;
5878522c52aSRob Johnston char *prod, *psn, *csn, *server;
5888522c52aSRob Johnston
5898522c52aSRob Johnston if (auth == NULL)
5908522c52aSRob Johnston return;
5918522c52aSRob Johnston
5928522c52aSRob Johnston if (topo_pgroup_create(node, &auth_pgroup, &err) != 0) {
5938522c52aSRob Johnston if (err != ETOPO_PROP_DEFD)
5948522c52aSRob Johnston return;
5958522c52aSRob Johnston }
5968522c52aSRob Johnston
5978522c52aSRob Johnston /*
5988522c52aSRob Johnston * Inherit if we can, it saves memory
5998522c52aSRob Johnston */
6008522c52aSRob Johnston if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT,
6018522c52aSRob Johnston &err) != 0) && (err != ETOPO_PROP_DEFD)) {
6028522c52aSRob Johnston if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT, &prod) ==
6038522c52aSRob Johnston 0)
6048522c52aSRob Johnston (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
6058522c52aSRob Johnston FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod,
6068522c52aSRob Johnston &err);
6078522c52aSRob Johnston }
6088522c52aSRob Johnston if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT_SN,
6098522c52aSRob Johnston &err) != 0) && (err != ETOPO_PROP_DEFD)) {
6108522c52aSRob Johnston if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN, &psn) ==
6118522c52aSRob Johnston 0)
6128522c52aSRob Johnston (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
6138522c52aSRob Johnston FM_FMRI_AUTH_PRODUCT_SN, TOPO_PROP_IMMUTABLE, psn,
6148522c52aSRob Johnston &err);
6158522c52aSRob Johnston }
6168522c52aSRob Johnston if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS,
6178522c52aSRob Johnston &err) != 0) && (err != ETOPO_PROP_DEFD)) {
6188522c52aSRob Johnston if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &csn) == 0)
6198522c52aSRob Johnston (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
6208522c52aSRob Johnston FM_FMRI_AUTH_CHASSIS, TOPO_PROP_IMMUTABLE, csn,
6218522c52aSRob Johnston &err);
6228522c52aSRob Johnston }
6238522c52aSRob Johnston if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_SERVER,
6248522c52aSRob Johnston &err) != 0) && (err != ETOPO_PROP_DEFD)) {
6258522c52aSRob Johnston if (nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER, &server) ==
6268522c52aSRob Johnston 0)
6278522c52aSRob Johnston (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
6288522c52aSRob Johnston FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server,
6298522c52aSRob Johnston &err);
6308522c52aSRob Johnston }
6318522c52aSRob Johnston
6328522c52aSRob Johnston if (topo_pgroup_create(node, &sys_pgroup, &err) != 0)
6338522c52aSRob Johnston return;
6348522c52aSRob Johnston
6358522c52aSRob Johnston if (sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)) != -1)
6368522c52aSRob Johnston (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM,
6378522c52aSRob Johnston TOPO_PROP_ISA, TOPO_PROP_IMMUTABLE, isa, &err);
6388522c52aSRob Johnston
6398522c52aSRob Johnston if (uname(&uts) != -1)
6408522c52aSRob Johnston (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM,
6418522c52aSRob Johnston TOPO_PROP_MACHINE, TOPO_PROP_IMMUTABLE, uts.machine, &err);
6428522c52aSRob Johnston }
643