opl_ioboard.c revision 23a276b1252962c987a613be470dde26561247b8
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * CDDL HEADER START
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * The contents of this file are subject to the terms of the
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * Common Development and Distribution License (the "License").
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * You may not use this file except in compliance with the License.
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * See the License for the specific language governing permissions
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * and limitations under the License.
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * When distributing Covered Code, include this CDDL HEADER in each
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * If applicable, add the following below this CDDL HEADER, with the
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * fields enclosed by brackets "[]" replaced with your own identifying
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * information: Portions Copyright [yyyy] [name of copyright owner]
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * CDDL HEADER END
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * Use is subject to license terms.
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston#pragma ident "%Z%%M% %I% %E% SMI"
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * SUNW,OPL-Enterprise platform ioboard topology enumerator
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chuestonstatic int opl_iob_enum(topo_mod_t *hdl, tnode_t *parent, const char *name,
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston topo_instance_t imin, topo_instance_t imax, void *notused);
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * Turn on module debugging output
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston topo_mod_dprintf(modhdl, "initializing ioboard enumerator\n");
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * Checks to see if there's a physical board number property on this
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * device node.
23a276b1252962c987a613be470dde26561247b8huestonopl_get_physical_board(di_node_t n, di_prom_handle_t opl_promtree)
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston if (strcmp(di_prom_prop_name(pp), OPL_PHYSICAL_BD) == 0) {
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston return (-1);
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * Creates a map of logical boards to physical location.
23a276b1252962c987a613be470dde26561247b8huestonopl_map_boards(int lsb_to_psb[OPL_IOB_MAX], di_node_t opl_devtree,
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* Initialize all entries to no mapping */
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston for (i = 0; i < OPL_IOB_MAX; i++) {
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * Get LSB-to-PSB (logical-to-physical board) mapping by finding the
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * memory controller driver per LSB. The MC driver will have a
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * physical-board# property.
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston for (n = di_drv_first_node(OPL_MC_DRV, opl_devtree);
23a276b1252962c987a613be470dde26561247b8hueston * di_bus_addr returned NULL. This can happen during
23a276b1252962c987a613be470dde26561247b8hueston * DR attach/detach of the mc driver. Just skip this
23a276b1252962c987a613be470dde26561247b8hueston * node for now.
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* psb mapping is out of range, skip */
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * Create the ioboard node. Add fru and label properties, and create room
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * for child hostbridge nodes.
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chuestonopl_iob_node_create(topo_mod_t *mp, tnode_t *parent, int inst)
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* Get parent FMRI */
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston if (topo_mod_nvalloc(mp, &args, NV_UNIQUE_NAME) != 0 ||
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_PARENT, pfmri)
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* Create ioboard FMRI */
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston if ((fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, IOBOARD, inst,
23a276b1252962c987a613be470dde26561247b8hueston topo_mod_dprintf(mp, "create of tnode for ioboard failed: %s\n",
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* Create node for this ioboard */
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston ion = topo_node_bind(mp, parent, IOBOARD, inst, fmri, NULL);
23a276b1252962c987a613be470dde26561247b8hueston topo_mod_dprintf(mp, "unable to bind ioboard: %s\n",
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* Create and add FRU fmri for this ioboard */
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston snprintf(fmri_str, sizeof (fmri_str), IOBDFRU, inst);
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston if (topo_fmri_str2nvl(thp, fmri_str, &fmri, &err) == 0) {
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* Add label for this ioboard */
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* Create range of hostbridges on this ioboard */
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston if (topo_node_range_create(mp, ion, HOSTBRIDGE, 0, OPL_HB_MAX) != 0) {
23a276b1252962c987a613be470dde26561247b8hueston topo_mod_dprintf(mp, "topo_node_range_create failed: %s\n",
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston/*ARGSUSED*/
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chuestonopl_iob_enum(topo_mod_t *mp, tnode_t *parent, const char *name,
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston topo_instance_t imin, topo_instance_t imax, void *notused)
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* Validate the name is correct */
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston return (-1);
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* Initialize devinfo once for the module */
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston if ((opl_promtree = di_prom_init()) == DI_PROM_HANDLE_NIL) {
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston "Ioboard enumerator: di_prom_handle_init failed.\n");
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston return (-1);
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* Make sure we don't exceed OPL_IOB_MAX */
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston return (-1);
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * Create a mapping from logical board numbers (which are part of
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * the device node bus address) to physical board numbers, so we
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * can create meaningful fru labels.
23a276b1252962c987a613be470dde26561247b8hueston opl_map_boards(lsb_to_psb, opl_devtree, opl_promtree);
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * Figure out which boards are installed by finding hostbridges
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * with matching bus addresses.
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston for (pnode = di_drv_first_node(OPL_PX_DRV, opl_devtree);
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* Map logical system board to physical system board */
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* If valid psb, note that this board exists */
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * Now enumerate each existing board Exit loop if retval is
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston * ever set to non-zero.
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston for (inst = imin; inst <= imax && retval == 0; inst++) {
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* If this board doesn't contain any hostbridges, skip it */
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* Create node for this ioboard */
23a276b1252962c987a613be470dde26561247b8hueston "enumeration of ioboard failed: %s\n",
0b6016e6ff70af39f99c9cc28e0c2207c8f5413chueston /* Enumerate hostbridges on this ioboard, sets errno */