hc.c revision aab83bb83be7342f6cfccaed8d5fe0b2f404855d
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * CDDL HEADER START
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * The contents of this file are subject to the terms of the
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Common Development and Distribution License (the "License").
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * You may not use this file except in compliance with the License.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * or http://www.opensolaris.org/os/licensing.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * See the License for the specific language governing permissions
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * and limitations under the License.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * When distributing Covered Code, include this CDDL HEADER in each
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * If applicable, add the following below this CDDL HEADER, with the
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * fields enclosed by brackets "[]" replaced with your own identifying
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * information: Portions Copyright [yyyy] [name of copyright owner]
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * CDDL HEADER END
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <stdio.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <stdlib.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <string.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <errno.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <ctype.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <alloca.h>
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye#include <assert.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <limits.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <zone.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <fm/topo_mod.h>
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi#include <fm/topo_hc.h>
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh#include <fm/fmd_fmri.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/param.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/systeminfo.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi#include <sys/fm/protocol.h>
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi#include <sys/stat.h>
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi#include <sys/systeminfo.h>
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi#include <sys/utsname.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi#include <topo_method.h>
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj#include <topo_module.h>
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi#include <topo_subr.h>
c40d7343efa60b18ad1ceb316eb337caeea79046cindi#include <topo_prop.h>
940d71d237794874e18a0eb72f6564821a823517eschrock#include <topo_tree.h>
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi#include <hc.h>
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int hc_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_instance_t, void *, void *);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic void hc_release(topo_mod_t *, tnode_t *);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int hc_fmri_nvl2str(topo_mod_t *, tnode_t *, topo_version_t,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *, nvlist_t **);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int hc_fmri_str2nvl(topo_mod_t *, tnode_t *, topo_version_t,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *, nvlist_t **);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int hc_compare(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t **);
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int hc_fmri_present(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t **);
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephhstatic int hc_fmri_replaced(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *,
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh nvlist_t **);
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int hc_fmri_unusable(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t **);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic int hc_fmri_expand(topo_mod_t *, tnode_t *, topo_version_t,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *, nvlist_t **);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic int hc_fmri_retire(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t **);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic int hc_fmri_unretire(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t **);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic int hc_fmri_service_state(topo_mod_t *, tnode_t *, topo_version_t,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *, nvlist_t **);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int hc_fmri_create_meth(topo_mod_t *, tnode_t *, topo_version_t,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *, nvlist_t **);
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int hc_fmri_prop_get(topo_mod_t *, tnode_t *, topo_version_t,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *, nvlist_t **);
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int hc_fmri_prop_set(topo_mod_t *, tnode_t *, topo_version_t,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *, nvlist_t **);
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int hc_fmri_pgrp_get(topo_mod_t *, tnode_t *, topo_version_t,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *, nvlist_t **);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robjstatic int hc_fmri_facility(topo_mod_t *, tnode_t *, topo_version_t,
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_t *, nvlist_t **);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic nvlist_t *hc_fmri_create(topo_mod_t *, nvlist_t *, int, const char *,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_instance_t inst, const nvlist_t *, const char *, const char *,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi const char *);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiconst topo_method_t hc_methods[] = {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi { TOPO_METH_NVL2STR, TOPO_METH_NVL2STR_DESC, TOPO_METH_NVL2STR_VERSION,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi TOPO_STABILITY_INTERNAL, hc_fmri_nvl2str },
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi { TOPO_METH_STR2NVL, TOPO_METH_STR2NVL_DESC, TOPO_METH_STR2NVL_VERSION,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi TOPO_STABILITY_INTERNAL, hc_fmri_str2nvl },
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi { TOPO_METH_COMPARE, TOPO_METH_COMPARE_DESC, TOPO_METH_COMPARE_VERSION,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi TOPO_STABILITY_INTERNAL, hc_compare },
c40d7343efa60b18ad1ceb316eb337caeea79046cindi { TOPO_METH_PRESENT, TOPO_METH_PRESENT_DESC, TOPO_METH_PRESENT_VERSION,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi TOPO_STABILITY_INTERNAL, hc_fmri_present },
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh { TOPO_METH_REPLACED, TOPO_METH_REPLACED_DESC,
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh TOPO_METH_REPLACED_VERSION, TOPO_STABILITY_INTERNAL,
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh hc_fmri_replaced },
c40d7343efa60b18ad1ceb316eb337caeea79046cindi { TOPO_METH_UNUSABLE, TOPO_METH_UNUSABLE_DESC,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi TOPO_METH_UNUSABLE_VERSION, TOPO_STABILITY_INTERNAL,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi hc_fmri_unusable },
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye { TOPO_METH_EXPAND, TOPO_METH_EXPAND_DESC,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye TOPO_METH_EXPAND_VERSION, TOPO_STABILITY_INTERNAL,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hc_fmri_expand },
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye { TOPO_METH_RETIRE, TOPO_METH_RETIRE_DESC,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye TOPO_METH_RETIRE_VERSION, TOPO_STABILITY_INTERNAL,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hc_fmri_retire },
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye { TOPO_METH_UNRETIRE, TOPO_METH_UNRETIRE_DESC,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye TOPO_METH_UNRETIRE_VERSION, TOPO_STABILITY_INTERNAL,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hc_fmri_unretire },
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye { TOPO_METH_SERVICE_STATE, TOPO_METH_SERVICE_STATE_DESC,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye TOPO_METH_SERVICE_STATE_VERSION, TOPO_STABILITY_INTERNAL,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hc_fmri_service_state },
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi { TOPO_METH_FMRI, TOPO_METH_FMRI_DESC, TOPO_METH_FMRI_VERSION,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi TOPO_STABILITY_INTERNAL, hc_fmri_create_meth },
c40d7343efa60b18ad1ceb316eb337caeea79046cindi { TOPO_METH_PROP_GET, TOPO_METH_PROP_GET_DESC,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi TOPO_METH_PROP_GET_VERSION, TOPO_STABILITY_INTERNAL,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi hc_fmri_prop_get },
c40d7343efa60b18ad1ceb316eb337caeea79046cindi { TOPO_METH_PROP_SET, TOPO_METH_PROP_SET_DESC,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi TOPO_METH_PROP_SET_VERSION, TOPO_STABILITY_INTERNAL,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi hc_fmri_prop_set },
c40d7343efa60b18ad1ceb316eb337caeea79046cindi { TOPO_METH_PGRP_GET, TOPO_METH_PGRP_GET_DESC,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi TOPO_METH_PGRP_GET_VERSION, TOPO_STABILITY_INTERNAL,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi hc_fmri_pgrp_get },
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj { TOPO_METH_FACILITY, TOPO_METH_FACILITY_DESC,
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj TOPO_METH_FACILITY_VERSION, TOPO_STABILITY_INTERNAL,
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj hc_fmri_facility },
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi { NULL }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi};
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindistatic const topo_modops_t hc_ops =
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { hc_enum, hc_release };
0eb822a1c0c2bea495647510b75f77f0e57633ebcindistatic const topo_modinfo_t hc_info =
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { HC, FM_FMRI_SCHEME_HC, HC_VERSION, &hc_ops };
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindistatic const hcc_t hc_canon[] = {
908f1e1388f616898b4e515d343c0414f2a6472esd { BANK, TOPO_STABILITY_PRIVATE },
184cd04c26b064536977dfbb913a1240eaf6f708cth { BAY, TOPO_STABILITY_PRIVATE },
908f1e1388f616898b4e515d343c0414f2a6472esd { BLADE, TOPO_STABILITY_PRIVATE },
14ea4bb737263733ad80a36b4f73f681c30a6b45sd { BRANCH, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { CMP, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { CENTERPLANE, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { CHASSIS, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { CHIP, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { CHIP_SELECT, TOPO_STABILITY_PRIVATE },
908f1e1388f616898b4e515d343c0414f2a6472esd { CORE, TOPO_STABILITY_PRIVATE },
940d71d237794874e18a0eb72f6564821a823517eschrock { CONTROLLER, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { CPU, TOPO_STABILITY_PRIVATE },
13faa91230bde46da937bf33010b9accc5bdeb59sd { CPUBOARD, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { DIMM, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { DISK, TOPO_STABILITY_PRIVATE },
908f1e1388f616898b4e515d343c0414f2a6472esd { DRAM, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { DRAMCHANNEL, TOPO_STABILITY_PRIVATE },
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj { FAN, TOPO_STABILITY_PRIVATE },
ded9341448cd6e2573619c7f6fe98909bdd35ec6Hyon Kim { FANBOARD, TOPO_STABILITY_PRIVATE },
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj { FANMODULE, TOPO_STABILITY_PRIVATE },
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier { HBA, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { HOSTBRIDGE, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { INTERCONNECT, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { IOBOARD, TOPO_STABILITY_PRIVATE },
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim { IPORT, TOPO_STABILITY_PRIVATE },
13faa91230bde46da937bf33010b9accc5bdeb59sd { MEMBOARD, TOPO_STABILITY_PRIVATE },
908f1e1388f616898b4e515d343c0414f2a6472esd { MEMORYBUFFER, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { MEMORYCONTROL, TOPO_STABILITY_PRIVATE },
908f1e1388f616898b4e515d343c0414f2a6472esd { MICROCORE, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { MOTHERBOARD, TOPO_STABILITY_PRIVATE },
14ea4bb737263733ad80a36b4f73f681c30a6b45sd { NIU, TOPO_STABILITY_PRIVATE },
14ea4bb737263733ad80a36b4f73f681c30a6b45sd { NIUFN, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { PCI_BUS, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { PCI_DEVICE, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { PCI_FUNCTION, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { PCIEX_BUS, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { PCIEX_DEVICE, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { PCIEX_FUNCTION, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { PCIEX_ROOT, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { PCIEX_SWUP, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { PCIEX_SWDWN, TOPO_STABILITY_PRIVATE },
ded9341448cd6e2573619c7f6fe98909bdd35ec6Hyon Kim { POWERBOARD, TOPO_STABILITY_PRIVATE },
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj { POWERMODULE, TOPO_STABILITY_PRIVATE },
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj { PSU, TOPO_STABILITY_PRIVATE },
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi { RANK, TOPO_STABILITY_PRIVATE },
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim { RECEPTACLE, TOPO_STABILITY_PRIVATE },
908f1e1388f616898b4e515d343c0414f2a6472esd { RISER, TOPO_STABILITY_PRIVATE },
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim { SASEXPANDER, TOPO_STABILITY_PRIVATE },
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim { SCSI_DEVICE, TOPO_STABILITY_PRIVATE },
908f1e1388f616898b4e515d343c0414f2a6472esd { SHELF, TOPO_STABILITY_PRIVATE },
940d71d237794874e18a0eb72f6564821a823517eschrock { SES_ENCLOSURE, TOPO_STABILITY_PRIVATE },
ac88567a7a5bb7f01cf22cf366bc9d6203e24d7aHyon Kim { SMP_DEVICE, TOPO_STABILITY_PRIVATE },
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu { SP, TOPO_STABILITY_PRIVATE },
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye { STRAND, TOPO_STABILITY_PRIVATE },
53dbcc5939527e6d5d52d814e51e364b5e8bb532Sundeep Panicker { SUBCHASSIS, TOPO_STABILITY_PRIVATE },
14ea4bb737263733ad80a36b4f73f681c30a6b45sd { SYSTEMBOARD, TOPO_STABILITY_PRIVATE },
14ea4bb737263733ad80a36b4f73f681c30a6b45sd { XAUI, TOPO_STABILITY_PRIVATE },
14ea4bb737263733ad80a36b4f73f681c30a6b45sd { XFP, TOPO_STABILITY_PRIVATE }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi};
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindistatic int hc_ncanon = sizeof (hc_canon) / sizeof (hcc_t);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindiint
0eb822a1c0c2bea495647510b75f77f0e57633ebcindihc_init(topo_mod_t *mod, topo_version_t version)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Turn on module debugging output
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (getenv("TOPOHCDEBUG"))
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_mod_setdebug(mod);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_mod_dprintf(mod, "initializing hc builtin\n");
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (version != HC_VERSION)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (topo_mod_seterrno(mod, EMOD_VER_NEW));
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (topo_mod_register(mod, &hc_info, TOPO_VERSION) != 0) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_mod_dprintf(mod, "failed to register hc: "
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi "%s\n", topo_mod_errmsg(mod));
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (-1); /* mod errno already set */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindivoid
0eb822a1c0c2bea495647510b75f77f0e57633ebcindihc_fini(topo_mod_t *mod)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_mod_unregister(mod);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi}
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindistatic const topo_pgroup_info_t sys_pgroup = {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi TOPO_PGROUP_SYSTEM,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi TOPO_STABILITY_PRIVATE,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi TOPO_STABILITY_PRIVATE,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi 1
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi};
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindistatic const topo_pgroup_info_t auth_pgroup = {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi FM_FMRI_AUTHORITY,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi TOPO_STABILITY_PRIVATE,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi TOPO_STABILITY_PRIVATE,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi 1
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi};
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindistatic void
0eb822a1c0c2bea495647510b75f77f0e57633ebcindihc_prop_set(tnode_t *node, nvlist_t *auth)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi{
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi int err;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi char isa[MAXNAMELEN];
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi struct utsname uts;
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye char *prod, *psn, *csn, *server;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
9dd0f810214fdc8e1af881a9a5c4b6927629ff9ecindi if (auth == NULL)
9dd0f810214fdc8e1af881a9a5c4b6927629ff9ecindi return;
9dd0f810214fdc8e1af881a9a5c4b6927629ff9ecindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (topo_pgroup_create(node, &auth_pgroup, &err) != 0) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (err != ETOPO_PROP_DEFD)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi /*
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi * Inherit if we can, it saves memory
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi */
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj &err) != 0) && (err != ETOPO_PROP_DEFD)) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT, &prod)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi == 0)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi &err);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT_SN,
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye &err) != 0) && (err != ETOPO_PROP_DEFD)) {
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN, &psn)
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye == 0)
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye FM_FMRI_AUTH_PRODUCT_SN, TOPO_PROP_IMMUTABLE, psn,
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye &err);
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj &err) != 0) && (err != ETOPO_PROP_DEFD)) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &csn) == 0)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi FM_FMRI_AUTH_CHASSIS, TOPO_PROP_IMMUTABLE, csn,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi &err);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_SERVER,
2eeaed14a5e2ed9bd811643ad5bffc3510ca0310robj &err) != 0) && (err != ETOPO_PROP_DEFD)) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER, &server)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi == 0)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi &err);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (topo_pgroup_create(node, &sys_pgroup, &err) != 0)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi isa[0] = '\0';
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi (void) sysinfo(SI_ARCHITECTURE, isa, sizeof (isa));
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi (void) uname(&uts);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi TOPO_PROP_IMMUTABLE, isa, &err);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi TOPO_PROP_IMMUTABLE, uts.machine, &err);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*ARGSUSED*/
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindiint
0eb822a1c0c2bea495647510b75f77f0e57633ebcindihc_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, topo_instance_t min,
9dd0f810214fdc8e1af881a9a5c4b6927629ff9ecindi topo_instance_t max, void *notused1, void *notused2)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int isglobal = (getzoneid() == GLOBAL_ZONEID);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *pfmri = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *nvl;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi nvlist_t *auth;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi tnode_t *node;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int err;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Register root node methods
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (strcmp(name, HC) == 0) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi (void) topo_method_register(mod, pnode, hc_methods);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (min != max) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_mod_dprintf(mod,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi "Request to enumerate %s component with an "
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi "ambiguous instance number, min (%d) != max (%d).\n",
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi HC, min, max);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (topo_mod_seterrno(mod, EINVAL));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (!isglobal)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) topo_node_resource(pnode, &pfmri, &err);
9dd0f810214fdc8e1af881a9a5c4b6927629ff9ecindi auth = topo_mod_auth(mod, pnode);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi nvl = hc_fmri_create(mod, pfmri, FM_HC_SCHEME_VERSION, name, min,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi auth, NULL, NULL, NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_free(pfmri); /* callee ignores NULLs */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (nvl == NULL) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi nvlist_free(auth);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (-1);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if ((node = topo_node_bind(mod, pnode, name, min, nvl)) == NULL) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_mod_dprintf(mod, "topo_node_bind failed: %s\n",
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_strerror(topo_mod_errno(mod)));
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi nvlist_free(auth);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_free(nvl);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (-1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
47911a7d5f24c2fc37e7b5bcc696fe32e750c16ccy /*
47911a7d5f24c2fc37e7b5bcc696fe32e750c16ccy * Set FRU for the motherboard node
47911a7d5f24c2fc37e7b5bcc696fe32e750c16ccy */
47911a7d5f24c2fc37e7b5bcc696fe32e750c16ccy if (strcmp(name, MOTHERBOARD) == 0)
47911a7d5f24c2fc37e7b5bcc696fe32e750c16ccy (void) topo_node_fru_set(node, nvl, 0, &err);
47911a7d5f24c2fc37e7b5bcc696fe32e750c16ccy
9dd0f810214fdc8e1af881a9a5c4b6927629ff9ecindi hc_prop_set(node, auth);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_free(nvl);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi nvlist_free(auth);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*ARGSUSED*/
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic void
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindihc_release(topo_mod_t *mp, tnode_t *node)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_method_unregister_all(mp, node);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int
c40d7343efa60b18ad1ceb316eb337caeea79046cindifmri_compare(topo_mod_t *mod, nvlist_t *nv1, nvlist_t *nv2)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint8_t v1, v2;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t **hcp1, **hcp2;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_t *f1 = NULL, *f2 = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int err, i;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint_t nhcp1, nhcp2;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj char *f1str, *f2str;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (nvlist_lookup_uint8(nv1, FM_VERSION, &v1) != 0 ||
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_lookup_uint8(nv2, FM_VERSION, &v2) != 0 ||
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi v1 > FM_HC_SCHEME_VERSION || v2 > FM_HC_SCHEME_VERSION)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (topo_mod_seterrno(mod, EMOD_FMRI_VERSION));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi err = nvlist_lookup_nvlist_array(nv1, FM_FMRI_HC_LIST, &hcp1, &nhcp1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi err |= nvlist_lookup_nvlist_array(nv2, FM_FMRI_HC_LIST, &hcp2, &nhcp2);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (err != 0)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (nhcp1 != nhcp2)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (i = 0; i < nhcp1; i++) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *nm1 = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *nm2 = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *id1 = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *id2 = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) nvlist_lookup_string(hcp1[i], FM_FMRI_HC_NAME, &nm1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) nvlist_lookup_string(hcp2[i], FM_FMRI_HC_NAME, &nm2);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) nvlist_lookup_string(hcp1[i], FM_FMRI_HC_ID, &id1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) nvlist_lookup_string(hcp2[i], FM_FMRI_HC_ID, &id2);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (nm1 == NULL || nm2 == NULL || id1 == NULL || id2 == NULL)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (strcmp(nm1, nm2) == 0 && strcmp(id1, id2) == 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi continue;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj /*
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * Finally, check if the FMRI's represent a facility node. If so, then
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * verify that the facilty type ("sensor"|"indicator") and facility
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * name match.
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj */
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj (void) nvlist_lookup_nvlist(nv1, FM_FMRI_FACILITY, &f1);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj (void) nvlist_lookup_nvlist(nv2, FM_FMRI_FACILITY, &f2);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (f1 == NULL && f2 == NULL)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (1);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj else if (f1 == NULL || f2 == NULL)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (0);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (nvlist_lookup_string(f1, FM_FMRI_FACILITY_NAME, &f1str) == 0 &&
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_lookup_string(f2, FM_FMRI_FACILITY_NAME, &f2str) == 0 &&
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj strcmp(f1str, f2str) == 0 &&
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_lookup_string(f1, FM_FMRI_FACILITY_TYPE, &f1str) == 0 &&
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_lookup_string(f2, FM_FMRI_FACILITY_TYPE, &f2str) == 0 &&
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj strcmp(f1str, f2str) == 0) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (1);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi/*ARGSUSED*/
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int
c40d7343efa60b18ad1ceb316eb337caeea79046cindihc_compare(topo_mod_t *mod, tnode_t *node, topo_version_t version,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *in, nvlist_t **out)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi{
c40d7343efa60b18ad1ceb316eb337caeea79046cindi int ret;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi uint32_t compare;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *nv1, *nv2;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (version > TOPO_METH_COMPARE_VERSION)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, EMOD_VER_NEW));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (nvlist_lookup_nvlist(in, TOPO_METH_FMRI_ARG_NV1, &nv1) != 0 ||
12cc75c814f0c017004a9bbc96429911e008601bcindi nvlist_lookup_nvlist(in, TOPO_METH_FMRI_ARG_NV2, &nv2) != 0)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi ret = fmri_compare(mod, nv1, nv2);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (ret < 0)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (-1);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi compare = ret;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (topo_mod_nvalloc(mod, out, NV_UNIQUE_NAME) == 0) {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (nvlist_add_uint32(*out, TOPO_METH_COMPARE_RET,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi compare) == 0)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (0);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi else
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_free(*out);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (-1);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi}
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic ssize_t
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindifmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t **hcprs = NULL;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *hcsp = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *anvl = NULL;
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye nvpair_t *apair;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_t *fnvl;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint8_t version;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi ssize_t size = 0;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint_t hcnprs;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *serial = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *part = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *root = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *rev = NULL;
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye char *aname, *aval;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj char *fname = NULL, *ftype = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int err, i;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 ||
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi version > FM_HC_SCHEME_VERSION)
f5961f52af4b214e15b671fc88e5f5ea948e9deeAdrian Frost return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /* Get authority, if present */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi err = nvlist_lookup_nvlist(nvl, FM_FMRI_AUTHORITY, &anvl);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (err != 0 && err != ENOENT)
f5961f52af4b214e15b671fc88e5f5ea948e9deeAdrian Frost return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
f5961f52af4b214e15b671fc88e5f5ea948e9deeAdrian Frost (void) nvlist_lookup_string(nvl, FM_FMRI_HC_ROOT, &root);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi err = nvlist_lookup_nvlist_array(nvl, FM_FMRI_HC_LIST, &hcprs, &hcnprs);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (err != 0 || hcprs == NULL)
f5961f52af4b214e15b671fc88e5f5ea948e9deeAdrian Frost return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) nvlist_lookup_string(nvl, FM_FMRI_HC_SERIAL_ID, &serial);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) nvlist_lookup_string(nvl, FM_FMRI_HC_PART, &part);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) nvlist_lookup_string(nvl, FM_FMRI_HC_REVISION, &rev);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /* hc:// */
74a31ce69a88d851777ca840d31ec610ce9ecab3timh topo_fmristr_build(&size, buf, buflen, FM_FMRI_SCHEME_HC, NULL, "://");
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /* authority, if any */
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye if (anvl != NULL) {
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye for (apair = nvlist_next_nvpair(anvl, NULL);
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye apair != NULL; apair = nvlist_next_nvpair(anvl, apair)) {
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye if (nvpair_type(apair) != DATA_TYPE_STRING ||
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye nvpair_value_string(apair, &aval) != 0)
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye continue;
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye aname = nvpair_name(apair);
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye topo_fmristr_build(&size, buf, buflen, ":", NULL, NULL);
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye topo_fmristr_build(&size, buf, buflen, "=",
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye aname, aval);
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye }
9c94f155585ea35e938fea603bc227c685223abdCheng Sean Ye }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /* hardware-id part */
74a31ce69a88d851777ca840d31ec610ce9ecab3timh topo_fmristr_build(&size,
74a31ce69a88d851777ca840d31ec610ce9ecab3timh buf, buflen, serial, ":" FM_FMRI_HC_SERIAL_ID "=", NULL);
74a31ce69a88d851777ca840d31ec610ce9ecab3timh topo_fmristr_build(&size,
74a31ce69a88d851777ca840d31ec610ce9ecab3timh buf, buflen, part, ":" FM_FMRI_HC_PART "=", NULL);
74a31ce69a88d851777ca840d31ec610ce9ecab3timh topo_fmristr_build(&size,
74a31ce69a88d851777ca840d31ec610ce9ecab3timh buf, buflen, rev, ":" FM_FMRI_HC_REVISION "=", NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /* separating slash */
74a31ce69a88d851777ca840d31ec610ce9ecab3timh topo_fmristr_build(&size, buf, buflen, "/", NULL, NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /* hc-root */
f5961f52af4b214e15b671fc88e5f5ea948e9deeAdrian Frost if (root)
f5961f52af4b214e15b671fc88e5f5ea948e9deeAdrian Frost topo_fmristr_build(&size, buf, buflen, root, NULL, NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /* all the pairs */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (i = 0; i < hcnprs; i++) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *nm = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *id = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (i > 0)
74a31ce69a88d851777ca840d31ec610ce9ecab3timh topo_fmristr_build(&size,
74a31ce69a88d851777ca840d31ec610ce9ecab3timh buf, buflen, "/", NULL, NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) nvlist_lookup_string(hcprs[i], FM_FMRI_HC_NAME, &nm);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) nvlist_lookup_string(hcprs[i], FM_FMRI_HC_ID, &id);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (nm == NULL || id == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
74a31ce69a88d851777ca840d31ec610ce9ecab3timh topo_fmristr_build(&size, buf, buflen, nm, NULL, "=");
74a31ce69a88d851777ca840d31ec610ce9ecab3timh topo_fmristr_build(&size, buf, buflen, id, NULL, NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye /* append offset/physaddr if it exists in hc-specific */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (nvlist_lookup_nvlist(nvl, FM_FMRI_HC_SPECIFIC, &hcsp) == 0) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye char *hcsn = NULL;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye char hexstr[17];
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye uint64_t val;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (nvlist_lookup_uint64(hcsp, FM_FMRI_HC_SPECIFIC_OFFSET,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye &val) == 0 || nvlist_lookup_uint64(hcsp,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye "asru-" FM_FMRI_HC_SPECIFIC_OFFSET, &val) == 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hcsn = FM_FMRI_HC_SPECIFIC_OFFSET;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else if (nvlist_lookup_uint64(hcsp,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye FM_FMRI_HC_SPECIFIC_PHYSADDR, &val) == 0 ||
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_lookup_uint64(hcsp,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye "asru-" FM_FMRI_HC_SPECIFIC_PHYSADDR, &val) == 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hcsn = FM_FMRI_HC_SPECIFIC_PHYSADDR;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (hcsn != NULL) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye (void) snprintf(hexstr, sizeof (hexstr), "%llx", val);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_fmristr_build(&size, buf, buflen, "/", NULL, NULL);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_fmristr_build(&size, buf, buflen, "=", hcsn,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hexstr);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj /*
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * If the nvlist represents a facility node, then we append the
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * facility type and name to the end of the string representation using
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * the format below:
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj *
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * ?<ftype>=<fname>
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj */
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (nvlist_lookup_nvlist(nvl, FM_FMRI_FACILITY, &fnvl) == 0) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (nvlist_lookup_string(fnvl, FM_FMRI_FACILITY_NAME,
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj &fname) != 0 || nvlist_lookup_string(fnvl,
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj FM_FMRI_FACILITY_TYPE, &ftype) != 0)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (0);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_fmristr_build(&size, buf, buflen, "?", NULL, NULL);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_fmristr_build(&size, buf, buflen, "=", ftype, fname);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (size);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*ARGSUSED*/
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindihc_fmri_nvl2str(topo_mod_t *mod, tnode_t *node, topo_version_t version,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *nvl, nvlist_t **out)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi ssize_t len;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *name = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *fmristr;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (version > TOPO_METH_NVL2STR_VERSION)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (topo_mod_seterrno(mod, EMOD_VER_NEW));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if ((len = fmri_nvl2str(nvl, NULL, 0)) == 0 ||
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (name = topo_mod_alloc(mod, len + 1)) == NULL ||
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi fmri_nvl2str(nvl, name, len + 1) == 0) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (name != NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_free(mod, name, len + 1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
12cc75c814f0c017004a9bbc96429911e008601bcindi if (topo_mod_nvalloc(mod, &fmristr, NV_UNIQUE_NAME) != 0) {
12cc75c814f0c017004a9bbc96429911e008601bcindi topo_mod_free(mod, name, len + 1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
12cc75c814f0c017004a9bbc96429911e008601bcindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (nvlist_add_string(fmristr, "fmri-string", name) != 0) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_free(mod, name, len + 1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_free(fmristr);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_free(mod, name, len + 1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *out = fmristr;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic nvlist_t *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindihc_base_fmri_create(topo_mod_t *mod, const nvlist_t *auth, const char *part,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi const char *rev, const char *serial)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *fmri;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int err = 0;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Create base HC nvlist
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (topo_mod_nvalloc(mod, &fmri, NV_UNIQUE_NAME) != 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi err = nvlist_add_uint8(fmri, FM_VERSION, FM_HC_SCHEME_VERSION);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi err |= nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_HC);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi err |= nvlist_add_string(fmri, FM_FMRI_HC_ROOT, "");
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (err != 0) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_free(fmri);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Add optional payload members
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (serial != NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) nvlist_add_string(fmri, FM_FMRI_HC_SERIAL_ID, serial);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (part != NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) nvlist_add_string(fmri, FM_FMRI_HC_PART, part);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (rev != NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) nvlist_add_string(fmri, FM_FMRI_HC_REVISION, rev);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (auth != NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) nvlist_add_nvlist(fmri, FM_FMRI_AUTHORITY,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (nvlist_t *)auth);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (fmri);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic nvlist_t **
0eb822a1c0c2bea495647510b75f77f0e57633ebcindimake_hc_pairs(topo_mod_t *mod, char *fmri, int *num)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t **pa;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi char *hc, *fromstr;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *starti, *startn, *endi, *endi2;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *ne, *ns;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi char *cname = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *find;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi char *cid = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int nslashes = 0;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int npairs = 0;
12cc75c814f0c017004a9bbc96429911e008601bcindi int i, hclen;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if ((hc = topo_mod_strdup(mod, fmri + 5)) == NULL)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (NULL);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
12cc75c814f0c017004a9bbc96429911e008601bcindi hclen = strlen(hc) + 1;
12cc75c814f0c017004a9bbc96429911e008601bcindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Count equal signs and slashes to determine how many
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * hc-pairs will be present in the final FMRI. There should
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * be at least as many slashes as equal signs. There can be
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * more, though if the string after an = includes them.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if ((fromstr = strchr(hc, '/')) == NULL)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (NULL);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi find = fromstr;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi while ((ne = strchr(find, '=')) != NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi find = ne + 1;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi npairs++;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi find = fromstr;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi while ((ns = strchr(find, '/')) != NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi find = ns + 1;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nslashes++;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Do we appear to have a well-formed string version of the FMRI?
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (nslashes < npairs || npairs == 0) {
12cc75c814f0c017004a9bbc96429911e008601bcindi topo_mod_free(mod, hc, hclen);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *num = npairs;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi find = fromstr;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
12cc75c814f0c017004a9bbc96429911e008601bcindi if ((pa = topo_mod_zalloc(mod, npairs * sizeof (nvlist_t *))) == NULL) {
12cc75c814f0c017004a9bbc96429911e008601bcindi topo_mod_free(mod, hc, hclen);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (NULL);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * We go through a pretty complicated procedure to find the
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * name and id for each pair. That's because, unfortunately,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * we have some ids that can have slashes within them. So
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * we can't just search for the next slash after the equal sign
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * and decide that starts a new pair. Instead we have to find
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * an equal sign for the next pair and work our way back to the
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * slash from there.
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (i = 0; i < npairs; i++) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi startn = strchr(find, '/');
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (startn == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi break;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi startn++;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi starti = strchr(find, '=');
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (starti == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi break;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *starti = '\0';
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((cname = topo_mod_strdup(mod, startn)) == NULL)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi break;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *starti++ = '=';
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi endi = strchr(starti, '=');
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (endi != NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *endi = '\0';
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi endi2 = strrchr(starti, '/');
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (endi2 == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi break;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *endi = '=';
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *endi2 = '\0';
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((cid = topo_mod_strdup(mod, starti)) == NULL)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi break;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *endi2 = '/';
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi find = endi2;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi } else {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((cid = topo_mod_strdup(mod, starti)) == NULL)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi break;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi find = starti + strlen(starti);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (topo_mod_nvalloc(mod, &pa[i], NV_UNIQUE_NAME) < 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi break;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (nvlist_add_string(pa[i], FM_FMRI_HC_NAME, cname) ||
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_add_string(pa[i], FM_FMRI_HC_ID, cid))
c40d7343efa60b18ad1ceb316eb337caeea79046cindi break;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_strfree(mod, cname);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_strfree(mod, cid);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi cname = NULL;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi cid = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_strfree(mod, cname);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_strfree(mod, cid);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (i < npairs) {
12cc75c814f0c017004a9bbc96429911e008601bcindi for (i = 0; i < npairs; i++)
12cc75c814f0c017004a9bbc96429911e008601bcindi nvlist_free(pa[i]);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_free(mod, pa, npairs * sizeof (nvlist_t *));
12cc75c814f0c017004a9bbc96429911e008601bcindi topo_mod_free(mod, hc, hclen);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
12cc75c814f0c017004a9bbc96429911e008601bcindi topo_mod_free(mod, hc, hclen);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (pa);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robjint
0eb822a1c0c2bea495647510b75f77f0e57633ebcindimake_hc_auth(topo_mod_t *mod, char *fmri, char **serial, char **part,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindichar **rev, nvlist_t **auth)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi{
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi char *starti, *startn, *endi, *copy;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj char *aname = NULL, *aid = NULL, *fs;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi nvlist_t *na = NULL;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi size_t len;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if ((copy = topo_mod_strdup(mod, fmri + 5)) == NULL)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (-1);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi len = strlen(copy);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi /*
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi * Make sure there are a valid authority members
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi startn = strchr(copy, ':');
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi fs = strchr(copy, '/');
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (startn == NULL || fs == NULL) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_mod_strfree(mod, copy);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (0);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi /*
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi * The first colon we encounter must occur before the
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi * first slash
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (startn > fs)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj goto hcabail;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi do {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (++startn >= copy + len)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi break;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if ((starti = strchr(startn, '=')) == NULL)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj goto hcabail;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi *starti = '\0';
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (++starti > copy + len)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj goto hcabail;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if ((aname = topo_mod_strdup(mod, startn)) == NULL)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj goto hcabail;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi startn = endi = strchr(starti, ':');
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (endi == NULL)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if ((endi = strchr(starti, '/')) == NULL)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi break;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi *endi = '\0';
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if ((aid = topo_mod_strdup(mod, starti)) == NULL)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj goto hcabail;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi /*
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi * Return possible serial, part and revision
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (strcmp(aname, FM_FMRI_HC_SERIAL_ID) == 0) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd *serial = topo_mod_strdup(mod, aid);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi } else if (strcmp(aname, FM_FMRI_HC_PART) == 0) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd *part = topo_mod_strdup(mod, aid);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi } else if (strcmp(aname, FM_FMRI_HC_REVISION) == 0) {
14ea4bb737263733ad80a36b4f73f681c30a6b45sd *rev = topo_mod_strdup(mod, aid);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi } else {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (na == NULL) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (topo_mod_nvalloc(mod, &na,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi NV_UNIQUE_NAME) == 0) {
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock (void) nvlist_add_string(na, aname,
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock aid);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi } else {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi (void) nvlist_add_string(na, aname, aid);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_mod_strfree(mod, aname);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_mod_strfree(mod, aid);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj aname = aid = NULL;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi } while (startn != NULL);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi *auth = na;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_mod_free(mod, copy, len + 1);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (0);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robjhcabail:
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_free(mod, copy, len + 1);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_strfree(mod, aname);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_strfree(mod, aid);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_free(na);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (-1);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj}
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj/*
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * This function creates an nvlist to represent the facility portion of an
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * hc-scheme node, given a string representation of the fmri. This is called by
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * hc_fmri_str2nvl. If the string does not contain a facility component
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * (e.g. ?<ftype>=<fname>) then it bails early and returns 0.
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj *
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * On failure it returns -1 and sets the topo mod errno
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj */
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robjint
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robjmake_facility(topo_mod_t *mod, char *str, nvlist_t **nvl)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj{
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj char *fac, *copy, *fname, *ftype;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_t *nf = NULL;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj size_t len;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if ((fac = strchr(str, '?')) == NULL)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (0);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj ++fac;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if ((copy = topo_mod_strdup(mod, fac)) == NULL)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (topo_mod_seterrno(mod, EMOD_NOMEM));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj fac = copy;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj len = strlen(fac);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if ((fname = strchr(fac, '=')) == NULL) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_free(mod, copy, len + 1);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (topo_mod_seterrno(mod, EMOD_FMRI_MALFORM));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj fname[0] = '\0';
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj ++fname;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj ftype = fac;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (topo_mod_nvalloc(mod, &nf, NV_UNIQUE_NAME) != 0) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_free(mod, copy, len + 1);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (topo_mod_seterrno(mod, EMOD_NOMEM));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (nvlist_add_string(nf, FM_FMRI_FACILITY_NAME, fname) != 0 ||
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_add_string(nf, FM_FMRI_FACILITY_TYPE, ftype) != 0) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_free(mod, copy, len + 1);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_free(mod, copy, len + 1);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj *nvl = nf;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (0);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi}
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*ARGSUSED*/
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindihc_fmri_str2nvl(topo_mod_t *mod, tnode_t *node, topo_version_t version,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *in, nvlist_t **out)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t **pa = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *nf = NULL;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi nvlist_t *auth = NULL;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_t *fac = NULL;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi char *str;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye char *serial = NULL, *part = NULL, *rev = NULL, *hcsn = NULL;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye int npairs, n;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int i, e;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (version > TOPO_METH_STR2NVL_VERSION)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (topo_mod_seterrno(mod, EMOD_VER_NEW));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (nvlist_lookup_string(in, "fmri-string", &str) != 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /* We're expecting a string version of an hc scheme FMRI */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (strncmp(str, "hc://", 5) != 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (topo_mod_seterrno(mod, EMOD_FMRI_MALFORM));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if ((pa = make_hc_pairs(mod, str, &npairs)) == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (topo_mod_seterrno(mod, EMOD_FMRI_MALFORM));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (make_hc_auth(mod, str, &serial, &part, &rev, &auth) < 0)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj goto hcfmbail;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if ((nf = hc_base_fmri_create(mod, auth, part, rev, serial)) == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi goto hcfmbail;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye n = npairs;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye /*
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye * If the last pair in hc-list is offset or physaddr, we move
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye * it to hc-specific.
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye (void) nvlist_lookup_string(pa[npairs - 1], FM_FMRI_HC_NAME, &hcsn);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (strcmp(hcsn, FM_FMRI_HC_SPECIFIC_OFFSET) == 0 ||
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye strcmp(hcsn, FM_FMRI_HC_SPECIFIC_PHYSADDR) == 0) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye char *hcid;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *hcsp;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye uint64_t val;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye (void) nvlist_lookup_string(pa[npairs - 1], FM_FMRI_HC_ID,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye &hcid);
1db96d3b343c9ab3090da5b745f1cd9de2f192efCheng Sean Ye val = strtoull(hcid, NULL, 16);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (topo_mod_nvalloc(mod, &hcsp, NV_UNIQUE_NAME) != 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye goto hcfmbail;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (nvlist_add_uint64(hcsp, hcsn, val) != 0 ||
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_add_nvlist(nf, FM_FMRI_HC_SPECIFIC, hcsp) != 0) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_free(hcsp);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye goto hcfmbail;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_free(hcsp);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye n--;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if ((e = nvlist_add_uint32(nf, FM_FMRI_HC_LIST_SZ, n)) == 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye e = nvlist_add_nvlist_array(nf, FM_FMRI_HC_LIST, pa, n);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (e != 0) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_dprintf(mod, "construction of new hc nvl failed");
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi goto hcfmbail;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj /*
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * Clean-up
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (i = 0; i < npairs; i++)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_free(pa[i]);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_free(mod, pa, npairs * sizeof (nvlist_t *));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_strfree(mod, serial);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_strfree(mod, part);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_strfree(mod, rev);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi nvlist_free(auth);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (make_facility(mod, str, &fac) == -1)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj goto hcfmbail;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (fac != NULL) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (nvlist_add_nvlist(nf, FM_FMRI_FACILITY, fac) != 0)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj goto hcfmbail;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi *out = nf;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindihcfmbail:
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(nf);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (i = 0; i < npairs; i++)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_free(pa[i]);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_free(mod, pa, npairs * sizeof (nvlist_t *));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_strfree(mod, serial);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_strfree(mod, part);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_strfree(mod, rev);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi nvlist_free(auth);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_free(nf);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (topo_mod_seterrno(mod, EMOD_FMRI_MALFORM));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic nvlist_t *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindihc_list_create(topo_mod_t *mod, const char *name, char *inst)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int err;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *hc;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (topo_mod_nvalloc(mod, &hc, NV_UNIQUE_NAME) != 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi err = nvlist_add_string(hc, FM_FMRI_HC_NAME, name);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi err |= nvlist_add_string(hc, FM_FMRI_HC_ID, inst);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (err != 0) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_free(hc);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (hc);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic nvlist_t *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindihc_create_seterror(topo_mod_t *mod, nvlist_t **hcl, int n, nvlist_t *fmri,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int err)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int i;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (hcl != NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (i = 0; i < n + 1; ++i)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_free(hcl[i]);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_free(mod, hcl, sizeof (nvlist_t *) * (n + 1));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_free(fmri);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) topo_mod_seterrno(mod, err);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_dprintf(mod, "unable to create hc FMRI: %s\n",
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_errmsg(mod));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (NULL);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int
0eb822a1c0c2bea495647510b75f77f0e57633ebcindihc_name_canonical(topo_mod_t *mod, const char *name)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int i;
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (getenv("NOHCCHECK") != NULL)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (1);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Only enumerate elements with correct canonical names
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi for (i = 0; i < hc_ncanon; i++) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (strcmp(name, hc_canon[i].hcc_name) == 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi break;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (i >= hc_ncanon) {
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi topo_mod_dprintf(mod, "non-canonical name %s\n",
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi name);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi } else {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (1);
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic nvlist_t *
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindihc_fmri_create(topo_mod_t *mod, nvlist_t *pfmri, int version, const char *name,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_instance_t inst, const nvlist_t *auth, const char *part,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi const char *rev, const char *serial)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi int i;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char str[21]; /* sizeof (UINT64_MAX) + '\0' */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint_t pelems = 0;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t **phcl = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t **hcl = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *fmri = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (version > FM_HC_SCHEME_VERSION)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (hc_create_seterror(mod,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi hcl, pelems, fmri, EMOD_VER_OLD));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi else if (version < FM_HC_SCHEME_VERSION)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (hc_create_seterror(mod,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi hcl, pelems, fmri, EMOD_VER_NEW));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Check that the requested name is in our canonical list
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi if (hc_name_canonical(mod, name) == 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (hc_create_seterror(mod,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi hcl, pelems, fmri, EMOD_NONCANON));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /*
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi * Copy the parent's HC_LIST
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (pfmri != NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (nvlist_lookup_nvlist_array(pfmri, FM_FMRI_HC_LIST,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi &phcl, &pelems) != 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (hc_create_seterror(mod,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi hcl, pelems, fmri, EMOD_FMRI_MALFORM));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi hcl = topo_mod_zalloc(mod, sizeof (nvlist_t *) * (pelems + 1));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (hcl == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (hc_create_seterror(mod, hcl, pelems, fmri,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi EMOD_NOMEM));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (i = 0; i < pelems; ++i)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (topo_mod_nvdup(mod, phcl[i], &hcl[i]) != 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (hc_create_seterror(mod,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi hcl, pelems, fmri, EMOD_FMRI_NVL));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi (void) snprintf(str, sizeof (str), "%d", inst);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if ((hcl[i] = hc_list_create(mod, name, str)) == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (hc_create_seterror(mod,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi hcl, pelems, fmri, EMOD_FMRI_NVL));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if ((fmri = hc_base_fmri_create(mod, auth, part, rev, serial)) == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (hc_create_seterror(mod,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi hcl, pelems, fmri, EMOD_FMRI_NVL));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (nvlist_add_nvlist_array(fmri, FM_FMRI_HC_LIST, hcl, pelems + 1)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi != 0)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (hc_create_seterror(mod,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi hcl, pelems, fmri, EMOD_FMRI_NVL));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (hcl != NULL) {
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi for (i = 0; i < pelems + 1; ++i) {
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(hcl[i]);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi topo_mod_free(mod, hcl, sizeof (nvlist_t *) * (pelems + 1));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (fmri);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi/*ARGSUSED*/
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindistatic int
0eb822a1c0c2bea495647510b75f77f0e57633ebcindihc_fmri_create_meth(topo_mod_t *mod, tnode_t *node, topo_version_t version,
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *in, nvlist_t **out)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi{
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi int ret;
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi nvlist_t *args, *pfmri = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi nvlist_t *auth;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi uint32_t inst;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi char *name, *serial, *rev, *part;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (version > TOPO_METH_FMRI_VERSION)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (topo_mod_seterrno(mod, EMOD_VER_NEW));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi /* First the must-have fields */
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (nvlist_lookup_string(in, TOPO_METH_FMRI_ARG_NAME, &name) != 0)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (nvlist_lookup_uint32(in, TOPO_METH_FMRI_ARG_INST, &inst) != 0)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi /*
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi * args is optional
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi */
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi pfmri = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi auth = NULL;
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi serial = rev = part = NULL;
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi if ((ret = nvlist_lookup_nvlist(in, TOPO_METH_FMRI_ARG_NVL, &args))
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi != 0) {
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi if (ret != ENOENT)
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi } else {
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi /* And then optional arguments */
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi (void) nvlist_lookup_nvlist(args, TOPO_METH_FMRI_ARG_PARENT,
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi &pfmri);
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi (void) nvlist_lookup_nvlist(args, TOPO_METH_FMRI_ARG_AUTH,
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi &auth);
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi (void) nvlist_lookup_string(args, TOPO_METH_FMRI_ARG_PART,
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi &part);
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi (void) nvlist_lookup_string(args, TOPO_METH_FMRI_ARG_REV, &rev);
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi (void) nvlist_lookup_string(args, TOPO_METH_FMRI_ARG_SER,
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi &serial);
89c0ae934a35c2ab26de63e1d9fba6bcb04c6306cindi }
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi *out = hc_fmri_create(mod, pfmri, version, name, inst, auth, part,
0eb822a1c0c2bea495647510b75f77f0e57633ebcindi rev, serial);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi if (*out == NULL)
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (-1);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi return (0);
7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fecindi}
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindistruct hc_walk {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_walk_cb_t hcw_cb;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi void *hcw_priv;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_walk_t *hcw_wp;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t **hcw_list;
940d71d237794874e18a0eb72f6564821a823517eschrock nvlist_t *hcw_fmri;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_t *hcw_fac;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi uint_t hcw_index;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi uint_t hcw_end;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi};
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
940d71d237794874e18a0eb72f6564821a823517eschrock/*
940d71d237794874e18a0eb72f6564821a823517eschrock * Returns true if the given node is beneath the specified FMRI. This uses
940d71d237794874e18a0eb72f6564821a823517eschrock * the TOPO_METH_CONTAINS method, because some enumerators (such as external
940d71d237794874e18a0eb72f6564821a823517eschrock * enclosures) may want to do a comparison based on chassis WWN instead of the
940d71d237794874e18a0eb72f6564821a823517eschrock * instance ID. If this comparison function fails or is not supported, then we
940d71d237794874e18a0eb72f6564821a823517eschrock * fall back to a direct name/instance comparison.
940d71d237794874e18a0eb72f6564821a823517eschrock */
940d71d237794874e18a0eb72f6564821a823517eschrockstatic int
940d71d237794874e18a0eb72f6564821a823517eschrockhc_match(topo_mod_t *mod, tnode_t *node, nvlist_t *fmri, const char *name,
940d71d237794874e18a0eb72f6564821a823517eschrock topo_instance_t inst, boolean_t *result)
940d71d237794874e18a0eb72f6564821a823517eschrock{
940d71d237794874e18a0eb72f6564821a823517eschrock nvlist_t *rsrc;
940d71d237794874e18a0eb72f6564821a823517eschrock nvlist_t *arg, *nvl;
940d71d237794874e18a0eb72f6564821a823517eschrock uint32_t match = 0;
940d71d237794874e18a0eb72f6564821a823517eschrock int err;
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock if (topo_node_resource(node, &rsrc, &err) != 0)
940d71d237794874e18a0eb72f6564821a823517eschrock return (-1);
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock if (topo_mod_nvalloc(mod, &arg, NV_UNIQUE_NAME) != 0 ||
940d71d237794874e18a0eb72f6564821a823517eschrock nvlist_add_nvlist(arg, TOPO_METH_FMRI_ARG_FMRI,
940d71d237794874e18a0eb72f6564821a823517eschrock rsrc) != 0 ||
940d71d237794874e18a0eb72f6564821a823517eschrock nvlist_add_nvlist(arg, TOPO_METH_FMRI_ARG_SUBFMRI,
940d71d237794874e18a0eb72f6564821a823517eschrock fmri) != 0) {
940d71d237794874e18a0eb72f6564821a823517eschrock nvlist_free(rsrc);
940d71d237794874e18a0eb72f6564821a823517eschrock (void) topo_mod_seterrno(mod, EMOD_NOMEM);
940d71d237794874e18a0eb72f6564821a823517eschrock return (-1);
940d71d237794874e18a0eb72f6564821a823517eschrock }
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock nvlist_free(rsrc);
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock if (topo_method_invoke(node, TOPO_METH_CONTAINS,
940d71d237794874e18a0eb72f6564821a823517eschrock TOPO_METH_CONTAINS_VERSION, arg, &nvl, &err) != 0) {
940d71d237794874e18a0eb72f6564821a823517eschrock nvlist_free(arg);
940d71d237794874e18a0eb72f6564821a823517eschrock if (err == ETOPO_METHOD_NOTSUP) {
940d71d237794874e18a0eb72f6564821a823517eschrock match = (strcmp(name,
940d71d237794874e18a0eb72f6564821a823517eschrock topo_node_name(node)) == 0 &&
940d71d237794874e18a0eb72f6564821a823517eschrock inst == topo_node_instance(node));
940d71d237794874e18a0eb72f6564821a823517eschrock } else {
940d71d237794874e18a0eb72f6564821a823517eschrock return (-1);
940d71d237794874e18a0eb72f6564821a823517eschrock }
940d71d237794874e18a0eb72f6564821a823517eschrock } else {
940d71d237794874e18a0eb72f6564821a823517eschrock nvlist_free(arg);
940d71d237794874e18a0eb72f6564821a823517eschrock if (nvlist_lookup_uint32(nvl, TOPO_METH_CONTAINS_RET,
940d71d237794874e18a0eb72f6564821a823517eschrock &match) != 0) {
940d71d237794874e18a0eb72f6564821a823517eschrock nvlist_free(nvl);
940d71d237794874e18a0eb72f6564821a823517eschrock (void) topo_mod_seterrno(mod, EMOD_NVL_INVAL);
940d71d237794874e18a0eb72f6564821a823517eschrock return (-1);
940d71d237794874e18a0eb72f6564821a823517eschrock }
940d71d237794874e18a0eb72f6564821a823517eschrock nvlist_free(nvl);
940d71d237794874e18a0eb72f6564821a823517eschrock }
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock *result = (match != 0);
940d71d237794874e18a0eb72f6564821a823517eschrock return (0);
940d71d237794874e18a0eb72f6564821a823517eschrock}
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock/*
940d71d237794874e18a0eb72f6564821a823517eschrock * Ideally, we should just be able to call topo_walk_bysibling(). But that
940d71d237794874e18a0eb72f6564821a823517eschrock * code assumes that the name/instance pair will match, so we need to
940d71d237794874e18a0eb72f6564821a823517eschrock * explicitly iterate over children of the parent looking for a matching value.
940d71d237794874e18a0eb72f6564821a823517eschrock */
940d71d237794874e18a0eb72f6564821a823517eschrockstatic int
940d71d237794874e18a0eb72f6564821a823517eschrockhc_walk_sibling(topo_mod_t *mod, tnode_t *node, struct hc_walk *hwp,
940d71d237794874e18a0eb72f6564821a823517eschrock const char *name, topo_instance_t inst)
940d71d237794874e18a0eb72f6564821a823517eschrock{
940d71d237794874e18a0eb72f6564821a823517eschrock tnode_t *pnp = topo_node_parent(node);
940d71d237794874e18a0eb72f6564821a823517eschrock topo_walk_t *wp = hwp->hcw_wp;
940d71d237794874e18a0eb72f6564821a823517eschrock tnode_t *np;
940d71d237794874e18a0eb72f6564821a823517eschrock boolean_t matched;
940d71d237794874e18a0eb72f6564821a823517eschrock int status;
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock for (np = topo_child_first(pnp); np != NULL;
940d71d237794874e18a0eb72f6564821a823517eschrock np = topo_child_next(pnp, np)) {
940d71d237794874e18a0eb72f6564821a823517eschrock topo_node_hold(np);
940d71d237794874e18a0eb72f6564821a823517eschrock if (hc_match(mod, np, hwp->hcw_fmri, name, inst,
940d71d237794874e18a0eb72f6564821a823517eschrock &matched) == 0 && matched) {
940d71d237794874e18a0eb72f6564821a823517eschrock wp->tw_node = np;
940d71d237794874e18a0eb72f6564821a823517eschrock if (wp->tw_mod != NULL)
940d71d237794874e18a0eb72f6564821a823517eschrock status = wp->tw_cb(mod, np, hwp);
940d71d237794874e18a0eb72f6564821a823517eschrock else
940d71d237794874e18a0eb72f6564821a823517eschrock status = wp->tw_cb(wp->tw_thp, np, hwp);
940d71d237794874e18a0eb72f6564821a823517eschrock topo_node_rele(np);
940d71d237794874e18a0eb72f6564821a823517eschrock wp->tw_node = node;
940d71d237794874e18a0eb72f6564821a823517eschrock return (status);
940d71d237794874e18a0eb72f6564821a823517eschrock }
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock topo_node_rele(np);
940d71d237794874e18a0eb72f6564821a823517eschrock }
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock return (TOPO_WALK_TERMINATE);
940d71d237794874e18a0eb72f6564821a823517eschrock}
940d71d237794874e18a0eb72f6564821a823517eschrock
c40d7343efa60b18ad1ceb316eb337caeea79046cindi/*
c40d7343efa60b18ad1ceb316eb337caeea79046cindi * Generic walker for the hc-scheme topo tree. This function uses the
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * hierachical nature of the hc-scheme to efficiently step through
78432d5ed5122db8b0bbfa41e00d063bf8ae7171cy * the topo hc tree. Node lookups are done by topo_walk_byid() and
78432d5ed5122db8b0bbfa41e00d063bf8ae7171cy * topo_walk_bysibling() at each component level to avoid unnecessary
78432d5ed5122db8b0bbfa41e00d063bf8ae7171cy * traversal of the tree. hc_walker() never returns TOPO_WALK_NEXT, so
78432d5ed5122db8b0bbfa41e00d063bf8ae7171cy * whether TOPO_WALK_CHILD or TOPO_WALK_SIBLING is specified by
78432d5ed5122db8b0bbfa41e00d063bf8ae7171cy * topo_walk_step() doesn't affect the traversal.
c40d7343efa60b18ad1ceb316eb337caeea79046cindi */
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int
c40d7343efa60b18ad1ceb316eb337caeea79046cindihc_walker(topo_mod_t *mod, tnode_t *node, void *pdata)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi{
c40d7343efa60b18ad1ceb316eb337caeea79046cindi int i, err;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct hc_walk *hwp = (struct hc_walk *)pdata;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi char *name, *id;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj char *fname, *ftype;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_instance_t inst;
940d71d237794874e18a0eb72f6564821a823517eschrock boolean_t match;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi i = hwp->hcw_index;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (i > hwp->hcw_end) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (hwp->hcw_fac != NULL) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if ((err = hwp->hcw_cb(mod, node, hwp->hcw_priv))
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj != 0) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj (void) topo_mod_seterrno(mod, err);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_dprintf(mod, "hc_walker: callback "
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj "failed: %s\n ", topo_mod_errmsg(mod));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (TOPO_WALK_ERR);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_dprintf(mod, "hc_walker: callback "
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj "complete: terminate walk\n");
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (TOPO_WALK_TERMINATE);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj } else {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_dprintf(mod, "hc_walker: node not found\n");
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (TOPO_WALK_TERMINATE);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = nvlist_lookup_string(hwp->hcw_list[i], FM_FMRI_HC_NAME, &name);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err |= nvlist_lookup_string(hwp->hcw_list[i], FM_FMRI_HC_ID, &id);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (err != 0) {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (void) topo_mod_seterrno(mod, EMOD_NVL_INVAL);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (TOPO_WALK_ERR);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi inst = atoi(id);
01e689ccb14727455003b77ee332005223497875cindi
01e689ccb14727455003b77ee332005223497875cindi /*
940d71d237794874e18a0eb72f6564821a823517eschrock * Check to see if our node matches the requested FMRI. If it doesn't
940d71d237794874e18a0eb72f6564821a823517eschrock * (because the enumerator determines matching based on something other
940d71d237794874e18a0eb72f6564821a823517eschrock * than name/instance, or because we're at the first level below the
940d71d237794874e18a0eb72f6564821a823517eschrock * root), then iterate over siblings to find the matching node.
01e689ccb14727455003b77ee332005223497875cindi */
940d71d237794874e18a0eb72f6564821a823517eschrock if (hc_match(mod, node, hwp->hcw_fmri, name, inst, &match) != 0)
940d71d237794874e18a0eb72f6564821a823517eschrock return (TOPO_WALK_ERR);
940d71d237794874e18a0eb72f6564821a823517eschrock
940d71d237794874e18a0eb72f6564821a823517eschrock if (!match)
940d71d237794874e18a0eb72f6564821a823517eschrock return (hc_walk_sibling(mod, node, hwp, name, inst));
01e689ccb14727455003b77ee332005223497875cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_dprintf(mod, "hc_walker: walking node:%s=%d for hc:"
c40d7343efa60b18ad1ceb316eb337caeea79046cindi "%s=%d at %d, end at %d \n", topo_node_name(node),
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_node_instance(node), name, inst, i, hwp->hcw_end);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (i == hwp->hcw_end) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
c40d7343efa60b18ad1ceb316eb337caeea79046cindi /*
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * We are at the end of the hc-list. Now, check for
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * a facility leaf and walk one more time.
c40d7343efa60b18ad1ceb316eb337caeea79046cindi */
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (hwp->hcw_fac != NULL) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj err = nvlist_lookup_string(hwp->hcw_fac,
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj FM_FMRI_FACILITY_NAME, &fname);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj err |= nvlist_lookup_string(hwp->hcw_fac,
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj FM_FMRI_FACILITY_TYPE, &ftype);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (err != 0) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj (void) topo_mod_seterrno(mod, EMOD_NVL_INVAL);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (TOPO_WALK_ERR);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj hwp->hcw_index++;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_dprintf(mod, "hc_walker: walk to facility "
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj "node:%s=%s\n", fname, ftype);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (topo_walk_byid(hwp->hcw_wp, fname, 0));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj /*
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * Otherwise, this is the node we're looking for.
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj */
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if ((err = hwp->hcw_cb(mod, node, hwp->hcw_priv)) != 0) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj (void) topo_mod_seterrno(mod, err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_dprintf(mod, "hc_walker: callback "
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj "failed: %s\n ", topo_mod_errmsg(mod));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (TOPO_WALK_ERR);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi } else {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_dprintf(mod, "hc_walker: callback "
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj "complete: terminate walk\n");
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (TOPO_WALK_TERMINATE);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj /*
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * Move on to the next component in the hc-list
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj */
c40d7343efa60b18ad1ceb316eb337caeea79046cindi hwp->hcw_index = ++i;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = nvlist_lookup_string(hwp->hcw_list[i], FM_FMRI_HC_NAME, &name);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err |= nvlist_lookup_string(hwp->hcw_list[i], FM_FMRI_HC_ID, &id);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (err != 0) {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (void) topo_mod_seterrno(mod, err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (TOPO_WALK_ERR);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi inst = atoi(id);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_walk_byid(hwp->hcw_wp, name, inst));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi}
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic struct hc_walk *
c40d7343efa60b18ad1ceb316eb337caeea79046cindihc_walk_init(topo_mod_t *mod, tnode_t *node, nvlist_t *rsrc,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_walk_cb_t cb, void *pdata)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi{
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj int err, ret;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi uint_t sz;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct hc_walk *hwp;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_walk_t *wp;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
918a0d8ae0916c29c35aae9b95c22b02a0c6e390robj if ((hwp = topo_mod_alloc(mod, sizeof (struct hc_walk))) == NULL) {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (void) topo_mod_seterrno(mod, EMOD_NOMEM);
918a0d8ae0916c29c35aae9b95c22b02a0c6e390robj return (NULL);
918a0d8ae0916c29c35aae9b95c22b02a0c6e390robj }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (nvlist_lookup_nvlist_array(rsrc, FM_FMRI_HC_LIST, &hwp->hcw_list,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi &sz) != 0) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_dprintf(mod, "hc_walk_init: failed to lookup %s "
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj "nvlist\n", FM_FMRI_HC_LIST);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_free(mod, hwp, sizeof (struct hc_walk));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (void) topo_mod_seterrno(mod, EMOD_METHOD_INVAL);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (NULL);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if ((ret = nvlist_lookup_nvlist(rsrc, FM_FMRI_FACILITY, &hwp->hcw_fac))
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj != 0) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (ret != ENOENT) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_dprintf(mod, "hc_walk_init: unexpected error "
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj "looking up %s nvlist", FM_FMRI_FACILITY);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_free(mod, hwp, sizeof (struct hc_walk));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj (void) topo_mod_seterrno(mod, EMOD_METHOD_INVAL);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (NULL);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj } else {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj hwp->hcw_fac = NULL;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
940d71d237794874e18a0eb72f6564821a823517eschrock hwp->hcw_fmri = rsrc;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi hwp->hcw_end = sz - 1;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi hwp->hcw_index = 0;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi hwp->hcw_priv = pdata;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi hwp->hcw_cb = cb;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((wp = topo_mod_walk_init(mod, node, hc_walker, (void *)hwp, &err))
c40d7343efa60b18ad1ceb316eb337caeea79046cindi == NULL) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_dprintf(mod, "hc_walk_init: topo_mod_walk_init failed "
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj "(%s)\n", topo_strerror(err));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_free(mod, hwp, sizeof (struct hc_walk));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (void) topo_mod_seterrno(mod, err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (NULL);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi hwp->hcw_wp = wp;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (hwp);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi}
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindistruct prop_lookup {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi const char *pl_pgroup;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi const char *pl_pname;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi int pl_flag;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *pl_args;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *pl_rsrc;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *pl_prop;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi};
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi/*ARGSUSED*/
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int
c40d7343efa60b18ad1ceb316eb337caeea79046cindihc_prop_get(topo_mod_t *mod, tnode_t *node, void *pdata)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi{
c40d7343efa60b18ad1ceb316eb337caeea79046cindi int err = 0;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct prop_lookup *plp = (struct prop_lookup *)pdata;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (void) topo_prop_getprop(node, plp->pl_pgroup, plp->pl_pname,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi plp->pl_args, &plp->pl_prop, &err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi}
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int
c40d7343efa60b18ad1ceb316eb337caeea79046cindihc_fmri_prop_get(topo_mod_t *mod, tnode_t *node, topo_version_t version,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *in, nvlist_t **out)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi{
c40d7343efa60b18ad1ceb316eb337caeea79046cindi int err;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct hc_walk *hwp;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct prop_lookup *plp;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (version > TOPO_METH_PROP_GET_VERSION)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((plp = topo_mod_alloc(mod, sizeof (struct prop_lookup))) == NULL)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, EMOD_NOMEM));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = nvlist_lookup_string(in, TOPO_PROP_GROUP,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (char **)&plp->pl_pgroup);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err |= nvlist_lookup_string(in, TOPO_PROP_VAL_NAME,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (char **)&plp->pl_pname);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err |= nvlist_lookup_nvlist(in, TOPO_PROP_RESOURCE, &plp->pl_rsrc);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (err != 0) {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_free(mod, plp, sizeof (struct prop_lookup));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi /*
c40d7343efa60b18ad1ceb316eb337caeea79046cindi * Private args to prop method are optional
c40d7343efa60b18ad1ceb316eb337caeea79046cindi */
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((err = nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &plp->pl_args))
c40d7343efa60b18ad1ceb316eb337caeea79046cindi != 0) {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (err != ENOENT) {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_free(mod, plp, sizeof (struct prop_lookup));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi } else {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi plp->pl_args = NULL;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi plp->pl_prop = NULL;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((hwp = hc_walk_init(mod, node, plp->pl_rsrc, hc_prop_get,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (void *)plp)) != NULL) {
78432d5ed5122db8b0bbfa41e00d063bf8ae7171cy if (topo_walk_step(hwp->hcw_wp, TOPO_WALK_CHILD) ==
c40d7343efa60b18ad1ceb316eb337caeea79046cindi TOPO_WALK_ERR)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = -1;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi else
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = 0;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_walk_fini(hwp->hcw_wp);
918a0d8ae0916c29c35aae9b95c22b02a0c6e390robj topo_mod_free(mod, hwp, sizeof (struct hc_walk));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi } else {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = -1;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (plp->pl_prop != NULL)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi *out = plp->pl_prop;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_free(mod, plp, sizeof (struct prop_lookup));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi}
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi/*ARGSUSED*/
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int
c40d7343efa60b18ad1ceb316eb337caeea79046cindihc_pgrp_get(topo_mod_t *mod, tnode_t *node, void *pdata)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi{
c40d7343efa60b18ad1ceb316eb337caeea79046cindi int err = 0;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct prop_lookup *plp = (struct prop_lookup *)pdata;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (void) topo_prop_getpgrp(node, plp->pl_pgroup, &plp->pl_prop, &err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi}
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int
c40d7343efa60b18ad1ceb316eb337caeea79046cindihc_fmri_pgrp_get(topo_mod_t *mod, tnode_t *node, topo_version_t version,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *in, nvlist_t **out)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi{
c40d7343efa60b18ad1ceb316eb337caeea79046cindi int err;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct hc_walk *hwp;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct prop_lookup *plp;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (version > TOPO_METH_PGRP_GET_VERSION)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((plp = topo_mod_alloc(mod, sizeof (struct prop_lookup))) == NULL)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, EMOD_NOMEM));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = nvlist_lookup_string(in, TOPO_PROP_GROUP,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (char **)&plp->pl_pgroup);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err |= nvlist_lookup_nvlist(in, TOPO_PROP_RESOURCE, &plp->pl_rsrc);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (err != 0) {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_free(mod, plp, sizeof (struct prop_lookup));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi plp->pl_prop = NULL;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((hwp = hc_walk_init(mod, node, plp->pl_rsrc, hc_pgrp_get,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (void *)plp)) != NULL) {
78432d5ed5122db8b0bbfa41e00d063bf8ae7171cy if (topo_walk_step(hwp->hcw_wp, TOPO_WALK_CHILD) ==
c40d7343efa60b18ad1ceb316eb337caeea79046cindi TOPO_WALK_ERR)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = -1;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi else
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = 0;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_walk_fini(hwp->hcw_wp);
918a0d8ae0916c29c35aae9b95c22b02a0c6e390robj topo_mod_free(mod, hwp, sizeof (struct hc_walk));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi } else {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = -1;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (plp->pl_prop != NULL)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi *out = plp->pl_prop;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_free(mod, plp, sizeof (struct prop_lookup));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi}
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi/*ARGSUSED*/
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int
c40d7343efa60b18ad1ceb316eb337caeea79046cindihc_prop_setprop(topo_mod_t *mod, tnode_t *node, void *pdata)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi{
c40d7343efa60b18ad1ceb316eb337caeea79046cindi int err = 0;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct prop_lookup *plp = (struct prop_lookup *)pdata;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (void) topo_prop_setprop(node, plp->pl_pgroup, plp->pl_prop,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi plp->pl_flag, plp->pl_args, &err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi}
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi/*ARGSUSED*/
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int
c40d7343efa60b18ad1ceb316eb337caeea79046cindihc_fmri_prop_set(topo_mod_t *mod, tnode_t *node, topo_version_t version,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *in, nvlist_t **out)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi{
c40d7343efa60b18ad1ceb316eb337caeea79046cindi int err;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct hc_walk *hwp;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct prop_lookup *plp;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (version > TOPO_METH_PROP_SET_VERSION)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((plp = topo_mod_alloc(mod, sizeof (struct prop_lookup))) == NULL)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, EMOD_NOMEM));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = nvlist_lookup_string(in, TOPO_PROP_GROUP,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (char **)&plp->pl_pgroup);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err |= nvlist_lookup_nvlist(in, TOPO_PROP_RESOURCE, &plp->pl_rsrc);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err |= nvlist_lookup_nvlist(in, TOPO_PROP_VAL, &plp->pl_prop);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err |= nvlist_lookup_int32(in, TOPO_PROP_FLAG, &plp->pl_flag);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (err != 0) {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_free(mod, plp, sizeof (struct prop_lookup));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi /*
c40d7343efa60b18ad1ceb316eb337caeea79046cindi * Private args to prop method are optional
c40d7343efa60b18ad1ceb316eb337caeea79046cindi */
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((err = nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &plp->pl_args))
c40d7343efa60b18ad1ceb316eb337caeea79046cindi != 0) {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (err != ENOENT)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi else
c40d7343efa60b18ad1ceb316eb337caeea79046cindi plp->pl_args = NULL;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((hwp = hc_walk_init(mod, node, plp->pl_rsrc, hc_prop_setprop,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (void *)plp)) != NULL) {
78432d5ed5122db8b0bbfa41e00d063bf8ae7171cy if (topo_walk_step(hwp->hcw_wp, TOPO_WALK_CHILD) ==
c40d7343efa60b18ad1ceb316eb337caeea79046cindi TOPO_WALK_ERR)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = -1;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi else
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = 0;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_walk_fini(hwp->hcw_wp);
918a0d8ae0916c29c35aae9b95c22b02a0c6e390robj topo_mod_free(mod, hwp, sizeof (struct hc_walk));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi } else {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = -1;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_free(mod, plp, sizeof (struct prop_lookup));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi}
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindistruct hc_args {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *ha_fmri;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *ha_nvl;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye char *ha_method_name;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_version_t ha_method_ver;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi};
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hansonstatic int
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrockhc_auth_changed(nvlist_t *nva, nvlist_t *nvb, const char *propname)
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock{
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock char *stra, *strb;
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock if (nvlist_lookup_string(nva, propname, &stra) != 0 ||
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock nvlist_lookup_string(nvb, propname, &strb) != 0)
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson return (FMD_OBJ_STATE_UNKNOWN);
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock if (strcmp(stra, strb) != 0)
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson return (FMD_OBJ_STATE_REPLACED);
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock else
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson return (FMD_OBJ_STATE_STILL_PRESENT);
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock}
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int
c40d7343efa60b18ad1ceb316eb337caeea79046cindihc_is_present(topo_mod_t *mod, tnode_t *node, void *pdata)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi{
c40d7343efa60b18ad1ceb316eb337caeea79046cindi int err;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct hc_args *hap = (struct hc_args *)pdata;
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock nvlist_t *rsrc;
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock boolean_t present;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi /*
c40d7343efa60b18ad1ceb316eb337caeea79046cindi * check with the enumerator that created this FMRI
c40d7343efa60b18ad1ceb316eb337caeea79046cindi * (topo node)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi */
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (topo_method_invoke(node, TOPO_METH_PRESENT,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi TOPO_METH_PRESENT_VERSION, hap->ha_fmri, &hap->ha_nvl,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi &err) < 0) {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi /*
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock * If the method exists but failed for some other reason,
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock * propagate the error as making any decision over presence is
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock * impossible.
c40d7343efa60b18ad1ceb316eb337caeea79046cindi */
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock if (err != ETOPO_METHOD_NOTSUP)
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock return (err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock /*
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock * Check the authority information. If the part id or serial
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock * number doesn't match, then it isn't the same FMRI.
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock * Otherwise, assume presence.
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock */
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock if (topo_node_resource(node, &rsrc, &err) != 0)
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock return (err);
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock present = B_TRUE;
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock if (hc_auth_changed(hap->ha_fmri, rsrc,
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson FM_FMRI_HC_SERIAL_ID) == FMD_OBJ_STATE_REPLACED ||
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock hc_auth_changed(hap->ha_fmri, rsrc,
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson FM_FMRI_HC_PART) == FMD_OBJ_STATE_REPLACED) {
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock present = B_FALSE;
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock }
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock nvlist_free(rsrc);
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock if (topo_mod_nvalloc(mod, &hap->ha_nvl, NV_UNIQUE_NAME) != 0)
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock return (EMOD_NOMEM);
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock if (nvlist_add_uint32(hap->ha_nvl,
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock TOPO_METH_PRESENT_RET, present) != 0) {
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock nvlist_free(hap->ha_nvl);
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock hap->ha_nvl = NULL;
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock return (EMOD_NOMEM);
7793aa8b1cb26c7fc1397aa9db2364098fc25543Eric Schrock }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
24db46411fd54f70c35b94bb952eb7ba040e43b4eschrock return (0);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi}
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int
c40d7343efa60b18ad1ceb316eb337caeea79046cindihc_fmri_present(topo_mod_t *mod, tnode_t *node, topo_version_t version,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *in, nvlist_t **out)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi{
c40d7343efa60b18ad1ceb316eb337caeea79046cindi int err;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct hc_walk *hwp;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct hc_args *hap;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (version > TOPO_METH_PRESENT_VERSION)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((hap = topo_mod_alloc(mod, sizeof (struct hc_args))) == NULL)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, EMOD_NOMEM));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi hap->ha_fmri = in;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi hap->ha_nvl = NULL;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((hwp = hc_walk_init(mod, node, hap->ha_fmri, hc_is_present,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (void *)hap)) != NULL) {
78432d5ed5122db8b0bbfa41e00d063bf8ae7171cy if (topo_walk_step(hwp->hcw_wp, TOPO_WALK_CHILD) ==
c40d7343efa60b18ad1ceb316eb337caeea79046cindi TOPO_WALK_ERR)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = -1;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi else
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = 0;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_walk_fini(hwp->hcw_wp);
918a0d8ae0916c29c35aae9b95c22b02a0c6e390robj topo_mod_free(mod, hwp, sizeof (struct hc_walk));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi } else {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = -1;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (hap->ha_nvl != NULL)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi *out = hap->ha_nvl;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_free(mod, hap, sizeof (struct hc_args));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi}
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephhstatic int
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephhhc_is_replaced(topo_mod_t *mod, tnode_t *node, void *pdata)
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh{
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh int err;
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh struct hc_args *hap = (struct hc_args *)pdata;
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh uint32_t present = 0;
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson nvlist_t *rsrc;
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson uint32_t rval = FMD_OBJ_STATE_UNKNOWN;
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh /*
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh * check with the enumerator that created this FMRI
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh * (topo node)
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh */
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh if (topo_method_invoke(node, TOPO_METH_REPLACED,
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh TOPO_METH_REPLACED_VERSION, hap->ha_fmri, &hap->ha_nvl,
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh &err) < 0) {
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh /*
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * If the method exists but failed for some other
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * reason, propagate the error as making any decision
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * over presence is impossible.
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson */
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson if (err != ETOPO_METHOD_NOTSUP)
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson return (err);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson /*
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * Enumerator didn't provide "replaced" method -
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh * try "present" method
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh */
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh if (topo_method_invoke(node, TOPO_METH_PRESENT,
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh TOPO_METH_PRESENT_VERSION, hap->ha_fmri, &hap->ha_nvl,
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh &err) < 0) {
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson /*
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * If the method exists but failed for some other
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * reason, propagate the error as making any decision
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * over presence is impossible.
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson */
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson if (err != ETOPO_METHOD_NOTSUP)
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson return (err);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson /*
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * Enumerator didn't provide "present" method either -
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * so check the authority information. If the part id
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * or serial number doesn't match, then it isn't the
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * same FMRI. Otherwise, if we have a serial number and
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson * it hasn't changed, then assume it is the same FMRI.
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson */
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson if (topo_node_resource(node, &rsrc, &err) != 0)
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson return (err);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson rval = hc_auth_changed(hap->ha_fmri, rsrc,
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson FM_FMRI_HC_PART);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson if (rval != FMD_OBJ_STATE_REPLACED)
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson rval = hc_auth_changed(hap->ha_fmri, rsrc,
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson FM_FMRI_HC_SERIAL_ID);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson nvlist_free(rsrc);
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston if (topo_mod_nvalloc(mod, &hap->ha_nvl,
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston NV_UNIQUE_NAME) != 0)
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson return (EMOD_NOMEM);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson if (nvlist_add_uint32(hap->ha_nvl,
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson TOPO_METH_REPLACED_RET, rval) != 0) {
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson nvlist_free(hap->ha_nvl);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson hap->ha_nvl = NULL;
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston return (ETOPO_PROP_NVL);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson }
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh } else {
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh (void) nvlist_lookup_uint32(hap->ha_nvl,
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh TOPO_METH_PRESENT_RET, &present);
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh (void) nvlist_remove(hap->ha_nvl,
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh TOPO_METH_PRESENT_RET, DATA_TYPE_UINT32);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson if (nvlist_add_uint32(hap->ha_nvl,
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson TOPO_METH_REPLACED_RET,
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson present ? FMD_OBJ_STATE_UNKNOWN :
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson FMD_OBJ_STATE_NOT_PRESENT) != 0) {
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson nvlist_free(hap->ha_nvl);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson hap->ha_nvl = NULL;
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson return (ETOPO_PROP_NVL);
6e1fa242609208de48dfe1939b8814d4dff455a5Stephen Hanson }
e5dcf7beb7c949f9234713d5818b581ec3825443Robert Johnston }
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh }
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh return (0);
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh}
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephhstatic int
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephhhc_fmri_replaced(topo_mod_t *mod, tnode_t *node, topo_version_t version,
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh nvlist_t *in, nvlist_t **out)
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh{
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh int err;
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh struct hc_walk *hwp;
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh struct hc_args *hap;
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh if (version > TOPO_METH_REPLACED_VERSION)
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh if ((hap = topo_mod_alloc(mod, sizeof (struct hc_args))) == NULL)
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh return (topo_mod_seterrno(mod, EMOD_NOMEM));
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh hap->ha_fmri = in;
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh hap->ha_nvl = NULL;
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh if ((hwp = hc_walk_init(mod, node, hap->ha_fmri, hc_is_replaced,
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh (void *)hap)) != NULL) {
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh if (topo_walk_step(hwp->hcw_wp, TOPO_WALK_CHILD) ==
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh TOPO_WALK_ERR)
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh err = -1;
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh else
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh err = 0;
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh topo_walk_fini(hwp->hcw_wp);
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh topo_mod_free(mod, hwp, sizeof (struct hc_walk));
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh } else {
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh err = -1;
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh }
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh if (hap->ha_nvl != NULL)
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh *out = hap->ha_nvl;
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh topo_mod_free(mod, hap, sizeof (struct hc_args));
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh return (err);
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh}
25c6ff4b77fcddf4097ce78a8277275ca603b46cstephh
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int
c40d7343efa60b18ad1ceb316eb337caeea79046cindihc_unusable(topo_mod_t *mod, tnode_t *node, void *pdata)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi{
c40d7343efa60b18ad1ceb316eb337caeea79046cindi int err;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct hc_args *hap = (struct hc_args *)pdata;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi /*
c40d7343efa60b18ad1ceb316eb337caeea79046cindi * check with the enumerator that created this FMRI
c40d7343efa60b18ad1ceb316eb337caeea79046cindi * (topo node)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi */
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (topo_method_invoke(node, TOPO_METH_UNUSABLE,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi TOPO_METH_UNUSABLE_VERSION, hap->ha_fmri, &hap->ha_nvl,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi &err) < 0) {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi /*
c40d7343efa60b18ad1ceb316eb337caeea79046cindi * Err on the side of caution and return usable
c40d7343efa60b18ad1ceb316eb337caeea79046cindi */
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (topo_mod_nvalloc(mod, &hap->ha_nvl, NV_UNIQUE_NAME) == 0)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (nvlist_add_uint32(hap->ha_nvl,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi TOPO_METH_UNUSABLE_RET, 0) == 0)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (0);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (ETOPO_PROP_NVL);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (0);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi}
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindistatic int
c40d7343efa60b18ad1ceb316eb337caeea79046cindihc_fmri_unusable(topo_mod_t *mod, tnode_t *node, topo_version_t version,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi nvlist_t *in, nvlist_t **out)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi{
c40d7343efa60b18ad1ceb316eb337caeea79046cindi int err;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct hc_walk *hwp;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi struct hc_args *hap;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (version > TOPO_METH_UNUSABLE_VERSION)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((hap = topo_mod_alloc(mod, sizeof (struct hc_args))) == NULL)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (topo_mod_seterrno(mod, EMOD_NOMEM));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi hap->ha_fmri = in;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi hap->ha_nvl = NULL;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if ((hwp = hc_walk_init(mod, node, hap->ha_fmri, hc_unusable,
c40d7343efa60b18ad1ceb316eb337caeea79046cindi (void *)hap)) != NULL) {
78432d5ed5122db8b0bbfa41e00d063bf8ae7171cy if (topo_walk_step(hwp->hcw_wp, TOPO_WALK_CHILD) ==
c40d7343efa60b18ad1ceb316eb337caeea79046cindi TOPO_WALK_ERR)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = -1;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi else
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = 0;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_walk_fini(hwp->hcw_wp);
918a0d8ae0916c29c35aae9b95c22b02a0c6e390robj topo_mod_free(mod, hwp, sizeof (struct hc_walk));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi } else {
c40d7343efa60b18ad1ceb316eb337caeea79046cindi err = -1;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi }
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi if (hap->ha_nvl != NULL)
c40d7343efa60b18ad1ceb316eb337caeea79046cindi *out = hap->ha_nvl;
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi topo_mod_free(mod, hap, sizeof (struct hc_args));
c40d7343efa60b18ad1ceb316eb337caeea79046cindi
c40d7343efa60b18ad1ceb316eb337caeea79046cindi return (err);
c40d7343efa60b18ad1ceb316eb337caeea79046cindi}
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robjstruct fac_lookup {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj const char *fl_fac_type;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj uint32_t fl_fac_subtype;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj#ifdef _LP64
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj uint64_t fl_callback;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj uint64_t fl_callback_args;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj#else
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj uint32_t fl_callback;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj uint32_t fl_callback_args;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj#endif
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_t *fl_rsrc;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_t *fl_fac_rsrc;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj};
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robjstatic int
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robjhc_fac_get(topo_mod_t *mod, tnode_t *node, void *pdata)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj{
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj struct fac_lookup *flp = (struct fac_lookup *)pdata;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_walk_cb_t cb = (topo_walk_cb_t)flp->fl_callback;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_faclist_t faclist, *tmp;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj int err, ret = 0;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj /*
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * Lookup the specified facility node. Return with an error if we can't
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * find it.
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj */
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (topo_node_facility(mod->tm_hdl, node, flp->fl_fac_type,
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj flp->fl_fac_subtype, &faclist, &err) != 0) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_dprintf(mod, "hc_fac_get: topo_node_facility "
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj "failed\n");
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (TOPO_WALK_ERR);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj /*
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * Invoke user's callback for each facility node in the topo list,
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * passing in a pointer to the facility node
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj */
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj for (tmp = topo_list_next(&faclist.tf_list); tmp != NULL;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj tmp = topo_list_next(tmp)) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if ((err = cb(mod->tm_hdl, tmp->tf_node,
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj (void *)flp->fl_callback_args)) != 0) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj (void) topo_mod_seterrno(mod, err);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_dprintf(mod, "hc_fac_get: callback failed: "
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj "%s\n ", topo_mod_errmsg(mod));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj ret = TOPO_WALK_ERR;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj break;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj while ((tmp = topo_list_next(&faclist.tf_list)) != NULL) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_list_delete(&faclist.tf_list, tmp);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_free(mod, tmp, sizeof (topo_faclist_t));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (ret);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj}
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robjstatic int
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robjhc_fmri_facility(topo_mod_t *mod, tnode_t *node, topo_version_t version,
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj nvlist_t *in, nvlist_t **out)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj{
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj int err = 0;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj struct hc_walk *hwp;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj struct fac_lookup *flp;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (version > TOPO_METH_FACILITY_VERSION)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if ((flp = topo_mod_alloc(mod, sizeof (struct fac_lookup))) == NULL)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (topo_mod_seterrno(mod, EMOD_NOMEM));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj /*
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * lookup arguments: hw resource, facility type, facility subtype,
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj * callback and callback args
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj */
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj err = nvlist_lookup_nvlist(in, TOPO_PROP_RESOURCE, &flp->fl_rsrc);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj err |= nvlist_lookup_string(in, FM_FMRI_FACILITY_TYPE,
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj (char **)&flp->fl_fac_type);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj err |= nvlist_lookup_uint32(in, "type", &flp->fl_fac_subtype);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj#ifdef _LP64
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj err |= nvlist_lookup_uint64(in, "callback", &flp->fl_callback);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj err |= nvlist_lookup_uint64(in, "callback-args",
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj &flp->fl_callback_args);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj#else
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj err |= nvlist_lookup_uint32(in, "callback", &flp->fl_callback);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj err |= nvlist_lookup_uint32(in, "callback-args",
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj &flp->fl_callback_args);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj#endif
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (err != 0) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_dprintf(mod, "hc_fmri_facility: failed to construct "
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj "walker arg nvlist\n");
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_free(mod, flp, sizeof (struct fac_lookup));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj flp->fl_fac_rsrc = NULL;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if ((hwp = hc_walk_init(mod, node, flp->fl_rsrc, hc_fac_get,
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj (void *)flp)) != NULL) {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (topo_walk_step(hwp->hcw_wp, TOPO_WALK_CHILD) ==
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj TOPO_WALK_ERR)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj err = -1;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj else
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj err = 0;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_walk_fini(hwp->hcw_wp);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_free(mod, hwp, sizeof (struct hc_walk));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj } else {
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_dprintf(mod, "hc_fmri_facility: failed to initialize "
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj "hc walker\n");
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj err = -1;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj }
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj if (flp->fl_fac_rsrc != NULL)
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj *out = flp->fl_fac_rsrc;
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj topo_mod_free(mod, flp, sizeof (struct fac_lookup));
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj return (err);
825ba0f20a74fd9c5d0d1ce2c195da2cc88a7f77robj}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye/* ARGSUSED */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic int
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yehc_expand(topo_mod_t *mod, tnode_t *node, void *pdata)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye int err;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t *nvl;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye const char **namep;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye struct hc_args *hap = (struct hc_args *)pdata;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye const char *names[] = {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye FM_FMRI_HC_SERIAL_ID,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye FM_FMRI_HC_PART,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye FM_FMRI_HC_REVISION,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye NULL
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye };
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (topo_node_resource(node, &nvl, &err) != 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (ETOPO_METHOD_FAIL);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye for (namep = names; *namep != NULL; namep++) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye char *in_val, *node_val;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (nvlist_lookup_string(nvl, *namep, &node_val) != 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye continue;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (nvlist_lookup_string(hap->ha_fmri, *namep, &in_val) == 0) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (strcmp(in_val, node_val) == 0)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye continue;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye (void) nvlist_remove(hap->ha_fmri, *namep,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye DATA_TYPE_STRING);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (nvlist_add_string(hap->ha_fmri, *namep, node_val) != 0) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_free(nvl);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (ETOPO_PROP_NVL);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_free(nvl);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (0);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye/* ARGSUSED */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic int
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yehc_fmri_expand(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 int err;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye struct hc_walk *hwp;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye struct hc_args *hap;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (version > TOPO_METH_EXPAND_VERSION)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if ((hap = topo_mod_alloc(mod, sizeof (struct hc_args))) == NULL)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, EMOD_NOMEM));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hap->ha_fmri = in;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hap->ha_nvl = NULL;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if ((hwp = hc_walk_init(mod, node, hap->ha_fmri, hc_expand,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye (void *)hap)) != NULL) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (topo_walk_step(hwp->hcw_wp, TOPO_WALK_CHILD) ==
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye TOPO_WALK_ERR)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye err = -1;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye err = 0;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_walk_fini(hwp->hcw_wp);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye } else {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye err = -1;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_mod_free(mod, hwp, sizeof (struct hc_walk));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye /* expand method should not return out nvlist */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye assert(hap->ha_nvl == NULL);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_mod_free(mod, hap, sizeof (struct hc_args));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (err);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic int
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yehc_retire_subr(topo_mod_t *mod, tnode_t *node, void *pdata)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye int err, rc;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye struct hc_args *hap = (struct hc_args *)pdata;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_mod_dprintf(mod, "hc_retire_subr: invoking method %s\n",
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hap->ha_method_name);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye /*
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye * check with the enumerator that created this FMRI
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye * (topo node)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye */
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye rc = topo_method_invoke(node, hap->ha_method_name,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hap->ha_method_ver, hap->ha_fmri, &hap->ha_nvl, &err);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_mod_dprintf(mod, "hc_retire_subr: invoking method %s "
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye "returned %d\n", hap->ha_method_name, rc);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (rc < 0 ? err : 0);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic int
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yehc_fmri_retire_subr(topo_mod_t *mod, tnode_t *node, char *method_name,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_version_t builtin_version, topo_version_t version, nvlist_t *in,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye nvlist_t **out)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye{
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye int err;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye struct hc_walk *hwp;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye struct hc_args *hap;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (version > builtin_version)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if ((hap = topo_mod_alloc(mod, sizeof (struct hc_args))) == NULL)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (topo_mod_seterrno(mod, EMOD_NOMEM));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hap->ha_fmri = in;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hap->ha_nvl = NULL;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hap->ha_method_name = method_name;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye hap->ha_method_ver = version;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if ((hwp = hc_walk_init(mod, node, hap->ha_fmri, hc_retire_subr,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye (void *)hap)) != NULL) {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (topo_walk_step(hwp->hcw_wp, TOPO_WALK_CHILD) ==
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye TOPO_WALK_ERR)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye err = -1;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye else
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye err = 0;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_walk_fini(hwp->hcw_wp);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye } else {
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye err = -1;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye }
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_mod_free(mod, hwp, sizeof (struct hc_walk));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye if (hap->ha_nvl != NULL)
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye *out = hap->ha_nvl;
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye topo_mod_free(mod, hap, sizeof (struct hc_args));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye return (err);
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic int
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yehc_fmri_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 return (hc_fmri_retire_subr(mod, node, TOPO_METH_RETIRE,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye TOPO_METH_RETIRE_VERSION, version, in, out));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic int
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yehc_fmri_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 return (hc_fmri_retire_subr(mod, node, TOPO_METH_UNRETIRE,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye TOPO_METH_UNRETIRE_VERSION, version, in, out));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yestatic int
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Yehc_fmri_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 return (hc_fmri_retire_subr(mod, node, TOPO_METH_SERVICE_STATE,
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye TOPO_METH_SERVICE_STATE_VERSION, version, in, out));
e4b86885570d77af552e9cf94f142f4d744fb8c8Cheng Sean Ye}