Beispiel #1
0
/*ARGSUSED*/
static int
MODULEprop_set(tnode_t *tn, did_t *pd,
    const char *dpnm, const char *tpgrp, const char *tpnm)
{
	nvlist_t *mod;
	topo_mod_t *mp;
	char *dnm;
	int err;

	if ((dnm = di_driver_name(did_dinode(pd))) == NULL)
		return (0);

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

	if (topo_prop_set_fmri(tn, tpgrp, tpnm, TOPO_PROP_IMMUTABLE, mod,
	    &err) < 0) {
		nvlist_free(mod);
		return (topo_mod_seterrno(mp, err));
	}
	nvlist_free(mod);

	return (0);
}
Beispiel #2
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);
}
Beispiel #3
0
tnode_t *
topo_node_bind(topo_mod_t *mod, tnode_t *pnode, const char *name,
    topo_instance_t inst, nvlist_t *fmri, void *priv)
{
	int h, err;
	tnode_t *node;
	topo_nodehash_t *nhp;

	topo_node_lock(pnode);
	for (nhp = topo_list_next(&pnode->tn_children); nhp != NULL;
	    nhp = topo_list_next(nhp)) {
		if (strcmp(nhp->th_name, name) == 0) {

			if (inst > nhp->th_range.tr_max ||
			    inst < nhp->th_range.tr_min)
				return (node_bind_seterror(mod, pnode, NULL,
				    ETOPO_NODE_INVAL));

			h = topo_node_hash(nhp, inst);
			if (nhp->th_nodearr[h] != NULL)
				return (node_bind_seterror(mod, pnode, NULL,
				    ETOPO_NODE_BOUND));
			else
				break;

		}
	}

	if (nhp == NULL)
		return (node_bind_seterror(mod, pnode, NULL, ETOPO_NODE_NOENT));

	if ((node = topo_mod_zalloc(mod, sizeof (tnode_t))) == NULL)
		return (node_bind_seterror(mod, pnode, NULL, ETOPO_NOMEM));

	(void) pthread_mutex_init(&node->tn_lock, NULL);

	node->tn_enum = mod;
	node->tn_hdl = mod->tm_hdl;
	node->tn_parent = pnode;
	node->tn_name = nhp->th_name;
	node->tn_instance = inst;
	node->tn_phash = nhp;
	node->tn_refs = 0;

	/* Ref count module that bound this node */
	topo_mod_hold(mod);

	if (fmri == NULL)
		return (node_bind_seterror(mod, pnode, node, ETOPO_NODE_INVAL));

	if (topo_pgroup_create(node, TOPO_PGROUP_PROTOCOL,
	    TOPO_STABILITY_PRIVATE, &err) < 0)
		return (node_bind_seterror(mod, pnode, node, err));

	if (topo_prop_set_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_RESOURCE,
	    TOPO_PROP_SET_ONCE, fmri, &err) < 0)
		return (node_bind_seterror(mod, pnode, node, err));

	topo_dprintf(TOPO_DBG_MOD, "node bound %s=%d\n", node->tn_name,
	    node->tn_instance);

	node->tn_state |= TOPO_NODE_BOUND;
	node->tn_priv = priv;

	topo_node_hold(node);
	nhp->th_nodearr[h] = node;
	++pnode->tn_refs;
	topo_node_unlock(pnode);

	if (topo_pgroup_create(node, TOPO_PGROUP_SYSTEM,
	    TOPO_STABILITY_PRIVATE, &err) == 0) {
		(void) topo_prop_inherit(node, TOPO_PGROUP_SYSTEM,
		    TOPO_PROP_PLATFORM, &err);
		(void) topo_prop_inherit(node, TOPO_PGROUP_SYSTEM,
		    TOPO_PROP_ISA, &err);
		(void) topo_prop_inherit(node, TOPO_PGROUP_SYSTEM,
		    TOPO_PROP_MACHINE, &err);
	}

	return (node);
}
Beispiel #4
0
/*
 * Create a root complex node.
 */
