03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The contents of this file are subject to the terms of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Common Development and Distribution License, Version 1.0 only
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (the "License"). You may not use this file except in compliance
03831d35f7499c87d51205817c93e9a8d42c4baestevel * with the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or http://www.opensolaris.org/os/licensing.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When distributing Covered Code, include this CDDL HEADER in each
03831d35f7499c87d51205817c93e9a8d42c4baestevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If applicable, add the following below this CDDL HEADER, with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fields enclosed by brackets "[]" replaced with your own identifying
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information: Portions Copyright [yyyy] [name of copyright owner]
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Copyright 2000, 2003 Sun Microsystems, Inc. All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Use is subject to license terms.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Daktari Platform specific functions.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#pragma ident "%Z%%M% %I% %E% SMI"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <libdevinfo.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <alloca.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <inttypes.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <libprtdiag.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/mc.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define EXIT_MSG(msg, err) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel { printf("\n%s failed with %d\n", msg, err); exit(err); }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* we only need the 5 LSB of the portid to calculate the board number */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DAK_SAFARI_ID_MASK 0x1F /* 5 bits */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DAK_NODE_MASK 0x1F /* 5 bits */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DAK_PORTID_NODE_SHIFT 5
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DAK_MIN_CPU_SAFARI_ID 0 /* 0x00 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DAK_MAX_CPU_SAFARI_ID 23 /* 0x17 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DAK_MIN_IO_SAFARI_ID 24 /* 0x18 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DAK_MAX_IO_SAFARI_ID 31 /* 0x1F */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define NUM_MBANKS_PER_MC 4
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DAK_CLK_FREQ_TO_MHZ(x) (((x) + 500000) / 1000000)
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * DAK_PORTID_IS_CPU_TYPE
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If the portid associated with a CPU board is passed in, TRUE is returned,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * otherwise FALSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DAK_PORTID_IS_CPU_TYPE(portid) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel (((((portid) & DAK_SAFARI_ID_MASK) >= DAK_MIN_CPU_SAFARI_ID) && \
03831d35f7499c87d51205817c93e9a8d42c4baestevel (((portid) & DAK_SAFARI_ID_MASK) <= DAK_MAX_CPU_SAFARI_ID)) ? \
03831d35f7499c87d51205817c93e9a8d42c4baestevel TRUE: FALSE)
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * DAK_CPU_BD_PORTID_TO_BD_NUM
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If the portid associated with a CPU board is passed in, the board number
03831d35f7499c87d51205817c93e9a8d42c4baestevel * associated with this portid is returned, otherwise -1.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DAK_CPU_BD_PORTID_TO_BD_NUM(portid) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel ((DAK_PORTID_IS_CPU_TYPE(portid)) ? \
03831d35f7499c87d51205817c93e9a8d42c4baestevel (((portid) & DAK_SAFARI_ID_MASK) / 4) : (-1))
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * DAK_PORTID_IS_IO_TYPE
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If the portid associated with an IO board is passed in, TRUE is returned,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * otherwise FALSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DAK_PORTID_IS_IO_TYPE(portid) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel (((((portid) & DAK_SAFARI_ID_MASK) >= DAK_MIN_IO_SAFARI_ID) && \
03831d35f7499c87d51205817c93e9a8d42c4baestevel (((portid) & DAK_SAFARI_ID_MASK) <= DAK_MAX_IO_SAFARI_ID)) ? \
03831d35f7499c87d51205817c93e9a8d42c4baestevel TRUE: FALSE)
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * DAK_IO_BD_PORTID_TO_BD_NUM
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If the portid associated with an IO board is passed in, the board number
03831d35f7499c87d51205817c93e9a8d42c4baestevel * associated with this portid is returned, otherwise -1.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DAK_IO_BD_PORTID_TO_BD_NUM(portid) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel (DAK_PORTID_IS_IO_TYPE(portid) ? \
03831d35f7499c87d51205817c93e9a8d42c4baestevel (((((portid) & DAK_SAFARI_ID_MASK) - 24) / 2) + 6) : (-1))
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * DAK_PORTID_TO_BOARD_NUM
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If a valid portid is passed in, this macro returns the board number
03831d35f7499c87d51205817c93e9a8d42c4baestevel * associated with it, otherwise it returns -1.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define DAK_PORTID_TO_BOARD_NUM(portid) \
03831d35f7499c87d51205817c93e9a8d42c4baestevel ((DAK_PORTID_IS_CPU_TYPE(portid)) ? \
03831d35f7499c87d51205817c93e9a8d42c4baestevel (DAK_CPU_BD_PORTID_TO_BD_NUM(portid)) : \
03831d35f7499c87d51205817c93e9a8d42c4baestevel ((DAK_PORTID_IS_IO_TYPE(portid)) ? \
03831d35f7499c87d51205817c93e9a8d42c4baestevel DAK_IO_BD_PORTID_TO_BD_NUM(portid) : (-1)))
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Local Functions */
03831d35f7499c87d51205817c93e9a8d42c4baestevelchar *get_node_name(Prom_node *pnode);
03831d35f7499c87d51205817c93e9a8d42c4baestevelchar *get_node_type(Prom_node *pnode);
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid add_node(Sys_tree *root, Prom_node *pnode);
03831d35f7499c87d51205817c93e9a8d42c4baestevelProp *find_prop(Prom_node *pnode, char *name);
03831d35f7499c87d51205817c93e9a8d42c4baestevelint do_prominfo(int syserrlog, char *pgname, int log_flag, int prt_flag);
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid *get_prop_val(Prop *prop);
03831d35f7499c87d51205817c93e9a8d42c4baestevelchar *get_node_type(Prom_node *pnode);
03831d35f7499c87d51205817c93e9a8d42c4baestevelint get_us3_mem_regs(Board_node *bnode);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid fill_pci_card_list(Prom_node *pci_instance,
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node *pci_card_node,
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card *pci_card,
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card **pci_card_list,
03831d35f7499c87d51205817c93e9a8d42c4baestevel char **pci_slot_name_arr);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic Prom_node *next_pci_card(Prom_node *curr_card, int *is_bridge,
03831d35f7499c87d51205817c93e9a8d42c4baestevel int is_pcidev, Prom_node *curr_bridge,
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node * parent_bridge, Prom_node *pci);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic Prom_node *dev_next_node_by_compat(Prom_node *root, char *compat);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic Prom_node *dev_find_node_by_compat(Prom_node *root, char *compat);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic Board_node *daktari_insert_board(Sys_tree *root, int board);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic Board_node *daktari_find_board(Sys_tree *root, int board);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int32_t find_child_device(picl_nodehdl_t, char *, picl_nodehdl_t *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int32_t fill_device_from_id(picl_nodehdl_t, char *, picl_nodehdl_t *);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic int32_t fill_device_array_from_id(picl_nodehdl_t, char *, int32_t *,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t **);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Overlaying routines */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function searches through the properties of the node passed in
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and returns a pointer to the value of the name property.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelchar *
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_node_name(Prom_node *pnode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prop *prop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pnode == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop = pnode->props;
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (prop != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp("name", (char *)prop->name.val_ptr) == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (prop->value.val_ptr);
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop = prop->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function searches through the properties of the node passed in
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and returns a pointer to the value of the name property.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelchar *
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_node_type(Prom_node *pnode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prop *prop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pnode == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop = pnode->props;
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (prop != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp("device_type", (char *)prop->name.val_ptr) == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (prop->value.val_ptr);
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop = prop->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * add_node
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function adds a board node to the board structure where that
03831d35f7499c87d51205817c93e9a8d42c4baestevel * that node's physical component lives.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_node(Sys_tree *root, Prom_node *pnode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int board = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int portid = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel void *value = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel Board_node *bnode = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node *p = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Get the board number of this board from the portid prop */
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(pnode, "portid"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel portid = *(int *)value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel board = DAK_PORTID_TO_BOARD_NUM(portid);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* board = DAK_GETSLOT(portid); */
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* find the board node with the same board number */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((bnode = daktari_find_board(root, board)) == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bnode = daktari_insert_board(root, board);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* now attach this prom node to the board list */
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Insert this node at the end of the list */
03831d35f7499c87d51205817c93e9a8d42c4baestevel pnode->sibling = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bnode->nodes == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel bnode->nodes = pnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel p = bnode->nodes;
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (p->sibling != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel p = p->sibling;
03831d35f7499c87d51205817c93e9a8d42c4baestevel p->sibling = pnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Search a Prom node and retrieve the property with the correct
03831d35f7499c87d51205817c93e9a8d42c4baestevel * name.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelProp *
03831d35f7499c87d51205817c93e9a8d42c4baestevelfind_prop(Prom_node *pnode, char *name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prop *prop;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pnode == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pnode->props == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop = pnode->props;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (prop == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (prop->name.val_ptr == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel while ((prop != NULL) && (strcmp((char *)(prop->name.val_ptr), name))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel prop = prop->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (prop);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baesteveldo_prominfo(int syserrlog, char *pgname, int log_flag, int prt_flag)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (do_devinfo(syserrlog, pgname, log_flag, prt_flag));
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * return the property value for the Prop
03831d35f7499c87d51205817c93e9a8d42c4baestevel * passed in.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid *
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_prop_val(Prop *prop)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (prop == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return ((void *)(prop->value.val_ptr));
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* Local Routines */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Start from the current node and return the next node besides
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the current one which has the requested model property.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic Prom_node *
03831d35f7499c87d51205817c93e9a8d42c4baesteveldev_next_node_by_compat(Prom_node *root, char *compat)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node *node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (root == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* look at your children first */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((node = dev_find_node_by_compat(root->child, compat)) != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (node);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* now look at your siblings */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((node = dev_find_node_by_compat(root->sibling, compat)) != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (node);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL); /* not found */
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Do a depth-first walk of a device tree and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * return the first node with the matching model.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic Prom_node *
03831d35f7499c87d51205817c93e9a8d42c4baesteveldev_find_node_by_compat(Prom_node *root, char *compat)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node *node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *compatible;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *name;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (root == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (compat == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel name = get_node_name(root);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (name == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel name = "";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel compatible = (char *)get_prop_val(find_prop(root, "compatible"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (compatible == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((strcmp(name, "pci") == 0) && (compatible != NULL) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (strcmp(compatible, compat) == 0)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (root); /* found a match */
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* look at your children first */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((node = dev_find_node_by_compat(root->child, compat)) != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (node);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* now look at your siblings */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((node = dev_find_node_by_compat(root->sibling, compat)) != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (node);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (NULL); /* not found */
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Add a board to the system list in order (sorted by board#).
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Initialize all pointer fields to NULL.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic Board_node *
03831d35f7499c87d51205817c93e9a8d42c4baesteveldaktari_insert_board(Sys_tree *root, int board)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel Board_node *bnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel Board_node *temp = root->bd_list;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((bnode = (Board_node *) malloc(sizeof (Board_node))) == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel perror("malloc");
03831d35f7499c87d51205817c93e9a8d42c4baestevel exit(1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bnode->nodes = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bnode->next = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bnode->board_num = board;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bnode->board_type = UNKNOWN_BOARD;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (temp == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel root->bd_list = bnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel else if (temp->board_num > board) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bnode->next = temp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel root->bd_list = bnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel while ((temp->next != NULL) && (board > temp->next->board_num))
03831d35f7499c87d51205817c93e9a8d42c4baestevel temp = temp->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel bnode->next = temp->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel temp->next = bnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel root->board_cnt++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (bnode);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Find the requested board struct in the system device tree.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function overrides the functionality of the generic find_board()
03831d35f7499c87d51205817c93e9a8d42c4baestevel * function in libprtdiag, but since we need to pass another parameter,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we cannot simply overlay the symbol table.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic Board_node *
03831d35f7499c87d51205817c93e9a8d42c4baesteveldaktari_find_board(Sys_tree *root, int board)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel Board_node *bnode = root->bd_list;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel while ((bnode != NULL) && (board != bnode->board_num)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bnode = bnode->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (bnode);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint32_t
03831d35f7499c87d51205817c93e9a8d42c4baestevelfind_child_device(picl_nodehdl_t parent, char *child_name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t *child)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char name[PICL_PROPNAMELEN_MAX];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = picl_get_propval_by_name(parent, PICL_PROP_CHILD, &(*child),
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (err) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case PICL_SUCCESS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case PICL_PROPNOTFOUND:
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = PICL_INVALIDHANDLE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef WORKFILE_DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "Failed picl_get_propval_by_name with %s\n"),
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_strerror(err));
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = picl_get_propval_by_name(*child, PICL_PROP_NAME, name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel PICL_PROPNAMELEN_MAX);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef WORKFILE_DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "failed the get name for root\n"), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN, "%s\n"),
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_strerror(err), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(name, child_name) == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (err != PICL_PROPNOTFOUND) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = picl_get_propval_by_name(*child, PICL_PROP_PEER,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &(*child), sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (err) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case PICL_SUCCESS:
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = picl_get_propval_by_name(*child, PICL_PROP_NAME,
03831d35f7499c87d51205817c93e9a8d42c4baestevel name, PICL_PROPNAMELEN_MAX);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(name, child_name) == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case PICL_PROPNOTFOUND:
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef WORKFILE_DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "Failed picl_get_propval_by_name with %s\n"),
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_strerror(err), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = PICL_INVALIDHANDLE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint32_t
03831d35f7499c87d51205817c93e9a8d42c4baestevelfill_device_from_id(picl_nodehdl_t device_id, char *assoc_id,
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_nodehdl_t *device)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tbl_hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t reference_property;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = picl_get_propval_by_name(device_id, assoc_id, &tbl_hdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (picl_prophdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef WORKFILE_DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_INVALIDHANDLE) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "fill_device_from_id failure in "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "picl_get_propval_by_name err is %s\n"),
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_strerror(err), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = picl_get_next_by_row(tbl_hdl, &reference_property);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != PICL_SUCCESS) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef WORKFILE_DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "fill_device_from_id failure in picl_get_next_by_row"
03831d35f7499c87d51205817c93e9a8d42c4baestevel " err is %s\n"), picl_strerror(err), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* get node associated with reference property */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = picl_get_propval(reference_property, &(*device),
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef WORKFILE_DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "fill_device_from_id failure in picl_get_propval"
03831d35f7499c87d51205817c93e9a8d42c4baestevel " err is %s\n"), picl_strerror(err), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint32_t
03831d35f7499c87d51205817c93e9a8d42c4baestevelfill_device_array_from_id(picl_nodehdl_t device_id, char *assoc_id,
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t *number_of_devices, picl_nodehdl_t *device_array[])
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int32_t err;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t tbl_hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_prophdl_t entry;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int devs = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = picl_get_propval_by_name(device_id, assoc_id, &tbl_hdl,
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (picl_prophdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((err != PICL_SUCCESS) && (err != PICL_INVALIDHANDLE)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef WORKFILE_DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "fill_device_array_from_id failure in "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "picl_get_propval_by_name err is %s\n"),
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_strerror(err), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel entry = tbl_hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (picl_get_next_by_row(entry, &entry) == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel ++devs;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel *device_array = calloc((devs), sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (*device_array == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef WORKFILE_DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "fill_device_array_from_id failure getting memory"
03831d35f7499c87d51205817c93e9a8d42c4baestevel " for array\n"), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PICL_FAILURE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel entry = tbl_hdl;
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < (devs); i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = picl_get_next_by_row(entry, &entry);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef WORKFILE_DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "fill_device_array_from_id failure in "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "picl_get_next_by_row err is %s\n"),
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_strerror(err), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* get node associated with reference property */
03831d35f7499c87d51205817c93e9a8d42c4baestevel err = picl_get_propval(entry, &((*device_array)[i]),
03831d35f7499c87d51205817c93e9a8d42c4baestevel sizeof (picl_nodehdl_t));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (err != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef WORKFILE_DEBUG
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "fill_device_array_from_id failure in "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "picl_get_propval err is %s\n"),
03831d35f7499c87d51205817c93e9a8d42c4baestevel picl_strerror(err), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel *number_of_devices = devs;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (err);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function provides formatting of the memory config
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information that get_us3_mem_regs() and display_us3_banks() code has
03831d35f7499c87d51205817c93e9a8d42c4baestevel * gathered. It overrides the generic print_us3_memory_line() code
03831d35f7499c87d51205817c93e9a8d42c4baestevel * which prints an error message.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelprint_us3_memory_line(int portid, int bank_id, uint64_t bank_size,
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *bank_status, uint64_t dimm_size, uint32_t intlv, int seg_id)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int mcid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel mcid = portid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "\n %-1c %2d %2d %4lldMB %11-s %4lldMB "
03831d35f7499c87d51205817c93e9a8d42c4baestevel " %2d-way %d"),
03831d35f7499c87d51205817c93e9a8d42c4baestevel 'A' + DAK_GETSLOT(portid), mcid, (bank_id % 4),
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank_size, bank_status, dimm_size, intlv, seg_id, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Fills in the i/o card list to be displayed later in display_pci();
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelfill_pci_card_list(Prom_node * pci_instance, Prom_node * pci_card_node,
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card *pci_card,
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card **pci_card_list, char **slot_name_arr)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node *pci_bridge_node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node *pci_parent_bridge;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int *int_val;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int pci_bridge = FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int pci_bridge_dev_no = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int portid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int pci_bus;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char buf[MAXSTRLEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *slot_name = NULL; /* info in "slot-names" prop */
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *child_name;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *name;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *type;
03831d35f7499c87d51205817c93e9a8d42c4baestevel void *value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (pci_card_node != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel int is_pci = FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel type = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel name = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* If it doesn't have a name, skip it */
03831d35f7499c87d51205817c93e9a8d42c4baestevel name = (char *)get_prop_val(
03831d35f7499c87d51205817c93e9a8d42c4baestevel find_prop(pci_card_node, "name"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (name == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card_node = pci_card_node->sibling;
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get the portid of the schizo that this card
03831d35f7499c87d51205817c93e9a8d42c4baestevel * lives under.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel portid = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(pci_instance, "portid"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel portid = *(int *)value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card->schizo_portid = portid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Find out whether this is PCI bus A or B
03831d35f7499c87d51205817c93e9a8d42c4baestevel * using the 'reg' property.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel int_val = (int *)get_prop_val(find_prop(pci_instance, "reg"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (int_val != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel int_val++; /* skip over first integer */
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_bus = ((*int_val) & 0x7f0000);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pci_bus == 0x600000)
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card->pci_bus = 'A';
03831d35f7499c87d51205817c93e9a8d42c4baestevel else if (pci_bus == 0x700000)
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card->pci_bus = 'B';
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card->pci_bus = '-';
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card->pci_bus = '-';
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((pci_card->schizo_portid == 8) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (pci_card->pci_bus == 'A')) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card_node = pci_card_node->sibling;
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * get dev# and func# for this card from the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * 'reg' property.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel int_val = (int *)get_prop_val(
03831d35f7499c87d51205817c93e9a8d42c4baestevel find_prop(pci_card_node, "reg"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (int_val != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card->dev_no = (((*int_val) & 0xF800) >> 11);
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card->func_no = (((*int_val) & 0x700) >> 8);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card->dev_no = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card->func_no = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel type = (char *)get_prop_val(
03831d35f7499c87d51205817c93e9a8d42c4baestevel find_prop(pci_card_node, "device_type"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If this is a pci-bridge, then store its dev#
03831d35f7499c87d51205817c93e9a8d42c4baestevel * as its children nodes need this to get their slot#.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We set the pci_bridge flag so that we know we are
03831d35f7499c87d51205817c93e9a8d42c4baestevel * looking at a pci-bridge node. This flag gets reset
03831d35f7499c87d51205817c93e9a8d42c4baestevel * every time we enter this while loop.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check for a PCI-PCI Bridge for PCI and cPCI
03831d35f7499c87d51205817c93e9a8d42c4baestevel * IO Boards using the name and type properties.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((type != NULL) && (strncmp(name, "pci", 3) == 0) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (strcmp(type, "pci") == 0)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_bridge_node = pci_card_node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel is_pci = TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!pci_bridge) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_bridge_dev_no = pci_card->dev_no;
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_parent_bridge = pci_bridge_node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_bridge = TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((pci_card->pci_bus == 'B') && (pci_card->dev_no == 1) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (!pci_bridge)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card_node = pci_card_node->sibling;
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get slot-names property from slot_names_arr.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If we are the child of a pci_bridge we use the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * dev# of the pci_bridge as an index to get
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the slot number. We know that we are a child of
03831d35f7499c87d51205817c93e9a8d42c4baestevel * a pci-bridge if our parent is the same as the last
03831d35f7499c87d51205817c93e9a8d42c4baestevel * pci_bridge node found above.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pci_card->dev_no != -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We compare this cards parent node with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * pci_bridge_node to see if it's a child.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pci_card_node->parent != pci_instance &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_bridge) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* use dev_no of pci_bridge */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pci_card->pci_bus == 'B') {
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot_name =
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot_name_arr[pci_bridge_dev_no -2];
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot_name =
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot_name_arr[pci_bridge_dev_no -1];
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pci_card->pci_bus == 'B') {
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot_name =
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot_name_arr[pci_card->dev_no-2];
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot_name =
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot_name_arr[pci_card->dev_no-1];
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (slot_name != NULL &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel strlen(slot_name) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Slot num is last char in string */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(pci_card->slot_str, MAXSTRLEN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "%c", slot_name[strlen(slot_name) - 1]);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(pci_card->slot_str, MAXSTRLEN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "-");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(pci_card->slot_str, MAXSTRLEN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "%c", '-');
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Check for failed status.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (node_failed(pci_card_node))
03831d35f7499c87d51205817c93e9a8d42c4baestevel strcpy(pci_card->status, "fail");
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel strcpy(pci_card->status, "ok");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Get the model of this pci_card */
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(pci_card_node, "model"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card->model[0] = '\0';
03831d35f7499c87d51205817c93e9a8d42c4baestevel else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(pci_card->model, MAXSTRLEN, "%s",
03831d35f7499c87d51205817c93e9a8d42c4baestevel (char *)value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The card may have a "clock-frequency" but we
03831d35f7499c87d51205817c93e9a8d42c4baestevel * are not interested in that. Instead we get the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * "clock-frequency" of the PCI Bus that the card
03831d35f7499c87d51205817c93e9a8d42c4baestevel * resides on. PCI-A can operate at 33Mhz or 66Mhz
03831d35f7499c87d51205817c93e9a8d42c4baestevel * depending on what card is plugged into the Bus.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * PCI-B always operates at 33Mhz.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel int_val = get_prop_val(find_prop(pci_instance,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "clock-frequency"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (int_val != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card->freq = DAK_CLK_FREQ_TO_MHZ(*int_val);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card->freq = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Figure out how we want to display the name
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(pci_card_node,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "compatible"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* use 'name'-'compatible' */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(buf, MAXSTRLEN, "%s-%s", name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (char *)value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* just use 'name' */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(buf, MAXSTRLEN, "%s", name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel name = buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If this node has children, add the device_type
03831d35f7499c87d51205817c93e9a8d42c4baestevel * of the child to the name value of this pci_card->
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel child_name = (char *)get_node_name(pci_card_node->child);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((pci_card_node->child != NULL) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (child_name != NULL)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(pci_card_node->child,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "device_type"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* add device_type of child to name */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(pci_card->name, MAXSTRLEN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "%s/%s (%s)", name, child_name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (char *)value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* just add childs name */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(pci_card->name, MAXSTRLEN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "%s/%s", name, child_name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(pci_card->name, MAXSTRLEN, "%s",
03831d35f7499c87d51205817c93e9a8d42c4baestevel (char *)name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If this is a pci-bridge, then add the word
03831d35f7499c87d51205817c93e9a8d42c4baestevel * 'pci-bridge' to its model. If we can't find
03831d35f7499c87d51205817c93e9a8d42c4baestevel * a model, then we just describe what the device
03831d35f7499c87d51205817c93e9a8d42c4baestevel * is based on some properties.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pci_bridge) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strlen(pci_card->model) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pci_card_node->parent == pci_bridge_node)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(pci_card->model, MAXSTRLEN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "%s", "device on pci-bridge");
03831d35f7499c87d51205817c93e9a8d42c4baestevel else if (pci_card_node->parent
03831d35f7499c87d51205817c93e9a8d42c4baestevel == pci_parent_bridge)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(pci_card->model, MAXSTRLEN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "%s", "pci-bridge/pci-bridge");
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(pci_card->model, MAXSTRLEN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "%s", "PCI-BRIDGE");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(pci_card->model, MAXSTRLEN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "%s/pci-bridge", pci_card->model);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* insert this pci_card in the list to be displayed later */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel *pci_card_list = insert_io_card(*pci_card_list, pci_card);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If we are dealing with a pci-bridge, we need to move
03831d35f7499c87d51205817c93e9a8d42c4baestevel * down to the children of this bridge if there are any.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If we are not, we are either dealing with a regular
03831d35f7499c87d51205817c93e9a8d42c4baestevel * card (in which case we move onto the sibling of this
03831d35f7499c87d51205817c93e9a8d42c4baestevel * card) or we are dealing with a child of a pci-bridge
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (in which case we move onto the child's siblings or
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if there are no more siblings for this child, we
03831d35f7499c87d51205817c93e9a8d42c4baestevel * move onto the parents siblings).
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_card_node = next_pci_card(pci_card_node, &pci_bridge,
03831d35f7499c87d51205817c93e9a8d42c4baestevel is_pci, pci_bridge_node,
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_parent_bridge, pci_instance);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } /* end-while */
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Helper function for fill_pci_card_list(). Indicates which
03831d35f7499c87d51205817c93e9a8d42c4baestevel * card node to go to next.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Parameters:
03831d35f7499c87d51205817c93e9a8d42c4baestevel * -----------
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Prom_node * curr_card: pointer to the current card node
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * int * is_bridge: indicates whether or not the card (is | is on)
03831d35f7499c87d51205817c93e9a8d42c4baestevel * a pci bridge
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * int is_pcidev: indicates whether or not the current card
03831d35f7499c87d51205817c93e9a8d42c4baestevel * is a pci bridge
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Prom_node * curr_bridge: pointer to the current pci bridge. Eg:
03831d35f7499c87d51205817c93e9a8d42c4baestevel * curr_card->parent.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Prom_node * parent_bridge: pointer to the first pci bridge encountered.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we could have nested pci bridges, this would
03831d35f7499c87d51205817c93e9a8d42c4baestevel * be the first one.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Prom_node * pci: pointer to the pci instance that we are attached to.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This would be parent_bridge->parent, or
03831d35f7499c87d51205817c93e9a8d42c4baestevel * curr_node->parent, if curr_node is not on a pci bridge.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic Prom_node *
03831d35f7499c87d51205817c93e9a8d42c4baestevelnext_pci_card(Prom_node *curr_card, int *is_bridge, int is_pcidev,
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node *curr_bridge, Prom_node *parent_bridge,
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node *pci)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node * curr_node = curr_card;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (*is_bridge) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * is_pcidev is used to prevent us from following the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * children of something like a scsi device.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (curr_node->child != NULL && is_pcidev) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel curr_node = curr_node->child;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel curr_node = curr_node->sibling;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (curr_node == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel curr_node = curr_bridge->sibling;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (curr_node == NULL &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel curr_bridge != parent_bridge &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel curr_bridge != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel curr_node =
03831d35f7499c87d51205817c93e9a8d42c4baestevel curr_bridge->parent->sibling;
03831d35f7499c87d51205817c93e9a8d42c4baestevel curr_bridge = curr_bridge->parent;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (curr_node != NULL &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel curr_node->parent == pci) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (curr_bridge == NULL ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel curr_node == NULL ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel curr_node->parent == pci ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel curr_bridge == parent_bridge ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel curr_node == parent_bridge) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel *is_bridge = FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel curr_node = curr_node->sibling;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (curr_node);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}