int did_props_set(tnode_t *tn, did_t *pd, txprop_t txarray[], int txnum) { topo_mod_t *mp; int i, r, e; mp = did_mod(pd); for (i = 0; i < txnum; i++) { /* * Ensure the property group has been created. */ if (txarray[i].tx_tpgroup != NULL) { if (topo_pgroup_create(tn, txarray[i].tx_tpgroup, &e) < 0) { if (e != ETOPO_PROP_DEFD) return (topo_mod_seterrno(mp, e)); } } topo_mod_dprintf(mp, "Setting property %s in group %s.\n", txarray[i].tx_tprop, txarray[i].tx_tpgroup->tpi_name); r = txarray[i].tx_xlate(tn, pd, txarray[i].tx_diprop, txarray[i].tx_tpgroup->tpi_name, txarray[i].tx_tprop); if (r != 0) { topo_mod_dprintf(mp, "failed.\n"); topo_mod_dprintf(mp, "Error was %s.\n", topo_strerror(topo_mod_errno(mp))); return (-1); } topo_mod_dprintf(mp, "succeeded.\n"); } return (0); }
static int amd_dramchan_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *auth) { tnode_t *chnode; nvlist_t *fmri; char *socket; int i, nchan; nvlist_t *pfmri = NULL; int err, nerr = 0; /* * We will enumerate the number of channels present even if only * channel A is in use (i.e., running in 64-bit mode). Only * the socket 754 package has a single channel. */ if (topo_prop_get_string(pnode, PGNAME(MCT), "socket", &socket, &err) == 0 && strcmp(socket, "Socket 754") == 0) nchan = 1; else nchan = 2; topo_mod_strfree(mod, socket); if (topo_node_range_create(mod, pnode, name, 0, nchan - 1) < 0) return (-1); (void) topo_node_fru(pnode, &pfmri, NULL, &err); for (i = 0; i < nchan; i++) { if (mkrsrc(mod, pnode, name, i, auth, &fmri) != 0) { whinge(mod, &nerr, "amd_dramchan_create: mkrsrc " "failed\n"); continue; } if ((chnode = topo_node_bind(mod, pnode, name, i, fmri)) == NULL) { nvlist_free(fmri); whinge(mod, &nerr, "amd_dramchan_create: node bind " "failed\n"); continue; } (void) topo_node_asru_set(chnode, fmri, 0, &err); if (pfmri) (void) topo_node_fru_set(chnode, pfmri, 0, &err); nvlist_free(fmri); (void) topo_pgroup_create(chnode, &chan_pgroup, &err); (void) topo_prop_set_string(chnode, PGNAME(CHAN), "channel", TOPO_PROP_IMMUTABLE, i == 0 ? "A" : "B", &err); } nvlist_free(pfmri); return (nerr == 0 ? 0 : -1); }
static int amd_cs_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc, nvlist_t *auth) { int i, err, nerr = 0; nvpair_t *nvp; tnode_t *csnode; nvlist_t *fmri, **csarr = NULL; uint64_t csnum; uint_t ncs; if (nvlist_lookup_nvlist_array(mc, "cslist", &csarr, &ncs) != 0) return (-1); if (ncs == 0) return (0); /* no chip-selects configured on this node */ if (topo_node_range_create(mod, pnode, name, 0, MAX_CSNUM) < 0) return (-1); for (i = 0; i < ncs; i++) { if (nvlist_lookup_uint64(csarr[i], "num", &csnum) != 0) { whinge(mod, &nerr, "amd_cs_create: cs num property " "missing\n"); continue; } if (mkrsrc(mod, pnode, name, csnum, auth, &fmri) != 0) { whinge(mod, &nerr, "amd_cs_create: mkrsrc failed\n"); continue; } if ((csnode = topo_node_bind(mod, pnode, name, csnum, fmri)) == NULL) { nvlist_free(fmri); whinge(mod, &nerr, "amd_cs_create: node bind failed\n"); continue; } cs_fmri[csnum] = fmri; /* nvlist will be freed in mc_create */ (void) topo_node_asru_set(csnode, fmri, 0, &err); (void) topo_node_fru_set(csnode, fmri, 0, &err); (void) topo_pgroup_create(csnode, &cs_pgroup, &err); for (nvp = nvlist_next_nvpair(csarr[i], NULL); nvp != NULL; nvp = nvlist_next_nvpair(csarr[i], nvp)) { nerr += nvprop_add(mod, nvp, PGNAME(CS), csnode); } } return (nerr == 0 ? 0 : -1); }
static tnode_t * hb_tnode_create(topo_mod_t *mod, tnode_t *parent, const char *name, topo_instance_t i, void *priv) { int err; nvlist_t *fmri; tnode_t *ntn; nvlist_t *auth = topo_mod_auth(mod, parent); fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i, NULL, auth, NULL, NULL, NULL); nvlist_free(auth); if (fmri == NULL) { topo_mod_dprintf(mod, "Unable to make nvlist for %s bind: %s.\n", name, topo_mod_errmsg(mod)); return (NULL); } ntn = topo_node_bind(mod, parent, name, i, fmri); if (ntn == NULL) { topo_mod_dprintf(mod, "topo_node_bind (%s%d/%s%d) failed: %s\n", topo_node_name(parent), topo_node_instance(parent), name, i, topo_strerror(topo_mod_errno(mod))); nvlist_free(fmri); return (NULL); } nvlist_free(fmri); topo_node_setspecific(ntn, priv); if (topo_pgroup_create(ntn, &hb_auth_pgroup, &err) == 0) { (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT, &err); (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT_SN, &err); (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS, &err); (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_SERVER, &err); } if (topo_method_register(mod, ntn, Hb_methods) < 0) { topo_mod_dprintf(mod, "topo_method_register failed: %s\n", topo_strerror(topo_mod_errno(mod))); topo_node_unbind(ntn); return (NULL); } return (ntn); }
static void mb_prop_set(tnode_t *node, nvlist_t *auth) { int err; char isa[MAXNAMELEN]; struct utsname uts; char *prod, *psn, *csn, *server; if ((topo_pgroup_create(node, &mb_auth_pgroup, &err) != 0) && (err != ETOPO_PROP_DEFD)) return; if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT, &prod) == 0) (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod, &err); if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN, &psn) == 0) (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT_SN, TOPO_PROP_IMMUTABLE, psn, &err); if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &csn) == 0) (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS, TOPO_PROP_IMMUTABLE, csn, &err); if (nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER, &server) == 0) (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server, &err); if (topo_pgroup_create(node, &mb_sys_pgroup, &err) != 0) return; isa[0] = '\0'; (void) sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)); (void) uname(&uts); (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA, TOPO_PROP_IMMUTABLE, isa, &err); (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE, TOPO_PROP_IMMUTABLE, uts.machine, &err); }
static tnode_t * niu_tnode_create(topo_mod_t *mod, tnode_t *parent, const char *name, topo_instance_t i, void *priv) { int err; nvlist_t *fmri; tnode_t *ntn; nvlist_t *auth = topo_mod_auth(mod, parent); fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i, NULL, auth, NULL, NULL, NULL); nvlist_free(auth); if (fmri == NULL) { topo_mod_dprintf(mod, "Unable to make nvlist for %s bind: %s.\n", name, topo_mod_errmsg(mod)); return (NULL); } ntn = topo_node_bind(mod, parent, name, i, fmri); if (ntn == NULL) { topo_mod_dprintf(mod, "topo_node_bind (%s%d/%s%d) failed: %s\n", topo_node_name(parent), topo_node_instance(parent), name, i, topo_strerror(topo_mod_errno(mod))); nvlist_free(fmri); return (NULL); } nvlist_free(fmri); topo_node_setspecific(ntn, priv); if (topo_pgroup_create(ntn, &io_pgroup, &err) == 0) { (void) devprop_set(ntn, priv, TOPO_PGROUP_IO, TOPO_IO_DEV, mod); (void) driverprop_set(ntn, priv, TOPO_PGROUP_IO, TOPO_IO_DRIVER, mod); (void) moduleprop_set(ntn, priv, TOPO_PGROUP_IO, TOPO_IO_MODULE, mod); } return (ntn); }
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); }
/* * Calculate the system information for a node. Inherit the data if * possible, but always create an appropriate property group. */ int x86pi_set_system(topo_mod_t *mod, tnode_t *t_node) { int result; int err; struct utsname uts; char isa[MAXNAMELEN]; if (mod == NULL || t_node == NULL) { return (-1); } result = topo_pgroup_create(t_node, &sys_pgroup, &err); if (result != 0 && err != ETOPO_PROP_DEFD) { /* * We failed to create the property group and it was not * already defined. Set the err code and return failure. */ (void) topo_mod_seterrno(mod, err); return (-1); } result = topo_prop_inherit(t_node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA, &err); if (result != 0 && err != ETOPO_PROP_DEFD) { isa[0] = '\0'; result = sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)); if (result == -1) { /* Preserve the error and continue */ topo_mod_dprintf(mod, "x86pi_set_system: failed to " "read SI_ARCHITECTURE: %d\n", errno); } if (strnlen(isa, MAXNAMELEN) > 0) { result = topo_prop_set_string(t_node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA, TOPO_PROP_IMMUTABLE, isa, &err); if (result != 0) { /* Preserve the error and continue */ (void) topo_mod_seterrno(mod, err); topo_mod_dprintf(mod, "x86pi_set_auth: failed to " "set property %s (%d) : %s\n", TOPO_PROP_ISA, err, topo_strerror(err)); } } } result = topo_prop_inherit(t_node, TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE, &err); if (result != 0 && err != ETOPO_PROP_DEFD) { result = uname(&uts); if (result == -1) { /* Preserve the error and continue */ (void) topo_mod_seterrno(mod, errno); topo_mod_dprintf(mod, "x86pi_set_system: failed to " "read uname: %d\n", errno); } if (strnlen(uts.machine, sizeof (uts.machine)) > 0) { result = topo_prop_set_string(t_node, TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE, TOPO_PROP_IMMUTABLE, uts.machine, &err); if (result != 0) { /* Preserve the error and continue */ (void) topo_mod_seterrno(mod, err); topo_mod_dprintf(mod, "x86pi_set_auth: failed to " "set property %s (%d) : %s\n", TOPO_PROP_MACHINE, err, topo_strerror(err)); } } } return (0); }
/* * Calculate the authority information for a node. Inherit the data if * possible, but always create an appropriate property group. */ int x86pi_set_auth(topo_mod_t *mod, x86pi_hcfmri_t *hcfmri, tnode_t *t_parent, tnode_t *t_node) { int result; int err; int is_chassis = 0; int chassis_instance = 0; nvlist_t *auth; char *val = NULL; char *prod = NULL; char *psn = NULL; char *csn = NULL; char *server = NULL; char *f = "x86pi_set_auth"; if (mod == NULL || t_parent == NULL || t_node == NULL) { return (-1); } result = topo_pgroup_create(t_node, &auth_pgroup, &err); if (result != 0 && err != ETOPO_PROP_DEFD) { /* * We failed to create the property group and it was not * already defined. Set the err code and return failure. */ (void) topo_mod_seterrno(mod, err); return (-1); } /* Get the authority information already available from the parent */ auth = topo_mod_auth(mod, t_parent); /* Determnine if this is a chassis node and set it's instance */ if ((strlen(hcfmri->hc_name) == strlen(CHASSIS)) && strncmp(hcfmri->hc_name, CHASSIS, strlen(CHASSIS)) == 0) { is_chassis = 1; chassis_instance = hcfmri->instance; } /* * Set the authority data, inheriting it if possible, but creating it * if necessary. */ /* product-id */ result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT, &err); if (result != 0 && err != ETOPO_PROP_DEFD) { result = nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT, &prod); if (result != 0 || prod == NULL) { /* * No product information in the parent node or auth * list. Use the product information in the hcfrmi * struct. */ prod = (char *)hcfmri->product; if (prod == NULL) { topo_mod_dprintf(mod, "%s: product name not " "found for %s node\n", f, hcfmri->hc_name); } } /* * We continue even if the product information is not available * to enumerate as much as possible. */ if (prod != NULL) { result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod, &err); if (result != 0) { /* Preserve the error and continue */ (void) topo_mod_seterrno(mod, err); topo_mod_dprintf(mod, "%s: failed to set " "property %s (%d) : %s\n", f, FM_FMRI_AUTH_PRODUCT, err, topo_strerror(err)); } } } /* product-sn */ result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT_SN, &err); if (result != 0 && err != ETOPO_PROP_DEFD) { result = nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN, &psn); if (result != 0 || psn == NULL) { /* * No product-sn information in the parent node or auth * list. */ topo_mod_dprintf(mod, "%s: psn not found\n", f); } else { /* * We continue even if the product-sn information is * not available to enumerate as much as possible. */ result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT_SN, TOPO_PROP_IMMUTABLE, psn, &err); if (result != 0) { /* Preserve the error and continue */ (void) topo_mod_seterrno(mod, err); topo_mod_dprintf(mod, "%s: failed to " "set property %s (%d) : %s\n", f, FM_FMRI_AUTH_PRODUCT_SN, err, topo_strerror(err)); } } } /* chassis-id */ if (is_chassis == 0 || (is_chassis == 1 && chassis_instance == 0)) { /* either not a chassis node, or chassis #0 */ result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS, &err); } else { /* chassis 'n' in a >1 chassis system */ result = err = -1; } if (result != 0 && err != ETOPO_PROP_DEFD) { if (is_chassis == 0) { result = nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &csn); if (result != 0 || csn == NULL) { /* * No chassis information in the parent * node or auth list. */ topo_mod_dprintf(mod, "%s: csn name not found\n", f); } } else { /* * So as not to blindly set the chassis-id to * chassis #0's serial number. */ csn = val = topo_mod_strdup(mod, hcfmri->serial_number); } /* * We continue even if the chassis information is not available * to enumerate as much as possible. */ if (csn != NULL) { if (is_chassis == 1) result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS, TOPO_PROP_MUTABLE, csn, &err); else result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS, TOPO_PROP_IMMUTABLE, csn, &err); if (result != 0) { /* Preserve the error and continue */ (void) topo_mod_seterrno(mod, err); topo_mod_dprintf(mod, "%s: failed to " "set property %s (%d) : %s\n", f, FM_FMRI_AUTH_CHASSIS, err, topo_strerror(err)); } } if (val != NULL) { topo_mod_strfree(mod, val); val = NULL; } } /* server-id */ result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_SERVER, &err); if (result != 0 && err != ETOPO_PROP_DEFD) { result = nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER, &server); if (result != 0 || server == NULL) { /* * No server information in the parent node or auth * list. Find the server information in hostname. */ server = val = x86pi_get_serverid(mod); if (server == NULL) { topo_mod_dprintf(mod, "%s: server " "name not found for %s node\n", f, hcfmri->hc_name); } } /* * We continue even if the server information is not available * to enumerate as much as possible. */ if (server != NULL) { result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server, &err); if (result != 0) { /* Preserve the error and continue */ (void) topo_mod_seterrno(mod, err); topo_mod_dprintf(mod, "%s: failed to " "set property %s (%d) : %s\n", f, FM_FMRI_AUTH_SERVER, err, topo_strerror(err)); } } if (val != NULL) topo_mod_strfree(mod, val); } nvlist_free(auth); return (0); }
static int disk_add_temp_sensor(topo_mod_t *mod, tnode_t *pnode, const char *devid) { tnode_t *fnode; topo_pgroup_info_t pgi; nvlist_t *arg_nvl = NULL; int err; if ((fnode = topo_node_facbind(mod, pnode, "temp", TOPO_FAC_TYPE_SENSOR)) == NULL) { topo_mod_dprintf(mod, "failed to bind facility node"); /* errno set */ return (-1); } /* * Set props: * - facility/sensor-class * - facility/sensor-type * - facility/units */ pgi.tpi_name = TOPO_PGROUP_FACILITY; pgi.tpi_namestab = TOPO_STABILITY_PRIVATE; pgi.tpi_datastab = TOPO_STABILITY_PRIVATE; pgi.tpi_version = 1; if (topo_pgroup_create(fnode, &pgi, &err) != 0) { if (err != ETOPO_PROP_DEFD) { topo_mod_dprintf(mod, "pgroups create failure (%s)\n", topo_strerror(err)); /* errno set */ goto err; } } if (topo_prop_set_string(fnode, TOPO_PGROUP_FACILITY, TOPO_SENSOR_CLASS, TOPO_PROP_IMMUTABLE, TOPO_SENSOR_CLASS_THRESHOLD, &err) != 0 || topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE, TOPO_PROP_IMMUTABLE, TOPO_SENSOR_TYPE_TEMP, &err) != 0 || topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY, TOPO_SENSOR_UNITS, TOPO_PROP_IMMUTABLE, TOPO_SENSOR_UNITS_DEGREES_C, &err) != 0) { topo_mod_dprintf(mod, "Failed to set props on facnode (%s)", topo_strerror(err)); /* errno set */ goto err; } /* * Register a property method for facility/reading */ if (topo_method_register(mod, fnode, disk_fac_methods) < 0) { topo_mod_dprintf(mod, "failed to register facility methods"); goto err; } if (topo_mod_nvalloc(mod, &arg_nvl, NV_UNIQUE_NAME) < 0 || nvlist_add_string(arg_nvl, TOPO_IO_DEVID, devid) != 0) { topo_mod_dprintf(mod, "Failed build arg nvlist\n"); (void) topo_mod_seterrno(mod, EMOD_NOMEM); goto err; } if (topo_prop_method_register(fnode, TOPO_PGROUP_FACILITY, TOPO_SENSOR_READING, TOPO_TYPE_DOUBLE, "disk_temp_reading", arg_nvl, &err) != 0) { topo_mod_dprintf(mod, "Failed to register %s propmeth " "on fac node %s (%s)\n", TOPO_SENSOR_READING, topo_node_name(fnode), topo_strerror(err)); /* errno set */ goto err; } nvlist_free(arg_nvl); return (0); err: topo_node_unbind(fnode); nvlist_free(arg_nvl); return (-1); }
/* * Set the properties of the disk node, from dev_di_node_t data. * Properties include: * group: protocol properties: resource, asru, label, fru * group: authority properties: product-id, chasis-id, server-id * group: io properties: devfs-path, devid * group: storage properties: * - logical-disk, disk-model, disk-manufacturer, serial-number * - firmware-revision, capacity-in-bytes * * NOTE: the io and storage groups won't be present if the dnode passed in is * NULL. This happens when a disk is found through ses, but is not enumerated * in the devinfo tree. */ static int disk_set_props(topo_mod_t *mod, tnode_t *parent, tnode_t *dtn, dev_di_node_t *dnode) { nvlist_t *asru = NULL, *drive_attrs; char *label = NULL; nvlist_t *fmri = NULL; dm_descriptor_t drive_descr = NULL; uint32_t rpm; int err; /* pull the label property down from our parent 'bay' node */ if (topo_node_label(parent, &label, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "label error %s\n", topo_strerror(err)); goto error; } if (topo_node_label_set(dtn, label, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "label_set error %s\n", topo_strerror(err)); goto error; } /* get the resource fmri, and use it as the fru */ if (topo_node_resource(dtn, &fmri, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "resource error: %s\n", topo_strerror(err)); goto error; } if (topo_node_fru_set(dtn, fmri, 0, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "fru_set error: %s\n", topo_strerror(err)); goto error; } /* create/set the authority group */ if ((topo_pgroup_create(dtn, &disk_auth_pgroup, &err) != 0) && (err != ETOPO_PROP_DEFD)) { topo_mod_dprintf(mod, "disk_set_props: " "create disk_auth error %s\n", topo_strerror(err)); goto error; } /* create the storage group */ if (topo_pgroup_create(dtn, &storage_pgroup, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "create storage error %s\n", topo_strerror(err)); goto error; } /* no dnode was found for this disk - skip the io and storage groups */ if (dnode == NULL) { err = 0; goto out; } /* form and set the asru */ if ((asru = topo_mod_devfmri(mod, FM_DEV_SCHEME_VERSION, dnode->ddn_dpath, dnode->ddn_devid)) == NULL) { err = ETOPO_FMRI_UNKNOWN; topo_mod_dprintf(mod, "disk_set_props: " "asru error %s\n", topo_strerror(err)); goto error; } if (topo_node_asru_set(dtn, asru, 0, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "asru_set error %s\n", topo_strerror(err)); goto error; } /* create/set the devfs-path and devid in the io group */ if (topo_pgroup_create(dtn, &io_pgroup, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "create io error %s\n", topo_strerror(err)); goto error; } if (topo_prop_set_string(dtn, TOPO_PGROUP_IO, TOPO_IO_DEV_PATH, TOPO_PROP_IMMUTABLE, dnode->ddn_dpath, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "set dev error %s\n", topo_strerror(err)); goto error; } if (dnode->ddn_devid && topo_prop_set_string(dtn, TOPO_PGROUP_IO, TOPO_IO_DEVID, TOPO_PROP_IMMUTABLE, dnode->ddn_devid, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "set devid error %s\n", topo_strerror(err)); goto error; } if (dnode->ddn_ppath_count != 0 && topo_prop_set_string_array(dtn, TOPO_PGROUP_IO, TOPO_IO_PHYS_PATH, TOPO_PROP_IMMUTABLE, (const char **)dnode->ddn_ppath, dnode->ddn_ppath_count, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "set phys-path error %s\n", topo_strerror(err)); goto error; } /* set the storage group public /dev name */ if (dnode->ddn_lpath != NULL && topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_LOGICAL_DISK_NAME, TOPO_PROP_IMMUTABLE, dnode->ddn_lpath, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "set disk_name error %s\n", topo_strerror(err)); goto error; } /* populate other misc storage group properties */ if (dnode->ddn_mfg && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_MANUFACTURER, TOPO_PROP_IMMUTABLE, dnode->ddn_mfg, &err) != 0)) { topo_mod_dprintf(mod, "disk_set_props: " "set mfg error %s\n", topo_strerror(err)); goto error; } if (dnode->ddn_model && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_MODEL, TOPO_PROP_IMMUTABLE, dnode->ddn_model, &err) != 0)) { topo_mod_dprintf(mod, "disk_set_props: " "set model error %s\n", topo_strerror(err)); goto error; } if (dnode->ddn_serial && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_SERIAL_NUM, TOPO_PROP_IMMUTABLE, dnode->ddn_serial, &err) != 0)) { topo_mod_dprintf(mod, "disk_set_props: " "set serial error %s\n", topo_strerror(err)); goto error; } if (dnode->ddn_firm && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_FIRMWARE_REV, TOPO_PROP_IMMUTABLE, dnode->ddn_firm, &err) != 0)) { topo_mod_dprintf(mod, "disk_set_props: " "set firm error %s\n", topo_strerror(err)); goto error; } if (dnode->ddn_cap && (topo_prop_set_string(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_CAPACITY, TOPO_PROP_IMMUTABLE, dnode->ddn_cap, &err) != 0)) { topo_mod_dprintf(mod, "disk_set_props: " "set cap error %s\n", topo_strerror(err)); goto error; } if (dnode->ddn_devid == NULL || (drive_descr = dm_get_descriptor_by_name(DM_DRIVE, dnode->ddn_devid, &err)) == NULL || (drive_attrs = dm_get_attributes(drive_descr, &err)) == NULL) goto out; if (nvlist_lookup_boolean(drive_attrs, DM_SOLIDSTATE) == 0 || nvlist_lookup_uint32(drive_attrs, DM_RPM, &rpm) != 0) goto out; if (topo_prop_set_uint32(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_RPM, TOPO_PROP_IMMUTABLE, rpm, &err) != 0) { topo_mod_dprintf(mod, "disk_set_props: " "set rpm error %s\n", topo_strerror(err)); dm_free_descriptor(drive_descr); goto error; } err = 0; out: if (drive_descr != NULL) dm_free_descriptor(drive_descr); nvlist_free(fmri); if (label) topo_mod_strfree(mod, label); nvlist_free(asru); return (err); error: err = topo_mod_seterrno(mod, err); goto out; }
static int create_core(topo_mod_t *mod, tnode_t *pnode, nvlist_t *cpu, nvlist_t *auth, uint16_t chip_smbiosid) { tnode_t *core; int32_t coreid, cpuid; int err, perr, nerr = 0; nvlist_t *fmri; char *serial = NULL; char *part = NULL; char *rev = NULL; if ((err = nvlist_lookup_int32(cpu, FM_PHYSCPU_INFO_CORE_ID, &coreid)) != 0) { whinge(mod, NULL, "create_core: lookup core_id failed: %s\n", strerror(err)); return (-1); } if ((core = topo_node_lookup(pnode, CORE_NODE_NAME, coreid)) == NULL) { if ((core = create_node(mod, pnode, auth, CORE_NODE_NAME, coreid, chip_smbiosid)) == NULL) return (-1); /* * Inherit FRU from the chip node, for native, we use hc * scheme ASRU for the core node. */ (void) topo_node_fru_set(core, NULL, 0, &perr); /* * From the inherited FRU, extract the Serial * number if SMBIOS donates and set it in the ASRU */ if (FM_AWARE_SMBIOS(mod)) { char *val = NULL; if (topo_node_resource(core, &fmri, &err) != 0) whinge(mod, NULL, "create_core: topo_prop_get_fmri failed\n"); if (nvlist_lookup_string(fmri, FM_FMRI_HC_SERIAL_ID, &val) != 0) whinge(mod, NULL, "create_core:" "nvlist_lookup_string failed\n"); else serial = topo_mod_strdup(mod, val); nvlist_free(fmri); } if (is_xpv()) { if (topo_node_resource(core, &fmri, &err) == -1) { whinge(mod, &nerr, "create_core: " "topo_node_resource failed\n"); } else { if (FM_AWARE_SMBIOS(mod)) (void) nvlist_add_string(fmri, FM_FMRI_HC_SERIAL_ID, serial); (void) topo_node_asru_set(core, fmri, 0, &err); nvlist_free(fmri); } } if (topo_method_register(mod, core, strands_retire_methods) < 0) whinge(mod, &nerr, "create_core: " "topo_method_register failed\n"); (void) topo_pgroup_create(core, &core_pgroup, &err); nerr -= add_nvlist_longprops(mod, core, cpu, PGNAME(CORE), NULL, CORE_CHIP_ID, CORE_PROCNODE_ID, NULL); if (topo_node_range_create(mod, core, STRAND_NODE_NAME, 0, 255) != 0) return (-1); } if (!is_xpv()) { /* * In native mode, we're in favor of cpu scheme ASRU for * printing reason. More work needs to be done to support * multi-strand cpu: the ASRU will be a list of cpuid then. */ if (nvlist_lookup_int32(cpu, STRAND_CPU_ID, &cpuid) != 0) { whinge(mod, &nerr, "create_core: lookup cpuid " "failed\n"); } else { if ((fmri = cpu_fmri_create(mod, cpuid, serial, 0)) != NULL) { (void) topo_node_asru_set(core, fmri, 0, &err); nvlist_free(fmri); } else { whinge(mod, &nerr, "create_core: " "cpu_fmri_create() failed\n"); } } } if (FM_AWARE_SMBIOS(mod)) { (void) topo_node_label_set(core, NULL, &perr); if (topo_node_resource(core, &fmri, &perr) != 0) { whinge(mod, &nerr, "create_core: " "topo_node_resource failed\n"); perr = 0; } perr += nvlist_lookup_string(fmri, FM_FMRI_HC_PART, &part); perr += nvlist_lookup_string(fmri, FM_FMRI_HC_REVISION, &rev); if (perr != 0) { whinge(mod, NULL, "create_core: nvlist_lookup_string failed\n"); perr = 0; } perr += topo_prop_set_string(core, PGNAME(CORE), FM_FMRI_HC_SERIAL_ID, TOPO_PROP_IMMUTABLE, serial, &perr); perr += topo_prop_set_string(core, PGNAME(CORE), FM_FMRI_HC_PART, TOPO_PROP_IMMUTABLE, part, &perr); perr += topo_prop_set_string(core, PGNAME(CORE), FM_FMRI_HC_REVISION, TOPO_PROP_IMMUTABLE, rev, &perr); if (perr != 0) whinge(mod, NULL, "create_core: topo_prop_set_string" "failed\n"); nvlist_free(fmri); topo_mod_strfree(mod, serial); } err = create_strand(mod, core, cpu, auth, chip_smbiosid); return (err == 0 && nerr == 0 ? 0 : -1); }
static int amd_dimm_create(topo_mod_t *mod, uint16_t chip_smbid, tnode_t *pnode, const char *name, nvlist_t *mc, nvlist_t *auth) { int i, err, nerr = 0; int perr = 0; nvpair_t *nvp; tnode_t *dimmnode; nvlist_t *fmri, **dimmarr = NULL; uint64_t num; uint_t ndimm; id_t smbid; const char *serial; const char *part; const char *rev; if (nvlist_lookup_nvlist_array(mc, "dimmlist", &dimmarr, &ndimm) != 0) { whinge(mod, NULL, "amd_dimm_create: dimmlist lookup failed\n"); return (-1); } if (ndimm == 0) return (0); /* no dimms present on this node */ if (topo_node_range_create(mod, pnode, name, 0, MAX_DIMMNUM) < 0) { whinge(mod, NULL, "amd_dimm_create: range create failed\n"); return (-1); } for (i = 0; i < ndimm; i++) { if (nvlist_lookup_uint64(dimmarr[i], "num", &num) != 0) { whinge(mod, &nerr, "amd_dimm_create: dimm num property " "missing\n"); continue; } if (mkrsrc(mod, pnode, name, num, auth, &fmri) < 0) { whinge(mod, &nerr, "amd_dimm_create: mkrsrc failed\n"); continue; } if (FM_AWARE_SMBIOS(mod)) { smbid = memnode_to_smbiosid(mod, chip_smbid, DIMM_NODE_NAME, i, NULL); serial = chip_serial_smbios_get(mod, smbid); part = chip_part_smbios_get(mod, smbid); rev = chip_rev_smbios_get(mod, smbid); perr += nvlist_add_string(fmri, FM_FMRI_HC_SERIAL_ID, serial); perr += nvlist_add_string(fmri, FM_FMRI_HC_PART, part); perr += nvlist_add_string(fmri, FM_FMRI_HC_REVISION, rev); if (perr != 0) whinge(mod, NULL, "amd_dimm_create:" "nvlist_add_string failed\n"); } if ((dimmnode = topo_node_bind(mod, pnode, name, num, fmri)) == NULL) { nvlist_free(fmri); whinge(mod, &nerr, "amd_dimm_create: node bind " "failed\n"); continue; } if (!FM_AWARE_SMBIOS(mod)) if (topo_method_register(mod, dimmnode, dimm_methods) < 0) whinge(mod, &nerr, "amd_dimm_create: " "topo_method_register failed"); (void) topo_pgroup_create(dimmnode, &dimm_pgroup, &err); if (FM_AWARE_SMBIOS(mod)) { char *label; nvlist_free(fmri); (void) topo_node_resource(dimmnode, &fmri, &err); label = (char *)chip_label_smbios_get(mod, pnode, smbid, NULL); if (topo_node_label_set(dimmnode, label, &perr) == -1) topo_mod_dprintf(mod, "Failed" "to set label\n"); topo_mod_strfree(mod, label); (void) topo_prop_set_string(dimmnode, PGNAME(DIMM), FM_FMRI_HC_SERIAL_ID, TOPO_PROP_IMMUTABLE, serial, &err); (void) topo_prop_set_string(dimmnode, PGNAME(DIMM), FM_FMRI_HC_PART, TOPO_PROP_IMMUTABLE, part, &err); (void) topo_prop_set_string(dimmnode, PGNAME(DIMM), FM_FMRI_HC_REVISION, TOPO_PROP_IMMUTABLE, rev, &err); } (void) topo_node_asru_set(dimmnode, fmri, 0, &err); (void) topo_node_fru_set(dimmnode, fmri, 0, &err); nvlist_free(fmri); for (nvp = nvlist_next_nvpair(dimmarr[i], NULL); nvp != NULL; nvp = nvlist_next_nvpair(dimmarr[i], nvp)) { if (nvpair_type(nvp) == DATA_TYPE_UINT64_ARRAY && strcmp(nvpair_name(nvp), "csnums") == 0 || nvpair_type(nvp) == DATA_TYPE_STRING_ARRAY && strcmp(nvpair_name(nvp), "csnames") == 0) continue; /* used in amd_rank_create() */ nerr += nvprop_add(mod, nvp, PGNAME(DIMM), dimmnode); } nerr += amd_rank_create(mod, dimmnode, dimmarr[i], auth); } return (nerr == 0 ? 0 : -1); }
int amd_rank_create(topo_mod_t *mod, tnode_t *pnode, nvlist_t *dimmnvl, nvlist_t *auth) { uint64_t *csnumarr; char **csnamearr; uint_t ncs, ncsname; tnode_t *ranknode; nvlist_t *fmri, *pfmri = NULL; uint64_t dsz, rsz; int nerr = 0; int err; int i; if (nvlist_lookup_uint64_array(dimmnvl, "csnums", &csnumarr, &ncs) != 0 || nvlist_lookup_string_array(dimmnvl, "csnames", &csnamearr, &ncsname) != 0 || ncs != ncsname) { whinge(mod, &nerr, "amd_rank_create: " "csnums/csnames extraction failed\n"); return (nerr); } if (topo_node_resource(pnode, &pfmri, &err) < 0) { whinge(mod, &nerr, "amd_rank_create: parent fmri lookup " "failed\n"); return (nerr); } if (topo_node_range_create(mod, pnode, RANK_NODE_NAME, 0, ncs) < 0) { whinge(mod, &nerr, "amd_rank_create: range create failed\n"); nvlist_free(pfmri); return (nerr); } if (topo_prop_get_uint64(pnode, PGNAME(DIMM), "size", &dsz, &err) == 0) { rsz = dsz / ncs; } else { whinge(mod, &nerr, "amd_rank_create: parent dimm has no " "size\n"); return (nerr); } for (i = 0; i < ncs; i++) { if (mkrsrc(mod, pnode, RANK_NODE_NAME, i, auth, &fmri) < 0) { whinge(mod, &nerr, "amd_rank_create: mkrsrc failed\n"); continue; } if ((ranknode = topo_node_bind(mod, pnode, RANK_NODE_NAME, i, fmri)) == NULL) { nvlist_free(fmri); whinge(mod, &nerr, "amd_rank_create: node bind " "failed\n"); continue; } nvlist_free(fmri); if (FM_AWARE_SMBIOS(mod)) (void) topo_node_fru_set(ranknode, NULL, 0, &err); else (void) topo_node_fru_set(ranknode, pfmri, 0, &err); /* * If a rank is faulted the asru is the associated * chip-select, but if a page within a rank is faulted * the asru is just that page. Hence the dual preconstructed * and computed ASRU. */ if (topo_method_register(mod, ranknode, rank_methods) < 0) whinge(mod, &nerr, "amd_rank_create: " "topo_method_register failed"); if (! is_xpv() && topo_method_register(mod, ranknode, ntv_page_retire_methods) < 0) whinge(mod, &nerr, "amd_rank_create: " "topo_method_register failed"); (void) topo_node_asru_set(ranknode, cs_fmri[csnumarr[i]], TOPO_ASRU_COMPUTE, &err); (void) topo_pgroup_create(ranknode, &rank_pgroup, &err); (void) topo_prop_set_uint64(ranknode, PGNAME(RANK), "size", TOPO_PROP_IMMUTABLE, rsz, &err); (void) topo_prop_set_string(ranknode, PGNAME(RANK), "csname", TOPO_PROP_IMMUTABLE, csnamearr[i], &err); (void) topo_prop_set_uint64(ranknode, PGNAME(RANK), "csnum", TOPO_PROP_IMMUTABLE, csnumarr[i], &err); } nvlist_free(pfmri); return (nerr); }
/*ARGSUSED*/ static int amd_generic_mc_create(topo_mod_t *mod, uint16_t smbid, tnode_t *cnode, tnode_t *mcnode, int family, int model, nvlist_t *auth) { int chan, cs; /* * Elsewhere we have already returned for families less than 0xf. * This "generic" topology is adequate for all of family 0xf and * for revisions A to E of family 0x10 (for the list of models * in each revision, refer to usr/src/uts/i86pc/os/cpuid_subr.c). * We cover all family 0x10 models, till model 10. */ if (family > 0x10 || (family == 0x10 && model > 10)) return (1); if (topo_node_range_create(mod, mcnode, CHAN_NODE_NAME, 0, MAX_CHANNUM) < 0) { whinge(mod, NULL, "amd_generic_mc_create: range create for " "channels failed\n"); return (-1); } for (chan = 0; chan <= MAX_CHANNUM; chan++) { tnode_t *chnode; nvlist_t *fmri; int err; if (mkrsrc(mod, mcnode, CHAN_NODE_NAME, chan, auth, &fmri) != 0) { whinge(mod, NULL, "amd_generic_mc_create: mkrsrc " "failed\n"); return (-1); } if ((chnode = topo_node_bind(mod, mcnode, CHAN_NODE_NAME, chan, fmri)) == NULL) { nvlist_free(fmri); whinge(mod, NULL, "amd_generic_mc_create: node " "bind failed\n"); return (-1); } nvlist_free(fmri); (void) topo_pgroup_create(chnode, &chan_pgroup, &err); (void) topo_prop_set_string(chnode, PGNAME(CHAN), "channel", TOPO_PROP_IMMUTABLE, chan == 0 ? "A" : "B", &err); if (FM_AWARE_SMBIOS(mod)) { if (topo_node_label_set(chnode, NULL, &err) == -1) whinge(mod, NULL, "amd_generic_mc_create: " "topo_node_label_set\n"); if (topo_node_fru_set(chnode, NULL, 0, &err) != 0) whinge(mod, NULL, "amd_generic_mc_create: " "topo_node_fru_set failed\n"); } if (topo_node_range_create(mod, chnode, CS_NODE_NAME, 0, MAX_CSNUM) < 0) { whinge(mod, NULL, "amd_generic_mc_create: " "range create for cs failed\n"); return (-1); } for (cs = 0; cs <= MAX_CSNUM; cs++) { tnode_t *csnode; if (mkrsrc(mod, chnode, CS_NODE_NAME, cs, auth, &fmri) != 0) { whinge(mod, NULL, "amd_generic_mc_create: " "mkrsrc for cs failed\n"); return (-1); } if ((csnode = topo_node_bind(mod, chnode, CS_NODE_NAME, cs, fmri)) == NULL) { nvlist_free(fmri); whinge(mod, NULL, "amd_generic_mc_create: " "bind for cs failed\n"); return (-1); } /* * Dynamic ASRU for page faults within a chip-select. * The topology does not represent pages (there are * too many) so when a page is faulted we generate * an ASRU to represent the individual page. * If SMBIOS meets FMA needs, derive labels & serials * for DIMMS and apply to chip-select nodes. * If deriving from SMBIOS, skip IPMI */ if (FM_AWARE_SMBIOS(mod)) { if (topo_method_register(mod, csnode, x86pi_gen_cs_methods) < 0) whinge(mod, NULL, "amd_generic_mc_create: " "method registration failed\n"); } else { if (topo_method_register(mod, csnode, gen_cs_methods) < 0) whinge(mod, NULL, "amd_generic_mc_create: method" "registration failed\n"); } (void) topo_node_asru_set(csnode, fmri, TOPO_ASRU_COMPUTE, &err); nvlist_free(fmri); /* * If SMBIOS meets FMA needs, set DIMM as the FRU for * the chip-select node. Use the channel & chip-select * numbers to get the DIMM instance. * Send via inst : dram channel number * Receive via inst : dimm instance */ if (FM_AWARE_SMBIOS(mod)) { int inst; id_t dimm_smbid; const char *serial; const char *part; const char *rev; char *label; (void) topo_pgroup_create(csnode, &cs_pgroup, &err); inst = chan; dimm_smbid = memnode_to_smbiosid(mod, smbid, CS_NODE_NAME, cs, &inst); serial = chip_serial_smbios_get(mod, dimm_smbid); part = chip_part_smbios_get(mod, dimm_smbid); rev = chip_rev_smbios_get(mod, dimm_smbid); label = (char *)chip_label_smbios_get(mod, chnode, dimm_smbid, NULL); (void) topo_prop_set_string(csnode, PGNAME(CS), FM_FMRI_HC_SERIAL_ID, TOPO_PROP_IMMUTABLE, serial, &err); (void) topo_prop_set_string(csnode, PGNAME(CS), FM_FMRI_HC_PART, TOPO_PROP_IMMUTABLE, part, &err); (void) topo_prop_set_string(csnode, PGNAME(CS), FM_FMRI_HC_REVISION, TOPO_PROP_IMMUTABLE, rev, &err); /* * We apply DIMM labels to chip-select nodes, * FRU for chip-selects should be DIMMs, and * we do not derive dimm nodes for Family 0x10 * so FRU fmri is NULL, but FRU Labels are set, * the FRU labels point to the DIMM. */ (void) topo_node_label_set(csnode, label, &err); topo_mod_strfree(mod, label); } } } return (0); }
/* * cpuboard_rc_node_create() * Description: * Create a root complex node pciexrc * Parameters: * mp: topo module pointer * parent: topo parent node of the newly created pciexrc node * dnode: Solaris device node of the root complex * rcpath: Used to populated the dev property of the topo pciexrc node if * the local host does not own the root complex. */ static tnode_t * cpuboard_rc_node_create(topo_mod_t *mp, tnode_t *parent, di_node_t dnode, char *rcpath, int inst) { int err; tnode_t *rcn; char *dnpath; nvlist_t *mod; topo_mod_dprintf(mp, "cpuboard_rc_node_create:\n"); rcn = cpuboard_node_create(mp, parent, PCIEX_ROOT, inst, (void *)dnode); if (rcn == NULL) { return (NULL); } /* Inherit parent FRU's label */ (void) topo_node_fru_set(rcn, NULL, 0, &err); (void) topo_node_label_set(rcn, NULL, &err); /* * Set ASRU to be the dev-scheme ASRU */ if ((dnpath = di_devfs_path(dnode)) != NULL) { nvlist_t *fmri; /* * The local host owns the root complex, so use the dev path * from the di_devfs_path(), instead of the passed in rcpath, * to populate the dev property. */ rcpath = dnpath; fmri = topo_mod_devfmri(mp, FM_DEV_SCHEME_VERSION, dnpath, NULL); if (fmri == NULL) { topo_mod_dprintf(mp, "dev:///%s fmri creation failed.\n", dnpath); (void) topo_mod_seterrno(mp, err); di_devfs_path_free(dnpath); return (NULL); } if (topo_node_asru_set(rcn, fmri, 0, &err) < 0) { topo_mod_dprintf(mp, "topo_node_asru_set failed\n"); (void) topo_mod_seterrno(mp, err); nvlist_free(fmri); di_devfs_path_free(dnpath); return (NULL); } nvlist_free(fmri); } else { topo_mod_dprintf(mp, "NULL di_devfs_path.\n"); } /* * Set pciexrc properties for root complex nodes */ /* Add the io and pci property groups */ if (topo_pgroup_create(rcn, &io_pgroup, &err) < 0) { topo_mod_dprintf(mp, "topo_pgroup_create failed\n"); di_devfs_path_free(dnpath); (void) topo_mod_seterrno(mp, err); return (NULL); } if (topo_pgroup_create(rcn, &pci_pgroup, &err) < 0) { topo_mod_dprintf(mp, "topo_pgroup_create failed\n"); di_devfs_path_free(dnpath); (void) topo_mod_seterrno(mp, err); return (NULL); } /* Add the devfs path property */ if (rcpath) { if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DEV, TOPO_PROP_IMMUTABLE, rcpath, &err) != 0) { topo_mod_dprintf(mp, "Failed to set DEV property\n"); (void) topo_mod_seterrno(mp, err); } } if (dnpath) { di_devfs_path_free(dnpath); } /* T5440 device type is always "pciex" */ if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DEVTYPE, TOPO_PROP_IMMUTABLE, CPUBOARD_PX_DEVTYPE, &err) != 0) { topo_mod_dprintf(mp, "Failed to set DEVTYPE property\n"); } /* T5440 driver is always "px" */ if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DRIVER, TOPO_PROP_IMMUTABLE, CPUBOARD_PX_DRV, &err) != 0) { topo_mod_dprintf(mp, "Failed to set DRIVER property\n"); } if ((mod = topo_mod_modfmri(mp, FM_MOD_SCHEME_VERSION, CPUBOARD_PX_DRV)) == NULL || topo_prop_set_fmri(rcn, TOPO_PGROUP_IO, TOPO_IO_MODULE, TOPO_PROP_IMMUTABLE, mod, &err) != 0) { topo_mod_dprintf(mp, "Failed to set MODULE property\n"); } if (mod != NULL) nvlist_free(mod); /* This is a PCIEX Root Complex */ if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI, TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCIEX_ROOT, &err) != 0) { topo_mod_dprintf(mp, "Failed to set EXCAP property\n"); } /* BDF of T5440 root complex is constant */ if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI, TOPO_PCI_BDF, TOPO_PROP_IMMUTABLE, CPUBOARD_PX_BDF, &err) != 0) { topo_mod_dprintf(mp, "Failed to set EXCAP property\n"); } /* Make room for children */ (void) topo_node_range_create(mp, rcn, PCIEX_BUS, 0, CPUBOARD_MAX); return (rcn); }
static int create_strand(topo_mod_t *mod, tnode_t *pnode, nvlist_t *cpu, nvlist_t *auth, uint16_t chip_smbiosid) { tnode_t *strand; int32_t strandid, cpuid; int err, perr, nerr = 0; nvlist_t *fmri; char *serial = NULL; char *part = NULL; char *rev = NULL; if ((err = nvlist_lookup_int32(cpu, FM_PHYSCPU_INFO_STRAND_ID, &strandid)) != 0) { whinge(mod, NULL, "create_strand: lookup strand_id failed: " "%s\n", strerror(err)); return (-1); } if ((strand = topo_node_lookup(pnode, STRAND_NODE_NAME, strandid)) != NULL) { whinge(mod, NULL, "create_strand: duplicate tuple found\n"); return (-1); } if ((strand = create_node(mod, pnode, auth, STRAND_NODE_NAME, strandid, chip_smbiosid)) == NULL) return (-1); /* * Inherit FRU from core node, in native use cpu scheme ASRU, * in xpv, use hc scheme ASRU. */ (void) topo_node_fru_set(strand, NULL, 0, &perr); /* * From the inherited FRU, extract the Serial * number(if SMBIOS donates) and set it in the ASRU */ if (FM_AWARE_SMBIOS(mod)) { char *val = NULL; if (topo_prop_get_fmri(strand, TOPO_PGROUP_PROTOCOL, TOPO_PROP_RESOURCE, &fmri, &err) != 0) whinge(mod, NULL, "create_strand: topo_prop_get_fmri failed\n"); if (nvlist_lookup_string(fmri, FM_FMRI_HC_SERIAL_ID, &val) != 0) whinge(mod, NULL, "create_strand: nvlist_lookup_string failed: \n"); else serial = topo_mod_strdup(mod, val); nvlist_free(fmri); } if (is_xpv()) { if (topo_node_resource(strand, &fmri, &err) == -1) { whinge(mod, &nerr, "create_strand: " "topo_node_resource failed\n"); } else { if (FM_AWARE_SMBIOS(mod)) (void) nvlist_add_string(fmri, FM_FMRI_HC_SERIAL_ID, serial); (void) topo_node_asru_set(strand, fmri, 0, &err); nvlist_free(fmri); } } else { if (nvlist_lookup_int32(cpu, STRAND_CPU_ID, &cpuid) != 0) { whinge(mod, &nerr, "create_strand: lookup cpuid " "failed\n"); } else { if ((fmri = cpu_fmri_create(mod, cpuid, serial, 0)) != NULL) { (void) topo_node_asru_set(strand, fmri, 0, &err); nvlist_free(fmri); } else { whinge(mod, &nerr, "create_strand: " "cpu_fmri_create() failed\n"); } } } if (topo_method_register(mod, strand, strands_retire_methods) < 0) whinge(mod, &nerr, "create_strand: " "topo_method_register failed\n"); (void) topo_pgroup_create(strand, &strand_pgroup, &err); nerr -= add_nvlist_longprops(mod, strand, cpu, PGNAME(STRAND), NULL, STRAND_CHIP_ID, STRAND_PROCNODE_ID, STRAND_CORE_ID, STRAND_CPU_ID, NULL); if (FM_AWARE_SMBIOS(mod)) { (void) topo_node_label_set(strand, NULL, &perr); if (topo_node_resource(strand, &fmri, &perr) != 0) { whinge(mod, &nerr, "create_strand: " "topo_node_resource failed\n"); perr = 0; } perr += nvlist_lookup_string(fmri, FM_FMRI_HC_PART, &part); perr += nvlist_lookup_string(fmri, FM_FMRI_HC_REVISION, &rev); if (perr != 0) { whinge(mod, NULL, "create_strand: nvlist_lookup_string failed\n"); perr = 0; } perr += topo_prop_set_string(strand, PGNAME(STRAND), FM_FMRI_HC_SERIAL_ID, TOPO_PROP_IMMUTABLE, serial, &perr); perr += topo_prop_set_string(strand, PGNAME(STRAND), FM_FMRI_HC_PART, TOPO_PROP_IMMUTABLE, part, &perr); perr += topo_prop_set_string(strand, PGNAME(STRAND), FM_FMRI_HC_REVISION, TOPO_PROP_IMMUTABLE, rev, &perr); if (perr != 0) whinge(mod, NULL, "create_strand: topo_prop_set_string" "failed\n"); nvlist_free(fmri); topo_mod_strfree(mod, serial); } return (err == 0 && nerr == 0 ? 0 : -1); }
void amd_mc_create(topo_mod_t *mod, uint16_t smbid, tnode_t *pnode, const char *name, nvlist_t *auth, int32_t procnodeid, int32_t procnodes_per_pkg, int family, int model, int *nerrp) { tnode_t *mcnode; nvlist_t *rfmri, *fmri; nvpair_t *nvp; nvlist_t *mc = NULL; int i, err; int mcnum = procnodeid % procnodes_per_pkg; char *serial = NULL; char *part = NULL; char *rev = NULL; /* * Return with no error for anything before AMD family 0xf - we * won't generate even a generic memory topology for earlier * families. */ if (family < 0xf) return; if (topo_node_lookup(pnode, name, mcnum) != NULL) return; if (FM_AWARE_SMBIOS(mod)) { (void) topo_node_resource(pnode, &rfmri, &err); (void) nvlist_lookup_string(rfmri, "serial", &serial); (void) nvlist_lookup_string(rfmri, "part", &part); (void) nvlist_lookup_string(rfmri, "revision", &rev); } if (mkrsrc(mod, pnode, name, mcnum, auth, &fmri) != 0) { if (FM_AWARE_SMBIOS(mod)) nvlist_free(rfmri); whinge(mod, nerrp, "mc_create: mkrsrc failed\n"); return; } if (FM_AWARE_SMBIOS(mod)) { (void) nvlist_add_string(fmri, "serial", serial); (void) nvlist_add_string(fmri, "part", part); (void) nvlist_add_string(fmri, "revision", rev); nvlist_free(rfmri); } if ((mcnode = topo_node_bind(mod, pnode, name, mcnum, fmri)) == NULL) { nvlist_free(fmri); whinge(mod, nerrp, "mc_create: mc bind failed\n"); return; } if (topo_node_fru_set(mcnode, NULL, 0, &err) < 0) whinge(mod, nerrp, "mc_create: topo_node_fru_set failed\n"); if (FM_AWARE_SMBIOS(mod)) { if (topo_node_label_set(mcnode, NULL, &err) == -1) topo_mod_dprintf(mod, "Failed to set label\n"); } nvlist_free(fmri); if (topo_pgroup_create(mcnode, &mc_pgroup, &err) < 0) whinge(mod, nerrp, "mc_create: topo_pgroup_create failed\n"); if (topo_prop_set_int32(mcnode, PGNAME(MCT), MCT_PROCNODE_ID, TOPO_PROP_IMMUTABLE, procnodeid, nerrp) != 0) whinge(mod, nerrp, "mc_create: topo_prop_set_int32 failed to" "add node id\n"); if ((mc = amd_lookup_by_mcid(mod, topo_node_instance(pnode))) == NULL) { /* * If a memory-controller driver exists for this chip model * it has not attached or has otherwise malfunctioned; * alternatively no memory-controller driver exists for this * (presumably newly-released) cpu model. We fallback to * creating a generic maximal topology. */ if (amd_generic_mc_create(mod, smbid, pnode, mcnode, family, model, auth) != 0) whinge(mod, nerrp, "mc_create: amd_generic_mc_create failed\n"); return; } /* * Add memory controller properties */ for (nvp = nvlist_next_nvpair(mc, NULL); nvp != NULL; nvp = nvlist_next_nvpair(mc, nvp)) { char *name = nvpair_name(nvp); data_type_t type = nvpair_type(nvp); if (type == DATA_TYPE_NVLIST_ARRAY && (strcmp(name, "cslist") == 0 || strcmp(name, "dimmlist") == 0)) { continue; } else if (type == DATA_TYPE_UINT8 && strcmp(name, MC_NVLIST_VERSTR) == 0) { continue; } else if (type == DATA_TYPE_NVLIST && strcmp(name, "htconfig") == 0) { nvlist_t *htnvl; (void) nvpair_value_nvlist(nvp, &htnvl); if (amd_htconfig(mod, pnode, htnvl) != 0) whinge(mod, nerrp, "mc_create: amd_htconfig failed\n"); } else { if (nvprop_add(mod, nvp, PGNAME(MCT), mcnode) != 0) whinge(mod, nerrp, "mc_create: nvprop_add failed\n"); } } if (amd_dramchan_create(mod, mcnode, CHAN_NODE_NAME, auth) != 0 || amd_cs_create(mod, mcnode, CS_NODE_NAME, mc, auth) != 0 || amd_dimm_create(mod, smbid, mcnode, DIMM_NODE_NAME, mc, auth) != 0) whinge(mod, nerrp, "mc_create: create children failed\n"); /* * Free the fmris for the chip-selects allocated in amd_cs_create */ for (i = 0; i < MC_CHIP_NCS; i++) { if (cs_fmri[i] != NULL) { nvlist_free(cs_fmri[i]); cs_fmri[i] = NULL; } } nvlist_free(mc); }
static int create_chip(topo_mod_t *mod, tnode_t *pnode, topo_instance_t min, topo_instance_t max, nvlist_t *cpu, nvlist_t *auth, int mc_offchip) { tnode_t *chip; nvlist_t *fmri = NULL; int err, perr, nerr = 0; int32_t chipid, procnodeid, procnodes_per_pkg; const char *vendor; int32_t family, model; boolean_t create_mc = B_FALSE; uint16_t smbios_id; /* * /dev/fm will export the chipid based on SMBIOS' ordering * of Type-4 structures, if SMBIOS meets FMA needs */ err = nvlist_lookup_pairs(cpu, 0, FM_PHYSCPU_INFO_CHIP_ID, DATA_TYPE_INT32, &chipid, FM_PHYSCPU_INFO_NPROCNODES, DATA_TYPE_INT32, &procnodes_per_pkg, FM_PHYSCPU_INFO_PROCNODE_ID, DATA_TYPE_INT32, &procnodeid, FM_PHYSCPU_INFO_VENDOR_ID, DATA_TYPE_STRING, &vendor, FM_PHYSCPU_INFO_FAMILY, DATA_TYPE_INT32, &family, FM_PHYSCPU_INFO_MODEL, DATA_TYPE_INT32, &model, NULL); if (err) { whinge(mod, NULL, "create_chip: lookup failed: %s\n", strerror(err)); return (-1); } if (chipid < min || chipid > max) return (-1); if (FM_AWARE_SMBIOS(mod)) { if ((err = nvlist_lookup_uint16(cpu, FM_PHYSCPU_INFO_SMBIOS_ID, &smbios_id)) != 0) { whinge(mod, NULL, "create_chip: lookup smbios_id failed" ": enumerating x86pi & chip topology, but" " no Chip properties from SMBIOS" " - err msg : %s\n", strerror(err)); /* * Lets reset the module specific * data to NULL, overriding any * SMBIOS capability encoded earlier. * This will fail all subsequent * FM_AWARE_SMBIOS checks. */ topo_mod_setspecific(mod, NULL); } } if ((chip = topo_node_lookup(pnode, CHIP_NODE_NAME, chipid)) == NULL) { if ((chip = create_node(mod, pnode, auth, CHIP_NODE_NAME, chipid, smbios_id)) == NULL) return (-1); /* * Do not register XML map methods if SMBIOS can provide * serial, part, revision & label */ if (!FM_AWARE_SMBIOS(mod)) { if (topo_method_register(mod, chip, chip_methods) < 0) whinge(mod, &nerr, "create_chip: " "topo_method_register failed\n"); } (void) topo_pgroup_create(chip, &chip_pgroup, &err); nerr -= add_nvlist_strprop(mod, chip, cpu, PGNAME(CHIP), CHIP_VENDOR_ID, NULL); nerr -= add_nvlist_longprops(mod, chip, cpu, PGNAME(CHIP), NULL, CHIP_FAMILY, CHIP_MODEL, CHIP_STEPPING, NULL); if (FM_AWARE_SMBIOS(mod)) { int fru = 0; char *serial = NULL; char *part = NULL; char *rev = NULL; char *label; fru = chip_fru_smbios_get(mod, smbios_id); /* * Chip is not a FRU, set the FRU fmri of parent node */ if (topo_node_resource(chip, &fmri, &perr) != 0) whinge(mod, &nerr, "create_chip: " "topo_node_resource failed\n"); if (!fru) { (void) topo_node_fru_set(chip, NULL, 0, &perr); label = NULL; } else { label = (char *)chip_label_smbios_get(mod, pnode, smbios_id, NULL); if (topo_node_fru_set(chip, fmri, 0, &perr) != 0) { whinge(mod, NULL, "create_chip: " "topo_node_fru_set failed\n"); perr = 0; } } perr += nvlist_lookup_string(fmri, FM_FMRI_HC_SERIAL_ID, &serial); perr += nvlist_lookup_string(fmri, FM_FMRI_HC_PART, &part); perr += nvlist_lookup_string(fmri, FM_FMRI_HC_REVISION, &rev); if (perr != 0) { whinge(mod, NULL, "create_chip: nvlist_lookup_string" "failed\n"); perr = 0; } perr += topo_prop_set_string(chip, PGNAME(CHIP), FM_FMRI_HC_SERIAL_ID, TOPO_PROP_IMMUTABLE, serial, &perr); perr += topo_prop_set_string(chip, PGNAME(CHIP), FM_FMRI_HC_PART, TOPO_PROP_IMMUTABLE, part, &perr); perr += topo_prop_set_string(chip, PGNAME(CHIP), FM_FMRI_HC_REVISION, TOPO_PROP_IMMUTABLE, rev, &perr); if (perr != 0) whinge(mod, NULL, "create_chip: topo_prop_set_string" "failed\n"); nvlist_free(fmri); if (topo_node_label_set(chip, label, &perr) == -1) { whinge(mod, NULL, "create_chip: " "topo_node_label_set failed\n"); } topo_mod_strfree(mod, label); } else { if (topo_node_resource(chip, &fmri, &err) == -1) { whinge(mod, &nerr, "create_chip: " "topo_node_resource failed\n"); } else { (void) topo_node_fru_set(chip, fmri, 0, &perr); nvlist_free(fmri); } } if (topo_method_register(mod, chip, strands_retire_methods) < 0) whinge(mod, &nerr, "create_chip: " "topo_method_register failed\n"); if (topo_node_range_create(mod, chip, CORE_NODE_NAME, 0, 255)) return (-1); if (strcmp(vendor, "AuthenticAMD") == 0) { if (topo_node_range_create(mod, chip, MCT_NODE_NAME, 0, 255)) return (-1); } create_mc = B_TRUE; } if (FM_AWARE_SMBIOS(mod)) { int status = 0; /* * STATUS * CPU Socket Populated * CPU Socket Unpopulated * Populated : Enabled * Populated : Disabled by BIOS (Setup) * Populated : Disabled by BIOS (Error) * Populated : Idle * * Enumerate core & strand only for Populated : Enabled * Enumerate Off-Chip Memory Controller only for * Populated : Enabled */ status = chip_status_smbios_get(mod, (id_t)smbios_id); if (!status) { whinge(mod, NULL, "create_chip: " "CPU Socket is not populated or is disabled\n"); return (0); } } err = create_core(mod, chip, cpu, auth, smbios_id); /* * Create memory-controller node under a chip for architectures * that may have on-chip memory-controller(s). * If SMBIOS meets FMA needs, when Multi-Chip-Module is * addressed, mc instances should be derived from SMBIOS */ if (strcmp(vendor, "AuthenticAMD") == 0) { amd_mc_create(mod, smbios_id, chip, MCT_NODE_NAME, auth, procnodeid, procnodes_per_pkg, family, model, &nerr); } else if (create_mc && !mc_offchip) onchip_mc_create(mod, smbios_id, chip, MCT_NODE_NAME, auth); return (err == 0 && nerr == 0 ? 0 : -1); }
/* * Create a root complex node. */ static tnode_t * opl_rc_node_create(topo_mod_t *mp, tnode_t *parent, di_node_t dnode, int inst) { int err; tnode_t *rcn; const char *slot_name; char *dnpath; nvlist_t *mod; rcn = opl_node_create(mp, parent, PCIEX_ROOT, inst, (void *)dnode); if (rcn == NULL) { return (NULL); } /* * If this root complex connects to a slot, it will have a * slot-names property. */ slot_name = opl_get_slot_name(mp, dnode); if (slot_name) { char fru_str[64]; nvlist_t *fru_fmri; /* Add FRU fmri */ (void) snprintf(fru_str, sizeof (fru_str), "hc:///component=%s", slot_name); if (topo_mod_str2nvl(mp, fru_str, &fru_fmri) == 0) { (void) topo_node_fru_set(rcn, fru_fmri, 0, &err); nvlist_free(fru_fmri); } /* Add label */ (void) topo_node_label_set(rcn, (char *)slot_name, &err); } else { /* Inherit parent FRU's label */ (void) topo_node_fru_set(rcn, NULL, 0, &err); (void) topo_node_label_set(rcn, NULL, &err); } /* * Set ASRU to be the dev-scheme ASRU */ if ((dnpath = di_devfs_path(dnode)) != NULL) { nvlist_t *fmri; fmri = topo_mod_devfmri(mp, FM_DEV_SCHEME_VERSION, dnpath, NULL); if (fmri == NULL) { topo_mod_dprintf(mp, "dev:///%s fmri creation failed.\n", dnpath); (void) topo_mod_seterrno(mp, err); di_devfs_path_free(dnpath); return (NULL); } if (topo_node_asru_set(rcn, fmri, 0, &err) < 0) { topo_mod_dprintf(mp, "topo_node_asru_set failed\n"); (void) topo_mod_seterrno(mp, err); nvlist_free(fmri); di_devfs_path_free(dnpath); return (NULL); } nvlist_free(fmri); } else { topo_mod_dprintf(mp, "NULL di_devfs_path.\n"); } /* * Set pciexrc properties for root complex nodes */ /* Add the io and pci property groups */ if (topo_pgroup_create(rcn, &io_pgroup, &err) < 0) { topo_mod_dprintf(mp, "topo_pgroup_create failed\n"); di_devfs_path_free(dnpath); (void) topo_mod_seterrno(mp, err); return (NULL); } if (topo_pgroup_create(rcn, &pci_pgroup, &err) < 0) { topo_mod_dprintf(mp, "topo_pgroup_create failed\n"); di_devfs_path_free(dnpath); (void) topo_mod_seterrno(mp, err); return (NULL); } /* Add the devfs path property */ if (dnpath) { if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DEV, TOPO_PROP_IMMUTABLE, dnpath, &err) != 0) { topo_mod_dprintf(mp, "Failed to set DEV property\n"); di_devfs_path_free(dnpath); (void) topo_mod_seterrno(mp, err); } di_devfs_path_free(dnpath); } /* Oberon device type is always "pciex" */ if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DEVTYPE, TOPO_PROP_IMMUTABLE, OPL_PX_DEVTYPE, &err) != 0) { topo_mod_dprintf(mp, "Failed to set DEVTYPE property\n"); } /* Oberon driver is always "px" */ if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DRIVER, TOPO_PROP_IMMUTABLE, OPL_PX_DRV, &err) != 0) { topo_mod_dprintf(mp, "Failed to set DRIVER property\n"); } if ((mod = topo_mod_modfmri(mp, FM_MOD_SCHEME_VERSION, OPL_PX_DRV)) == NULL || topo_prop_set_fmri(rcn, TOPO_PGROUP_IO, TOPO_IO_MODULE, TOPO_PROP_IMMUTABLE, mod, &err) != 0) { topo_mod_dprintf(mp, "Failed to set MODULE property\n"); } nvlist_free(mod); /* This is a PCIEX Root Complex */ if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI, TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCIEX_ROOT, &err) != 0) { topo_mod_dprintf(mp, "Failed to set EXCAP property\n"); } /* BDF of Oberon root complex is constant */ if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI, TOPO_PCI_BDF, TOPO_PROP_IMMUTABLE, OPL_PX_BDF, &err) != 0) { topo_mod_dprintf(mp, "Failed to set EXCAP property\n"); } /* Make room for children */ (void) topo_node_range_create(mp, rcn, PCIEX_BUS, 0, OPL_BUS_MAX); return (rcn); }