Esempio n. 1
0
/*
 * Fetch the Facility Node properties (name, type) from the FMRI
 * for this node, or return -1 if we can't.
 */
static int
get_facility_props(topo_hdl_t *hdl, tnode_t *node, char **facname,
    char **factype)
{
	int e, ret = -1;
	nvlist_t *fmri = NULL, *fnvl;
	char *nn = NULL, *tt = NULL;

	if (topo_node_resource(node, &fmri, &e) != 0)
		goto out;

	if (nvlist_lookup_nvlist(fmri, FM_FMRI_FACILITY, &fnvl) != 0)
		goto out;

	if (nvlist_lookup_string(fnvl, FM_FMRI_FACILITY_NAME, &nn) != 0)
		goto out;

	if (nvlist_lookup_string(fnvl, FM_FMRI_FACILITY_TYPE, &tt) != 0)
		goto out;

	*facname = topo_hdl_strdup(hdl, nn);
	*factype = topo_hdl_strdup(hdl, tt);
	ret = 0;

out:
	nvlist_free(fmri);
	return (ret);
}
Esempio n. 2
0
/*
 * Look up the FMRI corresponding to the node in the global
 * hash table and return the pointer stored (if any).  Save the
 * FMRI string in *str if str is non-NULL.
 */
static void *
fmri2ptr(topo_hdl_t *thp, tnode_t *node, char **str, int *err)
{
	nvlist_t	*fmri = NULL;
	char		*cstr = NULL;
	uint64_t	u64val;
	void		*p = NULL;

	if (topo_node_resource(node, &fmri, err) != 0)
		return (NULL);

	if (topo_fmri_nvl2str(thp, fmri, &cstr, err) != 0) {
		nvlist_free(fmri);
		return (NULL);
	}

	if (nvlist_lookup_uint64(g_topo2diskmon, cstr, &u64val) == 0) {

		p = (void *)(uintptr_t)u64val;
	}

	nvlist_free(fmri);
	if (str != NULL)
		*str = dstrdup(cstr);
	topo_hdl_strfree(thp, cstr);
	return (p);
}
Esempio n. 3
0
/* ARGSUSED */
static int
find_mb(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	int err;
	nvlist_t *rsrc, **hcl;
	char *name;
	uint_t n;

	if (topo_node_resource(node, &rsrc, &err) < 0) {
		return (TOPO_WALK_NEXT);	/* no resource, try next */
	}

	if (nvlist_lookup_nvlist_array(rsrc, FM_FMRI_HC_LIST, &hcl, &n) < 0) {
		nvlist_free(rsrc);
		return (TOPO_WALK_NEXT);
	}

	if (nvlist_lookup_string(hcl[0], FM_FMRI_HC_NAME, &name) != 0) {
		nvlist_free(rsrc);
		return (TOPO_WALK_NEXT);
	}

	if (strcmp(name, "motherboard") != 0) {
		nvlist_free(rsrc);
		return (TOPO_WALK_NEXT); /* not MB hc list, try next */
	}

	(void) nvlist_dup(rsrc, &mb_nvl, NV_UNIQUE_NAME);

	nvlist_free(rsrc);
	return (TOPO_WALK_TERMINATE);	/* if no space, give up */
}
Esempio n. 4
0
/*ARGSUSED*/
static tnode_t *
mb_declare(tnode_t *parent, const char *name, topo_instance_t i,
	void *priv, topo_mod_t *mp)
{
	tnode_t *ntn;
	nvlist_t *fmri;
	char *label = "MB";
	int err;

	if ((ntn = mb_tnode_create(mp, parent, name, 0, NULL)) == NULL)
		return (NULL);

	/* Set FRU */
	if (topo_node_resource(ntn, &fmri, &err) < 0) {
		(void) topo_mod_seterrno(mp, err);
		topo_node_unbind(ntn);
		return (NULL);
	}
	if (topo_node_fru_set(ntn, fmri, 0, &err) < 0)
		(void) topo_mod_seterrno(mp, err);
	nvlist_free(fmri);

	/* Label is MB */
	if (topo_prop_set_string(ntn, TOPO_PGROUP_PROTOCOL,
	    TOPO_PROP_LABEL,  TOPO_PROP_IMMUTABLE, label, &err) < 0) {
		(void) topo_mod_seterrno(mp, err);
	}

	return (ntn);
}
Esempio n. 5
0
/*ARGSUSED*/
static int
branch_dimm_cb(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	char *lbl, *p, *q;
	char cx[BUF_SIZE], cy[BUF_SIZE];
	nvlist_t *rsrc;
	int err;
	cmd_branch_t *branch = (cmd_branch_t *)arg;
	cmd_dimm_t *dimm;
	size_t nserids;
	char **serids;

	if (topo_node_resource(node, &rsrc, &err) < 0)
		return (TOPO_WALK_NEXT);	/* no label, try next */

	if ((nvlist_lookup_string(rsrc, FM_FMRI_MEM_UNUM, &lbl) != 0) ||
	    (nvlist_lookup_string_array(rsrc, FM_FMRI_MEM_SERIAL_ID,
	    &serids, &nserids) != 0)) {
		nvlist_free(rsrc);
		return (TOPO_WALK_NEXT);
	}

	/*
	 * Massage the unum of the candidate DIMM as follows:
	 * a) remove any trailing J number.  Use result for cmd_dimm_t.
	 * b) for branch membership purposes only, remove reference to
	 * a riser card (MR%d) if one exists.
	 */
	if ((p = strstr(lbl, "/J")) != NULL) {
		(void) strncpy(cx, lbl, p - lbl);
		cx[p - lbl] = '\0';
	} else {
		(void) strcpy(cx, lbl);
	}
	(void) strcpy(cy, cx);
	if ((p = strstr(cy, "/MR")) != NULL) {
		if ((q = strchr(p + 1, '/')) != NULL)
			(void) strcpy(p, q);
		else
			*p = '\0';
	}

	/*
	 * For benefit of Batoka-like platforms, start comparison with
	 * "CMP", so that any leading "MEM" or "CPU" makes no difference.
	 */

	p = strstr(branch->branch_unum, "CMP");
	q = strstr(cy, "CMP");

	if ((p != NULL) && (q != NULL) && strncmp(p, q, strlen(p)) == 0) {
		dimm = branch_dimm_create(br_hdl, cx, serids, nserids);
		if (dimm != NULL)
			cmd_branch_add_dimm(br_hdl, branch, dimm);
	}
	nvlist_free(rsrc);
	return (TOPO_WALK_NEXT);
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
int
pi_enum_mem(topo_mod_t *mod, md_t *mdp, mde_cookie_t mde_node,
    topo_instance_t inst, tnode_t *t_parent, const char *hc_name,
    tnode_t **t_node)
{
	int		result;
	int		err;
	nvlist_t	*rsrc = NULL;

	*t_node = NULL;

	/*
	 * Create the basic topology node for the DIMM using the generic
	 * enumerator.  The dimm serial is added to the resource so
	 * the retire agent can retire correct page whether the dimm
	 * has been moved or not.
	 */
	result = pi_enum_generic_impl(mod, mdp, mde_node, inst, t_parent,
	    t_parent, hc_name, _ENUM_NAME, t_node, SUN4VPI_ENUM_ADD_SERIAL);
	if (result != 0) {
		/* Error messages are printed by the generic routine */
		return (result);
	}

	/*
	 * Set ASRU compute method, using resource as argument.
	 */
	result = topo_node_resource(*t_node, &rsrc, &err);
	if (result != 0) {
		topo_mod_dprintf(mod,
		    "%s node_0x%llx failed to get resource: %s\n",
		    _ENUM_NAME, (uint64_t)mde_node, topo_strerror(err));
		return (-1);
	}

	/* Set the ASRU on the node with COMPUTE flag */
	result = topo_node_asru_set(*t_node, rsrc, TOPO_ASRU_COMPUTE, &err);
	nvlist_free(rsrc);
	if (result != 0) {
		topo_mod_dprintf(mod,
		    "%s node_0x%llx failed to set ASRU: %s\n", _ENUM_NAME,
		    (uint64_t)mde_node, topo_strerror(err));
		return (-1);
	}

	return (0);
}
Esempio n. 8
0
/*
 * Set the FRU property to the hc fmri of this tnode
 */
int
FRU_fmri_set(topo_mod_t *mp, tnode_t *tn)
{
	nvlist_t *fmri;
	int err, e;

	if (topo_node_resource(tn, &fmri, &err) < 0 ||
	    fmri == NULL) {
		topo_mod_dprintf(mp, "FRU_fmri_set error: %s\n",
		    topo_strerror(topo_mod_errno(mp)));
		return (topo_mod_seterrno(mp, err));
	}
	e = topo_node_fru_set(tn, fmri, 0, &err);
	nvlist_free(fmri);
	if (e < 0)
		return (topo_mod_seterrno(mp, err));
	return (0);
}
Esempio n. 9
0
/*ARGSUSED*/
static int
find_cpu_rsc_by_sn(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	int err;
	nvlist_t *rsc;
	cpuid_t *rscid = (cpuid_t *)arg;
	char *sn, *name, *id;
	nvlist_t **hcl;
	uint_t n;

	if (topo_node_resource(node, &rsc, &err) < 0) {
		return (TOPO_WALK_NEXT);	/* no rsc, try next */
	}

	if (nvlist_lookup_string(rsc, FM_FMRI_HC_SERIAL_ID, &sn) != 0) {
		nvlist_free(rsc);
		return (TOPO_WALK_NEXT);
	}
	if (strcmp(rscid->serial, sn) != 0) {
		nvlist_free(rsc);
		return (TOPO_WALK_NEXT);
	}

	if (nvlist_lookup_nvlist_array(rsc, FM_FMRI_HC_LIST, &hcl, &n) != 0) {
		nvlist_free(rsc);
		return (TOPO_WALK_NEXT);
	}

	if ((nvlist_lookup_string(hcl[n - 1], FM_FMRI_HC_NAME, &name) != 0) ||
	    (nvlist_lookup_string(hcl[n - 1], FM_FMRI_HC_ID, &id) != 0)) {
		nvlist_free(rsc);
		return (TOPO_WALK_NEXT);
	}

	if ((strcmp(name, "cpu") != 0) || (strcmp(rscid->id, id) != 0)) {
		nvlist_free(rsc);
		return (TOPO_WALK_NEXT);
	}

	(void) nvlist_dup(rsc, &rsc_nvl, NV_UNIQUE_NAME);

	nvlist_free(rsc);
	return (TOPO_WALK_TERMINATE);	/* if no space, give up */
}
Esempio n. 10
0
static int
dl_fault_walk_outer(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	disk_lights_t *dl = arg;
	dl_fault_walk_inner_t fwi;
	tnode_t *pnode;
	int err, has_fault;
	nvlist_t *fmri = NULL;

	bzero(&fwi, sizeof (fwi));

	/*
	 * We are only looking for DISK nodes in the topology that have a parent
	 * BAY.
	 */
	if (strcmp(DISK, topo_node_name(node)) != 0 ||
	    (pnode = topo_node_parent(node)) == NULL ||
	    strcmp(BAY, topo_node_name(pnode)) != 0) {
		return (TOPO_WALK_NEXT);
	}

	/*
	 * Check to see if the Resource this FMRI describes is Faulty:
	 */
	if (topo_node_resource(node, &fmri, &err) != 0)
		return (TOPO_WALK_NEXT);
	has_fault = fmd_nvl_fmri_has_fault(dl->dl_fmd, fmri,
	    FMD_HAS_FAULT_RESOURCE, NULL);
	nvlist_free(fmri);

	/*
	 * Walk the children of this BAY and flush out our fault status if
	 * we find an appropriate indicator node.
	 */
	fwi.fwi_name = "fail";
	fwi.fwi_mode = has_fault ? TOPO_LED_STATE_ON : TOPO_LED_STATE_OFF;
	(void) topo_node_child_walk(thp, pnode, dl_fault_walk_inner, &fwi,
	    &err);

	return (TOPO_WALK_NEXT);
}
Esempio n. 11
0
static int
walk_lookup(topo_hdl_t *thp, tnode_t *node, void *pdata)
{
	int rc;
	struct topo_lookup *tlp = (struct topo_lookup *)pdata;
	nvlist_t *r1, *r2 = tlp->tl_resource;

	if (topo_node_resource(node, &r1, &tlp->tl_err) != 0)
		return (TOPO_WALK_ERR);

	rc = topo_fmri_compare(thp, r1, r2, &tlp->tl_err);
	nvlist_free(r1);
	if (rc == 0)
		return (TOPO_WALK_NEXT);
	else if (rc == -1)
		return (TOPO_WALK_ERR);

	tlp->tl_err = tlp->tl_func(thp, node, tlp->tl_pdata);

	return (TOPO_WALK_TERMINATE);
}
Esempio n. 12
0
/*ARGSUSED*/
static int
find_mem_rsc_hc(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	int err;
	nvlist_t *rsc;
	char *sn;

	if (topo_node_resource(node, &rsc, &err) < 0) {
		return (TOPO_WALK_NEXT);	/* no rsc, try next */
	}
	if (nvlist_lookup_string(rsc, FM_FMRI_HC_SERIAL_ID, &sn) != 0) {
		nvlist_free(rsc);
		return (TOPO_WALK_NEXT);
	}
	if (strcmp(sn, (char *)arg) != 0) {
		nvlist_free(rsc);
		return (TOPO_WALK_NEXT);
	}
	(void) nvlist_dup(rsc, &rsc_nvl, NV_UNIQUE_NAME);
	nvlist_free(rsc);
	return (TOPO_WALK_TERMINATE);	/* if no space, give up */
}
Esempio n. 13
0
/*ARGSUSED*/
static int
branch_exist_cb(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	char *lbl, *p, *q;
	char cy[BUF_SIZE];
	nvlist_t *rsrc;
	int err;

	cmd_branch_t *branch = (cmd_branch_t *)arg;

	if (topo_node_resource(node, &rsrc, &err) < 0)
		return (TOPO_WALK_NEXT);	/* no label, try next */

	if (nvlist_lookup_string(rsrc, "unum", &lbl) != 0) {
		nvlist_free(rsrc);
		return (TOPO_WALK_NEXT);
	}
	/*
	 * for branch membership purposes only, remove reference to
	 * a riser card (MR%d) if one exists.
	 */
	(void) strcpy(cy, lbl);
	if ((p = strstr(cy, "/MR")) != NULL) {
		if ((q = strchr(p + 1, '/')) != NULL)
			(void) strcpy(p, q);
		else
			*p = '\0';
	}
	if (strncmp(branch->branch_unum, cy,
	    strlen(branch->branch_unum)) == 0) {
		br_dimmcount++;
		nvlist_free(rsrc);
		return (TOPO_WALK_TERMINATE);
	}
	nvlist_free(rsrc);
	return (TOPO_WALK_NEXT);
}
Esempio n. 14
0
static int
topo_add_disk(topo_hdl_t *thp, tnode_t *node, diskmon_t *target_diskp)
{
	nvlist_t	*fmri = NULL;
	nvlist_t	*asru_fmri;
	nvlist_t	*fru_fmri;
	char		*devpath = NULL;
	char		*capacity = NULL;
	char		*firmrev = NULL;
	char		*serial = NULL;
	char		*manuf = NULL;
	char		*model = NULL;
	char		*cstr = NULL;
	char		*buf;
	char		*label;
	char		*p;
	uint64_t	ptr = 0;
	int		buflen;
	int		err;
	int		orig_cstr_len;
	dm_fru_t	*frup;
	diskmon_t	*diskp;

	/*
	 * Match this node to a disk in the configuration by looking at
	 * our parent's fmri (and do that by getting our FMRI and chopping
	 * off the last part).
	 */
	if (topo_node_resource(node, &fmri, &err) != 0) {
		log_msg(MM_TOPO, "topo_add_disk: Could not generate FMRI for "
		    "node %p!\n", (void *)node);
		return (-1);
	}

	if (topo_fmri_nvl2str(thp, fmri, &cstr, &err) != 0) {
		log_msg(MM_TOPO, "topo_add_disk: Could not create string for "
		    "node %p's FMRI!\n", (void *)node);
		nvlist_free(fmri);
		return (-1);
	}

	nvlist_free(fmri);

	/*
	 * Chop off all but last path (since there's no way to get
	 * the node's parent in the libtopo API).
	 */
	orig_cstr_len = strlen(cstr) + 1;
	p = strrchr(cstr, '/');
	dm_assert(p != NULL);
	*p = 0;
	if (nvlist_lookup_uint64(g_topo2diskmon, cstr, &ptr) != 0) {
		log_msg(MM_TOPO, "No diskmon for parent of node %p.\n", node);
		topo_hdl_free(thp, cstr, orig_cstr_len);
		/* Skip this disk: */
		return (0);
	}

	topo_hdl_free(thp, cstr, orig_cstr_len);

	diskp = (diskmon_t *)(uintptr_t)ptr;

	/* If we were called upon to update a particular disk, do it */
	if (target_diskp != NULL && diskp != target_diskp) {
		return (0);
	}

	/*
	 * Update the diskmon's ASRU and FRU with our information (this
	 * information is cached in the diskmon so we don't have to do a
	 * time-consuming topo traversal when we get an ereport).
	 */
	if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_ASRU,
	    &asru_fmri, &err) == 0) {
		diskmon_add_asru(diskp, asru_fmri);
		nvlist_free(asru_fmri);
	}
	if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_FRU,
	    &fru_fmri, &err) == 0) {
		diskmon_add_fru(diskp, fru_fmri);
		nvlist_free(fru_fmri);
	}
	if (topo_node_resource(node, &fmri, &err) == 0) {
		diskmon_add_disk_fmri(diskp, fmri);
		nvlist_free(fmri);
	}

	/*
	 * Update the diskmon's location field with the disk's label
	 */
	if (diskp->location)
		dstrfree(diskp->location);
	if (topo_node_label(node, &label, &err) == 0) {
		diskp->location = dstrdup(label);
		topo_hdl_strfree(thp, label);
	} else
		diskp->location = dstrdup("unknown location");

	/*
	 * Check for a device path property (if the disk is configured,
	 * it will be present) and add it to the diskmon's properties)
	 */
	if (topo_prop_get_string(node, TOPO_PGROUP_IO, TOPO_IO_DEV_PATH,
	    &devpath, &err) == 0) {
		char devp[PATH_MAX];
		/*
		 * Consumers of the DISK_PROP_DEVPATH property expect a raw
		 * minor device node
		 */
		(void) snprintf(devp, PATH_MAX, "%s:q,raw", devpath);
		(void) nvlist_add_string(diskp->props, DISK_PROP_DEVPATH,
		    devp);
		topo_hdl_strfree(thp, devpath);
	}

	/*
	 * Add the logical disk node, if it exists
	 */
	if (topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_LOGICAL_DISK_NAME, &devpath, &err) == 0) {
		(void) nvlist_add_string(diskp->props, DISK_PROP_LOGNAME,
		    devpath);
		topo_hdl_strfree(thp, devpath);
	}

	/*
	 * Add the FRU information (if present in the node) to the diskmon's
	 * fru data structure:
	 */
	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_MODEL, &model, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_MANUFACTURER, &manuf, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_SERIAL_NUM, &serial, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_FIRMWARE_REV, &firmrev, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_CAPACITY, &capacity, &err);

	frup = new_dmfru(manuf, model, firmrev, serial,
	    capacity == NULL ? 0 : strtoull(capacity, 0, 0));

	/*
	 * Update the disk's resource FMRI with the
	 * SunService-required members:
	 * FM_FMRI_HC_SERIAL_ID, FM_FMRI_HC_PART, and
	 * FM_FMRI_HC_REVISION
	 */
	(void) nvlist_add_string(diskp->disk_res_fmri,
	    FM_FMRI_HC_SERIAL_ID, serial);

	transform_model_string(manuf, model, &buf, &buflen);

	(void) nvlist_add_string(diskp->disk_res_fmri,
	    FM_FMRI_HC_PART, buf);

	/*
	 * Add the serial number to the ASRU so that when the resource
	 * is marked faulty in the fmd resource cache, the hc scheme
	 * plugin can detect when the disk is no longer installed (and so,
	 * can clear the faulty state automatically across fmd restarts).
	 *
	 * The serial number is only updated when a disk comes online
	 * because that's when the disk node exists in the topo tree.
	 * It's ok to keep a stale value in the ASRU when the disk is removed
	 * because it's only used as part of fault creation when the disk
	 * is configured (online), at which point it will be updated with
	 * the (current) serial number of the disk inserted.
	 */
	(void) nvlist_add_string(diskp->asru_fmri,
	    FM_FMRI_HC_SERIAL_ID, serial);

	dfree(buf, buflen);

	(void) nvlist_add_string(diskp->disk_res_fmri,
	    FM_FMRI_HC_REVISION, firmrev);

	if (model) {
		topo_hdl_strfree(thp, model);
	}

	if (manuf) {
		topo_hdl_strfree(thp, manuf);
	}

	if (serial) {
		topo_hdl_strfree(thp, serial);
	}

	if (firmrev) {
		topo_hdl_strfree(thp, firmrev);
	}

	if (capacity) {
		topo_hdl_strfree(thp, capacity);
	}

	/* Add the fru information to the diskmon: */
	dm_assert(pthread_mutex_lock(&diskp->fru_mutex) == 0);
	dm_assert(diskp->frup == NULL);
	diskp->frup = frup;
	dm_assert(pthread_mutex_unlock(&diskp->fru_mutex) == 0);

	return (0);
}
Esempio n. 15
0
/*
 * 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;
}
Esempio n. 16
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);
}
Esempio n. 17
0
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);
}
Esempio n. 18
0
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);
}
Esempio n. 19
0
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);
}
Esempio n. 20
0
/*ARGSUSED*/
static int
do_slot_mapping_cb(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	int err, ret;
	nvlist_t *rsrc = NULL;
	const char *match = arg;
	char *s, *fmri = NULL;
	char *didstr = NULL, *driver = NULL, *vidstr = NULL;
	boolean_t printed = B_FALSE;

	ret = TOPO_WALK_NEXT;
	if (topo_node_resource(node, &rsrc, &err) < 0)
		goto next;
	if (topo_fmri_nvl2str(thp, rsrc, &fmri, &err) < 0)
		goto next;

	if ((s = strstr(fmri, match)) == NULL)
		goto next;
	if (s[strlen(match)] != '\0')
		goto next;

	/* At this point we think we've found a match */
	ret = TOPO_WALK_TERMINATE;
	if (topo_prop_get_string(node, TOPO_PGROUP_IO, TOPO_IO_DRIVER, &driver,
	    &err) != 0)
		driver = NULL;

	if (topo_prop_get_string(node, TOPO_PGROUP_PCI, TOPO_PCI_VENDID,
	    &vidstr, &err) != 0)
		goto next;

	if (topo_prop_get_string(node, TOPO_PGROUP_PCI, TOPO_PCI_DEVID,
	    &didstr, &err) != 0)
		goto next;

	if (prt_php != NULL) {
		long vid, did;

		vid = strtol(vidstr, NULL, 16);
		did = strtol(didstr, NULL, 16);
		if (vid >= 0 && vid <= UINT16_MAX &&
		    did >= 0 && did <= UINT16_MAX) {
			pcidb_device_t *pdev;

			pdev = pcidb_lookup_device(prt_php, vid, did);
			if (pdev != NULL) {
				pcidb_vendor_t *pvend;
				pvend = pcidb_device_vendor(pdev);
				(void) printf(gettext(", %s %s (%s)"),
				    pcidb_vendor_name(pvend),
				    pcidb_device_name(pdev),
				    driver != NULL ? driver : "<unknown>");
				printed = B_TRUE;
			}
		}
	}

	if (printed == B_FALSE) {
		(void) printf(gettext(", pci%s,%s (%s)"), vidstr, didstr,
		    driver != NULL ? driver : "<unknown>");
	}
next:
	topo_hdl_strfree(thp, didstr);
	topo_hdl_strfree(thp, driver);
	topo_hdl_strfree(thp, vidstr);
	topo_hdl_strfree(thp, fmri);
	nvlist_free(rsrc);
	return (ret);
}
Esempio n. 21
0
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);
}
Esempio n. 22
0
static void
print_prop_nameval(topo_hdl_t *thp, tnode_t *node, nvlist_t *nvl)
{
	int err;
	topo_type_t type;
	char *tstr, *propn, buf[48], *factype;
	nvpair_t *pv_nvp;
	int i;
	uint_t nelem;

	if ((pv_nvp = nvlist_next_nvpair(nvl, NULL)) == NULL)
		return;

	/* Print property name */
	if ((pv_nvp = nvlist_next_nvpair(nvl, NULL)) == NULL ||
	    nvpair_name(pv_nvp) == NULL ||
	    strcmp(TOPO_PROP_VAL_NAME, nvpair_name(pv_nvp)) != 0) {
		(void) fprintf(stderr, "%s: malformed property name\n",
		    g_pname);
		return;
	} else {
		(void) nvpair_value_string(pv_nvp, &propn);
	}

	if ((pv_nvp = nvlist_next_nvpair(nvl, pv_nvp)) == NULL ||
	    nvpair_name(pv_nvp) == NULL ||
	    strcmp(nvpair_name(pv_nvp), TOPO_PROP_VAL_TYPE) != 0 ||
	    nvpair_type(pv_nvp) != DATA_TYPE_UINT32)  {
		(void) fprintf(stderr, "%s: malformed property type for %s\n",
		    g_pname, propn);
		return;
	} else {
		(void) nvpair_value_uint32(pv_nvp, (uint32_t *)&type);
	}

	switch (type) {
		case TOPO_TYPE_BOOLEAN: tstr = "boolean"; break;
		case TOPO_TYPE_INT32: tstr = "int32"; break;
		case TOPO_TYPE_UINT32: tstr = "uint32"; break;
		case TOPO_TYPE_INT64: tstr = "int64"; break;
		case TOPO_TYPE_UINT64: tstr = "uint64"; break;
		case TOPO_TYPE_DOUBLE: tstr = "double"; break;
		case TOPO_TYPE_STRING: tstr = "string"; break;
		case TOPO_TYPE_FMRI: tstr = "fmri"; break;
		case TOPO_TYPE_INT32_ARRAY: tstr = "int32[]"; break;
		case TOPO_TYPE_UINT32_ARRAY: tstr = "uint32[]"; break;
		case TOPO_TYPE_INT64_ARRAY: tstr = "int64[]"; break;
		case TOPO_TYPE_UINT64_ARRAY: tstr = "uint64[]"; break;
		case TOPO_TYPE_STRING_ARRAY: tstr = "string[]"; break;
		case TOPO_TYPE_FMRI_ARRAY: tstr = "fmri[]"; break;
		default: tstr = "unknown type";
	}

	(void) printf("    %-17s %-8s ", propn, tstr);

	/*
	 * Get property value
	 */
	if (nvpair_name(pv_nvp) == NULL ||
	    (pv_nvp = nvlist_next_nvpair(nvl, pv_nvp)) == NULL) {
		(void) fprintf(stderr, "%s: malformed property value\n",
		    g_pname);
		return;
	}

	switch (nvpair_type(pv_nvp)) {
		case DATA_TYPE_INT32: {
			int32_t val;
			(void) nvpair_value_int32(pv_nvp, &val);
			(void) printf(" %d", val);
			break;
		}
		case DATA_TYPE_UINT32: {
			uint32_t val, type;
			char val_str[49];
			nvlist_t *fac, *rsrc = NULL;

			(void) nvpair_value_uint32(pv_nvp, &val);
			if (node == NULL || topo_node_flags(node) !=
			    TOPO_NODE_FACILITY)
				goto uint32_def;

			if (topo_node_resource(node, &rsrc, &err) != 0)
				goto uint32_def;

			if (nvlist_lookup_nvlist(rsrc, "facility", &fac) != 0)
				goto uint32_def;

			if (nvlist_lookup_string(fac, FM_FMRI_FACILITY_TYPE,
			    &factype) != 0)
				goto uint32_def;

			nvlist_free(rsrc);
			rsrc = NULL;

			/*
			 * Special case code to do friendlier printing of
			 * facility node properties
			 */
			if ((strcmp(propn, TOPO_FACILITY_TYPE) == 0) &&
			    (strcmp(factype, TOPO_FAC_TYPE_SENSOR) == 0)) {
				topo_sensor_type_name(val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			} else if ((strcmp(propn, TOPO_FACILITY_TYPE) == 0) &&
			    (strcmp(factype, TOPO_FAC_TYPE_INDICATOR) == 0)) {
				topo_led_type_name(val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			} else if (strcmp(propn, TOPO_SENSOR_UNITS) == 0) {
				topo_sensor_units_name(val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			} else if (strcmp(propn, TOPO_LED_MODE) == 0) {
				topo_led_state_name(val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			} else if ((strcmp(propn, TOPO_SENSOR_STATE) == 0) &&
			    (strcmp(factype, TOPO_FAC_TYPE_SENSOR) == 0)) {
				if (topo_prop_get_uint32(node,
				    TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE,
				    &type, &err) != 0) {
					goto uint32_def;
				}
				topo_sensor_state_name(type, val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			}
uint32_def:
			(void) printf(" 0x%x", val);
			if (rsrc != NULL)
				nvlist_free(rsrc);
			break;
		}
		case DATA_TYPE_INT64: {
			int64_t val;
			(void) nvpair_value_int64(pv_nvp, &val);
			(void) printf(" %lld", (longlong_t)val);
			break;
		}
		case DATA_TYPE_UINT64: {
			uint64_t val;
			(void) nvpair_value_uint64(pv_nvp, &val);
			(void) printf(" 0x%llx", (u_longlong_t)val);
			break;
		}
		case DATA_TYPE_DOUBLE: {
			double val;
			(void) nvpair_value_double(pv_nvp, &val);
			(void) printf(" %lf", (double)val);
			break;
		}
		case DATA_TYPE_STRING: {
			char *val;
			(void) nvpair_value_string(pv_nvp, &val);
			if (!opt_V && strlen(val) > 48) {
				(void) snprintf(buf, 48, "%s...", val);
				(void) printf(" %s", buf);
			} else {
				(void) printf(" %s", val);
			}
			break;
		}
		case DATA_TYPE_NVLIST: {
			nvlist_t *val;
			char *fmri;
			(void) nvpair_value_nvlist(pv_nvp, &val);
			if (topo_fmri_nvl2str(thp, val, &fmri, &err) != 0) {
				if (opt_V)
					nvlist_print(stdout, nvl);
				break;
			}

			if (!opt_V && strlen(fmri) > 48) {
				(void) snprintf(buf, 48, "%s", fmri);
				(void) snprintf(&buf[45], 4, "%s", DOTS);
				(void) printf(" %s", buf);
			} else {
				(void) printf(" %s", fmri);
			}

			topo_hdl_strfree(thp, fmri);
			break;
		}
		case DATA_TYPE_INT32_ARRAY: {
			int32_t *val;

			(void) nvpair_value_int32_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("%d ", val[i]);
			(void) printf("]");
			break;
		}
		case DATA_TYPE_UINT32_ARRAY: {
			uint32_t *val;

			(void) nvpair_value_uint32_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("%u ", val[i]);
			(void) printf("]");
			break;
		}
		case DATA_TYPE_INT64_ARRAY: {
			int64_t *val;

			(void) nvpair_value_int64_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("%lld ", val[i]);
			(void) printf("]");
			break;
		}
		case DATA_TYPE_UINT64_ARRAY: {
			uint64_t *val;

			(void) nvpair_value_uint64_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("%llu ", val[i]);
			(void) printf("]");
			break;
		}
		case DATA_TYPE_STRING_ARRAY: {
			char **val;

			(void) nvpair_value_string_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("\"%s\" ", val[i]);
			(void) printf("]");
			break;
		}
		default:
			(void) fprintf(stderr, " unknown data type (%d)",
			    nvpair_type(pv_nvp));
			break;
		}
		(void) printf("\n");
}
Esempio n. 23
0
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);
}
Esempio n. 24
0
/*ARGSUSED*/
static int
walk_node(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	int err;
	nvlist_t *nvl;
	nvlist_t *rsrc, *out;
	char *s;

	if (opt_e && strcmp(opt_s, FM_FMRI_SCHEME_HC) == 0) {
		print_everstyle(node);
		return (TOPO_WALK_NEXT);
	}

	if (topo_node_resource(node, &rsrc, &err) < 0) {
		(void) fprintf(stderr, "%s: failed to get resource: "
		    "%s", g_pname, topo_strerror(err));
		return (TOPO_WALK_NEXT);
	}
	if (topo_fmri_nvl2str(thp, rsrc, &s, &err) < 0) {
		(void) fprintf(stderr, "%s: failed to convert "
		    "resource to FMRI string: %s", g_pname,
		    topo_strerror(err));
		nvlist_free(rsrc);
		return (TOPO_WALK_NEXT);
	}

	if (g_fmri != NULL && fnmatch(g_fmri, s, 0) != 0) {
		nvlist_free(rsrc);
		topo_hdl_strfree(thp, s);
		return (TOPO_WALK_NEXT);
	}

	print_node(thp, node, rsrc, s);
	topo_hdl_strfree(thp, s);
	nvlist_free(rsrc);

	if (opt_m != NULL) {
		if (topo_method_invoke(node, opt_m, 0, NULL, &out, &err) == 0) {
			nvlist_print(stdout, out);
			nvlist_free(out);
		} else if (err != ETOPO_METHOD_NOTSUP)
			(void) fprintf(stderr, "%s: method failed unexpectedly "
			    "on %s=%d (%s)\n", g_pname, topo_node_name(node),
			    topo_node_instance(node), topo_strerror(err));
	}

	if (opt_V || opt_all) {
		if ((nvl = topo_prop_getprops(node, &err)) == NULL) {
			(void) fprintf(stderr, "%s: failed to get "
			    "properties for %s=%d: %s\n", g_pname,
			    topo_node_name(node), topo_node_instance(node),
			    topo_strerror(err));
		} else {
			print_all_props(thp, node, nvl, ALL);
			nvlist_free(nvl);
		}
	} else if (pcnt > 0)
		print_props(thp, node);

	(void) printf("\n");

	return (TOPO_WALK_NEXT);
}