static tnode_t *
opl_rc_node_create(topo_mod_t *mp, tnode_t *parent, di_node_t dnode, int inst)
{
	int err;
	tnode_t *rcn;
	const char *slot_name;
	char *dnpath;
	nvlist_t *mod;

	rcn = opl_node_create(mp, parent, PCIEX_ROOT, inst, (void *)dnode);
	if (rcn == NULL) {
		return (NULL);
	}

	/*
	 * If this root complex connects to a slot, it will have a
	 * slot-names property.
	 */
	slot_name = opl_get_slot_name(mp, dnode);
	if (slot_name) {
		char fru_str[64];
		nvlist_t *fru_fmri;
		/* Add FRU fmri */
		(void) snprintf(fru_str, sizeof (fru_str), "hc:///component=%s",
		    slot_name);
		if (topo_mod_str2nvl(mp, fru_str, &fru_fmri) == 0) {
			(void) topo_node_fru_set(rcn, fru_fmri, 0, &err);
			nvlist_free(fru_fmri);
		}
		/* Add label */
		(void) topo_node_label_set(rcn, (char *)slot_name, &err);
	} else {
		/* Inherit parent FRU's label */
		(void) topo_node_fru_set(rcn, NULL, 0, &err);
		(void) topo_node_label_set(rcn, NULL, &err);
	}

	/*
	 * Set ASRU to be the dev-scheme ASRU
	 */
	if ((dnpath = di_devfs_path(dnode)) != NULL) {
		nvlist_t *fmri;

		fmri = topo_mod_devfmri(mp, FM_DEV_SCHEME_VERSION,
		    dnpath, NULL);
		if (fmri == NULL) {
			topo_mod_dprintf(mp,
			    "dev:///%s fmri creation failed.\n",
			    dnpath);
			(void) topo_mod_seterrno(mp, err);
			di_devfs_path_free(dnpath);
			return (NULL);
		}
		if (topo_node_asru_set(rcn, fmri, 0, &err) < 0) {
			topo_mod_dprintf(mp, "topo_node_asru_set failed\n");
			(void) topo_mod_seterrno(mp, err);
			nvlist_free(fmri);
			di_devfs_path_free(dnpath);
			return (NULL);
		}
		nvlist_free(fmri);
	} else {
		topo_mod_dprintf(mp, "NULL di_devfs_path.\n");
	}

	/*
	 * Set pciexrc properties for root complex nodes
	 */

	/* Add the io and pci property groups */
	if (topo_pgroup_create(rcn, &io_pgroup, &err) < 0) {
		topo_mod_dprintf(mp, "topo_pgroup_create failed\n");
		di_devfs_path_free(dnpath);
		(void) topo_mod_seterrno(mp, err);
		return (NULL);
	}
	if (topo_pgroup_create(rcn, &pci_pgroup, &err) < 0) {
		topo_mod_dprintf(mp, "topo_pgroup_create failed\n");
		di_devfs_path_free(dnpath);
		(void) topo_mod_seterrno(mp, err);
		return (NULL);
	}
	/* Add the devfs path property */
	if (dnpath) {
		if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DEV,
		    TOPO_PROP_IMMUTABLE, dnpath, &err) != 0) {
			topo_mod_dprintf(mp, "Failed to set DEV property\n");
			di_devfs_path_free(dnpath);
			(void) topo_mod_seterrno(mp, err);
		}
		di_devfs_path_free(dnpath);
	}
	/* Oberon device type is always "pciex" */
	if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DEVTYPE,
	    TOPO_PROP_IMMUTABLE, OPL_PX_DEVTYPE, &err) != 0) {
		topo_mod_dprintf(mp, "Failed to set DEVTYPE property\n");
	}
	/* Oberon driver is always "px" */
	if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DRIVER,
	    TOPO_PROP_IMMUTABLE, OPL_PX_DRV, &err) != 0) {
		topo_mod_dprintf(mp, "Failed to set DRIVER property\n");
	}
	if ((mod = topo_mod_modfmri(mp, FM_MOD_SCHEME_VERSION, OPL_PX_DRV))
	    == NULL || topo_prop_set_fmri(rcn, TOPO_PGROUP_IO,
	    TOPO_IO_MODULE, TOPO_PROP_IMMUTABLE, mod,  &err) != 0) {
		topo_mod_dprintf(mp, "Failed to set MODULE property\n");
	}
	nvlist_free(mod);

	/* This is a PCIEX Root Complex */
	if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI, TOPO_PCI_EXCAP,
	    TOPO_PROP_IMMUTABLE, PCIEX_ROOT, &err) != 0) {
		topo_mod_dprintf(mp, "Failed to set EXCAP property\n");
	}
	/* BDF of Oberon root complex is constant */
	if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI,
	    TOPO_PCI_BDF, TOPO_PROP_IMMUTABLE, OPL_PX_BDF, &err) != 0) {
		topo_mod_dprintf(mp, "Failed to set EXCAP property\n");
	}

	/* Make room for children */
	(void) topo_node_range_create(mp, rcn, PCIEX_BUS, 0, OPL_BUS_MAX);
	return (rcn);
}
/*
 * cpuboard_rc_node_create()
 * Description:
 *     Create a root complex node pciexrc
 * Parameters:
 *     mp: topo module pointer
 *     parent: topo parent node of the newly created pciexrc node
 *     dnode: Solaris device node of the root complex
 *     rcpath: Used to populated the dev property of the topo pciexrc node if
 *          the local host does not own the root complex.
 */
