int topo_node_range_create(topo_mod_t *mod, tnode_t *pnode, const char *name, topo_instance_t min, topo_instance_t max) { topo_nodehash_t *nhp; topo_node_lock(pnode); assert((pnode->tn_state & TOPO_NODE_BOUND) || (pnode->tn_state & TOPO_NODE_ROOT)); for (nhp = topo_list_next(&pnode->tn_children); nhp != NULL; nhp = topo_list_next(nhp)) { if (strcmp(nhp->th_name, name) == 0) return (node_create_seterror(mod, pnode, NULL, ETOPO_NODE_DUP)); } if (min < 0 || max < min) return (node_create_seterror(mod, pnode, NULL, ETOPO_NODE_INVAL)); if ((nhp = topo_mod_zalloc(mod, sizeof (topo_nodehash_t))) == NULL) return (node_create_seterror(mod, pnode, nhp, ETOPO_NOMEM)); if ((nhp->th_name = topo_mod_strdup(mod, name)) == NULL) return (node_create_seterror(mod, pnode, nhp, ETOPO_NOMEM)); nhp->th_arrlen = max - min + 1; if ((nhp->th_nodearr = topo_mod_zalloc(mod, nhp->th_arrlen * sizeof (tnode_t *))) == NULL) return (node_create_seterror(mod, pnode, nhp, ETOPO_NOMEM)); nhp->th_range.tr_min = min; nhp->th_range.tr_max = max; nhp->th_enum = mod; topo_mod_hold(mod); /* * Add these nodes to parent child list */ topo_list_append(&pnode->tn_children, nhp); topo_node_unlock(pnode); topo_dprintf(TOPO_DBG_MOD, "created node range %s[%d-%d]\n", name, min, max); return (0); }
ttree_t * topo_tree_create(topo_hdl_t *thp, topo_mod_t *mod, const char *scheme) { ttree_t *tp; tnode_t *rp; if ((tp = topo_mod_zalloc(mod, sizeof (ttree_t))) == NULL) return (set_create_error(thp, NULL, ETOPO_NOMEM)); tp->tt_mod = mod; if ((tp->tt_scheme = topo_mod_strdup(mod, scheme)) == NULL) return (set_create_error(thp, tp, ETOPO_NOMEM)); /* * Initialize a private walker for internal use */ if ((tp->tt_walk = topo_mod_zalloc(mod, sizeof (topo_walk_t))) == NULL) return (set_create_error(thp, tp, ETOPO_NOMEM)); /* * Create the root of this tree: LINKED but never BOUND */ if ((rp = topo_mod_zalloc(mod, sizeof (tnode_t))) == NULL) return (set_create_error(thp, tp, 0)); /* th_errno set */ rp->tn_state = TOPO_NODE_ROOT | TOPO_NODE_INIT; rp->tn_name = tp->tt_scheme; rp->tn_instance = 0; rp->tn_enum = mod; rp->tn_hdl = thp; topo_node_hold(rp); tp->tt_walk->tw_root = rp; tp->tt_walk->tw_thp = thp; topo_mod_hold(mod); /* released when root node destroyed */ tp->tt_root = rp; return (tp); }
tnode_t * topo_node_bind(topo_mod_t *mod, tnode_t *pnode, const char *name, topo_instance_t inst, nvlist_t *fmri, void *priv) { int h, err; tnode_t *node; topo_nodehash_t *nhp; topo_node_lock(pnode); for (nhp = topo_list_next(&pnode->tn_children); nhp != NULL; nhp = topo_list_next(nhp)) { if (strcmp(nhp->th_name, name) == 0) { if (inst > nhp->th_range.tr_max || inst < nhp->th_range.tr_min) return (node_bind_seterror(mod, pnode, NULL, ETOPO_NODE_INVAL)); h = topo_node_hash(nhp, inst); if (nhp->th_nodearr[h] != NULL) return (node_bind_seterror(mod, pnode, NULL, ETOPO_NODE_BOUND)); else break; } } if (nhp == NULL) return (node_bind_seterror(mod, pnode, NULL, ETOPO_NODE_NOENT)); if ((node = topo_mod_zalloc(mod, sizeof (tnode_t))) == NULL) return (node_bind_seterror(mod, pnode, NULL, ETOPO_NOMEM)); (void) pthread_mutex_init(&node->tn_lock, NULL); node->tn_enum = mod; node->tn_hdl = mod->tm_hdl; node->tn_parent = pnode; node->tn_name = nhp->th_name; node->tn_instance = inst; node->tn_phash = nhp; node->tn_refs = 0; /* Ref count module that bound this node */ topo_mod_hold(mod); if (fmri == NULL) return (node_bind_seterror(mod, pnode, node, ETOPO_NODE_INVAL)); if (topo_pgroup_create(node, TOPO_PGROUP_PROTOCOL, TOPO_STABILITY_PRIVATE, &err) < 0) return (node_bind_seterror(mod, pnode, node, err)); if (topo_prop_set_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_RESOURCE, TOPO_PROP_SET_ONCE, fmri, &err) < 0) return (node_bind_seterror(mod, pnode, node, err)); topo_dprintf(TOPO_DBG_MOD, "node bound %s=%d\n", node->tn_name, node->tn_instance); node->tn_state |= TOPO_NODE_BOUND; node->tn_priv = priv; topo_node_hold(node); nhp->th_nodearr[h] = node; ++pnode->tn_refs; topo_node_unlock(pnode); if (topo_pgroup_create(node, TOPO_PGROUP_SYSTEM, TOPO_STABILITY_PRIVATE, &err) == 0) { (void) topo_prop_inherit(node, TOPO_PGROUP_SYSTEM, TOPO_PROP_PLATFORM, &err); (void) topo_prop_inherit(node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA, &err); (void) topo_prop_inherit(node, TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE, &err); } return (node); }