summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/hc_canon.h2
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/mem.c66
-rw-r--r--usr/src/lib/fm/topo/libtopo/common/topo_protocol.c103
-rw-r--r--usr/src/lib/fm/topo/modules/i86pc/chip/chip.c675
-rw-r--r--usr/src/lib/fm/topo/modules/i86pc/chip/chip.h17
5 files changed, 549 insertions, 314 deletions
diff --git a/usr/src/lib/fm/topo/libtopo/common/hc_canon.h b/usr/src/lib/fm/topo/libtopo/common/hc_canon.h
index 8da0c69c59..3edb066d32 100644
--- a/usr/src/lib/fm/topo/libtopo/common/hc_canon.h
+++ b/usr/src/lib/fm/topo/libtopo/common/hc_canon.h
@@ -45,12 +45,14 @@ static const char *Hc_canon[] = {
"chip-select",
"cpu",
"dimm",
+ "rank",
"disk",
"hostbridge",
"interconnect",
"chassis",
"ioboard",
"memory-controller",
+ "dram-channel",
"motherboard",
"pcibus",
"pcidev",
diff --git a/usr/src/lib/fm/topo/libtopo/common/mem.c b/usr/src/lib/fm/topo/libtopo/common/mem.c
index c228ff28b3..6d89042372 100644
--- a/usr/src/lib/fm/topo/libtopo/common/mem.c
+++ b/usr/src/lib/fm/topo/libtopo/common/mem.c
@@ -51,8 +51,6 @@ static int mem_unusable(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *,
nvlist_t **);
static int mem_expand(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *,
nvlist_t **);
-static int mem_asru(topo_mod_t *, tnode_t *, topo_version_t,
- nvlist_t *, nvlist_t **);
#define MEM_VERSION TOPO_VERSION
@@ -69,8 +67,6 @@ static const topo_method_t mem_methods[] = {
TOPO_METH_UNUSABLE_VERSION, TOPO_STABILITY_INTERNAL, mem_unusable },
{ TOPO_METH_EXPAND, TOPO_METH_UNUSABLE_DESC,
TOPO_METH_EXPAND_VERSION, TOPO_STABILITY_INTERNAL, mem_expand },
- { TOPO_METH_ASRU_COMPUTE, TOPO_METH_ASRU_COMPUTE_DESC,
- TOPO_METH_ASRU_COMPUTE_VERSION, TOPO_STABILITY_INTERNAL, mem_asru },
{ NULL }
};
@@ -138,15 +134,21 @@ mem_nvl2str(topo_mod_t *mod, tnode_t *node, topo_version_t version,
* PA then use that. Otherwise just format the unum element.
*/
if (nvlist_lookup_uint64(nvl, FM_FMRI_MEM_OFFSET, &val) == 0) {
- format = FM_FMRI_SCHEME_MEM ":///"
- FM_FMRI_MEM_UNUM "=%1$s/" FM_FMRI_MEM_OFFSET "=%2$llx";
+ format = FM_FMRI_SCHEME_MEM ":///%1$s/"
+ FM_FMRI_MEM_OFFSET "=%2$llx";
} else if (nvlist_lookup_uint64(nvl, FM_FMRI_MEM_PHYSADDR, &val) == 0) {
- format = FM_FMRI_SCHEME_MEM ":///"
- FM_FMRI_MEM_UNUM "=%1$s/" FM_FMRI_MEM_PHYSADDR "=%2$llx";
+ format = FM_FMRI_SCHEME_MEM ":///%1$s/"
+ FM_FMRI_MEM_PHYSADDR "=%2$llx";
} else
- format = FM_FMRI_SCHEME_MEM ":///" FM_FMRI_MEM_UNUM "=%1$s";
+ format = FM_FMRI_SCHEME_MEM ":///" "%1$s";
- len = snprintf(NULL, 0, format, unum, val);
+ /*
+ * If we have a well-formed unum we step over the hc:/// prefix
+ */
+ if (strncmp(unum, "hc:///", 6) == 0)
+ unum += 6;
+
+ len = snprintf(NULL, 0, format, unum, val) + 1;
buf = topo_mod_zalloc(mod, len);
if (buf == NULL) {
@@ -206,47 +208,3 @@ mem_expand(topo_mod_t *mod, tnode_t *node, topo_version_t version,
{
return (-1);
}
-
-/*ARGSUSED*/
-static int
-mem_asru(topo_mod_t *mod, tnode_t *node, topo_version_t version,
- nvlist_t *in, nvlist_t **out)
-{
- int err;
- uint64_t pa = 0, offset = 0;
- int incl_pa = 0, incl_offset = 0;
- nvlist_t *hcsp = NULL;
- nvlist_t *asru;
- char *cstr;
-
- if (nvlist_lookup_nvlist(in, FM_FMRI_HC_SPECIFIC, &hcsp) == 0) {
- incl_pa = (nvlist_lookup_uint64(hcsp,
- "asru-"FM_FMRI_MEM_PHYSADDR, &pa) == 0);
- incl_offset = (nvlist_lookup_uint64(hcsp,
- "asru-"FM_FMRI_MEM_OFFSET, &offset) == 0);
- }
-
- if (topo_fmri_nvl2str(topo_mod_handle(mod), in, &cstr, &err) < 0)
- return (topo_mod_seterrno(mod, err));
-
- if (topo_mod_nvalloc(mod, &asru, NV_UNIQUE_NAME) != 0) {
- topo_mod_strfree(mod, cstr);
- return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
- }
- err = nvlist_add_uint8(asru, FM_VERSION, FM_MEM_SCHEME_VERSION);
- err |= nvlist_add_string(asru, FM_FMRI_SCHEME, FM_FMRI_SCHEME_MEM);
- err |= nvlist_add_string(asru, FM_FMRI_MEM_UNUM, cstr);
- if (incl_pa)
- err |= nvlist_add_uint64(asru, FM_FMRI_MEM_PHYSADDR, pa);
- if (incl_offset)
- err |= nvlist_add_uint64(asru, FM_FMRI_MEM_OFFSET, offset);
- topo_mod_strfree(mod, cstr);
- if (err != 0) {
- nvlist_free(asru);
- return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
- }
-
- *out = asru;
-
- return (0);
-}
diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_protocol.c b/usr/src/lib/fm/topo/libtopo/common/topo_protocol.c
index 81ae45e3ca..85ced6fa43 100644
--- a/usr/src/lib/fm/topo/libtopo/common/topo_protocol.c
+++ b/usr/src/lib/fm/topo/libtopo/common/topo_protocol.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -39,35 +38,41 @@
#include <libtopo.h>
static int
-topo_asru_compute(topo_hdl_t *thp, const char *scheme, nvlist_t *rsrc,
- nvlist_t **asru)
+topo_compute(tnode_t *node, nvlist_t *stub, const char *method,
+ topo_version_t version, nvlist_t *rsrc, nvlist_t **asru, int *err)
{
- int err;
+ int rc;
+ char *scheme;
+ topo_hdl_t *thp = node->tn_hdl;
tnode_t *rnode;
- if ((rnode = topo_hdl_root(thp, scheme)) == NULL)
- return (ETOPO_METHOD_NOTSUP);
-
- if (topo_method_invoke(rnode, TOPO_METH_ASRU_COMPUTE,
- TOPO_METH_ASRU_COMPUTE_VERSION, rsrc, asru, &err) != 0)
- return (err);
+ /*
+ * First try the originating enumerator for
+ * a compute method. If none is supported, try the
+ * node's scheme-specific enumerator.
+ */
+ if (topo_method_invoke(node, method, version, rsrc, asru, err) == 0)
+ return (0);
- return (0);
-}
+ if (*err != ETOPO_METHOD_NOTSUP)
+ return (-1);
-static int
-topo_fru_compute(topo_hdl_t *thp, const char *scheme, nvlist_t *rsrc,
- nvlist_t **fru)
-{
- int err;
- tnode_t *rnode;
+ if ((rc = nvlist_lookup_string(stub, FM_FMRI_SCHEME, &scheme)) != 0) {
+ if (rc == ENOENT) {
+ *err = ETOPO_FMRI_MALFORM;
+ } else {
+ *err = ETOPO_FMRI_NVL;
+ }
+ return (-1);
+ }
- if ((rnode = topo_hdl_root(thp, scheme)) == NULL)
- return (ETOPO_METHOD_NOTSUP);
+ if ((rnode = topo_hdl_root(thp, scheme)) == NULL) {
+ *err = ETOPO_METHOD_NOTSUP;
+ return (-1);
+ }
- if (topo_method_invoke(rnode, TOPO_METH_FRU_COMPUTE,
- TOPO_METH_FRU_COMPUTE_VERSION, rsrc, fru, &err) != 0)
- return (err);
+ if (topo_method_invoke(rnode, method, version, rsrc, asru, err) != 0)
+ return (-1);
return (0);
}
@@ -77,35 +82,20 @@ topo_node_asru(tnode_t *node, nvlist_t **asru, nvlist_t *priv, int *err)
{
int rc;
nvlist_t *ap;
- char *scheme;
if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_ASRU, &ap,
err) != 0)
return (-1);
if (node->tn_fflags & TOPO_ASRU_COMPUTE) {
- if ((rc = nvlist_lookup_string(ap, FM_FMRI_SCHEME, &scheme))
- != 0) {
- if (rc == ENOENT)
- *err = ETOPO_FMRI_MALFORM;
- else
- *err = ETOPO_FMRI_NVL;
- nvlist_free(ap);
- return (-1);
- }
- if ((rc = topo_asru_compute(node->tn_hdl, scheme, priv, asru))
- != 0) {
- nvlist_free(ap);
- *err = rc;
- return (-1);
- }
+ rc = topo_compute(node, ap, TOPO_METH_ASRU_COMPUTE,
+ TOPO_METH_ASRU_COMPUTE_VERSION, priv, asru, err);
nvlist_free(ap);
- return (0);
+ return (rc);
} else {
*asru = ap;
+ return (0);
}
-
- return (0);
}
int
@@ -113,36 +103,20 @@ topo_node_fru(tnode_t *node, nvlist_t **fru, nvlist_t *priv, int *err)
{
int rc;
nvlist_t *fp;
- char *scheme;
if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_FRU, &fp,
err) != 0)
return (-1);
if (node->tn_fflags & TOPO_FRU_COMPUTE) {
- if ((rc = nvlist_lookup_string(fp, FM_FMRI_SCHEME, &scheme))
- != 0) {
- if (rc == ENOENT)
- *err = ETOPO_FMRI_MALFORM;
- else
- *err = ETOPO_FMRI_NVL;
-
- nvlist_free(fp);
- return (-1);
- }
- if ((rc = topo_fru_compute(node->tn_hdl, scheme, priv, fru))
- != 0) {
- nvlist_free(fp);
- *err = rc;
- return (-1);
- }
+ rc = topo_compute(node, fp, TOPO_METH_FRU_COMPUTE,
+ TOPO_METH_FRU_COMPUTE_VERSION, priv, fru, err);
nvlist_free(fp);
- return (0);
+ return (rc);
} else {
*fru = fp;
+ return (0);
}
-
- return (0);
}
int
@@ -220,7 +194,6 @@ topo_node_fru_set(tnode_t *node, nvlist_t *fru, int flag, int *err)
int
topo_node_label_set(tnode_t *node, char *label, int *err)
{
-
/*
* Inherit FRU property from our parent if * not specified
*/
diff --git a/usr/src/lib/fm/topo/modules/i86pc/chip/chip.c b/usr/src/lib/fm/topo/modules/i86pc/chip/chip.c
index 869abce891..9563120b61 100644
--- a/usr/src/lib/fm/topo/modules/i86pc/chip/chip.c
+++ b/usr/src/lib/fm/topo/modules/i86pc/chip/chip.c
@@ -29,6 +29,7 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <string.h>
#include <strings.h>
#include <limits.h>
@@ -44,6 +45,7 @@
#include <sys/fm/protocol.h>
#include <sys/systeminfo.h>
#include <sys/mc.h>
+#include <sys/mc_amd.h>
#include <fm/topo_mod.h>
#include "chip.h"
@@ -64,22 +66,74 @@
static int chip_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t,
topo_instance_t, void *);
+static int mem_asru_compute(topo_mod_t *, tnode_t *, topo_version_t,
+ nvlist_t *, nvlist_t **);
+
const topo_modinfo_t chip_info =
{ "chip", CHIP_VERSION, chip_enum, NULL};
+const topo_method_t rank_methods[] = {
+ { TOPO_METH_ASRU_COMPUTE, TOPO_METH_ASRU_COMPUTE_DESC,
+ TOPO_METH_ASRU_COMPUTE_VERSION, TOPO_STABILITY_INTERNAL,
+ mem_asru_compute },
+ { NULL }
+};
+
+static const struct debugopt {
+ const char *optname;
+ int optval;
+} debugopts[] = {
+ { "err", TOPO_DBG_ERR },
+ { "mod", TOPO_DBG_MOD },
+ { "log", TOPO_DBG_LOG },
+ { "walk", TOPO_DBG_WALK },
+ { "tree", TOPO_DBG_TREE },
+ { "all", TOPO_DBG_ALL }
+};
+
+static nvlist_t *cs_fmri[MC_CHIP_NCS];
+
+static void
+whinge(topo_mod_t *mod, int *nerr, const char *fmt, ...)
+{
+ va_list ap;
+ char buf[160];
+
+ if (nerr != NULL)
+ ++*nerr;
+
+ va_start(ap, fmt);
+ (void) vsnprintf(buf, sizeof (buf), fmt, ap);
+ va_end(ap);
+
+ topo_mod_dprintf(mod, "%s", buf);
+}
+
int
_topo_init(topo_mod_t *mod)
{
+ const char *debugstr = getenv("TOPOCHPDBG");
chip_t *chip;
+ int i;
+
+ if (debugstr != NULL) {
+ for (i = 0; i < sizeof (debugopts) / sizeof (struct debugopt);
+ i++) {
+ if (strncmp(debugstr, debugopts[i].optname, 4) == 0) {
+ topo_mod_clrdebug(mod);
+ topo_mod_setdebug(mod, debugopts[i].optval);
+ break; /* handle a single option only */
+ }
+ }
+ }
- topo_mod_setdebug(mod, TOPO_DBG_ALL);
topo_mod_dprintf(mod, "initializing chip enumerator\n");
if ((chip = topo_mod_zalloc(mod, sizeof (chip_t))) == NULL)
return (topo_mod_seterrno(mod, EMOD_NOMEM));
if ((chip->chip_kc = kstat_open()) == NULL) {
- topo_mod_dprintf(mod, "kstat_open failed: %s\n",
+ whinge(mod, NULL, "kstat_open failed: %s\n",
strerror(errno));
topo_mod_free(mod, chip, sizeof (chip_t));
return (topo_mod_seterrno(mod, errno));
@@ -94,7 +148,7 @@ _topo_init(topo_mod_t *mod)
}
if (topo_mod_register(mod, &chip_info, (void *)chip) != 0) {
- topo_mod_dprintf(mod, "failed to register hc: "
+ whinge(mod, NULL, "failed to register hc: "
"%s\n", topo_mod_errmsg(mod));
topo_mod_free(mod, chip->chip_cpustats,
(chip->chip_ncpustats + 1) * sizeof (kstat_t *));
@@ -151,6 +205,29 @@ chip_longprop(tnode_t *cnode, kstat_t *ksp, const char *name)
return (-1);
}
+static int
+mkrsrc(topo_mod_t *mod, tnode_t *pnode, const char *name, int inst,
+ nvlist_t **nvl)
+{
+ nvlist_t *args = NULL, *pfmri = NULL;
+ topo_hdl_t *thp = topo_mod_handle(mod);
+ int err;
+
+ if (topo_node_resource(pnode, &pfmri, &err) < 0 ||
+ topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0 ||
+ nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_PARENT, pfmri) != 0) {
+ nvlist_free(pfmri);
+ nvlist_free(args);
+ return (-1);
+ }
+
+ *nvl = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, name, inst, args, &err);
+ nvlist_free(pfmri);
+ nvlist_free(args);
+
+ return (nvl != NULL ? 0 : -1); /* caller must free nvlist */
+}
+
static nvlist_t *
cpu_fmri_create(topo_mod_t *mod, uint32_t cpuid, char *s, uint8_t cpumask)
{
@@ -175,86 +252,110 @@ cpu_fmri_create(topo_mod_t *mod, uint32_t cpuid, char *s, uint8_t cpumask)
return (asru);
}
+static nvlist_t *
+mem_fmri_create(topo_mod_t *mod)
+{
+ nvlist_t *asru;
+
+ if (topo_mod_nvalloc(mod, &asru, NV_UNIQUE_NAME) != 0)
+ return (NULL);
+
+ if (nvlist_add_string(asru, FM_FMRI_SCHEME, FM_FMRI_SCHEME_MEM) != 0 ||
+ nvlist_add_uint8(asru, FM_VERSION, FM_MEM_SCHEME_VERSION) != 0) {
+ nvlist_free(asru);
+ return (NULL);
+ }
+
+ return (asru);
+}
+
static int
cpu_create(topo_mod_t *mod, tnode_t *pnode, const char *name, int chipid,
chip_t *chip)
{
kstat_named_t *k;
- topo_hdl_t *thp;
- nvlist_t *fmri, *pfmri, *asru, *args;
+ nvlist_t *fmri, *asru;
tnode_t *cnode;
int i, err, nerr = 0;
+ int coreid, cpuid;
if (topo_node_range_create(mod, pnode, name, 0,
chip->chip_ncpustats) < 0)
return (-1);
- thp = topo_mod_handle(mod);
-
for (i = 0; i <= chip->chip_ncpustats; i++) {
-
if (chip->chip_cpustats[i] == NULL)
continue;
+ /*
+ * The chip_id in the cpu_info kstat numbers the individual
+ * chips from 0 to #chips - 1.
+ */
if ((k = kstat_data_lookup(chip->chip_cpustats[i], "chip_id"))
- == NULL || k->value.l != chipid) {
- ++nerr;
+ == NULL) {
+ whinge(mod, &nerr, "cpu_create: chip_id lookup via "
+ "kstats failed\n");
continue;
}
+ if (k->value.l != chipid)
+ continue; /* not an error */
+
+ /*
+ * The clog_id in the cpu_info kstat numbers the processor
+ * cores of a single chip from 0 to #chips - 1.
+ */
if ((k = kstat_data_lookup(chip->chip_cpustats[i], "clog_id"))
== NULL) {
- ++nerr;
+ whinge(mod, &nerr, "cpu_create: clog_id lookup via "
+ "kstats failed\n");
continue;
}
+ coreid = k->value.l;
- args = pfmri = NULL;
- if (topo_node_resource(pnode, &pfmri, &err) < 0 ||
- topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0 ||
- nvlist_add_nvlist(args,
- TOPO_METH_FMRI_ARG_PARENT, pfmri) != 0) {
- nvlist_free(pfmri);
- nvlist_free(args);
- ++nerr;
- continue;
- }
+ if (mkrsrc(mod, pnode, name, coreid, &fmri) != 0) {
+ whinge(mod, &nerr, "cpu_create: mkrsrc failed\n");
+ continue;
+ }
- fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, name,
- (topo_instance_t)k->value.l, args, &err);
- nvlist_free(pfmri);
- nvlist_free(args);
- if (fmri == NULL) {
- ++nerr;
+ /*
+ * The core_id in the cpu_info kstat corresponds to the
+ * processor id used in psradm etc - ie cpuid as used
+ * in a cpu scheme fmri. I'm not making this up!
+ */
+ if ((k = kstat_data_lookup(chip->chip_cpustats[i], "core_id"))
+ == NULL) {
+ whinge(mod, &nerr, "cpu_create: core_id lookup via "
+ "kstats failed\n");
continue;
}
+ cpuid = k->value.l;
- if ((cnode = topo_node_bind(mod, pnode, name, i, fmri,
+ if ((cnode = topo_node_bind(mod, pnode, name, cpuid, fmri,
NULL)) == NULL) {
- ++nerr;
+ whinge(mod, &nerr, "cpu_create: node bind failed\n");
nvlist_free(fmri);
continue;
}
nvlist_free(fmri);
- if ((asru = cpu_fmri_create(mod, i, NULL, 0)) != NULL) {
+ if ((asru = cpu_fmri_create(mod, cpuid, NULL, 0)) != NULL) {
(void) topo_node_asru_set(cnode, asru, 0, &err);
nvlist_free(asru);
} else {
- ++nerr;
+ whinge(mod, &nerr, "cpu_create: cpu_fmri_create "
+ "failed\n");
}
(void) topo_node_fru_set(cnode, NULL, 0, &err);
}
- if (nerr != 0)
- return (-1);
- else
- return (0);
+ return (nerr == 0 ? 0 : -1);
}
static int
-nvprop_add(nvpair_t *nvp, const char *pgname, tnode_t *node)
+nvprop_add(topo_mod_t *mod, nvpair_t *nvp, const char *pgname, tnode_t *node)
{
- int err;
+ int err = 0;
char *pname = nvpair_name(nvp);
switch (nvpair_type(nvp)) {
@@ -288,25 +389,66 @@ nvprop_add(nvpair_t *nvp, const char *pgname, tnode_t *node)
}
default:
- return (-1);
+ whinge(mod, &err, "nvprop_add: Can't handle type %d for "
+ "'%s' in property group %s of %s node\n",
+ nvpair_type(nvp), pname, pgname, topo_node_name(node));
+ return (1);
}
}
-nvlist_t *
-mem_fmri_create(topo_mod_t *mod)
+static int
+dramchan_create(topo_mod_t *mod, tnode_t *pnode, const char *name)
{
- nvlist_t *asru;
+ tnode_t *chnode;
+ nvlist_t *fmri;
+ char *socket;
+ int i, nchan;
+ int err, nerr = 0;
- if (topo_mod_nvalloc(mod, &asru, NV_UNIQUE_NAME) != 0)
- return (NULL);
+ /*
+ * 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, MCT_PGROUP, "socket",
+ &socket, &err) != 0)
+ return (-1);
- if (nvlist_add_string(asru, FM_FMRI_SCHEME, FM_FMRI_SCHEME_MEM) != 0 ||
- nvlist_add_uint8(asru, FM_VERSION, FM_MEM_SCHEME_VERSION) != 0) {
- nvlist_free(asru);
- return (NULL);
+ if (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);
+
+ for (i = 0; i < nchan; i++) {
+ if (mkrsrc(mod, pnode, name, i, &fmri) != 0) {
+ whinge(mod, &nerr, "dramchan_create: mkrsrc "
+ "failed\n");
+ continue;
+ }
+
+ if ((chnode = topo_node_bind(mod, pnode, name, i, fmri,
+ NULL)) == NULL) {
+ nvlist_free(fmri);
+ whinge(mod, &nerr, "dramchan_create: node bind "
+ "failed\n");
+ continue;
+ }
+
+ nvlist_free(fmri);
+
+ (void) topo_pgroup_create(chnode, CHAN_PGROUP,
+ TOPO_STABILITY_PRIVATE, &err);
+
+ (void) topo_prop_set_string(chnode, CHAN_PGROUP, "channel",
+ TOPO_PROP_SET_ONCE, i == 0 ? "A" : "B", &err);
}
- return (asru);
+ return (nerr == 0 ? 0 : -1);
}
static int
@@ -315,67 +457,218 @@ cs_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc)
int i, err, nerr = 0;
nvpair_t *nvp;
tnode_t *csnode;
- topo_hdl_t *thp;
nvlist_t *fmri, **csarr = NULL;
- nvlist_t *pfmri, *args;
uint64_t csnum;
uint_t ncs;
- if (nvlist_lookup_nvlist_array(mc, "cslist", &csarr, &ncs) != 0 ||
- ncs == 0)
+ 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);
- thp = topo_mod_handle(mod);
for (i = 0; i < ncs; i++) {
if (nvlist_lookup_uint64(csarr[i], "num", &csnum) != 0) {
- ++nerr;
+ whinge(mod, &nerr, "cs_create: cs num property "
+ "missing\n");
continue;
}
- args = pfmri = NULL;
- if (topo_node_resource(pnode, &pfmri, &err) < 0 ||
- topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0 ||
- nvlist_add_nvlist(args,
- TOPO_METH_FMRI_ARG_PARENT, pfmri) != 0) {
- nvlist_free(pfmri);
- nvlist_free(args);
- ++nerr;
- continue;
- }
- fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, name,
- csnum, args, &err);
- nvlist_free(pfmri);
- nvlist_free(args);
- if (fmri == NULL) {
- ++nerr;
+ if (mkrsrc(mod, pnode, name, csnum, &fmri) != 0) {
+ whinge(mod, &nerr, "cs_create: mkrsrc failed\n");
continue;
}
if ((csnode = topo_node_bind(mod, pnode, name, csnum, fmri,
NULL)) == NULL) {
nvlist_free(fmri);
- ++nerr;
+ whinge(mod, &nerr, "cs_create: node bind failed\n");
continue;
}
- nvlist_free(fmri);
+ cs_fmri[csnum] = fmri; /* nvlist will be freed in mc_create */
+
+ (void) topo_node_asru_set(csnode, fmri, 0, &err);
(void) topo_pgroup_create(csnode, CS_PGROUP,
TOPO_STABILITY_PRIVATE, &err);
for (nvp = nvlist_next_nvpair(csarr[i], NULL); nvp != NULL;
nvp = nvlist_next_nvpair(csarr[i], nvp)) {
- (void) nvprop_add(nvp, CS_PGROUP, csnode);
+ nerr += nvprop_add(mod, nvp, CS_PGROUP, csnode);
}
}
- if (nerr != 0)
- return (-1);
- else
- return (0);
+ return (nerr == 0 ? 0 : -1);
+}
+
+/*
+ * Registered method for asru computation for rank nodes. The 'node'
+ * argument identifies the node for which we seek an asru. The 'in'
+ * argument is used to select which asru we will return, as follows:
+ *
+ * - the node name must be "dimm" or "rank"
+ * - if 'in' is NULL then return any statically defined asru for this node
+ * - if 'in' is an "hc" scheme fmri then we construct a "mem" scheme asru
+ * with unum being the hc path to the dimm or rank (this method is called
+ * as part of dynamic asru computation for rank nodes only, but dimm_create
+ * also calls it directly to construct a "mem" scheme asru for a dimm node)
+ * - if 'in' in addition includes an hc-specific member which specifies
+ * asru-physaddr or asru-offset then these are includes in the "mem" scheme
+ * asru as additional membersl physaddr and offset
+ */
+/*ARGSUSED*/
+static int
+mem_asru_compute(topo_mod_t *mod, tnode_t *node, topo_version_t version,
+ nvlist_t *in, nvlist_t **out)
+{
+ int incl_pa = 0, incl_offset = 0;
+ nvlist_t *hcsp, *asru;
+ uint64_t pa, offset;
+ char *scheme, *unum;
+ int err;
+
+ if (strcmp(topo_node_name(node), RANK_NODE_NAME) != 0 &&
+ strcmp(topo_node_name(node), DIMM_NODE_NAME) != 0)
+ return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
+
+ if (in == NULL) {
+ if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL,
+ TOPO_PROP_ASRU, out, &err) == 0)
+ return (0);
+ else
+ return (topo_mod_seterrno(mod, err));
+ } else {
+ if (nvlist_lookup_string(in, FM_FMRI_SCHEME, &scheme) != 0 ||
+ strcmp(scheme, FM_FMRI_SCHEME_HC) != 0)
+ return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
+ }
+
+ if (nvlist_lookup_nvlist(in, FM_FMRI_HC_SPECIFIC, &hcsp) == 0) {
+ if (nvlist_lookup_uint64(hcsp, "asru-"FM_FMRI_MEM_PHYSADDR,
+ &pa) == 0)
+ incl_pa = 1;
+
+ if (nvlist_lookup_uint64(hcsp, "asru-"FM_FMRI_MEM_OFFSET,
+ &offset) == 0)
+ incl_offset = 1;
+ }
+
+ /* use 'in' to obtain resource path; could use node resource */
+ if (topo_fmri_nvl2str(topo_mod_handle(mod), in, &unum, &err) < 0)
+ return (topo_mod_seterrno(mod, err));
+
+ if ((asru = mem_fmri_create(mod)) == NULL) {
+ topo_mod_strfree(mod, unum);
+ return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
+ }
+
+ err = nvlist_add_string(asru, FM_FMRI_MEM_UNUM, unum);
+ if (incl_pa)
+ err |= nvlist_add_uint64(asru, FM_FMRI_MEM_PHYSADDR, pa);
+ if (incl_offset)
+ err |= nvlist_add_uint64(asru, FM_FMRI_MEM_OFFSET, offset);
+
+ topo_mod_strfree(mod, unum);
+ if (err != 0) {
+ nvlist_free(asru);
+ return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
+ }
+
+ *out = asru;
+ return (0);
+}
+
+static int
+rank_create(topo_mod_t *mod, tnode_t *pnode, nvlist_t *dimmnvl)
+{
+ 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, "rank_create: "
+ "csnums/csnames extraction failed\n");
+ return (nerr);
+ }
+
+ if (topo_node_resource(pnode, &pfmri, &err) < 0) {
+ whinge(mod, &nerr, "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, "rank_create: range create failed\n");
+ nvlist_free(pfmri);
+ return (nerr);
+ }
+
+ if (topo_prop_get_uint64(pnode, DIMM_PGROUP, "size", &dsz, &err) == 0) {
+ rsz = dsz / ncs;
+ } else {
+ whinge(mod, &nerr, "rank_create: parent dimm has no size\n");
+ return (nerr);
+ }
+
+ for (i = 0; i < ncs; i++) {
+ if (mkrsrc(mod, pnode, RANK_NODE_NAME, i, &fmri) < 0) {
+ whinge(mod, &nerr, "rank_create: mkrsrc failed\n");
+ continue;
+ }
+
+ if ((ranknode = topo_node_bind(mod, pnode, RANK_NODE_NAME, i,
+ fmri, NULL)) == NULL) {
+ nvlist_free(fmri);
+ whinge(mod, &nerr, "rank_create: node bind "
+ "failed\n");
+ continue;
+ }
+
+ nvlist_free(fmri);
+
+ (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.
+ */
+ (void) topo_node_asru_set(ranknode, cs_fmri[csnumarr[i]],
+ TOPO_ASRU_COMPUTE, &err);
+
+ if (topo_method_register(mod, ranknode, rank_methods) < 0)
+ whinge(mod, &nerr, "rank_create: "
+ "topo_method_register failed");
+
+ (void) topo_pgroup_create(ranknode, RANK_PGROUP,
+ TOPO_STABILITY_PRIVATE, &err);
+
+ (void) topo_prop_set_uint64(ranknode, RANK_PGROUP, "size",
+ TOPO_PROP_SET_ONCE, rsz, &err);
+
+ (void) topo_prop_set_string(ranknode, RANK_PGROUP, "csname",
+ TOPO_PROP_SET_ONCE, csnamearr[i], &err);
+
+ (void) topo_prop_set_uint64(ranknode, RANK_PGROUP, "csnum",
+ TOPO_PROP_SET_ONCE, csnumarr[i], &err);
+ }
+
+ nvlist_free(pfmri);
+
+ return (nerr);
}
static int
@@ -385,59 +678,61 @@ dimm_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc)
nvpair_t *nvp;
tnode_t *dimmnode;
nvlist_t *fmri, *asru, **dimmarr = NULL;
- nvlist_t *pfmri, *args;
- uint64_t ldimmnum;
+ uint64_t num;
uint_t ndimm;
- topo_hdl_t *thp;
-
- thp = topo_mod_handle(mod);
- if (nvlist_lookup_nvlist_array(mc, "dimmlist", &dimmarr, &ndimm) != 0 ||
- ndimm == 0)
+ if (nvlist_lookup_nvlist_array(mc, "dimmlist", &dimmarr, &ndimm) != 0) {
+ whinge(mod, NULL, "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)
+ if (topo_node_range_create(mod, pnode, name, 0, MAX_DIMMNUM) < 0) {
+ whinge(mod, NULL, "dimm_create: range create failed\n");
return (-1);
+ }
for (i = 0; i < ndimm; i++) {
- if (nvlist_lookup_uint64(dimmarr[i], "num", &ldimmnum) != 0) {
- ++nerr;
+ if (nvlist_lookup_uint64(dimmarr[i], "num", &num) != 0) {
+ whinge(mod, &nerr, "dimm_create: dimm num property "
+ "missing\n");
continue;
}
- args = pfmri = NULL;
- if (topo_node_resource(pnode, &pfmri, &err) < 0 ||
- topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0 ||
- nvlist_add_nvlist(args,
- TOPO_METH_FMRI_ARG_PARENT, pfmri) != 0) {
- nvlist_free(pfmri);
- nvlist_free(args);
- ++nerr;
- continue;
- }
- fmri = topo_fmri_create(thp,
- FM_FMRI_SCHEME_HC, name, ldimmnum, args, &err);
- nvlist_free(pfmri);
- nvlist_free(args);
- if (fmri == NULL) {
- ++nerr;
+ if (mkrsrc(mod, pnode, name, num, &fmri) < 0) {
+ whinge(mod, &nerr, "dimm_create: mkrsrc failed\n");
continue;
}
- if ((dimmnode = topo_node_bind(mod, pnode, name, ldimmnum, fmri,
+ if ((dimmnode = topo_node_bind(mod, pnode, name, num, fmri,
NULL)) == NULL) {
nvlist_free(fmri);
- ++nerr;
+ whinge(mod, &nerr, "dimm_create: node bind "
+ "failed\n");
continue;
}
- (void) topo_node_fru_set(dimmnode, fmri, 0, &err);
- if ((asru = mem_fmri_create(mod)) != NULL) {
- (void) topo_node_asru_set(dimmnode, asru,
- TOPO_ASRU_COMPUTE, &err);
+ /*
+ * The asru is static but we prefer to publish it in the
+ * "mem" scheme so call the compute method directly to
+ * perform the conversion.
+ */
+ if (mem_asru_compute(mod, dimmnode,
+ TOPO_METH_ASRU_COMPUTE_VERSION, fmri, &asru) == 0) {
+ (void) topo_node_asru_set(dimmnode, asru, 0, &err);
nvlist_free(asru);
+ } else {
+
+ nvlist_free(fmri);
+ whinge(mod, &nerr, "dimm_create: mem_asru_compute "
+ "failed\n");
+ continue;
}
+ (void) topo_node_fru_set(dimmnode, fmri, 0, &err);
+
nvlist_free(fmri);
(void) topo_pgroup_create(dimmnode, DIMM_PGROUP,
@@ -445,35 +740,19 @@ dimm_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc)
for (nvp = nvlist_next_nvpair(dimmarr[i], NULL); nvp != NULL;
nvp = nvlist_next_nvpair(dimmarr[i], nvp)) {
- if (nvprop_add(nvp, DIMM_PGROUP, dimmnode) == 0) {
- continue;
- } else if (nvpair_type(nvp) == DATA_TYPE_UINT64_ARRAY) {
- uint64_t *csnumarr;
- uint_t ncs;
- int i;
-
- if (strcmp(nvpair_name(nvp), "csnums") != 0 ||
- nvpair_value_uint64_array(nvp, &csnumarr,
- &ncs) != 0)
- continue;
-
- for (i = 0; i < ncs; i++) {
- char name[7];
- (void) snprintf(name, sizeof (name),
- "csnum%d", i);
- (void) topo_prop_set_uint64(dimmnode,
- DIMM_PGROUP, name,
- TOPO_PROP_SET_ONCE,
- csnumarr[i], &err);
- }
- }
+ 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 rank_create() */
+
+ nerr += nvprop_add(mod, nvp, DIMM_PGROUP, dimmnode);
}
+
+ nerr += rank_create(mod, dimmnode, dimmarr[i]);
}
- if (nerr != 0)
- return (-1);
- else
- return (0);
+ return (nerr == 0 ? 0 : -1);
}
static nvlist_t *
@@ -481,6 +760,7 @@ mc_lookup_by_mcid(topo_mod_t *mod, topo_instance_t id)
{
mc_snapshot_info_t mcs;
void *buf = NULL;
+ uint8_t ver;
nvlist_t *nvl;
char path[64];
@@ -490,7 +770,19 @@ mc_lookup_by_mcid(topo_mod_t *mod, topo_instance_t id)
fd = open(path, O_RDONLY);
if (fd == -1) {
- topo_mod_dprintf(mod, "mc failed to open %s: %s\n",
+ /*
+ * Some v20z and v40z systems may have had the 3rd-party
+ * NWSnps packagae installed which installs a /dev/mc
+ * link. So try again via /devices.
+ */
+ (void) snprintf(path, sizeof (path),
+ "/devices/pci@0,0/pci1022,1102@%x,2:mc-amd",
+ MC_AMD_DEV_OFFSET + id);
+ fd = open(path, O_RDONLY);
+ }
+
+ if (fd == -1) {
+ whinge(mod, NULL, "mc failed to open %s: %s\n",
path, strerror(errno));
return (NULL);
}
@@ -499,7 +791,7 @@ mc_lookup_by_mcid(topo_mod_t *mod, topo_instance_t id)
(buf = topo_mod_alloc(mod, mcs.mcs_size)) == NULL ||
ioctl(fd, MC_IOC_SNAPSHOT, buf) == -1) {
- topo_mod_dprintf(mod, "mc failed to snapshot %s: %s\n",
+ whinge(mod, NULL, "mc failed to snapshot %s: %s\n",
path, strerror(errno));
free(buf);
@@ -510,6 +802,17 @@ mc_lookup_by_mcid(topo_mod_t *mod, topo_instance_t id)
(void) close(fd);
err = nvlist_unpack(buf, mcs.mcs_size, &nvl, 0);
topo_mod_free(mod, buf, mcs.mcs_size);
+
+ if (nvlist_lookup_uint8(nvl, MC_NVLIST_VERSTR, &ver) != 0) {
+ whinge(mod, NULL, "mc nvlist is not versioned\n");
+ nvlist_free(nvl);
+ return (NULL);
+ } else if (ver != MC_NVLIST_VERS1) {
+ whinge(mod, NULL, "mc nvlist version mismatch\n");
+ nvlist_free(nvl);
+ return (NULL);
+ }
+
return (err ? NULL : nvl);
}
@@ -521,26 +824,16 @@ mc_create(topo_mod_t *mod, tnode_t *pnode, const char *name)
nvlist_t *fmri;
nvpair_t *nvp;
nvlist_t *mc = NULL;
- nvlist_t *pfmri, *args;
- topo_hdl_t *thp;
+ int i;
- thp = topo_mod_handle(mod);
- args = pfmri = NULL;
- if (topo_node_resource(pnode, &pfmri, &err) < 0 ||
- topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0 ||
- nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_PARENT, pfmri) != 0) {
- nvlist_free(pfmri);
- nvlist_free(args);
+ if (mkrsrc(mod, pnode, name, 0, &fmri) != 0) {
+ whinge(mod, NULL, "mc_create: mkrsrc failed\n");
return (-1);
}
- fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, name, 0, args, &err);
- nvlist_free(pfmri);
- nvlist_free(args);
- if (fmri == NULL)
- return (-1);
if (topo_node_range_create(mod, pnode, name, 0, 0) < 0) {
nvlist_free(fmri);
+ whinge(mod, NULL, "mc_create: node range create failed\n");
return (-1);
}
@@ -554,6 +847,7 @@ mc_create(topo_mod_t *mod, tnode_t *pnode, const char *name)
nvlist_free(mc);
topo_node_range_destroy(pnode, name);
nvlist_free(fmri);
+ whinge(mod, NULL, "mc_create: mc lookup or bind failed\n");
return (-1);
}
@@ -563,21 +857,39 @@ mc_create(topo_mod_t *mod, tnode_t *pnode, const char *name)
/*
* Add memory controller properties
*/
- (void) topo_pgroup_create(mcnode, MC_PGROUP,
+ (void) topo_pgroup_create(mcnode, MCT_PGROUP,
TOPO_STABILITY_PRIVATE, &err);
for (nvp = nvlist_next_nvpair(mc, NULL); nvp != NULL;
nvp = nvlist_next_nvpair(mc, nvp)) {
- if (nvprop_add(nvp, MC_PGROUP, mcnode) == 0)
+ if (nvpair_type(nvp) == DATA_TYPE_NVLIST_ARRAY &&
+ (strcmp(nvpair_name(nvp), "cslist") == 0 ||
+ strcmp(nvpair_name(nvp), "dimmlist") == 0)) {
continue;
- else if (nvpair_type(nvp) == DATA_TYPE_NVLIST_ARRAY)
- break;
+ } else if (nvpair_type(nvp) == DATA_TYPE_UINT8 &&
+ strcmp(nvpair_name(nvp), MC_NVLIST_VERSTR) == 0) {
+ continue;
+ } else {
+ if (nvprop_add(mod, nvp, MCT_PGROUP, mcnode) != 0)
+ rc = -1;
+ }
}
- if (dimm_create(mod, mcnode, DIMM_NODE_NAME, mc) != 0 ||
- cs_create(mod, mcnode, CS_NODE_NAME, mc) != 0)
+ if (dramchan_create(mod, mcnode, CHAN_NODE_NAME) != 0 ||
+ cs_create(mod, mcnode, CS_NODE_NAME, mc) != 0 ||
+ dimm_create(mod, mcnode, DIMM_NODE_NAME, mc) != 0)
rc = -1;
+ /*
+ * Free the fmris for the chip-selects allocated in 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);
return (rc);
}
@@ -590,12 +902,9 @@ chip_create(topo_mod_t *mod, tnode_t *pnode, const char *name,
kstat_t *ksp;
ulong_t *chipmap;
tnode_t *cnode;
- nvlist_t *pfmri, *fmri, *args;
- topo_hdl_t *thp;
-
- thp = topo_mod_handle(mod);
+ nvlist_t *fmri;
- if ((chipmap = topo_mod_zalloc(mod, BT_BITOUL(chip->chip_ncpustats) *
+ if ((chipmap = topo_mod_zalloc(mod, BT_BITOUL(max) *
sizeof (ulong_t))) == NULL)
return (topo_mod_seterrno(mod, EMOD_NOMEM));
@@ -619,7 +928,8 @@ chip_create(topo_mod_t *mod, tnode_t *pnode, const char *name,
continue;
if ((k = kstat_data_lookup(ksp, "chip_id")) == NULL) {
- ++nerr;
+ whinge(mod, &nerr, "chip_create: chip_id lookup "
+ "via kstats failed\n");
continue;
}
@@ -630,31 +940,19 @@ chip_create(topo_mod_t *mod, tnode_t *pnode, const char *name,
if (chipid < min || chipid > max)
continue;
- args = pfmri = NULL;
- if (topo_node_resource(pnode, &pfmri, &err) < 0 ||
- topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0 ||
- nvlist_add_nvlist(args,
- TOPO_METH_FMRI_ARG_PARENT, pfmri) != 0) {
- nvlist_free(pfmri);
- nvlist_free(args);
- ++nerr;
- continue;
- }
- fmri = topo_fmri_create(thp,
- FM_FMRI_SCHEME_HC, name, chipid, args, &err);
- nvlist_free(pfmri);
- nvlist_free(args);
- if (fmri == NULL) {
- ++nerr;
+ if (mkrsrc(mod, pnode, name, chipid, &fmri) != 0) {
+ whinge(mod, &nerr, "chip_create: mkrsrc failed\n");
continue;
}
if ((cnode = topo_node_bind(mod, pnode, name, chipid, fmri,
NULL)) == NULL) {
- ++nerr;
nvlist_free(fmri);
+ whinge(mod, &nerr, "chip_create: node bind "
+ "failed for chipid %d\n", chipid);
continue;
}
+ BT_SET(chipmap, chipid);
(void) topo_node_fru_set(cnode, fmri, 0, &err);
@@ -667,18 +965,19 @@ chip_create(topo_mod_t *mod, tnode_t *pnode, const char *name,
(void) chip_longprop(cnode, ksp, CHIP_MODEL);
(void) chip_longprop(cnode, ksp, CHIP_STEPPING);
- if (mc_create(mod, cnode, MC_NODE_NAME) != 0 ||
- cpu_create(mod, cnode, CPU_NODE_NAME, chipid, chip) != 0)
- ++nerr;
+ if (cpu_create(mod, cnode, CPU_NODE_NAME, chipid, chip) != 0 ||
+ mc_create(mod, cnode, MCT_NODE_NAME) != 0)
+ nerr++; /* have whinged elsewhere */
}
- topo_mod_free(mod, chipmap, BT_BITOUL(chip->chip_ncpustats) *
- sizeof (ulong_t));
+ topo_mod_free(mod, chipmap, BT_BITOUL(max) * sizeof (ulong_t));
- if (nerr != 0)
+ if (nerr == 0) {
+ return (0);
+ } else {
(void) topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM);
-
- return (0);
+ return (-1);
+ }
}
static int
diff --git a/usr/src/lib/fm/topo/modules/i86pc/chip/chip.h b/usr/src/lib/fm/topo/modules/i86pc/chip/chip.h
index 269dfa4f37..d1ff5ca3b4 100644
--- a/usr/src/lib/fm/topo/modules/i86pc/chip/chip.h
+++ b/usr/src/lib/fm/topo/modules/i86pc/chip/chip.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -39,15 +38,19 @@ extern "C" {
#define CHIP_VERSION TOPO_VERSION
-#define MC_NODE_NAME "memory-controller"
+#define MCT_NODE_NAME "memory-controller"
+#define CHAN_NODE_NAME "dram-channel"
#define CPU_NODE_NAME "cpu"
#define CS_NODE_NAME "chip-select"
#define DIMM_NODE_NAME "dimm"
+#define RANK_NODE_NAME "rank"
#define CHIP_PGROUP "chip-properties"
-#define CS_PGROUP "chip-select-properties"
-#define MC_PGROUP "memory-contoller-properties"
-#define DIMM_PGROUP "dimm-properties"
+#define MCT_PGROUP MCT_NODE_NAME "-properties"
+#define CHAN_PGROUP CHAN_NODE_NAME "-properties"
+#define CS_PGROUP CS_NODE_NAME "-properties"
+#define DIMM_PGROUP DIMM_NODE_NAME "-properties"
+#define RANK_PGROUP RANK_NODE_NAME "-properties"
/*
* CHIP_PGROUP properties