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 * iob_tnode_create(tnode_t *parent, const char *name, topo_instance_t i, void *priv, topo_mod_t *mod) { topo_hdl_t *thp; nvlist_t *args, *fmri, *pfmri; tnode_t *ntn; int err; thp = topo_mod_handle(mod); if (topo_node_resource(parent, &pfmri, &err) < 0) { topo_mod_seterrno(mod, err); topo_mod_dprintf(mod, "Unable to retrieve parent resource.\n"); return (NULL); } if (topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0) { (void) topo_mod_seterrno(mod, EMOD_FMRI_NVL); nvlist_free(pfmri); return (NULL); } err = nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_PARENT, pfmri); if (err != 0) { nvlist_free(pfmri); nvlist_free(args); (void) topo_mod_seterrno(mod, EMOD_FMRI_NVL); return (NULL); } fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, name, i, args, &err); if (fmri == NULL) { topo_mod_dprintf(mod, "Unable to make nvlist for %s bind.\n", name); return (NULL); } ntn = topo_node_bind(mod, parent, name, i, fmri, priv); 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); if (topo_method_register(mod, ntn, Iob_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 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 tnode_t * create_node(topo_mod_t *mod, tnode_t *pnode, nvlist_t *auth, char *name, topo_instance_t inst, uint16_t smbios_id) { nvlist_t *fmri; tnode_t *cnode; if (mkrsrc(mod, pnode, name, inst, auth, &fmri) != 0) { whinge(mod, NULL, "create_node: mkrsrc failed\n"); return (NULL); } if (FM_AWARE_SMBIOS(mod)) { id_t phys_cpu_smbid; int perr = 0; const char *serial = NULL; const char *part = NULL; const char *rev = NULL; phys_cpu_smbid = smbios_id; serial = chip_serial_smbios_get(mod, phys_cpu_smbid); part = chip_part_smbios_get(mod, phys_cpu_smbid); rev = chip_rev_smbios_get(mod, phys_cpu_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, "create_node: nvlist_add_string failed\n"); topo_mod_strfree(mod, (char *)serial); topo_mod_strfree(mod, (char *)part); topo_mod_strfree(mod, (char *)rev); } cnode = topo_node_bind(mod, pnode, name, inst, fmri); nvlist_free(fmri); if (cnode == NULL) { whinge(mod, NULL, "create_node: node bind failed" " for %s %d\n", name, (int)inst); } return (cnode); }
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); }
static tnode_t * cpuboard_node_create(topo_mod_t *mp, tnode_t *parent, const char *name, int inst, void *priv) { tnode_t *node; nvlist_t *fmri; nvlist_t *auth = topo_mod_auth(mp, parent); topo_mod_dprintf(mp, "cpuboard_node_create:\n"); if (parent == NULL || inst < 0) { return (NULL); } /* Create FMRI */ if ((fmri = topo_mod_hcfmri(mp, parent, FM_HC_SCHEME_VERSION, name, inst, NULL, auth, NULL, NULL, NULL)) == NULL) { topo_mod_dprintf(mp, "create of tnode for %s failed: %s", name, topo_strerror(topo_mod_errno(mp))); nvlist_free(auth); return (NULL); } nvlist_free(auth); /* Create and bind node */ node = topo_node_bind(mp, parent, name, inst, fmri); if (node == NULL) { nvlist_free(fmri); topo_mod_dprintf(mp, "unable to bind root complex: %s\n", topo_strerror(topo_mod_errno(mp))); return (NULL); /* mod_errno already set */ } nvlist_free(fmri); topo_node_setspecific(node, priv); return (node); }
tnode_t * x86pi_node_bind(topo_mod_t *mod, tnode_t *t_parent, x86pi_hcfmri_t *hcfmri, nvlist_t *fmri, int flag) { int result; tnode_t *t_node; char *f = "x86pi_node_bind"; if (t_parent == NULL) { topo_mod_dprintf(mod, "%s: NULL parent for %s node instance %d\n", f, hcfmri->hc_name, hcfmri->instance); return (NULL); } /* Bind this node to the parent */ t_node = topo_node_bind(mod, t_parent, hcfmri->hc_name, hcfmri->instance, fmri); if (t_node == NULL) { topo_mod_dprintf(mod, "%s: failed to bind %s node instance %d: %s\n", f, hcfmri->hc_name, (uint32_t)hcfmri->instance, topo_strerror(topo_mod_errno(mod))); return (NULL); } topo_mod_dprintf(mod, "%s: bound %s node instance %d type %s\n", f, hcfmri->hc_name, hcfmri->instance, hcfmri->hc_name); /* * We have bound the node. Now decorate it with an appropriate * FRU and label (which may be inherited from the parent). */ result = x86pi_set_frufmri(mod, hcfmri, t_parent, t_node, flag); if (result != 0) { /* * Though we have failed to set the FRU FMRI we still continue. * The module errno is set by the called routine, so we report * the problem and move on. */ topo_mod_dprintf(mod, "%s: failed to set FRU FMRI for %s node\n", f, hcfmri->hc_name); } result = x86pi_set_label(mod, hcfmri->location, hcfmri->hc_name, t_node); if (result != 0) { /* * Though we have failed to set the label, we still continue. * The module errno is set by the called routine, so we report * the problem and move on. */ topo_mod_dprintf(mod, "%s: no label for %s node\n", f, hcfmri->hc_name); } result = x86pi_set_auth(mod, hcfmri, t_parent, t_node); if (result != 0) { /* * Though we have failed to set the authority, we still * continue. The module errno is set by the called routine, so * we report the problem and move on. */ topo_mod_dprintf(mod, "%s: no authority information for %s node\n", f, hcfmri->hc_name); } result = x86pi_set_system(mod, t_node); if (result != 0) { /* * Though we have failed to set the system group, we still * continue. The module errno is set by the called routine, so * we report the problem and move on. */ topo_mod_dprintf(mod, "%s: no system information for %s node\n", f, hcfmri->hc_name); } return (t_node); }
/* create the disk topo node */ static int disk_tnode_create(topo_mod_t *mod, tnode_t *parent, dev_di_node_t *dnode, const char *name, topo_instance_t i, tnode_t **rval) { int len; nvlist_t *fmri; tnode_t *dtn; char *part = NULL; nvlist_t *auth; char *mfg, *model, *firm, *serial; *rval = NULL; if (dnode != NULL) { mfg = topo_mod_clean_str(mod, dnode->ddn_mfg); model = topo_mod_clean_str(mod, dnode->ddn_model); firm = topo_mod_clean_str(mod, dnode->ddn_firm); serial = topo_mod_clean_str(mod, dnode->ddn_serial); } else { mfg = model = firm = serial = NULL; } /* form 'part=' of fmri as "<mfg>-<model>" */ if (mfg != NULL && model != NULL) { len = strlen(mfg) + 1 + strlen(model) + 1; if ((part = topo_mod_alloc(mod, len)) != NULL) (void) snprintf(part, len, "%s-%s", mfg, model); } auth = topo_mod_auth(mod, parent); fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i, NULL, auth, part ? part : model, firm, serial); nvlist_free(auth); topo_mod_strfree(mod, part); topo_mod_strfree(mod, mfg); topo_mod_strfree(mod, model); topo_mod_strfree(mod, firm); topo_mod_strfree(mod, serial); if (fmri == NULL) { topo_mod_dprintf(mod, "disk_tnode_create: " "hcfmri (%s%d/%s%d) error %s\n", topo_node_name(parent), topo_node_instance(parent), name, i, topo_strerror(topo_mod_errno(mod))); return (-1); } if ((dtn = topo_node_bind(mod, parent, name, i, fmri)) == NULL) { if (topo_mod_errno(mod) == EMOD_NODE_BOUND) { /* * if disk 0 is already there then we're done */ nvlist_free(fmri); return (0); } topo_mod_dprintf(mod, "disk_tnode_create: " "bind (%s%d/%s%d) error %s\n", topo_node_name(parent), topo_node_instance(parent), name, i, topo_strerror(topo_mod_errno(mod))); nvlist_free(fmri); return (-1); } nvlist_free(fmri); /* add the properties of the disk */ if (disk_set_props(mod, parent, dtn, dnode) != 0) { topo_mod_dprintf(mod, "disk_tnode_create: " "disk_set_props (%s%d/%s%d) error %s\n", topo_node_name(parent), topo_node_instance(parent), name, i, topo_strerror(topo_mod_errno(mod))); topo_node_unbind(dtn); return (-1); } if (dnode->ddn_devid != NULL && disk_add_temp_sensor(mod, dtn, dnode->ddn_devid) != 0) { topo_mod_dprintf(mod, "disk_tnode_create: failed to create " "temperature sensor node on bay=%d/disk=0", topo_node_instance(parent)); } *rval = dtn; return (0); }
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 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); }
static tnode_t * mb_tnode_create(topo_mod_t *mod, tnode_t *parent, const char *name, topo_instance_t i, void *priv) { nvlist_t *fmri; tnode_t *ntn; char *serial = NULL, *part = NULL; char *psn = NULL, *csn = NULL, *pstr = NULL; nvlist_t *auth = topo_mod_auth(mod, parent); /* * Get Product Serial Number, Chassis ID, MB Serial Number and * Part Number from PRI. */ (void) mb_get_pri_info(mod, &serial, &part, &csn, &psn); if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &pstr) != 0 && csn != NULL) { if (nvlist_add_string(auth, FM_FMRI_AUTH_CHASSIS, csn) != 0) { topo_mod_dprintf(mod, "failed to add chassis to auth"); nvlist_free(auth); return (NULL); } } if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN, &pstr) != 0 && psn != NULL) { if (nvlist_add_string(auth, FM_FMRI_AUTH_PRODUCT_SN, psn) != 0) { topo_mod_dprintf(mod, "failed to add product-sn to auth"); nvlist_free(auth); return (NULL); } } fmri = topo_mod_hcfmri(mod, NULL, FM_HC_SCHEME_VERSION, name, i, NULL, auth, part, NULL, serial); topo_mod_strfree(mod, serial); topo_mod_strfree(mod, part); topo_mod_strfree(mod, csn); topo_mod_strfree(mod, psn); if (fmri == NULL) { topo_mod_dprintf(mod, "Unable to make nvlist for %s bind: %s.\n", name, topo_mod_errmsg(mod)); nvlist_free(auth); 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(auth); nvlist_free(fmri); return (NULL); } mb_prop_set(ntn, auth); nvlist_free(auth); nvlist_free(fmri); topo_node_setspecific(ntn, priv); return (ntn); }