xref: /onnv-gate/usr/src/lib/fm/topo/modules/i86pc/hostbridge/hb_i86pc.c (revision 10187:ad62e2dfbe0c)
11414Scindi /*
21414Scindi  * CDDL HEADER START
31414Scindi  *
41414Scindi  * The contents of this file are subject to the terms of the
51414Scindi  * Common Development and Distribution License (the "License").
61414Scindi  * You may not use this file except in compliance with the License.
71414Scindi  *
81414Scindi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91414Scindi  * or http://www.opensolaris.org/os/licensing.
101414Scindi  * See the License for the specific language governing permissions
111414Scindi  * and limitations under the License.
121414Scindi  *
131414Scindi  * When distributing Covered Code, include this CDDL HEADER in each
141414Scindi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151414Scindi  * If applicable, add the following below this CDDL HEADER, with the
161414Scindi  * fields enclosed by brackets "[]" replaced with your own identifying
171414Scindi  * information: Portions Copyright [yyyy] [name of copyright owner]
181414Scindi  *
191414Scindi  * CDDL HEADER END
201414Scindi  */
211414Scindi 
221414Scindi /*
23*10187SKrishna.Elango@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
241414Scindi  * Use is subject to license terms.
251414Scindi  */
261414Scindi 
271414Scindi #include <fm/topo_mod.h>
283062Scindi #include <fm/topo_hc.h>
291414Scindi #include <libdevinfo.h>
301865Sdilpreet #include <strings.h>
313062Scindi #include <pcibus.h>
323062Scindi #include <hostbridge.h>
333062Scindi #include <did.h>
343062Scindi #include <util.h>
351414Scindi 
361414Scindi static int
hb_process(topo_mod_t * mod,tnode_t * ptn,topo_instance_t hbi,di_node_t bn)373062Scindi hb_process(topo_mod_t *mod, tnode_t *ptn, topo_instance_t hbi, di_node_t bn)
381414Scindi {
391414Scindi 	tnode_t *hb;
403062Scindi 	did_t *hbdid;
411414Scindi 
423062Scindi 	if ((hbdid = did_create(mod, bn, 0, hbi, NO_RC, TRUST_BDF)) == NULL)
431414Scindi 		return (-1);
443062Scindi 	if ((hb = pcihostbridge_declare(mod, ptn, bn, hbi)) == NULL)
451414Scindi 		return (-1);
464328Scindi 	if (topo_mod_enumerate(mod,
474328Scindi 	    hb, PCI_BUS, PCI_BUS, 0, MAX_HB_BUSES, (void *)hbdid) < 0) {
484328Scindi 		topo_node_unbind(hb);
494328Scindi 		return (-1);
504328Scindi 	}
514328Scindi 
524328Scindi 	return (0);
531414Scindi }
541414Scindi 
551414Scindi static int
rc_process(topo_mod_t * mod,tnode_t * ptn,topo_instance_t hbi,di_node_t bn)563062Scindi rc_process(topo_mod_t *mod, tnode_t *ptn, topo_instance_t hbi, di_node_t bn)
571414Scindi {
581414Scindi 	tnode_t *hb;
591414Scindi 	tnode_t *rc;
603062Scindi 	did_t *hbdid;
611414Scindi 
623062Scindi 	if ((hbdid = did_create(mod, bn, 0, hbi, hbi, TRUST_BDF)) == NULL)
631414Scindi 		return (-1);
643062Scindi 	if ((hb = pciexhostbridge_declare(mod, ptn, bn, hbi)) == NULL)
651414Scindi 		return (-1);
663062Scindi 	if ((rc = pciexrc_declare(mod, hb, bn, hbi)) == NULL)
672027Ssethg 		return (-1);
684328Scindi 	if (topo_mod_enumerate(mod,
694328Scindi 	    rc, PCI_BUS, PCIEX_BUS, 0, MAX_HB_BUSES, (void *)hbdid) < 0) {
704328Scindi 		topo_node_unbind(hb);
714328Scindi 		topo_node_unbind(rc);
724328Scindi 		return (-1);
734328Scindi 	}
744328Scindi 
754328Scindi 	return (0);
761414Scindi }
771414Scindi 
781414Scindi 
791414Scindi int
pci_hostbridges_find(topo_mod_t * mod,tnode_t * ptn)803062Scindi pci_hostbridges_find(topo_mod_t *mod, tnode_t *ptn)
811414Scindi {
821414Scindi 	di_node_t devtree;
833062Scindi 	di_node_t pnode, cnode;
841414Scindi 	int hbcnt = 0;
851414Scindi 
861414Scindi 	/* Scan for buses, top-level devinfo nodes with the right driver */
873062Scindi 	devtree = topo_mod_devinfo(mod);
881414Scindi 	if (devtree == DI_NODE_NIL) {
892027Ssethg 		topo_mod_dprintf(mod, "devinfo init failed.");
901414Scindi 		topo_node_range_destroy(ptn, HOSTBRIDGE);
911414Scindi 		return (0);
921414Scindi 	}
931414Scindi 
941865Sdilpreet 	pnode = di_drv_first_node(PCI, devtree);
951865Sdilpreet 	while (pnode != DI_NODE_NIL) {
964328Scindi 		if (hb_process(mod, ptn, hbcnt, pnode) < 0) {
974328Scindi 			if (hbcnt == 0)
984328Scindi 				topo_node_range_destroy(ptn, HOSTBRIDGE);
992027Ssethg 			return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM));
1001414Scindi 		}
1014328Scindi 		hbcnt++;
1021865Sdilpreet 		pnode = di_drv_next_node(pnode);
1031414Scindi 	}
1041414Scindi 
1051414Scindi 	pnode = di_drv_first_node(NPE, devtree);
1061414Scindi 	while (pnode != DI_NODE_NIL) {
1071865Sdilpreet 		for (cnode = di_child_node(pnode); cnode != DI_NODE_NIL;
1081865Sdilpreet 		    cnode = di_sibling_node(cnode)) {
1091865Sdilpreet 			if (di_driver_name(cnode) == NULL)
1101865Sdilpreet 				continue;
1111865Sdilpreet 			if (strcmp(di_driver_name(cnode), PCI_PCI) == 0) {
1124328Scindi 				if (hb_process(mod, ptn, hbcnt, cnode) < 0) {
1134328Scindi 					if (hbcnt == 0)
1144328Scindi 						topo_node_range_destroy(ptn,
1154328Scindi 						    HOSTBRIDGE);
1162027Ssethg 					return (topo_mod_seterrno(mod,
1171865Sdilpreet 					    EMOD_PARTIAL_ENUM));
1181865Sdilpreet 				}
1194328Scindi 				hbcnt++;
1201865Sdilpreet 			}
121*10187SKrishna.Elango@Sun.COM 			if (strcmp(di_driver_name(cnode), PCIEB) == 0) {
1224328Scindi 				if (rc_process(mod, ptn, hbcnt, cnode) < 0) {
1234328Scindi 					if (hbcnt == 0)
1244328Scindi 						topo_node_range_destroy(ptn,
1254328Scindi 						    HOSTBRIDGE);
1262027Ssethg 					return (topo_mod_seterrno(mod,
1271865Sdilpreet 					    EMOD_PARTIAL_ENUM));
1281865Sdilpreet 				}
1294328Scindi 				hbcnt++;
1301865Sdilpreet 			}
1311414Scindi 		}
1321414Scindi 		pnode = di_drv_next_node(pnode);
1331414Scindi 	}
1341414Scindi 	return (0);
1351414Scindi }
1361414Scindi 
1371414Scindi /*ARGSUSED*/
1381414Scindi int
platform_hb_enum(topo_mod_t * mod,tnode_t * parent,const char * name,topo_instance_t imin,topo_instance_t imax)1393062Scindi platform_hb_enum(topo_mod_t *mod, tnode_t *parent, const char *name,
1403062Scindi     topo_instance_t imin, topo_instance_t imax)
1411414Scindi {
1423062Scindi 	return (pci_hostbridges_find(mod, parent));
1431414Scindi }
1441414Scindi 
1451414Scindi /*ARGSUSED*/
1461414Scindi int
platform_hb_label(topo_mod_t * mod,tnode_t * node,nvlist_t * in,nvlist_t ** out)1473062Scindi platform_hb_label(topo_mod_t *mod, tnode_t *node, nvlist_t *in, nvlist_t **out)
1481414Scindi {
1492027Ssethg 	return (labelmethod_inherit(mod, node, in, out));
1501414Scindi }
151