110942STom.Pothier@Sun.COM /*
210942STom.Pothier@Sun.COM * CDDL HEADER START
310942STom.Pothier@Sun.COM *
410942STom.Pothier@Sun.COM * The contents of this file are subject to the terms of the
510942STom.Pothier@Sun.COM * Common Development and Distribution License (the "License").
610942STom.Pothier@Sun.COM * You may not use this file except in compliance with the License.
710942STom.Pothier@Sun.COM *
810942STom.Pothier@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910942STom.Pothier@Sun.COM * or http://www.opensolaris.org/os/licensing.
1010942STom.Pothier@Sun.COM * See the License for the specific language governing permissions
1110942STom.Pothier@Sun.COM * and limitations under the License.
1210942STom.Pothier@Sun.COM *
1310942STom.Pothier@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1410942STom.Pothier@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510942STom.Pothier@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1610942STom.Pothier@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1710942STom.Pothier@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1810942STom.Pothier@Sun.COM *
1910942STom.Pothier@Sun.COM * CDDL HEADER END
2010942STom.Pothier@Sun.COM */
2110942STom.Pothier@Sun.COM
2210942STom.Pothier@Sun.COM /*
2312355SSean.Ye@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2410942STom.Pothier@Sun.COM */
2510942STom.Pothier@Sun.COM
2610942STom.Pothier@Sun.COM /*
2710942STom.Pothier@Sun.COM * x86 Generic FMA Topology Enumerator
2810942STom.Pothier@Sun.COM */
2910942STom.Pothier@Sun.COM
3010942STom.Pothier@Sun.COM
3110942STom.Pothier@Sun.COM #include <fcntl.h>
3210942STom.Pothier@Sun.COM #include <unistd.h>
3310942STom.Pothier@Sun.COM #include <sys/types.h>
3410942STom.Pothier@Sun.COM #include <strings.h>
3510942STom.Pothier@Sun.COM #include <sys/fcntl.h>
3610942STom.Pothier@Sun.COM #include <fm/topo_mod.h>
3710942STom.Pothier@Sun.COM #include <fm/topo_hc.h>
3810942STom.Pothier@Sun.COM #include <sys/systeminfo.h>
3910942STom.Pothier@Sun.COM #include <sys/smbios.h>
4010942STom.Pothier@Sun.COM #include <sys/smbios_impl.h>
4110942STom.Pothier@Sun.COM #include <sys/fm/protocol.h>
4210942STom.Pothier@Sun.COM #include <x86pi_impl.h>
4310942STom.Pothier@Sun.COM
4410942STom.Pothier@Sun.COM
4510942STom.Pothier@Sun.COM static int x86pi_enum_start(topo_mod_t *, x86pi_enum_t *);
4612832STrang.Do@Sun.COM static int x86pi_enum_gentopo(topo_mod_t *, tnode_t *);
4710942STom.Pothier@Sun.COM
4810942STom.Pothier@Sun.COM /*
4910942STom.Pothier@Sun.COM * Entry point called by libtopo when enumeration is required
5010942STom.Pothier@Sun.COM */
5110942STom.Pothier@Sun.COM static topo_enum_f x86pi_enum; /* libtopo enumeration entry point */
5210942STom.Pothier@Sun.COM
5310942STom.Pothier@Sun.COM /*
54*13017STom.Pothier@Sun.COM * Top level chassis node in a multiple chassis system; or the chassis
55*13017STom.Pothier@Sun.COM * node in a single chassis system.
56*13017STom.Pothier@Sun.COM */
57*13017STom.Pothier@Sun.COM static tnode_t *motherchassis_node = NULL;
58*13017STom.Pothier@Sun.COM
59*13017STom.Pothier@Sun.COM
60*13017STom.Pothier@Sun.COM /*
6110942STom.Pothier@Sun.COM * Declare the operations vector and information structure used during
6210942STom.Pothier@Sun.COM * module registration
6310942STom.Pothier@Sun.COM */
6410942STom.Pothier@Sun.COM static topo_modops_t x86pi_ops =
6510942STom.Pothier@Sun.COM { x86pi_enum, NULL };
6610942STom.Pothier@Sun.COM
6710942STom.Pothier@Sun.COM static topo_modinfo_t x86pi_modinfo =
6810942STom.Pothier@Sun.COM { X86PI_DESC, X86PI_SCHEME, X86PI_VERSION, &x86pi_ops };
6910942STom.Pothier@Sun.COM
7010942STom.Pothier@Sun.COM /*
7110942STom.Pothier@Sun.COM * Used to pass SMBIOS' FM compatibility to the
7210942STom.Pothier@Sun.COM * chip enumerator
7310942STom.Pothier@Sun.COM */
7410942STom.Pothier@Sun.COM int x86pi_smbios = 0;
7510942STom.Pothier@Sun.COM
7610942STom.Pothier@Sun.COM /*
7710942STom.Pothier@Sun.COM * Called by libtopo when the topo module is loaded.
7810942STom.Pothier@Sun.COM */
7910942STom.Pothier@Sun.COM int
_topo_init(topo_mod_t * mod,topo_version_t version)8010942STom.Pothier@Sun.COM _topo_init(topo_mod_t *mod, topo_version_t version)
8110942STom.Pothier@Sun.COM {
8210942STom.Pothier@Sun.COM int result;
8310942STom.Pothier@Sun.COM char isa[MAXNAMELEN];
8410942STom.Pothier@Sun.COM
8510942STom.Pothier@Sun.COM if (getenv("TOPOX86PIDBG") != NULL) {
8610942STom.Pothier@Sun.COM /* Debugging is requested for this module */
8710942STom.Pothier@Sun.COM topo_mod_setdebug(mod);
8810942STom.Pothier@Sun.COM }
8910942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "module initializing.\n");
9010942STom.Pothier@Sun.COM
9110942STom.Pothier@Sun.COM if (version != TOPO_VERSION) {
9210983STom.Pothier@Sun.COM (void) topo_mod_seterrno(mod, EMOD_VER_NEW);
9310942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "incompatible topo version %d\n",
9410942STom.Pothier@Sun.COM version);
9510942STom.Pothier@Sun.COM return (-1);
9610942STom.Pothier@Sun.COM }
9710942STom.Pothier@Sun.COM
9810942STom.Pothier@Sun.COM /* Verify that this is a i86pc architecture machine */
9910942STom.Pothier@Sun.COM (void) sysinfo(SI_MACHINE, isa, MAXNAMELEN);
10010942STom.Pothier@Sun.COM if (strncmp(isa, "i86pc", MAXNAMELEN) != 0) {
10110942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "not i86pc architecture: %s\n", isa);
10210942STom.Pothier@Sun.COM return (-1);
10310942STom.Pothier@Sun.COM }
10410942STom.Pothier@Sun.COM
10510942STom.Pothier@Sun.COM result = topo_mod_register(mod, &x86pi_modinfo, TOPO_VERSION);
10610942STom.Pothier@Sun.COM if (result < 0) {
10710942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "registration failed: %s\n",
10810942STom.Pothier@Sun.COM topo_mod_errmsg(mod));
10910942STom.Pothier@Sun.COM /* module errno already set */
11010942STom.Pothier@Sun.COM return (-1);
11110942STom.Pothier@Sun.COM }
11210942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "module ready.\n");
11310942STom.Pothier@Sun.COM return (0);
11410942STom.Pothier@Sun.COM }
11510942STom.Pothier@Sun.COM
11610942STom.Pothier@Sun.COM
11710942STom.Pothier@Sun.COM /*
11810942STom.Pothier@Sun.COM * Clean up any data used by the module before it is unloaded.
11910942STom.Pothier@Sun.COM */
12010942STom.Pothier@Sun.COM void
_topo_fini(topo_mod_t * mod)12110942STom.Pothier@Sun.COM _topo_fini(topo_mod_t *mod)
12210942STom.Pothier@Sun.COM {
12310942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "module finishing.\n");
12410942STom.Pothier@Sun.COM
12510942STom.Pothier@Sun.COM /* Unregister from libtopo */
12610942STom.Pothier@Sun.COM topo_mod_unregister(mod);
12710942STom.Pothier@Sun.COM }
12810942STom.Pothier@Sun.COM
12910942STom.Pothier@Sun.COM
13010942STom.Pothier@Sun.COM /*
13110942STom.Pothier@Sun.COM * Enumeration entry point for the x86 Generic topology enumerator
13210942STom.Pothier@Sun.COM */
13310942STom.Pothier@Sun.COM /* ARGSUSED */
13410942STom.Pothier@Sun.COM static int
x86pi_enum(topo_mod_t * mod,tnode_t * t_parent,const char * name,topo_instance_t min,topo_instance_t max,void * pi_private,void * data)13510942STom.Pothier@Sun.COM x86pi_enum(topo_mod_t *mod, tnode_t *t_parent, const char *name,
13610942STom.Pothier@Sun.COM topo_instance_t min, topo_instance_t max, void *pi_private, void *data)
13710942STom.Pothier@Sun.COM {
13810942STom.Pothier@Sun.COM int result;
13910942STom.Pothier@Sun.COM hrtime_t starttime;
14010942STom.Pothier@Sun.COM x86pi_enum_t x86pi;
14110942STom.Pothier@Sun.COM
14210942STom.Pothier@Sun.COM /* Begin enumeration */
14310942STom.Pothier@Sun.COM starttime = gethrtime();
14410942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "enumeration starting.\n");
14510942STom.Pothier@Sun.COM
14610942STom.Pothier@Sun.COM /*
14710942STom.Pothier@Sun.COM * Let's do some enumeration.
14810942STom.Pothier@Sun.COM */
14910942STom.Pothier@Sun.COM bzero(&x86pi, sizeof (x86pi_enum_t));
15010942STom.Pothier@Sun.COM x86pi.t_parent = t_parent;
15110942STom.Pothier@Sun.COM result = x86pi_enum_start(mod, &x86pi);
15210942STom.Pothier@Sun.COM if (result != 0) {
15310942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "Enumeration failed.\n");
15410942STom.Pothier@Sun.COM return (-1);
15510942STom.Pothier@Sun.COM }
15610942STom.Pothier@Sun.COM
15710942STom.Pothier@Sun.COM /* Complete enumeration */
15810942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "enumeration complete in %lld ms.\n",
15910942STom.Pothier@Sun.COM ((gethrtime() - starttime)/MICROSEC));
16010942STom.Pothier@Sun.COM
16110942STom.Pothier@Sun.COM /* All done */
16210942STom.Pothier@Sun.COM return (result);
16310942STom.Pothier@Sun.COM }
16410942STom.Pothier@Sun.COM
16510942STom.Pothier@Sun.COM static int
x86pi_enum_start(topo_mod_t * mod,x86pi_enum_t * x86pi)16610942STom.Pothier@Sun.COM x86pi_enum_start(topo_mod_t *mod, x86pi_enum_t *x86pi)
16710942STom.Pothier@Sun.COM {
16810942STom.Pothier@Sun.COM int rv;
16910942STom.Pothier@Sun.COM int complvl = 0;
17010942STom.Pothier@Sun.COM smbios_hdl_t *shp;
17110942STom.Pothier@Sun.COM char *f = "x86pi_enum_start";
17210942STom.Pothier@Sun.COM
17310942STom.Pothier@Sun.COM /*
17410942STom.Pothier@Sun.COM * Verify BIOS compliance.
17510942STom.Pothier@Sun.COM */
17610942STom.Pothier@Sun.COM shp = x86pi_smb_open(mod);
17710942STom.Pothier@Sun.COM if (shp == NULL) {
17810942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: failed to open SMBIOS\n", f);
17910942STom.Pothier@Sun.COM complvl = X86PI_NONE;
18010942STom.Pothier@Sun.COM } else {
18112832STrang.Do@Sun.COM complvl = x86pi_check_comp(mod);
18210942STom.Pothier@Sun.COM }
18310942STom.Pothier@Sun.COM
18410942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: SMBIOS x86pi compliance: %s\n", f,
18510942STom.Pothier@Sun.COM complvl == X86PI_FULL ? "FULL" : "NONE");
18610942STom.Pothier@Sun.COM
18710942STom.Pothier@Sun.COM if (complvl == X86PI_NONE) {
18810942STom.Pothier@Sun.COM /* fall back to legacy enumeration */
18910942STom.Pothier@Sun.COM topo_mod_dprintf(mod,
19010942STom.Pothier@Sun.COM "%s: Calling legacy enumeration\n", f);
19110942STom.Pothier@Sun.COM
19210942STom.Pothier@Sun.COM return (topo_mod_enummap(mod, x86pi->t_parent,
19310942STom.Pothier@Sun.COM "i86pc-legacy", FM_FMRI_SCHEME_HC));
19410942STom.Pothier@Sun.COM }
19510942STom.Pothier@Sun.COM
19610942STom.Pothier@Sun.COM x86pi->priv = (void *)shp;
19710942STom.Pothier@Sun.COM x86pi_smbios = complvl;
19810942STom.Pothier@Sun.COM
19910942STom.Pothier@Sun.COM if (x86pi_hbr_enum_init(mod) < 0) {
20010942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: x86pi_hbr_enum_init() failed.\n", f);
20110942STom.Pothier@Sun.COM return (-1);
20210942STom.Pothier@Sun.COM }
20310942STom.Pothier@Sun.COM
20410942STom.Pothier@Sun.COM /*
20510942STom.Pothier@Sun.COM * Create the topology.
20610942STom.Pothier@Sun.COM */
20710942STom.Pothier@Sun.COM fac_done = 0;
20812832STrang.Do@Sun.COM rv = x86pi_enum_gentopo(mod, x86pi->t_parent);
20912355SSean.Ye@Sun.COM
21012355SSean.Ye@Sun.COM x86pi_hbr_enum_fini(mod);
21112355SSean.Ye@Sun.COM
21210942STom.Pothier@Sun.COM if (rv != 0) {
21310942STom.Pothier@Sun.COM return (-1);
21410942STom.Pothier@Sun.COM }
21510942STom.Pothier@Sun.COM x86pi->mod = mod;
21610942STom.Pothier@Sun.COM
21710942STom.Pothier@Sun.COM if (fac_done == 0) {
218*13017STom.Pothier@Sun.COM (void) topo_mod_enummap(mod, motherchassis_node, "chassis",
21910942STom.Pothier@Sun.COM FM_FMRI_SCHEME_HC);
220*13017STom.Pothier@Sun.COM (void) topo_mod_enummap(mod, motherchassis_node, "fan",
22110942STom.Pothier@Sun.COM FM_FMRI_SCHEME_HC);
222*13017STom.Pothier@Sun.COM (void) topo_mod_enummap(mod, motherchassis_node, "psu",
22310942STom.Pothier@Sun.COM FM_FMRI_SCHEME_HC);
22410942STom.Pothier@Sun.COM }
22510942STom.Pothier@Sun.COM
22610942STom.Pothier@Sun.COM /* All done */
22710942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: done.\n", f);
22810942STom.Pothier@Sun.COM return (rv);
22910942STom.Pothier@Sun.COM }
23010942STom.Pothier@Sun.COM
23110942STom.Pothier@Sun.COM /*
23210942STom.Pothier@Sun.COM * Create the i86pc topology
23310942STom.Pothier@Sun.COM *
23410942STom.Pothier@Sun.COM * If either Type 2 or Type 3 structures have contained elements/handles,
23510942STom.Pothier@Sun.COM * walk them creating the topo.
23610942STom.Pothier@Sun.COM *
23710942STom.Pothier@Sun.COM * If there are no contained elements/handles, build this topo:
23810942STom.Pothier@Sun.COM *
23910942STom.Pothier@Sun.COM * Main Chassis
24010942STom.Pothier@Sun.COM * Motherboard
24110942STom.Pothier@Sun.COM * CMP Chip/Core/Strands
24210942STom.Pothier@Sun.COM * Memory Controllers/Memory Devices (DIMMs)
24310942STom.Pothier@Sun.COM * PCIE HostBrige
24410942STom.Pothier@Sun.COM * PCIE Root Complex
24510942STom.Pothier@Sun.COM *
24610942STom.Pothier@Sun.COM */
24710942STom.Pothier@Sun.COM static int
x86pi_enum_gentopo(topo_mod_t * mod,tnode_t * t_parent)24812832STrang.Do@Sun.COM x86pi_enum_gentopo(topo_mod_t *mod, tnode_t *t_parent)
24910942STom.Pothier@Sun.COM {
25010942STom.Pothier@Sun.COM int rv;
25110942STom.Pothier@Sun.COM int nch, nbb, ncmp, i;
25210942STom.Pothier@Sun.COM int ch_smbid, bb_smbid;
25310942STom.Pothier@Sun.COM tnode_t *chassis_node = NULL;
25410942STom.Pothier@Sun.COM tnode_t *basebd_node = NULL;
25510942STom.Pothier@Sun.COM smbs_cnt_t *smbc;
25610942STom.Pothier@Sun.COM tnode_t *pnode = NULL;
25710942STom.Pothier@Sun.COM id_t psmbid;
25810942STom.Pothier@Sun.COM int notvisited;
25910942STom.Pothier@Sun.COM int bb_count, ch_count;
26010942STom.Pothier@Sun.COM int min, max;
26110942STom.Pothier@Sun.COM int ch_inst = 0;
26211859STom.Pothier@Sun.COM int disk_inst = 0;
26310942STom.Pothier@Sun.COM topo_instance_t hbri = 0, rci = 0;
26410942STom.Pothier@Sun.COM smbios_pciexrc_t hbr;
26511859STom.Pothier@Sun.COM smbios_port_ext_t export;
26610942STom.Pothier@Sun.COM char *f = "x86pi_enum_gentopo";
26712832STrang.Do@Sun.COM smbios_hdl_t *shp;
26812832STrang.Do@Sun.COM
26912832STrang.Do@Sun.COM shp = topo_mod_smbios(mod);
27012832STrang.Do@Sun.COM if (shp == NULL) {
27112832STrang.Do@Sun.COM topo_mod_dprintf(mod, "%s: failed to load SMBIOS\n", f);
27212832STrang.Do@Sun.COM return (-1);
27312832STrang.Do@Sun.COM }
27410942STom.Pothier@Sun.COM
27510942STom.Pothier@Sun.COM if (t_parent == NULL) {
27610942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: NULL parent\n", f);
27710942STom.Pothier@Sun.COM return (-1);
27810942STom.Pothier@Sun.COM }
27910942STom.Pothier@Sun.COM
28010942STom.Pothier@Sun.COM /*
28110942STom.Pothier@Sun.COM * "Chassis'"
28210942STom.Pothier@Sun.COM */
28310942STom.Pothier@Sun.COM /* Type 3 structs */
28410942STom.Pothier@Sun.COM stypes[SMB_TYPE_CHASSIS].type = SMB_TYPE_CHASSIS;
28512832STrang.Do@Sun.COM x86pi_smb_strcnt(mod, &stypes[SMB_TYPE_CHASSIS]);
28610942STom.Pothier@Sun.COM
28710942STom.Pothier@Sun.COM ch_count = stypes[SMB_TYPE_CHASSIS].count;
28810942STom.Pothier@Sun.COM
28910942STom.Pothier@Sun.COM for (nch = 0; nch < ch_count; nch++) {
29010942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: found %d chassis\n", f,
29110942STom.Pothier@Sun.COM stypes[SMB_TYPE_CHASSIS].count);
29210942STom.Pothier@Sun.COM
29310942STom.Pothier@Sun.COM ch_smbid = stypes[SMB_TYPE_CHASSIS].ids[nch].id;
29410942STom.Pothier@Sun.COM
29510942STom.Pothier@Sun.COM /*
29610942STom.Pothier@Sun.COM * Expect SMBIOS to set the first Chassis Structure to be the
29710942STom.Pothier@Sun.COM * parent/mother of all chassis
29810942STom.Pothier@Sun.COM */
29910942STom.Pothier@Sun.COM if (nch == 0)
30010942STom.Pothier@Sun.COM motherchassis_node = chassis_node =
30112832STrang.Do@Sun.COM x86pi_gen_chassis(mod, t_parent, ch_smbid,
30212832STrang.Do@Sun.COM ch_inst++);
30310942STom.Pothier@Sun.COM else {
30410942STom.Pothier@Sun.COM if (motherchassis_node != NULL)
30510942STom.Pothier@Sun.COM chassis_node = x86pi_gen_chassis(mod,
30612832STrang.Do@Sun.COM motherchassis_node, ch_smbid, ch_inst++);
30710942STom.Pothier@Sun.COM else
30810942STom.Pothier@Sun.COM chassis_node = x86pi_gen_chassis(mod,
30912832STrang.Do@Sun.COM t_parent, ch_smbid, ch_inst++);
31010942STom.Pothier@Sun.COM }
31110942STom.Pothier@Sun.COM
31210942STom.Pothier@Sun.COM if (chassis_node == NULL) {
31310942STom.Pothier@Sun.COM topo_mod_dprintf(mod,
31410942STom.Pothier@Sun.COM "%s: Failed to create chassis %d\n", f, nch);
31510942STom.Pothier@Sun.COM continue;
31610942STom.Pothier@Sun.COM }
31710942STom.Pothier@Sun.COM stypes[SMB_TYPE_CHASSIS].ids[nch].node = chassis_node;
31811859STom.Pothier@Sun.COM
31911859STom.Pothier@Sun.COM /* count SMBIOS extended port connector structures */
32011859STom.Pothier@Sun.COM smbc = &stypes[SUN_OEM_EXT_PORT];
32111859STom.Pothier@Sun.COM smbc->type = SUN_OEM_EXT_PORT;
32212832STrang.Do@Sun.COM x86pi_smb_strcnt(mod, smbc);
32311859STom.Pothier@Sun.COM
32412815SVuong.Nguyen@Sun.COM /*
32512815SVuong.Nguyen@Sun.COM * enumerate direct attached SATA disks if we found a
32612815SVuong.Nguyen@Sun.COM * SUN_OEM_EXT_PORT record.
32712815SVuong.Nguyen@Sun.COM */
32812815SVuong.Nguyen@Sun.COM if (smbc->count > 0) {
32912815SVuong.Nguyen@Sun.COM rv = topo_node_range_create(mod, chassis_node, BAY, 0,
33012815SVuong.Nguyen@Sun.COM smbc->count + 1);
33112815SVuong.Nguyen@Sun.COM if (rv != 0) {
33212815SVuong.Nguyen@Sun.COM topo_mod_dprintf(mod,
33312815SVuong.Nguyen@Sun.COM "%s: Failed to create %s range: %s\n",
33412815SVuong.Nguyen@Sun.COM f, BAY, topo_mod_errmsg(mod));
33512815SVuong.Nguyen@Sun.COM continue;
33612815SVuong.Nguyen@Sun.COM }
33712815SVuong.Nguyen@Sun.COM } else {
33811859STom.Pothier@Sun.COM topo_mod_dprintf(mod,
33912815SVuong.Nguyen@Sun.COM "Skipping disk bay enumeration\n");
34011859STom.Pothier@Sun.COM }
34111859STom.Pothier@Sun.COM
34211859STom.Pothier@Sun.COM for (i = 0; i < smbc->count; i++) {
34311859STom.Pothier@Sun.COM if (smbios_info_extport(shp, smbc->ids[i].id,
34411859STom.Pothier@Sun.COM &export) != 0) {
34511859STom.Pothier@Sun.COM topo_mod_dprintf(mod,
34611859STom.Pothier@Sun.COM "smbios_info_export failed: id = %d\n",
34711859STom.Pothier@Sun.COM (int)smbc->ids[i].id);
34811859STom.Pothier@Sun.COM continue;
34911859STom.Pothier@Sun.COM }
35011859STom.Pothier@Sun.COM if (export.smbporte_chassis != ch_smbid)
35111859STom.Pothier@Sun.COM continue;
35211859STom.Pothier@Sun.COM
35311859STom.Pothier@Sun.COM /*
35411859STom.Pothier@Sun.COM * x86pi_gen_bay:
35511859STom.Pothier@Sun.COM * create "bay" node
35611859STom.Pothier@Sun.COM * call "disk" enum passing in "bay" node
35711859STom.Pothier@Sun.COM */
35812832STrang.Do@Sun.COM rv = x86pi_gen_bay(mod, chassis_node, &export,
35912832STrang.Do@Sun.COM disk_inst);
36011859STom.Pothier@Sun.COM if (rv != 0)
36111859STom.Pothier@Sun.COM topo_mod_dprintf(mod,
36211859STom.Pothier@Sun.COM "Failed to create disk %d\n", i);
36311859STom.Pothier@Sun.COM disk_inst++;
36411859STom.Pothier@Sun.COM }
36510942STom.Pothier@Sun.COM }
36610942STom.Pothier@Sun.COM
36710942STom.Pothier@Sun.COM /*
36810942STom.Pothier@Sun.COM * "Base Board"
36910942STom.Pothier@Sun.COM */
37010942STom.Pothier@Sun.COM /* Type 2 structs */
37110942STom.Pothier@Sun.COM stypes[SMB_TYPE_BASEBOARD].type = SMB_TYPE_BASEBOARD;
37212832STrang.Do@Sun.COM x86pi_smb_strcnt(mod, &stypes[SMB_TYPE_BASEBOARD]);
37310942STom.Pothier@Sun.COM bb_count = notvisited = stypes[SMB_TYPE_BASEBOARD].count;
37410942STom.Pothier@Sun.COM
37510942STom.Pothier@Sun.COM for (nbb = 0; nbb < bb_count; nbb++) {
37610942STom.Pothier@Sun.COM stypes[SMB_TYPE_BASEBOARD].ids[nbb].visited = 0;
37710942STom.Pothier@Sun.COM stypes[SMB_TYPE_BASEBOARD].ids[nbb].con_by_id = 0;
37810942STom.Pothier@Sun.COM stypes[SMB_TYPE_BASEBOARD].ids[nbb].node = NULL;
37910942STom.Pothier@Sun.COM }
38012832STrang.Do@Sun.COM (void) x86pi_bb_contains(mod);
38110942STom.Pothier@Sun.COM
38210942STom.Pothier@Sun.COM min = 0;
38310942STom.Pothier@Sun.COM nbb = 0;
38410942STom.Pothier@Sun.COM do {
38510942STom.Pothier@Sun.COM /*
38610942STom.Pothier@Sun.COM * We have reached end of the array due to the
38710942STom.Pothier@Sun.COM * parent-child relationship, without visiting all
38810942STom.Pothier@Sun.COM * baseboards! so re-iterate..
38910942STom.Pothier@Sun.COM * (or)
39010942STom.Pothier@Sun.COM * All baseboards are visited and their contained
39110942STom.Pothier@Sun.COM * processors are enumerated
39210942STom.Pothier@Sun.COM * (and/or)
39310942STom.Pothier@Sun.COM * More baseboards pending a visit
39410942STom.Pothier@Sun.COM */
39510942STom.Pothier@Sun.COM if (nbb > bb_count && notvisited)
39610942STom.Pothier@Sun.COM nbb = 0;
39710942STom.Pothier@Sun.COM else if (nbb > bb_count && !notvisited)
39810942STom.Pothier@Sun.COM break;
39910942STom.Pothier@Sun.COM if (stypes[SMB_TYPE_BASEBOARD].ids[nbb].visited ==
40010942STom.Pothier@Sun.COM X86PI_VISITED) {
40110942STom.Pothier@Sun.COM nbb++;
40210942STom.Pothier@Sun.COM continue;
40310942STom.Pothier@Sun.COM }
40410942STom.Pothier@Sun.COM
40510942STom.Pothier@Sun.COM /*
40610942STom.Pothier@Sun.COM * Get the Top-most Parent Baseboard, irrespective
40710942STom.Pothier@Sun.COM * of its index in the array of Type-2s
40810942STom.Pothier@Sun.COM * If this Baseboard has no Baseboard parents
40910942STom.Pothier@Sun.COM * place it under the chassis that contains it
41010942STom.Pothier@Sun.COM */
41112832STrang.Do@Sun.COM bb_smbid = x86pi_bb_topparent(mod, nbb, &pnode, &psmbid);
41210942STom.Pothier@Sun.COM if (bb_smbid == -1 || pnode == NULL) {
41310942STom.Pothier@Sun.COM topo_mod_dprintf(mod,
41410942STom.Pothier@Sun.COM "Failed to get BaseBoard node (%d): parent\n",
41510942STom.Pothier@Sun.COM nbb);
41610942STom.Pothier@Sun.COM return (-1);
41710942STom.Pothier@Sun.COM }
41810942STom.Pothier@Sun.COM
41910942STom.Pothier@Sun.COM if (stypes[SMB_TYPE_BASEBOARD].ids[nbb].id != bb_smbid) {
42010942STom.Pothier@Sun.COM for (int i = 0; i < bb_count; i++) {
42110942STom.Pothier@Sun.COM if (bb_smbid ==
42210942STom.Pothier@Sun.COM stypes[SMB_TYPE_BASEBOARD].ids[i].id) {
42310942STom.Pothier@Sun.COM stypes[SMB_TYPE_BASEBOARD].ids[i].\
42410942STom.Pothier@Sun.COM visited = 1;
42510942STom.Pothier@Sun.COM notvisited--;
42610942STom.Pothier@Sun.COM break;
42710942STom.Pothier@Sun.COM }
42810942STom.Pothier@Sun.COM }
42910942STom.Pothier@Sun.COM } else {
43010942STom.Pothier@Sun.COM stypes[SMB_TYPE_BASEBOARD].ids[nbb].visited = 1;
43110942STom.Pothier@Sun.COM notvisited--;
43210942STom.Pothier@Sun.COM }
43310942STom.Pothier@Sun.COM
43412832STrang.Do@Sun.COM basebd_node = x86pi_gen_bboard(mod, pnode, bb_smbid,
43512832STrang.Do@Sun.COM nbb, psmbid);
43610942STom.Pothier@Sun.COM if (basebd_node == NULL) {
43710942STom.Pothier@Sun.COM topo_mod_dprintf(mod,
43810942STom.Pothier@Sun.COM "Failed to create BaseBoard node (%d)\n", nbb);
43910942STom.Pothier@Sun.COM nbb++;
44010942STom.Pothier@Sun.COM continue;
44110942STom.Pothier@Sun.COM }
44210942STom.Pothier@Sun.COM
44310942STom.Pothier@Sun.COM stypes[SMB_TYPE_BASEBOARD].ids[nbb].node = basebd_node;
44410942STom.Pothier@Sun.COM /*
44510942STom.Pothier@Sun.COM * Look for contained handles here and if there are
44610942STom.Pothier@Sun.COM * make sure the chip handle below is part of it.
44710942STom.Pothier@Sun.COM */
44812832STrang.Do@Sun.COM ncmp = x86pi_bb_getchips(mod, nbb, bb_count);
44910942STom.Pothier@Sun.COM if (ncmp > 0) {
45010942STom.Pothier@Sun.COM max = min + ncmp - 1;
45110942STom.Pothier@Sun.COM /* make sure the chip enum is loaded */
45210942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: loading chip enum\n", f);
45310942STom.Pothier@Sun.COM
45410942STom.Pothier@Sun.COM if (topo_mod_load(mod, CHIP, TOPO_VERSION) == NULL) {
45510942STom.Pothier@Sun.COM topo_mod_dprintf(mod,
45610942STom.Pothier@Sun.COM "%s: Failed to load %s module: %s\n", f,
45710942STom.Pothier@Sun.COM CHIP, topo_strerror(topo_mod_errno(mod)));
45810942STom.Pothier@Sun.COM } else {
45910942STom.Pothier@Sun.COM /* create node range */
46010942STom.Pothier@Sun.COM topo_mod_dprintf(mod,
46110942STom.Pothier@Sun.COM "%s: chip range %d to %d\n",
46210942STom.Pothier@Sun.COM f, min, max);
46310942STom.Pothier@Sun.COM rv = topo_node_range_create(mod, basebd_node,
46410942STom.Pothier@Sun.COM CHIP, min, max);
46510942STom.Pothier@Sun.COM if (rv != 0) {
46610942STom.Pothier@Sun.COM topo_mod_dprintf(mod,
46710942STom.Pothier@Sun.COM "%s: Failed to create node range: "
46810942STom.Pothier@Sun.COM "%s\n", f,
46910942STom.Pothier@Sun.COM topo_strerror(topo_mod_errno(mod)));
47010942STom.Pothier@Sun.COM } else {
47110942STom.Pothier@Sun.COM /* call the chip enumerator */
47210942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s: calling"
47310942STom.Pothier@Sun.COM " chip enum\n", f);
47410942STom.Pothier@Sun.COM rv =
47510942STom.Pothier@Sun.COM topo_mod_enumerate(mod, basebd_node,
47610942STom.Pothier@Sun.COM CHIP, CHIP, min, max,
47710942STom.Pothier@Sun.COM &x86pi_smbios);
47810942STom.Pothier@Sun.COM min = max + 1;
47910942STom.Pothier@Sun.COM if (rv != 0)
48010942STom.Pothier@Sun.COM topo_mod_dprintf(mod, "%s:%s"
48110942STom.Pothier@Sun.COM "enumeration failed: \n",
48210942STom.Pothier@Sun.COM f, CHIP);
48310942STom.Pothier@Sun.COM }
48410942STom.Pothier@Sun.COM }
48510942STom.Pothier@Sun.COM }
48610942STom.Pothier@Sun.COM
48710942STom.Pothier@Sun.COM /* enumerate the hostbridge node */
48810942STom.Pothier@Sun.COM rv = topo_node_range_create(mod, basebd_node, HOSTBRIDGE,
48910942STom.Pothier@Sun.COM 0, 255);
49010942STom.Pothier@Sun.COM if (rv != 0) {
49110942STom.Pothier@Sun.COM topo_mod_dprintf(mod,
49210942STom.Pothier@Sun.COM "%s: Failed to create %s range: %s\n",
49310942STom.Pothier@Sun.COM f, HOSTBRIDGE, topo_mod_errmsg(mod));
49410942STom.Pothier@Sun.COM continue;
49510942STom.Pothier@Sun.COM }
49610942STom.Pothier@Sun.COM
49710942STom.Pothier@Sun.COM smbc = &stypes[SUN_OEM_PCIEXRC];
49810942STom.Pothier@Sun.COM smbc->type = SUN_OEM_PCIEXRC;
49912832STrang.Do@Sun.COM x86pi_smb_strcnt(mod, smbc);
50010942STom.Pothier@Sun.COM for (i = 0; i < smbc->count; i++) {
50110942STom.Pothier@Sun.COM if (smbios_info_pciexrc(shp, smbc->ids[i].id,
50210942STom.Pothier@Sun.COM &hbr) != 0) {
50310942STom.Pothier@Sun.COM topo_mod_dprintf(mod,
50410942STom.Pothier@Sun.COM "smbios_info_pciexrc failed: "
50510942STom.Pothier@Sun.COM "id = %d\n", (int)smbc->ids[i].id);
50610942STom.Pothier@Sun.COM continue;
50710942STom.Pothier@Sun.COM }
50810942STom.Pothier@Sun.COM
50910942STom.Pothier@Sun.COM if (hbr.smbpcie_bb != bb_smbid)
51010942STom.Pothier@Sun.COM continue;
51112832STrang.Do@Sun.COM rv = x86pi_gen_hbr(mod, basebd_node,
51210942STom.Pothier@Sun.COM smbc->ids[i].id, hbri, &rci);
51310942STom.Pothier@Sun.COM if (rv != 0)
51410942STom.Pothier@Sun.COM topo_mod_dprintf(mod,
51510942STom.Pothier@Sun.COM "couldn't create hostbridge=%d\n", hbri);
51610942STom.Pothier@Sun.COM hbri++;
51710942STom.Pothier@Sun.COM }
51810942STom.Pothier@Sun.COM nbb++;
51910942STom.Pothier@Sun.COM
52010942STom.Pothier@Sun.COM } while (notvisited);
52110942STom.Pothier@Sun.COM
52210942STom.Pothier@Sun.COM return (0);
52310942STom.Pothier@Sun.COM }
524