/*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); }
/*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); }
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); }
/* * 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); }