d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * CDDL HEADER START
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * The contents of this file are subject to the terms of the
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Common Development and Distribution License (the "License").
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * You may not use this file except in compliance with the License.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * or http://www.opensolaris.org/os/licensing.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * See the License for the specific language governing permissions
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * and limitations under the License.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * When distributing Covered Code, include this CDDL HEADER in each
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * If applicable, add the following below this CDDL HEADER, with the
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * fields enclosed by brackets "[]" replaced with your own identifying
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * information: Portions Copyright [yyyy] [name of copyright owner]
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * CDDL HEADER END
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*
6efb64ca6d97453babd6dae9c5c1f71ec3e53bedEric Schrock * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Use is subject to license terms.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Facility node support for SES enclosures. We support the following facility
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * nodes, based on the node type:
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * bay
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * indicator=ident
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * indicator=fail
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * indicator=ok2rm
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * sensor=fault
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * controller
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * indicator=ident
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * indicator=fail
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * fan
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * indicator=ident
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * indicator=fail
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * sensor=speed
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * sensor=fault
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * psu
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * indicator=ident
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * indicator=fail
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * sensor=status
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * ses-enclosure
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * indicator=ident
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * indicator=fail
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * sensor=fault
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * sensor=<name> (temperature)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * sensor=<name> (voltage)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * sensor=<name> (current)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Most of these are handled by a single method that supports getting and
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * setting boolean properties on the node. The fan speed sensor requires a
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * special handler, while the analog enclosure sensors all have similar
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * behavior and can be grouped together using a common method.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#include "ses.h"
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#include "disk.h"
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#include <string.h>
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic int ses_indicator_mode(topo_mod_t *, tnode_t *, topo_version_t,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *, nvlist_t **);
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic int ses_sensor_reading(topo_mod_t *, tnode_t *, topo_version_t,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *, nvlist_t **);
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic int ses_sensor_state(topo_mod_t *, tnode_t *, topo_version_t,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *, nvlist_t **);
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic int ses_psu_state(topo_mod_t *, tnode_t *, topo_version_t,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *, nvlist_t **);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#define SES_SUPP_WARN_UNDER 0x01
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#define SES_SUPP_WARN_OVER 0x02
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#define SES_SUPP_CRIT_UNDER 0x04
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#define SES_SUPP_CRIT_OVER 0x08
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrocktypedef struct ses_sensor_desc {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock int sd_type;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock int sd_units;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock const char *sd_propname;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock double sd_multiplier;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock} ses_sensor_desc_t;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#define TOPO_METH_SES_MODE_VERSION 0
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#define TOPO_METH_SES_READING_VERSION 0
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#define TOPO_METH_SES_STATE_VERSION 0
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#define TOPO_METH_SES_PSU_VERSION 0
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#define TOPO_METH_SES_READING_PROP "propname"
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#define TOPO_METH_SES_READING_MULT "multiplier"
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#define TOPO_METH_SES_STATE_PROP "propname"
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#define TOPO_METH_SES_MODE_PROP "property-name"
d91236fe104c7ea63142e053b22a39c8a30d304beschrock#define TOPO_METH_SES_MODE_ALTPROP "alternate-property"
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic const topo_method_t ses_indicator_methods[] = {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock { "ses_indicator_mode", TOPO_PROP_METH_DESC,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_METH_SES_MODE_VERSION, TOPO_STABILITY_INTERNAL,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_indicator_mode }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock};
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic const topo_method_t ses_sensor_methods[] = {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock { "ses_sensor_reading", TOPO_PROP_METH_DESC,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_METH_SES_READING_VERSION, TOPO_STABILITY_INTERNAL,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_sensor_reading },
d91236fe104c7ea63142e053b22a39c8a30d304beschrock { "ses_sensor_state", TOPO_PROP_METH_DESC,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_METH_SES_STATE_VERSION, TOPO_STABILITY_INTERNAL,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_sensor_state },
d91236fe104c7ea63142e053b22a39c8a30d304beschrock { "ses_psu_state", TOPO_PROP_METH_DESC,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_METH_SES_PSU_VERSION, TOPO_STABILITY_INTERNAL,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_psu_state },
d91236fe104c7ea63142e053b22a39c8a30d304beschrock};
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Get or set an indicator. This method is invoked with arguments indicating
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * the property to query to retrieve the value. Some elements (enclosures and
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * devices) support a request property that is distinct from an array-detected
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * property. Either of these conditions will result in the indicator being
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * lit, so we have to check both properties.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic int
d91236fe104c7ea63142e053b22a39c8a30d304beschrockses_indicator_mode(topo_mod_t *mod, tnode_t *tn, topo_version_t vers,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *in, nvlist_t **out)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock{
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_node_t *np;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *args, *pargs, *props;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock char *propname, *altprop;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock uint32_t mode;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock boolean_t current, altcurrent;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *nvl;
525b85dbd2fc64df4bd0092c1a2b0827dd8e1e89Eric Schrock ses_enum_target_t *tp = topo_node_getspecific(tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (vers > TOPO_METH_SES_MODE_VERSION)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_nvlist(in, TOPO_PROP_ARGS, &args) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_lookup_string(args, TOPO_METH_SES_MODE_PROP,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock &propname) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "invalid arguments to 'mode' method\n");
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_string(args, TOPO_METH_SES_MODE_ALTPROP,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock &altprop) != 0)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock altprop = NULL;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock if ((np = ses_node_lock(mod, tn)) == NULL) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to lookup ses node in 'mode' "
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "method\n");
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock verify((props = ses_node_props(np)) != NULL);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &pargs) == 0 &&
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_exists(pargs, TOPO_PROP_VAL_VAL)) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /* set operation */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_uint32(pargs, TOPO_PROP_VAL_VAL,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock &mode) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "invalid type for indicator "
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "mode property");
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock (void) topo_mod_seterrno(mod, EMOD_NVL_INVAL);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock goto error;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (mode != TOPO_LED_STATE_OFF && mode != TOPO_LED_STATE_ON) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "invalid indicator mode %d\n",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock mode);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock (void) topo_mod_seterrno(mod, EMOD_NVL_INVAL);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock goto error;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvl = NULL;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_boolean_value(nvl, propname,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock mode == TOPO_LED_STATE_ON ? B_TRUE : B_FALSE) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock (void) topo_mod_seterrno(mod, EMOD_NOMEM);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock goto error;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (ses_node_ctl(np, SES_CTL_OP_SETPROP, nvl) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to set indicator: %s\n",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_errmsg());
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock goto error;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
525b85dbd2fc64df4bd0092c1a2b0827dd8e1e89Eric Schrock tp->set_snaptime = 0;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock } else {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /* get operation */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_boolean_value(props,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock propname, &current) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to lookup %s in node "
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "properties\n", propname);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock (void) topo_mod_seterrno(mod, EMOD_METHOD_NOTSUP);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock goto error;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (altprop != NULL && nvlist_lookup_boolean_value(props,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock altprop, &altcurrent) == 0)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock current |= altcurrent;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock mode = current ? TOPO_LED_STATE_ON : TOPO_LED_STATE_OFF;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvl = NULL;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_string(nvl, TOPO_PROP_VAL_NAME,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_LED_MODE) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, mode) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock (void) topo_mod_seterrno(mod, EMOD_NOMEM);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock goto error;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock ses_node_unlock(mod, tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *out = nvl;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (0);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrockerror:
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock ses_node_unlock(mod, tn);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock}
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Read the given sensor value. This just looks up the value in the node
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * properties, and multiplies by a fixed value (determined when the method is
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * instantiated).
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic int
d91236fe104c7ea63142e053b22a39c8a30d304beschrockses_sensor_reading(topo_mod_t *mod, tnode_t *tn, topo_version_t vers,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *in, nvlist_t **out)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock{
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_node_t *np;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *args, *props;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock char *prop;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock double raw, multiplier;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock uint64_t current;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock int64_t scurrent;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *nvl;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (vers > TOPO_METH_SES_MODE_VERSION)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_nvlist(in, TOPO_PROP_ARGS, &args) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_lookup_string(args, TOPO_METH_SES_READING_PROP,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock &prop) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "invalid arguments to 'reading' method\n");
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_double(args, TOPO_METH_SES_READING_MULT,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock &multiplier) != 0)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock multiplier = 1;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock if ((np = ses_node_lock(mod, tn)) == NULL) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to lookup ses node in 'mode' "
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "method\n");
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock verify((props = ses_node_props(np)) != NULL);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_uint64(props, prop, &current) == 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock raw = (double)current;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock } else if (nvlist_lookup_int64(props, prop, &scurrent) == 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock raw = (double)scurrent;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock } else {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to lookup %s in node "
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "properties\n", prop);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock ses_node_unlock(mod, tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (topo_mod_seterrno(mod, EMOD_METHOD_NOTSUP));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock ses_node_unlock(mod, tn);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvl = NULL;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_string(nvl, TOPO_PROP_VAL_NAME,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_SENSOR_READING) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_DOUBLE) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_double(nvl, TOPO_PROP_VAL_VAL, raw * multiplier) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (topo_mod_seterrno(mod, EMOD_NOMEM));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *out = nvl;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (0);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock}
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Returns the current sensor state. This can be invoked for one of two
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * different types of sensors: threshold or discrete sensors. For discrete
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * sensors, we expect a name of a boolean property and indicate
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * asserted/deasserted based on that. For threshold sensors, we check for the
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * standard warning/critical properties and translate that into the appropriate
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * topo state.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*ARGSUSED*/
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic int
d91236fe104c7ea63142e053b22a39c8a30d304beschrockses_sensor_state(topo_mod_t *mod, tnode_t *tn, topo_version_t vers,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *in, nvlist_t **out)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock{
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *nvl, *args, *props;
6efb64ca6d97453babd6dae9c5c1f71ec3e53bedEric Schrock boolean_t value;
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock uint64_t status;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock uint32_t state;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_node_t *np;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock char *prop;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock if (nvlist_lookup_nvlist(in, TOPO_PROP_ARGS, &args) != 0) {
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock topo_mod_dprintf(mod,
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock "invalid arguments to 'state' method\n");
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock }
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock if ((np = ses_node_lock(mod, tn)) == NULL) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to lookup ses node in 'mode' "
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "method\n");
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock verify((props = ses_node_props(np)) != NULL);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock if (nvlist_lookup_uint64(props, SES_PROP_STATUS_CODE, &status) != 0)
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock status = SES_ESC_UNSUPPORTED;
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock state = 0;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_string(args, TOPO_METH_SES_STATE_PROP,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock &prop) == 0) {
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock /* discrete (fault) sensor */
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock
6efb64ca6d97453babd6dae9c5c1f71ec3e53bedEric Schrock if (status == SES_ESC_UNRECOVERABLE)
6efb64ca6d97453babd6dae9c5c1f71ec3e53bedEric Schrock state |= TOPO_SENSOR_STATE_GENERIC_FAIL_NONRECOV;
6efb64ca6d97453babd6dae9c5c1f71ec3e53bedEric Schrock else if (status == SES_ESC_CRITICAL)
6efb64ca6d97453babd6dae9c5c1f71ec3e53bedEric Schrock state |= TOPO_SENSOR_STATE_GENERIC_FAIL_CRITICAL;
6efb64ca6d97453babd6dae9c5c1f71ec3e53bedEric Schrock else if (nvlist_lookup_boolean_value(props, prop,
6efb64ca6d97453babd6dae9c5c1f71ec3e53bedEric Schrock &value) == 0 && value)
6efb64ca6d97453babd6dae9c5c1f71ec3e53bedEric Schrock state |= TOPO_SENSOR_STATE_GENERIC_FAIL_NONRECOV;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock else
6efb64ca6d97453babd6dae9c5c1f71ec3e53bedEric Schrock state |= TOPO_SENSOR_STATE_GENERIC_FAIL_DEASSERTED;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock } else {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /* threshold sensor */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_boolean_value(props,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock SES_PROP_WARN_UNDER, &value) == 0 && value)
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock state |= TOPO_SENSOR_STATE_THRESH_LOWER_NONCRIT;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_boolean_value(props,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock SES_PROP_WARN_OVER, &value) == 0 && value)
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock state |= TOPO_SENSOR_STATE_THRESH_UPPER_NONCRIT;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_boolean_value(props,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock SES_PROP_CRIT_UNDER, &value) == 0 && value)
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock state |= TOPO_SENSOR_STATE_THRESH_LOWER_CRIT;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_boolean_value(props,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock SES_PROP_CRIT_OVER, &value) == 0 && value)
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock state |= TOPO_SENSOR_STATE_THRESH_UPPER_CRIT;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock ses_node_unlock(mod, tn);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvl = NULL;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_string(nvl, TOPO_PROP_VAL_NAME,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_SENSOR_STATE) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, state) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (topo_mod_seterrno(mod, EMOD_NOMEM));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *out = nvl;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (0);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock}
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Read the status of a PSU. This is such a specialized operation that it has
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * its own method instead of trying to piggyback on ses_sensor_state(). We
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * use the following mapping to get to the standard topo power supply states:
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * acfail -> INPUT_LOST
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * dcfail -> INPUT_LOST
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * undervoltage -> INPUT_RANGE
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * overvoltage -> INPUT_RANGE_PRES
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * overcurrent -> INPUT_RANGE_PRES
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * overtemp -> (none)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * If we ever have a need for reading overtemp, we can expand the topo
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * representation for power supplies, but at the moment this seems unnecessary.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*ARGSUSED*/
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic int
d91236fe104c7ea63142e053b22a39c8a30d304beschrockses_psu_state(topo_mod_t *mod, tnode_t *tn, topo_version_t vers,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *in, nvlist_t **out)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock{
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *nvl, *props;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock boolean_t value;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock uint32_t state;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_node_t *np;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock if ((np = ses_node_lock(mod, tn)) == NULL) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to lookup ses node in 'mode' "
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "method\n");
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock verify((props = ses_node_props(np)) != NULL);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock state = 0;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if ((nvlist_lookup_boolean_value(props, SES_PSU_PROP_DC_FAIL,
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock &value) == 0 && value) ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock (nvlist_lookup_boolean_value(props, SES_PSU_PROP_AC_FAIL,
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock &value) == 0 && value))
d91236fe104c7ea63142e053b22a39c8a30d304beschrock state |= TOPO_SENSOR_STATE_POWER_SUPPLY_INPUT_LOST;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_boolean_value(props, SES_PSU_PROP_DC_UNDER_VOLTAGE,
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock &value) == 0 && value)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock state |= TOPO_SENSOR_STATE_POWER_SUPPLY_INPUT_RANGE;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if ((nvlist_lookup_boolean_value(props, SES_PSU_PROP_DC_OVER_VOLTAGE,
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock &value) == 0 && value) ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock (nvlist_lookup_boolean_value(props, SES_PSU_PROP_DC_OVER_CURRENT,
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock &value) == 0 && value))
d91236fe104c7ea63142e053b22a39c8a30d304beschrock state |= TOPO_SENSOR_STATE_POWER_SUPPLY_INPUT_RANGE_PRES;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock ses_node_unlock(mod, tn);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvl = NULL;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_string(nvl, TOPO_PROP_VAL_NAME,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_SENSOR_STATE) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, state) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (topo_mod_seterrno(mod, EMOD_NOMEM));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock *out = nvl;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (0);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock}
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Create a facility node, either a sensor or an indicator.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic tnode_t *
d91236fe104c7ea63142e053b22a39c8a30d304beschrockses_add_fac_common(topo_mod_t *mod, tnode_t *pnode, const char *name,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock const char *type, uint64_t nodeid)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock{
d91236fe104c7ea63142e053b22a39c8a30d304beschrock tnode_t *tn;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_pgroup_info_t pgi;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock int err;
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock ses_enum_target_t *stp = topo_node_getspecific(pnode);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if ((tn = topo_node_facbind(mod, pnode, name, type)) == NULL) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to bind facility node %s\n",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock name);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (NULL);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock stp->set_refcount++;
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock topo_node_setspecific(tn, stp);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock pgi.tpi_name = TOPO_PGROUP_FACILITY;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock pgi.tpi_namestab = TOPO_STABILITY_PRIVATE;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock pgi.tpi_datastab = TOPO_STABILITY_PRIVATE;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock pgi.tpi_version = 1;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_pgroup_create(tn, &pgi, &err) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to create facility property "
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "group: %s\n", topo_strerror(err));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_node_unbind(tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (NULL);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * We need the node-id property for each facility node.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock pgi.tpi_name = TOPO_PGROUP_SES;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock pgi.tpi_namestab = TOPO_STABILITY_PRIVATE;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock pgi.tpi_datastab = TOPO_STABILITY_PRIVATE;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock pgi.tpi_version = TOPO_VERSION;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_pgroup_create(tn, &pgi, &err) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to create ses property "
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "group: %s\n", topo_strerror(err));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_node_unbind(tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (NULL);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_prop_set_uint64(tn, TOPO_PGROUP_SES,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_PROP_NODE_ID, TOPO_PROP_IMMUTABLE,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nodeid, &err) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "failed to create property %s: %s\n",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_PROP_NODE_ID, topo_strerror(err));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_node_unbind(tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (NULL);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock}
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Add an indicator. This can be represented by a single property, or by the
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * union of two elements when SES is capable of distinguishing between
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * requested failure and detected failure.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic int
d91236fe104c7ea63142e053b22a39c8a30d304beschrockses_add_indicator(topo_mod_t *mod, tnode_t *pnode, uint64_t nodeid,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock int type, const char *name, const char *propname, const char *altprop)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock{
d91236fe104c7ea63142e053b22a39c8a30d304beschrock tnode_t *tn;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock int err;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *nvl;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /* create facility node and add methods */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if ((tn = ses_add_fac_common(mod, pnode, name,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_FAC_TYPE_INDICATOR, nodeid)) == NULL)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_method_register(mod, tn, ses_indicator_methods) < 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to register facility methods\n");
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_node_unbind(tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /* set standard properties */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_prop_set_uint32(tn, TOPO_PGROUP_FACILITY,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_FACILITY_TYPE, TOPO_PROP_IMMUTABLE, type, &err) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "failed to set facility node properties: %s\n",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_strerror(err));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_node_unbind(tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /* 'mode' property */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvl = NULL;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_string(nvl, TOPO_METH_SES_MODE_PROP,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock propname) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock (altprop != NULL && nvlist_add_string(nvl,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_METH_SES_MODE_ALTPROP, altprop) != 0)) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to setup method arguments\n");
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_node_unbind(tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (topo_mod_seterrno(mod, EMOD_NOMEM));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_prop_method_register(tn, TOPO_PGROUP_FACILITY,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_LED_MODE, TOPO_TYPE_UINT32, "ses_indicator_mode",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvl, &err) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to register reading method: %s\n",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_strerror(err));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_prop_setmutable(tn, TOPO_PGROUP_FACILITY,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_LED_MODE, &err) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to set property as mutable: %s\n",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_strerror(err));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (0);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock}
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic tnode_t *
d91236fe104c7ea63142e053b22a39c8a30d304beschrockses_add_sensor_common(topo_mod_t *mod, tnode_t *pnode, uint64_t nodeid,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock const char *name, const char *class, int type)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock{
d91236fe104c7ea63142e053b22a39c8a30d304beschrock tnode_t *tn;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock int err;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /* create facility node and add methods */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if ((tn = ses_add_fac_common(mod, pnode, name,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_FAC_TYPE_SENSOR, nodeid)) == NULL)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (NULL);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_method_register(mod, tn, ses_sensor_methods) < 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to register facility methods\n");
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_node_unbind(tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (NULL);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /* set standard properties */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_prop_set_string(tn, TOPO_PGROUP_FACILITY,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_SENSOR_CLASS, TOPO_PROP_IMMUTABLE,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock class, &err) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_prop_set_uint32(tn, TOPO_PGROUP_FACILITY,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_FACILITY_TYPE, TOPO_PROP_IMMUTABLE,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock type, &err) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "failed to set facility node properties: %s\n",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_strerror(err));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_node_unbind(tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (NULL);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock}
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Add an analog (threshold) sensor to the enclosure. This is used for fan
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * speed, voltage, current, and temperature sensors.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic int
d91236fe104c7ea63142e053b22a39c8a30d304beschrockses_add_sensor(topo_mod_t *mod, tnode_t *pnode, uint64_t nodeid,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock const char *name, const ses_sensor_desc_t *sdp)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock{
d91236fe104c7ea63142e053b22a39c8a30d304beschrock tnode_t *tn;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock int err;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *nvl;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if ((tn = ses_add_sensor_common(mod, pnode, nodeid, name,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_SENSOR_CLASS_THRESHOLD, sdp->sd_type)) == NULL)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_prop_set_uint32(tn, TOPO_PGROUP_FACILITY,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_SENSOR_UNITS, TOPO_PROP_IMMUTABLE, sdp->sd_units, &err) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "failed to set facility node properties: %s\n",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_strerror(err));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_node_unbind(tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /* 'reading' property */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvl = NULL;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_string(nvl, TOPO_METH_SES_READING_PROP,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sdp->sd_propname) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock (sdp->sd_multiplier != 0 &&
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_double(nvl, TOPO_METH_SES_READING_MULT,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sdp->sd_multiplier) != 0)) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to setup method arguments\n");
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_node_unbind(tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_prop_method_register(tn, TOPO_PGROUP_FACILITY,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_SENSOR_READING, TOPO_TYPE_DOUBLE, "ses_sensor_reading",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvl, &err) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to register reading method: %s\n",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_strerror(err));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to setup method arguments\n");
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_node_unbind(tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /* 'state' property */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_prop_method_register(tn, TOPO_PGROUP_FACILITY,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_SENSOR_STATE, TOPO_TYPE_UINT32, "ses_sensor_state",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvl, &err) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to register state method: %s\n",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_strerror(err));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (0);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock}
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Add a discrete sensor for simple boolean values. This is used to indicate
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * externally-detected failures for fans, bays, and enclosures.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic int
d91236fe104c7ea63142e053b22a39c8a30d304beschrockses_add_discrete(topo_mod_t *mod, tnode_t *pnode, uint64_t nodeid,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock const char *name, const char *prop)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock{
d91236fe104c7ea63142e053b22a39c8a30d304beschrock tnode_t *tn;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock int err;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *nvl;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if ((tn = ses_add_sensor_common(mod, pnode, nodeid, name,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_SENSOR_CLASS_DISCRETE,
6efb64ca6d97453babd6dae9c5c1f71ec3e53bedEric Schrock TOPO_SENSOR_TYPE_GENERIC_FAILURE)) == NULL)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvl = NULL;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_add_string(nvl, TOPO_METH_SES_STATE_PROP, prop) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to setup method arguments\n");
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_node_unbind(tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /* 'state' property */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_prop_method_register(tn, TOPO_PGROUP_FACILITY,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_SENSOR_STATE, TOPO_TYPE_UINT32, "ses_sensor_state",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvl, &err) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to register state method: %s\n",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_strerror(err));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (0);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock}
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*ARGSUSED*/
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic int
d91236fe104c7ea63142e053b22a39c8a30d304beschrockses_add_psu_status(topo_mod_t *mod, tnode_t *pnode, uint64_t nodeid)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock{
d91236fe104c7ea63142e053b22a39c8a30d304beschrock tnode_t *tn;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock int err;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *nvl;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /* create facility node and add methods */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if ((tn = ses_add_sensor_common(mod, pnode, nodeid, "status",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_SENSOR_CLASS_DISCRETE,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_SENSOR_TYPE_POWER_SUPPLY)) == NULL)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to setup method arguments\n");
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_node_unbind(tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /* 'state' property */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (topo_prop_method_register(tn, TOPO_PGROUP_FACILITY,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock TOPO_SENSOR_STATE, TOPO_TYPE_UINT32, "ses_psu_state",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvl, &err) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_dprintf(mod, "failed to register state method: %s\n",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_strerror(err));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_free(nvl);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (0);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock}
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*ARGSUSED*/
d91236fe104c7ea63142e053b22a39c8a30d304beschrockint
d91236fe104c7ea63142e053b22a39c8a30d304beschrockses_node_enum_facility(topo_mod_t *mod, tnode_t *tn, topo_version_t vers,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *in, nvlist_t **out)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock{
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_node_t *np;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *props;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock uint64_t type, nodeid;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_sensor_desc_t sd = { 0 };
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock if ((np = ses_node_lock(mod, tn)) == NULL)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock assert(ses_node_type(np) == SES_NODE_ELEMENT);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nodeid = ses_node_id(np);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock verify((props = ses_node_props(np)) != NULL);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock verify(nvlist_lookup_uint64(props, SES_PROP_ELEMENT_TYPE, &type) == 0);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (type != SES_ET_DEVICE && type != SES_ET_ARRAY_DEVICE &&
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock type != SES_ET_COOLING && type != SES_ET_POWER_SUPPLY) {
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock ses_node_unlock(mod, tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (0);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Every element supports an 'ident' indicator. All elements also
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * support a 'fail' indicator, but the properties used to represent
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * this condition differs between elements.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (ses_add_indicator(mod, tn, nodeid, TOPO_LED_TYPE_LOCATE, "ident",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock SES_PROP_IDENT, NULL) != 0)
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock goto error;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock switch (type) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock case SES_ET_DEVICE:
d91236fe104c7ea63142e053b22a39c8a30d304beschrock case SES_ET_ARRAY_DEVICE:
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Disks support an additional 'ok2rm' indicator, as well as
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * externally detected 'fail' sensor.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (ses_add_indicator(mod, tn, nodeid, TOPO_LED_TYPE_SERVICE,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "fail", SES_DEV_PROP_FAULT_RQSTD,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock SES_DEV_PROP_FAULT_SENSED) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_add_indicator(mod, tn, nodeid, TOPO_LED_TYPE_OK2RM,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "ok2rm", SES_PROP_RMV, SES_PROP_RMV) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_add_discrete(mod, tn, nodeid, "fault",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock SES_DEV_PROP_FAULT_SENSED) != 0)
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock goto error;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock break;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock case SES_ET_COOLING:
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Add the fan speed sensor, and a discrete sensor for
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * detecting failure.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
7bced3d7aec4d3a35bbb35571fbbfb990582579aEric Schrock sd.sd_type = TOPO_SENSOR_TYPE_THRESHOLD_STATE;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sd.sd_units = TOPO_SENSOR_UNITS_RPM;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sd.sd_propname = SES_COOLING_PROP_FAN_SPEED;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (ses_add_indicator(mod, tn, nodeid, TOPO_LED_TYPE_SERVICE,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "fail", SES_PROP_FAIL, NULL) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_add_sensor(mod, tn, nodeid, "speed", &sd) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_add_discrete(mod, tn, nodeid, "fault",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock SES_PROP_OFF) != 0)
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock goto error;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock break;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock case SES_ET_POWER_SUPPLY:
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * For power supplies, we have a number of different sensors:
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * acfail, dcfail, overtemp, undervoltate, overvoltage,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * and overcurrent. Rather than expose these all as individual
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * sensors, we lump them together into a 'status' sensor of
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * type TOPO_SENSOR_TYPE_POWER_SUPPLY and export the
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * appropriate status flags as defined by the libtopo standard.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (ses_add_indicator(mod, tn, nodeid, TOPO_LED_TYPE_SERVICE,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "fail", SES_PROP_FAIL, NULL) != 0)
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock goto error;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (ses_add_psu_status(mod, tn, nodeid) != 0)
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock goto error;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock break;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock default:
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (0);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock ses_node_unlock(mod, tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (0);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrockerror:
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock ses_node_unlock(mod, tn);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock}
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Add enclosure-wide sensors (temperature, voltage, and current) beneath the
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * given aggregate.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrockstatic int
d91236fe104c7ea63142e053b22a39c8a30d304beschrockses_add_enclosure_sensors(topo_mod_t *mod, tnode_t *tn, ses_node_t *agg,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock uint64_t type)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock{
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_node_t *child;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock const char *defaultname;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock char *desc, *name;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock char rawname[64];
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *props, *aprops;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock uint64_t index, nodeid;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_sensor_desc_t sd = { 0 };
d91236fe104c7ea63142e053b22a39c8a30d304beschrock size_t len;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock switch (type) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock case SES_ET_TEMPERATURE_SENSOR:
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sd.sd_type = TOPO_SENSOR_TYPE_TEMP;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sd.sd_units = TOPO_SENSOR_UNITS_DEGREES_C;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sd.sd_propname = SES_TEMP_PROP_TEMP;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock defaultname = "temperature";
d91236fe104c7ea63142e053b22a39c8a30d304beschrock break;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock case SES_ET_VOLTAGE_SENSOR:
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sd.sd_type = TOPO_SENSOR_TYPE_VOLTAGE;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sd.sd_units = TOPO_SENSOR_UNITS_VOLTS;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sd.sd_propname = SES_VS_PROP_VOLTAGE_MV;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sd.sd_multiplier = 0.001;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock defaultname = "voltage";
d91236fe104c7ea63142e053b22a39c8a30d304beschrock break;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock case SES_ET_CURRENT_SENSOR:
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sd.sd_type = TOPO_SENSOR_TYPE_CURRENT;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sd.sd_units = TOPO_SENSOR_UNITS_AMPS;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sd.sd_propname = SES_CS_PROP_CURRENT_MA;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock sd.sd_multiplier = 0.001;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock defaultname = "current";
d91236fe104c7ea63142e053b22a39c8a30d304beschrock break;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock default:
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (0);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock aprops = ses_node_props(agg);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock for (child = ses_node_child(agg); child != NULL;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock child = ses_node_sibling(child)) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * The only tricky part here is getting the name for the
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * sensor, where we follow the algorithm of the standard
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * elements.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock props = ses_node_props(child);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nodeid = ses_node_id(child);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_uint64(props, SES_PROP_ELEMENT_CLASS_INDEX,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock &index) != 0)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock continue;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_string(props, SES_PROP_DESCRIPTION,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock &desc) == 0 && desc[0] != '\0') {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock (void) strlcpy(rawname, desc, sizeof (rawname));
d91236fe104c7ea63142e053b22a39c8a30d304beschrock } else {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_string(aprops,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock SES_PROP_CLASS_DESCRIPTION, &desc) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock desc[0] == '\0')
d91236fe104c7ea63142e053b22a39c8a30d304beschrock desc = (char *)defaultname;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock len = strlen(desc);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock while (len > 0 && desc[len - 1] == ' ')
d91236fe104c7ea63142e053b22a39c8a30d304beschrock len--;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock (void) snprintf(rawname, sizeof (rawname),
d91236fe104c7ea63142e053b22a39c8a30d304beschrock "%.*s %llu", len, desc, index);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if ((name = disk_auth_clean(mod, rawname)) == NULL)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (ses_add_sensor(mod, tn, nodeid, name, &sd) != 0) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_strfree(mod, name);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock topo_mod_strfree(mod, name);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (0);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock}
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock/*ARGSUSED*/
d91236fe104c7ea63142e053b22a39c8a30d304beschrockint
d91236fe104c7ea63142e053b22a39c8a30d304beschrockses_enc_enum_facility(topo_mod_t *mod, tnode_t *tn, topo_version_t vers,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *in, nvlist_t **out)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock{
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_node_t *np, *agg;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nvlist_t *aprops;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock uint64_t type, nodeid;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock if ((np = ses_node_lock(mod, tn)) == NULL)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock assert(ses_node_type(np) == SES_NODE_ENCLOSURE);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock nodeid = ses_node_id(np);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * 'ident' and 'fail' LEDs, and 'fault' sensor.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (ses_add_indicator(mod, tn, nodeid, TOPO_LED_TYPE_LOCATE, "ident",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock SES_PROP_IDENT, NULL) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_add_indicator(mod, tn, nodeid, TOPO_LED_TYPE_SERVICE, "fail",
d91236fe104c7ea63142e053b22a39c8a30d304beschrock SES_PROP_FAIL_REQ, SES_PROP_FAIL) != 0 ||
d91236fe104c7ea63142e053b22a39c8a30d304beschrock ses_add_discrete(mod, tn, nodeid, "fault", SES_PROP_FAIL) != 0)
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock goto error;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock /*
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * Environmental sensors (temperature, voltage, current). We have no
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * way of knowing if any of these sensors correspond to a particular
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * element, so we just attach them to the enclosure as a whole. In the
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * future, some vendor-specific libses plugin knowledge could let us
d91236fe104c7ea63142e053b22a39c8a30d304beschrock * make this correlation clearer.
d91236fe104c7ea63142e053b22a39c8a30d304beschrock */
d91236fe104c7ea63142e053b22a39c8a30d304beschrock for (agg = ses_node_child(np); agg != NULL;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock agg = ses_node_sibling(agg)) {
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (ses_node_type(agg) != SES_NODE_AGGREGATE)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock continue;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock verify((aprops = ses_node_props(agg)) != NULL);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (nvlist_lookup_uint64(aprops, SES_PROP_ELEMENT_TYPE,
d91236fe104c7ea63142e053b22a39c8a30d304beschrock &type) != 0)
d91236fe104c7ea63142e053b22a39c8a30d304beschrock continue;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
d91236fe104c7ea63142e053b22a39c8a30d304beschrock if (ses_add_enclosure_sensors(mod, tn, agg, type) != 0)
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock goto error;
d91236fe104c7ea63142e053b22a39c8a30d304beschrock }
d91236fe104c7ea63142e053b22a39c8a30d304beschrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock ses_node_unlock(mod, tn);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock return (0);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock
0b32bb8bde09d49065e395405874016d9a227861Eric Schrockerror:
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock ses_node_unlock(mod, tn);
0b32bb8bde09d49065e395405874016d9a227861Eric Schrock return (-1);
d91236fe104c7ea63142e053b22a39c8a30d304beschrock}