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 (c) 1999-2001 by Sun Microsystems, Inc.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#pragma ident "%Z%%M% %I% %E% SMI"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <stdio.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <stdlib.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <unistd.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <ctype.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <string.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <kvm.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <varargs.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <errno.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <time.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <dirent.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <fcntl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/param.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/stat.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/types.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/utsname.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/openpromio.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/systeminfo.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <kstat.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <libintl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <syslog.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/dkio.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "pdevinfo.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "display.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "pdevinfo_sun4u.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "display_sun4u.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "libprtdiag.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#if !defined(TEXT_DOMAIN)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define TEXT_DOMAIN "SYS_TEST"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelProm_node *
03831d35f7499c87d51205817c93e9a8d42c4baestevelfind_pci_bus(Prom_node *node, int id, int bus)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node *pnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* find the first pci node */
03831d35f7499c87d51205817c93e9a8d42c4baestevel pnode = dev_find_node(node, "pci");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (pnode != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel int tmp_id;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int tmp_bus;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel tmp_id = get_id(pnode);
03831d35f7499c87d51205817c93e9a8d42c4baestevel tmp_bus = get_pci_bus(pnode);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((tmp_id == id) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (tmp_bus == bus)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel pnode = dev_next_node(pnode, "pci");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (pnode);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * get_pci_bus
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Determines the PCI bus, either A (0) or B (1). If the function cannot
03831d35f7499c87d51205817c93e9a8d42c4baestevel * find the bus-ranges property, it returns -1.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_pci_bus(Prom_node *pnode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int *value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* look up the bus-range property */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((value = (int *)get_prop_val(find_prop(pnode, "bus-range"))) ==
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (*value == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (1); /* B bus has a bus-range value = 0 */
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Find the PCI device number of this PCI device. If no device number can
03831d35f7499c87d51205817c93e9a8d42c4baestevel * be determined, then return -1.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_pci_device(Prom_node *pnode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel void *value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((value = get_prop_val(find_prop(pnode, "assigned-addresses"))) !=
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PCI_DEVICE(*(int *)value));
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Find the PCI device number of this PCI device. If no device number can
03831d35f7499c87d51205817c93e9a8d42c4baestevel * be determined, then return -1.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_pci_to_pci_device(Prom_node *pnode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel void *value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((value = get_prop_val(find_prop(pnode, "reg"))) !=
03831d35f7499c87d51205817c93e9a8d42c4baestevel NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (PCI_DEVICE(*(int *)value));
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * free_io_cards
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Frees the memory allocated for an io card list.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelfree_io_cards(struct io_card *card_list)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Free the list */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (card_list != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card *p, *q;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (p = card_list, q = NULL; p != NULL; p = q) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel q = p->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel free(p);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * insert_io_card
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Inserts an io_card structure into the list. The list is maintained
03831d35f7499c87d51205817c93e9a8d42c4baestevel * in order based on board number and slot number. Also, the storage
03831d35f7499c87d51205817c93e9a8d42c4baestevel * for the "card" argument is assumed to be handled by the caller,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * so we won't touch it.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstruct io_card *
03831d35f7499c87d51205817c93e9a8d42c4baestevelinsert_io_card(struct io_card *list, struct io_card *card)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card *newcard;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card *p, *q;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (card == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (list);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Copy the card to be added into new storage */
03831d35f7499c87d51205817c93e9a8d42c4baestevel newcard = (struct io_card *)malloc(sizeof (struct io_card));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (newcard == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel perror("malloc");
03831d35f7499c87d51205817c93e9a8d42c4baestevel exit(2);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) memcpy(newcard, card, sizeof (struct io_card));
03831d35f7499c87d51205817c93e9a8d42c4baestevel newcard->next = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (list == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (newcard);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Find the proper place in the list for the new card */
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (p = list, q = NULL; p != NULL; q = p, p = p->next) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (newcard->board < p->board)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((newcard->board == p->board) && (newcard->slot < p->slot))
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Insert the new card into the list */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (q == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel newcard->next = p;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (newcard);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel newcard->next = p;
03831d35f7499c87d51205817c93e9a8d42c4baestevel q->next = newcard;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (list);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelchar *
03831d35f7499c87d51205817c93e9a8d42c4baestevelfmt_manf_id(unsigned int encoded_id, char *outbuf)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel union manuf manuf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Format the manufacturer's info. Note a small inconsistency we
03831d35f7499c87d51205817c93e9a8d42c4baestevel * have to work around - Brooktree has it's part number in decimal,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * while Mitsubishi has it's part number in hex.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel manuf.encoded_id = encoded_id;
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (manuf.fld.manf) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case MANF_BROOKTREE:
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(outbuf, "%s %d, version %d", "Brooktree",
03831d35f7499c87d51205817c93e9a8d42c4baestevel manuf.fld.partno, manuf.fld.version);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case MANF_MITSUBISHI:
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(outbuf, "%s %x, version %d", "Mitsubishi",
03831d35f7499c87d51205817c93e9a8d42c4baestevel manuf.fld.partno, manuf.fld.version);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(outbuf, "JED code %d, Part num 0x%x, version %d",
03831d35f7499c87d51205817c93e9a8d42c4baestevel manuf.fld.manf, manuf.fld.partno, manuf.fld.version);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (outbuf);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Find the sbus slot number of this Sbus device. If no slot number can
03831d35f7499c87d51205817c93e9a8d42c4baestevel * be determined, then return -1.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_sbus_slot(Prom_node *pnode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel void *value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((value = get_prop_val(find_prop(pnode, "reg"))) != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (*(int *)value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This routine is the generic link into displaying system IO
03831d35f7499c87d51205817c93e9a8d42c4baestevel * configuration. It displays the table header, then displays
03831d35f7499c87d51205817c93e9a8d42c4baestevel * all the SBus cards, then displays all fo the PCI IO cards.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baesteveldisplay_io_devices(Sys_tree *tree)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel Board_node *bnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * TRANSLATION_NOTE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Following string is used as a table header.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Please maintain the current alignment in
03831d35f7499c87d51205817c93e9a8d42c4baestevel * translation.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("\n", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("=========================", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN, " IO Cards "), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("=========================", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("\n", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("\n", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel bnode = tree->bd_list;
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (bnode != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel display_sbus(bnode);
03831d35f7499c87d51205817c93e9a8d42c4baestevel display_pci(bnode);
03831d35f7499c87d51205817c93e9a8d42c4baestevel display_ffb(bnode, 1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel bnode = bnode->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baesteveldisplay_pci(Board_node *bnode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel#ifdef lint
03831d35f7499c87d51205817c93e9a8d42c4baestevel bnode = bnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function is intentionally empty
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Print out all the io cards in the list. Also print the column
03831d35f7499c87d51205817c93e9a8d42c4baestevel * headers if told to do so.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baesteveldisplay_io_cards(struct io_card *list)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static int banner = 0; /* Have we printed the column headings? */
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card *p;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (list == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (banner == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(" Bus Freq\n", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("Brd Type MHz Slot "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "Name "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "Model", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("\n", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("--- ---- ---- ---------- "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "---------------------------- "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "--------------------", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("\n", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel banner = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (p = list; p != NULL; p = p -> next) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("%2d ", p->board, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("%-4s ", p->bus_type, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("%3d ", p->freq, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * We check to see if it's an int or
03831d35f7499c87d51205817c93e9a8d42c4baestevel * a char string to display for slot.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (p->slot == PCI_SLOT_IS_STRING)
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("%10s ", p->slot_str, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("%10d ", p->slot, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("%-28.28s", p->name, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strlen(p->name) > 28)
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("+ ", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(" ", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("%-19.19s", p->model, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strlen(p->model) > 19)
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("+", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("\n", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Display all FFBs on this board. It can either be in tabular format,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or a more verbose format.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baesteveldisplay_ffb(Board_node *board, int table)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node *fb;
03831d35f7499c87d51205817c93e9a8d42c4baestevel void *value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card *card_list = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card card;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *type;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *label;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (board == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Fill in common information */
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.display = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.board = board->board_num;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card.bus_type, BUS_TYPE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.freq = sys_clk;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (fb = dev_find_node_by_type(board->nodes, "device_type", "display");
03831d35f7499c87d51205817c93e9a8d42c4baestevel fb != NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel fb = dev_next_node_by_type(fb, "device_type", "display")) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(fb, "name"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((strcmp(FFB_NAME, value)) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel type = FFB_NAME;
03831d35f7499c87d51205817c93e9a8d42c4baestevel label = "FFB";
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else if ((strcmp(AFB_NAME, value)) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel type = AFB_NAME;
03831d35f7499c87d51205817c93e9a8d42c4baestevel label = "AFB";
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (table == 1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Print out in table format */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* XXX - Get the slot number (hack) */
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.slot = get_id(fb);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Find out if it's single or double buffered */
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card.name, "%s", label);
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(fb, "board_type"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((*(int *)value) & FFB_B_BUFF)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card.name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "%s, Double Buffered", label);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card.name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "%s, Single Buffered", label);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Print model number only if board_type bit 2
03831d35f7499c87d51205817c93e9a8d42c4baestevel * is not set and it is not SUNW,XXX-XXXX.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.model[0] = '\0';
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(type, AFB_NAME) == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (((*(int *)value) & 0x4) != 0x4) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(fb,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "model"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((value != NULL) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (strcmp(value,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "SUNW,XXX-XXXX") != 0)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card.model, "%s",
03831d35f7499c87d51205817c93e9a8d42c4baestevel (char *)value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(fb, "model"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card.model, "%s",
03831d35f7499c87d51205817c93e9a8d42c4baestevel (char *)value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel card_list = insert_io_card(card_list, &card);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* print in long format */
03831d35f7499c87d51205817c93e9a8d42c4baestevel char device[MAXSTRLEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel int fd = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct dirent *direntp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel DIR *dirp;
03831d35f7499c87d51205817c93e9a8d42c4baestevel union strap_un strap;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct ffb_sys_info fsi;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Find the device node using upa-portid/portid */
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(fb, "upa-portid"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(fb, "portid"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(device, "%s@%x", type,
03831d35f7499c87d51205817c93e9a8d42c4baestevel *(int *)value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((dirp = opendir("/devices")) == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel while ((direntp = readdir(dirp)) != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strstr(direntp->d_name, device) != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(device, "/devices/%s",
03831d35f7499c87d51205817c93e9a8d42c4baestevel direntp->d_name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel fd = open(device, O_RDWR, 0666);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) closedir(dirp);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (fd == -1)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ioctl(fd, FFB_SYS_INFO, &fsi) < 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("%s Hardware Configuration:\n", label, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("-----------------------------------\n", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel strap.ffb_strap_bits = fsi.ffb_strap_bits;
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("\tBoard rev: %d\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel (int)strap.fld.board_rev, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("\tFBC version: 0x%x\n", fsi.fbc_version, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("\tDAC: %s\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel fmt_manf_id(fsi.dac_version, device), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("\t3DRAM: %s\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel fmt_manf_id(fsi.fbram_version, device), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("\n", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel display_io_cards(card_list);
03831d35f7499c87d51205817c93e9a8d42c4baestevel free_io_cards(card_list);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Display all the SBus IO cards on this board.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baesteveldisplay_sbus(Board_node *board)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card card;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card *card_list = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int freq;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int card_num;
03831d35f7499c87d51205817c93e9a8d42c4baestevel void *value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node *sbus;
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node *card_node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (board == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (sbus = dev_find_node(board->nodes, SBUS_NAME); sbus != NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel sbus = dev_next_node(sbus, SBUS_NAME)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Skip failed nodes for now */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (node_failed(sbus))
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Calculate SBus frequency in MHz */
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(sbus, "clock-frequency"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel freq = ((*(int *)value) + 500000) / 1000000;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel freq = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (card_node = sbus->child; card_node != NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel card_node = card_node->sibling) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *model;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *name;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *child_name;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel card_num = get_sbus_slot(card_node);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (card_num == -1)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Fill in card information */
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.display = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.freq = freq;
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.board = board->board_num;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card.bus_type, "SBus");
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.slot = card_num;
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.status[0] = '\0';
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Try and get card status */
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(card_node, "status"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strncpy(card.status, (char *)value,
03831d35f7499c87d51205817c93e9a8d42c4baestevel MAXSTRLEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* XXX - For now, don't display failed cards */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strstr(card.status, "fail") != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Now gather all of the node names for that card */
03831d35f7499c87d51205817c93e9a8d42c4baestevel model = (char *)get_prop_val(find_prop(card_node,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "model"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel name = get_node_name(card_node);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (name == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.name[0] = '\0';
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.model[0] = '\0';
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Figure out how we want to display the name */
03831d35f7499c87d51205817c93e9a8d42c4baestevel child_name = get_node_name(card_node->child);
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((card_node->child != NULL) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (child_name != NULL)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(card_node->child,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "device_type"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card.name, "%s/%s (%s)",
03831d35f7499c87d51205817c93e9a8d42c4baestevel name, child_name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (char *)value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card.name, "%s/%s", name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel child_name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strncpy(card.name, name, MAXSTRLEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (model != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) strncpy(card.model, model, MAXSTRLEN);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel card_list = insert_io_card(card_list, &card);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* We're all done gathering card info, now print it out */
03831d35f7499c87d51205817c93e9a8d42c4baestevel display_io_cards(card_list);
03831d35f7499c87d51205817c93e9a8d42c4baestevel free_io_cards(card_list);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get slot-names properties from parent node and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * store them in an array.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelpopulate_slot_name_arr(Prom_node *pci, int *slot_name_bits,
03831d35f7499c87d51205817c93e9a8d42c4baestevel char **slot_name_arr, int num_slots)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i, j, bit_mask;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = (char *)get_prop_val(find_prop(pci, "slot-names"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_PRINTF("\n populate_slot_name_arr: value = [0x%x]\n", value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *strings_arr[MAX_SLOTS_PER_IO_BD];
03831d35f7499c87d51205817c93e9a8d42c4baestevel bit_mask = *slot_name_bits = *(int *)value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_PRINTF("\nslot_names 1st integer = [0x%x]", *slot_name_bits);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* array starts after first int */
03831d35f7499c87d51205817c93e9a8d42c4baestevel strings_arr[0] = value + sizeof (int);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * break the array out into num_slots number of strings
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 1; i < num_slots; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel strings_arr[i] = (char *)strings_arr[i - 1]
03831d35f7499c87d51205817c93e9a8d42c4baestevel + strlen(strings_arr[i - 1]) + 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * process array of slot_names to remove blanks
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel j = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < num_slots; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((bit_mask >> i) & 0x1)
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot_name_arr[i] = strings_arr[j++];
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot_name_arr[i] = "";
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_PRINTF("\nslot_name_arr[%d] = [%s]", i,
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot_name_arr[i]);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_PRINTF("\n populate_slot_name_arr: - psycho with no "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "slot-names\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_card_frequency(Prom_node *pci)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *value = get_prop_val(find_prop(pci, "clock-frequency"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (-1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (int)(((*(int *)value) + 500000) / 1000000);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_dev_func_num(Prom_node *card_node, int *dev_no, int *func_no)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel void *value = get_prop_val(find_prop(card_node, "reg"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel int int_val = *(int *)value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel *dev_no = PCI_REG_TO_DEV(int_val);
03831d35f7499c87d51205817c93e9a8d42c4baestevel *func_no = PCI_REG_TO_FUNC(int_val);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel *dev_no = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel *func_no = -1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_pci_class_codes(Prom_node *card_node, int *class_code, int *subclass_code)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int class_code_reg = get_pci_class_code_reg(card_node);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel *class_code = CLASS_REG_TO_CLASS(class_code_reg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel *subclass_code = CLASS_REG_TO_SUBCLASS(class_code_reg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelis_pci_bridge(Prom_node *card_node, char *name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int class_code, subclass_code;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (card_node == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel get_pci_class_codes(card_node, &class_code, &subclass_code);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((strncmp(name, "pci", 3) == 0) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (class_code == PCI_BRIDGE_CLASS) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (subclass_code == PCI_PCI_BRIDGE_SUBCLASS))
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (TRUE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelis_pci_bridge_other(Prom_node *card_node, char *name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel int class_code, subclass_code;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (card_node == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel get_pci_class_codes(card_node, &class_code, &subclass_code);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((strncmp(name, "pci", 3) == 0) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (class_code == PCI_BRIDGE_CLASS) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (subclass_code == PCI_SUBCLASS_OTHER))
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (TRUE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (FALSE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_pci_card_model(Prom_node *card_node, char *model)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *name = get_prop_val(find_prop(card_node, "name"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *value = get_prop_val(find_prop(card_node, "model"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel int pci_bridge = is_pci_bridge(card_node, name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel model[0] = '\0';
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(model, "%s",
03831d35f7499c87d51205817c93e9a8d42c4baestevel (char *)value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pci_bridge) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strlen(model) == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(model,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "%s", "pci-bridge");
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(model,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "%s/pci-bridge", model);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelcreate_io_card_name(Prom_node *card_node, char *name, char *card_name)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *value = get_prop_val(find_prop(card_node, "compatible"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *child_name;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char buf[MAXSTRLEN];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(buf, "%s-%s", name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (char *)value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(buf, "%s", name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel name = buf;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel child_name = (char *)get_node_name(card_node->child);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((card_node->child != NULL) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (child_name != NULL)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(card_node->child,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "device_type"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card_name, "%s/%s (%s)",
03831d35f7499c87d51205817c93e9a8d42c4baestevel name, child_name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (char *)value);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card_name, "%s/%s", name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel child_name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card_name, "%s", (char *)name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Desktop display_psycho_pci
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Display all the psycho based PCI IO cards on this board.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/* ARGSUSED */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baesteveldisplay_psycho_pci(Board_node *board)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card *card_list = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card card;
03831d35f7499c87d51205817c93e9a8d42c4baestevel void *value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node *pci, *card_node, *pci_bridge_node = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *name;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int slot_name_bits, pci_bridge_dev_no,
03831d35f7499c87d51205817c93e9a8d42c4baestevel class_code, subclass_code,
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_pci_bridge;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *slot_name_arr[MAX_SLOTS_PER_IO_BD];
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (board == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Initialize all the common information */
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.display = 1;
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.board = board->board_num;
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card.bus_type, "PCI");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (pci = dev_find_node_by_type(board->nodes, "model", "SUNW,psycho");
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci != NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci = dev_next_node_by_type(pci, "model", "SUNW,psycho")) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If we have reached a pci-to-pci bridge node,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we are one level below the 'pci' nodes level
03831d35f7499c87d51205817c93e9a8d42c4baestevel * in the device tree. To get back to that level,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the search should continue with the sibling of
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the parent or else the remaining 'pci' cards
03831d35f7499c87d51205817c93e9a8d42c4baestevel * will not show up in the output.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (find_prop(pci, "upa-portid") == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((pci->parent->sibling != NULL) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (strcmp(get_prop_val(
03831d35f7499c87d51205817c93e9a8d42c4baestevel find_prop(pci->parent->sibling,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "name")), PCI_NAME) == 0))
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci = pci->parent->sibling;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci = pci->parent->sibling;
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_PRINTF("\n\n------->Looking at device [%s][%d] - [%s]\n",
03831d35f7499c87d51205817c93e9a8d42c4baestevel PCI_NAME, *((int *)get_prop_val(find_prop(
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci, "upa-portid"))),
03831d35f7499c87d51205817c93e9a8d42c4baestevel get_prop_val(find_prop(pci, "model")));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Skip all failed nodes for now */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (node_failed(pci))
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Fill in frequency */
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.freq = get_card_frequency(pci);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Each PSYCHO device has a slot-names property that can be
03831d35f7499c87d51205817c93e9a8d42c4baestevel * used to determine the slot-name string for each IO
03831d35f7499c87d51205817c93e9a8d42c4baestevel * device under this node. We get this array now and use
03831d35f7499c87d51205817c93e9a8d42c4baestevel * it later when looking at the children of this PSYCHO.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((populate_slot_name_arr(pci, &slot_name_bits,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (char **)&slot_name_arr, MAX_SLOTS_PER_IO_BD)) != 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_card;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Walk through the PSYCHO children */
03831d35f7499c87d51205817c93e9a8d42c4baestevel card_node = pci->child;
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (card_node != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_pci_bridge = FALSE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* If it doesn't have a name, skip it */
03831d35f7499c87d51205817c93e9a8d42c4baestevel name = (char *)get_prop_val(
03831d35f7499c87d51205817c93e9a8d42c4baestevel find_prop(card_node, "name"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (name == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_card;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* get dev# and func# for this card. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel get_dev_func_num(card_node, &card.dev_no,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &card.func_no);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* get class/subclass code for this card. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel get_pci_class_codes(card_node, &class_code,
03831d35f7499c87d51205817c93e9a8d42c4baestevel &subclass_code);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_PRINTF("\nName [%s] - ", name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_PRINTF("device no [%d] - ", card.dev_no);
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_PRINTF("class_code [%d] subclass_code [%d] - ",
03831d35f7499c87d51205817c93e9a8d42c4baestevel class_code, subclass_code);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Weed out PCI Bridge, subclass 'other' and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * ebus nodes.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (((class_code == PCI_BRIDGE_CLASS) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (subclass_code == PCI_SUBCLASS_OTHER)) ||
03831d35f7499c87d51205817c93e9a8d42c4baestevel (strstr(name, "ebus"))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_PRINTF("\nSkip ebus/class-other nodes [%s]",
03831d35f7499c87d51205817c93e9a8d42c4baestevel name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel goto next_card;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If this is a PCI bridge, then we store it's dev_no
03831d35f7499c87d51205817c93e9a8d42c4baestevel * so that it's children can use it for getting at
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the slot_name.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (is_pci_bridge(card_node, name)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_bridge_dev_no = card.dev_no;
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_bridge_node = card_node;
03831d35f7499c87d51205817c93e9a8d42c4baestevel pci_pci_bridge = TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_PRINTF("\nPCI Bridge detected\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
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 (card_node->parent == pci_bridge_node)
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.dev_no = pci_bridge_dev_no;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Get slot-names property from slot_names_arr. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel get_slot_number_str(&card, (char **)slot_name_arr,
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot_name_bits);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (slot_name_bits)
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_PRINTF("\nIO Card [%s] dev_no [%d] SlotStr "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "[%s] slot [%s]", name, card.dev_no,
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot_name_arr[card.dev_no],
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.slot_str);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* XXX - Don't know how to get status for PCI cards */
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.status[0] = '\0';
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Get the model of this card */
03831d35f7499c87d51205817c93e9a8d42c4baestevel get_pci_card_model(card_node, (char *)&card.model);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If we haven't figured out the frequency yet,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * try and get it from the card.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(pci, "clock-frequency"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL && card.freq == -1)
03831d35f7499c87d51205817c93e9a8d42c4baestevel card.freq = ((*(int *)value) + 500000)
03831d35f7499c87d51205817c93e9a8d42c4baestevel / 1000000;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Figure out how we want to display the name */
03831d35f7499c87d51205817c93e9a8d42c4baestevel create_io_card_name(card_node, name,
03831d35f7499c87d51205817c93e9a8d42c4baestevel (char *)&card.name);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (card.freq != -1)
03831d35f7499c87d51205817c93e9a8d42c4baestevel card_list = insert_io_card(card_list, &card);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelnext_card:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If we are done with the children of the pci bridge,
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we must continue with the remaining siblings of
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the pci-to-pci bridge - otherwise we move onto our
03831d35f7499c87d51205817c93e9a8d42c4baestevel * own sibling.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (pci_pci_bridge) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (card_node->child != NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel card_node = card_node->child;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel card_node = card_node->sibling;
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((card_node->parent == pci_bridge_node) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (card_node->sibling == NULL))
03831d35f7499c87d51205817c93e9a8d42c4baestevel card_node = pci_bridge_node->sibling;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel card_node = card_node->sibling;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel } /* end-while */
03831d35f7499c87d51205817c93e9a8d42c4baestevel } /* end-for */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel D_PRINTF("\n\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel display_io_cards(card_list);
03831d35f7499c87d51205817c93e9a8d42c4baestevel free_io_cards(card_list);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_slot_number_str(struct io_card *card, char **slot_name_arr,
03831d35f7499c87d51205817c93e9a8d42c4baestevel int slot_name_bits)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (card->dev_no != -1) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *slot;
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * slot_name_bits is a mask of the plug-in slots so if our
03831d35f7499c87d51205817c93e9a8d42c4baestevel * dev_no does not appear in this mask we must be an
03831d35f7499c87d51205817c93e9a8d42c4baestevel * on_board device so set the slot to 'On-Board'
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (slot_name_bits & (1 << card->dev_no)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* we are a plug-in card */
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot = slot_name_arr[card->dev_no];
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strlen(slot) != 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card->slot_str, "%s",
03831d35f7499c87d51205817c93e9a8d42c4baestevel slot);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card->slot_str, "-");
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* this is an on-board dev. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel sprintf(card->slot_str, "On-Board");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) sprintf(card->slot_str, "%c", '-');
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Informs display_io_cards to print slot_str instead of slot */
03831d35f7499c87d51205817c93e9a8d42c4baestevel card->slot = PCI_SLOT_IS_STRING;
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The output of a number of I/O cards are identical so we need to
03831d35f7499c87d51205817c93e9a8d42c4baestevel * differentiate between them.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function is called by the platform specific code and it decides
03831d35f7499c87d51205817c93e9a8d42c4baestevel * if the card needs further processing.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * It can be extended in the future if card types other than QLC have
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the same problems.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baesteveldistinguish_identical_io_cards(char *name, Prom_node *node,
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct io_card *card)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((name == NULL) || (node == NULL))
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(name, "SUNW,qlc") == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel decode_qlc_card_model_prop(node, card);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The name/model properties for a number of the QLC FCAL PCI cards are
03831d35f7499c87d51205817c93e9a8d42c4baestevel * identical (*), so we need to distinguish them using the subsystem-id
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and modify the model string to be more informative.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (*) Currently the problem cards are:
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Amber
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Crystal+
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baesteveldecode_qlc_card_model_prop(Prom_node *card_node, struct io_card *card)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel void *value = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (card_node == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel value = get_prop_val(find_prop(card_node, "subsystem-id"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (value != NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel int id = *(int *)value;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch (id) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case AMBER_SUBSYSTEM_ID:
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(card->model, MAX_QLC_MODEL_LEN, "%s",
03831d35f7499c87d51205817c93e9a8d42c4baestevel AMBER_CARD_NAME);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel case CRYSTAL_SUBSYSTEM_ID:
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(card->model, MAX_QLC_MODEL_LEN, "%s",
03831d35f7499c87d51205817c93e9a8d42c4baestevel CRYSTAL_CARD_NAME);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel default:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If information has been saved into the model field
03831d35f7499c87d51205817c93e9a8d42c4baestevel * before this function was called we will keep it as
03831d35f7499c87d51205817c93e9a8d42c4baestevel * it probably will be more meaningful that the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * subsystem-id, otherwise we save the subsystem-id in
03831d35f7499c87d51205817c93e9a8d42c4baestevel * the hope that it will distinguish the cards.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (strcmp(card->model, "") == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel (void) snprintf(card->model, MAX_QLC_MODEL_LEN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "0x%x", id);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}