908f1e1388f616898b4e515d343c0414f2a6472esd/*
908f1e1388f616898b4e515d343c0414f2a6472esd * CDDL HEADER START
908f1e1388f616898b4e515d343c0414f2a6472esd *
908f1e1388f616898b4e515d343c0414f2a6472esd * The contents of this file are subject to the terms of the
908f1e1388f616898b4e515d343c0414f2a6472esd * Common Development and Distribution License (the "License").
908f1e1388f616898b4e515d343c0414f2a6472esd * You may not use this file except in compliance with the License.
908f1e1388f616898b4e515d343c0414f2a6472esd *
908f1e1388f616898b4e515d343c0414f2a6472esd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
908f1e1388f616898b4e515d343c0414f2a6472esd * or http://www.opensolaris.org/os/licensing.
908f1e1388f616898b4e515d343c0414f2a6472esd * See the License for the specific language governing permissions
908f1e1388f616898b4e515d343c0414f2a6472esd * and limitations under the License.
908f1e1388f616898b4e515d343c0414f2a6472esd *
908f1e1388f616898b4e515d343c0414f2a6472esd * When distributing Covered Code, include this CDDL HEADER in each
908f1e1388f616898b4e515d343c0414f2a6472esd * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
908f1e1388f616898b4e515d343c0414f2a6472esd * If applicable, add the following below this CDDL HEADER, with the
908f1e1388f616898b4e515d343c0414f2a6472esd * fields enclosed by brackets "[]" replaced with your own identifying
908f1e1388f616898b4e515d343c0414f2a6472esd * information: Portions Copyright [yyyy] [name of copyright owner]
908f1e1388f616898b4e515d343c0414f2a6472esd *
908f1e1388f616898b4e515d343c0414f2a6472esd * CDDL HEADER END
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd/*
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd/*
908f1e1388f616898b4e515d343c0414f2a6472esd * Walk the LDOM PRI component nodes and create appropriate topology nodes
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd#include <sys/types.h>
908f1e1388f616898b4e515d343c0414f2a6472esd#include <sys/time.h>
908f1e1388f616898b4e515d343c0414f2a6472esd#include <stddef.h>
908f1e1388f616898b4e515d343c0414f2a6472esd#include <inttypes.h>
908f1e1388f616898b4e515d343c0414f2a6472esd#include <strings.h>
908f1e1388f616898b4e515d343c0414f2a6472esd#include <string.h>
908f1e1388f616898b4e515d343c0414f2a6472esd#include <libuutil.h>
908f1e1388f616898b4e515d343c0414f2a6472esd#include <libnvpair.h>
908f1e1388f616898b4e515d343c0414f2a6472esd#include <sys/mdesc.h>
908f1e1388f616898b4e515d343c0414f2a6472esd#include <fm/topo_mod.h>
908f1e1388f616898b4e515d343c0414f2a6472esd#include <fm/topo_hc.h>
908f1e1388f616898b4e515d343c0414f2a6472esd#include "pi_impl.h"
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd#define PI_STR_MIN "instance_min"
908f1e1388f616898b4e515d343c0414f2a6472esd#define PI_STR_MAX "instance_max"
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd/*
908f1e1388f616898b4e515d343c0414f2a6472esd * Allow for custom topo node creation routines based on topo-hc-name.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esdstruct pi_enum_functions_s {
908f1e1388f616898b4e515d343c0414f2a6472esd pi_enum_fn_t *func;
908f1e1388f616898b4e515d343c0414f2a6472esd char *hc_name; /* topo-hc-name */
908f1e1388f616898b4e515d343c0414f2a6472esd};
908f1e1388f616898b4e515d343c0414f2a6472esdtypedef struct pi_enum_functions_s pi_enum_functions_t;
908f1e1388f616898b4e515d343c0414f2a6472esd
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yestruct pi_methods_s {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye topo_method_t *meths;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye char *hc_name;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye};
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yetypedef struct pi_methods_s pi_methods_t;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yeextern topo_method_t pi_cpu_methods[], pi_mem_methods[];
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
908f1e1388f616898b4e515d343c0414f2a6472esd/*
908f1e1388f616898b4e515d343c0414f2a6472esd * List of custom enumerators for PRI nodes that require them. The most
908f1e1388f616898b4e515d343c0414f2a6472esd * common nodes are listed first.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esdstatic pi_enum_functions_t pi_enum_fns_builtin[] = {
72612f86fafbe2510a166b48e158c9031e0dd63bScott Davenport {pi_enum_cpu, STRAND},
908f1e1388f616898b4e515d343c0414f2a6472esd {pi_enum_cpu, CPU},
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye {pi_enum_mem, DIMM},
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye {pi_enum_cpu, CORE},
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye {pi_enum_cpu, CHIP},
73a0bd151c1115bf39cc2caa30c7cbfdd86361c1Tom Pothier {pi_enum_hostbridge, HOSTBRIDGE},
908f1e1388f616898b4e515d343c0414f2a6472esd {pi_enum_pciexrc, PCIEX_ROOT},
908f1e1388f616898b4e515d343c0414f2a6472esd {pi_enum_niu, NIU},
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier {pi_enum_bay, BAY},
908f1e1388f616898b4e515d343c0414f2a6472esd {NULL, NULL}
908f1e1388f616898b4e515d343c0414f2a6472esd};
908f1e1388f616898b4e515d343c0414f2a6472esdstatic nvlist_t *pi_enum_fns;
908f1e1388f616898b4e515d343c0414f2a6472esd
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye/* List of methods that will be registered in the nodes. */
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yestatic pi_methods_t pi_meths_builtin[] = {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye {pi_cpu_methods, CHIP},
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye {pi_cpu_methods, CORE},
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye {pi_cpu_methods, STRAND},
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye {pi_cpu_methods, CPU},
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye {pi_mem_methods, DIMM},
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye {NULL, NULL}
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye};
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Yenvlist_t *pi_meths;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd/*
908f1e1388f616898b4e515d343c0414f2a6472esd * In order to create a topology node from a PRI MDE node we need to know the
908f1e1388f616898b4e515d343c0414f2a6472esd * topology parent node that should be used. So, after creating a topology
908f1e1388f616898b4e515d343c0414f2a6472esd * node from an MDE node, we associate children of the MDE node with the new
908f1e1388f616898b4e515d343c0414f2a6472esd * topology node. Thus, when the children are visited we can know the
908f1e1388f616898b4e515d343c0414f2a6472esd * appropriate parent topology node to use.
908f1e1388f616898b4e515d343c0414f2a6472esd *
908f1e1388f616898b4e515d343c0414f2a6472esd * We take advantage of the libtopo threading model here, which guarantees a
908f1e1388f616898b4e515d343c0414f2a6472esd * single thread and a single invocation at a time for an enumerator. This
908f1e1388f616898b4e515d343c0414f2a6472esd * makes using a file-global safe.
908f1e1388f616898b4e515d343c0414f2a6472esd */
021ceb9857f712f245edda92c7eb82f0a3a83acbTom Pothierstatic uu_list_pool_t *walker_pool = NULL;
021ceb9857f712f245edda92c7eb82f0a3a83acbTom Pothierstatic uu_list_t *walker_list = NULL;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esdstruct pi_walkernode_s {
908f1e1388f616898b4e515d343c0414f2a6472esd uu_list_node_t walker_node;
908f1e1388f616898b4e515d343c0414f2a6472esd tnode_t *t_parent; /* Parent topology node */
908f1e1388f616898b4e515d343c0414f2a6472esd mde_cookie_t mde_node; /* Child MDE node index */
908f1e1388f616898b4e515d343c0414f2a6472esd};
908f1e1388f616898b4e515d343c0414f2a6472esdtypedef struct pi_walkernode_s pi_walkernode_t;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd/* The routine called for each node in the PRI while walking the graph */
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int pi_walker_node(md_t *, mde_cookie_t, mde_cookie_t, void *);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd/*
908f1e1388f616898b4e515d343c0414f2a6472esd * Create a sub-range for a given PRI node and associate the given topology
908f1e1388f616898b4e515d343c0414f2a6472esd * node with the children.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int pi_walker_node_range(topo_mod_t *, md_t *, tnode_t *, mde_cookie_t);
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int pi_walker_node_create(topo_mod_t *, md_t *, mde_cookie_t, tnode_t *,
908f1e1388f616898b4e515d343c0414f2a6472esd topo_instance_t, tnode_t **);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd/* Routines to handle the list of topology parents and mde_nodes */
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int pi_walkerlist_compare(const void *, const void *, void *);
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int pi_walkerlist_create(topo_mod_t *);
908f1e1388f616898b4e515d343c0414f2a6472esdstatic void pi_walkerlist_destroy(topo_mod_t *);
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int pi_walkerlist_add(topo_mod_t *, tnode_t *, mde_cookie_t);
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int pi_walkerlist_addtype(topo_mod_t *, nvlist_t *, char *, uint32_t,
908f1e1388f616898b4e515d343c0414f2a6472esd uint32_t);
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int pi_walkerlist_find(topo_mod_t *, mde_cookie_t, tnode_t **);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esdint
908f1e1388f616898b4e515d343c0414f2a6472esdpi_walker_init(topo_mod_t *mod)
908f1e1388f616898b4e515d343c0414f2a6472esd{
908f1e1388f616898b4e515d343c0414f2a6472esd int result;
908f1e1388f616898b4e515d343c0414f2a6472esd pi_enum_functions_t *fp;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye pi_methods_t *mp;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd result = topo_mod_nvalloc(mod, &pi_enum_fns, NV_UNIQUE_NAME);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye result |= topo_mod_nvalloc(mod, &pi_meths, NV_UNIQUE_NAME);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "pi_walker_init failed\n");
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_free(pi_enum_fns);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_free(pi_meths);
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Add the builtin functions to the list */
908f1e1388f616898b4e515d343c0414f2a6472esd fp = pi_enum_fns_builtin;
908f1e1388f616898b4e515d343c0414f2a6472esd while (fp != NULL && fp->hc_name != NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd uint64_t faddr;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd faddr = (uint64_t)(uintptr_t)*(fp->func);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye result |= nvlist_add_uint64(pi_enum_fns, fp->hc_name, faddr);
908f1e1388f616898b4e515d343c0414f2a6472esd fp++;
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye /* Add the builtin methods to the list */
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye mp = pi_meths_builtin;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye while (mp != NULL && mp->hc_name != NULL) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye uint64_t maddr;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye maddr = (uint64_t)(uintptr_t)mp->meths;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye result |= nvlist_add_uint64(pi_meths, mp->hc_name, maddr);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye mp++;
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye if (result != 0) {
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye topo_mod_dprintf(mod, "pi_walker_init failed\n");
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_free(pi_enum_fns);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_free(pi_meths);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye return (-1);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
908f1e1388f616898b4e515d343c0414f2a6472esd return (0);
908f1e1388f616898b4e515d343c0414f2a6472esd}
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esdvoid
908f1e1388f616898b4e515d343c0414f2a6472esdpi_walker_fini(topo_mod_t *mod)
908f1e1388f616898b4e515d343c0414f2a6472esd{
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "pi_walker_fini: enter\n");
908f1e1388f616898b4e515d343c0414f2a6472esd nvlist_free(pi_enum_fns);
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye nvlist_free(pi_meths);
908f1e1388f616898b4e515d343c0414f2a6472esd}
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd/*
908f1e1388f616898b4e515d343c0414f2a6472esd * Begin to walk the machine description array starting at the given PRI node.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esdint
908f1e1388f616898b4e515d343c0414f2a6472esdpi_walker(pi_enum_t *pip, tnode_t *t_parent, const char *hc_name,
908f1e1388f616898b4e515d343c0414f2a6472esd mde_cookie_t mde_node, mde_str_cookie_t component_cookie,
908f1e1388f616898b4e515d343c0414f2a6472esd mde_str_cookie_t arc_cookie)
908f1e1388f616898b4e515d343c0414f2a6472esd{
908f1e1388f616898b4e515d343c0414f2a6472esd int result;
908f1e1388f616898b4e515d343c0414f2a6472esd hrtime_t starttime;
908f1e1388f616898b4e515d343c0414f2a6472esd hrtime_t endtime;
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_t *mod;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd if (pip == NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd mod = pip->mod;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd starttime = gethrtime();
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "walker starting at node_0x%llx\n",
908f1e1388f616898b4e515d343c0414f2a6472esd mde_node);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * Create a list to store topology nodes and their associated machine
908f1e1388f616898b4e515d343c0414f2a6472esd * description index. This allows the code to know the parent of a
908f1e1388f616898b4e515d343c0414f2a6472esd * node when creating topology entries.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd result = pi_walkerlist_create(mod);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "walker could not create list\n");
908f1e1388f616898b4e515d343c0414f2a6472esd return (result);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Create a walker node for the parent of the start node */
908f1e1388f616898b4e515d343c0414f2a6472esd result = pi_walkerlist_add(mod, t_parent, mde_node);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd pi_walkerlist_destroy(mod);
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "walker could not add to list\n");
186d582bd9dbcd38e0aeea49036d47d3426a3536Surya Prakki (void) topo_mod_seterrno(mod, EMOD_UKNOWN_ENUM);
908f1e1388f616898b4e515d343c0414f2a6472esd return (result);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * This is a top-level node. Make sure we call the top level
908f1e1388f616898b4e515d343c0414f2a6472esd * enumerator if there is not already a custom enumerator registered.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd if (! nvlist_exists(pi_enum_fns, hc_name)) {
908f1e1388f616898b4e515d343c0414f2a6472esd uint64_t faddr;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * There is no enumerator function registered for this
908f1e1388f616898b4e515d343c0414f2a6472esd * hc name. Automatically register the top level node
908f1e1388f616898b4e515d343c0414f2a6472esd * enumerator function.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd faddr = (uint64_t)(uintptr_t)pi_enum_top;
908f1e1388f616898b4e515d343c0414f2a6472esd result = nvlist_add_uint64(pi_enum_fns, hc_name, faddr);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd pi_walkerlist_destroy(mod);
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod,
908f1e1388f616898b4e515d343c0414f2a6472esd "walker could not register enumerator for type "
908f1e1388f616898b4e515d343c0414f2a6472esd "%s\n", hc_name);
186d582bd9dbcd38e0aeea49036d47d3426a3536Surya Prakki (void) topo_mod_seterrno(mod, EMOD_UKNOWN_ENUM);
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod,
908f1e1388f616898b4e515d343c0414f2a6472esd "walker registered pi_enum_top enumerator for type %s\n",
908f1e1388f616898b4e515d343c0414f2a6472esd hc_name);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Walk the machine description list starting at the given node */
908f1e1388f616898b4e515d343c0414f2a6472esd result = md_walk_dag(pip->mdp, mde_node, component_cookie, arc_cookie,
908f1e1388f616898b4e515d343c0414f2a6472esd pi_walker_node, (void *)pip);
908f1e1388f616898b4e515d343c0414f2a6472esd switch (result) {
908f1e1388f616898b4e515d343c0414f2a6472esd case 0:
908f1e1388f616898b4e515d343c0414f2a6472esd /* Successful completion */
908f1e1388f616898b4e515d343c0414f2a6472esd /* DO NOTHING */
908f1e1388f616898b4e515d343c0414f2a6472esd break;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd case MDE_WALK_ERROR:
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * Store that we have a partial enumeration and return
908f1e1388f616898b4e515d343c0414f2a6472esd * that we have encountered an error.
908f1e1388f616898b4e515d343c0414f2a6472esd */
186d582bd9dbcd38e0aeea49036d47d3426a3536Surya Prakki (void) topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM);
908f1e1388f616898b4e515d343c0414f2a6472esd result = -1;
908f1e1388f616898b4e515d343c0414f2a6472esd break;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd default:
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * This should not happen. We want to always produce
908f1e1388f616898b4e515d343c0414f2a6472esd * as complete a topology as possible, even in the face
908f1e1388f616898b4e515d343c0414f2a6472esd * of errors, however, so set an error and continue.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod,
908f1e1388f616898b4e515d343c0414f2a6472esd "walker encountered invalid result: %d. "
908f1e1388f616898b4e515d343c0414f2a6472esd "Continuing\n", result);
186d582bd9dbcd38e0aeea49036d47d3426a3536Surya Prakki (void) topo_mod_seterrno(mod, EMOD_UKNOWN_ENUM);
908f1e1388f616898b4e515d343c0414f2a6472esd result = 0;
908f1e1388f616898b4e515d343c0414f2a6472esd break;
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Destroy the walker list, which is no longer necessary */
908f1e1388f616898b4e515d343c0414f2a6472esd pi_walkerlist_destroy(mod);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "walker done with node_0x%llx\n", mde_node);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd endtime = gethrtime();
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "walker scan time %lld ms\n",
908f1e1388f616898b4e515d343c0414f2a6472esd (endtime-starttime)/MICROSEC);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd return (result);
908f1e1388f616898b4e515d343c0414f2a6472esd}
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd/*
908f1e1388f616898b4e515d343c0414f2a6472esd * Visited once for each node in the machine description. Creates a topo
908f1e1388f616898b4e515d343c0414f2a6472esd * node for the machine description node and associates it with it's parent,
908f1e1388f616898b4e515d343c0414f2a6472esd * by calling an appropriate creation routine for the node type.
908f1e1388f616898b4e515d343c0414f2a6472esd *
908f1e1388f616898b4e515d343c0414f2a6472esd * Output:
908f1e1388f616898b4e515d343c0414f2a6472esd * This routine returns MDE_WALK_NEXT, MDE_WALK_DONE or MDE_WALK_ERROR
908f1e1388f616898b4e515d343c0414f2a6472esd * only.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int
908f1e1388f616898b4e515d343c0414f2a6472esdpi_walker_node(md_t *mdp, mde_cookie_t parent_mde_node, mde_cookie_t mde_node,
908f1e1388f616898b4e515d343c0414f2a6472esd void *private)
908f1e1388f616898b4e515d343c0414f2a6472esd{
908f1e1388f616898b4e515d343c0414f2a6472esd int result;
908f1e1388f616898b4e515d343c0414f2a6472esd pi_enum_t *pip = (pi_enum_t *)private;
908f1e1388f616898b4e515d343c0414f2a6472esd uint64_t skip; /* flag in md to skip this node */
908f1e1388f616898b4e515d343c0414f2a6472esd tnode_t *t_parent; /* topo parent to this md node */
908f1e1388f616898b4e515d343c0414f2a6472esd tnode_t *t_node; /* topo parent to this md node */
908f1e1388f616898b4e515d343c0414f2a6472esd topo_instance_t inst;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_t *mod;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Make sure we have our private data */
908f1e1388f616898b4e515d343c0414f2a6472esd if (pip == NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd return (MDE_WALK_ERROR);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd mod = pip->mod;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(pip->mod,
908f1e1388f616898b4e515d343c0414f2a6472esd "walker processing node_0x%llx parent node 0x%llx\n",
908f1e1388f616898b4e515d343c0414f2a6472esd (uint64_t)mde_node, (uint64_t)parent_mde_node);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Should we skip this node ? */
908f1e1388f616898b4e515d343c0414f2a6472esd skip = pi_skip_node(mod, pip->mdp, mde_node);
908f1e1388f616898b4e515d343c0414f2a6472esd if (skip) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* Skip this node and continue to the next node */
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "walker skipping node_0x%llx\n",
908f1e1388f616898b4e515d343c0414f2a6472esd (uint64_t)mde_node);
908f1e1388f616898b4e515d343c0414f2a6472esd return (MDE_WALK_NEXT);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd result = pi_get_instance(mod, mdp, mde_node, &inst);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * No ID available to place this mde node in the topology so
908f1e1388f616898b4e515d343c0414f2a6472esd * we cannot create a topology node.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "walker skipping node_0x%llx: "
908f1e1388f616898b4e515d343c0414f2a6472esd "no instance\n", (uint64_t)mde_node);
186d582bd9dbcd38e0aeea49036d47d3426a3536Surya Prakki (void) topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM);
908f1e1388f616898b4e515d343c0414f2a6472esd return (MDE_WALK_NEXT);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * Find the parent topo node for this machine description node.
908f1e1388f616898b4e515d343c0414f2a6472esd *
908f1e1388f616898b4e515d343c0414f2a6472esd * If found, the element will also be removed from the list and the
908f1e1388f616898b4e515d343c0414f2a6472esd * memory used to keep track of it released. We will only visit an
908f1e1388f616898b4e515d343c0414f2a6472esd * MDE node once and so the memory is no longer needed.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd t_parent = NULL;
908f1e1388f616898b4e515d343c0414f2a6472esd result = pi_walkerlist_find(mod, mde_node, &t_parent);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0 || t_parent == NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * No parent was found or a NULL parent encountered. We
908f1e1388f616898b4e515d343c0414f2a6472esd * cannot create a new topology node without a parent (
908f1e1388f616898b4e515d343c0414f2a6472esd * even for top level nodes). We associate children of
908f1e1388f616898b4e515d343c0414f2a6472esd * this MDE node with a NULL parent to silently skip the
908f1e1388f616898b4e515d343c0414f2a6472esd * remainder of this MDE branch.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "no topo parent found for node_0x%llx\n",
908f1e1388f616898b4e515d343c0414f2a6472esd mde_node);
908f1e1388f616898b4e515d343c0414f2a6472esd result = pi_walker_node_range(mod, mdp, NULL, mde_node);
186d582bd9dbcd38e0aeea49036d47d3426a3536Surya Prakki (void) topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd return (result);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * We have the mde node instance and parent information.
908f1e1388f616898b4e515d343c0414f2a6472esd * Attempt to create a topology node for this mde node.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd t_node = NULL;
908f1e1388f616898b4e515d343c0414f2a6472esd result = pi_walker_node_create(mod, mdp, mde_node, t_parent, inst,
908f1e1388f616898b4e515d343c0414f2a6472esd &t_node);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != MDE_WALK_NEXT || t_node == NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * We have failed to create a new topology node based on
908f1e1388f616898b4e515d343c0414f2a6472esd * the current MDE node. We set partial enumeration and
908f1e1388f616898b4e515d343c0414f2a6472esd * return without associating the children of this MDE
908f1e1388f616898b4e515d343c0414f2a6472esd * node with a topology parent. This will propgate the
908f1e1388f616898b4e515d343c0414f2a6472esd * creation error down this MDE branch.
908f1e1388f616898b4e515d343c0414f2a6472esd */
186d582bd9dbcd38e0aeea49036d47d3426a3536Surya Prakki (void) topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM);
908f1e1388f616898b4e515d343c0414f2a6472esd return (result);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * Associate the new topology node with any children of this mde node.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd result = pi_walker_node_range(mod, mdp, t_node, mde_node);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "walker completed node_0x%llx result = %d\n",
908f1e1388f616898b4e515d343c0414f2a6472esd (uint64_t)mde_node, result);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd return (result);
908f1e1388f616898b4e515d343c0414f2a6472esd}
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int
908f1e1388f616898b4e515d343c0414f2a6472esdpi_walker_node_create(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node,
908f1e1388f616898b4e515d343c0414f2a6472esd tnode_t *t_parent, topo_instance_t inst, tnode_t **t_node)
908f1e1388f616898b4e515d343c0414f2a6472esd{
908f1e1388f616898b4e515d343c0414f2a6472esd int result;
908f1e1388f616898b4e515d343c0414f2a6472esd char *hc_name;
908f1e1388f616898b4e515d343c0414f2a6472esd uint64_t faddr;
908f1e1388f616898b4e515d343c0414f2a6472esd pi_enum_fn_t *func;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd if (t_parent == NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * A parent topology node is required even for top-level
908f1e1388f616898b4e515d343c0414f2a6472esd * nodes.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd return (MDE_WALK_NEXT);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * Find the topo-hc-name for this node which is used to find
908f1e1388f616898b4e515d343c0414f2a6472esd * the specific creation function
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd hc_name = pi_get_topo_hc_name(mod, mdp, mde_node);
908f1e1388f616898b4e515d343c0414f2a6472esd if (hc_name == NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* Cannot get the hc-name */
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod,
908f1e1388f616898b4e515d343c0414f2a6472esd "failed to find hc-name for node_0x%llx\n", mde_node);
908f1e1388f616898b4e515d343c0414f2a6472esd return (MDE_WALK_NEXT);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Determine the topology node creation routine to use */
908f1e1388f616898b4e515d343c0414f2a6472esd func = pi_enum_generic;
908f1e1388f616898b4e515d343c0414f2a6472esd faddr = 0;
908f1e1388f616898b4e515d343c0414f2a6472esd result = nvlist_lookup_uint64(pi_enum_fns, hc_name, &faddr);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result == 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * A function is registered for this node. Convert the
908f1e1388f616898b4e515d343c0414f2a6472esd * address to a pointer to function
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd func = (pi_enum_fn_t *)(uintptr_t)faddr;
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * Create a topology node for this mde node by calling the identified
908f1e1388f616898b4e515d343c0414f2a6472esd * enumeration function
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd *t_node = NULL;
908f1e1388f616898b4e515d343c0414f2a6472esd result = (func)(mod, mdp, mde_node, inst, t_parent, hc_name, t_node);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod,
908f1e1388f616898b4e515d343c0414f2a6472esd "failed to create topo entry for node_0x%llx type %s\n",
908f1e1388f616898b4e515d343c0414f2a6472esd (uint64_t)mde_node, hc_name);
908f1e1388f616898b4e515d343c0414f2a6472esd }
3f1e69bef33050bee99ea1e9992af13fc467281fCheng Sean Ye
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_strfree(mod, hc_name);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd return (MDE_WALK_NEXT);
908f1e1388f616898b4e515d343c0414f2a6472esd}
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd/*
908f1e1388f616898b4e515d343c0414f2a6472esd * Scan the children of a given MDE node and find all the sets of topo-hc-name
908f1e1388f616898b4e515d343c0414f2a6472esd * types and their instance ranges. From this information we create topology
908f1e1388f616898b4e515d343c0414f2a6472esd * node ranges on the given parent so that when the children are visited and a
908f1e1388f616898b4e515d343c0414f2a6472esd * topology node is created, the range exists and the creation will succeed.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int
908f1e1388f616898b4e515d343c0414f2a6472esdpi_walker_node_range(topo_mod_t *mod, md_t *mdp, tnode_t *t_parent,
908f1e1388f616898b4e515d343c0414f2a6472esd mde_cookie_t mde_node)
908f1e1388f616898b4e515d343c0414f2a6472esd{
908f1e1388f616898b4e515d343c0414f2a6472esd int result;
908f1e1388f616898b4e515d343c0414f2a6472esd int rc;
908f1e1388f616898b4e515d343c0414f2a6472esd int num_arcs;
908f1e1388f616898b4e515d343c0414f2a6472esd nvlist_t *typelist;
908f1e1388f616898b4e515d343c0414f2a6472esd nvpair_t *nvp;
908f1e1388f616898b4e515d343c0414f2a6472esd mde_cookie_t *arcp;
908f1e1388f616898b4e515d343c0414f2a6472esd size_t arcsize;
908f1e1388f616898b4e515d343c0414f2a6472esd int arcidx;
908f1e1388f616898b4e515d343c0414f2a6472esd char *hc_name;
908f1e1388f616898b4e515d343c0414f2a6472esd nvlist_t *hc_range;
908f1e1388f616898b4e515d343c0414f2a6472esd topo_instance_t inst;
908f1e1388f616898b4e515d343c0414f2a6472esd uint32_t min;
908f1e1388f616898b4e515d343c0414f2a6472esd uint32_t max;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd if (t_parent == NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod,
908f1e1388f616898b4e515d343c0414f2a6472esd "walker failed to create node range with a NULL parent\n");
908f1e1388f616898b4e515d343c0414f2a6472esd return (MDE_WALK_NEXT);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Determine how many children the given node has */
908f1e1388f616898b4e515d343c0414f2a6472esd num_arcs = md_get_prop_arcs(mdp, mde_node, MD_STR_FWD, NULL, 0);
908f1e1388f616898b4e515d343c0414f2a6472esd if (num_arcs == 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* This node has no children */
908f1e1388f616898b4e515d343c0414f2a6472esd return (MDE_WALK_NEXT);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "node_0x%llx has %d children\n",
908f1e1388f616898b4e515d343c0414f2a6472esd (uint64_t)mde_node, num_arcs);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Get the indexes for all the child nodes and put them in an array */
908f1e1388f616898b4e515d343c0414f2a6472esd arcsize = sizeof (mde_cookie_t) * num_arcs;
908f1e1388f616898b4e515d343c0414f2a6472esd arcp = topo_mod_zalloc(mod, arcsize);
908f1e1388f616898b4e515d343c0414f2a6472esd if (arcp == NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "out of memory\n");
186d582bd9dbcd38e0aeea49036d47d3426a3536Surya Prakki (void) topo_mod_seterrno(mod, EMOD_NOMEM);
908f1e1388f616898b4e515d343c0414f2a6472esd return (MDE_WALK_ERROR);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd num_arcs = md_get_prop_arcs(mdp, mde_node, MD_STR_FWD, arcp, arcsize);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * The children of the given node may have multiple types.
908f1e1388f616898b4e515d343c0414f2a6472esd * Potentially, each child may have a different type and we need to
908f1e1388f616898b4e515d343c0414f2a6472esd * create a topo node range for each one.
908f1e1388f616898b4e515d343c0414f2a6472esd *
908f1e1388f616898b4e515d343c0414f2a6472esd * We loop through the children and collect the type information for
908f1e1388f616898b4e515d343c0414f2a6472esd * each one and associate the child with the given parent topo node.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd result = topo_mod_nvalloc(mod, &typelist, NV_UNIQUE_NAME);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_free(mod, arcp, arcsize);
186d582bd9dbcd38e0aeea49036d47d3426a3536Surya Prakki (void) topo_mod_seterrno(mod, EMOD_NOMEM);
908f1e1388f616898b4e515d343c0414f2a6472esd return (MDE_WALK_ERROR);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd arcidx = 0;
908f1e1388f616898b4e515d343c0414f2a6472esd for (arcidx = 0; arcidx < num_arcs; arcidx++) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* Should this node be skipped? */
908f1e1388f616898b4e515d343c0414f2a6472esd if (pi_skip_node(mod, mdp, arcp[arcidx])) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* Skip this node */
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "skipping node_0x%llx\n",
908f1e1388f616898b4e515d343c0414f2a6472esd (uint64_t)arcp[arcidx]);
908f1e1388f616898b4e515d343c0414f2a6472esd continue;
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Get the type of this node */
908f1e1388f616898b4e515d343c0414f2a6472esd hc_name = pi_get_topo_hc_name(mod, mdp, arcp[arcidx]);
908f1e1388f616898b4e515d343c0414f2a6472esd rc = pi_get_instance(mod, mdp, arcp[arcidx], &inst);
908f1e1388f616898b4e515d343c0414f2a6472esd if (rc == 0 && hc_name != NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* Increment the count of nodes with this type */
908f1e1388f616898b4e515d343c0414f2a6472esd hc_range = NULL;
908f1e1388f616898b4e515d343c0414f2a6472esd rc = nvlist_lookup_nvlist(typelist, hc_name, &hc_range);
908f1e1388f616898b4e515d343c0414f2a6472esd if (rc != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * We have not visited this type yet. Create
908f1e1388f616898b4e515d343c0414f2a6472esd * a new range based on this nodes instance
908f1e1388f616898b4e515d343c0414f2a6472esd * information.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd result = pi_walkerlist_addtype(mod, typelist,
908f1e1388f616898b4e515d343c0414f2a6472esd hc_name, (uint32_t)inst, (uint32_t)inst);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * This error can only if there was a
908f1e1388f616898b4e515d343c0414f2a6472esd * memory failure of some kind. Stop
908f1e1388f616898b4e515d343c0414f2a6472esd * the walk or it will just get worse.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd nvlist_free(typelist);
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_strfree(mod, hc_name);
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_free(mod, arcp, arcsize);
186d582bd9dbcd38e0aeea49036d47d3426a3536Surya Prakki (void) topo_mod_seterrno(mod,
908f1e1388f616898b4e515d343c0414f2a6472esd EMOD_PARTIAL_ENUM);
908f1e1388f616898b4e515d343c0414f2a6472esd return (MDE_WALK_ERROR);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * We know the list exists now or the above
908f1e1388f616898b4e515d343c0414f2a6472esd * would have failed. Just look it up.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd (void) nvlist_lookup_nvlist(typelist, hc_name,
908f1e1388f616898b4e515d343c0414f2a6472esd &hc_range);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Re-calculate the range minimums and maximums */
908f1e1388f616898b4e515d343c0414f2a6472esd (void) nvlist_lookup_uint32(hc_range, PI_STR_MIN, &min);
908f1e1388f616898b4e515d343c0414f2a6472esd (void) nvlist_lookup_uint32(hc_range, PI_STR_MAX, &max);
908f1e1388f616898b4e515d343c0414f2a6472esd min = MIN(min, (uint32_t)inst);
908f1e1388f616898b4e515d343c0414f2a6472esd max = MAX(max, (uint32_t)inst);
908f1e1388f616898b4e515d343c0414f2a6472esd (void) nvlist_add_uint32(hc_range, PI_STR_MIN, min);
908f1e1388f616898b4e515d343c0414f2a6472esd (void) nvlist_add_uint32(hc_range, PI_STR_MAX, max);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd } else {
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier if (hc_name == NULL) {
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier topo_mod_dprintf(mod, "node_0x%llx has no "
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier "topo_hc_name.", (uint64_t)arcp[arcidx]);
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier (void) topo_mod_seterrno(mod,
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier EMOD_PARTIAL_ENUM);
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier return (MDE_WALK_ERROR);
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier }
fc33347812f84907261f6fd501e2409da108b8d8Tom Pothier
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "node_0x%llx type %s has no id. "
908f1e1388f616898b4e515d343c0414f2a6472esd "Excluding from range", (uint64_t)arcp[arcidx],
908f1e1388f616898b4e515d343c0414f2a6472esd hc_name);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_strfree(mod, hc_name);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * Associate this node with the given topo parent even if it
908f1e1388f616898b4e515d343c0414f2a6472esd * has no instance. We do this so that later an error with
908f1e1388f616898b4e515d343c0414f2a6472esd * the PRI node will be reported instead of an internal
908f1e1388f616898b4e515d343c0414f2a6472esd * error about not being able to find the parent of a node
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd rc = pi_walkerlist_add(mod, t_parent, arcp[arcidx]);
908f1e1388f616898b4e515d343c0414f2a6472esd if (rc != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod,
908f1e1388f616898b4e515d343c0414f2a6472esd "could not add node_0x%llx to walker list\n",
908f1e1388f616898b4e515d343c0414f2a6472esd (uint64_t)arcp[arcidx]);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * We have associated all the child nodes with the given topo parent
908f1e1388f616898b4e515d343c0414f2a6472esd * in the walker list. Now we need to create topo ranges for each
908f1e1388f616898b4e515d343c0414f2a6472esd * set of child types under the parent.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd nvp = nvlist_next_nvpair(typelist, NULL);
908f1e1388f616898b4e515d343c0414f2a6472esd while (nvp != NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd /* Get the type name and count from the list element */
908f1e1388f616898b4e515d343c0414f2a6472esd hc_name = nvpair_name(nvp);
908f1e1388f616898b4e515d343c0414f2a6472esd (void) nvpair_value_nvlist(nvp, &hc_range);
908f1e1388f616898b4e515d343c0414f2a6472esd (void) nvlist_lookup_uint32(hc_range, PI_STR_MIN, &min);
908f1e1388f616898b4e515d343c0414f2a6472esd (void) nvlist_lookup_uint32(hc_range, PI_STR_MAX, &max);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * We have the number of children with this type.
908f1e1388f616898b4e515d343c0414f2a6472esd * Create an appropriate range.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod,
908f1e1388f616898b4e515d343c0414f2a6472esd "creating instance range %d to %d of type %s\n",
908f1e1388f616898b4e515d343c0414f2a6472esd min, max, hc_name);
908f1e1388f616898b4e515d343c0414f2a6472esd rc = topo_node_range_create(mod, t_parent, hc_name,
908f1e1388f616898b4e515d343c0414f2a6472esd (topo_instance_t)min, (topo_instance_t)max);
908f1e1388f616898b4e515d343c0414f2a6472esd if (rc != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod,
908f1e1388f616898b4e515d343c0414f2a6472esd "failed to created node range %d to %d for "
908f1e1388f616898b4e515d343c0414f2a6472esd "nodes of type %s\n", min, max, hc_name);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Check the next node */
908f1e1388f616898b4e515d343c0414f2a6472esd nvp = nvlist_next_nvpair(typelist, nvp);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_free(mod, arcp, arcsize);
908f1e1388f616898b4e515d343c0414f2a6472esd nvlist_free(typelist);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd return (MDE_WALK_NEXT);
908f1e1388f616898b4e515d343c0414f2a6472esd}
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int
908f1e1388f616898b4e515d343c0414f2a6472esdpi_walkerlist_addtype(topo_mod_t *mod, nvlist_t *typelist, char *hc_name,
908f1e1388f616898b4e515d343c0414f2a6472esd uint32_t min, uint32_t max)
908f1e1388f616898b4e515d343c0414f2a6472esd{
908f1e1388f616898b4e515d343c0414f2a6472esd int result;
908f1e1388f616898b4e515d343c0414f2a6472esd nvlist_t *nvl;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd result = topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd return (result);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Create min and max elements in this list */
908f1e1388f616898b4e515d343c0414f2a6472esd if (nvlist_add_uint32(nvl, PI_STR_MIN, min) != 0 ||
908f1e1388f616898b4e515d343c0414f2a6472esd nvlist_add_uint32(nvl, PI_STR_MAX, max) != 0 ||
908f1e1388f616898b4e515d343c0414f2a6472esd nvlist_add_nvlist(typelist, hc_name, nvl) != 0) {
908f1e1388f616898b4e515d343c0414f2a6472esd nvlist_free(nvl);
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd nvlist_free(nvl);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd return (0);
908f1e1388f616898b4e515d343c0414f2a6472esd}
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd/* ARGSUSED */
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int
908f1e1388f616898b4e515d343c0414f2a6472esdpi_walkerlist_compare(const void *left, const void *right, void *private)
908f1e1388f616898b4e515d343c0414f2a6472esd{
908f1e1388f616898b4e515d343c0414f2a6472esd pi_walkernode_t *lp = (pi_walkernode_t *)left;
908f1e1388f616898b4e515d343c0414f2a6472esd pi_walkernode_t *rp = (pi_walkernode_t *)right;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd if (lp->mde_node > rp->mde_node) {
908f1e1388f616898b4e515d343c0414f2a6472esd return (1);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd if (lp->mde_node < rp->mde_node) {
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd return (0);
908f1e1388f616898b4e515d343c0414f2a6472esd}
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int
908f1e1388f616898b4e515d343c0414f2a6472esdpi_walkerlist_create(topo_mod_t *mod)
908f1e1388f616898b4e515d343c0414f2a6472esd{
908f1e1388f616898b4e515d343c0414f2a6472esd /* Initialize the uutil list structure */
908f1e1388f616898b4e515d343c0414f2a6472esd walker_pool = uu_list_pool_create("pi_walker_pool",
908f1e1388f616898b4e515d343c0414f2a6472esd sizeof (pi_walkernode_t), offsetof(pi_walkernode_t, walker_node),
908f1e1388f616898b4e515d343c0414f2a6472esd pi_walkerlist_compare, NULL);
908f1e1388f616898b4e515d343c0414f2a6472esd if (walker_pool == NULL) {
186d582bd9dbcd38e0aeea49036d47d3426a3536Surya Prakki (void) topo_mod_seterrno(mod, EMOD_NOMEM);
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd walker_list = uu_list_create(walker_pool, NULL, 0);
908f1e1388f616898b4e515d343c0414f2a6472esd if (walker_list == NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd uu_list_pool_destroy(walker_pool);
021ceb9857f712f245edda92c7eb82f0a3a83acbTom Pothier walker_pool = NULL;
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd return (0);
908f1e1388f616898b4e515d343c0414f2a6472esd}
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esdstatic void
908f1e1388f616898b4e515d343c0414f2a6472esdpi_walkerlist_destroy(topo_mod_t *mod)
908f1e1388f616898b4e515d343c0414f2a6472esd{
908f1e1388f616898b4e515d343c0414f2a6472esd void *wvp;
908f1e1388f616898b4e515d343c0414f2a6472esd pi_walkernode_t *wp;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Destroy our list of items */
908f1e1388f616898b4e515d343c0414f2a6472esd while ((wvp = uu_list_first(walker_list)) != NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd /*
908f1e1388f616898b4e515d343c0414f2a6472esd * First, we empty the list of elements and free each one.
908f1e1388f616898b4e515d343c0414f2a6472esd * We do not free the data elements as they are libtopo nodes
908f1e1388f616898b4e515d343c0414f2a6472esd * and will be freed by libtopo
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esd wp = (pi_walkernode_t *)wvp;
908f1e1388f616898b4e515d343c0414f2a6472esd uu_list_remove(walker_list, wvp);
908f1e1388f616898b4e515d343c0414f2a6472esd uu_list_node_fini(wp, &(wp->walker_node), walker_pool);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_free(mod, wvp, sizeof (pi_walkernode_t));
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd uu_list_destroy(walker_list);
908f1e1388f616898b4e515d343c0414f2a6472esd uu_list_pool_destroy(walker_pool);
021ceb9857f712f245edda92c7eb82f0a3a83acbTom Pothier walker_list = NULL;
021ceb9857f712f245edda92c7eb82f0a3a83acbTom Pothier walker_pool = NULL;
908f1e1388f616898b4e515d343c0414f2a6472esd}
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int
908f1e1388f616898b4e515d343c0414f2a6472esdpi_walkerlist_add(topo_mod_t *mod, tnode_t *t_parent, mde_cookie_t mde_node)
908f1e1388f616898b4e515d343c0414f2a6472esd{
908f1e1388f616898b4e515d343c0414f2a6472esd uu_list_index_t idx;
908f1e1388f616898b4e515d343c0414f2a6472esd pi_walkernode_t *wnp;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd wnp = topo_mod_zalloc(mod, sizeof (pi_walkernode_t));
908f1e1388f616898b4e515d343c0414f2a6472esd if (wnp == NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_dprintf(mod, "failed to add node_0x%llx parent %p\n",
908f1e1388f616898b4e515d343c0414f2a6472esd (uint64_t)mde_node, t_parent);
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd uu_list_node_init(wnp, &(wnp->walker_node), walker_pool);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd wnp->t_parent = t_parent;
908f1e1388f616898b4e515d343c0414f2a6472esd wnp->mde_node = mde_node;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd (void) uu_list_find(walker_list, wnp, NULL, &idx);
908f1e1388f616898b4e515d343c0414f2a6472esd uu_list_insert(walker_list, wnp, idx);
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd return (0);
908f1e1388f616898b4e515d343c0414f2a6472esd}
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd/*
908f1e1388f616898b4e515d343c0414f2a6472esd * Find the parent topo node for this machine description node.
908f1e1388f616898b4e515d343c0414f2a6472esd *
908f1e1388f616898b4e515d343c0414f2a6472esd * Nodes are removed from the list as they are found. They are only
908f1e1388f616898b4e515d343c0414f2a6472esd * visited once and this eliminates the need for a separate routine
908f1e1388f616898b4e515d343c0414f2a6472esd * that walks the list to free elements later.
908f1e1388f616898b4e515d343c0414f2a6472esd */
908f1e1388f616898b4e515d343c0414f2a6472esdstatic int
908f1e1388f616898b4e515d343c0414f2a6472esdpi_walkerlist_find(topo_mod_t *mod, mde_cookie_t mde_node, tnode_t **tpp)
908f1e1388f616898b4e515d343c0414f2a6472esd{
908f1e1388f616898b4e515d343c0414f2a6472esd pi_walkernode_t *result;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd uu_list_index_t idx;
908f1e1388f616898b4e515d343c0414f2a6472esd pi_walkernode_t search_criteria;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd search_criteria.mde_node = mde_node;
908f1e1388f616898b4e515d343c0414f2a6472esd search_criteria.t_parent = NULL;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd *tpp = NULL;
908f1e1388f616898b4e515d343c0414f2a6472esd result = uu_list_find(walker_list, &search_criteria, NULL, &idx);
908f1e1388f616898b4e515d343c0414f2a6472esd if (result == NULL) {
908f1e1388f616898b4e515d343c0414f2a6472esd return (-1);
908f1e1388f616898b4e515d343c0414f2a6472esd }
908f1e1388f616898b4e515d343c0414f2a6472esd *tpp = result->t_parent;
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd /* Remove this element from the list */
908f1e1388f616898b4e515d343c0414f2a6472esd uu_list_remove(walker_list, result);
908f1e1388f616898b4e515d343c0414f2a6472esd uu_list_node_fini(result, &(result->walker_node), walker_pool);
908f1e1388f616898b4e515d343c0414f2a6472esd topo_mod_free(mod, result, sizeof (pi_walkernode_t));
908f1e1388f616898b4e515d343c0414f2a6472esd
908f1e1388f616898b4e515d343c0414f2a6472esd return (0);
908f1e1388f616898b4e515d343c0414f2a6472esd}