PSARC 2008/428 Extending libnvpair for type double
PSARC 2008/463 Extending HC FMRI scheme to represent sensors/indicators
6579615 fmtopo -e has lots of memory leaks
6635159 libtopo: extend hc scheme to allow for representing sensors and indicators in the topology
6692392 fmtopo -x doesn't handle property methods properly
6718703 Need to extend libnvpair to support type double
6718712 libtopo: Need to implement facility provider module for IPMI
6722594 libtopo: the topo_prop_set_* interfaces need to learn to play well with propmethods
6727190 libtopo: add support for node properties of type double
6727459 libipmi: need interface to convert raw sensor readings to unit-based values
6727470 libipmi: need convenience routine to convert sensor unit defines to string
6729595 libtopo: add <set> case in fan and psu xml maps for SUN-FIRE-X4600-M2
6732318 fmd: small leak in sysevent modelling code
--- a/usr/src/cmd/fm/fmd/common/fmd_sysevent.c Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/cmd/fm/fmd/common/fmd_sysevent.c Thu Jul 31 17:35:39 2008 -0700
@@ -119,8 +119,10 @@
(void) nvlist_xalloc(&nvl, NV_UNIQUE_NAME, &fmd.d_nva);
(void) nvlist_add_string(nvl, FM_CLASS, fullclass);
(void) nvlist_add_uint8(nvl, FM_VERSION, FM_RSRC_VERSION);
- if (sysevent_get_attr_list(sep, &attr) == 0)
+ if (sysevent_get_attr_list(sep, &attr) == 0) {
(void) nvlist_merge(nvl, attr, 0);
+ nvlist_free(attr);
+ }
/*
* Dispatch the event. Ideally, we'd like to use the same transport
--- a/usr/src/cmd/fm/fmtopo/common/fmtopo.c Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/cmd/fm/fmtopo/common/fmtopo.c Thu Jul 31 17:35:39 2008 -0700
@@ -50,11 +50,12 @@
static const char *opt_R = "/";
static const char *opt_s = FM_FMRI_SCHEME_HC;
-static const char optstr[] = "bCdeP:pR:s:StVx";
+static const char optstr[] = "bCdeEP:pR:s:StVx";
static int opt_b = 0;
static int opt_d = 0;
static int opt_e = 0;
+static int opt_E = 0;
static int opt_p = 0;
static int opt_S = 0;
static int opt_t = 0;
@@ -76,7 +77,7 @@
usage(FILE *fp)
{
(void) fprintf(fp,
- "Usage: %s [-bCedpSVx] [-P group.property[=type:value]] "
+ "Usage: %s [-bCeEdpSVx] [-P group.property[=type:value]] "
"[-R root] [-s scheme] [fmri]\n", g_pname);
(void) fprintf(fp,
@@ -84,6 +85,7 @@
"\t-C dump core after completing execution\n"
"\t-d set debug mode for libtopo modules\n"
"\t-e display FMRIs as paths using esc/eft notation\n"
+ "\t-E enumerate sensor nodes\n"
"\t-P get/set specified properties\n"
"\t-p display of FMRI protocol properties\n"
"\t-R set root directory for libtopo plug-ins and other files\n"
@@ -196,6 +198,7 @@
(void) fprintf(stderr, "%s: failed to find %s for %s=%d\n",
g_pname, FM_FMRI_HC_LIST, topo_node_name(node),
topo_node_instance(node));
+ nvlist_free(fmri);
return;
}
@@ -210,6 +213,7 @@
(void) fprintf(stderr, "%s: failed to get "
"name-instance for %s=%d\n", g_pname,
topo_node_name(node), topo_node_instance(node));
+ nvlist_free(fmri);
return;
}
@@ -226,16 +230,17 @@
(void) snprintf(numbuf, sizeof (numbuf), "%u", ul);
(void) strlcat(buf, numbuf, sizeof (buf));
}
+ nvlist_free(fmri);
(void) printf("%s\n", buf);
}
static void
-print_prop_nameval(topo_hdl_t *thp, nvlist_t *nvl)
+print_prop_nameval(topo_hdl_t *thp, tnode_t *node, nvlist_t *nvl)
{
int err;
topo_type_t type;
- char *tstr, *propn, buf[48];
+ char *tstr, *propn, buf[48], *factype;
nvpair_t *pv_nvp;
int i;
uint_t nelem;
@@ -271,6 +276,7 @@
case TOPO_TYPE_UINT32: tstr = "uint32"; break;
case TOPO_TYPE_INT64: tstr = "int64"; break;
case TOPO_TYPE_UINT64: tstr = "uint64"; break;
+ case TOPO_TYPE_DOUBLE: tstr = "double"; break;
case TOPO_TYPE_STRING: tstr = "string"; break;
case TOPO_TYPE_FMRI: tstr = "fmri"; break;
case TOPO_TYPE_INT32_ARRAY: tstr = "int32[]"; break;
@@ -302,9 +308,65 @@
break;
}
case DATA_TYPE_UINT32: {
- uint32_t val;
+ uint32_t val, type;
+ char val_str[49];
+ nvlist_t *fac, *rsrc = NULL;
+
(void) nvpair_value_uint32(pv_nvp, &val);
+ if (node == NULL || topo_node_flags(node) !=
+ TOPO_NODE_FACILITY)
+ goto uint32_def;
+
+ if (topo_node_resource(node, &rsrc, &err) != 0)
+ goto uint32_def;
+
+ if (nvlist_lookup_nvlist(rsrc, "facility", &fac) != 0)
+ goto uint32_def;
+
+ if (nvlist_lookup_string(fac, FM_FMRI_FACILITY_TYPE,
+ &factype) != 0)
+ goto uint32_def;
+
+ nvlist_free(rsrc);
+ rsrc = NULL;
+
+ /*
+ * Special case code to do friendlier printing of
+ * facility node properties
+ */
+ if ((strcmp(propn, TOPO_FACILITY_TYPE) == 0) &&
+ (strcmp(factype, TOPO_FAC_TYPE_SENSOR) == 0)) {
+ topo_sensor_type_name(val, val_str, 48);
+ (void) printf(" 0x%x (%s)", val, val_str);
+ break;
+ } else if ((strcmp(propn, TOPO_FACILITY_TYPE) == 0) &&
+ (strcmp(factype, TOPO_FAC_TYPE_INDICATOR) == 0)) {
+ topo_led_type_name(val, val_str, 48);
+ (void) printf(" 0x%x (%s)", val, val_str);
+ break;
+ } else if (strcmp(propn, TOPO_SENSOR_UNITS) == 0) {
+ topo_sensor_units_name(val, val_str, 48);
+ (void) printf(" 0x%x (%s)", val, val_str);
+ break;
+ } else if (strcmp(propn, TOPO_LED_MODE) == 0) {
+ topo_led_state_name(val, val_str, 48);
+ (void) printf(" 0x%x (%s)", val, val_str);
+ break;
+ } else if ((strcmp(propn, TOPO_SENSOR_STATE) == 0) &&
+ (strcmp(factype, TOPO_FAC_TYPE_SENSOR) == 0)) {
+ if (topo_prop_get_uint32(node,
+ TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE,
+ &type, &err) != 0) {
+ goto uint32_def;
+ }
+ topo_sensor_state_name(type, val, val_str, 48);
+ (void) printf(" 0x%x (%s)", val, val_str);
+ break;
+ }
+uint32_def:
(void) printf(" 0x%x", val);
+ if (rsrc != NULL)
+ nvlist_free(rsrc);
break;
}
case DATA_TYPE_INT64: {
@@ -319,6 +381,12 @@
(void) printf(" 0x%llx", (u_longlong_t)val);
break;
}
+ case DATA_TYPE_DOUBLE: {
+ double val;
+ (void) nvpair_value_double(pv_nvp, &val);
+ (void) printf(" %lf", (double)val);
+ break;
+ }
case DATA_TYPE_STRING: {
char *val;
(void) nvpair_value_string(pv_nvp, &val);
@@ -361,6 +429,16 @@
(void) printf("]");
break;
}
+ case DATA_TYPE_INT64_ARRAY: {
+ int64_t *val;
+
+ (void) nvpair_value_int64_array(pv_nvp, &val, &nelem);
+ (void) printf(" [ ");
+ for (i = 0; i < nelem; i++)
+ (void) printf("%lld ", val[i]);
+ (void) printf("]");
+ break;
+ }
case DATA_TYPE_STRING_ARRAY: {
char **val;
@@ -483,7 +561,7 @@
== 0 && nvpair_type(pg_nvp) == DATA_TYPE_NVLIST) {
(void) nvpair_value_nvlist(pg_nvp, &pv_nv);
if ((match || all) && pg_done) {
- print_prop_nameval(thp, pv_nv);
+ print_prop_nameval(thp, node, pv_nv);
}
}
@@ -649,7 +727,7 @@
}
print_pgroup(thp, node, pp->group, NULL, NULL, 0);
- print_prop_nameval(thp, nvl);
+ print_prop_nameval(thp, node, nvl);
nvlist_free(nvl);
nvlist_free(f);
@@ -706,7 +784,7 @@
} else {
print_pgroup(thp, node, pp->group, NULL,
NULL, 0);
- print_prop_nameval(thp, nvl);
+ print_prop_nameval(thp, node, nvl);
nvlist_free(nvl);
}
} else {
@@ -721,7 +799,7 @@
{
int err;
nvlist_t *nvl;
- nvlist_t *rsrc;
+ nvlist_t *rsrc, *out;
char *s;
if (opt_e && strcmp(opt_s, FM_FMRI_SCHEME_HC) == 0) {
@@ -752,6 +830,24 @@
topo_hdl_strfree(thp, s);
nvlist_free(rsrc);
+ /*
+ * If the "-E" option was specified, we want to also enumerate any
+ * available facility nodes. To do that we check if the node supports
+ * a facility enumerator method. If it exists, then we invoke it to
+ * enumerate the sensors for this node.
+ */
+ if (opt_E) {
+ if (topo_method_supported(node, TOPO_METH_FAC_ENUM, 0))
+ if (topo_method_invoke(node, TOPO_METH_FAC_ENUM, 0,
+ NULL, &out, &err) != 0) {
+ (void) fprintf(stderr,
+ "topo_method_invoke failed (%s) on node "
+ "%s=%d\n", topo_strerror(err),
+ topo_node_name(node),
+ topo_node_instance(node));
+ }
+ }
+
if (opt_V || opt_all) {
if ((nvl = topo_prop_getprops(node, &err)) == NULL) {
(void) fprintf(stderr, "%s: failed to get "
@@ -762,9 +858,8 @@
print_all_props(thp, node, nvl, ALL);
nvlist_free(nvl);
}
- } else if (pcnt > 0) {
+ } else if (pcnt > 0)
print_props(thp, node);
- }
printf("\n");
@@ -911,7 +1006,7 @@
if (strcmp(TOPO_PROP_VAL, nvpair_name(pnvp))
== 0 && nvpair_type(pnvp) == DATA_TYPE_NVLIST) {
(void) nvpair_value_nvlist(pnvp, &pnvl);
- print_prop_nameval(thp, pnvl);
+ print_prop_nameval(thp, NULL, pnvl);
}
@@ -951,7 +1046,8 @@
pp->group, topo_strerror(err));
continue;
} else {
- print_fmri_pgroup(thp, pp->group, pnvl);
+ print_fmri_pgroup(thp, pp->group,
+ pnvl);
nvlist_free(pnvl);
continue;
}
@@ -965,7 +1061,7 @@
continue;
} else {
print_fmri_pgroup(thp, pp->group, pnvl);
- print_prop_nameval(thp, pnvl);
+ print_prop_nameval(thp, NULL, pnvl);
nvlist_free(nvl);
}
} else {
@@ -1100,6 +1196,9 @@
case 'e':
opt_e++;
break;
+ case 'E':
+ opt_E++;
+ break;
case 'P':
pcnt++;
break;
--- a/usr/src/common/nvpair/nvpair.c Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/common/nvpair/nvpair.c Thu Jul 31 17:35:39 2008 -0700
@@ -402,6 +402,9 @@
case DATA_TYPE_STRING:
case DATA_TYPE_HRTIME:
case DATA_TYPE_NVLIST:
+#if !defined(_KERNEL)
+ case DATA_TYPE_DOUBLE:
+#endif
if (nelem != 1)
return (EINVAL);
break;
@@ -740,6 +743,11 @@
case DATA_TYPE_UINT64:
value_sz = sizeof (uint64_t);
break;
+#if !defined(_KERNEL)
+ case DATA_TYPE_DOUBLE:
+ value_sz = sizeof (double);
+ break;
+#endif
case DATA_TYPE_STRING:
if (data == NULL)
value_sz = 0;
@@ -1024,6 +1032,14 @@
return (nvlist_add_common(nvl, name, DATA_TYPE_UINT64, 1, &val));
}
+#if !defined(_KERNEL)
+int
+nvlist_add_double(nvlist_t *nvl, const char *name, double val)
+{
+ return (nvlist_add_common(nvl, name, DATA_TYPE_DOUBLE, 1, &val));
+}
+#endif
+
int
nvlist_add_string(nvlist_t *nvl, const char *name, const char *val)
{
@@ -1206,6 +1222,9 @@
case DATA_TYPE_INT64:
case DATA_TYPE_UINT64:
case DATA_TYPE_HRTIME:
+#if !defined(_KERNEL)
+ case DATA_TYPE_DOUBLE:
+#endif
if (data == NULL)
return (EINVAL);
bcopy(NVP_VALUE(nvp), data,
@@ -1342,6 +1361,14 @@
return (nvlist_lookup_common(nvl, name, DATA_TYPE_UINT64, NULL, val));
}
+#if !defined(_KERNEL)
+int
+nvlist_lookup_double(nvlist_t *nvl, const char *name, double *val)
+{
+ return (nvlist_lookup_common(nvl, name, DATA_TYPE_DOUBLE, NULL, val));
+}
+#endif
+
int
nvlist_lookup_string(nvlist_t *nvl, const char *name, char **val)
{
@@ -1476,6 +1503,9 @@
case DATA_TYPE_HRTIME:
case DATA_TYPE_STRING:
case DATA_TYPE_NVLIST:
+#if !defined(_KERNEL)
+ case DATA_TYPE_DOUBLE:
+#endif
val = va_arg(ap, void *);
ret = nvlist_lookup_common(nvl, name, type, NULL, val);
break;
@@ -1787,6 +1817,14 @@
return (nvpair_value_common(nvp, DATA_TYPE_UINT64, NULL, val));
}
+#if !defined(_KERNEL)
+int
+nvpair_value_double(nvpair_t *nvp, double *val)
+{
+ return (nvpair_value_common(nvp, DATA_TYPE_DOUBLE, NULL, val));
+}
+#endif
+
int
nvpair_value_string(nvpair_t *nvp, char **val)
{
@@ -2924,7 +2962,11 @@
*/
ret = xdr_longlong_t(xdr, (void *)buf);
break;
-
+#if !defined(_KERNEL)
+ case DATA_TYPE_DOUBLE:
+ ret = xdr_double(xdr, (void *)buf);
+ break;
+#endif
case DATA_TYPE_STRING:
ret = xdr_string(xdr, &buf, buflen - 1);
break;
@@ -3030,6 +3072,9 @@
case DATA_TYPE_INT64:
case DATA_TYPE_UINT64:
case DATA_TYPE_HRTIME:
+#if !defined(_KERNEL)
+ case DATA_TYPE_DOUBLE:
+#endif
nvp_sz += 8;
break;
--- a/usr/src/lib/fm/topo/libtopo/Makefile.com Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/Makefile.com Thu Jul 31 17:35:39 2008 -0700
@@ -59,6 +59,7 @@
topo_snap.c \
topo_string.c \
topo_subr.c \
+ topo_tables.c \
topo_tree.c \
topo_xml.c
@@ -72,7 +73,7 @@
SRCDIR = ../common
-CLEANFILES += ../common/topo_error.c
+CLEANFILES += $(SRCDIR)/topo_error.c $(SRCDIR)/topo_tables.c
CPPFLAGS += -I../common -I/usr/include/libxml2 -I.
CFLAGS += $(CCVERBOSE) $(C_BIGPICFLAGS)
@@ -113,5 +114,8 @@
sh ../common/mkerror.sh hdlerrors < ../common/libtopo.h >> $@
sh ../common/mkerror.sh moderrors < ../common/topo_mod.h >> $@
+$(SRCDIR)/topo_tables.c: $(SRCDIR)/mktables.sh $(SRCDIR)/libtopo.h
+ sh $(SRCDIR)/mktables.sh $(SRCDIR)/libtopo.h > $@
+
include ../../../../Makefile.targ
include ../../../Makefile.targ
--- a/usr/src/lib/fm/topo/libtopo/common/hc.c Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/hc.c Thu Jul 31 17:35:39 2008 -0700
@@ -44,6 +44,7 @@
#include <sys/utsname.h>
#include <topo_method.h>
+#include <topo_module.h>
#include <topo_subr.h>
#include <topo_prop.h>
#include <topo_tree.h>
@@ -70,6 +71,8 @@
nvlist_t *, nvlist_t **);
static int hc_fmri_pgrp_get(topo_mod_t *, tnode_t *, topo_version_t,
nvlist_t *, nvlist_t **);
+static int hc_fmri_facility(topo_mod_t *, tnode_t *, topo_version_t,
+ nvlist_t *, nvlist_t **);
static nvlist_t *hc_fmri_create(topo_mod_t *, nvlist_t *, int, const char *,
topo_instance_t inst, const nvlist_t *, const char *, const char *,
@@ -98,6 +101,9 @@
{ TOPO_METH_PGRP_GET, TOPO_METH_PGRP_GET_DESC,
TOPO_METH_PGRP_GET_VERSION, TOPO_STABILITY_INTERNAL,
hc_fmri_pgrp_get },
+ { TOPO_METH_FACILITY, TOPO_METH_FACILITY_DESC,
+ TOPO_METH_FACILITY_VERSION, TOPO_STABILITY_INTERNAL,
+ hc_fmri_facility },
{ NULL }
};
@@ -325,8 +331,10 @@
{
uint8_t v1, v2;
nvlist_t **hcp1, **hcp2;
+ nvlist_t *f1 = NULL, *f2 = NULL;
int err, i;
uint_t nhcp1, nhcp2;
+ char *f1str, *f2str;
if (nvlist_lookup_uint8(nv1, FM_VERSION, &v1) != 0 ||
nvlist_lookup_uint8(nv2, FM_VERSION, &v2) != 0 ||
@@ -360,7 +368,28 @@
return (0);
}
- return (1);
+ /*
+ * Finally, check if the FMRI's represent a facility node. If so, then
+ * verify that the facilty type ("sensor"|"indicator") and facility
+ * name match.
+ */
+ (void) nvlist_lookup_nvlist(nv1, FM_FMRI_FACILITY, &f1);
+ (void) nvlist_lookup_nvlist(nv2, FM_FMRI_FACILITY, &f2);
+
+ if (f1 == NULL && f2 == NULL)
+ return (1);
+ else if (f1 == NULL || f2 == NULL)
+ return (0);
+
+ if (nvlist_lookup_string(f1, FM_FMRI_FACILITY_NAME, &f1str) == 0 &&
+ nvlist_lookup_string(f2, FM_FMRI_FACILITY_NAME, &f2str) == 0 &&
+ strcmp(f1str, f2str) == 0 &&
+ nvlist_lookup_string(f1, FM_FMRI_FACILITY_TYPE, &f1str) == 0 &&
+ nvlist_lookup_string(f2, FM_FMRI_FACILITY_TYPE, &f2str) == 0 &&
+ strcmp(f1str, f2str) == 0) {
+ return (1);
+ }
+ return (0);
}
/*ARGSUSED*/
@@ -400,6 +429,7 @@
{
nvlist_t **hcprs = NULL;
nvlist_t *anvl = NULL;
+ nvlist_t *fnvl;
uint8_t version;
ssize_t size = 0;
uint_t hcnprs;
@@ -412,6 +442,7 @@
char *part = NULL;
char *root = NULL;
char *rev = NULL;
+ char *fname = NULL, *ftype = NULL;
int more_auth = 0;
int err, i;
@@ -508,6 +539,22 @@
topo_fmristr_build(&size, buf, buflen, id, NULL, NULL);
}
+ /*
+ * If the nvlist represents a facility node, then we append the
+ * facility type and name to the end of the string representation using
+ * the format below:
+ *
+ * ?<ftype>=<fname>
+ */
+ if (nvlist_lookup_nvlist(nvl, FM_FMRI_FACILITY, &fnvl) == 0) {
+ if (nvlist_lookup_string(fnvl, FM_FMRI_FACILITY_NAME,
+ &fname) != 0 || nvlist_lookup_string(fnvl,
+ FM_FMRI_FACILITY_TYPE, &ftype) != 0)
+ return (0);
+ topo_fmristr_build(&size, buf, buflen, "?", NULL, NULL);
+ topo_fmristr_build(&size, buf, buflen, "=", ftype, fname);
+ }
+
return (size);
}
@@ -707,17 +754,17 @@
return (pa);
}
-void
+int
make_hc_auth(topo_mod_t *mod, char *fmri, char **serial, char **part,
char **rev, nvlist_t **auth)
{
char *starti, *startn, *endi, *copy;
- char *aname, *aid, *fs;
+ char *aname = NULL, *aid = NULL, *fs;
nvlist_t *na = NULL;
size_t len;
if ((copy = topo_mod_strdup(mod, fmri + 5)) == NULL)
- return;
+ return (-1);
len = strlen(copy);
@@ -729,7 +776,7 @@
if (startn == NULL || fs == NULL) {
topo_mod_strfree(mod, copy);
- return;
+ return (0);
}
/*
@@ -737,21 +784,21 @@
* first slash
*/
if (startn > fs)
- return;
+ goto hcabail;
do {
if (++startn >= copy + len)
break;
if ((starti = strchr(startn, '=')) == NULL)
- break;
+ goto hcabail;
*starti = '\0';
if (++starti > copy + len)
- break;
+ goto hcabail;
if ((aname = topo_mod_strdup(mod, startn)) == NULL)
- break;
+ goto hcabail;
startn = endi = strchr(starti, ':');
if (endi == NULL)
@@ -759,10 +806,8 @@
break;
*endi = '\0';
- if ((aid = topo_mod_strdup(mod, starti)) == NULL) {
- topo_mod_strfree(mod, aname);
- break;
- }
+ if ((aid = topo_mod_strdup(mod, starti)) == NULL)
+ goto hcabail;
/*
* Return possible serial, part and revision
@@ -786,12 +831,74 @@
}
topo_mod_strfree(mod, aname);
topo_mod_strfree(mod, aid);
+ aname = aid = NULL;
} while (startn != NULL);
*auth = na;
topo_mod_free(mod, copy, len + 1);
+ return (0);
+
+hcabail:
+ topo_mod_free(mod, copy, len + 1);
+ topo_mod_strfree(mod, aname);
+ topo_mod_strfree(mod, aid);
+ nvlist_free(na);
+ return (-1);
+}
+
+
+/*
+ * This function creates an nvlist to represent the facility portion of an
+ * hc-scheme node, given a string representation of the fmri. This is called by
+ * hc_fmri_str2nvl. If the string does not contain a facility component
+ * (e.g. ?<ftype>=<fname>) then it bails early and returns 0.
+ *
+ * On failure it returns -1 and sets the topo mod errno
+ */
+int
+make_facility(topo_mod_t *mod, char *str, nvlist_t **nvl)
+{
+ char *fac, *copy, *fname, *ftype;
+ nvlist_t *nf = NULL;
+ size_t len;
+
+ if ((fac = strchr(str, '?')) == NULL)
+ return (0);
+
+ ++fac;
+ if ((copy = topo_mod_strdup(mod, fac)) == NULL)
+ return (topo_mod_seterrno(mod, EMOD_NOMEM));
+
+ fac = copy;
+ len = strlen(fac);
+
+ if ((fname = strchr(fac, '=')) == NULL) {
+ topo_mod_free(mod, copy, len + 1);
+ return (topo_mod_seterrno(mod, EMOD_FMRI_MALFORM));
+ }
+
+ fname[0] = '\0';
+ ++fname;
+ ftype = fac;
+
+ if (topo_mod_nvalloc(mod, &nf, NV_UNIQUE_NAME) != 0) {
+ topo_mod_free(mod, copy, len + 1);
+ return (topo_mod_seterrno(mod, EMOD_NOMEM));
+ }
+
+ if (nvlist_add_string(nf, FM_FMRI_FACILITY_NAME, fname) != 0 ||
+ nvlist_add_string(nf, FM_FMRI_FACILITY_TYPE, ftype) != 0) {
+ topo_mod_free(mod, copy, len + 1);
+ return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
+ }
+
+ topo_mod_free(mod, copy, len + 1);
+
+ *nvl = nf;
+
+ return (0);
}
/*ARGSUSED*/
@@ -802,6 +909,7 @@
nvlist_t **pa = NULL;
nvlist_t *nf = NULL;
nvlist_t *auth = NULL;
+ nvlist_t *fac = NULL;
char *str;
char *serial = NULL, *part = NULL, *rev = NULL;
int npairs;
@@ -820,7 +928,9 @@
if ((pa = make_hc_pairs(mod, str, &npairs)) == NULL)
return (topo_mod_seterrno(mod, EMOD_FMRI_MALFORM));
- make_hc_auth(mod, str, &serial, &part, &rev, &auth);
+ if (make_hc_auth(mod, str, &serial, &part, &rev, &auth) < 0)
+ goto hcfmbail;
+
if ((nf = hc_base_fmri_create(mod, auth, part, rev, serial)) == NULL)
goto hcfmbail;
if ((e = nvlist_add_uint32(nf, FM_FMRI_HC_LIST_SZ, npairs)) == 0)
@@ -829,17 +939,26 @@
topo_mod_dprintf(mod, "construction of new hc nvl failed");
goto hcfmbail;
}
+
+ /*
+ * Clean-up
+ */
for (i = 0; i < npairs; i++)
nvlist_free(pa[i]);
topo_mod_free(mod, pa, npairs * sizeof (nvlist_t *));
- if (serial != NULL)
- topo_mod_strfree(mod, serial);
- if (part != NULL)
- topo_mod_strfree(mod, part);
- if (rev != NULL)
- topo_mod_strfree(mod, rev);
+ topo_mod_strfree(mod, serial);
+ topo_mod_strfree(mod, part);
+ topo_mod_strfree(mod, rev);
nvlist_free(auth);
+ if (make_facility(mod, str, &fac) == -1)
+ goto hcfmbail;
+
+ if (fac != NULL) {
+ if (nvlist_add_nvlist(nf, FM_FMRI_FACILITY, fac) != 0)
+ goto hcfmbail;
+ }
+
*out = nf;
return (0);
@@ -850,13 +969,12 @@
for (i = 0; i < npairs; i++)
nvlist_free(pa[i]);
topo_mod_free(mod, pa, npairs * sizeof (nvlist_t *));
- if (serial != NULL)
- topo_mod_strfree(mod, serial);
- if (part != NULL)
- topo_mod_strfree(mod, part);
- if (rev != NULL)
- topo_mod_strfree(mod, rev);
+
+ topo_mod_strfree(mod, serial);
+ topo_mod_strfree(mod, part);
+ topo_mod_strfree(mod, rev);
nvlist_free(auth);
+ nvlist_free(nf);
return (topo_mod_seterrno(mod, EMOD_FMRI_MALFORM));
}
@@ -1053,6 +1171,7 @@
topo_walk_t *hcw_wp;
nvlist_t **hcw_list;
nvlist_t *hcw_fmri;
+ nvlist_t *hcw_fac;
uint_t hcw_index;
uint_t hcw_end;
};
@@ -1151,7 +1270,7 @@
/*
* Generic walker for the hc-scheme topo tree. This function uses the
- * hierachical nature of the hc-scheme to step through efficiently through
+ * hierachical nature of the hc-scheme to efficiently step through
* the topo hc tree. Node lookups are done by topo_walk_byid() and
* topo_walk_bysibling() at each component level to avoid unnecessary
* traversal of the tree. hc_walker() never returns TOPO_WALK_NEXT, so
@@ -1164,13 +1283,27 @@
int i, err;
struct hc_walk *hwp = (struct hc_walk *)pdata;
char *name, *id;
+ char *fname, *ftype;
topo_instance_t inst;
boolean_t match;
i = hwp->hcw_index;
if (i > hwp->hcw_end) {
- (void) topo_mod_seterrno(mod, ETOPO_PROP_NOENT);
- return (TOPO_WALK_TERMINATE);
+ if (hwp->hcw_fac != NULL) {
+ if ((err = hwp->hcw_cb(mod, node, hwp->hcw_priv))
+ != 0) {
+ (void) topo_mod_seterrno(mod, err);
+ topo_mod_dprintf(mod, "hc_walker: callback "
+ "failed: %s\n ", topo_mod_errmsg(mod));
+ return (TOPO_WALK_ERR);
+ }
+ topo_mod_dprintf(mod, "hc_walker: callback "
+ "complete: terminate walk\n");
+ return (TOPO_WALK_TERMINATE);
+ } else {
+ topo_mod_dprintf(mod, "hc_walker: node not found\n");
+ return (TOPO_WALK_TERMINATE);
+ }
}
err = nvlist_lookup_string(hwp->hcw_list[i], FM_FMRI_HC_NAME, &name);
@@ -1198,29 +1331,46 @@
topo_mod_dprintf(mod, "hc_walker: walking node:%s=%d for hc:"
"%s=%d at %d, end at %d \n", topo_node_name(node),
topo_node_instance(node), name, inst, i, hwp->hcw_end);
+
if (i == hwp->hcw_end) {
+
/*
- * We are at the end of the hc-list. Verify that
- * the last node contains the name/instance we are looking for.
+ * We are at the end of the hc-list. Now, check for
+ * a facility leaf and walk one more time.
*/
- if (match) {
- if ((err = hwp->hcw_cb(mod, node, hwp->hcw_priv))
- != 0) {
- (void) topo_mod_seterrno(mod, err);
- topo_mod_dprintf(mod, "hc_walker: callback "
- "failed: %s\n ", topo_mod_errmsg(mod));
+ if (hwp->hcw_fac != NULL) {
+ err = nvlist_lookup_string(hwp->hcw_fac,
+ FM_FMRI_FACILITY_NAME, &fname);
+ err |= nvlist_lookup_string(hwp->hcw_fac,
+ FM_FMRI_FACILITY_TYPE, &ftype);
+ if (err != 0) {
+ (void) topo_mod_seterrno(mod, EMOD_NVL_INVAL);
return (TOPO_WALK_ERR);
}
+ hwp->hcw_index++;
+ topo_mod_dprintf(mod, "hc_walker: walk to facility "
+ "node:%s=%s\n", fname, ftype);
+ return (topo_walk_byid(hwp->hcw_wp, fname, 0));
+ }
+
+ /*
+ * Otherwise, this is the node we're looking for.
+ */
+ if ((err = hwp->hcw_cb(mod, node, hwp->hcw_priv)) != 0) {
+ (void) topo_mod_seterrno(mod, err);
+ topo_mod_dprintf(mod, "hc_walker: callback "
+ "failed: %s\n ", topo_mod_errmsg(mod));
+ return (TOPO_WALK_ERR);
+ } else {
topo_mod_dprintf(mod, "hc_walker: callback "
"complete: terminate walk\n");
return (TOPO_WALK_TERMINATE);
- } else {
- topo_mod_dprintf(mod, "hc_walker: %s=%d\n "
- "not found\n", name, inst);
- return (TOPO_WALK_TERMINATE);
}
}
+ /*
+ * Move on to the next component in the hc-list
+ */
hwp->hcw_index = ++i;
err = nvlist_lookup_string(hwp->hcw_list[i], FM_FMRI_HC_NAME, &name);
err |= nvlist_lookup_string(hwp->hcw_list[i], FM_FMRI_HC_ID, &id);
@@ -1230,8 +1380,6 @@
}
inst = atoi(id);
- topo_mod_dprintf(mod, "hc_walker: walk byid of %s=%d \n", name,
- inst);
return (topo_walk_byid(hwp->hcw_wp, name, inst));
}
@@ -1240,7 +1388,7 @@
hc_walk_init(topo_mod_t *mod, tnode_t *node, nvlist_t *rsrc,
topo_mod_walk_cb_t cb, void *pdata)
{
- int err;
+ int err, ret;
uint_t sz;
struct hc_walk *hwp;
topo_walk_t *wp;
@@ -1252,10 +1400,24 @@
if (nvlist_lookup_nvlist_array(rsrc, FM_FMRI_HC_LIST, &hwp->hcw_list,
&sz) != 0) {
+ topo_mod_dprintf(mod, "hc_walk_init: failed to lookup %s "
+ "nvlist\n", FM_FMRI_HC_LIST);
topo_mod_free(mod, hwp, sizeof (struct hc_walk));
(void) topo_mod_seterrno(mod, EMOD_METHOD_INVAL);
return (NULL);
}
+ if ((ret = nvlist_lookup_nvlist(rsrc, FM_FMRI_FACILITY, &hwp->hcw_fac))
+ != 0) {
+ if (ret != ENOENT) {
+ topo_mod_dprintf(mod, "hc_walk_init: unexpected error "
+ "looking up %s nvlist", FM_FMRI_FACILITY);
+ topo_mod_free(mod, hwp, sizeof (struct hc_walk));
+ (void) topo_mod_seterrno(mod, EMOD_METHOD_INVAL);
+ return (NULL);
+ } else {
+ hwp->hcw_fac = NULL;
+ }
+ }
hwp->hcw_fmri = rsrc;
hwp->hcw_end = sz - 1;
@@ -1264,6 +1426,8 @@
hwp->hcw_cb = cb;
if ((wp = topo_mod_walk_init(mod, node, hc_walker, (void *)hwp, &err))
== NULL) {
+ topo_mod_dprintf(mod, "hc_walk_init: topo_mod_walk_init failed "
+ "(%s)\n", topo_strerror(err));
topo_mod_free(mod, hwp, sizeof (struct hc_walk));
(void) topo_mod_seterrno(mod, err);
return (NULL);
@@ -1615,3 +1779,122 @@
return (err);
}
+
+struct fac_lookup {
+ const char *fl_fac_type;
+ uint32_t fl_fac_subtype;
+#ifdef _LP64
+ uint64_t fl_callback;
+ uint64_t fl_callback_args;
+#else
+ uint32_t fl_callback;
+ uint32_t fl_callback_args;
+#endif
+ nvlist_t *fl_rsrc;
+ nvlist_t *fl_fac_rsrc;
+};
+
+static int
+hc_fac_get(topo_mod_t *mod, tnode_t *node, void *pdata)
+{
+ struct fac_lookup *flp = (struct fac_lookup *)pdata;
+ topo_walk_cb_t cb = (topo_walk_cb_t)flp->fl_callback;
+ topo_faclist_t faclist, *tmp;
+ int err, ret = 0;
+
+ /*
+ * Lookup the specified facility node. Return with an error if we can't
+ * find it.
+ */
+ if (topo_node_facility(mod->tm_hdl, node, flp->fl_fac_type,
+ flp->fl_fac_subtype, &faclist, &err) != 0) {
+ topo_mod_dprintf(mod, "hc_fac_get: topo_node_facility "
+ "failed\n");
+ return (TOPO_WALK_ERR);
+ }
+
+ /*
+ * Invoke user's callback for each facility node in the topo list,
+ * passing in a pointer to the facility node
+ */
+ for (tmp = topo_list_next(&faclist.tf_list); tmp != NULL;
+ tmp = topo_list_next(tmp)) {
+
+ if ((err = cb(mod->tm_hdl, tmp->tf_node,
+ (void *)flp->fl_callback_args)) != 0) {
+ (void) topo_mod_seterrno(mod, err);
+ topo_mod_dprintf(mod, "hc_fac_get: callback failed: "
+ "%s\n ", topo_mod_errmsg(mod));
+ ret = TOPO_WALK_ERR;
+ break;
+ }
+ }
+
+ while ((tmp = topo_list_next(&faclist.tf_list)) != NULL) {
+ topo_list_delete(&faclist.tf_list, tmp);
+ topo_mod_free(mod, tmp, sizeof (topo_faclist_t));
+ }
+ return (ret);
+}
+
+static int
+hc_fmri_facility(topo_mod_t *mod, tnode_t *node, topo_version_t version,
+ nvlist_t *in, nvlist_t **out)
+{
+ int err = 0;
+ struct hc_walk *hwp;
+ struct fac_lookup *flp;
+
+ if (version > TOPO_METH_FACILITY_VERSION)
+ return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
+
+ if ((flp = topo_mod_alloc(mod, sizeof (struct fac_lookup))) == NULL)
+ return (topo_mod_seterrno(mod, EMOD_NOMEM));
+
+ /*
+ * lookup arguments: hw resource, facility type, facility subtype,
+ * callback and callback args
+ */
+ err = nvlist_lookup_nvlist(in, TOPO_PROP_RESOURCE, &flp->fl_rsrc);
+ err |= nvlist_lookup_string(in, FM_FMRI_FACILITY_TYPE,
+ (char **)&flp->fl_fac_type);
+ err |= nvlist_lookup_uint32(in, "type", &flp->fl_fac_subtype);
+#ifdef _LP64
+ err |= nvlist_lookup_uint64(in, "callback", &flp->fl_callback);
+ err |= nvlist_lookup_uint64(in, "callback-args",
+ &flp->fl_callback_args);
+#else
+ err |= nvlist_lookup_uint32(in, "callback", &flp->fl_callback);
+ err |= nvlist_lookup_uint32(in, "callback-args",
+ &flp->fl_callback_args);
+#endif
+ if (err != 0) {
+ topo_mod_dprintf(mod, "hc_fmri_facility: failed to construct "
+ "walker arg nvlist\n");
+ topo_mod_free(mod, flp, sizeof (struct fac_lookup));
+ return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
+ }
+
+ flp->fl_fac_rsrc = NULL;
+ if ((hwp = hc_walk_init(mod, node, flp->fl_rsrc, hc_fac_get,
+ (void *)flp)) != NULL) {
+ if (topo_walk_step(hwp->hcw_wp, TOPO_WALK_CHILD) ==
+ TOPO_WALK_ERR)
+ err = -1;
+ else
+ err = 0;
+ topo_walk_fini(hwp->hcw_wp);
+ topo_mod_free(mod, hwp, sizeof (struct hc_walk));
+ } else {
+ topo_mod_dprintf(mod, "hc_fmri_facility: failed to initialize "
+ "hc walker\n");
+ err = -1;
+ }
+
+ if (flp->fl_fac_rsrc != NULL)
+ *out = flp->fl_fac_rsrc;
+
+ topo_mod_free(mod, flp, sizeof (struct fac_lookup));
+
+ return (err);
+}
--- a/usr/src/lib/fm/topo/libtopo/common/libtopo.h Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/libtopo.h Thu Jul 31 17:35:39 2008 -0700
@@ -44,6 +44,16 @@
typedef int32_t topo_instance_t;
typedef uint32_t topo_version_t;
+typedef struct topo_list {
+ struct topo_list *l_prev;
+ struct topo_list *l_next;
+} topo_list_t;
+
+typedef struct topo_faclist {
+ topo_list_t tf_list;
+ tnode_t *tf_node;
+} topo_faclist_t;
+
/*
* The following functions, error codes and data structures are private
* to libtopo snapshot consumers and enumerator modules.
@@ -91,6 +101,8 @@
extern int topo_fmri_label(topo_hdl_t *, nvlist_t *, char **, int *);
extern int topo_fmri_serial(topo_hdl_t *, nvlist_t *, char **, int *);
extern int topo_fmri_compare(topo_hdl_t *, nvlist_t *, nvlist_t *, int *);
+extern int topo_fmri_facility(topo_hdl_t *, nvlist_t *, const char *,
+ uint32_t, topo_walk_cb_t, void *, int *);
/*
* Private utility functions for fmd
@@ -106,13 +118,30 @@
extern topo_instance_t topo_node_instance(tnode_t *);
extern tnode_t *topo_node_parent(tnode_t *);
extern void *topo_node_private(tnode_t *);
+extern int topo_node_flags(tnode_t *);
extern int topo_node_asru(tnode_t *, nvlist_t **, nvlist_t *, int *);
extern int topo_node_fru(tnode_t *, nvlist_t **, nvlist_t *, int *);
extern int topo_node_resource(tnode_t *, nvlist_t **, int *);
extern int topo_node_label(tnode_t *, char **, int *);
extern int topo_method_invoke(tnode_t *node, const char *, topo_version_t,
nvlist_t *, nvlist_t **, int *);
+extern boolean_t topo_method_supported(tnode_t *, const char *,
+ topo_version_t);
+extern int topo_node_facility(topo_hdl_t *, tnode_t *, const char *,
+ uint32_t, topo_faclist_t *, int *);
+/*
+ * Node flags: denotes type of node
+ */
+#define TOPO_NODE_DEFAULT 0
+#define TOPO_NODE_FACILITY 1
+
+#define TOPO_FAC_TYPE_SENSOR "sensor"
+#define TOPO_FAC_TYPE_INDICATOR "indicator"
+
+/*
+ * Topo property get functions
+ */
extern int topo_prop_get_int32(tnode_t *, const char *, const char *,
int32_t *, int *);
extern int topo_prop_get_uint32(tnode_t *, const char *, const char *,
@@ -121,6 +150,8 @@
int64_t *, int *);
extern int topo_prop_get_uint64(tnode_t *, const char *, const char *,
uint64_t *, int *);
+extern int topo_prop_get_double(tnode_t *, const char *, const char *,
+ double *, int *);
extern int topo_prop_get_string(tnode_t *, const char *, const char *,
char **, int *);
extern int topo_prop_get_fmri(tnode_t *, const char *, const char *,
@@ -138,6 +169,36 @@
extern int topo_prop_get_fmri_array(tnode_t *, const char *, const char *,
nvlist_t ***, uint_t *, int *);
+/*
+ * Topo property set functions
+ */
+extern int topo_prop_set_int32(tnode_t *, const char *, const char *, int,
+ int32_t, int *);
+extern int topo_prop_set_uint32(tnode_t *, const char *, const char *, int,
+ uint32_t, int *);
+extern int topo_prop_set_int64(tnode_t *, const char *, const char *,
+ int, int64_t, int *);
+extern int topo_prop_set_uint64(tnode_t *, const char *, const char *,
+ int, uint64_t, int *);
+extern int topo_prop_set_double(tnode_t *, const char *, const char *,
+ int, double, int *);
+extern int topo_prop_set_string(tnode_t *, const char *, const char *,
+ int, const char *, int *);
+extern int topo_prop_set_fmri(tnode_t *, const char *, const char *,
+ int, const nvlist_t *, int *);
+extern int topo_prop_set_int32_array(tnode_t *, const char *, const char *, int,
+ int32_t *, uint_t, int *);
+extern int topo_prop_set_uint32_array(tnode_t *, const char *, const char *,
+ int, uint32_t *, uint_t, int *);
+extern int topo_prop_set_int64_array(tnode_t *, const char *, const char *,
+ int, int64_t *, uint_t, int *);
+extern int topo_prop_set_uint64_array(tnode_t *, const char *, const char *,
+ int, uint64_t *, uint_t, int *);
+extern int topo_prop_set_string_array(tnode_t *, const char *, const char *,
+ int, const char **, uint_t, int *);
+extern int topo_prop_set_fmri_array(tnode_t *, const char *, const char *,
+ int, const nvlist_t **, uint_t, int *);
+
#define TOPO_PROP_IMMUTABLE 0
#define TOPO_PROP_MUTABLE 1
@@ -150,6 +211,8 @@
#define TOPO_PROP_PKG "package" /* software package FMRI */
#define TOPO_PROP_LABEL "label" /* property LABEL */
+#define TOPO_METH_FAC_ENUM "fac_enum"
+
/*
* System property group
*/
@@ -270,7 +333,8 @@
TOPO_TYPE_INT64_ARRAY, /* array of int64_t */
TOPO_TYPE_UINT64_ARRAY, /* array of uint64_t */
TOPO_TYPE_STRING_ARRAY, /* array of const char* */
- TOPO_TYPE_FMRI_ARRAY /* array of nvlist_t */
+ TOPO_TYPE_FMRI_ARRAY, /* array of nvlist_t */
+ TOPO_TYPE_DOUBLE /* double */
} topo_type_t;
extern nvlist_t *topo_prop_getprops(tnode_t *, int *err);
@@ -313,6 +377,590 @@
extern int topo_hdl_nvdup(topo_hdl_t *, nvlist_t *, nvlist_t **);
extern char *topo_hdl_strdup(topo_hdl_t *, const char *);
+/*
+ * Interfaces for converting sensor/indicator types, units, states, etc to
+ * a string
+ */
+void topo_sensor_type_name(uint32_t type, char *buf, size_t len);
+void topo_sensor_units_name(uint8_t type, char *buf, size_t len);
+void topo_led_type_name(uint8_t type, char *buf, size_t len);
+void topo_led_state_name(uint8_t type, char *buf, size_t len);
+void topo_sensor_state_name(uint32_t sensor_type, uint8_t state, char *buf,
+ size_t len);
+
+/*
+ * Defines for standard properties for sensors and indicators
+ */
+#define TOPO_PGROUP_FACILITY "facility"
+
+#define TOPO_SENSOR_READING "reading"
+#define TOPO_SENSOR_STATE "state"
+#define TOPO_SENSOR_CLASS "sensor-class"
+#define TOPO_FACILITY_TYPE "type"
+#define TOPO_SENSOR_UNITS "units"
+#define TOPO_LED_MODE "mode"
+
+/*
+ * Sensor Classes
+ *
+ * The "sensor-class" property in the "facility" propgroup on
+ * facility nodes of type "sensor" should be set to one of these
+ * two values.
+ *
+ * Threshold sensors provide an analog sensor reading via the
+ * "reading" property in the facility propgroup. They will also
+ * provide one or more discrete states via the "state" property
+ * in the facility propgroup.
+ *
+ * Discrete sensors will not provide an analog reading by will
+ * provide one or more discrete states via the "state" property
+ * in the facility propgroup.
+ */
+#define TOPO_SENSOR_CLASS_THRESHOLD "threshold"
+#define TOPO_SENSOR_CLASS_DISCRETE "discrete"
+
+/*
+ * Sensor unit types. We're using the unit types and corresponding
+ * codes described in the IPMI 2.0 spec as a reference as it seems to be a
+ * reasonably comprehensive list. This also simplifies the IPMI provider code
+ * since the unit type codes will map exactly to what libtopo uses (so no
+ * conversion necessary).
+ */
+typedef enum topo_sensor_unit {
+ TOPO_SENSOR_UNITS_UNSPECIFIED = 0,
+ TOPO_SENSOR_UNITS_DEGREES_C,
+ TOPO_SENSOR_UNITS_DEGREES_F,
+ TOPO_SENSOR_UNITS_DEGREES_K,
+ TOPO_SENSOR_UNITS_VOLTS,
+ TOPO_SENSOR_UNITS_AMPS,
+ TOPO_SENSOR_UNITS_WATTS,
+ TOPO_SENSOR_UNITS_JOULES,
+ TOPO_SENSOR_UNITS_COULOMBS,
+ TOPO_SENSOR_UNITS_VA,
+ TOPO_SENSOR_UNITS_NITS,
+ TOPO_SENSOR_UNITS_LUMEN,
+ TOPO_SENSOR_UNITS_LUX,
+ TOPO_SENSOR_UNITS_CANDELA,
+ TOPO_SENSOR_UNITS_KPA,
+ TOPO_SENSOR_UNITS_PSI,
+
+ TOPO_SENSOR_UNITS_NEWTON,
+ TOPO_SENSOR_UNITS_CFM,
+ TOPO_SENSOR_UNITS_RPM,
+ TOPO_SENSOR_UNITS_HZ,
+ TOPO_SENSOR_UNITS_MICROSEC,
+ TOPO_SENSOR_UNITS_MILLISEC,
+ TOPO_SENSOR_UNITS_SECS,
+ TOPO_SENSOR_UNITS_MIN,
+ TOPO_SENSOR_UNITS_HOUR,
+ TOPO_SENSOR_UNITS_DAY,
+ TOPO_SENSOR_UNITS_WEEK,
+ TOPO_SENSOR_UNITS_MIL,
+ TOPO_SENSOR_UNITS_INCHES,
+ TOPO_SENSOR_UNITS_FEET,
+ TOPO_SENSOR_UNITS_CUB_INCH,
+ TOPO_SENSOR_UNITS_CUB_FEET,
+
+ TOPO_SENSOR_UNITS_MM,
+ TOPO_SENSOR_UNITS_CM,
+ TOPO_SENSOR_UNITS_METERS,
+ TOPO_SENSOR_UNITS_CUB_CM,
+ TOPO_SENSOR_UNITS_CUB_METER,
+ TOPO_SENSOR_UNITS_LITERS,
+ TOPO_SENSOR_UNITS_FLUID_OUNCE,
+ TOPO_SENSOR_UNITS_RADIANS,
+ TOPO_SENSOR_UNITS_STERADIANS,
+ TOPO_SENSOR_UNITS_REVOLUTIONS,
+ TOPO_SENSOR_UNITS_CYCLES,
+ TOPO_SENSOR_UNITS_GRAVITIES,
+ TOPO_SENSOR_UNITS_OUNCE,
+ TOPO_SENSOR_UNITS_POUND,
+ TOPO_SENSOR_UNITS_FOOT_POUND,
+ TOPO_SENSOR_UNITS_OZ_INCH,
+
+ TOPO_SENSOR_UNITS_GAUSS,
+ TOPO_SENSOR_UNITS_GILBERTS,
+ TOPO_SENSOR_UNITS_HENRY,
+ TOPO_SENSOR_UNITS_MILHENRY,
+ TOPO_SENSOR_UNITS_FARAD,
+ TOPO_SENSOR_UNITS_MICROFARAD,
+ TOPO_SENSOR_UNITS_OHMS,
+ TOPO_SENSOR_UNITS_SIEMENS,
+ TOPO_SENSOR_UNITS_MOLE,
+ TOPO_SENSOR_UNITS_BECQUEREL,
+ TOPO_SENSOR_UNITS_PPM,
+ TOPO_SENSOR_UNITS_RESERVED1,
+ TOPO_SENSOR_UNITS_DECIBELS,
+ TOPO_SENSOR_UNITS_DBA,
+ TOPO_SENSOR_UNITS_DBC,
+ TOPO_SENSOR_UNITS_GRAY,
+
+ TOPO_SENSOR_UNITS_SIEVERT,
+ TOPO_SENSOR_UNITS_COLOR_TEMP_K,
+ TOPO_SENSOR_UNITS_BIT,
+ TOPO_SENSOR_UNITS_KILOBIT,
+ TOPO_SENSOR_UNITS_MEGABIT,
+ TOPO_SENSOR_UNITS_GIGABIT,
+ TOPO_SENSOR_UNITS_BYTE,
+ TOPO_SENSOR_UNITS_KILOBYTE,
+ TOPO_SENSOR_UNITS_MEGABYTE,
+ TOPO_SENSOR_UNITS_GIGABYTE,
+ TOPO_SENSOR_UNITS_WORD,
+ TOPO_SENSOR_UNITS_DWORD,
+ TOPO_SENSOR_UNITS_QWORD,
+ TOPO_SENSOR_UNITS_MEMLINE,
+ TOPO_SENSOR_UNITS_HIT,
+ TOPO_SENSOR_UNITS_MISS,
+
+ TOPO_SENSOR_UNITS_RETRY,
+ TOPO_SENSOR_UNITS_RESET,
+ TOPO_SENSOR_UNITS_OVERFLOW,
+ TOPO_SENSOR_UNITS_UNDERRUN,
+ TOPO_SENSOR_UNITS_COLLISION,
+ TOPO_SENSOR_UNITS_PACKETS,
+ TOPO_SENSOR_UNITS_MESSAGES,
+ TOPO_SENSOR_UNITS_CHARACTERS,
+ TOPO_SENSOR_UNITS_ERROR,
+ TOPO_SENSOR_UNITS_CE,
+ TOPO_SENSOR_UNITS_UE,
+ TOPO_SENSOR_UNITS_FATAL_ERROR,
+ TOPO_SENSOR_UNITS_GRAMS
+} topo_sensor_unit_t;
+
+/*
+ * Sensor Types amd the associated sensor-type-specific states
+ *
+ * These are used to decode the type and state properties in the facility
+ * propgroup on facility nodes of type sensor.
+ *
+ * Again we're basically using the same defines as for IPMI as it's serves
+ * as a good starting point and simplifies the IPMI provider code. Of course
+ * other facility providers will need to convert from their native codes
+ * to the topo code when they set the type and state properties.
+ */
+#define TOPO_SENSOR_TYPE_RESERVED 0x0000
+#define TOPO_SENSOR_TYPE_TEMP 0x0001
+#define TOPO_SENSOR_TYPE_VOLTAGE 0x0002
+#define TOPO_SENSOR_TYPE_CURRENT 0x0003
+#define TOPO_SENSOR_TYPE_FAN 0x0004
+#define TOPO_SENSOR_TYPE_PHYSICAL 0x0005
+
+#define TOPO_SENSOR_STATE_PHYSICAL_GENERAL 0x0001
+#define TOPO_SENSOR_STATE_PHYSICAL_BAY 0x0002
+#define TOPO_SENSOR_STATE_PHYSICAL_CARD 0x0004
+#define TOPO_SENSOR_STATE_PHYSICAL_PROCESSOR 0x0008
+#define TOPO_SENSOR_STATE_PHYSICAL_LAN 0x0010
+#define TOPO_SENSOR_STATE_PHYSICAL_DOCK 0x0020
+#define TOPO_SENSOR_STATE_PHYSICAL_FAN 0x0040
+
+#define TOPO_SENSOR_TYPE_PLATFORM 0x0006
+
+#define TOPO_SENSOR_STATE_PLATFORM_SECURE 0x0001
+#define TOPO_SENSOR_STATE_PLATFORM_USER_PASS 0x0002
+#define TOPO_SENSOR_STATE_PLATFORM_SETUP_PASS 0x0004
+#define TOPO_SENSOR_STATE_PLATFORM_NETWORK_PASS 0x0008
+#define TOPO_SENSOR_STATE_PLATFORM_OTHER_PASS 0x0010
+#define TOPO_SENSOR_STATE_PLATFORM_OUT_OF_BAND 0x0020
+
+#define TOPO_SENSOR_TYPE_PROCESSOR 0x0007
+
+#define TOPO_SENSOR_STATE_PROCESSOR_IERR 0x0001
+#define TOPO_SENSOR_STATE_PROCESSOR_THERMAL 0x0002
+#define TOPO_SENSOR_STATE_PROCESSOR_FRB1 0x0004
+#define TOPO_SENSOR_STATE_PROCESSOR_FRB2 0x0008
+#define TOPO_SENSOR_STATE_PROCESSOR_FRB3 0x0010
+#define TOPO_SENSOR_STATE_PROCESSOR_CONFIG 0x0020
+#define TOPO_SENSOR_STATE_PROCESSOR_SMBIOS 0x0040
+#define TOPO_SENSOR_STATE_PROCESSOR_PRESENT 0x0080
+#define TOPO_SENSOR_STATE_PROCESSOR_DISABLED 0x0100
+#define TOPO_SENSOR_STATE_PROCESSOR_TERMINATOR 0x0200
+#define TOPO_SENSOR_STATE_PROCESSOR_THROTTLED 0x0400
+
+#define TOPO_SENSOR_TYPE_POWER_SUPPLY 0x0008
+
+#define TOPO_SENSOR_STATE_POWER_SUPPLY_PRESENT 0x0001
+#define TOPO_SENSOR_STATE_POWER_SUPPLY_FAILURE 0x0002
+#define TOPO_SENSOR_STATE_POWER_SUPPLY_PREDFAIL 0x0004
+#define TOPO_SENSOR_STATE_POWER_SUPPLY_INPUT_LOST 0x0008
+#define TOPO_SENSOR_STATE_POWER_SUPPLY_INPUT_RANGE 0x0010
+#define TOPO_SENSOR_STATE_POWER_SUPPLY_INPUT_RANGE_PRES 0x0020
+#define TOPO_SENSOR_STATE_POWER_SUPPLY_CONFIG_ERR 0x0040
+
+#define TOPO_SENSOR_TYPE_POWER_UNIT 0x0009
+
+#define TOPO_SENSOR_STATE_POWER_UNIT_OFF 0x0001
+#define TOPO_SENSOR_STATE_POWER_UNIT_CYCLE 0x0002
+#define TOPO_SENSOR_STATE_POWER_UNIT_240_DOWN 0x0004
+#define TOPO_SENSOR_STATE_POWER_UNIT_INTERLOCK_DOWN 0x0008
+#define TOPO_SENSOR_STATE_POWER_UNIT_AC_LOST 0x0010
+#define TOPO_SENSOR_STATE_POWER_UNIT_SOFT_FAILURE 0x0020
+#define TOPO_SENSOR_STATE_POWER_UNIT_FAIL 0x0040
+#define TOPO_SENSOR_STATE_POWER_UNIT_PREDFAIL 0x0080
+
+#define TOPO_SENSOR_TYPE_COOLING 0x000A
+#define TOPO_SENSOR_TYPE_OTHER 0x000B
+
+#define TOPO_SENSOR_TYPE_MEMORY 0x000C
+
+#define TOPO_SENSOR_STATE_MEMORY_CE 0x0001
+#define TOPO_SENSOR_STATE_MEMORY_UE 0x0002
+#define TOPO_SENSOR_STATE_MEMORY_PARITY 0x0004
+#define TOPO_SENSOR_STATE_MEMORY_SCRUB_FAIL 0x0008
+#define TOPO_SENSOR_STATE_MEMORY_DISABLED 0x0010
+#define TOPO_SENSOR_STATE_MEMORY_CE_LOG_LIMIT 0x0020
+#define TOPO_SENSOR_STATE_MEMORY_PRESENT 0x0040
+#define TOPO_SENSOR_STATE_MEMORY_CONFIG_ERR 0x0080
+#define TOPO_SENSOR_STATE_MEMORY_SPARE 0x0100
+#define TOPO_SENSOR_STATE_MEMORY_THROTTLED 0x0200
+#define TOPO_SENSOR_STATE_MEMORY_OVERTEMP 0x0400
+
+#define TOPO_SENSOR_TYPE_BAY 0x000D
+
+#define TOPO_SENSOR_STATE_BAY_PRESENT 0x0001
+#define TOPO_SENSOR_STATE_BAY_FAULT 0x0002
+#define TOPO_SENSOR_STATE_BAY_PREDFAIL 0x0004
+#define TOPO_SENSOR_STATE_BAY_SPARE 0x0008
+#define TOPO_SENSOR_STATE_BAY_CHECK 0x0010
+#define TOPO_SENSOR_STATE_BAY_CRITICAL 0x0020
+#define TOPO_SENSOR_STATE_BAY_FAILED 0x0040
+#define TOPO_SENSOR_STATE_BAY_REBUILDING 0x0080
+#define TOPO_SENSOR_STATE_BAY_ABORTED 0x0100
+
+#define TOPO_SENSOR_TYPE_POST_RESIZE 0x000E
+
+#define TOPO_SENSOR_TYPE_FIRMWARE 0x000F
+
+#define TOPO_SENSOR_STATE_FIRMWARE_ERROR 0x0001
+#define TOPO_SENSOR_STATE_FIRMWARE_HANG 0x0002
+#define TOPO_SENSOR_STATE_FIRMWARE_PROGRESS 0x0004
+
+#define TOPO_SENSOR_TYPE_EVENT_LOG 0x0010
+
+#define TOPO_SENSOR_STATE_EVENT_LOG_CE 0x0001
+#define TOPO_SENSOR_STATE_EVENT_LOG_TYPE 0x0002
+#define TOPO_SENSOR_STATE_EVENT_LOG_RESET 0x0004
+#define TOPO_SENSOR_STATE_EVENT_LOG_ALL 0x0008
+#define TOPO_SENSOR_STATE_EVENT_LOG_FULL 0x0010
+#define TOPO_SENSOR_STATE_EVENT_LOG_ALMOST_FULL 0x0020
+
+#define TOPO_SENSOR_TYPE_WATCHDOG1 0x0011
+
+#define TOPO_SENSOR_STATE_WATCHDOG_BIOS_RESET 0x0001
+#define TOPO_SENSOR_STATE_WATCHDOG_OS_RESET 0x0002
+#define TOPO_SENSOR_STATE_WATCHDOG_OS_SHUTDOWN 0x0004
+#define TOPO_SENSOR_STATE_WATCHDOG_OS_PWR_DOWN 0x0008
+#define TOPO_SENSOR_STATE_WATCHDOG_OS_PWR_CYCLE 0x0010
+#define TOPO_SENSOR_STATE_WATCHDOG_OS_NMI_DIAG 0x0020
+#define TOPO_SENSOR_STATE_WATCHDOG_EXPIRED 0x0040
+#define TOPO_SENSOR_STATE_WATCHDOG_PRE_TIMEOUT_INT 0x0080
+
+#define TOPO_SENSOR_TYPE_SYSTEM 0x0012
+
+#define TOPO_SENSOR_STATE_SYSTEM_RECONF 0x0001
+#define TOPO_SENSOR_STATE_SYSTEM_BOOT 0x0002
+#define TOPO_SENSOR_STATE_SYSTEM_UNKNOWN_HW_FAILURE 0x0004
+#define TOPO_SENSOR_STATE_SYSTEM_AUX_LOG_UPDATED 0x0008
+#define TOPO_SENSOR_STATE_SYSTEM_PEF_ACTION 0x0010
+#define TOPO_SENSOR_STATE_SYSTEM_TIMETAMP_CLOCKSYNC 0x0020
+
+#define TOPO_SENSOR_TYPE_CRITICAL 0x0013
+
+#define TOPO_SENSOR_STATE_CRITICAL_EXT_NMI 0x0001
+#define TOPO_SENSOR_STATE_CRITICAL_BUS_TIMEOUT 0x0002
+#define TOPO_SENSOR_STATE_CRITICAL_IO_NMI 0x0004
+#define TOPO_SENSOR_STATE_CRITICAL_SW_NMI 0x0008
+#define TOPO_SENSOR_STATE_CRITICAL_PCI_PERR 0x0010
+#define TOPO_SENSOR_STATE_CRITICAL_PCI_SERR 0x0020
+#define TOPO_SENSOR_STATE_CRITICAL_EISA_FAILSAFE 0x0040
+#define TOPO_SENSOR_STATE_CRITICAL_BUS_CE 0x0080
+#define TOPO_SENSOR_STATE_CRITICAL_BUS_UE 0x0100
+#define TOPO_SENSOR_STATE_CRITICAL_FATAL_NMI 0x0200
+#define TOPO_SENSOR_STATE_CRITICAL_BUS_FATAL_ERR 0x0400
+#define TOPO_SENSOR_STATE_CRITICAL_BUS_DEGRADED 0x0800
+
+#define TOPO_SENSOR_TYPE_BUTTON 0x0014
+
+#define TOPO_SENSOR_STATE_BUTTON_PWR 0x0001
+#define TOPO_SENSOR_STATE_BUTTON_SLEEP 0x0002
+#define TOPO_SENSOR_STATE_BUTTON_RESET 0x0004
+#define TOPO_SENSOR_STATE_BUTTON_FRU_LATCH 0x0008
+#define TOPO_SENSOR_STATE_BUTTON_FRU_SERVICE 0x0010
+
+#define TOPO_SENSOR_TYPE_MODULE 0x0015
+#define TOPO_SENSOR_TYPE_MICROCONTROLLER 0x0016
+#define TOPO_SENSOR_TYPE_CARD 0x0017
+#define TOPO_SENSOR_TYPE_CHASSIS 0x0018
+
+#define TOPO_SENSOR_TYPE_CHIPSET 0x0019
+
+#define TOPO_SENSOR_STATE_CHIPSET_PWR_CTL_FAIL 0x0001
+
+#define TOPO_SENSOR_TYPE_FRU 0x001A
+
+#define TOPO_SENSOR_TYPE_CABLE 0x001B
+
+#define TOPO_SENSOR_STATE_CABLE_CONNECTED 0x0001
+#define TOPO_SENSOR_STATE_CABLE_CONFIG_ERR 0x0002
+
+#define TOPO_SENSOR_TYPE_TERMINATOR 0x001C
+
+#define TOPO_SENSOR_TYPE_BOOT_STATE 0x001D
+
+#define TOPO_SENSOR_STATE_BOOT_STATE_BIOS_PWR_UP 0x0001
+#define TOPO_SENSOR_STATE_BOOT_STATE_BIOS_HARD_RESET 0x0002
+#define TOPO_SENSOR_STATE_BOOT_STATE_BIOS_WARM_RESET 0x0004
+#define TOPO_SENSOR_STATE_BOOT_STATE_PXE_BOOT 0x0008
+#define TOPO_SENSOR_STATE_BOOT_STATE_DIAG_BOOT 0x0010
+#define TOPO_SENSOR_STATE_BOOT_STATE_OS_HARD_RESET 0x0020
+#define TOPO_SENSOR_STATE_BOOT_STATE_OS_WARM_RESET 0x0040
+#define TOPO_SENSOR_STATE_BOOT_STATE_SYS_RESTART 0x0080
+
+#define TOPO_SENSOR_TYPE_BOOT_ERROR 0x001E
+
+#define TOPO_SENSOR_STATE_BOOT_ERROR_NOMEDIA 0x0001
+#define TOPO_SENSOR_STATE_BOOT_ERROR_NON_BOOTABLE_DISK 0x0002
+#define TOPO_SENSOR_STATE_BOOT_ERROR_NO_PXE_SERVER 0x0004
+#define TOPO_SENSOR_STATE_BOOT_ERROR_INV_BOOT_SECT 0x0008
+#define TOPO_SENSOR_STATE_BOOT_ERROR_USR_SELECT_TIMEOUT 0x0010
+
+#define TOPO_SENSOR_TYPE_BOOT_OS 0x001F
+
+#define TOPO_SENSOR_STATE_BOOT_OS_A_DRV_BOOT_COMPLETE 0x0001
+#define TOPO_SENSOR_STATE_BOOT_OS_C_DRV_BOOT_COMPLETE 0x0002
+#define TOPO_SENSOR_STATE_BOOT_OS_PXE_BOOT_COMPLETE 0x0004
+#define TOPO_SENSOR_STATE_BOOT_OS_DIAG_BOOT_COMPLETE 0x0008
+#define TOPO_SENSOR_STATE_BOOT_OS_CDROM_BOOT_COMPLETE 0x0010
+#define TOPO_SENSOR_STATE_BOOT_OS_ROM_BOOT_COMPLETE 0x0020
+#define TOPO_SENSOR_STATE_BOOT_OS_UNSPEC_BOOT_COMPLETE 0x0040
+
+#define TOPO_SENSOR_TYPE_OS_SHUTDOWN 0x0020
+
+#define TOPO_SENSOR_STATE_OS_SHUTDOWN_LOADING 0x0001
+#define TOPO_SENSOR_STATE_OS_SHUTDOWN_CRASH 0x0002
+#define TOPO_SENSOR_STATE_OS_STOP_GRACEFUL 0x0004
+#define TOPO_SENSOR_STATE_OS_SHUTDOWN_GRACEFUL 0x0008
+#define TOPO_SENSOR_STATE_OS_SHUTDOWN_PEF 0x0010
+#define TOPO_SENSOR_STATE_OS_SHUTDOWN_BMC 0x0020
+
+#define TOPO_SENSOR_TYPE_SLOT 0x0021
+
+#define TOPO_SENSOR_STATE_SLOT_FAULT_ASSERTED 0x0001
+#define TOPO_SENSOR_STATE_SLOT_IDENTIFY_ASSERTED 0x0002
+#define TOPO_SENSOR_STATE_SLOT_CONNECTED 0x0004
+#define TOPO_SENSOR_STATE_SLOT_INSTALL_READY 0x0008
+#define TOPO_SENSOR_STATE_SLOT_REMOVE_READY 0x0010
+#define TOPO_SENSOR_STATE_SLOT_PWR_OFF 0x0020
+#define TOPO_SENSOR_STATE_SLOT_REMOVED 0x0040
+#define TOPO_SENSOR_STATE_SLOT_INTERLOCK_ASSERTED 0x0080
+#define TOPO_SENSOR_STATE_SLOT_DISABLED 0x0100
+#define TOPO_SENSOR_STATE_SLOT_SPARE_DEVICE 0x0200
+
+#define TOPO_SENSOR_TYPE_ACPI 0x0022
+
+#define TOPO_SENSOR_STATE_ACPI_PSTATE_S0_G0 0x0001
+#define TOPO_SENSOR_STATE_ACPI_PSTATE_S1 0x0002
+#define TOPO_SENSOR_STATE_ACPI_PSTATE_S2 0x0004
+#define TOPO_SENSOR_STATE_ACPI_PSTATE_S3 0x0008
+#define TOPO_SENSOR_STATE_ACPI_PSTATE_S4 0x0010
+#define TOPO_SENSOR_STATE_ACPI_PSTATE_S5_G2_SOFT_OFF 0x0020
+#define TOPO_SENSOR_STATE_ACPI_PSTATE_S4_S5_SOFT_OFF 0x0040
+#define TOPO_SENSOR_STATE_ACPI_PSATTE_G3_MECH_OFF 0x0080
+#define TOPO_SENSOR_STATE_ACPI_PSTATE_S1_S2_S3_SLEEP 0x0100
+#define TOPO_SENSOR_STATE_ACPI_PSTATE_G1_SLEEP 0x0200
+#define TOPO_SENSOR_STATE_ACPI_PSTATE_S5_OVERRIDE 0x0400
+#define TOPO_SENSOR_STATE_ACPI_PSTATE_LEGACY_ON 0x0800
+#define TOPO_SENSOR_STATE_ACPI_PSTATE_LEGACY_OFF 0x1000
+#define TOPO_SENSOR_STATE_ACPI_PSTATE_UNKNOWN 0x2000
+
+#define TOPO_SENSOR_TYPE_WATCHDOG2 0x0023
+
+#define TOPO_SENSOR_STATE_WATCHDOG2_EXPIRED 0x0001
+#define TOPO_SENSOR_STATE_WATCHDOG2_HARD_RESET 0x0002
+#define TOPO_SENSOR_STATE_WATCHDOG2_PWR_DOWN 0x0004
+#define TOPO_SENSOR_STATE_WATCHDOG2_PWR_CYCLE 0x0008
+#define TOPO_SENSOR_STATE_WATCHDOG2_RESERVED1 0x0010
+#define TOPO_SENSOR_STATE_WATCHDOG2_RESERVED2 0x0020
+#define TOPO_SENSOR_STATE_WATCHDOG2_RESERVED3 0x0040
+#define TOPO_SENSOR_STATE_WATCHDOG2_RESERVED4 0x0080
+#define TOPO_SENSOR_STATE_WATCHDOG2_TIMEOUT_INT 0x0100
+
+#define TOPO_SENSOR_TYPE_ALERT 0x0024
+
+#define TOPO_SENSOR_STATE_ALERT_PLAT_PAGE 0x0001
+#define TOPO_SENSOR_STATE_ALERT_PLAT_LAN_ALERT 0x0002
+#define TOPO_SENSOR_STATE_ALERT_PLAT_EVT_TRAP 0x0004
+#define TOPO_SENSOR_STATE_ALERT_PLAT_SNMP_TRAP 0x0008
+
+#define TOPO_SENSOR_TYPE_PRESENCE 0x0025
+
+#define TOPO_SENSOR_STATE_PRESENCE_PRESENT 0x0001
+#define TOPO_SENSOR_STATE_PRESENCE_ABSENT 0x0002
+#define TOPO_SENSOR_STATE_PRESENCE_DISABLED 0x0004
+
+#define TOPO_SENSOR_TYPE_ASIC 0x0026
+
+#define TOPO_SENSOR_TYPE_LAN 0x0027
+
+#define TOPO_SENSOR_STATE_LAN_HEARTBEAT_LOST 0x0001
+#define TOPO_SENSOR_STATE_LAN_HEARTBEAT 0x0002
+
+#define TOPO_SENSOR_TYPE_HEALTH 0x0028
+
+#define TOPO_SENSOR_STATE_HEALTH_SENSOR_ACC_DEGRADED 0x0001
+#define TOPO_SENSOR_STATE_HEALTH_CNTLR_ACC_DEGRADED 0x0002
+#define TOPO_SENSOR_STATE_HEALTH_CNTLR_OFFLINE 0x0004
+#define TOPO_SENSOR_STATE_HEALTH_CNTLR_UNAVAIL 0x0008
+#define TOPO_SENSOR_STATE_HEALTH_SENSOR_FAILURE 0x0010
+#define TOPO_SENSOR_STATE_HEALTH_FRU_FAILURE 0x0020
+
+#define TOPO_SENSOR_TYPE_BATTERY 0x0029
+
+#define TOPO_SENSOR_STATE_BATTERY_LOW 0x0001
+#define TOPO_SENSOR_STATE_BATTERY_FAILED 0x0002
+#define TOPO_SENSOR_STATE_BATTERY_PRESENCE 0x0004
+
+#define TOPO_SENSOR_TYPE_AUDIT 0x002A
+
+#define TOPO_SENSOR_STATE_AUDIT_SESSION_ACTIVATED 0x0001
+#define TOPO_SENSOR_STATE_AUDIT_SESSION_DEACTIVATED 0x0002
+
+#define TOPO_SENSOR_TYPE_VERSION 0x002B
+
+#define TOPO_SENSOR_STATE_VERSION_HW_CHANGE 0x0001
+#define TOPO_SENSOR_STATE_VERSION_SW_CHANGE 0x0002
+#define TOPO_SENSOR_STATE_VERSION_HW_INCOMPATIBLE 0x0004
+#define TOPO_SENSOR_STATE_VERSION_SW_INCOMPATIBLE 0x0008
+#define TOPO_SENSOR_STATE_VERSION_HW_INVAL 0x0010
+#define TOPO_SENSOR_STATE_VERSION_SW_INVAL 0x0020
+#define TOPO_SENSOR_STATE_VERSION_HW_CHANGE_SUCCESS 0x0040
+#define TOPO_SENSOR_STATE_VERSION_SW_CHANGE_SUCCESS 0x0080
+
+#define TOPO_SENSOR_TYPE_FRU_STATE 0x002C
+
+#define TOPO_SENSOR_STATE_FRU_STATE_NOT_INSTALLED 0x0001
+#define TOPO_SENSOR_STATE_FRU_STATE_INACTIVE 0x0002
+#define TOPO_SENSOR_STATE_FRU_STATE_ACT_REQ 0x0004
+#define TOPO_SENSOR_STATE_FRU_STATE_ACT_INPROGRESS 0x0008
+#define TOPO_SENSOR_STATE_FRU_STATE_ACTIVE 0x0010
+#define TOPO_SENSOR_STATE_FRU_STATE_DEACT_REQ 0x0020
+#define TOPO_SENSOR_STATE_FRU_STATE_DEACT_INPROGRESS 0x0040
+#define TOPO_SENSOR_STATE_FRU_STATE_COMM_LOST 0x0080
+
+/*
+ * We simplify the IPMI sensor type code defines by combining the generic
+ * and sensor-specific codes into a single range. Because there's overlap
+ * between the two ranges we offset the generic type codes by 0x0100
+ * which allows ample room in the hole for future expansion of the table to
+ * accomodate either additions to the IPMI spec or to support new sensor types
+ * for alternate provider modules.
+ */
+#define TOPO_SENSOR_TYPE_THRESHOLD_STATE 0x0101
+
+#define TOPO_SENSOR_THRESH_LOWER_NONCRIT_GOING_LOW 0x0001
+#define TOPO_SENSOR_THRESH_LOWER_NONCRIT_GOING_HIGH 0x0002
+#define TOPO_SENSOR_THRESH_LOWER_CRIT_GOING_LOW 0x0004
+#define TOPO_SENSOR_THRESH_LOWER_CRIT_GOING_HIGH 0x0008
+#define TOPO_SENSOR_THRESH_LOWER_NONREC_GOING_LOW 0x0010
+#define TOPO_SENSOR_THRESH_LOWER_NONREC_GOING_HIGH 0x0020
+#define TOPO_SENSOR_THRESH_UPPER_NONCRIT_GOING_LOW 0x0040
+#define TOPO_SENSOR_THRESH_UPPER_NONCRIT_GOING_HIGH 0x0080
+#define TOPO_SENSOR_THRESH_UPPER_CRIT_GOING_LOW 0x0100
+#define TOPO_SENSOR_THRESH_UPPER_CRIT_GOING_HIGH 0x0200
+#define TOPO_SENSOR_THRESH_UPPER_NONREC_GOING_LOW 0x0400
+#define TOPO_SENSOR_THRESH_UPPER_NONREC_GOING_HIGH 0x0800
+
+#define TOPO_SENSOR_TYPE_GENERIC_USAGE 0x0102
+
+#define TOPO_SENSOR_STATE_GENERIC_USAGE_IDLE 0x0001
+#define TOPO_SENSOR_STATE_GENERIC_USAGE_ACTIVE 0x0002
+#define TOPO_SENSOR_STATE_GENERIC_USAGE_BUSY 0x0004
+
+#define TOPO_SENSOR_TYPE_GENERIC_STATE 0x0103
+
+#define TOPO_SENSOR_STATE_GENERIC_STATE_DEASSERTED 0x0001
+#define TOPO_SENSOR_STATE_GENERIC_STATE_ASSERTED 0x0002
+
+#define TOPO_SENSOR_TYPE_GENERIC_PREDFAIL 0x0104
+
+#define TOPO_SENSOR_STATE_GENERIC_PREDFAIL_DEASSERTED 0x0001
+#define TOPO_SENSOR_STATE_GENERIC_PREDFAIL_ASSERTED 0x0002
+
+#define TOPO_SENSOR_TYPE_GENERIC_LIMIT 0x0105
+
+#define TOPO_SENSOR_STATE_GENERIC_LIMIT_NOT_EXCEEDED 0x0001
+#define TOPO_SENSOR_STATE_GENERIC_LIMIT_EXCEEDED 0x0002
+
+#define TOPO_SENSOR_TYPE_GENERIC_PERFORMANCE 0x0106
+
+#define TOPO_SENSOR_STATE_GENERIC_PERFORMANCE_MET 0x0001
+#define TOPO_SENSOR_STATE_GENERIC_PERFORMANCE_LAGS 0x0002
+
+#define TOPO_SENSOR_TYPE_SEVERITY 0x0107
+
+#define TOPO_SENSOR_STATE_SEVERITY_OK 0x0001
+#define TOPO_SENSOR_STATE_SEVERITY_NONCRIT_GOING_HIGH 0x0002
+#define TOPO_SENSOR_STATE_SEVERITY_CRIT_GOING_HIGH 0x0004
+#define TOPO_SENSOR_STATE_SEVERITY_NONREC_GOING_HIGH 0x0008
+#define TOPO_SENSOR_STATE_SEVERITY_NONCRIT_GOING_LOW 0x0010
+#define TOPO_SENSOR_STATE_SEVERITY_CRIT_GOING_LOW 0x0020
+#define TOPO_SENSOR_STATE_SEVERITY_NONREC_GOING_LOW 0x0020
+#define TOPO_SENSOR_STATE_SEVERITY_MONITOR 0x0040
+#define TOPO_SENSOR_STATE_SEVERITY_INFORMATIONAL 0x0080
+
+#define TOPO_SENSOR_TYPE_GENERIC_PRESENCE 0x0108
+
+#define TOPO_SENSOR_STATE_GENERIC_PRESENCE_DEASSERTED 0x0001
+#define TOPO_SENSOR_STATE_GENERIC_PRESENCE_ASSERTED 0x0002
+
+#define TOPO_SENSOR_TYPE_GENERIC_AVAILABILITY 0x0109
+
+#define TOPO_SENSOR_STATE_GENERIC_AVAIL_DEASSERTED 0x0001
+#define TOPO_SENSOR_STATE_GENERIC_AVAIL_ASSERTED 0x0002
+
+#define TOPO_SENSOR_TYPE_GENERIC_STATUS 0x010A
+
+#define TOPO_SENSOR_STATE_GENERIC_STATUS_RUNNING 0x0001
+#define TOPO_SENSOR_STATE_GENERIC_STATUS_IN_TEST 0x0002
+#define TOPO_SENSOR_STATE_GENERIC_STATUS_POWER_OFF 0x0004
+#define TOPO_SENSOR_STATE_GENERIC_STATUS_ONLINE 0x0008
+#define TOPO_SENSOR_STATE_GENERIC_STATUS_OFFLINE 0x0010
+#define TOPO_SENSOR_STATE_GENERIC_STATUS_OFF_DUTY 0x0020
+#define TOPO_SENSOR_STATE_GENERIC_STATUS_DEGRADED 0x0040
+#define TOPO_SENSOR_STATE_GENERIC_STATUS_POWER_SAVE 0x0080
+#define TOPO_SENSOR_STATE_GENERIC_STATUS_INSTALL_ERR 0x0100
+
+#define TOPO_SENSOR_TYPE_GENERIC_REDUNDANCY 0x010B
+
+/*
+ * ACPI power state
+ */
+#define TOPO_SENSOR_TYPE_GENERIC_ACPI 0x010C
+
+#define TOPO_SENSOR_STATE_GENERIC_ACPI_D0 0x0001
+#define TOPO_SENSOR_STATE_GENERIC_ACPI_D1 0x0002
+#define TOPO_SENSOR_STATE_GENERIC_ACPI_D2 0x0004
+#define TOPO_SENSOR_STATE_GENERIC_ACPI_D3 0x0008
+
+/*
+ * Indicator modes and types
+ */
+typedef enum topo_led_state {
+ TOPO_LED_STATE_OFF = 0,
+ TOPO_LED_STATE_ON
+} topo_led_state_t;
+
+/*
+ * This list is limited to the set of LED's that we're likely to manage through
+ * FMA. Thus is does not include things like power or activity LED's
+ */
+typedef enum topo_led_type {
+ TOPO_LED_TYPE_SERVICE = 0,
+ TOPO_LED_TYPE_LOCATE,
+ TOPO_LED_TYPE_OK2RM,
+ TOPO_LED_TYPE_PRESENT
+} topo_led_type_t;
+
+
#ifdef __cplusplus
}
#endif
--- a/usr/src/lib/fm/topo/libtopo/common/mapfile-vers Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/mapfile-vers Thu Jul 31 17:35:39 2008 -0700
@@ -34,6 +34,7 @@
topo_fmri_contains;
topo_fmri_create;
topo_fmri_expand;
+ topo_fmri_facility;
topo_fmri_fru;
topo_fmri_getpgrp;
topo_fmri_getprop;
@@ -55,10 +56,13 @@
topo_hdl_strdup;
topo_hdl_strfree;
topo_hdl_zalloc;
+ topo_led_state_name;
+ topo_led_type_name;
topo_list_append;
topo_list_delete;
topo_method_invoke;
topo_method_register;
+ topo_method_supported;
topo_method_unregister;
topo_method_unregister_all;
topo_mod_alloc;
@@ -98,6 +102,9 @@
topo_node_asru;
topo_node_asru_set;
topo_node_bind;
+ topo_node_facility;
+ topo_node_facbind;
+ topo_node_flags;
topo_node_fru;
topo_node_fru_set;
topo_node_getspecific;
@@ -121,6 +128,7 @@
topo_prop_get_string;
topo_prop_get_uint32;
topo_prop_get_uint64;
+ topo_prop_get_double;
topo_prop_get_int32_array;
topo_prop_get_uint32_array;
topo_prop_get_int64_array;
@@ -139,6 +147,7 @@
topo_prop_set_string;
topo_prop_set_uint32;
topo_prop_set_uint64;
+ topo_prop_set_double;
topo_prop_set_int32_array;
topo_prop_set_uint32_array;
topo_prop_set_int64_array;
@@ -146,7 +155,11 @@
topo_prop_set_string_array;
topo_prop_set_fmri_array;
topo_prop_setprop;
+ topo_prop_setmutable;
topo_name2stability;
+ topo_sensor_state_name;
+ topo_sensor_type_name;
+ topo_sensor_units_name;
topo_stability2name;
topo_snap_hold;
topo_snap_release;
--- a/usr/src/lib/fm/topo/libtopo/common/topo_2xml.c Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_2xml.c Thu Jul 31 17:35:39 2008 -0700
@@ -38,7 +38,8 @@
#include <topo_tree.h>
#define INT32BUFSZ sizeof (UINT32_MAX) + 1
-#define INT64BUFSZ sizeof (UINT64_MAX) + 1
+/* 2 bytes for "0x" + 16 bytes for the hex value + 1 for sign + null */
+#define INT64BUFSZ 20
#define XML_VERSION "1.0"
static int txml_print_range(topo_hdl_t *, FILE *, tnode_t *, int);
@@ -103,77 +104,88 @@
}
static void
-txml_print_prop(topo_hdl_t *thp, FILE *fp, topo_propval_t *pv)
+txml_print_prop(topo_hdl_t *thp, FILE *fp, tnode_t *node, const char *pgname,
+ topo_propval_t *pv)
{
int err;
char *fmri = NULL;
- char vbuf[INT64BUFSZ], tbuf[10], *pval, *aval;
- nvpair_t *nvp;
-
- nvp = nvlist_next_nvpair(pv->tp_val, NULL);
- while (nvp && (strcmp(TOPO_PROP_VAL_VAL, nvpair_name(nvp)) != 0))
- nvp = nvlist_next_nvpair(pv->tp_val, nvp);
-
- if (nvp == NULL)
- return;
+ char vbuf[INT64BUFSZ], tbuf[32], *pval = NULL, *aval;
switch (pv->tp_type) {
case TOPO_TYPE_INT32: {
int32_t val;
- (void) nvpair_value_int32(nvp, &val);
- (void) snprintf(vbuf, INT64BUFSZ, "%d", val);
- (void) snprintf(tbuf, 10, "%s", Int32);
- pval = vbuf;
+ if (topo_prop_get_int32(node, pgname, pv->tp_name, &val,
+ &err) == 0) {
+ (void) snprintf(vbuf, INT64BUFSZ, "%d", val);
+ (void) snprintf(tbuf, 10, "%s", Int32);
+ pval = vbuf;
+ } else
+ return;
break;
}
case TOPO_TYPE_UINT32: {
uint32_t val;
- (void) nvpair_value_uint32(nvp, &val);
- (void) snprintf(vbuf, INT64BUFSZ, "0x%x", val);
- (void) snprintf(tbuf, 10, "%s", UInt32);
- pval = vbuf;
+ if (topo_prop_get_uint32(node, pgname, pv->tp_name,
+ &val, &err) == 0) {
+ (void) snprintf(vbuf, INT64BUFSZ, "0x%x", val);
+ (void) snprintf(tbuf, 10, "%s", UInt32);
+ pval = vbuf;
+ } else
+ return;
break;
}
case TOPO_TYPE_INT64: {
int64_t val;
- (void) nvpair_value_int64(nvp, &val);
- (void) snprintf(vbuf, INT64BUFSZ, "%lld",
- (longlong_t)val);
- (void) snprintf(tbuf, 10, "%s", Int64);
- pval = vbuf;
+ if (topo_prop_get_int64(node, pgname, pv->tp_name, &val,
+ &err) == 0) {
+ (void) snprintf(vbuf, INT64BUFSZ, "0x%llx",
+ (longlong_t)val);
+ (void) snprintf(tbuf, 10, "%s", Int64);
+ pval = vbuf;
+ } else
+ return;
break;
}
case TOPO_TYPE_UINT64: {
uint64_t val;
- (void) nvpair_value_uint64(nvp, &val);
- (void) snprintf(vbuf, INT64BUFSZ, "0x%llx",
- (u_longlong_t)val);
- (void) snprintf(tbuf, 10, "%s", UInt64);
- pval = vbuf;
+ if (topo_prop_get_uint64(node, pgname, pv->tp_name,
+ &val, &err) == 0) {
+ (void) snprintf(vbuf, INT64BUFSZ, "0x%llx",
+ (u_longlong_t)val);
+ (void) snprintf(tbuf, 10, "%s", UInt64);
+ pval = vbuf;
+ } else
+ return;
break;
}
case TOPO_TYPE_STRING: {
- (void) nvpair_value_string(nvp, &pval);
- (void) snprintf(tbuf, 10, "%s", String);
+ if (topo_prop_get_string(node, pgname, pv->tp_name,
+ &pval, &err) != 0)
+ return;
+ (void) snprintf(tbuf, 10, "%s", "string");
break;
}
case TOPO_TYPE_FMRI: {
nvlist_t *val;
- (void) nvpair_value_nvlist(nvp, &val);
- if (topo_fmri_nvl2str(thp, val, &fmri, &err) == 0)
- pval = fmri;
- else
+ if (topo_prop_get_fmri(node, pgname, pv->tp_name, &val,
+ &err) == 0) {
+ if (topo_fmri_nvl2str(thp, val, &fmri, &err)
+ == 0)
+ pval = fmri;
+ else
+ return;
+ } else
return;
-
(void) snprintf(tbuf, 10, "%s", FMRI);
break;
}
case TOPO_TYPE_UINT32_ARRAY: {
uint32_t *val;
uint_t nelem, i;
-
- (void) nvpair_value_uint32_array(nvp, &val, &nelem);
+ if (topo_prop_get_uint32_array(node, pgname,
+ pv->tp_name, &val, &nelem, &err) != 0)
+ return;
if (nelem > 0) {
aval = calloc((nelem*9-1), sizeof (uchar_t));
@@ -195,11 +207,10 @@
if (fmri != NULL)
topo_hdl_strfree(thp, fmri);
-
}
static void
-txml_print_pgroup(topo_hdl_t *thp, FILE *fp, topo_pgroup_t *pg)
+txml_print_pgroup(topo_hdl_t *thp, FILE *fp, tnode_t *node, topo_pgroup_t *pg)
{
topo_ipgroup_info_t *pip = pg->tpg_info;
topo_proplist_t *plp;
@@ -213,7 +224,7 @@
namestab, Datastab, datastab, Version, version, NULL);
for (plp = topo_list_next(&pg->tpg_pvals); plp != NULL;
plp = topo_list_next(plp)) {
- txml_print_prop(thp, fp, plp->tp_pval);
+ txml_print_prop(thp, fp, node, pip->tpi_name, plp->tp_pval);
}
end_element(fp, Propgrp);
}
@@ -238,7 +249,7 @@
begin_element(fp, Node, Instance, inst, Static, True, NULL);
for (pg = topo_list_next(&node->tn_pgroups); pg != NULL;
pg = topo_list_next(pg)) {
- txml_print_pgroup(thp, fp, pg);
+ txml_print_pgroup(thp, fp, node, pg);
}
txml_print_dependents(thp, fp, node);
end_element(fp, Node);
--- a/usr/src/lib/fm/topo/libtopo/common/topo_error.h Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_error.h Thu Jul 31 17:35:39 2008 -0700
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -64,13 +64,6 @@
ETOPO_RTLD_NOMEM, /* memory limit exceeded when opening shared library */
ETOPO_BLTIN_NAME, /* built-in plug-in name not found in definition list */
ETOPO_BLTIN_INIT, /* built-in plug-in does not define init function */
- ETOPO_NODE_INVAL, /* node opertation invalid argument */
- ETOPO_NODE_LINKED, /* node already linked */
- ETOPO_NODE_BOUND, /* node already bound */
- ETOPO_NODE_DUP, /* duplicate node */
- ETOPO_NODE_RANGE, /* invalid instance range */
- ETOPO_NODE_NOENT, /* node not found */
- ETOPO_NODE_FMRI, /* no fmri specified */
ETOPO_VER_OLD, /* plugin compiled using an obsolete topo ABI */
ETOPO_VER_NEW, /* plugin is compiled using a newer topo ABI */
ETOPO_ENUM_PARTIAL, /* partial enumeration completed for client */
@@ -93,6 +86,7 @@
ETOPO_PRSR_REGMETH, /* failed to register property method */
ETOPO_WALK_EMPTY, /* empty topology */
ETOPO_WALK_NOTFOUND, /* scheme based topology not found */
+ ETOPO_FAC_NOENT, /* no facility node of specified type found */
ETOPO_END /* end of custom errno list (to ease auto-merge) */
} topo_errno_t;
--- a/usr/src/lib/fm/topo/libtopo/common/topo_fmri.c Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_fmri.c Thu Jul 31 17:35:39 2008 -0700
@@ -690,3 +690,49 @@
return (strcmp(ea, eb) == 0);
}
+
+int
+topo_fmri_facility(topo_hdl_t *thp, nvlist_t *rsrc, const char *fac_type,
+ uint32_t fac_subtype, topo_walk_cb_t cb, void *cb_args, int *err)
+{
+ int rv;
+ nvlist_t *in = NULL, *out;
+ tnode_t *rnode;
+ char *scheme;
+
+ if (nvlist_lookup_string(rsrc, FM_FMRI_SCHEME, &scheme) != 0)
+ return (set_error(thp, ETOPO_FMRI_MALFORM, err,
+ TOPO_METH_PROP_GET, in));
+
+ if ((rnode = topo_hdl_root(thp, scheme)) == NULL)
+ return (set_error(thp, ETOPO_METHOD_NOTSUP, err,
+ TOPO_METH_PROP_GET, in));
+
+ if (topo_hdl_nvalloc(thp, &in, NV_UNIQUE_NAME) != 0)
+ return (set_error(thp, ETOPO_FMRI_NVL, err,
+ TOPO_METH_PROP_GET, in));
+
+ rv = nvlist_add_nvlist(in, TOPO_PROP_RESOURCE, rsrc);
+ rv |= nvlist_add_string(in, FM_FMRI_FACILITY_TYPE, fac_type);
+ rv |= nvlist_add_uint32(in, "type", fac_subtype);
+#ifdef _LP64
+ rv |= nvlist_add_uint64(in, "callback", (uint64_t)cb);
+ rv |= nvlist_add_uint64(in, "callback-args", (uint64_t)cb_args);
+#else
+ rv |= nvlist_add_uint32(in, "callback", (uint32_t)cb);
+ rv |= nvlist_add_uint32(in, "callback-args", (uint32_t)cb_args);
+#endif
+ if (rv != 0)
+ return (set_error(thp, ETOPO_FMRI_NVL, err,
+ TOPO_METH_PROP_GET, in));
+
+ rv = topo_method_invoke(rnode, TOPO_METH_FACILITY,
+ TOPO_METH_FACILITY_VERSION, in, &out, err);
+
+ nvlist_free(in);
+
+ if (rv != 0)
+ return (-1); /* *err is set for us */
+
+ return (0);
+}
--- a/usr/src/lib/fm/topo/libtopo/common/topo_method.c Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_method.c Thu Jul 31 17:35:39 2008 -0700
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -58,6 +58,29 @@
return (NULL);
}
+/*
+ * Simple API to determine if the specified node supports a given topo method
+ * (specified by the method name and version). Returns true if supported, false
+ * otherwise.
+ */
+boolean_t
+topo_method_supported(tnode_t *node, const char *name, topo_version_t vers)
+{
+ topo_imethod_t *mp;
+
+ topo_node_lock(node);
+ for (mp = topo_list_next(&node->tn_methods); mp != NULL;
+ mp = topo_list_next(mp)) {
+ if ((strcmp(name, mp->tim_name) == 0) &&
+ (vers == mp->tim_version)) {
+ topo_node_unlock(node);
+ return (B_TRUE);
+ }
+ }
+ topo_node_unlock(node);
+ return (B_FALSE);
+}
+
static void
topo_method_enter(topo_imethod_t *mp)
{
--- a/usr/src/lib/fm/topo/libtopo/common/topo_method.h Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_method.h Thu Jul 31 17:35:39 2008 -0700
@@ -67,6 +67,7 @@
#define TOPO_METH_PROP_GET "topo_prop_get"
#define TOPO_METH_PGRP_GET "topo_pgrp_get"
#define TOPO_METH_PROP_SET "topo_prop_set"
+#define TOPO_METH_FACILITY "topo_facility"
#define TOPO_METH_FMRI_VERSION 0
#define TOPO_METH_FRU_COMPUTE_VERSION 0
@@ -77,6 +78,7 @@
#define TOPO_METH_PROP_GET_VERSION 0
#define TOPO_METH_PGRP_GET_VERSION 0
#define TOPO_METH_PROP_SET_VERSION 0
+#define TOPO_METH_FACILITY_VERSION 0
#define TOPO_METH_ASRU_COMPUTE_DESC "Dynamic ASRU constructor"
#define TOPO_METH_FRU_COMPUTE_DESC "Dynamic FRU constructor"
@@ -87,6 +89,7 @@
#define TOPO_METH_PROP_GET_DESC "get properties for FMRI"
#define TOPO_METH_PGRP_GET_DESC "get property group for FMRI"
#define TOPO_METH_PROP_SET_DESC "set properties for FMRI"
+#define TOPO_METH_FACILITY_DESC "get facility for FMRI"
#define TOPO_METH_COMPARE_RET "contains-return"
--- a/usr/src/lib/fm/topo/libtopo/common/topo_mod.h Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_mod.h Thu Jul 31 17:35:39 2008 -0700
@@ -96,7 +96,8 @@
extern nvlist_t *topo_mod_pkgfmri(topo_mod_t *, int, const char *);
extern int topo_mod_nvl2str(topo_mod_t *, nvlist_t *, char **);
extern int topo_mod_str2nvl(topo_mod_t *, const char *, nvlist_t **);
-
+extern int topo_prop_setmutable(tnode_t *node, const char *pgname,
+ const char *pname, int *err);
/*
* Snapshot walker support
*/
@@ -127,8 +128,8 @@
#define TOPO_METH_LABEL_DESC "label constructor"
#define TOPO_METH_LABEL_VERSION0 0
#define TOPO_METH_LABEL_VERSION TOPO_METH_LABEL_VERSION0
-#define TOPO_METH_LABEL_ARG_NVL "label-specific"
-#define TOPO_METH_LABEL_RET_STR "label-string"
+#define TOPO_METH_LABEL_ARG_NVL "label-specific"
+#define TOPO_METH_LABEL_RET_STR "label-string"
#define TOPO_METH_PRESENT "topo_present"
#define TOPO_METH_PRESENT_DESC "presence indicator"
@@ -167,6 +168,11 @@
#define TOPO_METH_DISK_STATUS_VERSION 0
#define TOPO_METH_DISK_STATUS_DESC "Disk status"
+#define TOPO_PROP_METH_DESC "Dynamic Property method"
+
+#define TOPO_METH_IPMI_ENTITY "ipmi_entity"
+#define TOPO_METH_FAC_ENUM_DESC "Facility Enumerator"
+
extern void *topo_mod_alloc(topo_mod_t *, size_t);
extern void *topo_mod_zalloc(topo_mod_t *, size_t);
extern void topo_mod_free(topo_mod_t *, void *, size_t);
@@ -189,6 +195,8 @@
extern void topo_node_range_destroy(tnode_t *, const char *);
extern tnode_t *topo_node_bind(topo_mod_t *, tnode_t *, const char *,
topo_instance_t, nvlist_t *);
+extern tnode_t *topo_node_facbind(topo_mod_t *, tnode_t *, const char *,
+ const char *);
extern void topo_node_unbind(tnode_t *);
extern void topo_node_setspecific(tnode_t *, void *);
extern void *topo_node_getspecific(tnode_t *);
@@ -199,33 +207,6 @@
#define TOPO_ASRU_COMPUTE 0x0001 /* Compute ASRU dynamically */
#define TOPO_FRU_COMPUTE 0x0002 /* Compute FRU dynamically */
-/*
- * Topo property set functions
- */
-extern int topo_prop_set_int32(tnode_t *, const char *, const char *, int,
- int32_t, int *);
-extern int topo_prop_set_uint32(tnode_t *, const char *, const char *, int,
- uint32_t, int *);
-extern int topo_prop_set_int64(tnode_t *, const char *, const char *,
- int, int64_t, int *);
-extern int topo_prop_set_uint64(tnode_t *, const char *, const char *,
- int, uint64_t, int *);
-extern int topo_prop_set_string(tnode_t *, const char *, const char *,
- int, const char *, int *);
-extern int topo_prop_set_fmri(tnode_t *, const char *, const char *,
- int, const nvlist_t *, int *);
-extern int topo_prop_set_int32_array(tnode_t *, const char *, const char *, int,
- int32_t *, uint_t, int *);
-extern int topo_prop_set_uint32_array(tnode_t *, const char *, const char *,
- int, uint32_t *, uint_t, int *);
-extern int topo_prop_set_int64_array(tnode_t *, const char *, const char *,
- int, int64_t *, uint_t, int *);
-extern int topo_prop_set_uint64_array(tnode_t *, const char *, const char *,
- int, uint64_t *, uint_t, int *);
-extern int topo_prop_set_string_array(tnode_t *, const char *, const char *,
- int, const char **, uint_t, int *);
-extern int topo_prop_set_fmri_array(tnode_t *, const char *, const char *,
- int, const nvlist_t **, uint_t, int *);
extern int topo_prop_inherit(tnode_t *, const char *, const char *, int *);
extern int topo_pgroup_create(tnode_t *, const topo_pgroup_info_t *, int *);
@@ -252,6 +233,10 @@
EMOD_FMRI_NVL, /* nvlist allocation failure for FMRI */
EMOD_FMRI_VERSION, /* invalid FMRI scheme version */
EMOD_FMRI_MALFORM, /* malformed FMRI */
+ EMOD_NODE_BOUND, /* node already bound */
+ EMOD_NODE_DUP, /* duplicate node */
+ EMOD_NODE_NOENT, /* node not found */
+ EMOD_NODE_RANGE, /* invalid node range */
EMOD_VER_ABI, /* registered with invalid ABI version */
EMOD_VER_OLD, /* attempt to load obsolete module */
EMOD_VER_NEW, /* attempt to load a newer module */
--- a/usr/src/lib/fm/topo/libtopo/common/topo_node.c Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_node.c Thu Jul 31 17:35:39 2008 -0700
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -94,6 +94,13 @@
* -----------
* | tnode_t |
* -----------
+ *
+ * Facility Nodes
+ *
+ * Facility nodes are always leaf nodes in the topology and represent a FMRI
+ * sensor or indicator facility for the path to which it is connected.
+ * Facility nodes are bound to the topology with topo_node_facbind() and
+ * unbound with topo_node_unbind().
*/
#include <assert.h>
@@ -102,6 +109,7 @@
#include <sys/fm/protocol.h>
#include <topo_alloc.h>
#include <topo_error.h>
+#include <topo_list.h>
#include <topo_method.h>
#include <topo_subr.h>
#include <topo_tree.h>
@@ -248,6 +256,12 @@
return (node->tn_parent);
}
+int
+topo_node_flags(tnode_t *node)
+{
+ return (node->tn_fflags);
+}
+
void
topo_node_setspecific(tnode_t *node, void *data)
{
@@ -297,24 +311,24 @@
nhp = topo_list_next(nhp)) {
if (strcmp(nhp->th_name, name) == 0)
return (node_create_seterror(mod, pnode, NULL,
- ETOPO_NODE_DUP));
+ EMOD_NODE_DUP));
}
if (min < 0 || max < min)
return (node_create_seterror(mod, pnode, NULL,
- ETOPO_NODE_INVAL));
+ EMOD_NODE_RANGE));
if ((nhp = topo_mod_zalloc(mod, sizeof (topo_nodehash_t))) == NULL)
- return (node_create_seterror(mod, pnode, nhp, ETOPO_NOMEM));
+ return (node_create_seterror(mod, pnode, nhp, EMOD_NOMEM));
if ((nhp->th_name = topo_mod_strdup(mod, name)) == NULL)
- return (node_create_seterror(mod, pnode, nhp, ETOPO_NOMEM));
+ return (node_create_seterror(mod, pnode, nhp, EMOD_NOMEM));
nhp->th_arrlen = max - min + 1;
if ((nhp->th_nodearr = topo_mod_zalloc(mod,
nhp->th_arrlen * sizeof (tnode_t *))) == NULL)
- return (node_create_seterror(mod, pnode, nhp, ETOPO_NOMEM));
+ return (node_create_seterror(mod, pnode, nhp, EMOD_NOMEM));
nhp->th_range.tr_min = min;
nhp->th_range.tr_max = max;
@@ -442,12 +456,12 @@
if (inst > nhp->th_range.tr_max ||
inst < nhp->th_range.tr_min)
return (node_bind_seterror(mod, pnode, NULL,
- ETOPO_NODE_INVAL));
+ EMOD_NODE_RANGE));
h = topo_node_hash(nhp, inst);
if (nhp->th_nodearr[h] != NULL)
return (node_bind_seterror(mod, pnode, NULL,
- ETOPO_NODE_BOUND));
+ EMOD_NODE_BOUND));
else
break;
@@ -455,10 +469,10 @@
}
if (nhp == NULL)
- return (node_bind_seterror(mod, pnode, NULL, ETOPO_NODE_NOENT));
+ return (node_bind_seterror(mod, pnode, NULL, EMOD_NODE_NOENT));
if ((node = topo_mod_zalloc(mod, sizeof (tnode_t))) == NULL)
- return (node_bind_seterror(mod, pnode, NULL, ETOPO_NOMEM));
+ return (node_bind_seterror(mod, pnode, NULL, EMOD_NOMEM));
(void) pthread_mutex_init(&node->tn_lock, NULL);
@@ -474,7 +488,7 @@
topo_mod_hold(mod);
if (fmri == NULL)
- return (node_bind_seterror(mod, pnode, node, ETOPO_NODE_INVAL));
+ return (node_bind_seterror(mod, pnode, node, EMOD_NVL_INVAL));
if (topo_pgroup_create(node, &protocol_pgroup, &err) < 0)
return (node_bind_seterror(mod, pnode, node, err));
@@ -492,6 +506,7 @@
topo_node_hold(node);
nhp->th_nodearr[h] = node;
++pnode->tn_refs;
+
topo_node_unlock(pnode);
if (topo_pgroup_create(node, &auth_pgroup, &err) == 0) {
@@ -506,6 +521,227 @@
return (node);
}
+tnode_t *
+topo_node_facbind(topo_mod_t *mod, tnode_t *pnode, const char *name,
+ const char *type)
+{
+ int h, err;
+ tnode_t *node;
+ topo_nodehash_t *nhp;
+ topo_instance_t inst = 0;
+ nvlist_t *pfmri, *fnvl;
+
+ /*
+ * Create a single entry range for this facility
+ */
+ if (topo_node_range_create(mod, pnode, name, 0, 0) < 0)
+ return (NULL); /* mod errno set */
+
+ topo_node_lock(pnode);
+ for (nhp = topo_list_next(&pnode->tn_children); nhp != NULL;
+ nhp = topo_list_next(nhp)) {
+ if (strcmp(nhp->th_name, name) == 0) {
+
+ if (inst > nhp->th_range.tr_max ||
+ inst < nhp->th_range.tr_min)
+ return (node_bind_seterror(mod, pnode, NULL,
+ EMOD_NVL_INVAL));
+
+ h = topo_node_hash(nhp, inst);
+ if (nhp->th_nodearr[h] != NULL)
+ return (node_bind_seterror(mod, pnode, NULL,
+ EMOD_NODE_BOUND));
+ else
+ break;
+
+ }
+ }
+
+ if (nhp == NULL)
+ return (node_bind_seterror(mod, pnode, NULL, EMOD_NODE_NOENT));
+
+ if ((node = topo_mod_zalloc(mod, sizeof (tnode_t))) == NULL)
+ return (node_bind_seterror(mod, pnode, NULL, EMOD_NOMEM));
+
+ (void) pthread_mutex_init(&node->tn_lock, NULL);
+
+ node->tn_enum = mod;
+ node->tn_hdl = mod->tm_hdl;
+ node->tn_parent = pnode;
+ node->tn_name = nhp->th_name;
+ node->tn_instance = inst;
+ node->tn_phash = nhp;
+ node->tn_refs = 0;
+ node->tn_fflags = TOPO_NODE_FACILITY;
+
+ /* Ref count module that bound this node */
+ topo_mod_hold(mod);
+
+ if (topo_pgroup_create(node, &protocol_pgroup, &err) < 0)
+ return (node_bind_seterror(mod, pnode, node, err));
+
+ if (topo_mod_nvalloc(mod, &fnvl, NV_UNIQUE_NAME) < 0)
+ return (node_bind_seterror(mod, pnode, node, EMOD_NOMEM));
+ if (nvlist_add_string(fnvl, FM_FMRI_FACILITY_NAME, name) != 0 ||
+ nvlist_add_string(fnvl, FM_FMRI_FACILITY_TYPE, type) != 0) {
+ nvlist_free(fnvl);
+ return (node_bind_seterror(mod, pnode, node, EMOD_FMRI_NVL));
+ }
+
+ if (topo_node_resource(pnode, &pfmri, &err) < 0) {
+ nvlist_free(fnvl);
+ return (node_bind_seterror(mod, pnode, node, err));
+ }
+
+ if (nvlist_add_nvlist(pfmri, FM_FMRI_FACILITY, fnvl) != 0) {
+ nvlist_free(fnvl);
+ nvlist_free(pfmri);
+ return (node_bind_seterror(mod, pnode, node, EMOD_FMRI_NVL));
+ }
+
+ nvlist_free(fnvl);
+
+ if (topo_prop_set_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_RESOURCE,
+ TOPO_PROP_IMMUTABLE, pfmri, &err) < 0) {
+ nvlist_free(pfmri);
+ return (node_bind_seterror(mod, pnode, node, err));
+ }
+
+ nvlist_free(pfmri);
+
+ topo_dprintf(mod->tm_hdl, TOPO_DBG_MODSVC,
+ "facility node bound %s=%s\n", type, node->tn_name);
+
+ node->tn_state |= TOPO_NODE_BOUND;
+
+ topo_node_hold(node);
+ nhp->th_nodearr[h] = node;
+ ++pnode->tn_refs;
+
+ topo_node_unlock(pnode);
+
+ if (topo_pgroup_create(node, &auth_pgroup, &err) == 0) {
+ (void) topo_prop_inherit(node, FM_FMRI_AUTHORITY,
+ FM_FMRI_AUTH_PRODUCT, &err);
+ (void) topo_prop_inherit(node, FM_FMRI_AUTHORITY,
+ FM_FMRI_AUTH_CHASSIS, &err);
+ (void) topo_prop_inherit(node, FM_FMRI_AUTHORITY,
+ FM_FMRI_AUTH_SERVER, &err);
+ }
+
+ return (node);
+}
+
+int
+topo_node_facility(topo_hdl_t *thp, tnode_t *node, const char *fac_type,
+ uint32_t fac_subtype, topo_faclist_t *faclist, int *errp)
+{
+ tnode_t *tmp;
+ nvlist_t *rsrc, *fac, *out;
+ char *tmp_factype;
+ uint32_t tmp_facsubtype;
+ boolean_t list_empty = 1;
+ topo_faclist_t *fac_ele;
+
+ /*
+ * Some facility nodes will be statically enumerated in the xml maps.
+ * Other may be enumerated on-demand. We can check for/handle the
+ * latter case by looking for a node method for doing facility
+ * enumeration and invoking it, if found.
+ *
+ * If the TOPO_FACILITIES_BOUND flag is set on this node, then we've
+ * already enumerated the facilties for this node (by a previous call
+ * to topo_node_facility) so there's no need to invoke the enumeration
+ * method.
+ */
+ topo_node_lock(node);
+ if (!(node->tn_state & TOPO_FACILITIES_BOUND) &&
+ topo_method_supported(node, TOPO_METH_FAC_ENUM, 0)) {
+
+ if (topo_method_invoke(node, TOPO_METH_FAC_ENUM, 0, NULL, &out,
+ errp) != 0) {
+ topo_dprintf(thp, TOPO_DBG_ERR,
+ "topo_method_invoke failed (%s) on node %s=%d\n",
+ topo_strerror(*errp), topo_node_name(node),
+ topo_node_instance(node));
+ topo_node_unlock(node);
+ return (-1);
+ } else
+ node->tn_state |= TOPO_FACILITIES_BOUND;
+ }
+
+ bzero(faclist, sizeof (topo_faclist_t));
+ for (tmp = topo_child_first(node); tmp != NULL;
+ tmp = topo_child_next(node, tmp)) {
+
+ topo_node_hold(tmp);
+ /*
+ * If it's not a facility node, move on
+ */
+ if (topo_node_flags(tmp) != TOPO_NODE_FACILITY) {
+ topo_node_rele(tmp);
+ continue;
+ }
+
+ /*
+ * Lookup whether the fac type is sensor or indicator and if
+ * it's not the type we're looking for, move on
+ */
+ if (topo_node_resource(tmp, &rsrc, errp) != 0) {
+ topo_dprintf(thp, TOPO_DBG_ERR,
+ "Failed to get resource for node %s=%d (%s)\n",
+ topo_node_name(node), topo_node_instance(node),
+ topo_strerror(*errp));
+ topo_node_rele(tmp);
+ topo_node_unlock(node);
+ return (-1);
+ }
+ if ((nvlist_lookup_nvlist(rsrc, "facility", &fac) != 0) ||
+ (nvlist_lookup_string(fac, FM_FMRI_FACILITY_TYPE,
+ &tmp_factype) != 0)) {
+
+ topo_node_rele(tmp);
+ topo_node_unlock(node);
+ return (-1);
+ }
+ if (strcmp(fac_type, tmp_factype) != 0) {
+ topo_node_rele(tmp);
+ continue;
+ }
+
+ /*
+ * Finally, look up the subtype, which is a property in the
+ * facility propgroup. If it's a match return a pointer to the
+ * node. Otherwise, move on.
+ */
+ if (topo_prop_get_uint32(tmp, TOPO_PGROUP_FACILITY,
+ TOPO_FACILITY_TYPE, &tmp_facsubtype, errp) != 0) {
+
+ topo_node_rele(tmp);
+ topo_node_unlock(node);
+ return (-1);
+ }
+ if (fac_subtype == tmp_facsubtype) {
+ if ((fac_ele = topo_mod_zalloc(tmp->tn_enum,
+ sizeof (topo_faclist_t))) == NULL) {
+ *errp = ETOPO_NOMEM;
+ return (-1);
+ }
+ fac_ele->tf_node = tmp;
+ topo_list_append(&faclist->tf_list, fac_ele);
+ list_empty = 0;
+ }
+ topo_node_rele(tmp);
+ }
+ topo_node_unlock(node);
+
+ if (list_empty) {
+ *errp = ETOPO_FAC_NOENT;
+ return (-1);
+ }
+ return (0);
+}
+
void
topo_node_unbind(tnode_t *node)
{
@@ -561,7 +797,7 @@
topo_node_hold(node);
if ((wp = topo_hdl_zalloc(thp, sizeof (topo_walk_t))) == NULL) {
- *errp = ETOPO_NOMEM;
+ *errp = ETOPO_HDL_NOMEM;
topo_node_rele(node);
return (NULL);
}
--- a/usr/src/lib/fm/topo/libtopo/common/topo_parse.h Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_parse.h Thu Jul 31 17:35:39 2008 -0700
@@ -95,6 +95,15 @@
tf_edata_t *rd_einfo; /* enumerator information, if any */
struct tf_idata *rd_instances; /* hard instances */
tf_pad_t *rd_pad; /* properties and dependents */
+ /*
+ * true, if this range xml element contains any child xml
+ * node elements.
+ * We use this to determine whether or not we should apply
+ * property map changes to all of the nodes in a given range
+ * or just a specific node.
+ *
+ */
+ int contains_node_ele;
} tf_rdata_t;
/*
@@ -135,19 +144,25 @@
#define Argval "argval"
#define Children "children"
#define Dependents "dependents"
+#define Facility "facility"
#define FMRI "fmri"
#define Grouping "grouping"
#define Immutable "immutable"
+#define Indicator "indicator"
#define Instance "instance"
#define Int32 "int32"
#define Int64 "int64"
+#define Ipmi "ipmi"
+#define Mutable "mutable"
#define Name "name"
#define Propname "propname"
#define Proptype "proptype"
+#define Provider "provider"
#define Range "range"
#define Scheme "scheme"
#define Set "set"
#define Setlist "setlist"
+#define Sensor "sensor"
#define Siblings "siblings"
#define Static "static"
#define String "string"
--- a/usr/src/lib/fm/topo/libtopo/common/topo_prop.c Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_prop.c Thu Jul 31 17:35:39 2008 -0700
@@ -234,6 +234,10 @@
ret = nvlist_lookup_uint64(pv->tp_val,
TOPO_PROP_VAL_VAL, (uint64_t *)val);
break;
+ case TOPO_TYPE_DOUBLE:
+ ret = nvlist_lookup_double(pv->tp_val,
+ TOPO_PROP_VAL_VAL, (double *)val);
+ break;
case TOPO_TYPE_STRING: {
char *str;
@@ -419,6 +423,14 @@
}
int
+topo_prop_get_double(tnode_t *node, const char *pgname, const char *pname,
+ double *val, int *err)
+{
+ return (prop_getval(node, pgname, pname, (void *)val, TOPO_TYPE_DOUBLE,
+ NULL, err));
+}
+
+int
topo_prop_get_string(tnode_t *node, const char *pgname, const char *pname,
char **val, int *err)
{
@@ -557,7 +569,6 @@
int ret;
topo_hdl_t *thp = node->tn_hdl;
nvlist_t *nvl;
- topo_propval_t *pv;
if (topo_hdl_nvalloc(thp, &nvl, NV_UNIQUE_NAME) < 0) {
*err = ETOPO_PROP_NVL;
@@ -583,6 +594,10 @@
ret |= nvlist_add_uint64(nvl, TOPO_PROP_VAL_VAL,
*(uint64_t *)val);
break;
+ case TOPO_TYPE_DOUBLE:
+ ret |= nvlist_add_double(nvl, TOPO_PROP_VAL_VAL,
+ *(double *)val);
+ break;
case TOPO_TYPE_STRING:
ret |= nvlist_add_string(nvl, TOPO_PROP_VAL_VAL,
(char *)val);
@@ -631,16 +646,11 @@
}
}
- topo_node_lock(node);
- if ((pv = prop_create(node, pgname, pname, type, flag, err)) == NULL) {
+ if (topo_prop_setprop(node, pgname, nvl, flag, nvl, err) != 0) {
nvlist_free(nvl);
- return (-1); /* unlocked and err set */
+ return (-1); /* err set */
}
-
- pv->tp_val = nvl;
-
- topo_node_unlock(node);
-
+ nvlist_free(nvl);
return (ret);
}
@@ -677,6 +687,14 @@
}
int
+topo_prop_set_double(tnode_t *node, const char *pgname, const char *pname,
+ int flag, double val, int *err)
+{
+ return (topo_prop_set(node, pgname, pname, TOPO_TYPE_DOUBLE, flag,
+ &val, 1, err));
+}
+
+int
topo_prop_set_string(tnode_t *node, const char *pgname, const char *pname,
int flag, const char *val, int *err)
{
@@ -877,10 +895,18 @@
* to allow the method to be registered. This is to handle the case
* where we specify an prop method in an xml map to override the value
* that was set by the enumerator.
+ *
+ * By default, propmethod-backed properties are IMMUTABLE. This is done
+ * to simplify the programming model for modules that implement property
+ * methods as most propmethods tend to only support get operations.
+ * Enumerator modules can override this by calling topo_prop_setflags().
+ * Propmethods that are registered via XML can be set as mutable via
+ * the optional "mutable" attribute, which will result in the xml parser
+ * calling topo_prop_setflags() after registering the propmethod.
*/
if ((pv = propval_get(pgroup_get(node, pgname), pname)) == NULL)
if ((pv = prop_create(node, pgname, pname, ptype,
- TOPO_PROP_MUTABLE, err)) == NULL) {
+ TOPO_PROP_IMMUTABLE, err)) == NULL) {
/* node unlocked */
return (register_methoderror(node, pm, err, 0, *err));
}
@@ -982,6 +1008,35 @@
topo_node_unlock(node);
}
+int
+topo_prop_setmutable(tnode_t *node, const char *pgname, const char *pname,
+ int *err)
+{
+ topo_propval_t *pv = NULL;
+
+ topo_node_lock(node);
+ if ((pv = propval_get(pgroup_get(node, pgname), pname)) == NULL) {
+ topo_node_unlock(node);
+ *err = ETOPO_PROP_NOENT;
+ return (-1);
+ }
+
+ /*
+ * If the property is being inherited then we don't want to allow a
+ * change from IMMUTABLE to MUTABLE.
+ */
+ if (pv->tp_refs > 1) {
+ topo_node_unlock(node);
+ *err = ETOPO_PROP_DEFD;
+ return (-1);
+ }
+ pv->tp_flag = TOPO_PROP_MUTABLE;
+
+ topo_node_unlock(node);
+
+ return (0);
+}
+
static int
inherit_seterror(tnode_t *node, int *errp, int err)
{
--- a/usr/src/lib/fm/topo/libtopo/common/topo_subr.c Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_subr.c Thu Jul 31 17:35:39 2008 -0700
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -351,3 +351,204 @@
pp = topo_hdl_strdup(thp, buf);
return (pp);
}
+
+void
+topo_sensor_type_name(uint32_t type, char *buf, size_t len)
+{
+ topo_name_trans_t *ntp;
+
+ for (ntp = &topo_sensor_type_table[0]; ntp->int_name != NULL; ntp++) {
+ if (ntp->int_value == type) {
+ (void) strlcpy(buf, ntp->int_name, len);
+ return;
+ }
+ }
+
+ (void) snprintf(buf, len, "0x%02x", type);
+}
+
+void
+topo_sensor_units_name(uint8_t type, char *buf, size_t len)
+{
+ topo_name_trans_t *ntp;
+
+ for (ntp = &topo_units_type_table[0]; ntp->int_name != NULL; ntp++) {
+ if (ntp->int_value == type) {
+ (void) strlcpy(buf, ntp->int_name, len);
+ return;
+ }
+ }
+
+ (void) snprintf(buf, len, "0x%02x", type);
+}
+
+void
+topo_led_type_name(uint8_t type, char *buf, size_t len)
+{
+ topo_name_trans_t *ntp;
+
+ for (ntp = &topo_led_type_table[0]; ntp->int_name != NULL; ntp++) {
+ if (ntp->int_value == type) {
+ (void) strlcpy(buf, ntp->int_name, len);
+ return;
+ }
+ }
+
+ (void) snprintf(buf, len, "0x%02x", type);
+}
+
+void
+topo_led_state_name(uint8_t type, char *buf, size_t len)
+{
+ topo_name_trans_t *ntp;
+
+ for (ntp = &topo_led_states_table[0]; ntp->int_name != NULL; ntp++) {
+ if (ntp->int_value == type) {
+ (void) strlcpy(buf, ntp->int_name, len);
+ return;
+ }
+ }
+
+ (void) snprintf(buf, len, "0x%02x", type);
+}
+
+void
+topo_sensor_state_name(uint32_t sensor_type, uint8_t state, char *buf,
+size_t len)
+{
+ topo_name_trans_t *ntp;
+
+ switch (sensor_type) {
+ case TOPO_SENSOR_TYPE_PHYSICAL:
+ ntp = &topo_sensor_states_physical_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_PLATFORM:
+ ntp = &topo_sensor_states_platform_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_PROCESSOR:
+ ntp = &topo_sensor_states_processor_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_POWER_SUPPLY:
+ ntp = &topo_sensor_states_power_supply_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_POWER_UNIT:
+ ntp = &topo_sensor_states_power_unit_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_MEMORY:
+ ntp = &topo_sensor_states_memory_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_BAY:
+ ntp = &topo_sensor_states_bay_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_FIRMWARE:
+ ntp = &topo_sensor_states_firmware_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_EVENT_LOG:
+ ntp = &topo_sensor_states_event_log_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_WATCHDOG1:
+ ntp = &topo_sensor_states_watchdog1_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_SYSTEM:
+ ntp = &topo_sensor_states_system_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_CRITICAL:
+ ntp = &topo_sensor_states_critical_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_BUTTON:
+ ntp = &topo_sensor_states_button_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_CABLE:
+ ntp = &topo_sensor_states_cable_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_BOOT_STATE:
+ ntp = &topo_sensor_states_boot_state_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_BOOT_ERROR:
+ ntp = &topo_sensor_states_boot_error_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_BOOT_OS:
+ ntp = &topo_sensor_states_boot_os_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_OS_SHUTDOWN:
+ ntp = &topo_sensor_states_os_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_SLOT:
+ ntp = &topo_sensor_states_slot_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_ACPI:
+ ntp = &topo_sensor_states_acpi_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_WATCHDOG2:
+ ntp = &topo_sensor_states_watchdog2_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_ALERT:
+ ntp = &topo_sensor_states_alert_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_PRESENCE:
+ ntp = &topo_sensor_states_presence_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_LAN:
+ ntp = &topo_sensor_states_lan_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_HEALTH:
+ ntp = &topo_sensor_states_health_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_BATTERY:
+ ntp = &topo_sensor_states_battery_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_AUDIT:
+ ntp = &topo_sensor_states_audit_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_VERSION:
+ ntp = &topo_sensor_states_version_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_FRU_STATE:
+ ntp = &topo_sensor_states_fru_state_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_THRESHOLD_STATE:
+ ntp = &topo_sensor_states_thresh_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_GENERIC_USAGE:
+ ntp = &topo_sensor_states_generic_usage_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_GENERIC_STATE:
+ ntp = &topo_sensor_states_generic_state_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_GENERIC_PREDFAIL:
+ ntp = &topo_sensor_states_generic_predfail_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_GENERIC_LIMIT:
+ ntp = &topo_sensor_states_generic_limit_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_GENERIC_PERFORMANCE:
+ ntp = &topo_sensor_states_generic_perf_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_SEVERITY:
+ ntp = &topo_sensor_states_severity_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_GENERIC_PRESENCE:
+ ntp = &topo_sensor_states_generic_presence_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_GENERIC_AVAILABILITY:
+ ntp = &topo_sensor_states_generic_avail_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_GENERIC_STATUS:
+ ntp = &topo_sensor_states_generic_status_table[0];
+ break;
+ case TOPO_SENSOR_TYPE_GENERIC_ACPI:
+ ntp = &topo_sensor_states_generic_acpi_pwr_table[0];
+ break;
+ default:
+ (void) snprintf(buf, len, "0x%02x", state);
+ return;
+ }
+ for (; ntp->int_name != NULL; ntp++) {
+ if (ntp->int_value == state) {
+ (void) strlcpy(buf, ntp->int_name, len);
+ return;
+ }
+ }
+
+ (void) snprintf(buf, len, "0x%02x", state);
+}
--- a/usr/src/lib/fm/topo/libtopo/common/topo_subr.h Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_subr.h Thu Jul 31 17:35:39 2008 -0700
@@ -65,6 +65,55 @@
#define TOPO_STABSTR_STANDARD "Standard" /* industry standard */
#define TOPO_STABSTR_UNKNOWN "Unknown" /* stability unknown */
+typedef struct topo_name_trans {
+ uint32_t int_value;
+ const char *int_name;
+} topo_name_trans_t;
+
+extern topo_name_trans_t topo_sensor_type_table[];
+extern topo_name_trans_t topo_units_type_table[];
+extern topo_name_trans_t topo_led_type_table[];
+extern topo_name_trans_t topo_led_states_table[];
+extern topo_name_trans_t topo_sensor_states_physical_table[];
+extern topo_name_trans_t topo_sensor_states_platform_table[];
+extern topo_name_trans_t topo_sensor_states_processor_table[];
+extern topo_name_trans_t topo_sensor_states_power_supply_table[];
+extern topo_name_trans_t topo_sensor_states_power_unit_table[];
+extern topo_name_trans_t topo_sensor_states_memory_table[];
+extern topo_name_trans_t topo_sensor_states_bay_table[];
+extern topo_name_trans_t topo_sensor_states_firmware_table[];
+extern topo_name_trans_t topo_sensor_states_event_log_table[];
+extern topo_name_trans_t topo_sensor_states_watchdog1_table[];
+extern topo_name_trans_t topo_sensor_states_system_table[];
+extern topo_name_trans_t topo_sensor_states_critical_table[];
+extern topo_name_trans_t topo_sensor_states_button_table[];
+extern topo_name_trans_t topo_sensor_states_cable_table[];
+extern topo_name_trans_t topo_sensor_states_boot_state_table[];
+extern topo_name_trans_t topo_sensor_states_boot_error_table[];
+extern topo_name_trans_t topo_sensor_states_boot_os_table[];
+extern topo_name_trans_t topo_sensor_states_os_table[];
+extern topo_name_trans_t topo_sensor_states_slot_table[];
+extern topo_name_trans_t topo_sensor_states_acpi_table[];
+extern topo_name_trans_t topo_sensor_states_watchdog2_table[];
+extern topo_name_trans_t topo_sensor_states_alert_table[];
+extern topo_name_trans_t topo_sensor_states_presence_table[];
+extern topo_name_trans_t topo_sensor_states_lan_table[];
+extern topo_name_trans_t topo_sensor_states_health_table[];
+extern topo_name_trans_t topo_sensor_states_battery_table[];
+extern topo_name_trans_t topo_sensor_states_audit_table[];
+extern topo_name_trans_t topo_sensor_states_version_table[];
+extern topo_name_trans_t topo_sensor_states_fru_state_table[];
+extern topo_name_trans_t topo_sensor_states_thresh_table[];
+extern topo_name_trans_t topo_sensor_states_generic_usage_table[];
+extern topo_name_trans_t topo_sensor_states_generic_state_table[];
+extern topo_name_trans_t topo_sensor_states_generic_predfail_table[];
+extern topo_name_trans_t topo_sensor_states_generic_limit_table[];
+extern topo_name_trans_t topo_sensor_states_generic_perf_table[];
+extern topo_name_trans_t topo_sensor_states_generic_presence_table[];
+extern topo_name_trans_t topo_sensor_states_severity_table[];
+extern topo_name_trans_t topo_sensor_states_generic_avail_table[];
+extern topo_name_trans_t topo_sensor_states_generic_status_table[];
+extern topo_name_trans_t topo_sensor_states_generic_acpi_pwr_table[];
extern int topo_rw_read_held(pthread_rwlock_t *);
extern int topo_rw_write_held(pthread_rwlock_t *);
--- a/usr/src/lib/fm/topo/libtopo/common/topo_xml.c Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_xml.c Thu Jul 31 17:35:39 2008 -0700
@@ -23,7 +23,6 @@
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
#pragma ident "%Z%%M% %I% %E% SMI"
#include <libxml/parser.h>
@@ -50,6 +49,9 @@
tnode_t *);
static tf_edata_t *enum_attributes_process(topo_mod_t *, xmlNodePtr);
static int enum_run(topo_mod_t *, tf_rdata_t *);
+static int fac_enum_run(topo_mod_t *, tnode_t *, const char *);
+static int fac_process(topo_mod_t *, xmlNodePtr, tf_rdata_t *, tnode_t *);
+static int fac_enum_process(topo_mod_t *, xmlNodePtr, tnode_t *);
static int decorate_nodes(topo_mod_t *, tf_rdata_t *, xmlNodePtr, tnode_t *,
tf_pad_t **);
@@ -103,7 +105,8 @@
xmlChar *str;
xmlChar *estr;
- topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "attribute to int\n");
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "xmlattr_to_int(propname=%s)\n",
+ propname);
if ((str = xmlGetProp(n, (xmlChar *)propname)) == NULL)
return (topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR));
*value = strtoull((char *)str, (char **)&estr, 10);
@@ -122,7 +125,8 @@
{
xmlChar *str;
- topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "attribute to int\n");
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "xmlattr_to_fmri(propname=%s)\n",
+ propname);
if ((str = xmlGetProp(xn, (xmlChar *)propname)) == NULL)
return (topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR));
if (topo_mod_str2nvl(mp, (const char *)str, rnvl) < 0) {
@@ -176,7 +180,8 @@
nvlist_t *fmri;
xmlChar *str;
- topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "xlate_common\n");
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "xlate_common (name=%s)\n",
+ name);
switch (ptype) {
case TOPO_TYPE_INT32:
if (xmlattr_to_int(mp, xn, Value, &ui) < 0)
@@ -329,8 +334,8 @@
char *str;
int err, e;
- topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "prop_create(gnm = %s, "
- "pnm = %s)\n", gnm, pnm);
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "prop_create(pgrp = %s, "
+ "prop = %s)\n", gnm, pnm);
switch (ptype) {
case TOPO_TYPE_INT32:
e = nvlist_lookup_int32(pfmri, INV_PVAL, &i32);
@@ -404,7 +409,8 @@
int pn;
int e;
- topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "props_create(gnm = %s)\n", gnm);
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "props_create(pgrp = %s)\n",
+ gnm);
for (pn = 0; pn < nprops; pn++) {
e = nvlist_lookup_string(props[pn], INV_PNAME, &pnm);
if (e != 0) {
@@ -449,7 +455,8 @@
int pg;
int e;
- topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "pgroups_create\n");
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "pgroups_create: %s=%d\n",
+ topo_node_name(ptn), topo_node_instance(ptn));
for (pg = 0; pg < pad->tpad_pgcnt; pg++) {
e = nvlist_lookup_string(pad->tpad_pgs[pg],
INV_PGRP_NAME, &gnm);
@@ -601,14 +608,15 @@
xmlNodePtr cn;
xmlChar *meth_name = NULL, *prop_name = NULL;
xmlChar *arg_name = NULL;
- uint64_t meth_ver;
+ uint64_t meth_ver, is_mutable = 0;
topo_type_t prop_type;
struct propmeth_data meth;
- int ret = 0;
+ int ret = 0, err;
topo_type_t ptype;
tnode_t *tmp;
- topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "pmeth_record\n");
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "pmeth_record: %s=%d "
+ "(pgrp=%s)\n", topo_node_name(tn), topo_node_instance(tn), pg_name);
/*
* Get propmethod attribute values
@@ -624,6 +632,12 @@
ret = topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR);
goto pmr_done;
}
+ /*
+ * The "mutable" attribute is optional. If not specified we default to
+ * false (0)
+ */
+ (void) xmlattr_to_int(mp, xn, Mutable, &is_mutable);
+
if ((prop_name = xmlGetProp(xn, (xmlChar *)Propname)) == NULL) {
topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR,
"propmethod element lacks propname attribute\n");
@@ -702,18 +716,36 @@
*/
if (strcmp(ppgrp_name, Range) == 0) {
for (tmp = tn; tmp != NULL; tmp = topo_child_next(NULL, tmp)) {
- if (strcmp(rname, topo_node_name(tmp)) == 0)
+ if (strcmp(rname, topo_node_name(tmp)) == 0) {
if (register_method(mp, tmp, &meth) != 0) {
ret = topo_mod_seterrno(mp,
ETOPO_PRSR_REGMETH);
goto pmr_done;
}
+ if (is_mutable) {
+ if (topo_prop_setmutable(tmp,
+ meth.pg_name, meth.prop_name, &err)
+ != 0) {
+ ret = topo_mod_seterrno(mp,
+ ETOPO_PRSR_REGMETH);
+ goto pmr_done;
+ }
+ }
+ }
}
} else {
if (register_method(mp, tn, &meth) != 0) {
ret = topo_mod_seterrno(mp, ETOPO_PRSR_REGMETH);
goto pmr_done;
}
+ if (is_mutable) {
+ if (topo_prop_setmutable(tn, meth.pg_name,
+ meth.prop_name, &err) != 0) {
+ ret = topo_mod_seterrno(mp,
+ ETOPO_PRSR_REGMETH);
+ goto pmr_done;
+ }
+ }
}
pmr_done:
@@ -878,8 +910,9 @@
pad_process(topo_mod_t *mp, tf_rdata_t *rd, xmlNodePtr pxn, tnode_t *ptn,
tf_pad_t **rpad)
{
- xmlNodePtr cn, gcn, psn, ecn;
+ xmlNodePtr cn, gcn, psn, ecn, target;
xmlNodePtr def_set = NULL;
+ tnode_t *ct;
tf_pad_t *new = *rpad;
tf_rdata_t tmp_rd;
int pgcnt = 0;
@@ -1008,23 +1041,48 @@
return (-1);
}
- if (joined_set) {
- /*
- * If the property groups are contained within a
- * set then they will be one level lower in
- * the XML tree.
- */
- if (pgroups_record(mp, psn, ptn, rd->rd_name,
- new, (const char *)pxn->name) < 0) {
- tf_pad_free(mp, new);
+ /*
+ * If the property groups are contained within a set
+ * then they will be one level lower in the XML tree.
+ */
+ if (joined_set)
+ target = psn;
+ else
+ target = pxn;
+
+ /*
+ * If there is no "node" element under the "range"
+ * element, then we need to attach the facility node to
+ * each node in this range.
+ *
+ * Otherwise we only attach it to the current node
+ */
+ if (!rd->contains_node_ele) {
+ for (ct = topo_child_first(rd->rd_pn);
+ ct != NULL;
+ ct = topo_child_next(rd->rd_pn, ct)) {
+
+ if (strcmp(topo_node_name(ct),
+ rd->rd_name) != 0)
+ continue;
+
+ if (fac_enum_process(mp, target,
+ ct) < 0)
+ return (-1);
+
+ if (fac_process(mp, target, rd, ct) < 0)
+ return (-1);
+ }
+ } else
+ if (fac_enum_process(mp, target, ptn) < 0)
return (-1);
- }
- } else {
- if (pgroups_record(mp, pxn, ptn, rd->rd_name,
- new, (const char *)pxn->name) < 0) {
- tf_pad_free(mp, new);
+ if (fac_process(mp, target, rd, ptn) < 0)
return (-1);
- }
+
+ if (pgroups_record(mp, target, ptn, rd->rd_name,
+ new, (const char *)pxn->name) < 0) {
+ tf_pad_free(mp, new);
+ return (-1);
}
}
*rpad = new;
@@ -1043,6 +1101,154 @@
static int
+fac_enum_process(topo_mod_t *mp, xmlNodePtr pn, tnode_t *ptn)
+{
+ xmlNodePtr cn;
+ xmlChar *fprov = NULL;
+ int rv = 0;
+
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_XML,
+ "fac_enum_process() called for %s=%d\n", topo_node_name(ptn),
+ topo_node_instance(ptn));
+
+ for (cn = pn->xmlChildrenNode; cn != NULL; cn = cn->next) {
+
+ if (xmlStrcmp(cn->name, (xmlChar *)"fac-enum") != 0)
+ continue;
+
+ if ((fprov = xmlGetProp(cn, (xmlChar *)Provider)) == NULL)
+ goto fenumdone;
+
+ if (xmlStrcmp(fprov, (xmlChar *)"fac_prov_ipmi") != 0) {
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_XML,
+ "Invalid provider specified: %s\n", fprov);
+ goto fenumdone;
+ }
+
+ /*
+ * Invoke enum entry point in fac provider which will cause the
+ * facility enumeration node method to be registered.
+ */
+ if (fac_enum_run(mp, ptn, (const char *)fprov) != 0) {
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR,
+ "fac_enum_process: enum entry point failed!\n");
+ goto fenumdone;
+ }
+ xmlFree(fprov);
+ }
+ return (0);
+fenumdone:
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "fac-enum processing failed\n");
+
+ if (fprov != NULL)
+ xmlFree(fprov);
+
+ return (rv);
+}
+
+
+static int
+fac_process(topo_mod_t *mp, xmlNodePtr pn, tf_rdata_t *rd, tnode_t *ptn)
+{
+ xmlNodePtr cn;
+ xmlChar *fname = NULL, *ftype = NULL, *provider = NULL;
+ tnode_t *ntn = NULL;
+ tf_idata_t *newi;
+ int err;
+ topo_pgroup_info_t pgi;
+
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_XML,
+ "fac_process() called\n");
+
+ for (cn = pn->xmlChildrenNode; cn != NULL; cn = cn->next) {
+
+ if (xmlStrcmp(cn->name, (xmlChar *)Facility) != 0)
+ continue;
+
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_XML,
+ "facility processing\n");
+
+ if ((fname = xmlGetProp(cn, (xmlChar *)Name)) == NULL)
+ goto facdone;
+
+ if ((ftype = xmlGetProp(cn, (xmlChar *)Type)) == NULL)
+ goto facdone;
+
+ if ((provider = xmlGetProp(cn, (xmlChar *)Provider)) == NULL)
+ goto facdone;
+
+ if (xmlStrcmp(ftype, (xmlChar *)Sensor) != 0 &&
+ xmlStrcmp(ftype, (xmlChar *)Indicator) != 0)
+ goto facdone;
+
+ if (xmlStrcmp(provider, (xmlChar *)"fac_prov_ipmi") != 0) {
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "fac_process: "
+ "Invalid provider attr value: %s\n", provider);
+ goto facdone;
+ }
+
+ if ((ntn = topo_node_facbind(mp, ptn, (char *)fname,
+ (char *)ftype)) == NULL)
+ goto facdone;
+
+ pgi.tpi_name = TOPO_PGROUP_FACILITY;
+ pgi.tpi_namestab = TOPO_STABILITY_PRIVATE;
+ pgi.tpi_datastab = TOPO_STABILITY_PRIVATE;
+ pgi.tpi_version = 1;
+ if (topo_pgroup_create(ntn, &pgi, &err) != 0) {
+ if (err != ETOPO_PROP_DEFD) {
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR,
+ "pgroups create failure: %s\n",
+ topo_strerror(err));
+ return (-1);
+ }
+ }
+ /*
+ * Invoke enum entry point in fac_prov_ipmi module, which will
+ * cause the provider methods to be registered on this node
+ */
+ if (fac_enum_run(mp, ntn, (const char *)provider) != 0) {
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "fac_process: "
+ "enum entry point failed for provider %s!\n",
+ provider);
+ goto facdone;
+ }
+
+ if ((newi = tf_idata_new(mp, 0, ntn)) == NULL)
+ goto facdone;
+
+ if (tf_idata_insert(&rd->rd_instances, newi) < 0)
+ goto facdone;
+
+ if (pad_process(mp, rd, cn, ntn, &newi->ti_pad) < 0)
+ goto facdone;
+
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "done with "
+ "facility %s=%s.\n", ftype, fname);
+
+ xmlFree(ftype);
+ xmlFree(fname);
+ xmlFree(provider);
+ }
+
+ return (0);
+
+facdone:
+ topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "facility processing failed\n");
+
+ if (ftype != NULL)
+ xmlFree(ftype);
+ if (fname != NULL)
+ xmlFree(fname);
+ if (provider != NULL)
+ xmlFree(provider);
+ if (ntn != NULL)
+ topo_node_unbind(ntn);
+
+ return (0);
+}
+
+static int
node_process(topo_mod_t *mp, xmlNodePtr nn, tf_rdata_t *rd)
{
xmlChar *str;
@@ -1056,6 +1262,7 @@
topo_dprintf(mp->tm_hdl, TOPO_DBG_XML,
"node_process %s\n", rd->rd_name);
+ rd->contains_node_ele = 1;
if (xmlattr_to_int(mp, nn, Instance, &ui) < 0)
goto nodedone;
inst = (topo_instance_t)ui;
@@ -1098,6 +1305,8 @@
}
if (pad_process(mp, rd, nn, ntn, &newi->ti_pad) < 0)
goto nodedone;
+ if (fac_process(mp, nn, rd, ntn) < 0)
+ goto nodedone;
rv = 0;
nodedone:
topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "done with node %s.\n",
@@ -1191,6 +1400,44 @@
return (e);
}
+static int
+fac_enum_run(topo_mod_t *mp, tnode_t *node, const char *name)
+{
+ topo_hdl_t *thp = mp->tm_hdl;
+ topo_mod_t *fmod;
+ int e = -1;
+
+ topo_dprintf(thp, TOPO_DBG_XML, "fac_enum_run\n");
+ /*
+ * Check if the enumerator module is already loaded.
+ * Module loading is single-threaded at this point so there's
+ * no need to worry about the module going away or bumping the
+ * ref count.
+ */
+ if ((fmod = topo_mod_lookup(thp, name, 0)) == NULL) {
+ if ((fmod = topo_mod_load(mp, name, TOPO_VERSION)) == NULL) {
+ topo_dprintf(thp, TOPO_DBG_ERR,
+ "fac_enum_run: mod_load of %s failed: %s.\n",
+ name, topo_strerror(topo_mod_errno(mp)));
+ (void) topo_hdl_seterrno(thp, topo_mod_errno(mp));
+ return (e);
+ }
+ }
+ /*
+ * We're live, so let's enumerate.
+ */
+ topo_dprintf(thp, TOPO_DBG_XML, "fac enumerate request. (%s)\n", name);
+ e = topo_mod_enumerate(fmod, node, name, name, 0, 0, NULL);
+ topo_dprintf(thp, TOPO_DBG_XML, "back from enumeration. %d\n", e);
+ if (e != 0) {
+ topo_dprintf(thp, TOPO_DBG_ERR,
+ "Facility provider enumeration failed (%s)\n",
+ topo_strerror(topo_mod_errno(mp)));
+ (void) topo_hdl_seterrno(thp, EMOD_PARTIAL_ENUM);
+ return (topo_mod_seterrno(mp, EMOD_PARTIAL_ENUM));
+ }
+ return (e);
+}
int
decorate_nodes(topo_mod_t *mp, tf_rdata_t *rd, xmlNodePtr pxn, tnode_t *ptn,
@@ -1231,9 +1478,10 @@
"process %s range beneath %s\n", rd->rd_name,
topo_node_name(rd->rd_pn));
+ rd->contains_node_ele = 0;
e = topo_node_range_create(mp,
rd->rd_pn, rd->rd_name, rd->rd_min, rd->rd_max);
- if (e != 0 && topo_mod_errno(mp) != ETOPO_NODE_DUP) {
+ if (e != 0 && topo_mod_errno(mp) != EMOD_NODE_DUP) {
topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR,
"Range create failed due to %s.\n",
topo_strerror(topo_mod_errno(mp)));
@@ -1326,6 +1574,10 @@
if (pad_process(mp, rd, rn, ct, &rd->rd_pad)
< 0)
return (-1);
+
+ if (fac_process(mp, rn, rd, ct) < 0)
+ return (-1);
+
ct = topo_child_next(rd->rd_pn, ct);
ccnt++;
}
--- a/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-X4500/Sun-Fire-X4500-hc-topology.xmlgen Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-X4500/Sun-Fire-X4500-hc-topology.xmlgen Thu Jul 31 17:35:39 2008 -0700
@@ -201,6 +201,103 @@
printf OFILE " <range name='bay' min='0' max='%d'>\n",
$sys_supported->{"num_bays"}-1;
+#
+# Statically define locate indicator
+#
+print OFILE " <facility name='locate' type='indicator' ".
+ "provider='fac_prov_ipmi' >\n";
+print OFILE " <propgroup name='facility' version='1' ".
+ "name-stability='Private' data-stability='Private' >\n";
+print OFILE " <propval name='type' type='uint32' value='1' />\n";
+print OFILE " <propmethod name='ipmi_entity' version='0' ".
+ "propname='entity_ref' proptype='string' >\n";
+print OFILE " <argval name='format' type='string' ".
+ "value='hdd%d.ok2rm.led' />\n";
+print OFILE " <argval name='offset' type='uint32' ".
+ "value='0' />\n";
+print OFILE " <argval name='nparams' type='uint32' ".
+ "value='1' />\n";
+print OFILE " </propmethod>\n";
+print OFILE " <propmethod name='thumper_locate_mode' ".
+ "version='0'\n";
+print OFILE " propname='mode' proptype='uint32' ".
+ "mutable='1' >\n";
+print OFILE " </propmethod>\n";
+print OFILE " </propgroup>\n";
+print OFILE " </facility>\n";
+
+#
+# Statically define ok2rm indicator
+#
+print OFILE " <facility name='ok2rm' type='indicator' ".
+ "provider='fac_prov_ipmi' >\n";
+print OFILE " <propgroup name='facility' version='1' ".
+ "name-stability='Private' data-stability='Private' >\n";
+print OFILE " <propval name='type' type='uint32' value='2' />\n";
+print OFILE " <propmethod name='ipmi_entity' version='0' ".
+ "propname='entity_ref' proptype='string' >\n";
+print OFILE " <argval name='format' type='string' ".
+ "value='hdd%d.state' />\n";
+print OFILE " <argval name='offset' type='uint32' ".
+ "value='0' />\n";
+print OFILE " <argval name='nparams' type='uint32' ".
+ "value='1' />\n";
+print OFILE " </propmethod>\n";
+print OFILE " <propmethod name='thumper_indicator_mode' ".
+ "version='0'\n";
+print OFILE " propname='mode' proptype='uint32' ".
+ "mutable='1' >\n";
+print OFILE " </propmethod>\n";
+print OFILE " </propgroup>\n";
+print OFILE " </facility>\n";
+
+#
+# Statically define service indicator
+#
+print OFILE " <facility name='service' type='indicator' ".
+ "provider='fac_prov_ipmi' >\n";
+print OFILE " <propgroup name='facility' version='1' ".
+ "name-stability='Private' data-stability='Private' >\n";
+print OFILE " <propval name='type' type='uint32' value='0' />\n";
+print OFILE " <propmethod name='ipmi_entity' version='0' ".
+ "propname='entity_ref' proptype='string' >\n";
+print OFILE " <argval name='format' type='string' ".
+ "value='hdd%d.state' />\n";
+print OFILE " <argval name='offset' type='uint32' ".
+ "value='0' />\n";
+print OFILE " <argval name='nparams' type='uint32' ".
+ "value='1' />\n";
+print OFILE " </propmethod>\n";
+print OFILE " <propmethod name='thumper_indicator_mode' ".
+ "version='0' propname='mode' proptype='uint32' mutable='1' >\n";
+print OFILE " </propmethod>\n";
+print OFILE " </propgroup>\n";
+print OFILE " </facility>\n";
+
+
+#
+# Statically define present indicator
+#
+print OFILE " <facility name='present' type='indicator' ".
+ "provider='fac_prov_ipmi' >\n";
+print OFILE " <propgroup name='facility' version='1' ".
+ "name-stability='Private' data-stability='Private' >\n";
+print OFILE " <propval name='type' type='uint32' value='3' />\n";
+print OFILE " <propmethod name='ipmi_entity' version='0' ".
+ "propname='entity_ref' proptype='string' >\n";
+print OFILE " <argval name='format' type='string' ".
+ "value='hdd%d.state' />\n";
+print OFILE " <argval name='offset' type='uint32' ".
+ "value='0' />\n";
+print OFILE " <argval name='nparams' type='uint32' ".
+ "value='1' />\n";
+print OFILE " </propmethod>\n";
+print OFILE " <propmethod name='thumper_indicator_mode' ".
+ "version='0' propname='mode' proptype='uint32' mutable='1' >\n";
+print OFILE " </propmethod>\n";
+print OFILE " </propgroup>\n";
+print OFILE " </facility>\n";
+
calc_nodes(0);
printf OFILE " <dependents grouping='children'>\n";
--- a/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-X4540/Sun-Fire-X4540-hc-topology.xmlgen Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-X4540/Sun-Fire-X4540-hc-topology.xmlgen Thu Jul 31 17:35:39 2008 -0700
@@ -200,6 +200,102 @@
printf OFILE " <range name='bay' min='0' max='%d'>\n",
$sys_supported->{"num_bays"}-1;
+#
+# Statically define locate indicator
+#
+print OFILE " <facility name='locate' type='indicator' ".
+ "provider='fac_prov_ipmi' >\n";
+print OFILE " <propgroup name='facility' version='1' ".
+ "name-stability='Private' data-stability='Private' >\n";
+print OFILE " <propval name='type' type='uint32' value='1' />\n";
+print OFILE " <propmethod name='ipmi_entity' version='0' ".
+ "propname='entity_ref' proptype='string' >\n";
+print OFILE " <argval name='format' type='string' ".
+ "value='hdd%d.ok2rm.led' />\n";
+print OFILE " <argval name='offset' type='uint32' ".
+ "value='0' />\n";
+print OFILE " <argval name='nparams' type='uint32' ".
+ "value='1' />\n";
+print OFILE " </propmethod>\n";
+print OFILE " <propmethod name='thumper_locate_mode' ".
+ "version='0'\n";
+print OFILE " propname='mode' proptype='uint32' ".
+ "mutable='1' >\n";
+print OFILE " </propmethod>\n";
+print OFILE " </propgroup>\n";
+print OFILE " </facility>\n";
+
+#
+# Statically define ok2rm indicator
+#
+print OFILE " <facility name='ok2rm' type='indicator' ".
+ "provider='fac_prov_ipmi' >\n";
+print OFILE " <propgroup name='facility' version='1' ".
+ "name-stability='Private' data-stability='Private' >\n";
+print OFILE " <propval name='type' type='uint32' value='2' />\n";
+print OFILE " <propmethod name='ipmi_entity' version='0' ".
+ "propname='entity_ref' proptype='string' >\n";
+print OFILE " <argval name='format' type='string' ".
+ "value='hdd%d.state' />\n";
+print OFILE " <argval name='offset' type='uint32' ".
+ "value='0' />\n";
+print OFILE " <argval name='nparams' type='uint32' ".
+ "value='1' />\n";
+print OFILE " </propmethod>\n";
+print OFILE " <propmethod name='thumper_indicator_mode' ".
+ "version='0'\n";
+print OFILE " propname='mode' proptype='uint32' ".
+ "mutable='1' >\n";
+print OFILE " </propmethod>\n";
+print OFILE " </propgroup>\n";
+print OFILE " </facility>\n";
+
+#
+# Statically define service indicator
+#
+print OFILE " <facility name='service' type='indicator' ".
+ "provider='fac_prov_ipmi' >\n";
+print OFILE " <propgroup name='facility' version='1' ".
+ "name-stability='Private' data-stability='Private' >\n";
+print OFILE " <propval name='type' type='uint32' value='0' />\n";
+print OFILE " <propmethod name='ipmi_entity' version='0' ".
+ "propname='entity_ref' proptype='string' >\n";
+print OFILE " <argval name='format' type='string' ".
+ "value='hdd%d.state' />\n";
+print OFILE " <argval name='offset' type='uint32' ".
+ "value='0' />\n";
+print OFILE " <argval name='nparams' type='uint32' ".
+ "value='1' />\n";
+print OFILE " </propmethod>\n";
+print OFILE " <propmethod name='thumper_indicator_mode' ".
+ "version='0' propname='mode' proptype='uint32' mutable='1' >\n";
+print OFILE " </propmethod>\n";
+print OFILE " </propgroup>\n";
+print OFILE " </facility>\n";
+
+#
+# Statically define present indicator
+#
+print OFILE " <facility name='present' type='indicator' ".
+ "provider='fac_prov_ipmi' >\n";
+print OFILE " <propgroup name='facility' version='1' ".
+ "name-stability='Private' data-stability='Private' >\n";
+print OFILE " <propval name='type' type='uint32' value='3' />\n";
+print OFILE " <propmethod name='ipmi_entity' version='0' ".
+ "propname='entity_ref' proptype='string' >\n";
+print OFILE " <argval name='format' type='string' ".
+ "value='hdd%d.state' />\n";
+print OFILE " <argval name='offset' type='uint32' ".
+ "value='0' />\n";
+print OFILE " <argval name='nparams' type='uint32' ".
+ "value='1' />\n";
+print OFILE " </propmethod>\n";
+print OFILE " <propmethod name='thumper_indicator_mode' ".
+ "version='0' propname='mode' proptype='uint32' mutable='1' >\n";
+print OFILE " </propmethod>\n";
+print OFILE " </propgroup>\n";
+print OFILE " </facility>\n";
+
calc_nodes(0);
printf OFILE " <dependents grouping='children'>\n";
--- a/usr/src/lib/fm/topo/maps/common/topology.dtd.1 Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/maps/common/topology.dtd.1 Thu Jul 31 17:35:39 2008 -0700
@@ -125,7 +125,7 @@
-->
<!ELEMENT set
- ( range*, propgroup* ) >
+ ( range*, fac-enum?, propgroup*, facility* ) >
<!ATTLIST set
type ( product ) #REQUIRED
@@ -177,6 +177,7 @@
version Version of the method API
propname Name of the property to create
proptype Type of the property to create
+ mutable optional: default is false (0)
-->
<!ELEMENT propmethod
@@ -186,7 +187,8 @@
name CDATA #REQUIRED
version CDATA #REQUIRED
propname CDATA #REQUIRED
- proptype CDATA #REQUIRED>
+ proptype CDATA #REQUIRED
+ mutable (0|1) "0" >
<!--
enum-method
@@ -221,7 +223,7 @@
-->
<!ELEMENT node
- ( propgroup*, dependents*, set*, enum-method* ) >
+ ( fac-enum?, facility*, propgroup*, set*, enum-method*, dependents? ) >
<!ATTLIST node
instance CDATA #REQUIRED >
@@ -259,7 +261,8 @@
-->
<!ELEMENT range
- ( enum-method?, propmap?, node*, propgroup*, set*, dependents* ) >
+ ( enum-method?, propmap?, fac-enum?, facility*, node*, propgroup*, set*,
+ dependents* ) >
<!ATTLIST range
name CDATA #REQUIRED
@@ -267,6 +270,47 @@
max CDATA #REQUIRED >
<!--
+ facility
+
+ This element identifies a single facility node instance
+
+ Its attributes are
+
+ name The name of the facility node
+
+ type The type of facility node: either "sensor" or "indicator"
+
+ provider The name of the facility provider module that
+ implements the methods for this node or range
+-->
+
+<!ELEMENT facility
+ ( propgroup* ) >
+
+<!ATTLIST facility
+ name CDATA #REQUIRED
+ type (sensor | indicator) #REQUIRED
+ provider CDATA #REQUIRED >
+
+<!--
+ fac-enum
+
+ This element identifies a facility provider module that
+ implements a facility enumeration method for the enclosing
+ node or range.
+
+ Its attributes are
+
+ provider The name of the facility provider module that
+ implements the facility enumerator method for
+ the parent node or range
+-->
+
+<!ELEMENT fac-enum EMPTY >
+
+<!ATTLIST fac-enum provider CDATA #REQUIRED >
+
+<!--
topology
This is the root-level for the scheme-specific topology
--- a/usr/src/lib/fm/topo/maps/i86pc/chip-hc-topology.xml Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/maps/i86pc/chip-hc-topology.xml Thu Jul 31 17:35:39 2008 -0700
@@ -31,7 +31,7 @@
<range name='chip' min='0' max='100'>
<set type='product'
- setlist='Sun-Fire-V20z|Sun-Fire-V40z|W1100z-2100z|Sun-Ultra-20-Workstation|Ultra20-M2|Sun-Ultra-40-M2-Workstation'>
+ setlist='Sun-Fire(TM)-X2100|W1100z-2100z|Sun-Ultra-20-Workstation|Ultra20-M2|Sun-Ultra-40-M2-Workstation'>
<propgroup name='protocol' version='1'
name-stability='Private' data-stability='Private' >
@@ -48,7 +48,7 @@
</set>
<set type='product'
- setlist='Sun-Fire(TM)-X2100|Sun-Fire-X4100-Server|Sun-Fire-X4200-Server|Sun-Fire-X4200E|Sun-Fire-X4500|X2100-M2|Sun-Fire-X4140|Sun-Fire-X4240|Sun-Fire-X4440'>
+ setlist='Sun-Fire-V20z|Sun-Fire-V40z'>
<propgroup name='protocol' version='1'
name-stability='Private' data-stability='Private' >
@@ -62,14 +62,191 @@
</propmethod>
</propgroup>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propmethod name='ipmi_entity' version='0'
+ propname='entity_ref' proptype='string' >
+
+ <argval name='format' type='string' value='cpu%d.vpd' />
+ <argval name='offset' type='uint32' value='0' />
+ <argval name='nparams' type='uint32' value='1' />
+ </propmethod>
+ </propgroup>
+
+ </set>
+ <set type='product'
+ setlist='X2100-M2|Sun-Blade-X8440-Server-Module'>
+ <propgroup name='protocol' version='1'
+ name-stability='Private' data-stability='Private' >
+
+ <propmethod name='simple_chip_label' version='0'
+ propname='label' proptype='string' >
+
+ <argval name='format' type='string' value='CPU %d' />
+ <argval name='offset' type='uint32' value='0' />
+
+ </propmethod>
+
+ </propgroup>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propmethod name='ipmi_entity' version='0'
+ propname='entity_ref' proptype='string' >
+
+ <argval name='format' type='string' value='p%d.fru' />
+ <argval name='offset' type='uint32' value='0' />
+ <argval name='nparams' type='uint32' value='1' />
+
+ </propmethod>
+ </propgroup>
+ </set>
+
+ <set type='product'
+ setlist='Sun-Fire-X4100-Server|Sun-Fire-X4200-Server|Sun-Fire-X4200E|Sun-Fire-X4140|Sun-Fire-X4240|Sun-Fire-X4440'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <!--
+ chip FRU label
+ -->
+ <propgroup name='protocol' version='1'
+ name-stability='Private' data-stability='Private' >
+
+ <propmethod name='simple_chip_label' version='0'
+ propname='label' proptype='string' >
+
+ <argval name='format' type='string' value='CPU %d' />
+ <argval name='offset' type='uint32' value='0' />
+
+ </propmethod>
+
+ </propgroup>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propmethod name='ipmi_entity' version='0'
+ propname='entity_ref' proptype='string' >
+
+ <argval name='format' type='string' value='p%d.fru' />
+ <argval name='offset' type='uint32' value='0' />
+ <argval name='nparams' type='uint32' value='1' />
+
+ </propmethod>
+ </propgroup>
+ <!--
+ chip service LED
+ -->
+ <facility name='service' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='ipmi_entity' version='0' propname='entity_ref' proptype='string' >
+ <argval name='format' type='string' value='p%d.led' />
+ <argval name='offset' type='uint32' value='0' />
+ <argval name='nparams' type='uint32' value='1' />
+ </propmethod>
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1'>
+ </propmethod>
+ </propgroup>
+ </facility>
+ </set>
+ <set type='product' setlist='Sun-Fire-X4500'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <!--
+ chip FRU label
+ -->
+ <propgroup name='protocol' version='1'
+ name-stability='Private' data-stability='Private' >
+
+ <propmethod name='simple_chip_label' version='0'
+ propname='label' proptype='string' >
+
+ <argval name='format' type='string' value='CPU %d' />
+ <argval name='offset' type='uint32' value='0' />
+
+ </propmethod>
+
+ </propgroup>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propmethod name='ipmi_entity' version='0'
+ propname='entity_ref' proptype='string' >
+
+ <argval name='format' type='string' value='p%d.fru' />
+ <argval name='offset' type='uint32' value='0' />
+ <argval name='nparams' type='uint32' value='1' />
+
+ </propmethod>
+ </propgroup>
+ <!--
+ chip service LED
+ -->
+ <facility name='service' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='ipmi_entity' version='0' propname='entity_ref' proptype='string' >
+ <argval name='format' type='string' value='p%d.fail.led' />
+ <argval name='offset' type='uint32' value='0' />
+ <argval name='nparams' type='uint32' value='1' />
+ </propmethod>
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ </set>
+
+ <set type='product' setlist='Sun-Fire-X4540'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <!--
+ chip FRU label
+ -->
+ <propgroup name='protocol' version='1'
+ name-stability='Private' data-stability='Private' >
+
+ <propmethod name='simple_chip_label' version='0'
+ propname='label' proptype='string' >
+
+ <argval name='format' type='string' value='CPU %d' />
+ <argval name='offset' type='uint32' value='0' />
+
+ </propmethod>
+
+ </propgroup>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propmethod name='ipmi_entity' version='0'
+ propname='entity_ref' proptype='string' >
+
+ <argval name='format' type='string' value='p%d.fru' />
+ <argval name='offset' type='uint32' value='0' />
+ <argval name='nparams' type='uint32' value='1' />
+
+ </propmethod>
+ </propgroup>
+ <!--
+ chip service LED
+ -->
+ <facility name='service' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='ipmi_entity' version='0' propname='entity_ref' proptype='string' >
+ <argval name='format' type='string' value='p%d.led' />
+ <argval name='offset' type='uint32' value='0' />
+ <argval name='nparams' type='uint32' value='1' />
+ </propmethod>
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
</set>
<set type='product'
setlist='Sun-Fire-X4100-M2|Sun-Fire-X4200-M2'>
-
+ <fac-enum provider='fac_prov_ipmi' />
+ <!--
+ chip FRU label
+ -->
<propgroup name='protocol' version='1'
name-stability='Private' data-stability='Private' >
-
<propmethod name='simple_chip_label' version='0'
propname='label' proptype='string' >
@@ -79,11 +256,41 @@
</propmethod>
</propgroup>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propmethod name='ipmi_entity' version='0'
+ propname='entity_ref' proptype='string' >
+
+ <argval name='format' type='string' value='p%d.fru' />
+ <argval name='offset' type='uint32' value='0' />
+ <argval name='nparams' type='uint32' value='1' />
+ </propmethod>
+ </propgroup>
+ <!--
+ chip service LED
+ -->
+ <facility name='service' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='ipmi_entity' version='0' propname='entity_ref' proptype='string' >
+ <argval name='format' type='string' value='p%d.led' />
+ <argval name='offset' type='uint32' value='0' />
+ <argval name='nparams' type='uint32' value='1' />
+ </propmethod>
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
</set>
<set type='product'
setlist='Sun-Fire-X4600|Sun-Fire-X4600-M2'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <!--
+ chip FRU label
+ -->
<propgroup name='protocol' version='1'
name-stability='Private' data-stability='Private' >
@@ -95,7 +302,34 @@
</propmethod>
</propgroup>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propmethod name='ipmi_entity' version='0'
+ propname='entity_ref' proptype='string' >
+
+ <argval name='format' type='string' value='p%d.fru' />
+ <argval name='offset' type='uint32' value='0' />
+ <argval name='nparams' type='uint32' value='1' />
+ </propmethod>
+ </propgroup>
+ <!--
+ chip service LED
+ -->
+ <facility name='service' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='ipmi_entity' version='0' propname='entity_ref' proptype='string' >
+ <argval name='format' type='string' value='p%d.led' />
+ <argval name='offset' type='uint32' value='0' />
+ <argval name='nparams' type='uint32' value='1' />
+ </propmethod>
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+
</set>
<set type='product'
setlist='Sun-Blade-X8420-Server-Module|Sun-Blade-X8440-Server-Module|SUN-BLADE-X8440-SERVER-MODULE'>
@@ -212,8 +446,62 @@
</propgroup>
</set>
- <set type='product' setlist='Sun-Fire-X4100-Server|Sun-Fire-X4200-Server|Sun-Fire-X4200E|Sun-Fire-X4500'>
+ <set type='product' setlist='Sun-Fire-X4100-Server|Sun-Fire-X4200-Server|Sun-Fire-X4200E'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='protocol' version='1'
+ name-stability='Private'
+ data-stability='Private' >
+
+ <propmethod name='simple_dimm_label_mp' version='0'
+ propname='label' proptype='string' >
+
+ <argval name='format' type='string'
+ value='CPU %d DIMM %d' />
+ <argval name='offset' type='uint32' value='0' />
+ <argval name='order' type='string'
+ value='forward' />
+ <argval name='dimms_per_chip' type='uint32'
+ value='4' />
+
+ </propmethod>
+ <propmethod name='get_dimm_serial' version='0'
+ propname='serial' proptype='string' >
+
+ <argval name='format' type='string'
+ value='p%d.d%d.fru' />
+ <argval name='offset' type='uint32' value='0' />
+
+ </propmethod>
+ </propgroup>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+
+ <propmethod name='dimm_ipmi_entity' version='0'
+ propname='entity_ref' proptype='string' >
+
+ <argval name='format' type='string'
+ value='p%d.d%d.fru' />
+ <argval name='offset' type='uint32' value='0' />
+
+ </propmethod>
+ </propgroup>
+ <facility name='service' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='dimm_ipmi_entity' version='0' propname='entity_ref' proptype='string' >
+ <argval name='format' type='string' value='p%d.d%d.led' />
+ <argval name='offset' type='uint32' value='0' />
+ </propmethod>
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ </set>
+ <set type='product' setlist='Sun-Fire-X4500'>
+
+ <fac-enum provider='fac_prov_ipmi' />
<propgroup name='protocol' version='1'
name-stability='Private'
data-stability='Private' >
@@ -238,12 +526,35 @@
<argval name='offset' type='uint32' value='0' />
</propmethod>
+ </propgroup>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+
+ <propmethod name='dimm_ipmi_entity' version='0'
+ propname='entity_ref' proptype='string' >
+
+ <argval name='format' type='string'
+ value='p%d.d%d.fru' />
+ <argval name='offset' type='uint32' value='0' />
+ </propmethod>
</propgroup>
-
+ <facility name='service' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='dimm_ipmi_entity' version='0' propname='entity_ref' proptype='string' >
+ <argval name='format' type='string' value='p%d.d%d.fail.led' />
+ <argval name='offset' type='uint32' value='0' />
+ </propmethod>
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
</set>
<set type='product' setlist='Sun-Fire-X4100-M2|Sun-Fire-X4200-M2'>
+ <fac-enum provider='fac_prov_ipmi' />
<propgroup name='protocol' version='1'
name-stability='Private'
data-stability='Private' >
@@ -265,10 +576,37 @@
</propmethod>
</propgroup>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+
+ <propmethod name='dimm_ipmi_entity' version='0'
+ propname='entity_ref' proptype='string' >
+
+ <argval name='format' type='string'
+ value='p%d.d%d.fru' />
+ <argval name='offset' type='uint32' value='0' />
+ </propmethod>
+ </propgroup>
+ <!--
+ DIMM service LED
+ -->
+ <facility name='service' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='dimm_ipmi_entity' version='0' propname='entity_ref' proptype='string' >
+ <argval name='format' type='string' value='p%d.d%d.led' />
+ <argval name='offset' type='uint32' value='0' />
+ </propmethod>
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
</set>
<set type='product' setlist='Sun-Fire-X4600|Sun-Fire-X4600-M2'>
+ <fac-enum provider='fac_prov_ipmi' />
<propgroup name='protocol' version='1'
name-stability='Private'
data-stability='Private' >
@@ -291,6 +629,33 @@
</propmethod>
</propgroup>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+
+ <propmethod name='dimm_ipmi_entity' version='0'
+ propname='entity_ref' proptype='string' >
+
+ <argval name='format' type='string'
+ value='p%d.d%d.fru' />
+ <argval name='offset' type='uint32' value='0' />
+
+ </propmethod>
+ </propgroup>
+ <!--
+ DIMM service LED
+ -->
+ <facility name='service' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='dimm_ipmi_entity' version='0' propname='entity_ref' proptype='string' >
+ <argval name='format' type='string' value='p%d.d%d.led' />
+ <argval name='offset' type='uint32' value='0' />
+ </propmethod>
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
</set>
<set type='product'
--- a/usr/src/lib/fm/topo/maps/i86pc/fan-hc-topology.xmlgen Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/maps/i86pc/fan-hc-topology.xmlgen Thu Jul 31 17:35:39 2008 -0700
@@ -54,9 +54,13 @@
count => 2,
fru => "self"
}, {
+ fac_enum => 1,
+ provider => "fac_prov_ipmi",
count => 3,
label => "FT %d FM %d",
entity_ref => "ft%d.fm%d.led",
+ entity_ref_nparams => 2,
+ fm_service_indctr => "ft%d.fm%d.led",
fru => "self"
}
]
@@ -72,12 +76,21 @@
set => "Sun-Fire-X4500|Sun-Fire-X4540",
topology => [
{
+ fac_enum => 0,
+ provider => "fac_prov_ipmi",
label => "FT %d",
count => 5,
fru => "self",
entity_ref => "ft%d.prsnt",
+ entity_ref_nparams => 1,
+ fm_service_indctr => "ft%d.service.led",
+ fm_ok2rm_indctr => "ft%d.ok2rm.led",
}, {
+ fac_enum => 1,
+ provider => "fac_prov_ipmi",
count => 2,
+ entity_ref => "ft%d.f%d.speed",
+ entity_ref_nparams => 2,
fru => "parent"
}
]
@@ -86,8 +99,10 @@
#
# Fan Module/Fan topology for all G1N/G2N platforms.
#
- # These systems have 6 fan modules, with each fan module containing 2 fans.
- # The FRU's for the individual fans are the containing fan module.
+ # There are two fan boards, which are FRU's. Each fan board has
+ # 3 fan modules for a total of 6 fan modules, with each fan module
+ # containing 2 fans. The FRU's for the individual fans are the
+ # containing fan module.
#
# Unfortunately, the IPMI topology on these systems is rather broken, and
# all the SDRs that should be separate entities in fact refer to the same
@@ -99,19 +114,47 @@
topology => [
{
count => 2,
- label => "FT %d",
+ label => "FANBD%d",
fru => "self"
}, {
- label => "FT %d FM %d",
+ fac_enum => 1,
+ provider => "fac_prov_ipmi",
+ label => "FANBD%d FM%d",
count => 3,
fru => "self",
entity_present => "fb%d.fm%d.prsnt",
+ entity_ref => "fb%d.fm%d.prsnt",
+ entity_ref_nparams => 2,
+ fm_service_indctr_ => "fb%d.fm%d.led",
}, {
count => 2,
fru => "parent"
}
]
+ },
+
+ #
+ # Fan Module/Fan topology for G4F platforms.
+ #
+ # These systems have 4 fan assemblies with a single fan per assembly.
+ # Each fan assembly is a FRU. The fan assemblies have a service LED
+ # but no other indicators.
+ #
+ {
+ set => "Sun-Fire-X4600-M2",
+ topology => [
+ {
+ fac_enum => 1,
+ provider => "fac_prov_ipmi",
+ count => 4,
+ label => "FT %d",
+ fru => "self",
+ entity_ref => "ft%d.fm0.prsnt",
+ entity_ref_nparams => 1,
+ fm_service_indctr => "ft%d.fm0.led"
+ }
+ ]
}
);
@@ -143,6 +186,69 @@
$indent += 2;
+ # Facility enumerator
+ if ($level->{fac_enum}) {
+ printf(OFILE "%*s<fac-enum provider='",
+ $indent, "");
+ printf(OFILE $level->{provider}, @indices);
+ printf(OFILE "' />\n");
+ }
+
+ # Facility nodes for service and ok2rm LED's
+ if ($level->{fm_service_indctr}) {
+ printf(OFILE "%*s<facility name='service' type='indicator' ".
+ "provider='fac_prov_ipmi' >\n", $indent+2, "");
+ printf(OFILE "%*s<propgroup name='facility' version='1' ".
+ "name-stability='Private' data-stability='Private' >\n",
+ $indent+4, "");
+ printf(OFILE "%*s<propval name='type' type='uint32' ".
+ "value='1' />\n", $indent+6, "");
+ printf(OFILE "%*s<propmethod name='ipmi_entity' version='0' ".
+ "propname='entity_ref' proptype='string' >\n",
+ $indent+6, "");
+ printf(OFILE "%*s<argval name='format' type='string' ".
+ "value='%s' />\n", $indent+8, "",
+ $level->{fm_service_indctr});
+ printf(OFILE "%*s<argval name='offset' type='uint32' ".
+ "value='0' />\n", $indent+8, "");
+ printf(OFILE "%*s<argval name='nparams' type='uint32' ".
+ "value='%d' />\n", $indent+8, "",
+ $level->{entity_ref_nparams});
+ printf(OFILE "%*s</propmethod>\n", $indent+6, "");
+ printf(OFILE "%*s<propmethod name='ipmi_indicator_mode' ".
+ "version='0' propname='mode' proptype='uint32' ".
+ "mutable='1' >\n", $indent+6, "");
+ printf(OFILE "%*s</propmethod>\n", $indent+6, "");
+ printf(OFILE "%*s</propgroup>\n", $indent+4, "");
+ printf(OFILE "%*s</facility>\n", $indent+2, "");
+ }
+ if ($level->{fm_ok2rm_indctr}) {
+ printf(OFILE "%*s<facility name='ok2rm' type='indicator' ".
+ "provider='fac_prov_ipmi' >\n", $indent+2, "");
+ printf(OFILE "%*s<propgroup name='facility' version='1' ".
+ "name-stability='Private' data-stability='Private' >\n",
+ $indent+4, "");
+ printf(OFILE "%*s<propval name='type' type='uint32' ".
+ "value='2' />\n", $indent+6, "");
+ printf(OFILE "%*s<propmethod name='ipmi_entity' version='0' ".
+ "propname='entity_ref' proptype='string' >\n",
+ $indent+6, "");
+ printf(OFILE "%*s<argval name='format' type='string' ".
+ "value='%s' />\n", $indent+8, "",
+ $level->{fm_ok2rm_indctr});
+ printf(OFILE "%*s<argval name='offset' type='uint32' ".
+ "value='0' />\n", $indent+8, "");
+ printf(OFILE "%*s<argval name='nparams' type='uint32' ".
+ "value='%d' />\n", $indent+8, "",
+ $level->{entity_ref_nparams});
+ printf(OFILE "%*s</propmethod>\n", $indent+6, "");
+ printf(OFILE "%*s<propmethod name='ipmi_indicator_mode' ".
+ "version='0' propname='mode' proptype='uint32' mutable='1' >\n",
+ $indent+6, "");
+ printf(OFILE "%*s</propmethod>\n", $indent+6, "");
+ printf(OFILE "%*s</propgroup>\n", $indent+4, "");
+ printf(OFILE "%*s</facility>\n", $indent+2, "");
+ }
# Protocol properties (label, fmri)
printf(OFILE "%*s<propgroup name='protocol' version='1' " .
"name-stability='Private' data-stability='Private'>\n",
@@ -169,7 +275,7 @@
printf(OFILE "%*s</propgroup>\n", $indent, "");
#
- # Entity reference (if any)
+ # Entity references (if any)
#
if ($level->{entity_ref} || $level->{entity_present}) {
my $name = $level->{entity_ref} ? "entity_ref" :
@@ -185,6 +291,13 @@
printf(OFILE "%*s</propgroup>\n", $indent, "");
}
+ #
+ # Post-process IPMI enumerator method
+ #
+ if ($level->{provider}) {
+ printf(OFILE "%*s<enum-method name='ipmi' version='1' ".
+ "/>\n", $indent, "");
+ }
#
# Children (if any)
@@ -196,12 +309,6 @@
printf(OFILE "%*s</dependents>\n", $indent, "");
}
- #
- # Post-process IPMI enumerator method
- #
- printf(OFILE "%*s<enum-method name='ipmi' version='1' />\n",
- $indent, "");
-
$indent -= 2;
printf(OFILE "%*s</node>\n", $indent, "");
--- a/usr/src/lib/fm/topo/maps/i86pc/i86pc-hc-topology.xml Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/maps/i86pc/i86pc-hc-topology.xml Thu Jul 31 17:35:39 2008 -0700
@@ -30,10 +30,24 @@
<range name='motherboard' min='0' max='0'>
<node instance='0'>
- <propgroup name='protocol' version='1'
- name-stability='Private' data-stability='Private' >
- <propval name='label' type='string' value='MB' />
- </propgroup>
+ <set type='product' setlist='Sun-Fire-X4100-Server|Sun-Fire-X4200-Server|Sun-Fire-X4100-M2|Sun-Fire-X4200-M2|Sun-Fire-X4240|Sun-Fire-X4440|Sun-Fire-X4500|Sun-Fire-X4540|Sun-Fire-X4600-M2'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='protocol' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='label' type='string' value='MB' />
+ </propgroup>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='mb.fru' />
+ </propgroup>
+
+ </set>
+ <set type='product' setlist='default'>
+ <propgroup name='protocol' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='label' type='string' value='MB' />
+ </propgroup>
+ </set>
</node>
<dependents grouping='children'>
@@ -50,8 +64,152 @@
<range name='chassis' min='0' max='0'>
<node instance='0'>
+ <set type='product' setlist='Sun-Fire-X4240|Sun-Fire-X4440'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='sys.intsw' />
+ </propgroup>
+ </set>
+ <set type='product' setlist='Sun-Fire-X4100-Server|Sun-Fire-X4200-Server|Sun-Fire-X4100-M2|Sun-Fire-X4200-M2'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='sys.intsw' />
+ </propgroup>
+ <!--
+ chassis locate and service LED's for Galaxy 1/2
+ -->
+ <facility name='fp.locate.led' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='fp.locate.led' />
+ <propval name='type' type='uint32' value='1' />
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ <facility name='bp.locate.led' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='bp.locate.led' />
+ <propval name='type' type='uint32' value='1' />
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ <facility name='fp.alert.led' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='fp.alert.led' />
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ <facility name='bp.alert.led' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='bp.alert.led' />
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ </set>
+ <set type='product' setlist='Sun-Fire-X4500|Sun-Fire-X4540'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='sys.intsw' />
+ </propgroup>
+ <!--
+ chassis locate and service LED's for X4500/X4540
+ -->
+ <facility name='fp.locate.led' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='fp.locate.led' />
+ <propval name='type' type='uint32' value='1' />
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ <facility name='bp.locate.led' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='bp.locate.led' />
+ <propval name='type' type='uint32' value='1' />
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ <facility name='fp.alert.led' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='fp.alert.led' />
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ <facility name='bp.alert.led' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='bp.alert.led' />
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ <facility name='sys.top_svc.led' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='sys.top_svc.led' />
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ <facility name='sys.rear_svc.led' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='sys.rear_svc.led' />
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ </set>
+ <set type='product' setlist='Sun-Fire-X4600-M2'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='sys.intsw' />
+ </propgroup>
+ <!--
+ chassis locate and service LED's for X4600M2
+ -->
+ <facility name='sys.locate.led' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='sys.locate.led' />
+ <propval name='type' type='uint32' value='1' />
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ <facility name='sys.alert.led' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='sys.alert.led' />
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
+ </set>
</node>
-
<dependents grouping='children'>
<set type='product' setlist='Sun-Fire-X4100-Server|Sun-Fire-X4200-Server|Sun-Fire-X4100-M2|Sun-Fire-X4200-M2|Sun-Fire-X4240|Sun-Fire-X4440'>
@@ -73,6 +231,16 @@
</range>
</set>
+ <set type='product' setlist='Sun-Fire-X4600-M2'>
+ <range name='psu' min='0' max='100'>
+ <enum-method name='ipmi' version='1' />
+ <propmap name='psu' />
+ </range>
+ <range name='fan' min='0' max='3'>
+ <propmap name='fan' />
+ </range>
+ </set>
+
<set type='product' setlist='default'>
<range name='psu' min='0' max='100'>
<enum-method name='ipmi' version='1' />
--- a/usr/src/lib/fm/topo/maps/i86pc/psu-hc-topology.xml Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/maps/i86pc/psu-hc-topology.xml Thu Jul 31 17:35:39 2008 -0700
@@ -36,6 +36,7 @@
<set type='product' setlist='Sun-Fire-X4500|Sun-Fire-X4540'>
<range name='psu' min='0' max='100'>
<node instance='0'>
+ <fac-enum provider='fac_prov_ipmi' />
<propgroup name='protocol' version='1'
name-stability='Private' data-stability='Private' >
<propval name='label' type='string' value='PS0' />
@@ -52,6 +53,7 @@
<enum-method name='ipmi' version='1' />
</node>
<node instance='1'>
+ <fac-enum provider='fac_prov_ipmi' />
<propgroup name='protocol' version='1'
name-stability='Private' data-stability='Private' >
<propval name='label' type='string' value='PS1' />
@@ -69,8 +71,18 @@
</node>
</range>
</set>
- <set type='product' setlist='Sun-Fire-X4100-Server|Sun-Fire-X4200-Server|Sun-Fire-X4100-M2|Sun-Fire-X4200-M2|Sun-Fire-X4240|Sun-Fire-X4440'>
+ <set type='product' setlist='Sun-Fire-X4100-Server|Sun-Fire-X4200-Server|Sun-Fire-X4100-M2|Sun-Fire-X4200-M2|Sun-Fire-X4240|Sun-Fire-X4440|Sun-Fire-X4600-M2'>
<range name='psu' min='0' max='100'>
+ <fac-enum provider='fac_prov_ipmi' />
+ <facility name='sys.psfail.led' type='indicator' provider='fac_prov_ipmi' >
+ <propgroup name='facility' version='1' name-stability='Private' data-stability='Private' >
+ <propval name='entity_ref' type='string' value='sys.psfail.led' />
+ <propval name='type' type='uint32' value='0' />
+ <propmethod name='ipmi_indicator_mode' version='0'
+ propname='mode' proptype='uint32' mutable='1' >
+ </propmethod>
+ </propgroup>
+ </facility>
<propgroup name='protocol' version='1'
name-stability='Private' data-stability='Private' >
@@ -82,6 +94,18 @@
</propmethod>
</propgroup>
+ <propgroup name='ipmi' version='1'
+ name-stability='Private' data-stability='Private' >
+
+ <propmethod name='ipmi_entity' version='0'
+ propname='entity_ref' proptype='string' >
+
+ <argval name='format' type='string' value='ps%d.prsnt' />
+ <argval name='offset' type='uint32' value='0' />
+ <argval name='nparams' type='uint32' value='1' />
+
+ </propmethod>
+ </propgroup>
</range>
</set>
</topology>
--- a/usr/src/lib/fm/topo/modules/common/Makefile Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/fm/topo/modules/common/Makefile Thu Jul 31 17:35:39 2008 -0700
@@ -27,6 +27,7 @@
SUBDIRS = \
disk \
+ fac_prov_ipmi \
ipmi \
ses \
xfp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/common/fac_prov_ipmi/Makefile Thu Jul 31 17:35:39 2008 -0700
@@ -0,0 +1,34 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+MODULE = fac_prov_ipmi
+CLASS = common
+
+MODULESRCS = fac_prov_ipmi.c
+
+include ../../Makefile.plugin
+
+LDLIBS += -lipmi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/topo/modules/common/fac_prov_ipmi/fac_prov_ipmi.c Thu Jul 31 17:35:39 2008 -0700
@@ -0,0 +1,1095 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <limits.h>
+#include <alloca.h>
+#include <errno.h>
+#include <libnvpair.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/fm/protocol.h>
+#include <fm/libtopo.h>
+#include <fm/topo_mod.h>
+#include <libipmi.h>
+
+#define BUFSZ 128
+#define TOPO_PGROUP_IPMI "ipmi"
+
+#define THUMPER_PRESENT_LED_MASK 0x01
+#define THUMPER_SERVICE_LED_MASK 0x02
+#define THUMPER_OK2RM_LED_MASK 0x08
+
+/*
+ * The largest possible SDR ID length is 2^5+1
+ */
+#define MAX_ID_LEN 33
+
+#define TOPO_METH_IPMI_READING_VERSION 0
+#define TOPO_METH_IPMI_STATE_VERSION 0
+#define TOPO_METH_IPMI_MODE_VERSION 0
+#define TOPO_METH_THUMPER_LOCATE_VERSION 0
+#define TOPO_METH_THUMPER_MODE_VERSION 0
+#define TOPO_METH_IPMI_ENTITY_VERSION 0
+#define TOPO_METH_DIMM_IPMI_ENTITY_VERSION 0
+
+static int fac_prov_ipmi_enum(topo_mod_t *, tnode_t *, const char *,
+ topo_instance_t, topo_instance_t, void *, void *);
+
+/*
+ * IPMI facility provider methods
+ */
+static int ipmi_sensor_enum(topo_mod_t *, tnode_t *, topo_version_t,
+ nvlist_t *, nvlist_t **);
+static int ipmi_entity(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *,
+ nvlist_t **);
+static int dimm_ipmi_entity(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *,
+ nvlist_t **);
+static int ipmi_sensor_reading(topo_mod_t *, tnode_t *, topo_version_t,
+ nvlist_t *, nvlist_t **);
+static int ipmi_sensor_state(topo_mod_t *, tnode_t *, topo_version_t,
+ nvlist_t *, nvlist_t **);
+static int ipmi_indicator_mode(topo_mod_t *, tnode_t *, topo_version_t,
+ nvlist_t *, nvlist_t **);
+static int thumper_locate_mode(topo_mod_t *, tnode_t *, topo_version_t,
+ nvlist_t *, nvlist_t **);
+static int thumper_indicator_mode(topo_mod_t *, tnode_t *, topo_version_t,
+ nvlist_t *, nvlist_t **);
+
+const topo_modops_t ipmi_ops = { fac_prov_ipmi_enum, NULL };
+
+const topo_modinfo_t ipmi_info =
+ { "IPMI facility provider", FM_FMRI_SCHEME_HC, TOPO_VERSION,
+ &ipmi_ops };
+
+static const topo_method_t ipmi_node_methods[] = {
+ { TOPO_METH_FAC_ENUM, TOPO_METH_FAC_ENUM_DESC, 0,
+ TOPO_STABILITY_INTERNAL, ipmi_sensor_enum },
+ { TOPO_METH_IPMI_ENTITY, TOPO_PROP_METH_DESC,
+ TOPO_METH_IPMI_ENTITY_VERSION,
+ TOPO_STABILITY_INTERNAL, ipmi_entity },
+ { "dimm_ipmi_entity", TOPO_PROP_METH_DESC,
+ TOPO_METH_DIMM_IPMI_ENTITY_VERSION,
+ TOPO_STABILITY_INTERNAL, dimm_ipmi_entity },
+ { NULL }
+};
+
+static const topo_method_t ipmi_fac_methods[] = {
+ { "ipmi_sensor_reading", TOPO_PROP_METH_DESC,
+ TOPO_METH_IPMI_READING_VERSION,
+ TOPO_STABILITY_INTERNAL, ipmi_sensor_reading },
+ { "ipmi_sensor_state", TOPO_PROP_METH_DESC,
+ TOPO_METH_IPMI_STATE_VERSION,
+ TOPO_STABILITY_INTERNAL, ipmi_sensor_state },
+ { "ipmi_indicator_mode", TOPO_PROP_METH_DESC,
+ TOPO_METH_IPMI_MODE_VERSION,
+ TOPO_STABILITY_INTERNAL, ipmi_indicator_mode },
+ { "thumper_locate_mode", TOPO_PROP_METH_DESC,
+ TOPO_METH_THUMPER_LOCATE_VERSION,
+ TOPO_STABILITY_INTERNAL, thumper_locate_mode },
+ { "thumper_indicator_mode", TOPO_PROP_METH_DESC,
+ TOPO_METH_THUMPER_MODE_VERSION,
+ TOPO_STABILITY_INTERNAL, thumper_indicator_mode },
+ { TOPO_METH_IPMI_ENTITY, TOPO_PROP_METH_DESC,
+ TOPO_METH_IPMI_ENTITY_VERSION,
+ TOPO_STABILITY_INTERNAL, ipmi_entity },
+ { "dimm_ipmi_entity", TOPO_PROP_METH_DESC,
+ TOPO_METH_DIMM_IPMI_ENTITY_VERSION,
+ TOPO_STABILITY_INTERNAL, dimm_ipmi_entity },
+ { NULL }
+};
+
+struct entity_info {
+ uint32_t ei_id;
+ uint32_t ei_inst;
+ topo_mod_t *ei_mod;
+ tnode_t *ei_node;
+};
+
+struct sensor_data {
+ char sd_entity_ref[MAX_ID_LEN];
+ uint8_t sd_units;
+ uint32_t sd_stype;
+ uint32_t sd_rtype;
+ char *sd_class;
+};
+
+/*ARGSUSED*/
+int
+_topo_init(topo_mod_t *mod, topo_version_t version)
+{
+ if (getenv("TOPOFACIPMIDEBUG") != NULL)
+ topo_mod_setdebug(mod);
+
+ return (topo_mod_register(mod, &ipmi_info, TOPO_VERSION));
+}
+
+void
+_topo_fini(topo_mod_t *mod)
+{
+ topo_mod_unregister(mod);
+}
+
+static char *
+get_fmtstr(topo_mod_t *mod, nvlist_t *in)
+{
+ char *fmtstr;
+ nvlist_t *args;
+
+ if (nvlist_lookup_nvlist(in, TOPO_PROP_ARGS, &args) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup 'args' list (%s)\n",
+ strerror(errno));
+ (void) topo_mod_seterrno(mod, EMOD_NVL_INVAL);
+ return (NULL);
+ }
+ if (nvlist_lookup_string(args, "format", &fmtstr) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup 'format' arg (%s)\n",
+ strerror(errno));
+ (void) topo_mod_seterrno(mod, EMOD_NVL_INVAL);
+ return (NULL);
+ }
+ return (fmtstr);
+}
+
+/*ARGSUSED*/
+static int
+ipmi_sensor_state(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
+ nvlist_t *in, nvlist_t **out)
+{
+ char *entity_ref;
+ ipmi_sdr_t *sdr = NULL;
+ ipmi_sensor_reading_t *reading;
+ ipmi_handle_t *hdl;
+ int err;
+ uint8_t sensor_num;
+ ipmi_sdr_full_sensor_t *fsensor;
+ ipmi_sdr_compact_sensor_t *csensor;
+ nvlist_t *nvl;
+
+ if (vers > TOPO_METH_IPMI_STATE_VERSION)
+ return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
+
+ if (topo_prop_get_string(node, TOPO_PGROUP_FACILITY, "entity_ref",
+ &entity_ref, &err) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup entity_ref property "
+ "(%s)", topo_strerror(err));
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+
+ if ((hdl = topo_mod_ipmi(mod)) == NULL) {
+ topo_mod_dprintf(mod, "Failed to get IPMI handle\n");
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+
+ if ((sdr = ipmi_sdr_lookup(hdl, entity_ref)) == NULL) {
+ topo_mod_dprintf(mod, "Failed to lookup SDR for %s (%s)\n",
+ entity_ref, ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+
+ switch (sdr->is_type) {
+ case IPMI_SDR_TYPE_FULL_SENSOR:
+ fsensor = (ipmi_sdr_full_sensor_t *)sdr->is_record;
+ sensor_num = fsensor->is_fs_number;
+ break;
+ case IPMI_SDR_TYPE_COMPACT_SENSOR:
+ csensor = (ipmi_sdr_compact_sensor_t *)sdr->is_record;
+ sensor_num = csensor->is_cs_number;
+ break;
+ default:
+ topo_mod_dprintf(mod, "%s does not refer to a full or "
+ "compact SDR\n", entity_ref);
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+ if ((reading = ipmi_get_sensor_reading(hdl, sensor_num))
+ == NULL) {
+ topo_mod_dprintf(mod, "Failed to get sensor reading for sensor "
+ "%s, sensor_num=%d (%s)\n", entity_ref, sensor_num,
+ ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+ topo_mod_strfree(mod, entity_ref);
+
+ if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
+ nvlist_add_string(nvl, TOPO_PROP_VAL_NAME,
+ TOPO_SENSOR_STATE) != 0 ||
+ nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 ||
+ nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, reading->isr_state)
+ != 0) {
+ topo_mod_dprintf(mod, "Failed to allocate 'out' nvlist\n");
+ nvlist_free(nvl);
+ return (topo_mod_seterrno(mod, EMOD_NOMEM));
+ }
+ *out = nvl;
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+ipmi_sensor_reading(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
+ nvlist_t *in, nvlist_t **out)
+{
+ char *entity_ref, reading_str[BUFSZ];
+ int err = 0;
+ ipmi_sdr_full_sensor_t *sensor;
+ ipmi_sensor_reading_t *reading;
+ double conv_reading;
+ ipmi_handle_t *hdl;
+ nvlist_t *nvl;
+
+ if (vers > TOPO_METH_IPMI_READING_VERSION)
+ return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
+
+ if (topo_prop_get_string(node, TOPO_PGROUP_FACILITY, "entity_ref",
+ &entity_ref, &err) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup entity_ref property "
+ "(%s)", topo_strerror(err));
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+
+ if ((hdl = topo_mod_ipmi(mod)) == NULL) {
+ topo_mod_dprintf(mod, "Failed to get IPMI handle\n");
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+
+ if ((sensor = ipmi_sdr_lookup_full_sensor(hdl, entity_ref))
+ == NULL) {
+ topo_mod_dprintf(mod, "Failed to lookup SDR for %s (%s)\n",
+ entity_ref, ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+
+ if ((reading = ipmi_get_sensor_reading(hdl, sensor->is_fs_number))
+ == NULL) {
+ topo_mod_dprintf(mod, "Failed to get sensor reading for sensor "
+ "%s, sensor_num=%d (%s)\n", entity_ref,
+ sensor->is_fs_number, ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+ if (ipmi_sdr_conv_reading(sensor, reading->isr_reading, &conv_reading)
+ != 0) {
+ topo_mod_dprintf(mod, "Failed to convert sensor reading for "
+ "sensor %s (%s)\n", entity_ref, ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+ topo_mod_strfree(mod, entity_ref);
+
+ (void) snprintf(reading_str, BUFSZ, "%f", conv_reading);
+ if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
+ nvlist_add_string(nvl, TOPO_PROP_VAL_NAME,
+ TOPO_SENSOR_READING) != 0 ||
+ nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_DOUBLE) != 0 ||
+ nvlist_add_double(nvl, TOPO_PROP_VAL_VAL, conv_reading) != 0) {
+ topo_mod_dprintf(mod, "Failed to allocate 'out' nvlist\n");
+ nvlist_free(nvl);
+ return (topo_mod_seterrno(mod, EMOD_NOMEM));
+ }
+ *out = nvl;
+
+ return (0);
+}
+
+static int
+ipmi_indicator_mode(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
+ nvlist_t *in, nvlist_t **out)
+{
+ char *entity_ref;
+ ipmi_sdr_generic_locator_t *gdl = NULL;
+ ipmi_handle_t *hdl;
+ int err, ret;
+ uint8_t ledmode;
+ uint32_t mode_in;
+ nvlist_t *pargs, *nvl;
+
+ if (vers > TOPO_METH_IPMI_MODE_VERSION)
+ return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
+
+ /*
+ * Get an IPMI handle and then lookup the generic device locator sensor
+ * data record referenced by the entity_ref prop val
+ */
+ if ((hdl = topo_mod_ipmi(mod)) == NULL) {
+ topo_mod_dprintf(mod, "Failed to get IPMI handle\n");
+ return (-1);
+ }
+
+ if (topo_prop_get_string(node, TOPO_PGROUP_FACILITY, "entity_ref",
+ &entity_ref, &err) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup entity_ref property "
+ "(%s)", topo_strerror(err));
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+
+ if ((gdl = ipmi_sdr_lookup_generic(hdl, entity_ref))
+ == NULL) {
+ topo_mod_dprintf(mod, "Failed to lookup SDR for %s (%s)\n",
+ entity_ref, ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+
+ /*
+ * Now look for a private argument list to figure out whether we're
+ * doing a get or a set operation, and then do it.
+ */
+ if ((nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &pargs) == 0) &&
+ nvlist_exists(pargs, TOPO_PROP_VAL_VAL)) {
+ /*
+ * Set the LED mode
+ */
+ if ((ret = nvlist_lookup_uint32(pargs, TOPO_PROP_VAL_VAL,
+ &mode_in)) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup %s nvpair "
+ "(%s)\n", TOPO_PROP_VAL_VAL, strerror(ret));
+ topo_mod_strfree(mod, entity_ref);
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+ if (mode_in != TOPO_LED_STATE_OFF &&
+ mode_in != TOPO_LED_STATE_ON) {
+ topo_mod_dprintf(mod, "Invalid property value: %d\n",
+ mode_in);
+ topo_mod_strfree(mod, entity_ref);
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+ ledmode = (uint8_t)mode_in;
+ topo_mod_dprintf(mod, "Setting LED mode to %s\n",
+ ledmode ? "ON" : "OFF");
+ if (ipmi_sunoem_led_set(hdl, gdl, ledmode) < 0) {
+ topo_mod_dprintf(mod, "Failed to set LED mode for %s "
+ "(%s)\n", entity_ref, ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+ } else {
+ /*
+ * Get the LED mode
+ */
+ topo_mod_dprintf(mod, "Getting LED mode\n");
+ if (ipmi_sunoem_led_get(hdl, gdl, &ledmode) < 0) {
+ topo_mod_dprintf(mod, "Failed to get LED mode for %s "
+ "(%s)\n", entity_ref, ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+ }
+ topo_mod_strfree(mod, entity_ref);
+
+ if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
+ nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, TOPO_LED_MODE) != 0 ||
+ nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 ||
+ nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, ledmode) != 0) {
+ topo_mod_dprintf(mod, "Failed to allocate 'out' nvlist\n");
+ nvlist_free(nvl);
+ return (topo_mod_seterrno(mod, EMOD_NOMEM));
+ }
+ *out = nvl;
+
+ return (0);
+}
+
+/*
+ * On thumper platforms these is no seperate locate LED for the drive bays.
+ * Therefore we simulate a locate LED by blinking the ok2rm LED.
+ */
+static int
+thumper_locate_mode(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
+ nvlist_t *in, nvlist_t **out)
+{
+ char *entity_ref;
+ ipmi_sdr_generic_locator_t *gdl = NULL;
+ ipmi_handle_t *hdl;
+ int err, ret;
+ uint8_t ledmode;
+ uint32_t mode_in;
+ nvlist_t *pargs, *nvl;
+
+ if (vers > TOPO_METH_THUMPER_LOCATE_VERSION)
+ return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
+
+ /*
+ * Get an IPMI handle and then lookup the generic device locator sensor
+ * data record referenced by the entity_ref prop val
+ */
+ if ((hdl = topo_mod_ipmi(mod)) == NULL) {
+ topo_mod_dprintf(mod, "Failed to get IPMI handle\n");
+ return (-1);
+ }
+
+ if (topo_prop_get_string(node, TOPO_PGROUP_FACILITY, "entity_ref",
+ &entity_ref, &err) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup entity_ref property "
+ "(%s)", topo_strerror(err));
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+
+ if ((gdl = ipmi_sdr_lookup_generic(hdl, entity_ref))
+ == NULL) {
+ topo_mod_dprintf(mod, "Failed to lookup SDR for %s (%s)\n",
+ entity_ref, ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+
+ /*
+ * Now look for a private argument list to figure out whether we're
+ * doing a get or a set operation, and then do it.
+ */
+ if ((nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &pargs) == 0) &&
+ nvlist_exists(pargs, TOPO_PROP_VAL_VAL)) {
+ /*
+ * Set the LED mode
+ */
+ if ((ret = nvlist_lookup_uint32(pargs, TOPO_PROP_VAL_VAL,
+ &mode_in)) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup %s nvpair "
+ "(%s)\n", TOPO_PROP_VAL_VAL, strerror(ret));
+ topo_mod_strfree(mod, entity_ref);
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+ if (mode_in != TOPO_LED_STATE_OFF &&
+ mode_in != TOPO_LED_STATE_ON) {
+ topo_mod_dprintf(mod, "Invalid property value: %d\n",
+ mode_in);
+ topo_mod_strfree(mod, entity_ref);
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+ if (mode_in == TOPO_LED_STATE_ON)
+ ledmode = IPMI_SUNOEM_LED_MODE_FAST;
+ else
+ ledmode = (uint8_t)mode_in;
+ if (ipmi_sunoem_led_set(hdl, gdl, ledmode) < 0) {
+ topo_mod_dprintf(mod, "Failed to set LED mode for %s "
+ "(%s)\n", entity_ref, ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+ } else {
+ /*
+ * Get the LED mode
+ */
+ if (ipmi_sunoem_led_get(hdl, gdl, &ledmode) < 0) {
+ topo_mod_dprintf(mod, "Failed to get LED mode for %s "
+ "(%s)\n", entity_ref, ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+ }
+ topo_mod_strfree(mod, entity_ref);
+
+ if (ledmode == IPMI_SUNOEM_LED_MODE_FAST)
+ ledmode = TOPO_LED_STATE_ON;
+ else
+ ledmode = TOPO_LED_STATE_OFF;
+
+ if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
+ nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, TOPO_LED_MODE) != 0 ||
+ nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 ||
+ nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, ledmode) != 0) {
+ topo_mod_dprintf(mod, "Failed to allocate 'out' nvlist\n");
+ nvlist_free(nvl);
+ return (topo_mod_seterrno(mod, EMOD_NOMEM));
+ }
+ *out = nvl;
+
+ return (0);
+}
+
+
+/*
+ * This is a method for the "mode" property that is specific for the drive bay
+ * LED's on thumper platforms. On thumper, the drive bay LED's are manipulated
+ * by asserting the right state bits in the hdd#.state compact SDR.
+ */
+static int
+thumper_indicator_mode(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
+ nvlist_t *in, nvlist_t **out)
+{
+ char *entity_ref;
+ ipmi_sdr_compact_sensor_t *cs = NULL;
+ ipmi_handle_t *hdl;
+ int err, ret;
+ uint32_t mask, type, ledmode;
+ nvlist_t *pargs, *nvl;
+
+ if (vers > TOPO_METH_THUMPER_MODE_VERSION)
+ return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
+
+ /*
+ * Figure out which sensor state mask to use based on the indicator
+ * node's type prop val
+ */
+ if (topo_prop_get_uint32(node, TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE,
+ &type, &err) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup %s property "
+ "(%s)", TOPO_FACILITY_TYPE, topo_strerror(err));
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+ switch (type) {
+ case (TOPO_LED_TYPE_SERVICE):
+ mask = THUMPER_SERVICE_LED_MASK;
+ break;
+ case (TOPO_LED_TYPE_PRESENT):
+ mask = THUMPER_PRESENT_LED_MASK;
+ break;
+ case (TOPO_LED_TYPE_OK2RM):
+ mask = THUMPER_OK2RM_LED_MASK;
+ break;
+ default:
+ topo_mod_dprintf(mod, "Invalid LED type: 0x%x\n", type);
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+
+ /*
+ * Get an IPMI handle and then lookup the compact sensor data record
+ * referenced by the entity_ref prop val
+ */
+ if ((hdl = topo_mod_ipmi(mod)) == NULL) {
+ topo_mod_dprintf(mod, "Failed to get IPMI handle\n");
+ return (-1);
+ }
+
+ if (topo_prop_get_string(node, TOPO_PGROUP_FACILITY, "entity_ref",
+ &entity_ref, &err) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup entity_ref property "
+ "(%s)", topo_strerror(err));
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+
+ if ((cs = ipmi_sdr_lookup_compact_sensor(hdl, entity_ref))
+ == NULL) {
+ topo_mod_dprintf(mod, "Failed to lookup SDR for %s (%s)\n",
+ entity_ref, ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+
+ /*
+ * Now lookup the propmethod argument list and figure out whether we're
+ * doing a get or a set operation, and then do it.
+ */
+ if ((nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &pargs) == 0) &&
+ nvlist_exists(pargs, TOPO_PROP_VAL_VAL)) {
+ /*
+ * Set the LED mode
+ */
+ ipmi_set_sensor_reading_t sr_out;
+
+ if ((ret = nvlist_lookup_uint32(pargs, TOPO_PROP_VAL_VAL,
+ &ledmode)) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup %s nvpair "
+ "(%s)\n", TOPO_PROP_VAL_VAL, strerror(ret));
+ topo_mod_strfree(mod, entity_ref);
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+
+ if (ledmode == TOPO_LED_STATE_OFF) {
+ sr_out.iss_deassert_state = mask;
+ sr_out.iss_deassrt_op = IPMI_SENSOR_OP_SET;
+ } else if (ledmode == TOPO_LED_STATE_ON) {
+ sr_out.iss_assert_state = mask;
+ sr_out.iss_assert_op = IPMI_SENSOR_OP_SET;
+ } else {
+ topo_mod_dprintf(mod, "Invalid LED mode: %d 0x%x\n",
+ ledmode);
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+ sr_out.iss_id = cs->is_cs_number;
+ topo_mod_dprintf(mod, "Setting LED mode (mask = 0x%x)\n", mask);
+ if (ipmi_set_sensor_reading(hdl, &sr_out) != 0) {
+ topo_mod_dprintf(mod, "Failed to set sensor reading "
+ "for sensor %s (%s)\n", entity_ref,
+ ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+ } else {
+ /*
+ * Get the LED mode
+ */
+ ipmi_sensor_reading_t *sr_in;
+
+ topo_mod_dprintf(mod, "Getting LED mode\n");
+ if ((sr_in = ipmi_get_sensor_reading(hdl, cs->is_cs_number))
+ == NULL) {
+ topo_mod_dprintf(mod, "Failed to get sensor reading "
+ "for sensor %s (sensor num: %d) (error: %s)\n",
+ entity_ref, cs->is_cs_number, ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (-1);
+ }
+ if (sr_in->isr_state & (uint16_t)mask)
+ ledmode = TOPO_LED_STATE_ON;
+ else
+ ledmode = TOPO_LED_STATE_OFF;
+ }
+ topo_mod_strfree(mod, entity_ref);
+
+ if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
+ nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, TOPO_LED_MODE) != 0 ||
+ nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 ||
+ nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, ledmode) != 0) {
+ topo_mod_dprintf(mod, "Failed to allocate 'out' nvlist\n");
+ nvlist_free(nvl);
+ return (topo_mod_seterrno(mod, EMOD_NOMEM));
+ }
+ *out = nvl;
+ return (0);
+}
+
+static int
+make_sensor_node(topo_mod_t *mod, tnode_t *pnode, struct sensor_data *sd)
+{
+ int err, ret;
+ tnode_t *fnode;
+ char *ftype = "sensor";
+ topo_pgroup_info_t pgi;
+ nvlist_t *arg_nvl = NULL;
+
+ if ((fnode = topo_node_facbind(mod, pnode, sd->sd_entity_ref,
+ ftype)) == NULL) {
+ topo_mod_dprintf(mod, "Failed to bind facility node: %s\n",
+ sd->sd_entity_ref);
+ /* topo errno set */
+ return (-1);
+ }
+
+ pgi.tpi_name = TOPO_PGROUP_FACILITY;
+ pgi.tpi_namestab = TOPO_STABILITY_PRIVATE;
+ pgi.tpi_datastab = TOPO_STABILITY_PRIVATE;
+ pgi.tpi_version = 1;
+ if (topo_pgroup_create(fnode, &pgi, &err) != 0) {
+ if (err != ETOPO_PROP_DEFD) {
+ topo_mod_dprintf(mod, "pgroups create failure: %s\n",
+ topo_strerror(err));
+ topo_node_unbind(fnode);
+ return (-1);
+ }
+ }
+ if (topo_method_register(mod, fnode, ipmi_fac_methods) < 0) {
+ topo_mod_dprintf(mod, "make_fac_node: "
+ "failed to register facility methods");
+ topo_node_unbind(fnode);
+ return (-1);
+ }
+ /*
+ * For both threshold and discrete sensors we set up a propmethod for
+ * getting the sensor state and properties to hold the entity ref,
+ * sensor class and sensor type.
+ *
+ * Additionally, for analog sensors we set up a property method for
+ * getting the converted sensor reading and property for the base
+ * unit type
+ */
+ if (topo_prop_set_string(fnode, TOPO_PGROUP_FACILITY, "entity_ref",
+ TOPO_PROP_IMMUTABLE, sd->sd_entity_ref, &err) != 0) {
+ topo_mod_dprintf(mod, "Failed to set entity_ref property on "
+ "node: %s=%d (%s)\n", topo_node_name(fnode),
+ topo_node_instance(fnode), topo_strerror(err));
+ return (-1);
+ }
+ if (topo_prop_set_string(fnode, TOPO_PGROUP_FACILITY, TOPO_SENSOR_CLASS,
+ TOPO_PROP_IMMUTABLE, sd->sd_class, &err) != 0) {
+ topo_mod_dprintf(mod, "Failed to set %s property on node: "
+ "%s=%d (%s)\n", TOPO_SENSOR_CLASS, topo_node_name(fnode),
+ topo_node_instance(fnode), topo_strerror(err));
+ return (-1);
+ }
+ if (topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY,
+ TOPO_FACILITY_TYPE, TOPO_PROP_IMMUTABLE, sd->sd_stype, &err) != 0) {
+ topo_mod_dprintf(mod, "Failed to set %s property on node: "
+ "%s=%d (%s)\n", TOPO_FACILITY_TYPE, topo_node_name(fnode),
+ topo_node_instance(fnode), topo_strerror(err));
+ return (-1);
+ }
+ if (topo_mod_nvalloc(mod, &arg_nvl, NV_UNIQUE_NAME) < 0) {
+ topo_node_unbind(fnode);
+ return (topo_mod_seterrno(mod, EMOD_NOMEM));
+ }
+
+ if ((ret = nvlist_add_string(arg_nvl, "ipmi_entity", sd->sd_entity_ref))
+ != 0) {
+ topo_mod_dprintf(mod, "Failed build arg nvlist (%s)\n",
+ strerror(ret));
+ nvlist_free(arg_nvl);
+ return (-1);
+ }
+
+ if (topo_prop_method_register(fnode, TOPO_PGROUP_FACILITY,
+ TOPO_SENSOR_STATE, TOPO_TYPE_UINT32, "ipmi_sensor_state", arg_nvl,
+ &err) != 0) {
+ topo_mod_dprintf(mod, "Failed to register %s propmeth on fac "
+ "node %s (%s)\n", TOPO_SENSOR_STATE, topo_node_name(fnode),
+ topo_strerror(err));
+ nvlist_free(arg_nvl);
+ return (-1);
+ }
+
+ if (strcmp(sd->sd_class, TOPO_SENSOR_CLASS_THRESHOLD) == 0) {
+ if (topo_prop_method_register(fnode, TOPO_PGROUP_FACILITY,
+ TOPO_SENSOR_READING, TOPO_TYPE_DOUBLE,
+ "ipmi_sensor_reading", arg_nvl, &err) != 0) {
+ topo_mod_dprintf(mod, "Failed to register %s propmeth "
+ "on fac node %s (%s)\n", TOPO_SENSOR_READING,
+ topo_node_name(fnode), topo_strerror(err));
+ nvlist_free(arg_nvl);
+ return (-1);
+ }
+ if (topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY,
+ TOPO_SENSOR_UNITS, TOPO_PROP_IMMUTABLE, sd->sd_units, &err)
+ != 0) {
+ topo_mod_dprintf(mod, "Failed to set units property on "
+ "node: %s (%s)\n", topo_node_name(fnode),
+ topo_strerror(err));
+ nvlist_free(arg_nvl);
+ return (-1);
+ }
+ }
+ nvlist_free(arg_nvl);
+ return (0);
+}
+
+/* ARGSUSED */
+static int
+sdr_callback(ipmi_handle_t *hdl, const char *id, ipmi_sdr_t *sdr, void *data)
+{
+ uint8_t sensor_entity, sensor_inst;
+ int sensor_idlen;
+ ipmi_sdr_full_sensor_t *f_sensor = NULL;
+ ipmi_sdr_compact_sensor_t *c_sensor = NULL;
+ struct sensor_data sd;
+ struct entity_info *ei = (struct entity_info *)data;
+
+ switch (sdr->is_type) {
+ case IPMI_SDR_TYPE_FULL_SENSOR:
+ f_sensor =
+ (ipmi_sdr_full_sensor_t *)sdr->is_record;
+ sensor_entity = f_sensor->is_fs_entity_id;
+ sensor_inst = f_sensor->is_fs_entity_instance;
+ sensor_idlen = f_sensor->is_fs_idlen;
+ (void) strncpy(sd.sd_entity_ref,
+ f_sensor->is_fs_idstring,
+ f_sensor->is_fs_idlen);
+ sd.sd_entity_ref[sensor_idlen] = '\0';
+ sd.sd_class = TOPO_SENSOR_CLASS_THRESHOLD;
+ sd.sd_units = f_sensor->is_fs_unit2;
+ sd.sd_stype = f_sensor->is_fs_type;
+ sd.sd_rtype = f_sensor->is_fs_reading_type;
+ break;
+ case IPMI_SDR_TYPE_COMPACT_SENSOR:
+ c_sensor =
+ (ipmi_sdr_compact_sensor_t *)sdr->is_record;
+ sensor_entity = c_sensor->is_cs_entity_id;
+ sensor_inst = c_sensor->is_cs_entity_instance;
+ sensor_idlen = c_sensor->is_cs_idlen;
+ (void) strncpy(sd.sd_entity_ref,
+ c_sensor->is_cs_idstring,
+ sensor_idlen);
+ sd.sd_entity_ref[sensor_idlen] = '\0';
+ sd.sd_class = TOPO_SENSOR_CLASS_DISCRETE;
+ sd.sd_units = c_sensor->is_cs_unit2;
+ sd.sd_stype = c_sensor->is_cs_type;
+ sd.sd_rtype = c_sensor->is_cs_reading_type;
+ break;
+ default:
+ return (0);
+ }
+ /*
+ * We offset the threshold and generic sensor reading types by 0x100
+ */
+ if (sd.sd_rtype >= 0x1 && sd.sd_rtype <= 0xc)
+ sd.sd_stype = sd.sd_rtype + 0x100;
+
+ if ((sensor_entity == ei->ei_id) && (sensor_inst == ei->ei_inst))
+ if (make_sensor_node(ei->ei_mod, ei->ei_node, &sd) != 0) {
+ topo_mod_dprintf(ei->ei_mod, "Failed to create sensor "
+ "node for %s\n", sd.sd_entity_ref);
+ if (topo_mod_errno(ei->ei_mod) != EMOD_NODE_DUP)
+ return (-1);
+ }
+ return (0);
+}
+
+/* ARGSUSED */
+static int
+ipmi_sensor_enum(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
+ nvlist_t *in, nvlist_t **out)
+{
+ char *entity_ref;
+ int err;
+ struct entity_info ei;
+ ipmi_sdr_t *ref_sdr;
+ ipmi_handle_t *hdl;
+ ipmi_sdr_full_sensor_t *fsensor;
+ ipmi_sdr_compact_sensor_t *csensor;
+ ipmi_sdr_fru_locator_t *floc;
+ ipmi_sdr_generic_locator_t *gloc;
+
+ if ((hdl = topo_mod_ipmi(mod)) == NULL) {
+ topo_mod_dprintf(mod, "Failed to get IPMI handle\n");
+ return (-1);
+ }
+
+ /*
+ * Use the entity ref to lookup the SDR, which will have the entity ID
+ * and instance.
+ */
+ if (topo_prop_get_string(node, TOPO_PGROUP_IPMI,
+ "entity_ref", &entity_ref, &err) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup entity_ref "
+ "property (%s)\n", topo_strerror(err));
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+
+ topo_mod_dprintf(mod, "Looking up SDR for %s ...\n",
+ entity_ref);
+ if ((ref_sdr = ipmi_sdr_lookup(hdl, entity_ref)) == NULL) {
+ topo_mod_dprintf(mod, "Failed to lookup SDR (%s)\n",
+ ipmi_errmsg(hdl));
+ topo_mod_strfree(mod, entity_ref);
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+ topo_mod_strfree(mod, entity_ref);
+
+ switch (ref_sdr->is_type) {
+ case IPMI_SDR_TYPE_FULL_SENSOR:
+ fsensor = (ipmi_sdr_full_sensor_t *)ref_sdr->is_record;
+ ei.ei_id = fsensor->is_fs_entity_id;
+ ei.ei_inst = fsensor->is_fs_entity_instance;
+ break;
+ case IPMI_SDR_TYPE_COMPACT_SENSOR:
+ csensor
+ = (ipmi_sdr_compact_sensor_t *)ref_sdr->is_record;
+ ei.ei_id = csensor->is_cs_entity_id;
+ ei.ei_inst = csensor->is_cs_entity_instance;
+ break;
+ case IPMI_SDR_TYPE_FRU_LOCATOR:
+ floc = (ipmi_sdr_fru_locator_t *)ref_sdr->is_record;
+ ei.ei_id = floc->is_fl_entity;
+ ei.ei_inst = floc->is_fl_instance;
+ break;
+ case IPMI_SDR_TYPE_GENERIC_LOCATOR:
+ gloc = (ipmi_sdr_generic_locator_t *)ref_sdr->is_record;
+ ei.ei_id = gloc->is_gl_entity;
+ ei.ei_inst = gloc->is_gl_instance;
+ break;
+ default:
+ topo_mod_dprintf(mod, "Failed to determine entity id "
+ "and instance\n", ipmi_errmsg(hdl));
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+ topo_mod_dprintf(mod, "Entity ID = 0x%x, Entity Instance = 0x%x\n",
+ ei.ei_id, ei.ei_inst);
+
+ ei.ei_node = node;
+ ei.ei_mod = mod;
+
+ /*
+ * Now iterate through all of the full and compact sensor data records
+ * and create a sensor facility node for each record that matches our
+ * entity ID and instance
+ */
+ if (ipmi_sdr_iter(hdl, sdr_callback, &ei) != 0) {
+ topo_mod_dprintf(mod, "ipmi_sdr_iter() failed\n");
+ return (-1);
+ }
+ return (0);
+}
+
+static int
+ipmi_entity(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
+ nvlist_t *in, nvlist_t **out)
+{
+ char *fmtstr, buf[BUFSZ];
+ tnode_t *refnode;
+ int ret, inst1, inst2;
+ uint32_t offset, nparams;
+ nvlist_t *args, *nvl;
+
+ if (vers > TOPO_METH_IPMI_ENTITY_VERSION)
+ return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
+
+ if ((ret = nvlist_lookup_nvlist(in, TOPO_PROP_ARGS, &args)) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup 'args' list (%s)\n",
+ strerror(ret));
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+ if ((ret = nvlist_lookup_uint32(args, "offset", &offset)) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup 'offset' arg (%s)\n",
+ strerror(ret));
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+ if ((ret = nvlist_lookup_uint32(args, "nparams", &nparams)) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup 'nparams' arg (%s)\n",
+ strerror(ret));
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+
+ if ((fmtstr = get_fmtstr(mod, in)) == NULL) {
+ topo_mod_dprintf(mod, "Failed to retrieve 'format' arg\n");
+ /* topo errno already set */
+ return (-1);
+ }
+
+ if (topo_node_flags(node) & TOPO_NODE_FACILITY)
+ refnode = topo_node_parent(node);
+ else
+ refnode = node;
+
+ switch (nparams) {
+ case 1:
+ /* LINTED: E_SEC_PRINTF_VAR_FMT */
+ (void) snprintf(buf, BUFSZ, fmtstr,
+ (topo_node_instance(refnode) + offset));
+ break;
+ case 2:
+ inst1 = topo_node_instance(topo_node_parent(refnode)) + offset;
+ inst2 = topo_node_instance(refnode) + offset;
+ /* LINTED: E_SEC_PRINTF_VAR_FMT */
+ (void) snprintf(buf, BUFSZ, fmtstr, inst1, inst2);
+ break;
+ default:
+ topo_mod_dprintf(mod, "Invalid 'nparams' argval (%d)\n",
+ nparams);
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+
+ if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
+ nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, "entity_ref") != 0 ||
+ nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_STRING) != 0 ||
+ nvlist_add_string(nvl, TOPO_PROP_VAL_VAL, buf) != 0) {
+ topo_mod_dprintf(mod, "Failed to allocate 'out' nvlist\n");
+ nvlist_free(nvl);
+ return (topo_mod_seterrno(mod, EMOD_NOMEM));
+ }
+ *out = nvl;
+
+ return (0);
+}
+
+/* ARGSUSED */
+static int
+dimm_ipmi_entity(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
+ nvlist_t *in, nvlist_t **out)
+{
+ char *fmtstr, buf[BUFSZ];
+ tnode_t *chip, *dimm;
+ int ret;
+ uint32_t offset;
+ nvlist_t *args, *nvl;
+
+ if ((ret = nvlist_lookup_nvlist(in, TOPO_PROP_ARGS, &args)) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup 'args' list (%s)\n",
+ strerror(ret));
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+ if ((ret = nvlist_lookup_uint32(args, "offset", &offset)) != 0) {
+ topo_mod_dprintf(mod, "Failed to lookup 'offset' arg (%s)\n",
+ strerror(ret));
+ return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
+ }
+
+ if ((fmtstr = get_fmtstr(mod, in)) == NULL) {
+ topo_mod_dprintf(mod, "Failed to retrieve 'format' arg\n");
+ /* topo errno already set */
+ return (-1);
+ }
+
+ if (topo_node_flags(node) & TOPO_NODE_FACILITY)
+ dimm = topo_node_parent(node);
+ else
+ dimm = node;
+
+ chip = topo_node_parent(topo_node_parent(dimm));
+
+ /* LINTED: E_SEC_PRINTF_VAR_FMT */
+ (void) snprintf(buf, BUFSZ, fmtstr, topo_node_instance(chip),
+ (topo_node_instance(dimm) + offset));
+
+ if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
+ nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, "entity_ref") != 0 ||
+ nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_STRING) != 0 ||
+ nvlist_add_string(nvl, TOPO_PROP_VAL_VAL, buf) != 0) {
+ topo_mod_dprintf(mod, "Failed to allocate 'out' nvlist\n");
+ nvlist_free(nvl);
+ return (topo_mod_seterrno(mod, EMOD_NOMEM));
+ }
+ *out = nvl;
+
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+fac_prov_ipmi_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
+ topo_instance_t min, topo_instance_t max, void *arg, void *unused)
+{
+ topo_pgroup_info_t pgi;
+ int err;
+
+ if (topo_node_flags(rnode) == TOPO_NODE_DEFAULT) {
+ pgi.tpi_name = TOPO_PGROUP_IPMI;
+ pgi.tpi_namestab = TOPO_STABILITY_PRIVATE;
+ pgi.tpi_datastab = TOPO_STABILITY_PRIVATE;
+ pgi.tpi_version = 1;
+ if (topo_pgroup_create(rnode, &pgi, &err) != 0) {
+ if (err != ETOPO_PROP_DEFD) {
+ topo_mod_dprintf(mod,
+ "pgroups create failure: %s\n",
+ topo_strerror(err));
+ return (-1);
+ }
+ }
+ if (topo_method_register(mod, rnode, ipmi_node_methods) != 0) {
+ topo_mod_dprintf(mod, "fac_prov_ipmi_enum: "
+ "topo_method_register() failed: %s",
+ topo_mod_errmsg(mod));
+ return (-1);
+ }
+ } else {
+ if (topo_method_register(mod, rnode, ipmi_fac_methods) != 0) {
+ topo_mod_dprintf(mod, "fac_prov_ipmi_enum: "
+ "topo_method_register() failed: %s",
+ topo_mod_errmsg(mod));
+ return (-1);
+ }
+ }
+ return (0);
+}
--- a/usr/src/lib/libipmi/Makefile.com Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/libipmi/Makefile.com Thu Jul 31 17:35:39 2008 -0700
@@ -52,7 +52,7 @@
CLEANFILES += $(SRCDIR)/ipmi_tables.c
INCS += -I$(SRCDIR)
-LDLIBS += -lc
+LDLIBS += -lc -lm
CPPFLAGS += $(INCS)
$(LINTLIB) := SRCS= $(SRCDIR)/$(LINTSRC)
--- a/usr/src/lib/libipmi/common/ipmi_impl.h Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/libipmi/common/ipmi_impl.h Thu Jul 31 17:35:39 2008 -0700
@@ -120,6 +120,7 @@
extern ipmi_name_trans_t ipmi_reading_type_table[];
extern ipmi_name_trans_t ipmi_errno_table[];
extern ipmi_name_trans_t ipmi_threshold_state_table[];
+extern ipmi_name_trans_t ipmi_units_type_table[];
extern ipmi_sensor_trans_t ipmi_reading_state_table[];
extern ipmi_sensor_trans_t ipmi_specific_state_table[];
--- a/usr/src/lib/libipmi/common/ipmi_sdr.c Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/libipmi/common/ipmi_sdr.c Thu Jul 31 17:35:39 2008 -0700
@@ -30,9 +30,57 @@
#include <stddef.h>
#include <string.h>
#include <strings.h>
+#include <math.h>
#include "ipmi_impl.h"
+/*
+ * This macros are used by ipmi_sdr_conv_reading. They were taken verbatim from
+ * the source for ipmitool (v1.88)
+ */
+#define tos32(val, bits) ((val & ((1<<((bits)-1)))) ? (-((val) & \
+ (1<<((bits)-1))) | (val)) : (val))
+
+#define __TO_TOL(mtol) (uint16_t)(BSWAP_16(mtol) & 0x3f)
+
+#define __TO_M(mtol) (int16_t)(tos32((((BSWAP_16(mtol) & 0xff00) >> 8) | \
+ ((BSWAP_16(mtol) & 0xc0) << 2)), 10))
+
+#define __TO_B(bacc) (int32_t)(tos32((((BSWAP_32(bacc) & \
+ 0xff000000) >> 24) | \
+ ((BSWAP_32(bacc) & 0xc00000) >> 14)), 10))
+
+#define __TO_ACC(bacc) (uint32_t)(((BSWAP_32(bacc) & 0x3f0000) >> 16) | \
+ ((BSWAP_32(bacc) & 0xf000) >> 6))
+
+#define __TO_ACC_EXP(bacc) (uint32_t)((BSWAP_32(bacc) & 0xc00) >> 10)
+#define __TO_R_EXP(bacc) (int32_t)(tos32(((BSWAP_32(bacc) & 0xf0) >> 4),\
+ 4))
+#define __TO_B_EXP(bacc) (int32_t)(tos32((BSWAP_32(bacc) & 0xf), 4))
+
+#define SDR_SENSOR_L_LINEAR 0x00
+#define SDR_SENSOR_L_LN 0x01
+#define SDR_SENSOR_L_LOG10 0x02
+#define SDR_SENSOR_L_LOG2 0x03
+#define SDR_SENSOR_L_E 0x04
+#define SDR_SENSOR_L_EXP10 0x05
+#define SDR_SENSOR_L_EXP2 0x06
+#define SDR_SENSOR_L_1_X 0x07
+#define SDR_SENSOR_L_SQR 0x08
+#define SDR_SENSOR_L_CUBE 0x09
+#define SDR_SENSOR_L_SQRT 0x0a
+#define SDR_SENSOR_L_CUBERT 0x0b
+#define SDR_SENSOR_L_NONLINEAR 0x70
+
+/*
+ * Analog sensor reading data formats
+ *
+ * See Section 43.1
+ */
+#define IPMI_DATA_FMT_UNSIGNED 0
+#define IPMI_DATA_FMT_ONESCOMP 1
+#define IPMI_DATA_FMT_TWOSCOMP 2
+
typedef struct ipmi_sdr_cache_ent {
char *isc_name;
struct ipmi_sdr *isc_sdr;
@@ -530,3 +578,79 @@
return (ipmi_sdr_lookup_common(ihp, idstr,
IPMI_SDR_TYPE_FULL_SENSOR));
}
+
+/*
+ * Mostly taken from ipmitool source v1.88
+ *
+ * This function converts the raw sensor reading returned by
+ * ipmi_get_sensor_reading to a unit-based value of type double.
+ */
+int
+ipmi_sdr_conv_reading(ipmi_sdr_full_sensor_t *sensor, uint8_t val,
+ double *result)
+{
+ int m, b, k1, k2;
+
+ m = __TO_M(sensor->is_fs_mtol);
+ b = __TO_B(sensor->is_fs_bacc);
+ k1 = __TO_B_EXP(sensor->is_fs_bacc);
+ k2 = __TO_R_EXP(sensor->is_fs_bacc);
+
+ switch (sensor->is_fs_analog_fmt) {
+ case IPMI_DATA_FMT_UNSIGNED:
+ *result = (double)(((m * val) +
+ (b * pow(10, k1))) * pow(10, k2));
+ break;
+ case IPMI_DATA_FMT_ONESCOMP:
+ if (val & 0x80)
+ val++;
+ /* FALLTHRU */
+ case IPMI_DATA_FMT_TWOSCOMP:
+ *result = (double)(((m * (int8_t)val) +
+ (b * pow(10, k1))) * pow(10, k2));
+ break;
+ default:
+ /* This sensor does not return a numeric reading */
+ return (-1);
+ }
+
+ switch (sensor->is_fs_sensor_linear_type) {
+ case SDR_SENSOR_L_LN:
+ *result = log(*result);
+ break;
+ case SDR_SENSOR_L_LOG10:
+ *result = log10(*result);
+ break;
+ case SDR_SENSOR_L_LOG2:
+ *result = (double)(log(*result) / log(2.0));
+ break;
+ case SDR_SENSOR_L_E:
+ *result = exp(*result);
+ break;
+ case SDR_SENSOR_L_EXP10:
+ *result = pow(10.0, *result);
+ break;
+ case SDR_SENSOR_L_EXP2:
+ *result = pow(2.0, *result);
+ break;
+ case SDR_SENSOR_L_1_X:
+ *result = pow(*result, -1.0); /* 1/x w/o exception */
+ break;
+ case SDR_SENSOR_L_SQR:
+ *result = pow(*result, 2.0);
+ break;
+ case SDR_SENSOR_L_CUBE:
+ *result = pow(*result, 3.0);
+ break;
+ case SDR_SENSOR_L_SQRT:
+ *result = sqrt(*result);
+ break;
+ case SDR_SENSOR_L_CUBERT:
+ *result = cbrt(*result);
+ break;
+ case SDR_SENSOR_L_LINEAR:
+ default:
+ break;
+ }
+ return (0);
+}
--- a/usr/src/lib/libipmi/common/ipmi_util.c Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/libipmi/common/ipmi_util.c Thu Jul 31 17:35:39 2008 -0700
@@ -169,6 +169,21 @@
}
void
+ipmi_sensor_units_name(uint8_t type, char *buf, size_t len)
+{
+ ipmi_name_trans_t *ntp;
+
+ for (ntp = &ipmi_units_type_table[0]; ntp->int_name != NULL; ntp++) {
+ if (ntp->int_value == type) {
+ (void) strlcpy(buf, ntp->int_name, len);
+ return;
+ }
+ }
+
+ (void) snprintf(buf, len, "0x%02x", type);
+}
+
+void
ipmi_sensor_reading_name(uint8_t sensor_type, uint8_t reading_type,
char *buf, size_t len)
{
--- a/usr/src/lib/libipmi/common/libipmi.h Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/libipmi/common/libipmi.h Thu Jul 31 17:35:39 2008 -0700
@@ -1426,7 +1426,8 @@
#define IPMI_SENSOR_THRESHOLD_UPPER_NONRECOV 0x0020
extern ipmi_sensor_reading_t *ipmi_get_sensor_reading(ipmi_handle_t *, uint8_t);
-
+extern int ipmi_sdr_conv_reading(ipmi_sdr_full_sensor_t *, uint8_t,
+ double *);
/*
* Set Sensor Reading. See section 35.14.
*/
@@ -1517,6 +1518,7 @@
*/
void ipmi_entity_name(uint8_t, char *, size_t);
void ipmi_sensor_type_name(uint8_t, char *, size_t);
+void ipmi_sensor_units_name(uint8_t, char *, size_t);
void ipmi_sensor_reading_name(uint8_t, uint8_t, char *, size_t);
/*
--- a/usr/src/lib/libipmi/common/mapfile-vers Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/libipmi/common/mapfile-vers Thu Jul 31 17:35:39 2008 -0700
@@ -46,6 +46,7 @@
ipmi_get_sensor_reading;
ipmi_open;
ipmi_sdr_changed;
+ ipmi_sdr_conv_reading;
ipmi_sdr_get;
ipmi_sdr_iter;
ipmi_sdr_lookup;
@@ -62,6 +63,7 @@
ipmi_sel_set_utc_offset;
ipmi_sensor_reading_name;
ipmi_sensor_type_name;
+ ipmi_sensor_units_name;
ipmi_send;
ipmi_set_sensor_reading;
ipmi_sunoem_led_get;
--- a/usr/src/lib/libipmi/common/mktables.sh Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/libipmi/common/mktables.sh Thu Jul 31 17:35:39 2008 -0700
@@ -107,3 +107,17 @@
echo "\t{ 0, NULL }
};"
+
+#
+# Units
+#
+echo "\nipmi_name_trans_t ipmi_units_type_table[] = {"
+
+pattern="#define IPMI_UNITS_\([A-Z0-9_]*\).*\$"
+replace=" { IPMI_UNITS_\1, \"\1\" },"
+
+cat $libipmi_h | sed -n "s/$pattern/$replace/p" || exit 1
+
+echo "\t{ 0, NULL }
+};"
+
--- a/usr/src/lib/libnvpair/libnvpair.c Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/libnvpair/libnvpair.c Thu Jul 31 17:35:39 2008 -0700
@@ -138,6 +138,12 @@
(void) fprintf(fp, " 0x%llx", (u_longlong_t)val);
break;
}
+ case DATA_TYPE_DOUBLE: {
+ double val;
+ (void) nvpair_value_double(nvp, &val);
+ (void) fprintf(fp, " 0x%llf", val);
+ break;
+ }
case DATA_TYPE_STRING: {
char *val;
(void) nvpair_value_string(nvp, &val);
@@ -583,6 +589,7 @@
case DATA_TYPE_NVLIST:
case DATA_TYPE_NVLIST_ARRAY:
case DATA_TYPE_BOOLEAN:
+ case DATA_TYPE_DOUBLE:
case DATA_TYPE_UNKNOWN:
default:
/*
--- a/usr/src/lib/libnvpair/mapfile-vers Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/lib/libnvpair/mapfile-vers Thu Jul 31 17:35:39 2008 -0700
@@ -25,6 +25,13 @@
# ident "%Z%%M% %I% %E% SMI"
#
+SUNW_1.4 {
+ global:
+ nvlist_add_double;
+ nvlist_lookup_double;
+ nvpair_value_double;
+} SUNW_1.3;
+
SUNW_1.3 {
global:
nvlist_exists;
--- a/usr/src/pkgdefs/SUNWfmd/prototype_com Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/pkgdefs/SUNWfmd/prototype_com Thu Jul 31 17:35:39 2008 -0700
@@ -136,6 +136,7 @@
f none usr/lib/fm/topo/maps/xfp-hc-topology.xml 444 root bin
d none usr/lib/fm/topo/plugins 755 root bin
f none usr/lib/fm/topo/plugins/disk.so 555 root bin
+f none usr/lib/fm/topo/plugins/fac_prov_ipmi.so 555 root bin
f none usr/lib/fm/topo/plugins/ipmi.so 555 root bin
f none usr/lib/fm/topo/plugins/ses.so 555 root bin
f none usr/lib/fm/topo/plugins/xfp.so 555 root bin
--- a/usr/src/uts/common/sys/fm/protocol.h Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/uts/common/sys/fm/protocol.h Thu Jul 31 17:35:39 2008 -0700
@@ -153,6 +153,7 @@
#define FM_FMRI_AUTHORITY "authority"
#define FM_FMRI_SCHEME "scheme"
#define FM_FMRI_SVC_AUTHORITY "svc-authority"
+#define FM_FMRI_FACILITY "facility"
/* FMRI authority-type member names */
#define FM_FMRI_AUTH_CHASSIS "chassis-id"
@@ -206,6 +207,10 @@
#define FM_FMRI_HC_LIST "hc-list"
#define FM_FMRI_HC_SPECIFIC "hc-specific"
+/* facility member names */
+#define FM_FMRI_FACILITY_NAME "facility-name"
+#define FM_FMRI_FACILITY_TYPE "facility-type"
+
/* hc-list version and member names */
#define FM_FMRI_HC_NAME "hc-name"
#define FM_FMRI_HC_ID "hc-id"
--- a/usr/src/uts/common/sys/nvpair.h Thu Jul 31 15:42:10 2008 -0700
+++ b/usr/src/uts/common/sys/nvpair.h Thu Jul 31 17:35:39 2008 -0700
@@ -67,7 +67,12 @@
DATA_TYPE_UINT8,
DATA_TYPE_BOOLEAN_ARRAY,
DATA_TYPE_INT8_ARRAY,
+#if !defined(_KERNEL)
+ DATA_TYPE_UINT8_ARRAY,
+ DATA_TYPE_DOUBLE
+#else
DATA_TYPE_UINT8_ARRAY
+#endif
} data_type_t;
typedef struct nvpair {
@@ -188,6 +193,9 @@
int nvlist_add_string_array(nvlist_t *, const char *, char *const *, uint_t);
int nvlist_add_nvlist_array(nvlist_t *, const char *, nvlist_t **, uint_t);
int nvlist_add_hrtime(nvlist_t *, const char *, hrtime_t);
+#if !defined(_KERNEL)
+int nvlist_add_double(nvlist_t *, const char *, double);
+#endif
int nvlist_remove(nvlist_t *, const char *, data_type_t);
int nvlist_remove_all(nvlist_t *, const char *);
@@ -221,6 +229,9 @@
nvlist_t ***, uint_t *);
int nvlist_lookup_hrtime(nvlist_t *, const char *, hrtime_t *);
int nvlist_lookup_pairs(nvlist_t *, int, ...);
+#if !defined(_KERNEL)
+int nvlist_lookup_double(nvlist_t *, const char *, double *);
+#endif
int nvlist_lookup_nvpair(nvlist_t *, const char *, nvpair_t **);
int nvlist_lookup_nvpair_embedded_index(nvlist_t *, const char *, nvpair_t **,
@@ -257,6 +268,9 @@
int nvpair_value_string_array(nvpair_t *, char ***, uint_t *);
int nvpair_value_nvlist_array(nvpair_t *, nvlist_t ***, uint_t *);
int nvpair_value_hrtime(nvpair_t *, hrtime_t *);
+#if !defined(_KERNEL)
+int nvpair_value_double(nvpair_t *, double *);
+#endif
#ifdef __cplusplus
}