예제 #1
0
/*ARGSUSED*/
static int
DEVprop_set(tnode_t *tn, did_t *pd,
    const char *dpnm, const char *tpgrp, const char *tpnm)
{
	topo_mod_t *mp;
	char *dnpath;
	char *path, *fpath;
	int d, f;
	int err, e;

	mp = did_mod(pd);
	if ((dnpath = di_devfs_path(did_dinode(pd))) == NULL) {
		topo_mod_dprintf(mp, "NULL di_devfs_path.\n");
		return (topo_mod_seterrno(mp, ETOPO_PROP_NOENT));
	}
	if ((path = topo_mod_strdup(mp, dnpath)) == NULL) {
		di_devfs_path_free(dnpath);
		return (-1);
	}
	di_devfs_path_free(dnpath);

	/* The DEV path is modified for hostbridges */
	if (strcmp(topo_node_name(tn), HOSTBRIDGE) == 0) {
		fpath = dev_for_hostbridge(did_mod(pd), path);
	} else {
		did_BDF(pd, NULL, &d, &f);
		fpath = dev_path_fix(mp, path, d, f);
	}
	if (fpath == NULL)
		return (-1);
	e = topo_prop_set_string(tn,
	    tpgrp, tpnm, TOPO_PROP_IMMUTABLE, fpath, &err);
	topo_mod_strfree(mp, fpath);
	if (e != 0)
		return (topo_mod_seterrno(mp, err));
	return (0);
}
예제 #2
0
파일: ioboard.c 프로젝트: andreiw/polaris
/*ARGSUSED*/
static int
iob_enum(topo_mod_t *mp, tnode_t *pn, const char *name, topo_instance_t imin,
    topo_instance_t imax, void *notused)
{
	topo_mod_t *hbmod;
	int rv;
	did_hash_t *didhash;
	di_prom_handle_t promtree;

	if (strcmp(name, IOBOARD) != 0) {
		topo_mod_dprintf(mp,
		    "Currently only know how to enumerate %s components.\n",
		    IOBOARD);
		return (0);
	}

	if ((promtree = di_prom_init()) == DI_PROM_HANDLE_NIL) {
		topo_mod_dprintf(mp,
		    "Ioboard enumerator: di_prom_handle_init failed.\n");
		return (-1);
	}

	/*
	 * Load the hostbridge enumerator, we'll soon need it!
	 */
	if ((hbmod = hb_enumr_load(mp, pn)) == NULL) {
		di_prom_fini(promtree);
		return (-1);
	}

	if ((didhash = did_hash_init(mp)) == NULL) {
		topo_mod_dprintf(mp,
		    "Hash initialization for ioboard enumerator failed.\n");
		di_prom_fini(promtree);
		topo_mod_unload(hbmod);
		return (-1);
	}

	rv = platform_iob_enum(pn, imin, imax, didhash, promtree, mp);

	did_hash_fini(didhash);
	di_prom_fini(promtree);
	topo_mod_unload(hbmod);

	if (rv < 0)
		return (topo_mod_seterrno(mp, EMOD_PARTIAL_ENUM));
	else
		return (0);
}
예제 #3
0
/*ARGSUSED*/
static int
DRIVERprop_set(tnode_t *tn, did_t *pd,
    const char *dpnm, const char *tpgrp, const char *tpnm)
{
	char *dnm;
	int err;

	if ((dnm = di_driver_name(did_dinode(pd))) == NULL)
		return (0);
	if (topo_prop_set_string(tn,
	    tpgrp, tpnm, TOPO_PROP_IMMUTABLE, dnm, &err) < 0)
		return (topo_mod_seterrno(did_mod(pd), err));

	return (0);
}
예제 #4
0
/* ARGSUSED */
int
cpu_unusable(topo_mod_t *mod, tnode_t *node, topo_version_t version,
    nvlist_t *in, nvlist_t **out)
{
	struct cpu_walk_data swd;
	uint32_t rc;

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

	if (walk_cpus(mod, &swd, node, ldom_fmri_status) == -1)
		return (-1);

	rc = (swd.offline > 0 && swd.fail + swd.online == 0) ? 1 : 0;

	return (set_retnvl(mod, out, TOPO_METH_UNUSABLE_RET, rc));
}
예제 #5
0
/* ARGSUSED */
int
cpu_unretire(topo_mod_t *mod, tnode_t *node, topo_version_t version,
    nvlist_t *in, nvlist_t **out)
{
	struct cpu_walk_data swd;
	uint32_t rc;

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

	if (walk_cpus(mod, &swd, node, ldom_fmri_unretire) == -1)
		return (-1);

	rc = swd.fail > 0 ? FMD_AGENT_RETIRE_FAIL : FMD_AGENT_RETIRE_DONE;

	return (set_retnvl(mod, out, TOPO_METH_UNRETIRE_RET, rc));
}
예제 #6
0
/*ARGSUSED*/
static int
BDF_set(tnode_t *tn, did_t *pd, const char *dpnm, const char *tpgrp,
    const char *tpnm)
{
	int bdf;
	char str[23]; /* '0x' + sizeof (UINT64_MAX) + '\0' */
	int e;

	if ((bdf = did_bdf(pd)) <= 0)
		return (0);

	(void) snprintf(str, 23, "0x%x", bdf);
	if (topo_prop_set_string(tn,
	    tpgrp, tpnm, TOPO_PROP_IMMUTABLE, str, &e) < 0)
		return (topo_mod_seterrno(did_mod(pd), e));
	return (0);
}
예제 #7
0
/*
 * Calculate a generic FRU for the given node.  If the node is not a FRU,
 * then inherit the FRU data from the nodes parent.
 */
int
x86pi_set_frufmri(topo_mod_t *mod, x86pi_hcfmri_t *hcfmri, tnode_t *t_parent,
    tnode_t *t_node, int flag)
{
	int		result;
	int		err;

	nvlist_t	*auth = NULL;
	nvlist_t	*frufmri = NULL;

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

	/*
	 * Determine if this node is a FRU
	 */
	if (!(flag & X86PI_ENUM_FRU)) {
		/* This node is not a FRU.  Inherit from parent and return */
		(void) topo_node_fru_set(t_node, NULL, 0, &result);
		return (0);
	}

	/*
	 * This node is a FRU.  Create an FMRI.
	 */
	auth	= topo_mod_auth(mod, t_parent);
	frufmri	= topo_mod_hcfmri(mod, t_parent, FM_HC_SCHEME_VERSION,
	    hcfmri->hc_name, hcfmri->instance, NULL, auth,
	    hcfmri->part_number, hcfmri->version, hcfmri->serial_number);
	if (frufmri == NULL) {
		topo_mod_dprintf(mod, "failed to create FRU: %s\n",
		    topo_strerror(topo_mod_errno(mod)));
	}
	nvlist_free(auth);

	/* Set the FRU, whether NULL or not */
	result = topo_node_fru_set(t_node, frufmri, 0, &err);
	if (result != 0)  {
		(void) topo_mod_seterrno(mod, err);
	}
	nvlist_free(frufmri);

	return (result);
}
예제 #8
0
파일: sw.c 프로젝트: NanXiao/illumos-joyent
int
sw_init(topo_mod_t *mod, topo_version_t version)
{
	if (getenv("TOPOSWDEBUG"))
		topo_mod_setdebug(mod);
	topo_mod_dprintf(mod, "initializing sw builtin\n");

	if (version != SW_VERSION)
		return (topo_mod_seterrno(mod, EMOD_VER_NEW));

	if (topo_mod_register(mod, &sw_info, TOPO_VERSION) != 0) {
		topo_mod_dprintf(mod, "failed to register sw_info: "
		    "%s\n", topo_mod_errmsg(mod));
		return (-1);
	}

	return (0);
}
예제 #9
0
파일: topo_node.c 프로젝트: andreiw/polaris
static tnode_t *
node_bind_seterror(topo_mod_t *mod, tnode_t *pnode, tnode_t *node, int err)
{
	topo_node_unlock(pnode);

	(void) topo_mod_seterrno(mod, err);

	if (node == NULL)
		return (NULL);

	topo_dprintf(TOPO_DBG_ERR, "unable to bind %s=%d: "
	    "%s\n", (node->tn_name != NULL ? node->tn_name : "unknown"),
	    node->tn_instance, topo_strerror(err));

	topo_node_lock(node); /* expected to be locked */
	topo_node_destroy(node);

	return (NULL);
}
예제 #10
0
파일: topo_node.c 프로젝트: andreiw/polaris
static int
node_create_seterror(topo_mod_t *mod, tnode_t *pnode, topo_nodehash_t *nhp,
    int err)
{
	topo_node_unlock(pnode);

	topo_dprintf(TOPO_DBG_ERR, "unable to insert child:"
	    "%s\n", topo_strerror(err));

	if (nhp != NULL) {
		if (nhp->th_name != NULL)
			topo_mod_strfree(mod, nhp->th_name);
		if (nhp->th_nodearr != NULL) {
			topo_mod_free(mod, nhp->th_nodearr,
			    nhp->th_arrlen * sizeof (tnode_t *));
		}
		topo_mod_free(mod, nhp, sizeof (topo_nodehash_t));
	}

	return (topo_mod_seterrno(mod, err));
}
예제 #11
0
static int
dimm_page_unusable(topo_mod_t *mod, tnode_t *node, topo_version_t version,
    nvlist_t *in, nvlist_t **out)
{
	uint32_t rc = 0;
	nvlist_t *asru;
	int err;

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

	if (pi_lhp != NULL && is_page_fmri(in) &&
	    topo_node_asru(node, &asru, in, &err) == 0) {
		err = ldom_fmri_status(pi_lhp, asru);

		if (err == 0 || err == EINVAL)
			rc = 1;
		nvlist_free(asru);
	}

	return (set_retnvl(mod, out, TOPO_METH_UNUSABLE_RET, rc));
}
예제 #12
0
static int
AADDR_set(tnode_t *tn, did_t *pd, const char *dpnm, const char *tpgrp,
    const char *tpnm)
{
	topo_mod_t *mp;
	uchar_t *typbuf;
	int sz = -1;
	int err, e;

	if (di_bytes_get(did_mod(pd), did_dinode(pd), dpnm, &sz, &typbuf) < 0)
		return (0);

	mp = did_mod(pd);

	e = topo_prop_set_uint32_array(tn, tpgrp, tpnm, TOPO_PROP_IMMUTABLE,
	    /*LINTED*/
	    (uint32_t *)typbuf, sz/4, &err);

	if (e != 0)
		return (topo_mod_seterrno(mp, err));
	return (0);
}
예제 #13
0
int
platform_pci_label(topo_mod_t *mod, tnode_t *node, nvlist_t *in,
    nvlist_t **out)
{
	int	result;
	int	err;
	int	locsiz = 0;
	uchar_t	*loc = NULL;
	char	*nac = NULL;

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

	*out = NULL;
	result = di_bytes_get(mod, topo_node_getspecific(node),
	    PI_PROP_CHASSIS_LOCATION_NAME, &locsiz, &loc);
	if (result == -1 || locsiz < 0) {
		topo_mod_dprintf(mod, "platform_pci_label: %s not found (%s)\n",
		    PI_PROP_CHASSIS_LOCATION_NAME, strerror(errno));

		/* Invoke the generic label generator for this node */
		return (pci_label_cmn(mod, node, in, out));
	}

	/*
	 * We have crossed a FRU boundary.  Use the value in the
	 * chassis-location-name property as the node label.
	 */
	nac = alloca(locsiz+1);
	(void) memset(nac, 0, locsiz+1);
	(void) memcpy(nac, loc, locsiz);
	result = topo_node_label_set(node, nac, &err);
	if (result < 0) {
		if (err != ETOPO_PROP_NOENT) {
			return (topo_mod_seterrno(mod, err));
		}
	}

	return (0);
}
예제 #14
0
static int
set_methregister_error(topo_mod_t *mod, tnode_t *node, topo_imethod_t *mp,
    int err)
{
	if (mp != NULL) {
		topo_list_delete(&node->tn_methods, mp);
		if (mp->tim_name != NULL)
			topo_mod_strfree(mod, mp->tim_name);
		if (mp->tim_desc != NULL)
			topo_mod_strfree(mod, mp->tim_desc);

		topo_mod_free(mod, mp, sizeof (topo_imethod_t));
	}

	topo_node_unlock(node);

	topo_dprintf(mod->tm_hdl, TOPO_DBG_ERR,
	    "method registration failed for %s: %s\n",
	    mod->tm_name, topo_strerror(err));

	return (topo_mod_seterrno(mod, err));
}
예제 #15
0
static int
dimm_page_unretire(topo_mod_t *mod, tnode_t *node, topo_version_t version,
    nvlist_t *in, nvlist_t **out)
{
	uint32_t rc = FMD_AGENT_RETIRE_FAIL;
	nvlist_t *asru;
	int err;

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

	if (pi_lhp != NULL && is_page_fmri(in) &&
	    topo_node_asru(node, &asru, in, &err) == 0) {
		err = ldom_fmri_unretire(pi_lhp, asru);

		if (err == 0 || err == EIO)
			rc = FMD_AGENT_RETIRE_DONE;
		nvlist_free(asru);
	}

	return (set_retnvl(mod, out, TOPO_METH_UNRETIRE_RET, rc));
}
예제 #16
0
/*ARGSUSED*/
static int
EXCAP_set(tnode_t *tn, did_t *pd,
    const char *dpnm, const char *tpgrp, const char *tpnm)
{
	int excap = did_excap(pd);
	int err;
	int e = 0;

	switch (excap & PCIE_PCIECAP_DEV_TYPE_MASK) {
	case PCIE_PCIECAP_DEV_TYPE_ROOT:
		e = topo_prop_set_string(tn, TOPO_PGROUP_PCI,
		    TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCIEX_ROOT, &err);
		break;
	case PCIE_PCIECAP_DEV_TYPE_UP:
		e = topo_prop_set_string(tn, TOPO_PGROUP_PCI,
		    TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCIEX_SWUP, &err);
		break;
	case PCIE_PCIECAP_DEV_TYPE_DOWN:
		e = topo_prop_set_string(tn, TOPO_PGROUP_PCI,
		    TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCIEX_SWDWN, &err);
		break;
	case PCIE_PCIECAP_DEV_TYPE_PCI2PCIE:
		e = topo_prop_set_string(tn, TOPO_PGROUP_PCI,
		    TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCIEX_BUS, &err);
		break;
	case PCIE_PCIECAP_DEV_TYPE_PCIE2PCI:
		e = topo_prop_set_string(tn, TOPO_PGROUP_PCI,
		    TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCI_BUS, &err);
		break;
	case PCIE_PCIECAP_DEV_TYPE_PCIE_DEV:
		e = topo_prop_set_string(tn, TOPO_PGROUP_PCI,
		    TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCIEX_DEVICE, &err);
		break;
	}
	if (e != 0)
		return (topo_mod_seterrno(did_mod(pd), err));
	return (0);
}
예제 #17
0
static int
niufn_instantiate(tnode_t *parent, const char *name, di_node_t pnode,
	topo_mod_t *mod)
{
	di_node_t sib;
	tnode_t *ntn;
	topo_instance_t inst;

	if (strcmp(name, NIUFN) != 0) {
		topo_mod_dprintf(mod,
		    "Currently only know how to enumerate %s components.\n",
		    NIUFN);
		return (0);
	}

	sib = di_child_node(pnode);
	while (sib != DI_NODE_NIL) {
		if (niufn_instance_get(mod, sib, &inst) != 0) {
			topo_mod_dprintf(mod, "Enumeration of %s "
			    "instance failed.\n", NIUFN);
			sib = di_sibling_node(sib);
			continue;
		}
		if ((ntn = niufn_declare(parent, NIUFN, inst, sib, mod))
		    == NULL) {
			topo_mod_dprintf(mod, "Enumeration of %s=%d "
			    "failed: %s\n", NIUFN, inst,
			    topo_strerror(topo_mod_errno(mod)));
			return (-1);
		}
		if (topo_mod_enumerate(mod,
		    ntn, XAUI, XAUI, inst, inst, sib) != 0) {
			return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
		}
		sib = di_sibling_node(sib);
	}
	return (0);
}
예제 #18
0
static int
platform_pci_fru_location(topo_mod_t *mod, tnode_t *node, uchar_t *loc,
    int locsiz)
{
	int		err;
	tnode_t		*parent;
	tnode_t		*top;
	topo_walk_t	*wp;
	_pci_fru_t	walkdata;

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

	/* Find the root node */
	top = node;
	while ((parent = topo_node_parent(top)) != NULL) {
		top = parent;
	}
	walkdata.node = node;
	walkdata.locsiz = locsiz;
	walkdata.location = alloca(locsiz+1);
	(void) memset(walkdata.location, 0, locsiz+1);
	(void) memcpy(walkdata.location, loc, locsiz);

	/* Create a walker starting at the root node */
	wp = topo_mod_walk_init(mod, top, platform_pci_fru_cb, &walkdata, &err);
	if (wp == NULL) {
		return (topo_mod_seterrno(mod, err));
	}

	/*
	 * Walk the tree breadth first to hopefully avoid visiting too many
	 * nodes while searching for the node with the appropriate FMRI.
	 */
	(void) topo_walk_step(wp, TOPO_WALK_SIBLING);
	topo_walk_fini(wp);

	return (0);
}
예제 #19
0
/*ARGSUSED*/
static int
moduleprop_set(tnode_t *tn, di_node_t dn,
	const char *tpgrp, const char *tpnm, topo_mod_t *mod)
{
	nvlist_t *module;
	char *dnm;
	int err;

	if ((dnm = di_driver_name(dn)) == NULL)
		return (0);

	if ((module = topo_mod_modfmri(mod, FM_MOD_SCHEME_VERSION, dnm))
	    == NULL)
		return (0); /* driver maybe detached, return success */

	if (topo_prop_set_fmri(tn, tpgrp, tpnm, TOPO_PROP_IMMUTABLE, module,
	    &err) < 0) {
		nvlist_free(module);
		return (topo_mod_seterrno(mod, err));
	}
	nvlist_free(module);
	return (0);
}
예제 #20
0
int
_topo_init(topo_mod_t *modhdl, topo_version_t version)
{
	/*
	 * Turn on module debugging output
	 */
	if (getenv("TOPOHBDBG") != NULL)
		topo_mod_setdebug(modhdl);
	topo_mod_dprintf(modhdl, "initializing hostbridge enumerator\n");

	if (version != HB_ENUMR_VERS)
		return (topo_mod_seterrno(modhdl, EMOD_VER_NEW));

	if (topo_mod_register(modhdl, &Hb_info, TOPO_VERSION) < 0) {
		topo_mod_dprintf(modhdl, "hostbridge registration failed: %s\n",
		    topo_mod_errmsg(modhdl));
		return (-1); /* mod errno already set */
	}

	topo_mod_dprintf(modhdl, "Hostbridge enumr initd\n");

	return (0);
}
예제 #21
0
static nvlist_t *
mem_fmri_create(topo_mod_t *mod, char *serial, char *label)
{
	int err;
	nvlist_t *fmri;

	if (topo_mod_nvalloc(mod, &fmri, NV_UNIQUE_NAME) != 0)
		return (NULL);
	err = nvlist_add_uint8(fmri, FM_VERSION, FM_MEM_SCHEME_VERSION);
	err |= nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_MEM);
	if (serial != NULL)
		err |= nvlist_add_string_array(fmri, FM_FMRI_MEM_SERIAL_ID,
		    &serial, 1);
	if (label != NULL)
		err |= nvlist_add_string(fmri, FM_FMRI_MEM_UNUM, label);
	if (err != 0) {
		nvlist_free(fmri);
		(void) topo_mod_seterrno(mod, EMOD_FMRI_NVL);
		return (NULL);
	}

	return (fmri);
}
예제 #22
0
/* ARGSUSED */
int
cpu_service_state(topo_mod_t *mod, tnode_t *node, topo_version_t version,
    nvlist_t *in, nvlist_t **out)
{
	struct cpu_walk_data swd;
	uint32_t rc;

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

	if (walk_cpus(mod, &swd, node, ldom_fmri_status) == -1)
		return (-1);

	if (swd.fail > 0)
		rc = FMD_SERVICE_STATE_UNKNOWN;
	else if (swd.offline > 0)
		rc = swd.online > 0 ? FMD_SERVICE_STATE_DEGRADED :
		    FMD_SERVICE_STATE_UNUSABLE;
	else
		rc = FMD_SERVICE_STATE_OK;

	return (set_retnvl(mod, out, TOPO_METH_SERVICE_STATE_RET, rc));
}
예제 #23
0
/*ARGSUSED*/
static int
create_chips(topo_mod_t *mod, tnode_t *pnode, const char *name,
    topo_instance_t min, topo_instance_t max, void *arg, nvlist_t *auth,
    int mc_offchip)
{
	fmd_agent_hdl_t *hdl;
	nvlist_t **cpus;
	int nerr = 0;
	uint_t i, ncpu;

	if (strcmp(name, CHIP_NODE_NAME) != 0)
		return (0);

	if ((hdl = fmd_agent_open(FMD_AGENT_VERSION)) == NULL)
		return (-1);
	if (fmd_agent_physcpu_info(hdl, &cpus, &ncpu) != 0) {
		whinge(mod, NULL, "create_chip: fmd_agent_physcpu_info "
		    "failed: %s\n", fmd_agent_errmsg(hdl));
		fmd_agent_close(hdl);
		return (-1);
	}
	fmd_agent_close(hdl);

	for (i = 0; i < ncpu; i++) {
		nerr -= create_chip(mod, pnode, min, max, cpus[i], auth,
		    mc_offchip);
		nvlist_free(cpus[i]);
	}
	umem_free(cpus, sizeof (nvlist_t *) * ncpu);

	if (nerr == 0) {
		return (0);
	} else {
		(void) topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM);
		return (-1);
	}
}
예제 #24
0
static int
dimm_page_service_state(topo_mod_t *mod, tnode_t *node, topo_version_t version,
    nvlist_t *in, nvlist_t **out)
{
	uint32_t rc = FMD_SERVICE_STATE_OK;
	nvlist_t *asru;
	int err;

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

	if (pi_lhp != NULL && is_page_fmri(in) &&
	    topo_node_asru(node, &asru, in, &err) == 0) {
		err = ldom_fmri_status(pi_lhp, asru);

		if (err == 0 || err == EINVAL)
			rc = FMD_SERVICE_STATE_UNUSABLE;
		else if (err == EAGAIN)
			rc = FMD_SERVICE_STATE_ISOLATE_PENDING;
		nvlist_free(asru);
	}

	return (set_retnvl(mod, out, TOPO_METH_SERVICE_STATE_RET, rc));
}
예제 #25
0
/*
 * Called by libtopo when the topo module is loaded.
 */
