xref: /onnv-gate/usr/src/lib/fm/topo/modules/i86pc/x86pi/x86pi_bay.c (revision 12832:f4172e28e09f)
111859STom.Pothier@Sun.COM /*
211859STom.Pothier@Sun.COM  * CDDL HEADER START
311859STom.Pothier@Sun.COM  *
411859STom.Pothier@Sun.COM  * The contents of this file are subject to the terms of the
511859STom.Pothier@Sun.COM  * Common Development and Distribution License (the "License").
611859STom.Pothier@Sun.COM  * You may not use this file except in compliance with the License.
711859STom.Pothier@Sun.COM  *
811859STom.Pothier@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911859STom.Pothier@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1011859STom.Pothier@Sun.COM  * See the License for the specific language governing permissions
1111859STom.Pothier@Sun.COM  * and limitations under the License.
1211859STom.Pothier@Sun.COM  *
1311859STom.Pothier@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1411859STom.Pothier@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511859STom.Pothier@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1611859STom.Pothier@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1711859STom.Pothier@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1811859STom.Pothier@Sun.COM  *
1911859STom.Pothier@Sun.COM  * CDDL HEADER END
2011859STom.Pothier@Sun.COM  */
2111859STom.Pothier@Sun.COM 
2211859STom.Pothier@Sun.COM /*
23*12832STrang.Do@Sun.COM  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2411859STom.Pothier@Sun.COM  */
2511859STom.Pothier@Sun.COM 
2611859STom.Pothier@Sun.COM /*
2711859STom.Pothier@Sun.COM  * Create bay topology node from SMBIOS Type 136 structure, call the disk
2811859STom.Pothier@Sun.COM  * enumerator to enumerate a SATA direct attached disk.
2911859STom.Pothier@Sun.COM  */
3011859STom.Pothier@Sun.COM 
3111859STom.Pothier@Sun.COM #include <sys/types.h>
3211859STom.Pothier@Sun.COM #include <strings.h>
3311859STom.Pothier@Sun.COM #include <fm/topo_mod.h>
3411859STom.Pothier@Sun.COM #include <fm/topo_hc.h>
3511859STom.Pothier@Sun.COM #include <sys/systeminfo.h>
3611859STom.Pothier@Sun.COM #include <sys/smbios_impl.h>
3711859STom.Pothier@Sun.COM #include <x86pi_impl.h>
3811859STom.Pothier@Sun.COM 
3911859STom.Pothier@Sun.COM #define	DEVICES			"/devices"
4011859STom.Pothier@Sun.COM #define	HBA_DRV_NAME		"ahci"
4111859STom.Pothier@Sun.COM 
4211859STom.Pothier@Sun.COM #define	BDF(b, df) ((uint16_t)((((uint16_t)(b) << 8) & 0xFF00) | \
4311859STom.Pothier@Sun.COM 				((uint16_t)(df) & 0x00FF)));
4411859STom.Pothier@Sun.COM 
4511859STom.Pothier@Sun.COM static const topo_pgroup_info_t io_pgroup = {
4611859STom.Pothier@Sun.COM 	TOPO_PGROUP_IO,
4711859STom.Pothier@Sun.COM 	TOPO_STABILITY_PRIVATE,
4811859STom.Pothier@Sun.COM 	TOPO_STABILITY_PRIVATE,
4911859STom.Pothier@Sun.COM 	1
5011859STom.Pothier@Sun.COM };
5111859STom.Pothier@Sun.COM 
5211859STom.Pothier@Sun.COM static const topo_pgroup_info_t binding_pgroup = {
5311859STom.Pothier@Sun.COM 	TOPO_PGROUP_BINDING,
5411859STom.Pothier@Sun.COM 	TOPO_STABILITY_PRIVATE,
5511859STom.Pothier@Sun.COM 	TOPO_STABILITY_PRIVATE,
5611859STom.Pothier@Sun.COM 	1
5711859STom.Pothier@Sun.COM };
5811859STom.Pothier@Sun.COM 
5911859STom.Pothier@Sun.COM /*
6011859STom.Pothier@Sun.COM  * Return PCI Bus/Dev/Func
6111859STom.Pothier@Sun.COM  */
6211859STom.Pothier@Sun.COM int
bay_bdf(topo_mod_t * mod,smbios_port_ext_t * epp,uint16_t * bdf)63*12832STrang.Do@Sun.COM bay_bdf(topo_mod_t *mod, smbios_port_ext_t *epp, uint16_t *bdf)
6411859STom.Pothier@Sun.COM {
6511859STom.Pothier@Sun.COM 	int	devt;
6611859STom.Pothier@Sun.COM 	id_t	dev_id;
6711859STom.Pothier@Sun.COM 	uint8_t	bus, dev_funct;
6811859STom.Pothier@Sun.COM 
6911859STom.Pothier@Sun.COM 	char	*f = "bay_bdf";
70*12832STrang.Do@Sun.COM 	smbios_hdl_t *shp;
7111859STom.Pothier@Sun.COM 
72*12832STrang.Do@Sun.COM 	shp = topo_mod_smbios(mod);
73*12832STrang.Do@Sun.COM 	if (shp == NULL) {
74*12832STrang.Do@Sun.COM 		topo_mod_dprintf(mod, "%s: failed to load SMBIOS\n", f);
75*12832STrang.Do@Sun.COM 		return (-1);
76*12832STrang.Do@Sun.COM 	}
7711859STom.Pothier@Sun.COM 	/*
7811859STom.Pothier@Sun.COM 	 * Depending on device type, BDF comes from either slot (type-9) or
7911859STom.Pothier@Sun.COM 	 * on-board (type-41) SMBIOS structure.
8011859STom.Pothier@Sun.COM 	 */
8111859STom.Pothier@Sun.COM 	devt = epp->smbporte_dtype;
8211859STom.Pothier@Sun.COM 	dev_id = epp->smbporte_devhdl;
8311859STom.Pothier@Sun.COM 
8411859STom.Pothier@Sun.COM 	if (devt == SMB_TYPE_SLOT) {
8511859STom.Pothier@Sun.COM 		smbios_slot_t slot;
8611859STom.Pothier@Sun.COM 		(void) smbios_info_slot(shp, dev_id, &slot);
8711859STom.Pothier@Sun.COM 		bus = slot.smbl_bus;
8811859STom.Pothier@Sun.COM 		dev_funct = slot.smbl_df;
8911859STom.Pothier@Sun.COM 	} else if (devt == SMB_TYPE_OBDEVEXT) {
9011859STom.Pothier@Sun.COM 		smbios_obdev_ext_t ob;
9111859STom.Pothier@Sun.COM 		(void) smbios_info_obdevs_ext(shp, dev_id, &ob);
9211859STom.Pothier@Sun.COM 		bus = ob.smboe_bus;
9311859STom.Pothier@Sun.COM 		dev_funct = ob.smboe_df;
9411859STom.Pothier@Sun.COM 	} else {
9511859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: unknown device type: %d\n",
9611859STom.Pothier@Sun.COM 		    f, devt);
9711859STom.Pothier@Sun.COM 		return (-1);
9811859STom.Pothier@Sun.COM 	}
9911859STom.Pothier@Sun.COM 	topo_mod_dprintf(mod, "%s: %s: bus(0x%02x) dev/func(0x%02x)\n", f,
10011859STom.Pothier@Sun.COM 	    devt == SMB_TYPE_SLOT ? "slot" : "ob dev", bus, dev_funct);
10111859STom.Pothier@Sun.COM 
10211859STom.Pothier@Sun.COM 	*bdf = BDF(bus, dev_funct);
10311859STom.Pothier@Sun.COM 
10411859STom.Pothier@Sun.COM 	return (0);
10511859STom.Pothier@Sun.COM }
10611859STom.Pothier@Sun.COM 
10711859STom.Pothier@Sun.COM /*
10811859STom.Pothier@Sun.COM  * Decorate topo node with pgroups.
10911859STom.Pothier@Sun.COM  */
11011859STom.Pothier@Sun.COM int
bay_pgroups(topo_mod_t * mod,tnode_t * tnp,di_node_t * dnp,di_node_t * sibp,char * minor_name)11111859STom.Pothier@Sun.COM bay_pgroups(topo_mod_t *mod, tnode_t *tnp, di_node_t *dnp, di_node_t *sibp,
11211859STom.Pothier@Sun.COM     char *minor_name)
11311859STom.Pothier@Sun.COM {
11411859STom.Pothier@Sun.COM 	int		rv, err;
11511859STom.Pothier@Sun.COM 	char		*ap_path, *oc_path;
11611859STom.Pothier@Sun.COM 
11711859STom.Pothier@Sun.COM 	char		*f = "bay_pgoups";
11811859STom.Pothier@Sun.COM 
11911859STom.Pothier@Sun.COM 	/*
12011859STom.Pothier@Sun.COM 	 * Create "io" pgroup and attachment point path.
12111859STom.Pothier@Sun.COM 	 */
12211859STom.Pothier@Sun.COM 	rv = topo_pgroup_create(tnp, &io_pgroup, &err);
12311859STom.Pothier@Sun.COM 	if (rv != 0) {
12411859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod,
12511859STom.Pothier@Sun.COM 		    "%s: failed to create \"io\" pgroup: %s\n",
12611859STom.Pothier@Sun.COM 		    f, topo_strerror(err));
12711859STom.Pothier@Sun.COM 		(void) topo_mod_seterrno(mod, err);
12811859STom.Pothier@Sun.COM 		return (err);
12911859STom.Pothier@Sun.COM 	}
13011859STom.Pothier@Sun.COM 
13111859STom.Pothier@Sun.COM 	ap_path = topo_mod_alloc(mod, MAXPATHLEN);
13211859STom.Pothier@Sun.COM 	if (ap_path == NULL) {
13311859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: ap_path alloc failed\n");
13411859STom.Pothier@Sun.COM 		return (topo_mod_seterrno(mod, EMOD_NOMEM));
13511859STom.Pothier@Sun.COM 	}
13611859STom.Pothier@Sun.COM 	(void) snprintf(ap_path, MAXPATHLEN, "%s%s:%s", DEVICES,
13711859STom.Pothier@Sun.COM 	    di_devfs_path(*dnp), minor_name);
13811859STom.Pothier@Sun.COM 	topo_mod_dprintf(mod, "%s: ap_path(%s)\n", f, ap_path);
13911859STom.Pothier@Sun.COM 
14011859STom.Pothier@Sun.COM 	/* add ap-path */
14111859STom.Pothier@Sun.COM 	rv = topo_prop_set_string(tnp, TOPO_PGROUP_IO, TOPO_IO_AP_PATH,
14211859STom.Pothier@Sun.COM 	    TOPO_PROP_IMMUTABLE, ap_path, &err);
14311859STom.Pothier@Sun.COM 	if (rv != 0) {
14411859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: failed to set ap-path: %s\n",
14511859STom.Pothier@Sun.COM 		    f, topo_strerror(err));
14611859STom.Pothier@Sun.COM 		topo_mod_free(mod, ap_path, MAXPATHLEN);
14711859STom.Pothier@Sun.COM 		(void) topo_mod_seterrno(mod, err);
14811859STom.Pothier@Sun.COM 		return (err);
14911859STom.Pothier@Sun.COM 	}
15011859STom.Pothier@Sun.COM 	topo_mod_free(mod, ap_path, MAXPATHLEN);
15111859STom.Pothier@Sun.COM 
15211859STom.Pothier@Sun.COM 	/*
15311859STom.Pothier@Sun.COM 	 * Create "binding" pgroup and occupant path.
15411859STom.Pothier@Sun.COM 	 */
15511859STom.Pothier@Sun.COM 	rv = topo_pgroup_create(tnp, &binding_pgroup, &err);
15611859STom.Pothier@Sun.COM 	if (rv != 0) {
15711859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod,
15811859STom.Pothier@Sun.COM 		    "%s: failed to create \"io\" pgroup: %s\n",
15911859STom.Pothier@Sun.COM 		    f, topo_strerror(err));
16011859STom.Pothier@Sun.COM 		(void) topo_mod_seterrno(mod, err);
16111859STom.Pothier@Sun.COM 		return (err);
16211859STom.Pothier@Sun.COM 	}
16311859STom.Pothier@Sun.COM 
16411859STom.Pothier@Sun.COM 	oc_path = di_devfs_path(*sibp);
16511859STom.Pothier@Sun.COM 	if (oc_path == NULL) {
16611859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: no occupant path\n", f);
16711859STom.Pothier@Sun.COM 		return (-1);
16811859STom.Pothier@Sun.COM 	}
16911859STom.Pothier@Sun.COM 	topo_mod_dprintf(mod, "%s: oc_path(%s)\n", f, oc_path);
17011859STom.Pothier@Sun.COM 
17111859STom.Pothier@Sun.COM 	/* add ocupant-path */
17211859STom.Pothier@Sun.COM 	rv = topo_prop_set_string(tnp, TOPO_PGROUP_BINDING,
17311859STom.Pothier@Sun.COM 	    TOPO_BINDING_OCCUPANT, TOPO_PROP_IMMUTABLE, oc_path,
17411859STom.Pothier@Sun.COM 	    &err);
17511859STom.Pothier@Sun.COM 	if (rv != 0) {
17611859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: failed to set ap-path: %s\n",
17711859STom.Pothier@Sun.COM 		    f, topo_strerror(err));
17811859STom.Pothier@Sun.COM 		di_devfs_path_free(oc_path);
17911859STom.Pothier@Sun.COM 		(void) topo_mod_seterrno(mod, err);
18011859STom.Pothier@Sun.COM 		return (err);
18111859STom.Pothier@Sun.COM 	}
18211859STom.Pothier@Sun.COM 	di_devfs_path_free(oc_path);
18311859STom.Pothier@Sun.COM 
18411859STom.Pothier@Sun.COM 	return (0);
18511859STom.Pothier@Sun.COM }
18611859STom.Pothier@Sun.COM 
18711859STom.Pothier@Sun.COM int
bay_update_tnode(topo_mod_t * mod,tnode_t * tnodep,uint16_t bdf,int phy)18811859STom.Pothier@Sun.COM bay_update_tnode(topo_mod_t *mod, tnode_t *tnodep, uint16_t bdf, int phy)
18911859STom.Pothier@Sun.COM {
19011859STom.Pothier@Sun.COM 	int		rv;
19111859STom.Pothier@Sun.COM 	int		minor_cnt = 0;
19211859STom.Pothier@Sun.COM 	char		*minor_name = NULL;
19311859STom.Pothier@Sun.COM 	di_node_t	devtree, dnode, sib;
19411859STom.Pothier@Sun.COM 	di_minor_t	minor = DI_MINOR_NIL;
19511859STom.Pothier@Sun.COM 
19611859STom.Pothier@Sun.COM 	char		*f = "bay_update_tnode";
19711859STom.Pothier@Sun.COM 
19811859STom.Pothier@Sun.COM 	/*
19911859STom.Pothier@Sun.COM 	 * Find HBA device node from BDF.
20011859STom.Pothier@Sun.COM 	 */
20111859STom.Pothier@Sun.COM 	devtree = topo_mod_devinfo(mod);
20211859STom.Pothier@Sun.COM 	if (devtree == DI_NODE_NIL) {
20311859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: failed to get dev tree\n", f);
20411859STom.Pothier@Sun.COM 		return (-1);
20511859STom.Pothier@Sun.COM 	}
20611859STom.Pothier@Sun.COM 	for (dnode = di_drv_first_node(HBA_DRV_NAME, devtree);
20711859STom.Pothier@Sun.COM 	    dnode != DI_NODE_NIL;
20811859STom.Pothier@Sun.COM 	    dnode = di_drv_next_node(dnode)) {
20911859STom.Pothier@Sun.COM 		if (bdf == x86pi_bdf(mod, dnode)) {
21011859STom.Pothier@Sun.COM 			/*
21111859STom.Pothier@Sun.COM 			 * Match child node from PHY.
21211859STom.Pothier@Sun.COM 			 */
21311859STom.Pothier@Sun.COM 			sib = di_child_node(dnode);
21411859STom.Pothier@Sun.COM 			while (sib != DI_NODE_NIL) {
21511859STom.Pothier@Sun.COM 				if (phy == x86pi_phy(mod, sib))
21611859STom.Pothier@Sun.COM 					break;
21711859STom.Pothier@Sun.COM 				sib = di_sibling_node(sib);
21811859STom.Pothier@Sun.COM 			}
21911859STom.Pothier@Sun.COM 			break;
22011859STom.Pothier@Sun.COM 		}
22111859STom.Pothier@Sun.COM 	}
22211859STom.Pothier@Sun.COM 	if (dnode == DI_NODE_NIL) {
22311859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: no HBA di_node\n", f);
22411859STom.Pothier@Sun.COM 		return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
22511859STom.Pothier@Sun.COM 	}
22611859STom.Pothier@Sun.COM 
22711859STom.Pothier@Sun.COM 	/*
22811859STom.Pothier@Sun.COM 	 * HBA attachment point minor node name.
22911859STom.Pothier@Sun.COM 	 */
23011859STom.Pothier@Sun.COM 	while ((minor = di_minor_next(dnode, minor)) != DI_MINOR_NIL) {
23111859STom.Pothier@Sun.COM 		if (strncmp(DDI_NT_SATA_ATTACHMENT_POINT,
23211859STom.Pothier@Sun.COM 		    di_minor_nodetype(minor),
23311859STom.Pothier@Sun.COM 		    strlen(DDI_NT_SATA_ATTACHMENT_POINT)) == 0) {
23411859STom.Pothier@Sun.COM 			if (phy == minor_cnt++) {
23511859STom.Pothier@Sun.COM 				minor_name = di_minor_name(minor);
23611859STom.Pothier@Sun.COM 				topo_mod_dprintf(mod,
23711859STom.Pothier@Sun.COM 				    "%s: phy(%d) minor name(%s)\n",
23811859STom.Pothier@Sun.COM 				    f, phy, minor_name);
23911859STom.Pothier@Sun.COM 				break;
24011859STom.Pothier@Sun.COM 			}
24111859STom.Pothier@Sun.COM 		}
24211859STom.Pothier@Sun.COM 	}
24311859STom.Pothier@Sun.COM 
24411859STom.Pothier@Sun.COM 	rv = bay_pgroups(mod, tnodep, &dnode, &sib, minor_name);
24511859STom.Pothier@Sun.COM 	if (rv != 0) {
24611859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: failed to add pgroups\n", f);
24711859STom.Pothier@Sun.COM 		return (-1);
24811859STom.Pothier@Sun.COM 	}
24911859STom.Pothier@Sun.COM 
25011859STom.Pothier@Sun.COM 
25111859STom.Pothier@Sun.COM 	return (0);
25211859STom.Pothier@Sun.COM }
25311859STom.Pothier@Sun.COM 
25411859STom.Pothier@Sun.COM /*
25511859STom.Pothier@Sun.COM  * x86pi_gen_bay:
25611859STom.Pothier@Sun.COM  *   create "bay" node
25711859STom.Pothier@Sun.COM  *   call "disk" enum passing in "bay" node
25811859STom.Pothier@Sun.COM  */
25911859STom.Pothier@Sun.COM int
x86pi_gen_bay(topo_mod_t * mod,tnode_t * t_parent,smbios_port_ext_t * eport,int instance)260*12832STrang.Do@Sun.COM x86pi_gen_bay(topo_mod_t *mod, tnode_t *t_parent, smbios_port_ext_t *eport,
261*12832STrang.Do@Sun.COM     int instance)
26211859STom.Pothier@Sun.COM {
26311859STom.Pothier@Sun.COM 	int		rv;
26411859STom.Pothier@Sun.COM 	int		min = 0, max = 0;
26511859STom.Pothier@Sun.COM 	id_t		port_id;
26611859STom.Pothier@Sun.COM 	uint16_t	bdf;
26711859STom.Pothier@Sun.COM 	smbios_port_t	smb_port;
26811859STom.Pothier@Sun.COM 	x86pi_hcfmri_t	hcfmri = {0};
26911859STom.Pothier@Sun.COM 	tnode_t		*tn_bay;
27011859STom.Pothier@Sun.COM 
27111859STom.Pothier@Sun.COM 	char		*f = "x86pi_gen_disk";
272*12832STrang.Do@Sun.COM 	smbios_hdl_t *shp;
273*12832STrang.Do@Sun.COM 
274*12832STrang.Do@Sun.COM 	shp = topo_mod_smbios(mod);
275*12832STrang.Do@Sun.COM 	if (shp == NULL) {
276*12832STrang.Do@Sun.COM 		topo_mod_dprintf(mod, "%s: failed to load SMBIOS\n", f);
277*12832STrang.Do@Sun.COM 		return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
278*12832STrang.Do@Sun.COM 	}
27911859STom.Pothier@Sun.COM 
28011859STom.Pothier@Sun.COM 	/*
28111859STom.Pothier@Sun.COM 	 * Label comes from the port (type-8) SMBIOS structure.
28211859STom.Pothier@Sun.COM 	 */
28311859STom.Pothier@Sun.COM 	port_id = eport->smbporte_port;
28411859STom.Pothier@Sun.COM 
28511859STom.Pothier@Sun.COM 	rv = smbios_info_port(shp, port_id, &smb_port);
28611859STom.Pothier@Sun.COM 	if (rv != 0) {
28711859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod,
28811859STom.Pothier@Sun.COM 		    "%s: failed to get port %d SMBIOS struct\n",
28911859STom.Pothier@Sun.COM 		    f, port_id);
29011859STom.Pothier@Sun.COM 		return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
29111859STom.Pothier@Sun.COM 	}
29211859STom.Pothier@Sun.COM 
29311859STom.Pothier@Sun.COM 	/*
29411859STom.Pothier@Sun.COM 	 * Fill in hcfmri info.
29511859STom.Pothier@Sun.COM 	 */
29611859STom.Pothier@Sun.COM 	hcfmri.hc_name = BAY;
29711859STom.Pothier@Sun.COM 	hcfmri.instance = instance;
29811859STom.Pothier@Sun.COM 	hcfmri.location = x86pi_cleanup_smbios_str(mod, smb_port.smbo_eref, 0);
29911859STom.Pothier@Sun.COM 
30011859STom.Pothier@Sun.COM 	/*
30111859STom.Pothier@Sun.COM 	 * Create "bay" node.
30211859STom.Pothier@Sun.COM 	 */
30311859STom.Pothier@Sun.COM 	rv = x86pi_enum_generic(mod, &hcfmri, t_parent, t_parent, &tn_bay, 0);
30411859STom.Pothier@Sun.COM 	if (rv != 0) {
30511859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod,
30611859STom.Pothier@Sun.COM 		    "%s: failed to create %s topo node: %d\n",
30711859STom.Pothier@Sun.COM 		    f, BAY, instance);
30811859STom.Pothier@Sun.COM 		return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
30911859STom.Pothier@Sun.COM 	}
31011859STom.Pothier@Sun.COM 
31111859STom.Pothier@Sun.COM 	/* free up location string */
31211859STom.Pothier@Sun.COM 	if (hcfmri.location != NULL) {
31311859STom.Pothier@Sun.COM 		topo_mod_strfree(mod, (char *)hcfmri.location);
31411859STom.Pothier@Sun.COM 	}
31511859STom.Pothier@Sun.COM 
31611859STom.Pothier@Sun.COM 	/*
31711859STom.Pothier@Sun.COM 	 * Determine the bay BDF.
31811859STom.Pothier@Sun.COM 	 */
319*12832STrang.Do@Sun.COM 	rv = bay_bdf(mod, eport, &bdf);
32011859STom.Pothier@Sun.COM 	if (rv != 0) {
32111859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: failed to get BDF\n", f);
32211859STom.Pothier@Sun.COM 		return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
32311859STom.Pothier@Sun.COM 	}
32411859STom.Pothier@Sun.COM 	topo_mod_dprintf(mod, "%s: BDF(0x%04x)\n", f, bdf);
32511859STom.Pothier@Sun.COM 
32611859STom.Pothier@Sun.COM 	/*
32711859STom.Pothier@Sun.COM 	 * Decorate bay topo node.
32811859STom.Pothier@Sun.COM 	 */
32911859STom.Pothier@Sun.COM 	rv = bay_update_tnode(mod, tn_bay, bdf, eport->smbporte_phy);
33011859STom.Pothier@Sun.COM 	if (rv != 0) {
33111859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: failed to decorate bay node\n", f);
33211859STom.Pothier@Sun.COM 		return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
33311859STom.Pothier@Sun.COM 	}
33411859STom.Pothier@Sun.COM 
33511859STom.Pothier@Sun.COM 	/*
33611859STom.Pothier@Sun.COM 	 * Call disk enum passing in decorated bay topo node.
33711859STom.Pothier@Sun.COM 	 */
33811859STom.Pothier@Sun.COM 	if (topo_mod_load(mod, DISK, TOPO_VERSION) == NULL) {
33911859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: Failed to load %s module: %s\n",
34011859STom.Pothier@Sun.COM 		    f, DISK, topo_strerror(topo_mod_errno(mod)));
34111859STom.Pothier@Sun.COM 		return (topo_mod_errno(mod));
34211859STom.Pothier@Sun.COM 	}
34311859STom.Pothier@Sun.COM 
34411859STom.Pothier@Sun.COM 	rv = topo_node_range_create(mod, tn_bay, DISK, min, max);
34511859STom.Pothier@Sun.COM 	if (rv != 0) {
34611859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: failed to create range: %s\n", f,
34711859STom.Pothier@Sun.COM 		    topo_strerror(topo_mod_errno(mod)));
34811859STom.Pothier@Sun.COM 		return (topo_mod_errno(mod));
34911859STom.Pothier@Sun.COM 	}
35011859STom.Pothier@Sun.COM 
35111859STom.Pothier@Sun.COM 	rv = topo_mod_enumerate(mod, tn_bay, DISK, DISK, min, max, NULL);
35211859STom.Pothier@Sun.COM 	if (rv != 0) {
35311859STom.Pothier@Sun.COM 		topo_mod_dprintf(mod, "%s: %s enumeration failed: %s\n", f,
35411859STom.Pothier@Sun.COM 		    DISK, topo_strerror(topo_mod_errno(mod)));
35511859STom.Pothier@Sun.COM 		return (topo_mod_errno(mod));
35611859STom.Pothier@Sun.COM 	}
35711859STom.Pothier@Sun.COM 
35811859STom.Pothier@Sun.COM 	topo_mod_dprintf(mod, "%s: done.\n", f);
35911859STom.Pothier@Sun.COM 
36011859STom.Pothier@Sun.COM 	return (0);
36111859STom.Pothier@Sun.COM }
362