7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * CDDL HEADER START
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * The contents of this file are subject to the terms of the
a62bb709433c06fe335121c07822de4984bdcb84cindi * Common Development and Distribution License (the "License").
a62bb709433c06fe335121c07822de4984bdcb84cindi * You may not use this file except in compliance with the License.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * or http://www.opensolaris.org/os/licensing.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * See the License for the specific language governing permissions
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * and limitations under the License.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * When distributing Covered Code, include this CDDL HEADER in each
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * If applicable, add the following below this CDDL HEADER, with the
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * fields enclosed by brackets "[]" replaced with your own identifying
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * information: Portions Copyright [yyyy] [name of copyright owner]
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * CDDL HEADER END
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Use is subject to license terms.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <pthread.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <assert.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <errno.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <dirent.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <limits.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <alloca.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <unistd.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <stdio.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <strings.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <topo_mod.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <topo_error.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <topo_module.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <topo_subr.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <topo_tree.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
c40d7343efa60b18ad1ceb316eb337caeea79046cinditopo_imethod_t *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecinditopo_method_lookup(tnode_t *node, const char *name)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_imethod_t *mp;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (mp = topo_list_next(&node->tn_methods); mp != NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mp = topo_list_next(mp)) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (strcmp(name, mp->tim_name) == 0) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_node_unlock(node);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (mp);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj/*
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * Simple API to determine if the specified node supports a given topo method
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * (specified by the method name and version). Returns true if supported, false
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * otherwise.
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj */
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robjboolean_t
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robjtopo_method_supported(tnode_t *node, const char *name, topo_version_t vers)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj{
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_imethod_t *mp;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_node_lock(node);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj for (mp = topo_list_next(&node->tn_methods); mp != NULL;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj mp = topo_list_next(mp)) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if ((strcmp(name, mp->tim_name) == 0) &&
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj (vers == mp->tim_version)) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_node_unlock(node);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (B_TRUE);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_node_unlock(node);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (B_FALSE);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj}
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic void
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecinditopo_method_enter(topo_imethod_t *mp)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) pthread_mutex_lock(&mp->tim_lock);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi while (mp->tim_busy != 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) pthread_cond_wait(&mp->tim_cv, &mp->tim_lock);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi ++mp->tim_busy;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) pthread_mutex_unlock(&mp->tim_lock);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic void
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecinditopo_method_exit(topo_imethod_t *mp)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) pthread_mutex_lock(&mp->tim_lock);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi --mp->tim_busy;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi assert(mp->tim_busy == 0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
a62bb709433c06fe335121c07822de4984bdcb84cindi (void) pthread_cond_broadcast(&mp->tim_cv);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) pthread_mutex_unlock(&mp->tim_lock);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiset_methregister_error(topo_mod_t *mod, tnode_t *node, topo_imethod_t *mp,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int err)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (mp != NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_list_delete(&node->tn_methods, mp);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (mp->tim_name != NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_strfree(mod, mp->tim_name);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (mp->tim_desc != NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_strfree(mod, mp->tim_desc);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_free(mod, mp, sizeof (topo_imethod_t));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_node_unlock(node);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_dprintf(mod->tm_hdl, TOPO_DBG_ERR,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi "method registration failed for %s: %s\n",
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mod->tm_name, topo_strerror(err));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (topo_mod_seterrno(mod, err));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiint
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecinditopo_method_register(topo_mod_t *mod, tnode_t *node, const topo_method_t *mp)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_imethod_t *imp;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi const topo_method_t *meth;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Initialize module methods
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (meth = &mp[0]; meth->tm_name != NULL; meth++) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_node_lock(node);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (topo_method_lookup(node, meth->tm_name) != NULL) {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_node_unlock(node);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi continue;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (meth->tm_stability < TOPO_STABILITY_INTERNAL ||
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi meth->tm_stability > TOPO_STABILITY_MAX ||
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi meth->tm_func == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (set_methregister_error(mod, node, NULL,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi ETOPO_METHOD_INVAL));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi imp = topo_mod_zalloc(mod, sizeof (topo_imethod_t));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (imp == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (set_methregister_error(mod, node, imp,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi ETOPO_METHOD_NOMEM));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if ((imp->tim_name = topo_mod_strdup(mod, meth->tm_name))
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (set_methregister_error(mod, node, imp,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi ETOPO_METHOD_NOMEM));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if ((imp->tim_desc = topo_mod_strdup(mod, meth->tm_desc))
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (set_methregister_error(mod, node, imp,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi ETOPO_METHOD_NOMEM));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi imp->tim_stability = meth->tm_stability;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi imp->tim_version = meth->tm_version;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi imp->tim_func = meth->tm_func;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi imp->tim_mod = mod;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_list_append(&node->tn_methods, imp);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_node_unlock(node);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_dprintf(mod->tm_hdl, TOPO_DBG_MODSVC,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi "registered module %s method "
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi "%s for %s=%d\n", mod->tm_name, imp->tim_name,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_node_name(node), topo_node_instance(node));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindivoid
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecinditopo_method_unregister(topo_mod_t *mod, tnode_t *node, const char *name)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_imethod_t *mp;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_node_lock(node);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (mp = topo_list_next(&node->tn_methods); mp != NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mp = topo_list_next(mp)) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (strcmp(name, mp->tim_name) == 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi break;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (mp == NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_node_unlock(node);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_list_delete(&node->tn_methods, mp);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_node_unlock(node);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (mp->tim_name != NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_strfree(mod, mp->tim_name);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (mp->tim_desc != NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_strfree(mod, mp->tim_desc);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_free(mod, mp, sizeof (topo_imethod_t));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindivoid
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecinditopo_method_unregister_all(topo_mod_t *mod, tnode_t *node)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_imethod_t *mp;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_node_lock(node);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi while ((mp = topo_list_next(&node->tn_methods)) != NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_list_delete(&node->tn_methods, mp);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (mp->tim_name != NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_strfree(mod, mp->tim_name);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (mp->tim_desc != NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_strfree(mod, mp->tim_desc);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_free(mod, mp, sizeof (topo_imethod_t));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_node_unlock(node);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiint
c40d7343efa60b18ad1ceb316eb337caeea79046cinditopo_method_call(tnode_t *node, const char *method,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_version_t version, nvlist_t *in, nvlist_t **out, int *err)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock int rc, save;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_imethod_t *mp;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (mp = topo_list_next(&node->tn_methods); mp != NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi mp = topo_list_next(mp)) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (strcmp(method, mp->tim_name) != 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi continue;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (version < mp->tim_version) {
4557a2a1868181b517f5dfe61ba6eeba58edf4c0robj *err = ETOPO_METHOD_VEROLD;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (-1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi } else if (version > mp->tim_version) {
4557a2a1868181b517f5dfe61ba6eeba58edf4c0robj *err = ETOPO_METHOD_VERNEW;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (-1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_method_enter(mp);
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock save = mp->tim_mod->tm_errno;
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock mp->tim_mod->tm_errno = 0;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if ((rc = mp->tim_func(mp->tim_mod, node, version, in, out))
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi < 0) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (mp->tim_mod->tm_errno == 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *err = ETOPO_METHOD_FAIL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi else
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *err = mp->tim_mod->tm_errno;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock mp->tim_mod->tm_errno = save;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_method_exit(mp);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (rc);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *err = ETOPO_METHOD_NOTSUP;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (-1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindiint
c40d7343efa60b18ad1ceb316eb337caeea79046cinditopo_method_invoke(tnode_t *node, const char *method,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_version_t version, nvlist_t *in, nvlist_t **out, int *err)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi{
c40d7343efa60b18ad1ceb316eb337caeea79046cindi int rc;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_node_hold(node);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi rc = topo_method_call(node, method, version, in, out, err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_node_rele(node);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (rc);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi}
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnstonstruct sensor_errinfo
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston{
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston boolean_t se_predictive;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston boolean_t se_nonrecov;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston uint32_t se_src;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston};
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnstonstatic boolean_t
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnstontopo_sensor_failed(int32_t type, uint32_t state, struct sensor_errinfo *seinfo)
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston{
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston boolean_t failed;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston failed = B_FALSE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston /*
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * Unless the sensor explicitely says otherwise, all failures are
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * non-recoverable, hard failures, coming from an unknown source.
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston */
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston seinfo->se_predictive = B_FALSE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston seinfo->se_nonrecov = B_TRUE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston seinfo->se_src = TOPO_SENSOR_ERRSRC_UNKNOWN;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston switch (type) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston case TOPO_SENSOR_TYPE_THRESHOLD_STATE:
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (state & (TOPO_SENSOR_STATE_THRESH_LOWER_NONREC |
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston TOPO_SENSOR_STATE_THRESH_UPPER_NONREC)) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston failed = B_TRUE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston } else if (state & (TOPO_SENSOR_STATE_THRESH_LOWER_CRIT |
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston TOPO_SENSOR_STATE_THRESH_UPPER_CRIT)) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston failed = B_TRUE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston seinfo->se_nonrecov = B_FALSE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston }
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston break;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston case TOPO_SENSOR_TYPE_POWER_SUPPLY:
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (state & TOPO_SENSOR_STATE_POWER_SUPPLY_PREDFAIL) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston failed = B_TRUE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston seinfo->se_predictive = B_TRUE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston seinfo->se_src = TOPO_SENSOR_ERRSRC_INTERNAL;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston } else if (state & TOPO_SENSOR_STATE_POWER_SUPPLY_FAILURE) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston failed = B_TRUE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston seinfo->se_src = TOPO_SENSOR_ERRSRC_INTERNAL;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston } else if (state &
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston (TOPO_SENSOR_STATE_POWER_SUPPLY_INPUT_LOST |
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston TOPO_SENSOR_STATE_POWER_SUPPLY_INPUT_RANGE |
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston TOPO_SENSOR_STATE_POWER_SUPPLY_INPUT_RANGE_PRES)) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston seinfo->se_src = TOPO_SENSOR_ERRSRC_EXTERNAL;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston failed = B_TRUE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston }
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston break;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston case TOPO_SENSOR_TYPE_GENERIC_FAILURE:
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (state & TOPO_SENSOR_STATE_GENERIC_FAIL_NONRECOV) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston failed = B_TRUE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston } else if (state & TOPO_SENSOR_STATE_GENERIC_FAIL_CRITICAL) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston failed = B_TRUE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston seinfo->se_nonrecov = B_FALSE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston }
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston break;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston case TOPO_SENSOR_TYPE_GENERIC_OK:
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (state & TOPO_SENSOR_STATE_GENERIC_OK_DEASSERTED)
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston failed = B_TRUE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston break;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston case TOPO_SENSOR_TYPE_GENERIC_PREDFAIL:
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (state & TOPO_SENSOR_STATE_GENERIC_PREDFAIL_ASSERTED) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston failed = B_TRUE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston seinfo->se_predictive = B_TRUE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston }
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston break;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston }
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston return (failed);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston}
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston/*
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * Determine whether there are any sensors indicating failure. This function
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * is used internally to determine whether a given component is usable, as well
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * by external monitoring software that wants additional information such as
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * which sensors indicated failure. The return value is an nvlist of nvlists
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * indexed by sensor name, each entry with the following contents:
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston *
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * type, state, units, reading
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston *
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * Identical to sensor node.
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston *
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * nonrecov
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston *
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * Boolean value that is set to indicate that the error is
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * non-recoverable (the unit is out of service). The default is
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * critical failure, which indicates a fault but the unit is still
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston * operating.
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston */
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston/*ARGSUSED*/
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnstonint
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnstontopo_method_sensor_failure(topo_mod_t *mod, tnode_t *node,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston topo_version_t version, nvlist_t *in, nvlist_t **out)
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston{
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston const char *name = topo_node_name(node);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston topo_faclist_t faclist, *fp;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston int err;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvlist_t *nvl, *props, *propval, *tmp;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston int ret = -1;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston uint32_t type, state, units;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvpair_t *elem;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston double reading;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston char *propname;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston boolean_t has_reading;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston struct sensor_errinfo seinfo;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (strcmp(name, PSU) != 0 && strcmp(name, FAN) != 0)
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston return (topo_mod_seterrno(mod, ETOPO_METHOD_NOTSUP));
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (topo_node_facility(mod->tm_hdl, node, TOPO_FAC_TYPE_SENSOR,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston TOPO_FAC_TYPE_ANY, &faclist, &err) != 0)
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston return (topo_mod_seterrno(mod, ETOPO_METHOD_NOTSUP));
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0)
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston goto error;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston for (fp = topo_list_next(&faclist.tf_list); fp != NULL;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston fp = topo_list_next(fp)) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (topo_prop_getpgrp(fp->tf_node, TOPO_PGROUP_FACILITY,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston &props, &err) != 0) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvlist_free(nvl);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston goto error;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston }
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston type = state = units = 0;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston reading = 0;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston has_reading = B_FALSE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston elem = NULL;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (strcmp(nvpair_name(elem), TOPO_PROP_VAL) != 0 ||
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvpair_type(elem) != DATA_TYPE_NVLIST)
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston continue;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston (void) nvpair_value_nvlist(elem, &propval);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (nvlist_lookup_string(propval,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston TOPO_PROP_VAL_NAME, &propname) != 0)
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston continue;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (strcmp(propname, TOPO_FACILITY_TYPE) == 0) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston (void) nvlist_lookup_uint32(propval,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston TOPO_PROP_VAL_VAL, &type);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston } else if (strcmp(propname, TOPO_SENSOR_STATE) == 0) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston (void) nvlist_lookup_uint32(propval,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston TOPO_PROP_VAL_VAL, &state);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston } else if (strcmp(propname, TOPO_SENSOR_UNITS) == 0) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston (void) nvlist_lookup_uint32(propval,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston TOPO_PROP_VAL_VAL, &units);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston } else if (strcmp(propname, TOPO_SENSOR_READING) == 0) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston has_reading = B_TRUE;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston (void) nvlist_lookup_double(propval,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston TOPO_PROP_VAL_VAL, &reading);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston }
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston }
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (topo_sensor_failed(type, state, &seinfo)) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston tmp = NULL;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (topo_mod_nvalloc(mod, &tmp, NV_UNIQUE_NAME) != 0 ||
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvlist_add_uint32(tmp, TOPO_FACILITY_TYPE,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston type) != 0 ||
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvlist_add_uint32(tmp, TOPO_SENSOR_STATE,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston state) != 0 ||
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvlist_add_uint32(tmp, TOPO_SENSOR_UNITS,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston units) != 0 ||
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvlist_add_boolean_value(tmp,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston "nonrecov", seinfo.se_nonrecov) != 0 ||
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvlist_add_boolean_value(tmp,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston "predictive", seinfo.se_predictive) != 0 ||
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvlist_add_uint32(tmp, "source",
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston seinfo.se_src) != 0 ||
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston (has_reading && nvlist_add_double(tmp,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston TOPO_SENSOR_READING, reading) != 0) ||
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvlist_add_nvlist(nvl, topo_node_name(fp->tf_node),
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston tmp) != 0) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvlist_free(props);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvlist_free(tmp);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvlist_free(nvl);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston ret = topo_mod_seterrno(mod,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston ETOPO_METHOD_NOMEM);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston goto error;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston }
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvlist_free(tmp);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston }
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston nvlist_free(props);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston }
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston *out = nvl;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston ret = 0;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnstonerror:
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston while ((fp = topo_list_next(&faclist.tf_list)) != NULL) {
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston topo_list_delete(&faclist.tf_list, fp);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston topo_mod_free(mod, fp, sizeof (topo_faclist_t));
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston }
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston return (ret);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston}