Example #1
0
/*ARGSUSED*/
static int
ASRU_set(tnode_t *tn, did_t *pd,
    const char *dpnm, const char *tpgrp, const char *tpnm)
{
	topo_mod_t *mp;
	nvlist_t *fmri;
	char *dnpath, *path, *fpath, *nm;
	int d, e, f;

	/*
	 * If this topology node represents a function of device,
	 * set the ASRU to a dev scheme FMRI based on the value of
	 * di_devfs_path().  If that path is NULL, set the ASRU to
	 * be the resource describing this topology node.  If this
	 * isn't a function, inherit any ASRU from the parent.
	 */
	mp = did_mod(pd);
	nm = topo_node_name(tn);
	if ((strcmp(nm, PCI_BUS) == 0 && did_gettnode(pd) &&
	    strcmp(topo_node_name(did_gettnode(pd)), HOSTBRIDGE) == 0) ||
	    strcmp(nm, PCI_FUNCTION) == 0 || strcmp(nm, PCIEX_FUNCTION) == 0 ||
	    strcmp(nm, PCIEX_ROOT) == 0) {
		if ((dnpath = di_devfs_path(did_dinode(pd))) != NULL) {
			/*
			 * Dup the path, dev_path_fix() may replace it and
			 * dev_path_fix() wouldn't know to use
			 * di_devfs_path_free()
			 */
			if ((path = topo_mod_strdup(mp, dnpath)) == NULL) {
				di_devfs_path_free(dnpath);
				return (topo_mod_seterrno(mp, EMOD_NOMEM));
			}
			di_devfs_path_free(dnpath);
			did_BDF(pd, NULL, &d, &f);
			if ((fpath = dev_path_fix(mp, path, d, f)) == NULL)
				return (topo_mod_seterrno(mp, EMOD_NOMEM));

			fmri = topo_mod_devfmri(mp, FM_DEV_SCHEME_VERSION,
			    fpath, NULL);
			if (fmri == NULL) {
				topo_mod_dprintf(mp,
				    "dev:///%s fmri creation failed.\n", fpath);
				topo_mod_strfree(mp, fpath);
				return (-1);
			}
			topo_mod_strfree(mp, fpath);
		} else {
			topo_mod_dprintf(mp, "NULL di_devfs_path.\n");
			if (topo_prop_get_fmri(tn, TOPO_PGROUP_PROTOCOL,
			    TOPO_PROP_RESOURCE, &fmri, &e) < 0)
				return (topo_mod_seterrno(mp, e));
		}
		if (topo_node_asru_set(tn, fmri, 0, &e) < 0) {
			nvlist_free(fmri);
			return (topo_mod_seterrno(mp, e));
		}
		nvlist_free(fmri);
		return (0);
	}
	(void) topo_node_asru_set(tn, NULL, 0, &e);

	return (0);
}
Example #2
0
static int
mptsas_led_mode(topo_mod_t *mod, tnode_t *node, topo_version_t vers,
    nvlist_t *in, nvlist_t **nvout)
{
	int err, ret = 0;
	tnode_t *pnode = topo_node_parent(node);
	uint32_t type, ledmode = 0;
	nvlist_t *pargs, *nvl;
	char *driver = NULL, *devctl = NULL;
	uint32_t enclosure, slot;
	uint8_t mptsas_led;
	boolean_t set;

	if (vers > TOPO_METH_MPTSAS_LED_MODE_VERSION)
		return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW));

	if (topo_prop_get_string(pnode, TOPO_PGROUP_BINDING,
	    TOPO_BINDING_DRIVER, &driver, &err) != 0 ||
	    strcmp("mpt_sas", driver) != 0) {
		topo_mod_dprintf(mod, "%s: Facility driver was not mpt_sas",
		    __func__);
		ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL);
		goto out;
	}
	if (topo_prop_get_uint32(node, TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE,
	    &type, &err) != 0) {
		topo_mod_dprintf(mod, "%s: Failed to lookup %s property "
		    "(%s)", __func__, TOPO_FACILITY_TYPE, topo_strerror(err));
		return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
	}
	switch (type) {
	case (TOPO_LED_TYPE_SERVICE):
		mptsas_led = MPTSAS_LEDCTL_LED_FAIL;
		break;
	case (TOPO_LED_TYPE_LOCATE):
		mptsas_led = MPTSAS_LEDCTL_LED_IDENT;
		break;
	case (TOPO_LED_TYPE_OK2RM):
		mptsas_led = MPTSAS_LEDCTL_LED_OK2RM;
		break;
	default:
		topo_mod_dprintf(mod, "%s: Invalid LED type: 0x%x\n", __func__,
		    type);
		return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
	}
	if (topo_prop_get_string(pnode, TOPO_PGROUP_BINDING,
	    TOPO_BINDING_DEVCTL, &devctl, &err) != 0 ||
	    topo_prop_get_uint32(pnode, TOPO_PGROUP_BINDING,
	    TOPO_BINDING_ENCLOSURE, &enclosure, &err) != 0 ||
	    topo_prop_get_uint32(pnode, TOPO_PGROUP_BINDING,
	    TOPO_BINDING_SLOT, &slot, &err) != 0) {
		topo_mod_dprintf(mod, "%s: Facility was missing mpt_sas binding"
		    " properties\n", __func__);
		ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL);
		goto out;
	}

	if ((nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &pargs) == 0) &&
	    nvlist_exists(pargs, TOPO_PROP_VAL_VAL)) {
		/*
		 * Set the LED mode
		 */
		set = B_TRUE;
		if ((ret = nvlist_lookup_uint32(pargs, TOPO_PROP_VAL_VAL,
		    &ledmode)) != 0) {
			topo_mod_dprintf(mod, "%s: Failed to lookup %s nvpair "
			    "(%s)\n", __func__, TOPO_PROP_VAL_VAL,
			    strerror(ret));
			ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL);
			goto out;
		}
		topo_mod_dprintf(mod, "%s: Setting LED mode to %s\n", __func__,
		    ledmode ? "ON" : "OFF");
	} else {
		/*
		 * Get the LED mode
		 */
		set = B_FALSE;
		topo_mod_dprintf(mod, "%s: Getting LED mode\n", __func__);
	}

	if (do_led_control(mod, devctl, enclosure, slot, mptsas_led, &ledmode,
	    set) != 0) {
		topo_mod_dprintf(mod, "%s: do_led_control failed", __func__);
		ret = topo_mod_seterrno(mod, EMOD_UNKNOWN);
		goto out;
	}

	if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 ||
	    nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, TOPO_LED_MODE) != 0 ||
	    nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 ||
	    nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, ledmode) != 0) {
		topo_mod_dprintf(mod, "%s: Failed to allocate 'out' nvlist\n",
		    __func__);
		nvlist_free(nvl);
		ret = topo_mod_seterrno(mod, EMOD_NOMEM);
		goto out;
	}
	*nvout = nvl;

out:
	if (driver != NULL)
		topo_mod_strfree(mod, driver);
	if (devctl != NULL)
		topo_mod_strfree(mod, devctl);
	return (ret);
}
Example #3
0
static void
topo_node_destroy(tnode_t *node)
{
	int i;
	tnode_t *pnode = node->tn_parent;
	topo_nodehash_t *nhp;
	topo_mod_t *hmod, *mod = node->tn_enum;

	if (node == NULL)
		return;

	assert(node->tn_refs == 0);

	topo_dprintf(TOPO_DBG_TREE, "destroying node %s=%d\n", node->tn_name,
	    node->tn_instance);
	/*
	 * If not a root node, remove this node from the parent's node hash
	 */

	if (!(node->tn_state & TOPO_NODE_ROOT)) {
		topo_node_lock(pnode);

		nhp = node->tn_phash;
		for (i = 0; i < nhp->th_arrlen; i++) {
			if (node == nhp->th_nodearr[i]) {
				nhp->th_nodearr[i] = NULL;

				/*
				 * Release hold on parent
				 */
				--pnode->tn_refs;
				if (pnode->tn_refs == 0)
					topo_node_destroy(pnode);
			}
		}
		topo_node_unlock(pnode);
	}

	topo_node_unlock(node);

	/*
	 * Allow enumerator to clean-up private data and then release
	 * ref count
	 */
	if (mod->tm_info->tmi_release != NULL)
		mod->tm_info->tmi_release(mod, node);

	topo_method_unregister_all(mod, node);

	/*
	 * Destroy all node hash lists
	 */
	while ((nhp = topo_list_next(&node->tn_children)) != NULL) {
		for (i = 0; i < nhp->th_arrlen; i++) {
			assert(nhp->th_nodearr[i] == NULL);
		}
		hmod = nhp->th_enum;
		topo_mod_strfree(hmod, nhp->th_name);
		topo_mod_free(hmod, nhp->th_nodearr,
		    nhp->th_arrlen * sizeof (tnode_t *));
		topo_list_delete(&node->tn_children, nhp);
		topo_mod_free(hmod, nhp, sizeof (topo_nodehash_t));
		topo_mod_rele(hmod);
	}

	/*
	 * Destroy all property data structures, free the node and release
	 * the module that created it
	 */
	topo_pgroup_destroy_all(node);
	topo_mod_free(mod, node, sizeof (tnode_t));
	topo_mod_rele(mod);
}
Example #4
0
static void
dev_di_node_free(topo_mod_t *mod, dev_di_node_t *dnode)
{
	int i;

	/* free the stuff we point to */
	if (dnode->ddn_devid)
		topo_mod_strfree(mod, dnode->ddn_devid);
	for (i = 0; i < dnode->ddn_ppath_count; i++) {
		/* topo_mod_strfree does NULL checking. */
		topo_mod_strfree(mod, dnode->ddn_ppath[i]);
		topo_mod_strfree(mod, dnode->ddn_target_port[i]);
		topo_mod_strfree(mod, dnode->ddn_attached_port[i]);
		topo_mod_strfree(mod, dnode->ddn_bridge_port[i]);
	}
	topo_mod_free(mod, dnode->ddn_ppath,
	    dnode->ddn_ppath_count * sizeof (char *));
	topo_mod_free(mod, dnode->ddn_target_port,
	    dnode->ddn_ppath_count * sizeof (char *));
	topo_mod_free(mod, dnode->ddn_attached_port,
	    dnode->ddn_ppath_count * sizeof (char *));
	topo_mod_free(mod, dnode->ddn_bridge_port,
	    dnode->ddn_ppath_count * sizeof (char *));
	topo_mod_strfree(mod, dnode->ddn_dpath);
	topo_mod_strfree(mod, dnode->ddn_lpath);

	topo_mod_strfree(mod, dnode->ddn_mfg);
	topo_mod_strfree(mod, dnode->ddn_model);
	topo_mod_strfree(mod, dnode->ddn_serial);
	topo_mod_strfree(mod, dnode->ddn_firm);
	topo_mod_strfree(mod, dnode->ddn_cap);

	/* free self */
	topo_mod_free(mod, dnode, sizeof (dev_di_node_t));
}
Example #5
0
/*
 * Calculate the authority information for a node.  Inherit the data if
 * possible, but always create an appropriate property group.
 */
int
x86pi_set_auth(topo_mod_t *mod, x86pi_hcfmri_t *hcfmri, tnode_t *t_parent,
    tnode_t *t_node)
{
	int 		result;
	int		err;
	int		is_chassis = 0;
	int		chassis_instance = 0;
	nvlist_t	*auth;
	char		*val = NULL;
	char		*prod = NULL;
	char		*psn = NULL;
	char		*csn = NULL;
	char		*server = NULL;
	char		*f = "x86pi_set_auth";

	if (mod == NULL || t_parent == NULL || t_node == NULL) {
		return (-1);
	}

	result = topo_pgroup_create(t_node, &auth_pgroup, &err);
	if (result != 0 && err != ETOPO_PROP_DEFD) {
		/*
		 * We failed to create the property group and it was not
		 * already defined.  Set the err code and return failure.
		 */
		(void) topo_mod_seterrno(mod, err);
		return (-1);
	}

	/* Get the authority information already available from the parent */
	auth = topo_mod_auth(mod, t_parent);

	/* Determnine if this is a chassis node and set it's instance */
	if ((strlen(hcfmri->hc_name) == strlen(CHASSIS)) &&
	    strncmp(hcfmri->hc_name, CHASSIS, strlen(CHASSIS)) == 0) {
		is_chassis = 1;
		chassis_instance = hcfmri->instance;
	}

	/*
	 * Set the authority data, inheriting it if possible, but creating it
	 * if necessary.
	 */

	/* product-id */
	result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY,
	    FM_FMRI_AUTH_PRODUCT, &err);
	if (result != 0 && err != ETOPO_PROP_DEFD) {
		result = nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT,
		    &prod);
		if (result != 0 || prod == NULL) {
			/*
			 * No product information in the parent node or auth
			 * list. Use the product information in the hcfrmi
			 * struct.
			 */
			prod = (char *)hcfmri->product;
			if (prod == NULL) {
				topo_mod_dprintf(mod, "%s: product name not "
				    "found for %s node\n", f, hcfmri->hc_name);
			}
		}

		/*
		 * We continue even if the product information is not available
		 * to enumerate as much as possible.
		 */
		if (prod != NULL) {
			result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY,
			    FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod,
			    &err);
			if (result != 0) {
				/* Preserve the error and continue */
				(void) topo_mod_seterrno(mod, err);
				topo_mod_dprintf(mod, "%s: failed to set "
				    "property %s (%d) : %s\n", f,
				    FM_FMRI_AUTH_PRODUCT, err,
				    topo_strerror(err));
			}
		}
	}

	/* product-sn */
	result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY,
	    FM_FMRI_AUTH_PRODUCT_SN, &err);
	if (result != 0 && err != ETOPO_PROP_DEFD) {
		result = nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN,
		    &psn);
		if (result != 0 || psn == NULL) {
			/*
			 * No product-sn information in the parent node or auth
			 * list.
			 */
			topo_mod_dprintf(mod, "%s: psn not found\n", f);
		} else {
			/*
			 * We continue even if the product-sn information is
			 * not available to enumerate as much as possible.
			 */
			result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY,
			    FM_FMRI_AUTH_PRODUCT_SN, TOPO_PROP_IMMUTABLE, psn,
			    &err);
			if (result != 0) {
				/* Preserve the error and continue */
				(void) topo_mod_seterrno(mod, err);
				topo_mod_dprintf(mod, "%s: failed to "
				    "set property %s (%d) : %s\n", f,
				    FM_FMRI_AUTH_PRODUCT_SN, err,
				    topo_strerror(err));
			}
		}
	}

	/* chassis-id */
	if (is_chassis == 0 || (is_chassis == 1 && chassis_instance == 0)) {
		/* either not a chassis node, or chassis #0 */
		result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY,
		    FM_FMRI_AUTH_CHASSIS, &err);
	} else {
		/* chassis 'n' in a >1 chassis system */
		result = err = -1;
	}
	if (result != 0 && err != ETOPO_PROP_DEFD) {
		if (is_chassis == 0) {
			result = nvlist_lookup_string(auth,
			    FM_FMRI_AUTH_CHASSIS, &csn);
			if (result != 0 || csn == NULL) {
				/*
				 * No chassis information in the parent
				 * node or auth list.
				 */
				topo_mod_dprintf(mod,
				    "%s: csn name not found\n", f);
			}
		} else {
			/*
			 * So as not to blindly set the chassis-id to
			 * chassis #0's serial number.
			 */
			csn = val = topo_mod_strdup(mod, hcfmri->serial_number);
		}

		/*
		 * We continue even if the chassis information is not available
		 * to enumerate as much as possible.
		 */
		if (csn != NULL) {
			if (is_chassis == 1)
				result = topo_prop_set_string(t_node,
				    FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS,
				    TOPO_PROP_MUTABLE, csn, &err);
			else
				result = topo_prop_set_string(t_node,
				    FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS,
				    TOPO_PROP_IMMUTABLE, csn, &err);

			if (result != 0) {
				/* Preserve the error and continue */
				(void) topo_mod_seterrno(mod, err);
				topo_mod_dprintf(mod, "%s: failed to "
				    "set property %s (%d) : %s\n", f,
				    FM_FMRI_AUTH_CHASSIS, err,
				    topo_strerror(err));
			}
		}

		if (val != NULL) {
			topo_mod_strfree(mod, val);
			val = NULL;
		}
	}

	/* server-id */
	result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY,
	    FM_FMRI_AUTH_SERVER, &err);
	if (result != 0 && err != ETOPO_PROP_DEFD) {
		result = nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER,
		    &server);
		if (result != 0 || server == NULL) {
			/*
			 * No server information in the parent node or auth
			 * list.  Find the server information in hostname.
			 */
			server = val = x86pi_get_serverid(mod);
			if (server == NULL) {
				topo_mod_dprintf(mod, "%s: server "
				    "name not found for %s node\n", f,
				    hcfmri->hc_name);
			}
		}

		/*
		 * We continue even if the server information is not available
		 * to enumerate as much as possible.
		 */
		if (server != NULL) {
			result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY,
			    FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server,
			    &err);
			if (result != 0) {
				/* Preserve the error and continue */
				(void) topo_mod_seterrno(mod, err);
				topo_mod_dprintf(mod, "%s: failed to "
				    "set property %s (%d) : %s\n", f,
				    FM_FMRI_AUTH_SERVER, err,
				    topo_strerror(err));
			}
		}

		if (val != NULL)
			topo_mod_strfree(mod, val);
	}

	nvlist_free(auth);

	return (0);
}
Example #6
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);
}
Example #7
0
int
platform_pci_fru(topo_mod_t *mod, tnode_t *node, nvlist_t *in,
    nvlist_t **out)
{
	int err = 0;
	uint64_t ptr;
	did_t *dp, *pdp;
	tnode_t *pnode;
	char *nm, *plat, *pp, **cp;
	char *label;
	int found_t1plat = 0;
	uchar_t *loc;
	int locsiz;

	topo_mod_dprintf(mod, "entering platform_pci_fru\n");

	if (topo_prop_get_string(node, FM_FMRI_AUTHORITY,
	    FM_FMRI_AUTH_PRODUCT, &plat, &err) < 0) {
		(void) topo_mod_seterrno(mod, err);
		return (-1);
	}
	/* Delete the "SUNW," */
	pp = strchr(plat, ',');
	if (pp == NULL)
		pp = plat;
	else
		++pp;

	/* Is this an UltraSPARC-T1 platform? */
	cp = usT1_plats;
	while ((*cp != NULL) && (found_t1plat == 0)) {
		if (strcmp(pp, *cp) == 0)
			found_t1plat = 1;
		cp++;
	}

	topo_mod_strfree(mod, plat);

	/*
	 * On UltraSPARC-T1 systems, use the legacy hc scheme on
	 * the adapter slots to ensure ALOM on the SP can interpret
	 * the FRU correctly. For everything else, follow the normal
	 * code flow
	 */
	if (found_t1plat) {
		*out = NULL;
		nm = topo_node_name(node);
		if (strcmp(nm, PCI_DEVICE) != 0 &&
		    strcmp(nm, PCIEX_DEVICE) != 0 &&
		    strcmp(nm, PCIEX_BUS) != 0)
			return (0);

		if (nvlist_lookup_uint64(in, "nv1", &ptr) != 0) {
			topo_mod_dprintf(mod, "label method argument "
			    "not found.\n");
			return (-1);
		}
		dp = (did_t *)(uintptr_t)ptr;
		pnode = did_gettnode(dp);
		pdp = did_find(mod, topo_node_getspecific(pnode));

		/*
		 * Is there a slotname associated with the device?
		 */
		if ((label = pci_slot_label_lookup(mod, pnode, dp, pdp))
		    != NULL) {
			nvlist_t *rnvl;
			char buf[PATH_MAX];

			(void) snprintf(buf, PATH_MAX, "hc:///component=%s",
			    label);
			if (topo_mod_str2nvl(mod, buf, &rnvl) < 0)
				return (-1);
			*out = rnvl;
		}
		return (0);
	} else if (di_bytes_get(mod, topo_node_getspecific(node),
	    PI_PROP_CHASSIS_LOCATION_NAME, &locsiz, &loc) == 0 && locsiz > 0) {
		/*
		 * We have crossed a FRU boundary and need to find the parent
		 * node with this location and set our FMRI to that value.
		 */
		return (platform_pci_fru_location(mod, node, loc, locsiz));
	} else {
		return (pci_fru_compute(mod, node, in, out));
	}
}
Example #8
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);
}
Example #9
0
/*
 * Query the current disk status. If successful, the disk status is returned
 * as an nvlist consisting of at least the following members:
 *
 *	protocol	string		Supported protocol (currently "scsi")
 *
 *	status		nvlist		Arbitrary protocol-specific information
 *					about the current state of the disk.
 *
 *	faults		nvlist		A list of supported faults. Each
 *					element of this list is a boolean value.
 *					An element's existence indicates that
 *					the drive supports detecting this fault,
 *					and the value indicates the current
 *					state of the fault.
 *
 *	<fault-name>	nvlist		For each fault named in 'faults', a
 *					nvlist describing protocol-specific
 *					attributes of the fault.
 *
 * This method relies on the libdiskstatus library to query this information.
 */
static int
disk_status(topo_mod_t *mod, tnode_t *nodep, topo_version_t vers,
    nvlist_t *in_nvl, nvlist_t **out_nvl)
{
	disk_status_t	*dsp;
	char		*devpath, *fullpath;
	size_t		pathlen;
	nvlist_t	*status;
	int		err;

	*out_nvl = NULL;

	if (vers != TOPO_METH_DISK_STATUS_VERSION)
		return (topo_mod_seterrno(mod, EMOD_VER_NEW));

	/*
	 * If the caller specifies the "path" parameter, then this indicates
	 * that we should use this instead of deriving it from the topo node
	 * itself.
	 */
	if (nvlist_lookup_string(in_nvl, "path", &fullpath) == 0) {
		devpath = NULL;
	} else {
		/*
		 * Get the /devices path and attempt to open the disk status
		 * handle.
		 */
		if (topo_prop_get_string(nodep, TOPO_PGROUP_IO,
		    TOPO_IO_DEV_PATH, &devpath, &err) != 0)
			return (topo_mod_seterrno(mod, EMOD_METHOD_NOTSUP));

		/*
		 * Note that sizeof(string) includes the terminating NULL byte
		 */
		pathlen = strlen(devpath) + sizeof ("/devices") +
		    sizeof (PHYS_EXTN) - 1;

		if ((fullpath = topo_mod_alloc(mod, pathlen)) == NULL)
			return (topo_mod_seterrno(mod, EMOD_NOMEM));

		(void) snprintf(fullpath, pathlen, "/devices%s%s", devpath,
		    PHYS_EXTN);

		topo_mod_strfree(mod, devpath);
	}

	if ((dsp = disk_status_open(fullpath, &err)) == NULL) {
		if (devpath)
			topo_mod_free(mod, fullpath, pathlen);
		return (topo_mod_seterrno(mod, err == EDS_NOMEM ?
		    EMOD_NOMEM : EMOD_METHOD_NOTSUP));
	}

	if (devpath)
		topo_mod_free(mod, fullpath, pathlen);

	if ((status = disk_status_get(dsp)) == NULL) {
		err = (disk_status_errno(dsp) == EDS_NOMEM ?
		    EMOD_NOMEM : EMOD_METHOD_NOTSUP);
		disk_status_close(dsp);
		return (topo_mod_seterrno(mod, err));
	}

	*out_nvl = status;
	disk_status_close(dsp);
	return (0);
}
Example #10
0
static tnode_t *
mb_tnode_create(topo_mod_t *mod, tnode_t *parent,
    const char *name, topo_instance_t i, void *priv)
{
	nvlist_t *fmri;
	tnode_t *ntn;
	char *serial = NULL, *part = NULL;
	char *psn = NULL, *csn = NULL, *pstr = NULL;
	nvlist_t *auth = topo_mod_auth(mod, parent);

	/*
	 * Get Product Serial Number, Chassis ID, MB Serial Number and
	 * Part Number from PRI.
	 */
	(void) mb_get_pri_info(mod, &serial, &part, &csn, &psn);

	if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &pstr) != 0 &&
	    csn != NULL) {
		if (nvlist_add_string(auth, FM_FMRI_AUTH_CHASSIS, csn) != 0) {
			topo_mod_dprintf(mod,
			    "failed to add chassis to auth");
			nvlist_free(auth);
			return (NULL);
		}
	}

	if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN, &pstr) != 0 &&
	    psn != NULL) {
		if (nvlist_add_string(auth, FM_FMRI_AUTH_PRODUCT_SN, psn)
		    != 0) {
			topo_mod_dprintf(mod,
			    "failed to add product-sn to auth");
			nvlist_free(auth);
			return (NULL);
		}
	}

	fmri = topo_mod_hcfmri(mod, NULL, FM_HC_SCHEME_VERSION, name, i,
	    NULL, auth, part, NULL, serial);

	topo_mod_strfree(mod, serial);
	topo_mod_strfree(mod, part);
	topo_mod_strfree(mod, csn);
	topo_mod_strfree(mod, psn);

	if (fmri == NULL) {
		topo_mod_dprintf(mod,
		    "Unable to make nvlist for %s bind: %s.\n",
		    name, topo_mod_errmsg(mod));
		nvlist_free(auth);
		return (NULL);
	}

	ntn = topo_node_bind(mod, parent, name, i, fmri);
	if (ntn == NULL) {
		topo_mod_dprintf(mod,
		    "topo_node_bind (%s%d/%s%d) failed: %s\n",
		    topo_node_name(parent), topo_node_instance(parent),
		    name, i,
		    topo_strerror(topo_mod_errno(mod)));
		nvlist_free(auth);
		nvlist_free(fmri);
		return (NULL);
	}

	mb_prop_set(ntn, auth);

	nvlist_free(auth);
	nvlist_free(fmri);

	topo_node_setspecific(ntn, priv);

	return (ntn);
}
Example #11
0
/*ARGSUSED*/
static int
amd_generic_mc_create(topo_mod_t *mod, uint16_t smbid, tnode_t *cnode,
    tnode_t *mcnode, int family, int model, nvlist_t *auth)
{
	int chan, cs;

	/*
	 * Elsewhere we have already returned for families less than 0xf.
	 * This "generic" topology is adequate for all of family 0xf and
	 * for revisions A to E of family 0x10 (for the list of models
	 * in each revision, refer to usr/src/uts/i86pc/os/cpuid_subr.c).
	 * We cover all family 0x10 models, till model 10.
	 */
	if (family > 0x10 || (family == 0x10 && model > 10))
		return (1);

	if (topo_node_range_create(mod, mcnode, CHAN_NODE_NAME, 0,
	    MAX_CHANNUM) < 0) {
		whinge(mod, NULL, "amd_generic_mc_create: range create for "
		    "channels failed\n");
		return (-1);
	}

	for (chan = 0; chan <= MAX_CHANNUM; chan++) {
		tnode_t *chnode;
		nvlist_t *fmri;
		int err;

		if (mkrsrc(mod, mcnode, CHAN_NODE_NAME, chan, auth,
		    &fmri) != 0) {
			whinge(mod, NULL, "amd_generic_mc_create: mkrsrc "
			    "failed\n");
			return (-1);
		}

		if ((chnode = topo_node_bind(mod, mcnode, CHAN_NODE_NAME,
		    chan, fmri)) == NULL) {
			nvlist_free(fmri);
			whinge(mod, NULL, "amd_generic_mc_create: node "
			    "bind failed\n");
			return (-1);
		}

		nvlist_free(fmri);

		(void) topo_pgroup_create(chnode, &chan_pgroup, &err);

		(void) topo_prop_set_string(chnode, PGNAME(CHAN), "channel",
		    TOPO_PROP_IMMUTABLE, chan == 0 ? "A" : "B", &err);

		if (FM_AWARE_SMBIOS(mod)) {
			if (topo_node_label_set(chnode, NULL, &err) == -1)
				whinge(mod, NULL, "amd_generic_mc_create: "
				    "topo_node_label_set\n");
			if (topo_node_fru_set(chnode, NULL, 0, &err) != 0)
				whinge(mod, NULL, "amd_generic_mc_create: "
				    "topo_node_fru_set failed\n");
		}

		if (topo_node_range_create(mod, chnode, CS_NODE_NAME,
		    0, MAX_CSNUM) < 0) {
			whinge(mod, NULL, "amd_generic_mc_create: "
			    "range create for cs failed\n");
			return (-1);
		}

		for (cs = 0; cs <= MAX_CSNUM; cs++) {
			tnode_t *csnode;

			if (mkrsrc(mod, chnode, CS_NODE_NAME, cs, auth,
			    &fmri) != 0) {
				whinge(mod, NULL, "amd_generic_mc_create: "
				    "mkrsrc for cs failed\n");
				return (-1);
			}

			if ((csnode = topo_node_bind(mod, chnode, CS_NODE_NAME,
			    cs, fmri)) == NULL) {
				nvlist_free(fmri);
				whinge(mod, NULL, "amd_generic_mc_create: "
				    "bind for cs failed\n");
				return (-1);
			}

			/*
			 * Dynamic ASRU for page faults within a chip-select.
			 * The topology does not represent pages (there are
			 * too many) so when a page is faulted we generate
			 * an ASRU to represent the individual page.
			 * If SMBIOS meets FMA needs, derive labels & serials
			 * for DIMMS and apply to chip-select nodes.
			 * If deriving from SMBIOS, skip IPMI
			 */
			if (FM_AWARE_SMBIOS(mod)) {
				if (topo_method_register(mod, csnode,
				    x86pi_gen_cs_methods) < 0)
					whinge(mod, NULL,
					    "amd_generic_mc_create: "
					    "method registration failed\n");
			} else {
				if (topo_method_register(mod, csnode,
				    gen_cs_methods) < 0)
					whinge(mod, NULL,
					    "amd_generic_mc_create: method"
					    "registration failed\n");
			}

			(void) topo_node_asru_set(csnode, fmri,
			    TOPO_ASRU_COMPUTE, &err);
			nvlist_free(fmri);

			/*
			 * If SMBIOS meets FMA needs, set DIMM as the FRU for
			 * the chip-select node. Use the channel & chip-select
			 * numbers to get the DIMM instance.
			 * Send via inst : dram channel number
			 * Receive via inst : dimm instance
			 */
			if (FM_AWARE_SMBIOS(mod)) {
				int inst;
				id_t dimm_smbid;
				const char *serial;
				const char *part;
				const char *rev;
				char *label;

				(void) topo_pgroup_create(csnode,
				    &cs_pgroup, &err);
				inst = chan;
				dimm_smbid = memnode_to_smbiosid(mod, smbid,
				    CS_NODE_NAME, cs, &inst);
				serial = chip_serial_smbios_get(mod,
				    dimm_smbid);
				part = chip_part_smbios_get(mod,
				    dimm_smbid);
				rev = chip_rev_smbios_get(mod, dimm_smbid);
				label = (char *)chip_label_smbios_get(mod,
				    chnode, dimm_smbid, NULL);

				(void) topo_prop_set_string(csnode, PGNAME(CS),
				    FM_FMRI_HC_SERIAL_ID, TOPO_PROP_IMMUTABLE,
				    serial, &err);
				(void) topo_prop_set_string(csnode, PGNAME(CS),
				    FM_FMRI_HC_PART, TOPO_PROP_IMMUTABLE,
				    part, &err);
				(void) topo_prop_set_string(csnode, PGNAME(CS),
				    FM_FMRI_HC_REVISION, TOPO_PROP_IMMUTABLE,
				    rev, &err);

				/*
				 * We apply DIMM labels to chip-select nodes,
				 * FRU for chip-selects should be DIMMs, and
				 * we do not derive dimm nodes for Family 0x10
				 * so FRU fmri is NULL, but FRU Labels are set,
				 * the FRU labels point to the DIMM.
				 */
				(void) topo_node_label_set(csnode, label, &err);
				topo_mod_strfree(mod, label);
			}
		}
	}

	return (0);
}
Example #12
0
/*ARGSUSED*/
static int
sw_fmri_nvl2str(topo_mod_t *mod, tnode_t *node, topo_version_t version,
    nvlist_t *nvl, nvlist_t **out)
{
	nvlist_t *object, *site = NULL, *anvl = NULL;
	char *file, *func, *token;
	uint8_t scheme_version;
	char *path, *root;
	nvlist_t *fmristr;
	size_t buflen = 0;
	int linevalid = 0;
	char *buf = NULL;
	ssize_t size = 0;
	char linebuf[32];
	int64_t line;
	int pass;
	int err;

	if (version > TOPO_METH_NVL2STR_VERSION)
		return (topo_mod_seterrno(mod, EMOD_VER_NEW));

	if (nvlist_lookup_uint8(nvl, FM_VERSION, &scheme_version) != 0 ||
	    scheme_version > FM_SW_SCHEME_VERSION)
		return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));

	/* Get authority, if present */
	err = nvlist_lookup_nvlist(nvl, FM_FMRI_AUTHORITY, &anvl);
	if (err != 0 && err != ENOENT)
		return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));

	/*
	 * The 'object' nvlist is required. It must include the path,
	 * but the root is optional.
	 */
	if (nvlist_lookup_nvlist(nvl, FM_FMRI_SW_OBJ, &object) != 0 ||
	    !lookup_string(object, FM_FMRI_SW_OBJ_PATH, &path, B_TRUE) ||
	    !lookup_string(object, FM_FMRI_SW_OBJ_ROOT, &root, B_FALSE))
		return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));

	/* The 'site' nvlist is optional */
	file = func = token = NULL;
	linevalid = 0;
	if ((err = nvlist_lookup_nvlist(nvl, FM_FMRI_SW_SITE, &site)) == 0) {
		/*
		 * Prefer 'token' to file/func/line
		 */
		if (lookup_string(site, FM_FMRI_SW_SITE_TOKEN, &token,
		    B_FALSE) <= 0) {
			/*
			 * If no token then try file, func, line - but
			 * func and line are meaningless without file.
			 */
			if (lookup_string(site, FM_FMRI_SW_SITE_FILE,
			    &file, B_FALSE) == 1) {
				(void) lookup_string(site, FM_FMRI_SW_SITE_FUNC,
				    &func, B_FALSE);
				if (nvlist_lookup_int64(site,
				    FM_FMRI_SW_SITE_LINE, &line) == 0)
					linevalid = 1;
			}
		}
	} else if (err != ENOENT) {
		return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
	}

	/* On the first pass buf is NULL and size and buflen are 0 */
	pass = 1;
again:
	/*
	 * sw://[<authority>]/
	 *	[:root=<object.root]
	 *	:path=<object.path>
	 *	[#<fragment-identifier>]
	 *
	 *	<fragment-identifier> is one of
	 *
	 *		:token=<site.token>
	 *	or
	 *		:file=<site.file>[:func=<site.func>][:line=<site.line>]
	 */

	/* sw:// */
	topo_fmristr_build(&size, buf, buflen, FM_FMRI_SCHEME_SW,
	    NULL, "://");

	/* authority, if any */
	if (anvl != NULL) {
		nvpair_t *apair;
		char *aname, *aval;

		for (apair = nvlist_next_nvpair(anvl, NULL);
		    apair != NULL; apair = nvlist_next_nvpair(anvl, apair)) {
			if (nvpair_type(apair) != DATA_TYPE_STRING ||
			    nvpair_value_string(apair, &aval) != 0)
				continue;
			aname = nvpair_name(apair);
			topo_fmristr_build(&size, buf, buflen, ":", NULL, NULL);
			topo_fmristr_build(&size, buf, buflen, "=",
			    aname, aval);
		}
	}

	/* separating slash */
	topo_fmristr_build(&size, buf, buflen, "/", NULL, NULL);

	/* :root=... */
	if (root) {
		topo_fmristr_build(&size, buf, buflen, root,
		    ":" FM_FMRI_SW_OBJ_ROOT "=", NULL);
	}

	/* :path=... */
	topo_fmristr_build(&size, buf, buflen, path,
	    ":" FM_FMRI_SW_OBJ_PATH "=", NULL);

	if (token) {
		/* #:token=... */
		topo_fmristr_build(&size, buf, buflen, token,
		    "#:" FM_FMRI_SW_SITE_TOKEN "=", NULL);
	} else if (file) {
		/* #:file=... */
		topo_fmristr_build(&size, buf, buflen, file,
		    "#:" FM_FMRI_SW_SITE_FILE "=", NULL);

		/* :func=... */
		if (func) {
			topo_fmristr_build(&size, buf, buflen, func,
			    ":" FM_FMRI_SW_SITE_FUNC "=", NULL);
		}

		/* :line=... */
		if (linevalid) {
			if (pass == 1)
				(void) snprintf(linebuf, sizeof (linebuf),
				    "%lld", line);

			topo_fmristr_build(&size, buf, buflen, linebuf,
			    ":" FM_FMRI_SW_SITE_LINE "=", NULL);
		}
	}

	if (buf == NULL) {
		if ((buf = topo_mod_alloc(mod, size + 1)) == NULL)
			return (topo_mod_seterrno(mod, EMOD_NOMEM));

		buflen = size + 1;
		size = 0;
		pass = 2;
		goto again;
	}

	/*
	 * Construct the nvlist to return as the result.
	 */
	if (topo_mod_nvalloc(mod, &fmristr, NV_UNIQUE_NAME) != 0) {
		topo_mod_strfree(mod, buf);
		return (topo_mod_seterrno(mod, EMOD_NOMEM));
	}

	if (nvlist_add_string(fmristr, "fmri-string", buf) != 0) {
		topo_mod_strfree(mod, buf);
		nvlist_free(fmristr);
		return (topo_mod_seterrno(mod, EMOD_NOMEM));
	}
	topo_mod_strfree(mod, buf);
	*out = fmristr;

	return (0);
}
Example #13
0
static void
topo_snap_destroy(topo_hdl_t *thp)
{
	int i;
	ttree_t *tp;
	topo_walk_t *twp;
	tnode_t *root;
	topo_nodehash_t *nhp;
	topo_mod_t *mod;

	for (tp = topo_list_next(&thp->th_trees); tp != NULL;
	    tp = topo_list_next(tp)) {

		root = tp->tt_root;
		twp = tp->tt_walk;
		/*
		 * Clean-up tree nodes from the bottom-up
		 */
		if ((twp->tw_node = topo_child_first(root)) != NULL) {
			twp->tw_cb = topo_walk_destroy;
			topo_node_hold(root);
			topo_node_hold(twp->tw_node); /* released at walk end */
			(void) topo_walk_bottomup(twp, TOPO_WALK_CHILD);
			topo_node_rele(root);
		}

		/*
		 * Tidy-up the root node
		 */
		while ((nhp = topo_list_next(&root->tn_children)) != NULL) {
			for (i = 0; i < nhp->th_arrlen; i++) {
				assert(nhp->th_nodearr[i] == NULL);
			}
			mod = nhp->th_enum;
			topo_mod_strfree(mod, nhp->th_name);
			topo_mod_free(mod, nhp->th_nodearr,
			    nhp->th_arrlen * sizeof (tnode_t *));
			topo_list_delete(&root->tn_children, nhp);
			topo_mod_free(mod, nhp, sizeof (topo_nodehash_t));
			topo_mod_rele(mod);
		}

	}

	/*
	 * Clean-up our cached devinfo and prom tree handles.
	 */
	if (thp->th_di != DI_NODE_NIL) {
		di_fini(thp->th_di);
		thp->th_di = DI_NODE_NIL;
	}
	if (thp->th_pi != DI_PROM_HANDLE_NIL) {
		di_prom_fini(thp->th_pi);
		thp->th_pi = DI_PROM_HANDLE_NIL;
	}


	if (thp->th_uuid != NULL) {
		topo_hdl_free(thp, thp->th_uuid, TOPO_UUID_SIZE);
		thp->th_uuid = NULL;
	}
}
Example #14
0
tnode_t *
x86pi_gen_chassis(topo_mod_t *mod, tnode_t *t_parent, int smb_id, int instance)
{
	int			rv;
	smbios_info_t		ip;
	smbios_chassis_t	ch;
	x86pi_hcfmri_t		ch_hcfmri;
	tnode_t			*ch_node;
	char			*f = "x86pi_gen_chassis";
	smbios_hdl_t		*shp;

	shp = topo_mod_smbios(mod);
	if (shp == NULL) {
		topo_mod_dprintf(mod, "%s: failed to load SMBIOS\n", f);
		return (NULL);
	}

	/* init fmri struct */
	bzero(&ch_hcfmri, sizeof (x86pi_hcfmri_t));

	/* grab SMBIOS strings */
	rv = smbios_info_common(shp, smb_id, &ip);
	if (rv != 0) {
		return (NULL);
	}

	/* grab SMBIOS type 3 struct */
	rv = smbios_info_chassis(shp, smb_id, &ch);
	if (rv != 0) {
		return (NULL);
	}

	/* populate string entries */
	ch_hcfmri.serial_number = x86pi_cleanup_smbios_str(mod,
	    ip.smbi_serial, 0);
	ch_hcfmri.version = x86pi_cleanup_smbios_str(mod, ip.smbi_version, 0);
	ch_hcfmri.manufacturer = x86pi_cleanup_smbios_str(mod,
	    ip.smbi_manufacturer, 0);

	/* set hc_name and instance */
	ch_hcfmri.hc_name = topo_mod_strdup(mod, "chassis");
	ch_hcfmri.instance = instance;

	topo_mod_dprintf(mod, "%s: instance (%d)\n", f, ch_hcfmri.instance);
	topo_mod_dprintf(mod, "%s: hc name (%s)\n", f, ch_hcfmri.hc_name);
	topo_mod_dprintf(mod, "%s: Serial Number (%s)\n",
	    f, ch_hcfmri.serial_number);
	topo_mod_dprintf(mod, "%s: Version (%s)\n", f, ch_hcfmri.version);
	topo_mod_dprintf(mod, "%s: Manufacturer (%s)\n",
	    f, ch_hcfmri.manufacturer);

	/* create topo node */
	if (!instance) {
		/* First Chassis SMBIOS Record is Chassis topo instance 0 */
		rv = x86pi_enum_generic(mod, &ch_hcfmri, t_parent, NULL,
		    &ch_node, 0);
	} else {
		rv = x86pi_enum_generic(mod, &ch_hcfmri, t_parent, t_parent,
		    &ch_node, 0);
	}
	if (rv != 0) {
		topo_mod_dprintf(mod, "%s: failed to create %d tnode\n", f,
		    instance);
		return (NULL);
	}

	/* free up strings */
	if (ch_hcfmri.serial_number != NULL) {
		topo_mod_strfree(mod, (char *)ch_hcfmri.serial_number);
	}
	if (ch_hcfmri.version != NULL) {
		topo_mod_strfree(mod, (char *)ch_hcfmri.version);
	}
	if (ch_hcfmri.manufacturer != NULL) {
		topo_mod_strfree(mod, (char *)ch_hcfmri.manufacturer);
	}
	if (ch_hcfmri.hc_name != NULL) {
		topo_mod_strfree(mod, (char *)ch_hcfmri.hc_name);
	}

	return (ch_node);
}
Example #15
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);
}
Example #16
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;
}
Example #17
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);
}
Example #18
0
/* create the disk topo node */
static int
disk_tnode_create(topo_mod_t *mod, tnode_t *parent,
    dev_di_node_t *dnode, const char *name, topo_instance_t i, tnode_t **rval)
{
	int		len;
	nvlist_t	*fmri;
	tnode_t		*dtn;
	char		*part = NULL;
	nvlist_t	*auth;
	char		*mfg, *model, *firm, *serial;

	*rval = NULL;
	if (dnode != NULL) {
		mfg = topo_mod_clean_str(mod, dnode->ddn_mfg);
		model = topo_mod_clean_str(mod, dnode->ddn_model);
		firm = topo_mod_clean_str(mod, dnode->ddn_firm);
		serial = topo_mod_clean_str(mod, dnode->ddn_serial);
	} else {
		mfg = model = firm = serial = NULL;
	}

	/* form 'part=' of fmri as "<mfg>-<model>" */
	if (mfg != NULL && model != NULL) {
		len = strlen(mfg) + 1 + strlen(model) + 1;
		if ((part = topo_mod_alloc(mod, len)) != NULL)
			(void) snprintf(part, len, "%s-%s",
			    mfg, model);
	}

	auth = topo_mod_auth(mod, parent);
	fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i, NULL,
	    auth, part ? part : model, firm, serial);
	nvlist_free(auth);

	topo_mod_strfree(mod, part);
	topo_mod_strfree(mod, mfg);
	topo_mod_strfree(mod, model);
	topo_mod_strfree(mod, firm);
	topo_mod_strfree(mod, serial);

	if (fmri == NULL) {
		topo_mod_dprintf(mod, "disk_tnode_create: "
		    "hcfmri (%s%d/%s%d) error %s\n",
		    topo_node_name(parent), topo_node_instance(parent),
		    name, i, topo_strerror(topo_mod_errno(mod)));
		return (-1);
	}

	if ((dtn = topo_node_bind(mod, parent, name, i, fmri)) == NULL) {
		if (topo_mod_errno(mod) == EMOD_NODE_BOUND) {
			/*
			 * if disk 0 is already there then we're done
			 */
			nvlist_free(fmri);
			return (0);
		}
		topo_mod_dprintf(mod, "disk_tnode_create: "
		    "bind (%s%d/%s%d) error %s\n",
		    topo_node_name(parent), topo_node_instance(parent),
		    name, i, topo_strerror(topo_mod_errno(mod)));
		nvlist_free(fmri);
		return (-1);
	}
	nvlist_free(fmri);

	/* add the properties of the disk */
	if (disk_set_props(mod, parent, dtn, dnode) != 0) {
		topo_mod_dprintf(mod, "disk_tnode_create: "
		    "disk_set_props (%s%d/%s%d) error %s\n",
		    topo_node_name(parent), topo_node_instance(parent),
		    name, i, topo_strerror(topo_mod_errno(mod)));
		topo_node_unbind(dtn);
		return (-1);
	}

	if (dnode->ddn_devid != NULL &&
	    disk_add_temp_sensor(mod, dtn, dnode->ddn_devid) != 0) {
		topo_mod_dprintf(mod, "disk_tnode_create: failed to create "
		    "temperature sensor node on bay=%d/disk=0",
		    topo_node_instance(parent));
	}
	*rval = dtn;
	return (0);
}
Example #19
0
/*
 * For each visited cpu node, call the callback function with its ASRU.
 */
static int
cpu_walker(topo_mod_t *mod, tnode_t *node, void *pdata)
{
	struct cpu_walk_data *swdp = pdata;
	nvlist_t *asru;
	int err, rc;

	/*
	 * Terminate the walk if we reach start-node's sibling
	 */
	if (node != swdp->parent &&
	    topo_node_parent(node) == topo_node_parent(swdp->parent))
		return (TOPO_WALK_TERMINATE);

	if (strcmp(topo_node_name(node), CPU) != 0 &&
	    strcmp(topo_node_name(node), STRAND) != 0)
		return (TOPO_WALK_NEXT);

	if (topo_node_asru(node, &asru, NULL, &err) != 0) {
		swdp->fail++;
		return (TOPO_WALK_NEXT);
	}

	rc = swdp->func(swdp->lhp, asru);

	/*
	 * The "offline" and "online" counter are only useful for the "status"
	 * callback.
	 */
	if (rc == P_OFFLINE || rc == P_FAULTED) {
		swdp->offline++;
		err = 0;
	} else if (rc == P_ONLINE) {
		swdp->online++;
		err = 0;
	} else {
		swdp->fail++;
		err = errno;
	}

	/* dump out status info if debug is turned on. */
	if (getenv("TOPOCHIPDBG") != NULL ||
	    getenv("TOPOSUN4VPIDBG") != NULL) {
		const char *op;
		char *fmristr = NULL;

		if (swdp->func == ldom_fmri_retire)
			op = "retire";
		else if (swdp->func == ldom_fmri_unretire)
			op = "unretire";
		else if (swdp->func == ldom_fmri_status)
			op = "check status";
		else
			op = "unknown op";

		(void) topo_mod_nvl2str(mod, asru, &fmristr);
		topo_mod_dprintf(mod, "%s cpu (%s): rc = %d, err = %s\n",
		    op, fmristr == NULL ? "unknown fmri" : fmristr,
		    rc, strerror(err));
		if (fmristr != NULL)
			topo_mod_strfree(mod, fmristr);
	}

	nvlist_free(asru);
	return (TOPO_WALK_NEXT);
}
Example #20
0
static int
xaui_label_set(topo_mod_t *mod, tnode_t *node, topo_instance_t n, void *priv)
{
	const char *label = NULL;
	char *plat, *pp;
	int err;
	int i, p;

	(void) xaui_get_pri_label(mod, n, priv, (char **)&label);
	if (label == NULL) {
		topo_mod_dprintf(mod, "no PRI node for label\n");
		if (Phyxaui_Names == NULL)
			return (-1);

		if (topo_prop_get_string(node,
		    FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT, &plat, &err) < 0) {
			return (topo_mod_seterrno(mod, err));
		}
		/*
		 * Trim SUNW, from the platform name
		 */
		pp = strchr(plat, ',');
		if (pp == NULL)
			pp = plat;
		else
			++pp;

		for (p = 0; p < Phyxaui_Names->psn_nplats; p++) {
			if (strcmp(Phyxaui_Names->psn_names[p].pnm_platform,
			    pp) != 0)
				continue;
			for (i = 0; i < Phyxaui_Names->psn_names[p].pnm_nnames;
			    i++) {
				physnm_t ps;
				ps = Phyxaui_Names->psn_names[p].pnm_names[i];
				if (ps.ps_num == n) {
					label = ps.ps_label;
					break;
				}
			}
			break;
		}
		topo_mod_strfree(mod, plat);
	}

	if (label != NULL) {
		if (topo_prop_set_string(node, TOPO_PGROUP_PROTOCOL,
		    TOPO_PROP_LABEL, TOPO_PROP_IMMUTABLE,
		    label, &err) != 0) {
			if (freeprilabel == 1) {
				topo_mod_strfree(mod, (char *)label);
			}
			return (topo_mod_seterrno(mod, err));
		}
		if (freeprilabel == 1) {
			topo_mod_strfree(mod, (char *)label);
		}
	}

	return (0);
}