xref: /onnv-gate/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_bboard.c (revision 12832:f4172e28e09f)
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 /*
23*12832STrang.Do@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  * Create Base Board (MB) topology node from SMBIOS Type 2 structure
2810942STom.Pothier@Sun.COM  */
2910942STom.Pothier@Sun.COM 
3010942STom.Pothier@Sun.COM #include <sys/types.h>
3110942STom.Pothier@Sun.COM #include <strings.h>
3210942STom.Pothier@Sun.COM #include <fm/topo_mod.h>
3310942STom.Pothier@Sun.COM #include <fm/topo_hc.h>
3410942STom.Pothier@Sun.COM #include <sys/systeminfo.h>
3510942STom.Pothier@Sun.COM #include <sys/smbios_impl.h>
3610942STom.Pothier@Sun.COM #include <sys/smbios.h>
3710942STom.Pothier@Sun.COM #include <x86pi_impl.h>
3810942STom.Pothier@Sun.COM 
3910942STom.Pothier@Sun.COM /* base baoed type values to hc-canonical-name */
4010942STom.Pothier@Sun.COM static const struct x86pi_bb_name {
4110942STom.Pothier@Sun.COM 	int type;
4210942STom.Pothier@Sun.COM 	const char *name;
4310942STom.Pothier@Sun.COM } x86pi_bb_names[] = {
4410942STom.Pothier@Sun.COM 	{ SMB_BBT_SBLADE,	"systemboard" },
4510942STom.Pothier@Sun.COM 	{ SMB_BBT_PROC,		"cpuboard" },
4610942STom.Pothier@Sun.COM 	{ SMB_BBT_IO,		"ioboard" },
4710942STom.Pothier@Sun.COM 	{ SMB_BBT_MEM,		"memboard" },
4810942STom.Pothier@Sun.COM 	{ SMB_BBT_DAUGHTER,	"systemboard" },
4910942STom.Pothier@Sun.COM 	{ SMB_BBT_MOTHER,	"motherboard" },
5010942STom.Pothier@Sun.COM 	{ SMB_BBT_PROCMEM,	"systemboard" },
5110942STom.Pothier@Sun.COM 	{ SMB_BBT_PROCIO,	"systemboard" },
5210942STom.Pothier@Sun.COM 	{ SMB_BBT_INTER,	"systemboard" },
5310942STom.Pothier@Sun.COM 	{ 0x00 }
5410942STom.Pothier@Sun.COM };
5510942STom.Pothier@Sun.COM 
5610942STom.Pothier@Sun.COM tnode_t *
x86pi_gen_bboard(topo_mod_t * mod,tnode_t * t_parent,int smb_id,int instance,int psmb_id)57*12832STrang.Do@Sun.COM x86pi_gen_bboard(topo_mod_t *mod, tnode_t *t_parent, int smb_id,
58*12832STrang.Do@Sun.COM     int instance, int psmb_id)
5910942STom.Pothier@Sun.COM {
6010942STom.Pothier@Sun.COM 	int		rv;
6110942STom.Pothier@Sun.COM 	smbios_info_t	ip;
6210942STom.Pothier@Sun.COM 	smbios_bboard_t	bb;
6310942STom.Pothier@Sun.COM 	smbios_struct_t	sp;
6410942STom.Pothier@Sun.COM 	x86pi_hcfmri_t	bb_hcfmri;
6510942STom.Pothier@Sun.COM 	tnode_t		*bb_node;
6610942STom.Pothier@Sun.COM 	const struct x86pi_bb_name *bbnp;
6710942STom.Pothier@Sun.COM 	static int	cpuboard = 0;
6810942STom.Pothier@Sun.COM 	static int	memboard = 0;
6910942STom.Pothier@Sun.COM 	static int	ioboard = 0;
7010942STom.Pothier@Sun.COM 	static int	systemboard = 0;
7110942STom.Pothier@Sun.COM 	static int	motherboard = 0;
7210942STom.Pothier@Sun.COM 	char		*f = "x86pi_gen_bboard";
73*12832STrang.Do@Sun.COM 	smbios_hdl_t    *shp;
7410942STom.Pothier@Sun.COM 
7510942STom.Pothier@Sun.COM 	topo_mod_dprintf(mod, "%s\n", f);
7610942STom.Pothier@Sun.COM 
77*12832STrang.Do@Sun.COM 	shp = topo_mod_smbios(mod);
78*12832STrang.Do@Sun.COM 	if (shp == NULL) {
79*12832STrang.Do@Sun.COM 		topo_mod_dprintf(mod, "%s: failed to load SMBIOS\n", f);
80*12832STrang.Do@Sun.COM 		return (NULL);
81*12832STrang.Do@Sun.COM 	}
82*12832STrang.Do@Sun.COM 
8310942STom.Pothier@Sun.COM 	/* SMBIOS Base Board struct */
8410942STom.Pothier@Sun.COM 	rv = smbios_info_bboard(shp, smb_id, &bb);
8510942STom.Pothier@Sun.COM 	if (rv != 0) {
8610942STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: smbios_info_bboard() failed\n", f);
8710942STom.Pothier@Sun.COM 		return (NULL);
8810942STom.Pothier@Sun.COM 	}
8910942STom.Pothier@Sun.COM 	(void) smbios_lookup_id(shp, psmb_id, &sp);
9010942STom.Pothier@Sun.COM 	if (sp.smbstr_type == SMB_TYPE_CHASSIS &&
9110942STom.Pothier@Sun.COM 	    bb.smbb_chassis != psmb_id) {
9210942STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: base board (%d) does not belong to "
9310942STom.Pothier@Sun.COM 		    "chassis (%d)\n", f, smb_id, psmb_id);
9410942STom.Pothier@Sun.COM 		return (NULL);
9510942STom.Pothier@Sun.COM 	}
9610942STom.Pothier@Sun.COM 
9710942STom.Pothier@Sun.COM 	/* SMBIOS Base Board strings */
9810942STom.Pothier@Sun.COM 	rv = smbios_info_common(shp, smb_id, &ip);
9910942STom.Pothier@Sun.COM 	if (rv != 0) {
10010942STom.Pothier@Sun.COM 		return (NULL);
10110942STom.Pothier@Sun.COM 	}
10210942STom.Pothier@Sun.COM 
10310942STom.Pothier@Sun.COM 	/*
10410942STom.Pothier@Sun.COM 	 * populate string entries
10510942STom.Pothier@Sun.COM 	 *
10610942STom.Pothier@Sun.COM 	 * We don't set "product" because it may contain characters
10710942STom.Pothier@Sun.COM 	 * unacceptable by fmri.   topo_mod_auth() will set the product-id
10810942STom.Pothier@Sun.COM 	 * for us and call topo_cleanup_auth_str() when necessary.
10910942STom.Pothier@Sun.COM 	 */
11010942STom.Pothier@Sun.COM 	bb_hcfmri.serial_number = x86pi_cleanup_smbios_str(mod,
11110942STom.Pothier@Sun.COM 	    ip.smbi_serial, 0);
11210942STom.Pothier@Sun.COM 	bb_hcfmri.version = x86pi_cleanup_smbios_str(mod, ip.smbi_version, 0);
11310942STom.Pothier@Sun.COM 	/* asset tag string contains the part number */
11410942STom.Pothier@Sun.COM 	bb_hcfmri.part_number = x86pi_cleanup_smbios_str(mod,
11510942STom.Pothier@Sun.COM 	    ip.smbi_asset, 0);
11610942STom.Pothier@Sun.COM 	bb_hcfmri.location = x86pi_cleanup_smbios_str(mod, ip.smbi_location, 0);
11710942STom.Pothier@Sun.COM 
11810942STom.Pothier@Sun.COM 	/* determine the hc-name */
11910942STom.Pothier@Sun.COM 	for (bbnp = x86pi_bb_names; bbnp->type != 0x00; bbnp++) {
12010942STom.Pothier@Sun.COM 		if (bbnp->type == bb.smbb_type) {
12110942STom.Pothier@Sun.COM 			switch (bbnp->type) {
12210942STom.Pothier@Sun.COM 				case SMB_BBT_PROC :
12310942STom.Pothier@Sun.COM 					instance = cpuboard++;
12410942STom.Pothier@Sun.COM 					break;
12510942STom.Pothier@Sun.COM 				case SMB_BBT_IO :
12610942STom.Pothier@Sun.COM 					instance = ioboard++;
12710942STom.Pothier@Sun.COM 					break;
12810942STom.Pothier@Sun.COM 				case SMB_BBT_MEM :
12910942STom.Pothier@Sun.COM 					instance = memboard++;
13010942STom.Pothier@Sun.COM 					break;
13110942STom.Pothier@Sun.COM 				case SMB_BBT_MOTHER :
13210942STom.Pothier@Sun.COM 					instance = motherboard++;
13310942STom.Pothier@Sun.COM 					break;
13410942STom.Pothier@Sun.COM 				default :
13510942STom.Pothier@Sun.COM 					/*
13610942STom.Pothier@Sun.COM 					 * Enumerate any other baseboard type
13710942STom.Pothier@Sun.COM 					 * as systemboard.
13810942STom.Pothier@Sun.COM 					 *
13910942STom.Pothier@Sun.COM 					 * SMB_BBT_UNKNOWN
14010942STom.Pothier@Sun.COM 					 * SMB_BBT_OTHER
14110942STom.Pothier@Sun.COM 					 * SMB_BBT_SBLADE
14210942STom.Pothier@Sun.COM 					 * SMB_BBT_CSWITCH
14310942STom.Pothier@Sun.COM 					 * SMB_BBT_SMM
14410942STom.Pothier@Sun.COM 					 * SMB_BBT_DAUGHTER
14510942STom.Pothier@Sun.COM 					 * SMB_BBT_PROCMEM
14610942STom.Pothier@Sun.COM 					 * SMB_BBT_PROCIO
14710942STom.Pothier@Sun.COM 					 * SMB_BBT_INTER
14810942STom.Pothier@Sun.COM 					 */
14910942STom.Pothier@Sun.COM 					instance = systemboard++;
15010942STom.Pothier@Sun.COM 					break;
15110942STom.Pothier@Sun.COM 			}
15210942STom.Pothier@Sun.COM 			break;
15310942STom.Pothier@Sun.COM 		}
15410942STom.Pothier@Sun.COM 	}
15510942STom.Pothier@Sun.COM 
15610942STom.Pothier@Sun.COM 	bb_hcfmri.instance = instance;
15710942STom.Pothier@Sun.COM 	if (bbnp->type != 0x00)
15810942STom.Pothier@Sun.COM 		bb_hcfmri.hc_name = topo_mod_strdup(mod, bbnp->name);
15910942STom.Pothier@Sun.COM 	else
16010942STom.Pothier@Sun.COM 		bb_hcfmri.hc_name = topo_mod_strdup(mod, "NULL");
16110942STom.Pothier@Sun.COM 
16210942STom.Pothier@Sun.COM 	topo_mod_dprintf(mod, "%s: S/N (%s)\n", f, bb_hcfmri.serial_number);
16310942STom.Pothier@Sun.COM 	topo_mod_dprintf(mod, "%s: version/N (%s)\n", f, bb_hcfmri.version);
16410942STom.Pothier@Sun.COM 	topo_mod_dprintf(mod, "%s: Part/N (%s)\n", f, bb_hcfmri.part_number);
16510942STom.Pothier@Sun.COM 	topo_mod_dprintf(mod, "%s: location (%s)\n", f, bb_hcfmri.location);
16610942STom.Pothier@Sun.COM 	topo_mod_dprintf(mod, "%s: instance (%d)\n", f, bb_hcfmri.instance);
16710942STom.Pothier@Sun.COM 	topo_mod_dprintf(mod, "%s: hc_name (%s)\n", f, bb_hcfmri.hc_name);
16810942STom.Pothier@Sun.COM 
16910942STom.Pothier@Sun.COM 	rv = x86pi_enum_generic(mod, &bb_hcfmri, t_parent, t_parent, &bb_node,
17010942STom.Pothier@Sun.COM 	    X86PI_ENUM_FRU);
17110942STom.Pothier@Sun.COM 	if (rv != 0) {
17210942STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: failed to create tnode %d\n", f,
17310942STom.Pothier@Sun.COM 		    instance);
17410942STom.Pothier@Sun.COM 		bb_node = NULL;
17510942STom.Pothier@Sun.COM 	}
17610942STom.Pothier@Sun.COM 
17710942STom.Pothier@Sun.COM 	/* free up strings */
17810942STom.Pothier@Sun.COM 	if (bb_hcfmri.hc_name != NULL) {
17910942STom.Pothier@Sun.COM 		topo_mod_strfree(mod, (char *)bb_hcfmri.hc_name);
18010942STom.Pothier@Sun.COM 	}
18110942STom.Pothier@Sun.COM 	if (bb_hcfmri.part_number != NULL) {
18210942STom.Pothier@Sun.COM 		topo_mod_strfree(mod, (char *)bb_hcfmri.part_number);
18310942STom.Pothier@Sun.COM 	}
18410942STom.Pothier@Sun.COM 	if (bb_hcfmri.serial_number != NULL) {
18510942STom.Pothier@Sun.COM 		topo_mod_strfree(mod, (char *)bb_hcfmri.serial_number);
18610942STom.Pothier@Sun.COM 	}
18710942STom.Pothier@Sun.COM 	if (bb_hcfmri.version != NULL) {
18810942STom.Pothier@Sun.COM 		topo_mod_strfree(mod, (char *)bb_hcfmri.version);
18910942STom.Pothier@Sun.COM 	}
19010942STom.Pothier@Sun.COM 	if (bb_hcfmri.location != NULL) {
19110942STom.Pothier@Sun.COM 		topo_mod_strfree(mod, (char *)bb_hcfmri.location);
19210942STom.Pothier@Sun.COM 	}
19310942STom.Pothier@Sun.COM 
19410942STom.Pothier@Sun.COM 	return (bb_node);
19510942STom.Pothier@Sun.COM }
19610942STom.Pothier@Sun.COM 
19710942STom.Pothier@Sun.COM 
19810942STom.Pothier@Sun.COM int
x86pi_bb_getchips(topo_mod_t * mod,int index,int nboards)199*12832STrang.Do@Sun.COM x86pi_bb_getchips(topo_mod_t *mod, int index, int nboards)
20010942STom.Pothier@Sun.COM {
20110942STom.Pothier@Sun.COM 	id_t		*cid;
20210942STom.Pothier@Sun.COM 	int		count;
20310942STom.Pothier@Sun.COM 	int		ncmp = 0;
20410942STom.Pothier@Sun.COM 	smbios_struct_t	sp;
20510942STom.Pothier@Sun.COM 	smbs_cnt_t	*smbc = NULL;
206*12832STrang.Do@Sun.COM 	smbios_hdl_t *shp;
207*12832STrang.Do@Sun.COM 
208*12832STrang.Do@Sun.COM 	shp = topo_mod_smbios(mod);
209*12832STrang.Do@Sun.COM 	if (shp == NULL)
210*12832STrang.Do@Sun.COM 		return (ncmp);
21110942STom.Pothier@Sun.COM 
21210942STom.Pothier@Sun.COM 	cid = stypes[SMB_TYPE_BASEBOARD].ids[index].con_ids;
21310942STom.Pothier@Sun.COM 	count = stypes[SMB_TYPE_BASEBOARD].ids[index].con_cnt;
21410942STom.Pothier@Sun.COM 
21510942STom.Pothier@Sun.COM 	for (int i = 0; i < count; i++) {
21610942STom.Pothier@Sun.COM 		(void) smbios_lookup_id(shp, cid[i], &sp);
21710942STom.Pothier@Sun.COM 		if (sp.smbstr_type == SMB_TYPE_PROCESSOR) {
21810942STom.Pothier@Sun.COM 			ncmp++;
21910942STom.Pothier@Sun.COM 		}
22010942STom.Pothier@Sun.COM 	}
22110942STom.Pothier@Sun.COM 
22210942STom.Pothier@Sun.COM 	/*
22310942STom.Pothier@Sun.COM 	 * If there are missing SMB_TYPE_PROCESSOR structures
22410942STom.Pothier@Sun.COM 	 * contained within SMB_TYPE_BASEBOARD, and if the
22510942STom.Pothier@Sun.COM 	 * system has only one baseboard we enumerate
22610942STom.Pothier@Sun.COM 	 * all processors under it.
22710942STom.Pothier@Sun.COM 	 */
22810942STom.Pothier@Sun.COM 	smbc = &stypes[SMB_TYPE_PROCESSOR];
22910942STom.Pothier@Sun.COM 	smbc->type = SMB_TYPE_PROCESSOR;
230*12832STrang.Do@Sun.COM 	x86pi_smb_strcnt(mod, smbc);
23110942STom.Pothier@Sun.COM 
23210942STom.Pothier@Sun.COM 	if (nboards == 1) {
23310942STom.Pothier@Sun.COM 		if (ncmp != stypes[SMB_TYPE_PROCESSOR].count)
23410942STom.Pothier@Sun.COM 			ncmp = stypes[SMB_TYPE_PROCESSOR].count;
23510942STom.Pothier@Sun.COM 	} else {
23610942STom.Pothier@Sun.COM 		if (ncmp == 0) {
23710942STom.Pothier@Sun.COM 			topo_mod_dprintf(mod, "failed to get processors"
23810942STom.Pothier@Sun.COM 			    " (or) no processors are contained"
23910942STom.Pothier@Sun.COM 			    " within baseboard instance %d, unable to"
24010942STom.Pothier@Sun.COM 			    " enumerate chips\n", index);
24110942STom.Pothier@Sun.COM 		}
24210942STom.Pothier@Sun.COM 	}
24310942STom.Pothier@Sun.COM 
24410942STom.Pothier@Sun.COM 	return (ncmp);
24510942STom.Pothier@Sun.COM }
24610942STom.Pothier@Sun.COM 
24710942STom.Pothier@Sun.COM 
24810942STom.Pothier@Sun.COM id_t
x86pi_bb_topparent(topo_mod_t * mod,int index,tnode_t ** pnode,id_t * psmbid)249*12832STrang.Do@Sun.COM x86pi_bb_topparent(topo_mod_t *mod, int index, tnode_t **pnode, id_t *psmbid)
25010942STom.Pothier@Sun.COM {
25110942STom.Pothier@Sun.COM 
25210942STom.Pothier@Sun.COM 	id_t	top_bb_smbid = -1;
25310942STom.Pothier@Sun.COM 	id_t	smb_id;
25410942STom.Pothier@Sun.COM 	int	bb_count, ch_count;
25510942STom.Pothier@Sun.COM 	smbios_struct_t	sp;
256*12832STrang.Do@Sun.COM 	smbios_hdl_t *shp;
257*12832STrang.Do@Sun.COM 
258*12832STrang.Do@Sun.COM 	shp = topo_mod_smbios(mod);
259*12832STrang.Do@Sun.COM 	if (shp == NULL)
260*12832STrang.Do@Sun.COM 		return (top_bb_smbid);
26110942STom.Pothier@Sun.COM 
26210942STom.Pothier@Sun.COM 	smb_id = stypes[SMB_TYPE_BASEBOARD].ids[index].con_by_id;
26310942STom.Pothier@Sun.COM 	(void) smbios_lookup_id(shp, smb_id, &sp);
26410942STom.Pothier@Sun.COM 
26510942STom.Pothier@Sun.COM 	if (sp.smbstr_type == SMB_TYPE_CHASSIS) {
26610942STom.Pothier@Sun.COM 		top_bb_smbid = stypes[SMB_TYPE_BASEBOARD].ids[index].id;
26710942STom.Pothier@Sun.COM 		*psmbid = smb_id;
26810942STom.Pothier@Sun.COM 		ch_count = stypes[SMB_TYPE_CHASSIS].count;
26910942STom.Pothier@Sun.COM 		for (int i = 0; i < ch_count; i++)
27010942STom.Pothier@Sun.COM 			if (stypes[SMB_TYPE_CHASSIS].ids[i].id == *psmbid)
27110942STom.Pothier@Sun.COM 				*pnode = stypes[SMB_TYPE_CHASSIS].ids[i].node;
27210942STom.Pothier@Sun.COM 
27310942STom.Pothier@Sun.COM 		return (top_bb_smbid);
27410942STom.Pothier@Sun.COM 
27510942STom.Pothier@Sun.COM 	} else if (sp.smbstr_type == SMB_TYPE_BASEBOARD) {
27610942STom.Pothier@Sun.COM 		bb_count = stypes[SMB_TYPE_BASEBOARD].count;
27710942STom.Pothier@Sun.COM 		for (int i = 0; i < bb_count; i++) {
27810942STom.Pothier@Sun.COM 			if (stypes[SMB_TYPE_BASEBOARD].ids[i].id == smb_id) {
27910942STom.Pothier@Sun.COM 				if (stypes[SMB_TYPE_BASEBOARD].ids[i].visited
28010942STom.Pothier@Sun.COM 				    == X86PI_VISITED) {
28110942STom.Pothier@Sun.COM 					top_bb_smbid =
28210942STom.Pothier@Sun.COM 					    stypes[SMB_TYPE_BASEBOARD].\
28310942STom.Pothier@Sun.COM 					    ids[index].id;
28410942STom.Pothier@Sun.COM 					*pnode =
28510942STom.Pothier@Sun.COM 					    stypes[SMB_TYPE_BASEBOARD].ids[i].\
28610942STom.Pothier@Sun.COM 					    node;
28710942STom.Pothier@Sun.COM 					*psmbid =
28810942STom.Pothier@Sun.COM 					    stypes[SMB_TYPE_BASEBOARD].ids[i].\
28910942STom.Pothier@Sun.COM 					    id;
29010942STom.Pothier@Sun.COM 					break;
29110942STom.Pothier@Sun.COM 				}
292*12832STrang.Do@Sun.COM 				top_bb_smbid = x86pi_bb_topparent(mod,
29310942STom.Pothier@Sun.COM 				    i, pnode, psmbid);
29410942STom.Pothier@Sun.COM 				break;
29510942STom.Pothier@Sun.COM 			}
29610942STom.Pothier@Sun.COM 		}
29710942STom.Pothier@Sun.COM 	}
29810942STom.Pothier@Sun.COM 
29910942STom.Pothier@Sun.COM 	return (top_bb_smbid);
30010942STom.Pothier@Sun.COM }
30110942STom.Pothier@Sun.COM 
30210942STom.Pothier@Sun.COM 
30310942STom.Pothier@Sun.COM id_t
x86pi_bb_chassis(topo_mod_t * mod,id_t bb_smbid)304*12832STrang.Do@Sun.COM x86pi_bb_chassis(topo_mod_t *mod, id_t bb_smbid)
30510942STom.Pothier@Sun.COM {
30610942STom.Pothier@Sun.COM 	smbios_bboard_t	bb;
30710942STom.Pothier@Sun.COM 	int		rv;
308*12832STrang.Do@Sun.COM 	smbios_hdl_t *shp;
309*12832STrang.Do@Sun.COM 
310*12832STrang.Do@Sun.COM 	shp = topo_mod_smbios(mod);
311*12832STrang.Do@Sun.COM 	if (shp == NULL)
312*12832STrang.Do@Sun.COM 		return (-1);
31310942STom.Pothier@Sun.COM 
31410942STom.Pothier@Sun.COM 	rv = smbios_info_bboard(shp, bb_smbid, &bb);
31510942STom.Pothier@Sun.COM 	if (rv != 0)
31610942STom.Pothier@Sun.COM 		return (-1);
31710942STom.Pothier@Sun.COM 
31810942STom.Pothier@Sun.COM 	return (bb.smbb_chassis);
31910942STom.Pothier@Sun.COM }
32010942STom.Pothier@Sun.COM 
32110942STom.Pothier@Sun.COM 
32210942STom.Pothier@Sun.COM int
x86pi_bb_contains(topo_mod_t * mod)323*12832STrang.Do@Sun.COM x86pi_bb_contains(topo_mod_t *mod)
32410942STom.Pothier@Sun.COM {
32510942STom.Pothier@Sun.COM 	int		rv;
32610942STom.Pothier@Sun.COM 	id_t		smb_id;
32710942STom.Pothier@Sun.COM 	smbios_bboard_t	bb;
32810942STom.Pothier@Sun.COM 	int		bb_count = 0;
32910942STom.Pothier@Sun.COM 	uint_t		cont_cnt = 0;
33010942STom.Pothier@Sun.COM 	smbios_struct_t	sp;
331*12832STrang.Do@Sun.COM 	smbios_hdl_t *shp;
332*12832STrang.Do@Sun.COM 
333*12832STrang.Do@Sun.COM 	shp = topo_mod_smbios(mod);
334*12832STrang.Do@Sun.COM 	if (shp == NULL)
335*12832STrang.Do@Sun.COM 		return (-1);
33610942STom.Pothier@Sun.COM 
33710942STom.Pothier@Sun.COM 	bb_count = stypes[SMB_TYPE_BASEBOARD].count;
33810942STom.Pothier@Sun.COM 	for (int i = 0; i < bb_count; i++) {
33910942STom.Pothier@Sun.COM 		smb_id = stypes[SMB_TYPE_BASEBOARD].ids[i].id;
34010942STom.Pothier@Sun.COM 		/* SMBIOS Base Board struct */
34110942STom.Pothier@Sun.COM 		rv = smbios_info_bboard(shp, smb_id, &bb);
34210942STom.Pothier@Sun.COM 		if (rv != 0)
34310942STom.Pothier@Sun.COM 			return (-1);
34410942STom.Pothier@Sun.COM 		/* Set Baseboard - Chassis Relationship */
34510942STom.Pothier@Sun.COM 		if (stypes[SMB_TYPE_BASEBOARD].ids[i].con_by_id == 0) {
34610942STom.Pothier@Sun.COM 			stypes[SMB_TYPE_BASEBOARD].ids[i].con_by_id =
347*12832STrang.Do@Sun.COM 			    rv = x86pi_bb_chassis(mod, smb_id);
34810942STom.Pothier@Sun.COM 			if (rv == -1) {
34910942STom.Pothier@Sun.COM 				topo_mod_dprintf(mod, " failed to get"
35010942STom.Pothier@Sun.COM 				    " the chassis handle\n");
35110942STom.Pothier@Sun.COM 				return (rv);
35210942STom.Pothier@Sun.COM 			}
35310942STom.Pothier@Sun.COM 		}
35410942STom.Pothier@Sun.COM 
35510942STom.Pothier@Sun.COM 		/* SMBIOS contained object handles */
35610942STom.Pothier@Sun.COM 		cont_cnt = bb.smbb_contn;
35710942STom.Pothier@Sun.COM 		if (cont_cnt > 0) {
35810942STom.Pothier@Sun.COM 			id_t *cont_hdl;
35910942STom.Pothier@Sun.COM 			uint16_t hdl;
36010942STom.Pothier@Sun.COM 
36110942STom.Pothier@Sun.COM 			/* allocate space for and get contained handles */
36210942STom.Pothier@Sun.COM 			cont_hdl = topo_mod_alloc(mod, cont_cnt *
36310942STom.Pothier@Sun.COM 			    sizeof (id_t));
36410942STom.Pothier@Sun.COM 			rv = smbios_info_contains(shp, smb_id, cont_cnt,
36510942STom.Pothier@Sun.COM 			    cont_hdl);
36610942STom.Pothier@Sun.COM 			if (rv > SMB_CONT_MAX) {
36710942STom.Pothier@Sun.COM 				topo_mod_free(mod, cont_hdl, cont_cnt *
36810942STom.Pothier@Sun.COM 				    sizeof (id_t));
36910942STom.Pothier@Sun.COM 				return (-1);
37010942STom.Pothier@Sun.COM 			}
37110942STom.Pothier@Sun.COM 			cont_cnt = MIN(rv, cont_cnt);
37210942STom.Pothier@Sun.COM 
37310942STom.Pothier@Sun.COM 			/* attach contained handles */
37410942STom.Pothier@Sun.COM 			stypes[SMB_TYPE_BASEBOARD].ids[i].con_cnt = cont_cnt;
37510942STom.Pothier@Sun.COM 			for (int j = 0; j < cont_cnt; j++) {
37610942STom.Pothier@Sun.COM 				hdl = (uint16_t)cont_hdl[j];
37710942STom.Pothier@Sun.COM 				topo_mod_dprintf(mod, "id %d contained handle"
37810942STom.Pothier@Sun.COM 				    " %d: %d\n", i, j, hdl);
37910942STom.Pothier@Sun.COM 				stypes[SMB_TYPE_BASEBOARD].ids[i].\
38010942STom.Pothier@Sun.COM 				    con_ids[j] = hdl;
38110942STom.Pothier@Sun.COM 				(void) smbios_lookup_id(shp, hdl, &sp);
38210942STom.Pothier@Sun.COM 				if (sp.smbstr_type == SMB_TYPE_BASEBOARD) {
38310942STom.Pothier@Sun.COM 					for (int k = 0; k < bb_count; k++)
38410942STom.Pothier@Sun.COM 						if (stypes[SMB_TYPE_BASEBOARD].\
38510942STom.Pothier@Sun.COM 						    ids[k].id == hdl)
38610942STom.Pothier@Sun.COM 							stypes[\
38710942STom.Pothier@Sun.COM 							    SMB_TYPE_BASEBOARD\
38810942STom.Pothier@Sun.COM 							    ].ids[k].con_by_id =
38910942STom.Pothier@Sun.COM 							    smb_id;
39010942STom.Pothier@Sun.COM 				}
39110942STom.Pothier@Sun.COM 			}
39210942STom.Pothier@Sun.COM 			topo_mod_free(mod, cont_hdl, cont_cnt * sizeof (id_t));
39310942STom.Pothier@Sun.COM 		}
39410942STom.Pothier@Sun.COM 	}
39510942STom.Pothier@Sun.COM 	return (0);
39610942STom.Pothier@Sun.COM }
397