static tnode_t *
cpuboard_rc_node_create(topo_mod_t *mp, tnode_t *parent, di_node_t dnode,
    char *rcpath, int inst)
{
	int err;
	tnode_t *rcn;
	char *dnpath;
	nvlist_t *mod;

	topo_mod_dprintf(mp, "cpuboard_rc_node_create:\n");

	rcn = cpuboard_node_create(mp, parent, PCIEX_ROOT, inst, (void *)dnode);
	if (rcn == NULL) {
		return (NULL);
	}

	/* Inherit parent FRU's label */
	(void) topo_node_fru_set(rcn, NULL, 0, &err);
	(void) topo_node_label_set(rcn, NULL, &err);

	/*
	 * Set ASRU to be the dev-scheme ASRU
	 */
	if ((dnpath = di_devfs_path(dnode)) != NULL) {
		nvlist_t *fmri;

		/*
		 * The local host owns the root complex, so use the dev path
		 * from the di_devfs_path(), instead of the passed in rcpath,
		 * to populate the dev property.
		 */
		rcpath = dnpath;
		fmri = topo_mod_devfmri(mp, FM_DEV_SCHEME_VERSION,
		    dnpath, NULL);
		if (fmri == NULL) {
			topo_mod_dprintf(mp,
			    "dev:///%s fmri creation failed.\n",
			    dnpath);
			(void) topo_mod_seterrno(mp, err);
			di_devfs_path_free(dnpath);
			return (NULL);
		}
		if (topo_node_asru_set(rcn, fmri, 0, &err) < 0) {
			topo_mod_dprintf(mp, "topo_node_asru_set failed\n");
			(void) topo_mod_seterrno(mp, err);
			nvlist_free(fmri);
			di_devfs_path_free(dnpath);
			return (NULL);
		}
		nvlist_free(fmri);
	} else {
		topo_mod_dprintf(mp, "NULL di_devfs_path.\n");
	}

	/*
	 * Set pciexrc properties for root complex nodes
	 */

	/* Add the io and pci property groups */
	if (topo_pgroup_create(rcn, &io_pgroup, &err) < 0) {
		topo_mod_dprintf(mp, "topo_pgroup_create failed\n");
		di_devfs_path_free(dnpath);
		(void) topo_mod_seterrno(mp, err);
		return (NULL);
	}
	if (topo_pgroup_create(rcn, &pci_pgroup, &err) < 0) {
		topo_mod_dprintf(mp, "topo_pgroup_create failed\n");
		di_devfs_path_free(dnpath);
		(void) topo_mod_seterrno(mp, err);
		return (NULL);
	}
	/* Add the devfs path property */
	if (rcpath) {
		if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DEV,
		    TOPO_PROP_IMMUTABLE, rcpath, &err) != 0) {
			topo_mod_dprintf(mp, "Failed to set DEV property\n");
			(void) topo_mod_seterrno(mp, err);
		}
	}
	if (dnpath) {
		di_devfs_path_free(dnpath);
	}
	/* T5440 device type is always "pciex" */
	if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DEVTYPE,
	    TOPO_PROP_IMMUTABLE, CPUBOARD_PX_DEVTYPE, &err) != 0) {
		topo_mod_dprintf(mp, "Failed to set DEVTYPE property\n");
	}
	/* T5440 driver is always "px" */
	if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DRIVER,
	    TOPO_PROP_IMMUTABLE, CPUBOARD_PX_DRV, &err) != 0) {
		topo_mod_dprintf(mp, "Failed to set DRIVER property\n");
	}
	if ((mod = topo_mod_modfmri(mp, FM_MOD_SCHEME_VERSION, CPUBOARD_PX_DRV))
	    == NULL || topo_prop_set_fmri(rcn, TOPO_PGROUP_IO,
	    TOPO_IO_MODULE, TOPO_PROP_IMMUTABLE, mod,  &err) != 0) {
		topo_mod_dprintf(mp, "Failed to set MODULE property\n");
	}
	if (mod != NULL)
		nvlist_free(mod);

	/* This is a PCIEX Root Complex */
	if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI, TOPO_PCI_EXCAP,
	    TOPO_PROP_IMMUTABLE, PCIEX_ROOT, &err) != 0) {
		topo_mod_dprintf(mp, "Failed to set EXCAP property\n");
	}
	/* BDF of T5440 root complex is constant */
	if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI,
	    TOPO_PCI_BDF, TOPO_PROP_IMMUTABLE, CPUBOARD_PX_BDF, &err) != 0) {
		topo_mod_dprintf(mp, "Failed to set EXCAP property\n");
	}

	/* Make room for children */
	(void) topo_node_range_create(mp, rcn, PCIEX_BUS, 0, CPUBOARD_MAX);
	return (rcn);
}