void
_topo_init(topo_mod_t *mod, topo_version_t version)
{
	int		result;
	char		isa[MAXNAMELEN];

	if (getenv("TOPOSUN4VPIDBG") != NULL) {
		/* Debugging is requested for this module */
		topo_mod_setdebug(mod);
	}
	topo_mod_dprintf(mod, "sun4vpi module initializing.\n");

	if (version != TOPO_VERSION) {
		(void) topo_mod_seterrno(mod, EMOD_VER_NEW);
		topo_mod_dprintf(mod, "incompatible topo version %d\n",
		    version);
		return;
	}

	/* Verify that this is a SUN4V architecture machine */
	(void) sysinfo(SI_MACHINE, isa, MAXNAMELEN);
	if (strncmp(isa, "sun4v", MAXNAMELEN) != 0) {
		topo_mod_dprintf(mod, "not sun4v architecture: %s\n", isa);
		return;
	}

	result = topo_mod_register(mod, &pi_modinfo, TOPO_VERSION);
	if (result < 0) {
		topo_mod_dprintf(mod, "registration failed: %s\n",
		    topo_mod_errmsg(mod));

		/* module errno already set */
		return;
	}
	topo_mod_dprintf(mod, "module ready.\n");
}
예제 #26
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);
}
예제 #27
0
/*
 * Calculate the system information for a node.  Inherit the data if
 * possible, but always create an appropriate property group.
 */
