20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * CDDL HEADER START
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * The contents of this file are subject to the terms of the
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Common Development and Distribution License (the "License").
20c794b39650d115e17a15983b6b82e46238cf45gavinm * You may not use this file except in compliance with the License.
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
20c794b39650d115e17a15983b6b82e46238cf45gavinm * or http://www.opensolaris.org/os/licensing.
20c794b39650d115e17a15983b6b82e46238cf45gavinm * See the License for the specific language governing permissions
20c794b39650d115e17a15983b6b82e46238cf45gavinm * and limitations under the License.
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * When distributing Covered Code, include this CDDL HEADER in each
20c794b39650d115e17a15983b6b82e46238cf45gavinm * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
20c794b39650d115e17a15983b6b82e46238cf45gavinm * If applicable, add the following below this CDDL HEADER, with the
20c794b39650d115e17a15983b6b82e46238cf45gavinm * fields enclosed by brackets "[]" replaced with your own identifying
20c794b39650d115e17a15983b6b82e46238cf45gavinm * information: Portions Copyright [yyyy] [name of copyright owner]
20c794b39650d115e17a15983b6b82e46238cf45gavinm *
20c794b39650d115e17a15983b6b82e46238cf45gavinm * CDDL HEADER END
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Use is subject to license terms.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Support function for the i86pc chip enumerator
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/types.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <stdarg.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <strings.h>
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh#include <fm/fmd_fmri.h>
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye#include <sys/systeminfo.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include <sys/fm/protocol.h>
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye#include <fm/topo_mod.h>
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye#include <fm/fmd_agent.h>
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm#include "chip.h"
20c794b39650d115e17a15983b6b82e46238cf45gavinm
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Yestatic void fmri_dprint(topo_mod_t *, const char *, uint32_t, nvlist_t *);
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Yestatic boolean_t is_page_fmri(nvlist_t *);
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Whinge a debug message via topo_mod_dprintf and increment the
20c794b39650d115e17a15983b6b82e46238cf45gavinm * given error counter.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinmvoid
20c794b39650d115e17a15983b6b82e46238cf45gavinmwhinge(topo_mod_t *mod, int *nerr, const char *fmt, ...)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm va_list ap;
20c794b39650d115e17a15983b6b82e46238cf45gavinm char buf[160];
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (nerr != NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm ++*nerr;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm va_start(ap, fmt);
20c794b39650d115e17a15983b6b82e46238cf45gavinm (void) vsnprintf(buf, sizeof (buf), fmt, ap);
20c794b39650d115e17a15983b6b82e46238cf45gavinm va_end(ap);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm topo_mod_dprintf(mod, "%s", buf);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Given an nvpair of a limited number of data types, extract the property
20c794b39650d115e17a15983b6b82e46238cf45gavinm * name and value and add that combination to the given node in the
20c794b39650d115e17a15983b6b82e46238cf45gavinm * specified property group using the corresponding topo_prop_set_* function
20c794b39650d115e17a15983b6b82e46238cf45gavinm * for the data type. Return 1 on success, otherwise 0.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinmint
20c794b39650d115e17a15983b6b82e46238cf45gavinmnvprop_add(topo_mod_t *mod, nvpair_t *nvp, const char *pgname, tnode_t *node)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm int success = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm int err;
20c794b39650d115e17a15983b6b82e46238cf45gavinm char *pname = nvpair_name(nvp);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm switch (nvpair_type(nvp)) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm case DATA_TYPE_BOOLEAN_VALUE: {
20c794b39650d115e17a15983b6b82e46238cf45gavinm boolean_t val;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (nvpair_value_boolean_value(nvp, &val) == 0 &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm topo_prop_set_string(node, pgname, pname,
20c794b39650d115e17a15983b6b82e46238cf45gavinm TOPO_PROP_IMMUTABLE, val ? "true" : "false", &err) == 0)
20c794b39650d115e17a15983b6b82e46238cf45gavinm success = 1;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm case DATA_TYPE_UINT32: {
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint32_t val;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (nvpair_value_uint32(nvp, &val) == 0 &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm topo_prop_set_uint32(node, pgname, pname,
20c794b39650d115e17a15983b6b82e46238cf45gavinm TOPO_PROP_IMMUTABLE, val, &err) == 0)
20c794b39650d115e17a15983b6b82e46238cf45gavinm success = 1;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm case DATA_TYPE_UINT64: {
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint64_t val;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (nvpair_value_uint64(nvp, &val) == 0 &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm topo_prop_set_uint64(node, pgname, pname,
20c794b39650d115e17a15983b6b82e46238cf45gavinm TOPO_PROP_IMMUTABLE, val, &err) == 0)
20c794b39650d115e17a15983b6b82e46238cf45gavinm success = 1;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm case DATA_TYPE_UINT32_ARRAY: {
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint32_t *arrp;
20c794b39650d115e17a15983b6b82e46238cf45gavinm uint_t nelem;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (nvpair_value_uint32_array(nvp, &arrp, &nelem) == 0 &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm nelem > 0 && topo_prop_set_uint32_array(node, pgname, pname,
20c794b39650d115e17a15983b6b82e46238cf45gavinm TOPO_PROP_IMMUTABLE, arrp, nelem, &err) == 0)
20c794b39650d115e17a15983b6b82e46238cf45gavinm success = 1;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm case DATA_TYPE_STRING: {
20c794b39650d115e17a15983b6b82e46238cf45gavinm char *str;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (nvpair_value_string(nvp, &str) == 0 &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm topo_prop_set_string(node, pgname, pname,
20c794b39650d115e17a15983b6b82e46238cf45gavinm TOPO_PROP_IMMUTABLE, str, &err) == 0)
20c794b39650d115e17a15983b6b82e46238cf45gavinm success = 1;
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm default:
20c794b39650d115e17a15983b6b82e46238cf45gavinm whinge(mod, &err, "nvprop_add: Can't handle type %d for "
20c794b39650d115e17a15983b6b82e46238cf45gavinm "'%s' in property group %s of %s node\n",
20c794b39650d115e17a15983b6b82e46238cf45gavinm nvpair_type(nvp), pname, pgname, topo_node_name(node));
20c794b39650d115e17a15983b6b82e46238cf45gavinm break;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (success ? 0 : 1);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye * Lookup string data named pname in the given nvlist and add that
20c794b39650d115e17a15983b6b82e46238cf45gavinm * as property named pname in the given property group pgname on the indicated
20c794b39650d115e17a15983b6b82e46238cf45gavinm * topo node. Fill pvalp with a pointer to the string value, valid until
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye * nvlist_free is called.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinmint
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeadd_nvlist_strprop(topo_mod_t *mod, tnode_t *node, nvlist_t *nvl,
20c794b39650d115e17a15983b6b82e46238cf45gavinm const char *pgname, const char *pname, const char **pvalp)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye char *pval;
20c794b39650d115e17a15983b6b82e46238cf45gavinm int err = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (nvlist_lookup_string(nvl, pname, &pval) != 0)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (-1);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (topo_prop_set_string(node, pgname, pname,
20c794b39650d115e17a15983b6b82e46238cf45gavinm TOPO_PROP_IMMUTABLE, pval, &err) == 0) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (pvalp)
20c794b39650d115e17a15983b6b82e46238cf45gavinm *pvalp = pval;
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (0);
20c794b39650d115e17a15983b6b82e46238cf45gavinm } else {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye whinge(mod, &err, "add_nvlist_strprop: failed to add '%s'\n",
20c794b39650d115e17a15983b6b82e46238cf45gavinm pname);
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (-1);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye * Lookup an int32 item named pname in the given nvlist and add that
20c794b39650d115e17a15983b6b82e46238cf45gavinm * as property named pname in the given property group pgname on the indicated
20c794b39650d115e17a15983b6b82e46238cf45gavinm * topo node. Fill pvalp with the property value.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinmint
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeadd_nvlist_longprop(topo_mod_t *mod, tnode_t *node, nvlist_t *nvl,
20c794b39650d115e17a15983b6b82e46238cf45gavinm const char *pgname, const char *pname, int32_t *pvalp)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm int32_t pval;
20c794b39650d115e17a15983b6b82e46238cf45gavinm int err;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if ((nvlist_lookup_int32(nvl, pname, &pval)) != 0)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (-1);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (topo_prop_set_int32(node, pgname, pname,
20c794b39650d115e17a15983b6b82e46238cf45gavinm TOPO_PROP_IMMUTABLE, pval, &err) == 0) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (pvalp)
20c794b39650d115e17a15983b6b82e46238cf45gavinm *pvalp = pval;
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (0);
20c794b39650d115e17a15983b6b82e46238cf45gavinm } else {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye whinge(mod, &err, "add_nvlist_longprop: failed to add '%s'\n",
20c794b39650d115e17a15983b6b82e46238cf45gavinm pname);
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (-1);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye * In a given nvlist lookup a variable number of int32 properties named in
20c794b39650d115e17a15983b6b82e46238cf45gavinm * const char * varargs and each each in the given property group on the
20c794b39650d115e17a15983b6b82e46238cf45gavinm * node. Fill an array of the retrieved values.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinmint
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeadd_nvlist_longprops(topo_mod_t *mod, tnode_t *node, nvlist_t *nvl,
20c794b39650d115e17a15983b6b82e46238cf45gavinm const char *pgname, int32_t *pvalap, ...)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm const char *pname;
20c794b39650d115e17a15983b6b82e46238cf45gavinm va_list ap;
20c794b39650d115e17a15983b6b82e46238cf45gavinm int nerr = 0;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm va_start(ap, pvalap);
20c794b39650d115e17a15983b6b82e46238cf45gavinm while ((pname = va_arg(ap, const char *)) != NULL) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (add_nvlist_longprop(mod, node, nvl, pgname, pname,
20c794b39650d115e17a15983b6b82e46238cf45gavinm pvalap) != 0)
20c794b39650d115e17a15983b6b82e46238cf45gavinm nerr++; /* have whinged elsewhere */
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (pvalap != NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm ++pvalap;
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm va_end(ap);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (nerr == 0 ? 0 : -1);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Construct an hc scheme resource FMRI for a node named name with
20c794b39650d115e17a15983b6b82e46238cf45gavinm * instance number inst, parented by the given parent node pnode.
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinmint
20c794b39650d115e17a15983b6b82e46238cf45gavinmmkrsrc(topo_mod_t *mod, tnode_t *pnode, const char *name, int inst,
20c794b39650d115e17a15983b6b82e46238cf45gavinm nvlist_t *auth, nvlist_t **nvl)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm *nvl = topo_mod_hcfmri(mod, pnode, FM_HC_SCHEME_VERSION, name,
20c794b39650d115e17a15983b6b82e46238cf45gavinm inst, NULL, auth, NULL, NULL, NULL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (nvl != NULL ? 0 : -1); /* caller must free nvlist */
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*
20c794b39650d115e17a15983b6b82e46238cf45gavinm * Construct a cpu scheme FMRI with the given data; the caller must free
20c794b39650d115e17a15983b6b82e46238cf45gavinm * the allocated nvlist with nvlist_free().
20c794b39650d115e17a15983b6b82e46238cf45gavinm */
20c794b39650d115e17a15983b6b82e46238cf45gavinmnvlist_t *
20c794b39650d115e17a15983b6b82e46238cf45gavinmcpu_fmri_create(topo_mod_t *mod, uint32_t cpuid, char *s, uint8_t cpumask)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
20c794b39650d115e17a15983b6b82e46238cf45gavinm int err;
20c794b39650d115e17a15983b6b82e46238cf45gavinm nvlist_t *asru;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (topo_mod_nvalloc(mod, &asru, NV_UNIQUE_NAME) != 0)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (NULL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm err = nvlist_add_uint8(asru, FM_VERSION, FM_CPU_SCHEME_VERSION);
20c794b39650d115e17a15983b6b82e46238cf45gavinm err |= nvlist_add_string(asru, FM_FMRI_SCHEME, FM_FMRI_SCHEME_CPU);
20c794b39650d115e17a15983b6b82e46238cf45gavinm err |= nvlist_add_uint32(asru, FM_FMRI_CPU_ID, cpuid);
20c794b39650d115e17a15983b6b82e46238cf45gavinm err |= nvlist_add_uint8(asru, FM_FMRI_CPU_MASK, cpumask);
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (s != NULL)
20c794b39650d115e17a15983b6b82e46238cf45gavinm err |= nvlist_add_string(asru, FM_FMRI_CPU_SERIAL_ID, s);
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (err != 0) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm nvlist_free(asru);
20c794b39650d115e17a15983b6b82e46238cf45gavinm (void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (NULL);
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (asru);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm/*ARGSUSED*/
20c794b39650d115e17a15983b6b82e46238cf45gavinmint
20c794b39650d115e17a15983b6b82e46238cf45gavinmmem_asru_compute(topo_mod_t *mod, tnode_t *node, topo_version_t version,
20c794b39650d115e17a15983b6b82e46238cf45gavinm nvlist_t *in, nvlist_t **out)
20c794b39650d115e17a15983b6b82e46238cf45gavinm{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *asru, *args, *pargs, *hcsp;
20c794b39650d115e17a15983b6b82e46238cf45gavinm int err;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye uint64_t pa, offset;
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (strcmp(topo_node_name(node), RANK_NODE_NAME) != 0 &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm strcmp(topo_node_name(node), DIMM_NODE_NAME) != 0 &&
20c794b39650d115e17a15983b6b82e46238cf45gavinm strcmp(topo_node_name(node), CS_NODE_NAME) != 0)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (nvlist_lookup_nvlist(in, TOPO_PROP_ARGS, &args) != 0)
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm if ((err = nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &pargs)) != 0) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (err == ENOENT) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye pargs = args;
20c794b39650d115e17a15983b6b82e46238cf45gavinm } else {
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (topo_mod_nvdup(mod, pargs, &asru) != 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, EMOD_NOMEM));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye err = 0;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye /*
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye * if 'in' includes an hc-specific member which specifies asru-physaddr
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye * or asru-offset then rename them to asru and physaddr respectively.
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (nvlist_lookup_nvlist(asru, FM_FMRI_HC_SPECIFIC, &hcsp) == 0) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (nvlist_lookup_uint64(hcsp,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye "asru-"FM_FMRI_HC_SPECIFIC_PHYSADDR, &pa) == 0) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye err += nvlist_remove(hcsp,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye "asru-"FM_FMRI_HC_SPECIFIC_PHYSADDR,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye DATA_TYPE_UINT64);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye err += nvlist_add_uint64(hcsp,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye FM_FMRI_HC_SPECIFIC_PHYSADDR,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye pa);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (nvlist_lookup_uint64(hcsp,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye "asru-"FM_FMRI_HC_SPECIFIC_OFFSET, &offset) == 0) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye err += nvlist_remove(hcsp,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye "asru-"FM_FMRI_HC_SPECIFIC_OFFSET,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye DATA_TYPE_UINT64);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye err += nvlist_add_uint64(hcsp,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye FM_FMRI_HC_SPECIFIC_OFFSET,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye offset);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (err != 0 || topo_mod_nvalloc(mod, out, NV_UNIQUE_NAME) < 0) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm nvlist_free(asru);
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (topo_mod_seterrno(mod, EMOD_NOMEM));
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm err = nvlist_add_string(*out, TOPO_PROP_VAL_NAME, TOPO_PROP_ASRU);
20c794b39650d115e17a15983b6b82e46238cf45gavinm err |= nvlist_add_uint32(*out, TOPO_PROP_VAL_TYPE, TOPO_TYPE_FMRI);
20c794b39650d115e17a15983b6b82e46238cf45gavinm err |= nvlist_add_nvlist(*out, TOPO_PROP_VAL_VAL, asru);
20c794b39650d115e17a15983b6b82e46238cf45gavinm if (err != 0) {
20c794b39650d115e17a15983b6b82e46238cf45gavinm nvlist_free(asru);
20c794b39650d115e17a15983b6b82e46238cf45gavinm nvlist_free(*out);
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
20c794b39650d115e17a15983b6b82e46238cf45gavinm }
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm nvlist_free(asru);
20c794b39650d115e17a15983b6b82e46238cf45gavinm
20c794b39650d115e17a15983b6b82e46238cf45gavinm return (0);
20c794b39650d115e17a15983b6b82e46238cf45gavinm}
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic int
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeset_retnvl(topo_mod_t *mod, nvlist_t **out, const char *retname, uint32_t ret)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *nvl;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) < 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, EMOD_NOMEM));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (nvlist_add_uint32(nvl, retname, ret) != 0) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_free(nvl);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye *out = nvl;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (0);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj/*
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj * If we're getting called then the question of whether this dimm is plugged
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj * in has already been answered. What we don't know for sure is whether it's
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj * the same dimm or a different one plugged in the same slot. To check, we
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj * try and compare the serial numbers on the dimm in the current topology with
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj * the serial num from the unum fmri that got passed into this function as the
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj * argument.
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj *
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj */
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Yestatic int
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Yefmri_replaced(topo_mod_t *mod, tnode_t *node, nvlist_t *unum, int *errp)
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj{
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj tnode_t *dimmnode;
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson nvlist_t *resource;
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye int rc, err;
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye char *old_serial, *curr_serial;
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye fmd_agent_hdl_t *hdl;
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye /*
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye * If input is a page, return "replaced" if the offset is invalid.
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye */
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye if (is_page_fmri(unum) &&
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye (hdl = fmd_agent_open(FMD_AGENT_VERSION)) != NULL) {
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye rc = fmd_agent_page_isretired(hdl, unum);
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye err = fmd_agent_errno(hdl);
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye fmd_agent_close(hdl);
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye if (rc == FMD_AGENT_RETIRE_DONE &&
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye err == EINVAL)
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye return (FMD_OBJ_STATE_NOT_PRESENT);
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye }
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj /*
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj * If a serial number for the dimm was available at the time of the
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj * fault, it will have been added as a string to the unum nvlist
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj */
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye if (nvlist_lookup_string(unum, FM_FMRI_HC_SERIAL_ID, &old_serial))
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye return (FMD_OBJ_STATE_UNKNOWN);
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj /*
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj * If the current serial number is available for the DIMM that this rank
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj * belongs to, it will be accessible as a property on the parent (dimm)
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * node. If there is a serial id in the resource fmri, then use that.
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * Otherwise fall back to looking for a serial id property in the
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * protocol group.
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj */
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj dimmnode = topo_node_parent(node);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson if (topo_node_resource(dimmnode, &resource, &err) != -1) {
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson if (nvlist_lookup_string(resource, FM_FMRI_HC_SERIAL_ID,
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson &curr_serial) == 0) {
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson if (strcmp(old_serial, curr_serial) != 0) {
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson nvlist_free(resource);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson return (FMD_OBJ_STATE_REPLACED);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson } else {
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson nvlist_free(resource);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson return (FMD_OBJ_STATE_STILL_PRESENT);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson }
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson }
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson nvlist_free(resource);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson }
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj if (topo_prop_get_string(dimmnode, TOPO_PGROUP_PROTOCOL,
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj FM_FMRI_HC_SERIAL_ID, &curr_serial, &err) != 0) {
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye if (err == ETOPO_PROP_NOENT) {
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye return (FMD_OBJ_STATE_UNKNOWN);
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye } else {
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye *errp = EMOD_NVL_INVAL;
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye whinge(mod, NULL, "rank_fmri_present: Unexpected "
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye "error retrieving serial from node");
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye return (-1);
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye }
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj }
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye if (strcmp(old_serial, curr_serial) != 0) {
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye topo_mod_strfree(mod, curr_serial);
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye return (FMD_OBJ_STATE_REPLACED);
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye }
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj topo_mod_strfree(mod, curr_serial);
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye return (FMD_OBJ_STATE_STILL_PRESENT);
2cb5535af222653abf2eba5c180ded4a7b85d8b6robj}
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh/*
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh * In the event we encounter problems comparing serials or if a comparison isn't
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh * possible, we err on the side of caution and set is_present to TRUE.
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh */
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephhint
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Yerank_fmri_present(topo_mod_t *mod, tnode_t *node, topo_version_t version,
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh nvlist_t *in, nvlist_t **out)
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh{
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye int is_present, err;
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye if (version > TOPO_METH_PRESENT_VERSION)
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye return (topo_mod_seterrno(mod, EMOD_VER_NEW));
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye switch (fmri_replaced(mod, node, in, &err)) {
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye case FMD_OBJ_STATE_REPLACED:
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye case FMD_OBJ_STATE_NOT_PRESENT:
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye is_present = 0;
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye break;
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye case FMD_OBJ_STATE_UNKNOWN:
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye case FMD_OBJ_STATE_STILL_PRESENT:
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye is_present = 1;
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye break;
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye default:
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye return (topo_mod_seterrno(mod, err));
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh }
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye fmri_dprint(mod, "rank_fmri_present", is_present, in);
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye return (set_retnvl(mod, out, TOPO_METH_PRESENT_RET, is_present));
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye}
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Yeint
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Yerank_fmri_replaced(topo_mod_t *mod, tnode_t *node, topo_version_t version,
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye nvlist_t *in, nvlist_t **out)
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye{
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye int is_replaced, err;
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye if (version > TOPO_METH_REPLACED_VERSION)
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye return (topo_mod_seterrno(mod, EMOD_VER_NEW));
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye is_replaced = fmri_replaced(mod, node, in, &err);
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye if (is_replaced == -1)
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye return (topo_mod_seterrno(mod, err));
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye fmri_dprint(mod, "rank_fmri_replaced", is_replaced, in);
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye return (set_retnvl(mod, out, TOPO_METH_REPLACED_RET, is_replaced));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic void
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yefmri_dprint(topo_mod_t *mod, const char *op, uint32_t rc, nvlist_t *fmri)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye char *fmristr;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye const char *status;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (getenv("TOPOCHIPDBG") == NULL)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye switch (rc) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye case FMD_AGENT_RETIRE_DONE:
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye status = "sync success";
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye break;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye case FMD_AGENT_RETIRE_ASYNC:
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye status = "async retiring";
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye break;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye case FMD_AGENT_RETIRE_FAIL:
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye status = "not retired";
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye break;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye default:
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye status = "unknown status";
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (fmri != NULL && topo_mod_nvl2str(mod, fmri, &fmristr) == 0) {
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye topo_mod_dprintf(mod, "[%s]: %s => %d (\"%s\")\n", fmristr,
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye op, rc, status);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_mod_strfree(mod, fmristr);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestruct strand_walk_data {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye tnode_t *parent;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye fmd_agent_hdl_t *hdl;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye int (*func)(fmd_agent_hdl_t *, int, int, int);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye int err;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye int done;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye int fail;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye int async;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye};
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic int
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestrand_walker(topo_mod_t *mod, tnode_t *node, void *pdata)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye struct strand_walk_data *swdp = pdata;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye int32_t chipid, coreid, strandid;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye int err, rc;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye /*
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye * Terminate the walk if we reach start-node's sibling
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (node != swdp->parent &&
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_node_parent(node) == topo_node_parent(swdp->parent))
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (TOPO_WALK_TERMINATE);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (strcmp(topo_node_name(node), STRAND) != 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (TOPO_WALK_NEXT);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (topo_prop_get_int32(node, PGNAME(STRAND), STRAND_CHIP_ID,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye &chipid, &err) < 0 ||
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_prop_get_int32(node, PGNAME(STRAND), STRAND_CORE_ID,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye &coreid, &err) < 0) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye swdp->err++;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (TOPO_WALK_NEXT);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye strandid = topo_node_instance(node);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = swdp->func(swdp->hdl, chipid, coreid, strandid);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (rc == FMD_AGENT_RETIRE_DONE)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye swdp->done++;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else if (rc == FMD_AGENT_RETIRE_FAIL)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye swdp->fail++;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else if (rc == FMD_AGENT_RETIRE_ASYNC)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye swdp->async++;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye swdp->err++;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (getenv("TOPOCHIPDBG") != NULL) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye const char *op;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (swdp->func == fmd_agent_cpu_retire)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye op = "retire";
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else if (swdp->func == fmd_agent_cpu_unretire)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye op = "unretire";
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else if (swdp->func == fmd_agent_cpu_isretired)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye op = "check status";
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye op = "unknown op";
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_mod_dprintf(mod, "%s cpu (%d:%d:%d): rc = %d, err = %s\n",
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye op, (int)chipid, (int)coreid, (int)strandid, rc,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye fmd_agent_errmsg(swdp->hdl));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (TOPO_WALK_NEXT);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic int
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yewalk_strands(topo_mod_t *mod, struct strand_walk_data *swdp, tnode_t *parent,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye int (*func)(fmd_agent_hdl_t *, int, int, int))
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_walk_t *twp;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye int err;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye swdp->parent = parent;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye swdp->func = func;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye swdp->err = swdp->done = swdp->fail = swdp->async = 0;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if ((swdp->hdl = fmd_agent_open(FMD_AGENT_VERSION)) == NULL) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye swdp->fail++;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (0);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye twp = topo_mod_walk_init(mod, parent, strand_walker, swdp, &err);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (twp == NULL) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye fmd_agent_close(swdp->hdl);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (-1);
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh }
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye err = topo_walk_step(twp, TOPO_WALK_CHILD);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_walk_fini(twp);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye fmd_agent_close(swdp->hdl);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (err == TOPO_WALK_ERR || swdp->err > 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (-1);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh return (0);
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye/* ARGSUSED */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeint
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeretire_strands(topo_mod_t *mod, tnode_t *node, topo_version_t version,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *in, nvlist_t **out)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye struct strand_walk_data swd;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye uint32_t rc;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (version > TOPO_METH_RETIRE_VERSION)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, EMOD_VER_NEW));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (walk_strands(mod, &swd, node, fmd_agent_cpu_retire) == -1)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (-1);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (swd.fail > 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = FMD_AGENT_RETIRE_FAIL;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else if (swd.async > 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = FMD_AGENT_RETIRE_ASYNC;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = FMD_AGENT_RETIRE_DONE;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (set_retnvl(mod, out, TOPO_METH_RETIRE_RET, rc));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye/* ARGSUSED */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeint
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeunretire_strands(topo_mod_t *mod, tnode_t *node, topo_version_t version,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *in, nvlist_t **out)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye struct strand_walk_data swd;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye uint32_t rc;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (version > TOPO_METH_UNRETIRE_VERSION)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, EMOD_VER_NEW));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (walk_strands(mod, &swd, node, fmd_agent_cpu_unretire) == -1)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (-1);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (swd.fail > 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = FMD_AGENT_RETIRE_FAIL;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else if (swd.async > 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = FMD_AGENT_RETIRE_ASYNC;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = FMD_AGENT_RETIRE_DONE;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (set_retnvl(mod, out, TOPO_METH_UNRETIRE_RET, rc));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye/* ARGSUSED */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeint
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeservice_state_strands(topo_mod_t *mod, tnode_t *node, topo_version_t version,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *in, nvlist_t **out)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye struct strand_walk_data swd;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye uint32_t rc;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (version > TOPO_METH_SERVICE_STATE_VERSION)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, EMOD_VER_NEW));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (walk_strands(mod, &swd, node, fmd_agent_cpu_isretired) == -1)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (-1);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (swd.done > 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = (swd.fail + swd.async > 0) ? FMD_SERVICE_STATE_DEGRADED :
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye FMD_SERVICE_STATE_UNUSABLE;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else if (swd.async > 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = FMD_SERVICE_STATE_ISOLATE_PENDING;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else if (swd.fail > 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = FMD_SERVICE_STATE_OK;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = FMD_SERVICE_STATE_UNKNOWN;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (set_retnvl(mod, out, TOPO_METH_SERVICE_STATE_RET, rc));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye/* ARGSUSED */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeint
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeunusable_strands(topo_mod_t *mod, tnode_t *node, topo_version_t version,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *in, nvlist_t **out)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye struct strand_walk_data swd;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye uint32_t rc;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (version > TOPO_METH_UNUSABLE_VERSION)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, EMOD_VER_NEW));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (walk_strands(mod, &swd, node, fmd_agent_cpu_isretired) == -1)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (-1);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = (swd.fail + swd.async > 0 || swd.done == 0) ? 0 : 1;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (set_retnvl(mod, out, TOPO_METH_UNUSABLE_RET, rc));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic boolean_t
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeis_page_fmri(nvlist_t *nvl)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *hcsp;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye uint64_t val;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (nvlist_lookup_nvlist(nvl, FM_FMRI_HC_SPECIFIC, &hcsp) == 0 &&
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye (nvlist_lookup_uint64(hcsp, FM_FMRI_HC_SPECIFIC_OFFSET,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye &val) == 0 ||
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_lookup_uint64(hcsp, "asru-" FM_FMRI_HC_SPECIFIC_OFFSET,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye &val) == 0 ||
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_lookup_uint64(hcsp, FM_FMRI_HC_SPECIFIC_PHYSADDR,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye &val) == 0 ||
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_lookup_uint64(hcsp, "asru-" FM_FMRI_HC_SPECIFIC_PHYSADDR,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye &val) == 0))
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (B_TRUE);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (B_FALSE);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye/* ARGSUSED */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeint
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yentv_page_retire(topo_mod_t *mod, tnode_t *node, topo_version_t version,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *in, nvlist_t **out)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye fmd_agent_hdl_t *hdl;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye uint32_t rc = FMD_AGENT_RETIRE_FAIL;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (version > TOPO_METH_RETIRE_VERSION)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, EMOD_VER_NEW));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (is_page_fmri(in)) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if ((hdl = fmd_agent_open(FMD_AGENT_VERSION)) != NULL) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = fmd_agent_page_retire(hdl, in);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye fmd_agent_close(hdl);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye fmri_dprint(mod, "ntv_page_retire", rc, in);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (set_retnvl(mod, out, TOPO_METH_RETIRE_RET, rc));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye/* ARGSUSED */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeint
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yentv_page_unretire(topo_mod_t *mod, tnode_t *node, topo_version_t version,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *in, nvlist_t **out)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye fmd_agent_hdl_t *hdl;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye uint32_t rc = FMD_AGENT_RETIRE_FAIL;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (version > TOPO_METH_UNRETIRE_VERSION)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, EMOD_VER_NEW));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (is_page_fmri(in)) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if ((hdl = fmd_agent_open(FMD_AGENT_VERSION)) != NULL) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = fmd_agent_page_unretire(hdl, in);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye fmd_agent_close(hdl);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye fmri_dprint(mod, "ntv_page_unretire", rc, in);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (set_retnvl(mod, out, TOPO_METH_UNRETIRE_RET, rc));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye/* ARGSUSED */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeint
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yentv_page_service_state(topo_mod_t *mod, tnode_t *node, topo_version_t version,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *in, nvlist_t **out)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye fmd_agent_hdl_t *hdl;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye uint32_t rc = FMD_SERVICE_STATE_UNKNOWN;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (version > TOPO_METH_SERVICE_STATE_VERSION)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, EMOD_VER_NEW));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (is_page_fmri(in)) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if ((hdl = fmd_agent_open(FMD_AGENT_VERSION)) != NULL) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = fmd_agent_page_isretired(hdl, in);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye fmd_agent_close(hdl);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (rc == FMD_AGENT_RETIRE_DONE)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = FMD_SERVICE_STATE_UNUSABLE;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else if (rc == FMD_AGENT_RETIRE_FAIL)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = FMD_SERVICE_STATE_OK;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else if (rc == FMD_AGENT_RETIRE_ASYNC)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = FMD_SERVICE_STATE_ISOLATE_PENDING;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_mod_dprintf(mod, "ntv_page_service_state: rc = %u\n", rc);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (set_retnvl(mod, out, TOPO_METH_SERVICE_STATE_RET, rc));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye/* ARGSUSED */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yeint
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yentv_page_unusable(topo_mod_t *mod, tnode_t *node, topo_version_t version,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *in, nvlist_t **out)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye fmd_agent_hdl_t *hdl;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye uint32_t rc = FMD_AGENT_RETIRE_FAIL;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (version > TOPO_METH_UNUSABLE_VERSION)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, EMOD_VER_NEW));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (is_page_fmri(in)) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if ((hdl = fmd_agent_open(FMD_AGENT_VERSION)) != NULL) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = fmd_agent_page_isretired(hdl, in);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye fmd_agent_close(hdl);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_mod_dprintf(mod, "ntv_page_unusable: rc = %u\n", rc);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (set_retnvl(mod, out, TOPO_METH_UNUSABLE_RET,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc == FMD_AGENT_RETIRE_DONE ? 1 : 0));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}