/*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); }
/*ARGSUSED*/ static int hb_enum(topo_mod_t *mp, tnode_t *pn, const char *name, topo_instance_t imin, topo_instance_t imax, void *notused, void *data) { int rv; topo_mod_t *pcimod; if (strcmp(name, HOSTBRIDGE) != 0) { topo_mod_dprintf(mp, "Currently only know how to enumerate %s components.\n", HOSTBRIDGE); return (0); } /* * Load the pcibus enumerator */ if ((pcimod = pci_enumr_load(mp)) == NULL) return (-1); /* * If we're asked to enumerate a whole range of hostbridges, then * we need to find them all. If we're just asked to enumerate a * single hostbridge, we expect our caller to have passed us linked * did_t structures we can use to enumerate the singled out hostbridge. */ if (imin != imax) { if (did_hash_init(mp) < 0) { topo_mod_dprintf(mp, "Hash initialization for hostbridge " "enumerator failed.\n"); topo_mod_unload(pcimod); return (-1); } rv = platform_hb_enum(mp, pn, name, imin, imax); did_hash_fini(mp); } else { rv = specific_hb_enum(mp, pn, name, imin, imax, data); } return (rv); }
int pcifn_enum(topo_mod_t *mp, tnode_t *parent) { char *ccstr; int rv = 0; int i, e; uint_t cc; topo_mod_t *child_mod; topo_mod_dprintf(mp, "Enumerating beneath pci(ex) function.\n"); /* * Extract the class code of the PCI function and make sure * it matches the type that the module cares about. */ if (topo_prop_get_string(parent, TOPO_PGROUP_PCI, TOPO_PROP_CLASS, &ccstr, &e) < 0) return (0); if (sscanf(ccstr, "%x", &cc) != 1) { topo_mod_strfree(mp, ccstr); return (0); } topo_mod_strfree(mp, ccstr); cc = cc >> 16; for (i = 0; i < Pcifn_enumerator_count; i++) { if (cc != Pcifn_enumerators[i].pfne_class) continue; child_mod = module_load(mp, parent, Pcifn_enumerators[i].pfne_modname); if (child_mod) { rv = module_run(mp, parent, &Pcifn_enumerators[i]) != 0 ? -1 : 0; topo_mod_unload(child_mod); } } return (rv); }
/* * opl_hb_enum gets the ioboard instance passed in, and determines the * hostbridge and root complex instances numbers based on the bus addresses. */ int opl_hb_enum(topo_mod_t *mp, const ioboard_contents_t *iob, tnode_t *ion, int brd) { int hb; int rc; di_node_t p; tnode_t *hbnode; tnode_t *rcnode; topo_mod_t *pcimod; /* Load the pcibus module. We'll need it later. */ pcimod = topo_mod_load(mp, PCI_BUS, PCI_BUS_VERS); if (pcimod == NULL) { topo_mod_dprintf(mp, "can't load pcibus module: %s\n", topo_strerror(topo_mod_errno(mp))); return (-1); } /* For each hostbridge on an ioboard... */ for (hb = 0; hb < OPL_HB_MAX; hb++) { hbnode = NULL; /* For each root complex in a hostbridge... */ for (rc = 0; rc < OPL_RC_MAX; rc++) { p = iob->rcs[hb][rc]; /* If no root complex, continue */ if (p == DI_NODE_NIL) { continue; } /* The root complex exists! */ topo_mod_dprintf(mp, "declaring " "/chassis=0/ioboard=%d/hostbridge=%d/pciexrc=%d\n", brd, hb, rc); /* * If we haven't created a hostbridge node yet, do it * now. */ if (hbnode == NULL) { hbnode = opl_hb_node_create(mp, ion, hb); if (hbnode == NULL) { topo_mod_dprintf(mp, "unable to create hbnode: %s\n", topo_strerror(topo_mod_errno(mp))); topo_mod_unload(pcimod); return (-1); } } /* Create the root complex node */ rcnode = opl_rc_node_create(mp, hbnode, p, rc); if (rcnode == NULL) { topo_mod_dprintf(mp, "unable to create rcnode: %s\n", topo_strerror(topo_mod_errno(mp))); topo_mod_unload(pcimod); return (-1); } /* Enumerate pcibus nodes under the root complex */ if (topo_mod_enumerate(pcimod, rcnode, PCI_BUS, PCIEX_BUS, 0, 255, NULL) != 0) { topo_mod_dprintf(mp, "error enumerating pcibus: %s\n", topo_strerror(topo_mod_errno(mp))); topo_mod_unload(pcimod); return (-1); } } } topo_mod_unload(pcimod); return (0); }
/* * Enumerate hostbridge on the cpuboard. Hostbridge and root complex instances * match the cpuboard instance. */ int cpuboard_hb_enum(topo_mod_t *mp, di_node_t dnode, char *rcpath, tnode_t *cpubn, int brd) { int hb; int rc; tnode_t *hbnode; tnode_t *rcnode; topo_mod_t *pcimod; topo_mod_dprintf(mp, "cpuboard_hb_enum: brd: %d, cpubn=%p\n", brd, cpubn); /* Load the pcibus module. We'll need it later. */ pcimod = topo_mod_load(mp, PCI_BUS, PCI_BUS_VERS); if (pcimod == NULL) { topo_mod_dprintf(mp, "can't load pcibus module: %s\n", topo_strerror(topo_mod_errno(mp))); return (-1); } hb = rc = brd; /* The root complex exists! */ topo_mod_dprintf(mp, "declaring " "/motherboard=0/cpuboard=%d/hostbridge=%d/" "pciexrc=%d\n", brd, hb, rc); /* Create the hostbridge node */ hbnode = cpuboard_hb_node_create(mp, cpubn, hb); if (hbnode == NULL) { topo_mod_dprintf(mp, "unable to create hbnode: %s\n", topo_strerror(topo_mod_errno(mp))); topo_mod_unload(pcimod); return (-1); } /* Create the root complex node */ rcnode = cpuboard_rc_node_create(mp, hbnode, dnode, rcpath, rc); if (rcnode == NULL) { topo_mod_dprintf(mp, "unable to create rcnode: %s\n", topo_strerror(topo_mod_errno(mp))); topo_mod_unload(pcimod); return (-1); } /* * If dnode not NULL, enumerate pcibus nodes under the root complex. * If dnode NULL, skip enumeration. Condition could occur if the RC * is assigned to non-control domain. */ if ((dnode != NULL) && topo_mod_enumerate(pcimod, rcnode, PCI_BUS, PCIEX_BUS, 0, 255, NULL) != 0) { topo_mod_dprintf(mp, "error enumerating pcibus: %s\n", topo_strerror(topo_mod_errno(mp))); topo_mod_unload(pcimod); return (-1); } topo_mod_unload(pcimod); return (0); }