int
x86pi_set_system(topo_mod_t *mod, tnode_t *t_node)
{
	int		result;
	int		err;
	struct utsname	uts;
	char		isa[MAXNAMELEN];

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

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

	result = topo_prop_inherit(t_node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA,
	    &err);
	if (result != 0 && err != ETOPO_PROP_DEFD) {
		isa[0] = '\0';
		result = sysinfo(SI_ARCHITECTURE, isa, sizeof (isa));
		if (result == -1) {
			/* Preserve the error and continue */
			topo_mod_dprintf(mod, "x86pi_set_system: failed to "
			    "read SI_ARCHITECTURE: %d\n", errno);
		}
		if (strnlen(isa, MAXNAMELEN) > 0) {
			result = topo_prop_set_string(t_node,
			    TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA,
			    TOPO_PROP_IMMUTABLE, isa, &err);
			if (result != 0) {
				/* Preserve the error and continue */
				(void) topo_mod_seterrno(mod, err);
				topo_mod_dprintf(mod,
				    "x86pi_set_auth: failed to "
				    "set property %s (%d) : %s\n",
				    TOPO_PROP_ISA, err, topo_strerror(err));
			}
		}
	}

	result = topo_prop_inherit(t_node, TOPO_PGROUP_SYSTEM,
	    TOPO_PROP_MACHINE, &err);
	if (result != 0 && err != ETOPO_PROP_DEFD) {
		result = uname(&uts);
		if (result == -1) {
			/* Preserve the error and continue */
			(void) topo_mod_seterrno(mod, errno);
			topo_mod_dprintf(mod, "x86pi_set_system: failed to "
			    "read uname: %d\n", errno);
		}
		if (strnlen(uts.machine, sizeof (uts.machine)) > 0) {
			result = topo_prop_set_string(t_node,
			    TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE,
			    TOPO_PROP_IMMUTABLE, uts.machine, &err);
			if (result != 0) {
				/* Preserve the error and continue */
				(void) topo_mod_seterrno(mod, err);
				topo_mod_dprintf(mod,
				    "x86pi_set_auth: failed to "
				    "set property %s (%d) : %s\n",
				    TOPO_PROP_MACHINE, err, topo_strerror(err));
			}
		}
	}

	return (0);
}
예제 #28
0
/* Topo Methods */
static int
mem_asru_compute(topo_mod_t *mod, tnode_t *node, topo_version_t version,
    nvlist_t *in, nvlist_t **out)
{
	nvlist_t *asru, *pargs, *args, *hcsp;
	int err;
	char *serial = NULL, *label = NULL;
	uint64_t pa, offset;

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

	if (strcmp(topo_node_name(node), DIMM) != 0)
		return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));

	pargs = NULL;

	if (nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &pargs) == 0)
		(void) nvlist_lookup_string(pargs, FM_FMRI_HC_SERIAL_ID,
		    &serial);
	if (serial == NULL &&
	    nvlist_lookup_nvlist(in, TOPO_PROP_ARGS, &args) == 0)
		(void) nvlist_lookup_string(args, FM_FMRI_HC_SERIAL_ID,
		    &serial);

	(void) topo_node_label(node, &label, &err);

	asru = mem_fmri_create(mod, serial, label);

	if (label != NULL)
		topo_mod_strfree(mod, label);

	if (asru == NULL)
		return (topo_mod_seterrno(mod, EMOD_NOMEM));

	err = 0;

	/*
	 * For a memory page, 'in' includes an hc-specific member which
	 * specifies physaddr and/or offset. Set them in asru as well.
	 */
	if (pargs && nvlist_lookup_nvlist(pargs,
	    FM_FMRI_HC_SPECIFIC, &hcsp) == 0) {
		if (nvlist_lookup_uint64(hcsp,
		    FM_FMRI_HC_SPECIFIC_PHYSADDR, &pa) == 0)
			err += nvlist_add_uint64(asru, FM_FMRI_MEM_PHYSADDR,
			    pa);
		if (nvlist_lookup_uint64(hcsp,
		    FM_FMRI_HC_SPECIFIC_OFFSET, &offset) == 0)
			err += nvlist_add_uint64(asru, FM_FMRI_MEM_OFFSET,
			    offset);
	}


	if (err != 0 || topo_mod_nvalloc(mod, out, NV_UNIQUE_NAME) < 0) {
		nvlist_free(asru);
		return (topo_mod_seterrno(mod, EMOD_NOMEM));
	}

	err = nvlist_add_string(*out, TOPO_PROP_VAL_NAME, TOPO_PROP_ASRU);
	err |= nvlist_add_uint32(*out, TOPO_PROP_VAL_TYPE, TOPO_TYPE_FMRI);
	err |= nvlist_add_nvlist(*out, TOPO_PROP_VAL_VAL, asru);
	nvlist_free(asru);

	if (err != 0) {
		nvlist_free(*out);
		*out = NULL;
		return (topo_mod_seterrno(mod, EMOD_NVL_INVAL));
	}

	return (0);
}
예제 #29
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);
}
예제 #30
0
/*ARGSUSED*/
static int
FRU_set(tnode_t *tn, did_t *pd,
    const char *dpnm, const char *tpgrp, const char *tpnm)
{
	topo_mod_t *mp;
	char *nm;
	int e = 0, err = 0;

	nm = topo_node_name(tn);
	mp = did_mod(pd);

	/*
	 * If this is a PCIEX_BUS and its parent is a PCIEX_ROOT,
	 * check for a CPUBOARD predecessor.  If found, inherit its
	 * parent's FRU.  Otherwise, continue with FRU set.
	 */
	if ((strcmp(nm, PCIEX_BUS) == 0) &&
	    (strcmp(topo_node_name(topo_node_parent(tn)), PCIEX_ROOT) == 0)) {

		if (use_predecessor_fru(tn, CPUBOARD) == 0)
			return (0);
	}
	/*
	 * If this topology node represents something other than an
	 * ioboard or a device that implements a slot, inherit the
	 * parent's FRU value.  If there is no label, inherit our
	 * parent's FRU value.  Otherwise, munge up an fmri based on
	 * the label.
	 */
	if (strcmp(nm, IOBOARD) != 0 && strcmp(nm, PCI_DEVICE) != 0 &&
	    strcmp(nm, PCIEX_DEVICE) != 0 && strcmp(nm, PCIEX_BUS) != 0) {
		(void) topo_node_fru_set(tn, NULL, 0, &e);
		return (0);
	}

	/*
	 * If ioboard, set fru fmri to hc fmri
	 */
	if (strcmp(nm, IOBOARD) == 0) {
		e = FRU_fmri_set(mp, tn);
		return (e);
	} else if (strcmp(nm, PCI_DEVICE) == 0 ||
	    strcmp(nm, PCIEX_DEVICE) == 0 || strcmp(nm, PCIEX_BUS) == 0) {
		nvlist_t *in, *out;

		mp = did_mod(pd);
		if (topo_mod_nvalloc(mp, &in, NV_UNIQUE_NAME) != 0)
			return (topo_mod_seterrno(mp, EMOD_FMRI_NVL));
		if (nvlist_add_uint64(in, "nv1", (uintptr_t)pd) != 0) {
			nvlist_free(in);
			return (topo_mod_seterrno(mp, EMOD_NOMEM));
		}
		if (topo_method_invoke(tn,
		    TOPO_METH_FRU_COMPUTE, TOPO_METH_FRU_COMPUTE_VERSION,
		    in, &out, &err) != 0) {
			nvlist_free(in);
			return (topo_mod_seterrno(mp, err));
		}
		nvlist_free(in);
		(void) topo_node_fru_set(tn, out, 0, &err);
		if (out != NULL)
			nvlist_free(out);
	} else
		(void) topo_node_fru_set(tn, NULL, 0, &err);

	return (0);
}