2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj/*
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * CDDL HEADER START
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj *
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * The contents of this file are subject to the terms of the
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * Common Development and Distribution License (the "License").
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * You may not use this file except in compliance with the License.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj *
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * or http://www.opensolaris.org/os/licensing.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * See the License for the specific language governing permissions
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * and limitations under the License.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj *
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * When distributing Covered Code, include this CDDL HEADER in each
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * If applicable, add the following below this CDDL HEADER, with the
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * fields enclosed by brackets "[]" replaced with your own identifying
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * information: Portions Copyright [yyyy] [name of copyright owner]
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj *
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * CDDL HEADER END
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj/*
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj#include <assert.h>
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj#include <fm/libtopo.h>
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj#include <fm/topo_mod.h>
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj#include <sys/fm/protocol.h>
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj#include <string.h>
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj#define TOPO_PGROUP_IPMI "ipmi"
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj#define TOPO_PROP_IPMI_ENTITY_REF "entity_ref"
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj#define TOPO_PROP_IPMI_ENTITY_PRESENT "entity_present"
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjtypedef struct ipmi_enum_data {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_t *ed_mod;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj tnode_t *ed_pnode;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj const char *ed_name;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj char *ed_label;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj uint8_t ed_entity;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_instance_t ed_instance;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj boolean_t ed_hasfru;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj} ipmi_enum_data_t;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjstatic int ipmi_present(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj nvlist_t **);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjstatic int ipmi_enum(topo_mod_t *, tnode_t *, const char *,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_instance_t, topo_instance_t, void *, void *);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjstatic int ipmi_post_process(topo_mod_t *, tnode_t *);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjextern int ipmi_fru_label(topo_mod_t *mod, tnode_t *node,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_version_t vers, nvlist_t *in, nvlist_t **out);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjextern int ipmi_fru_fmri(topo_mod_t *mod, tnode_t *node,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_version_t vers, nvlist_t *in, nvlist_t **out);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjstatic const topo_method_t ipmi_methods[] = {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj { TOPO_METH_PRESENT, TOPO_METH_PRESENT_DESC,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj TOPO_METH_PRESENT_VERSION0, TOPO_STABILITY_INTERNAL, ipmi_present },
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj { "ipmi_fru_label", "Property method", 0,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj TOPO_STABILITY_INTERNAL, ipmi_fru_label},
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj { "ipmi_fru_fmri", "Property method", 0,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj TOPO_STABILITY_INTERNAL, ipmi_fru_fmri},
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston { TOPO_METH_SENSOR_FAILURE, TOPO_METH_SENSOR_FAILURE_DESC,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston TOPO_METH_SENSOR_FAILURE_VERSION, TOPO_STABILITY_INTERNAL,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston topo_method_sensor_failure },
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj { NULL }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj};
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjconst topo_modops_t ipmi_ops = { ipmi_enum, NULL };
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjconst topo_modinfo_t ipmi_info =
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj { "ipmi", FM_FMRI_SCHEME_HC, TOPO_VERSION, &ipmi_ops };
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj/*
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * Determine if the entity is present.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj/*ARGSUSED*/
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjstatic int
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjipmi_present(topo_mod_t *mod, tnode_t *tn, topo_version_t version,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj nvlist_t *in, nvlist_t **out)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj{
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ipmi_handle_t *ihp;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ipmi_entity_t *ep;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj boolean_t present;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj nvlist_t *nvl;
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston int err, i;
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston char *name, **names;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ipmi_sdr_t *sdrp;
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston uint_t nelems;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock if ((ihp = topo_mod_ipmi_hold(mod)) == NULL)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (topo_mod_seterrno(mod, ETOPO_METHOD_UNKNOWN));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ep = topo_node_getspecific(tn);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (ep == NULL) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (topo_prop_get_string(tn, TOPO_PGROUP_IPMI,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj TOPO_PROP_IPMI_ENTITY_PRESENT, &name, &err) == 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj /*
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * Some broken IPMI implementations don't export correct
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * entities, so referring to an entity isn't sufficient.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * For these platforms, we allow the XML to specify a
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * single SDR record that represents the current present
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * state.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if ((sdrp = ipmi_sdr_lookup(ihp, name)) == NULL ||
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ipmi_entity_present_sdr(ihp, sdrp, &present) != 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj "Failed to get present state of %s (%s)\n",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj name, ipmi_errmsg(ihp));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_strfree(mod, name);
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock topo_mod_ipmi_rele(mod);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (-1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
525b85dbd2fc64df4bd0092c1a2b0827dd8e1e89Eric Schrock topo_mod_dprintf(mod,
525b85dbd2fc64df4bd0092c1a2b0827dd8e1e89Eric Schrock "ipmi_entity_present_sdr(%s) = %d\n", name,
525b85dbd2fc64df4bd0092c1a2b0827dd8e1e89Eric Schrock present);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_strfree(mod, name);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj } else {
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston if (topo_prop_get_string_array(tn, TOPO_PGROUP_IPMI,
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston TOPO_PROP_IPMI_ENTITY_REF, &names, &nelems, &err)
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston != 0) {
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock /*
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock * Not all nodes have an entity_ref attribute.
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock * For these cases, return ENOTSUP so that we
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock * fall back to the default hc presence
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock * detection.
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock */
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock topo_mod_ipmi_rele(mod);
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock return (topo_mod_seterrno(mod,
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock ETOPO_METHOD_NOTSUP));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston for (i = 0; i < nelems; i++)
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston if ((ep = ipmi_entity_lookup_sdr(ihp, names[i]))
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston != NULL)
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston break;
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston for (i = 0; i < nelems; i++)
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston topo_mod_strfree(mod, names[i]);
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston topo_mod_free(mod, names, (nelems * sizeof (char *)));
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston if (ep == NULL) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod,
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston "Failed to get present state of %s=%d\n",
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston topo_node_name(tn), topo_node_instance(tn));
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock topo_mod_ipmi_rele(mod);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (-1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_node_setspecific(tn, ep);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (ep != NULL) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (ipmi_entity_present(ihp, ep, &present) != 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj "ipmi_entity_present() failed: %s",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ipmi_errmsg(ihp));
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock topo_mod_ipmi_rele(mod);
9af3851a3a831b4de34b42482c22351e14f33f16eschrock return (-1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
525b85dbd2fc64df4bd0092c1a2b0827dd8e1e89Eric Schrock
525b85dbd2fc64df4bd0092c1a2b0827dd8e1e89Eric Schrock topo_mod_dprintf(mod,
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston "ipmi_entity_present(%d, %d) = %d\n", ep->ie_type,
72c9c96770c90a8042add81e56bb8a2f9e4a29dcRobert Johnston ep->ie_instance, present);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock topo_mod_ipmi_rele(mod);
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (nvlist_add_uint32(nvl, TOPO_METH_PRESENT_RET, present) != 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj nvlist_free(nvl);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj *out = nvl;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (0);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj}
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj/*
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * This determines if the entity has a FRU locator record set, in which case we
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * treat this as a FRU, even if it's part of an association.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj/*ARGSUSED*/
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjstatic int
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjipmi_check_sdr(ipmi_handle_t *ihp, ipmi_entity_t *ep, const char *name,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ipmi_sdr_t *sdrp, void *data)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj{
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ipmi_enum_data_t *edp = data;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (sdrp->is_type == IPMI_SDR_TYPE_FRU_LOCATOR)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj edp->ed_hasfru = B_TRUE;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (0);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj}
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj/*
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * Main entity enumerator. If we find a matching entity type, then instantiate
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * a topo node.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjstatic int
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjipmi_check_entity(ipmi_handle_t *ihp, ipmi_entity_t *ep, void *data)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj{
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ipmi_enum_data_t *edp = data;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ipmi_enum_data_t cdata;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj tnode_t *pnode = edp->ed_pnode;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_t *mod = edp->ed_mod;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj nvlist_t *auth, *fmri;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj tnode_t *tn;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_pgroup_info_t pgi;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj int err;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj const char *labelname;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj char label[64];
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj size_t len;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (ep->ie_type != edp->ed_entity)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (0);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj /*
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * The purpose of power and cooling domains is to group psus and fans
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * together. Unfortunately, some broken IPMI implementations declare
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * domains that don't contain other elements. Since the end goal is to
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * only enumerate psus and fans, we'll just ignore such elements.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if ((ep->ie_type == IPMI_ET_POWER_DOMAIN ||
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ep->ie_type == IPMI_ET_COOLING_DOMAIN) &&
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ep->ie_children == 0)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (0);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if ((auth = topo_mod_auth(mod, pnode)) == NULL) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod, "topo_mod_auth() failed: %s",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_errmsg(mod));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if ((fmri = topo_mod_hcfmri(mod, pnode, FM_HC_SCHEME_VERSION,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj edp->ed_name, edp->ed_instance, NULL, auth, NULL, NULL,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj NULL)) == NULL) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj nvlist_free(auth);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod, "topo_mod_hcfmri() failed: %s",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_errmsg(mod));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj nvlist_free(auth);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if ((tn = topo_node_bind(mod, pnode, edp->ed_name,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj edp->ed_instance, fmri)) == NULL) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj nvlist_free(fmri);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod, "topo_node_bind() failed: %s",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_errmsg(mod));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj /*
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * We inherit our label from our parent, appending our label in the
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * process. This results in defaults labels of the form "FM 1 FAN 0"
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * by default when given a hierarchy.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (edp->ed_label != NULL)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj (void) snprintf(label, sizeof (label), "%s ", edp->ed_label);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj else
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj label[0] = '\0';
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj switch (edp->ed_entity) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj case IPMI_ET_POWER_DOMAIN:
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj labelname = "PM";
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj break;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj case IPMI_ET_PSU:
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj labelname = "PSU";
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj break;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj case IPMI_ET_COOLING_DOMAIN:
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj labelname = "FM";
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj break;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj case IPMI_ET_FAN:
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj labelname = "FAN";
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj break;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj len = strlen(label);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj (void) snprintf(label + len, sizeof (label) - len, "%s %d",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj labelname, edp->ed_instance);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj nvlist_free(fmri);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj edp->ed_instance++;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (topo_node_label_set(tn, label, &err) != 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod, "failed to set label: %s\n",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_strerror(err));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj /*
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * Store IPMI entity details as properties on the node
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj pgi.tpi_name = TOPO_PGROUP_IPMI;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj pgi.tpi_namestab = TOPO_STABILITY_PRIVATE;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj pgi.tpi_datastab = TOPO_STABILITY_PRIVATE;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj pgi.tpi_version = TOPO_VERSION;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (topo_pgroup_create(tn, &pgi, &err) != 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (err != ETOPO_PROP_DEFD) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod, "failed to create propgroup "
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj "%s: %s\n", TOPO_PGROUP_IPMI, topo_strerror(err));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (topo_method_register(mod, tn, ipmi_methods) != 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod, "topo_method_register() failed: %s",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_errmsg(mod));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj /*
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * If we are a child of a non-chassis node, and there isn't an explicit
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * FRU locator record, then propagate the parent's FRU. Otherwise, set
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * the FRU to be the same as the resource.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj edp->ed_hasfru = B_FALSE;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj (void) ipmi_entity_iter_sdr(ihp, ep, ipmi_check_sdr, edp);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (strcmp(topo_node_name(pnode), CHASSIS) == 0 ||
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj edp->ed_hasfru) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (topo_node_resource(tn, &fmri, &err) != 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod, "topo_node_resource() failed: %s",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_strerror(err));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj (void) topo_mod_seterrno(mod, err);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj } else {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (topo_node_fru(pnode, &fmri, NULL, &err) != 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod, "topo_node_fru() failed: %s",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_strerror(err));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj (void) topo_mod_seterrno(mod, err);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (topo_node_fru_set(tn, fmri, 0, &err) != 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj nvlist_free(fmri);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod, "topo_node_fru_set() failed: %s",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_strerror(err));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj (void) topo_mod_seterrno(mod, err);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_node_setspecific(tn, ep);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj nvlist_free(fmri);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj /*
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * Iterate over children, once for recursive domains and once for
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * psu/fans.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (ep->ie_children != 0 &&
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj (ep->ie_type == IPMI_ET_POWER_DOMAIN ||
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ep->ie_type == IPMI_ET_COOLING_DOMAIN)) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj cdata.ed_mod = edp->ed_mod;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj cdata.ed_pnode = tn;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj cdata.ed_instance = 0;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj cdata.ed_name = edp->ed_name;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj cdata.ed_entity = edp->ed_entity;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj cdata.ed_label = label;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (ipmi_entity_iter_children(ihp, ep,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ipmi_check_entity, &cdata) != 0)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj switch (cdata.ed_entity) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj case IPMI_ET_POWER_DOMAIN:
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj cdata.ed_entity = IPMI_ET_PSU;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj cdata.ed_name = PSU;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj break;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj case IPMI_ET_COOLING_DOMAIN:
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj cdata.ed_entity = IPMI_ET_FAN;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj cdata.ed_name = FAN;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj break;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (ipmi_entity_iter_children(ihp, ep,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ipmi_check_entity, &cdata) != 0)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (0);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj}
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj/*
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * libtopo enumeration point. This simply iterates over entities looking for
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * the appropriate type.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj/*ARGSUSED*/
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjstatic int
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjipmi_enum(topo_mod_t *mod, tnode_t *rnode, const char *name,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_instance_t min, topo_instance_t max, void *arg, void *unused)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj{
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ipmi_handle_t *ihp;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ipmi_enum_data_t data;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj int ret;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj /*
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * If the node being passed in ISN'T the chassis node, then we're being
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * asked to post-process a statically defined node.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (strcmp(topo_node_name(rnode), CHASSIS) != 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (ipmi_post_process(mod, rnode) != 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod, "post processing of node %s=%d "
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj "failed!", topo_node_name(rnode),
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_node_instance(rnode));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (-1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (0);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (strcmp(name, POWERMODULE) == 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj data.ed_entity = IPMI_ET_POWER_DOMAIN;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj } else if (strcmp(name, PSU) == 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj data.ed_entity = IPMI_ET_PSU;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj } else if (strcmp(name, FANMODULE) == 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj data.ed_entity = IPMI_ET_COOLING_DOMAIN;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj } else if (strcmp(name, FAN) == 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj data.ed_entity = IPMI_ET_FAN;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj } else {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod, "unknown enumeration type '%s'",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj name);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (-1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock if ((ihp = topo_mod_ipmi_hold(mod)) == NULL)
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock return (0);
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj data.ed_mod = mod;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj data.ed_pnode = rnode;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj data.ed_name = name;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj data.ed_instance = 0;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj data.ed_label = NULL;
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if ((ret = ipmi_entity_iter(ihp, ipmi_check_entity, &data)) != 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj /*
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * We don't return failure if IPMI enumeration fails. This may
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * be due to the SP being unavailable or an otherwise transient
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj * event.
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj */
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock if (ret < 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj "failed to enumerate entities: %s",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj ipmi_errmsg(ihp));
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock } else {
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock topo_mod_ipmi_rele(mod);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (-1);
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
0b1b4412cfd6c4ac5467dbe6f4088dcec4f55fe8Eric Schrock topo_mod_ipmi_rele(mod);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (0);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj}
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjstatic int
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjipmi_post_process(topo_mod_t *mod, tnode_t *tn)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj{
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (topo_method_register(mod, tn, ipmi_methods) != 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod, "ipmi_post_process() failed: %s",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_errmsg(mod));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (1);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (0);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj}
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj/*ARGSUSED*/
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjint
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj_topo_init(topo_mod_t *mod, topo_version_t version)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj{
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (getenv("TOPOIPMIDEBUG") != NULL)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_setdebug(mod);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if (topo_mod_register(mod, &ipmi_info, TOPO_VERSION) != 0) {
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod, "%s registration failed: %s\n",
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj DISK, topo_mod_errmsg(mod));
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (-1); /* mod errno already set */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_dprintf(mod, "IPMI enumerator initialized\n");
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj return (0);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj}
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robjvoid
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj_topo_fini(topo_mod_t *mod)
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj{
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj topo_mod_unregister(mod);
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj}