10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
53285Sgovinda * Common Development and Distribution License (the "License").
63285Sgovinda * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*11519SGarrett.Damore@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #include <stdio.h>
270Sstevel@tonic-gate #include <stddef.h>
280Sstevel@tonic-gate #include <fcntl.h>
290Sstevel@tonic-gate #include <string.h>
300Sstevel@tonic-gate #include <libdevinfo.h>
310Sstevel@tonic-gate #include <sys/pctypes.h>
320Sstevel@tonic-gate #include <sys/pcmcia.h>
330Sstevel@tonic-gate #include <sys/utsname.h>
340Sstevel@tonic-gate #include <sys/avintr.h>
350Sstevel@tonic-gate
360Sstevel@tonic-gate #include "prtconf.h"
370Sstevel@tonic-gate
380Sstevel@tonic-gate struct priv_data {
390Sstevel@tonic-gate char *drv_name; /* parent name */
400Sstevel@tonic-gate void (*pd_print)(uintptr_t, int); /* print function */
410Sstevel@tonic-gate };
420Sstevel@tonic-gate
430Sstevel@tonic-gate extern void indent_to_level();
440Sstevel@tonic-gate static void obio_printregs(struct regspec *, int);
450Sstevel@tonic-gate static void obio_printranges(struct rangespec *, int);
460Sstevel@tonic-gate static void obio_printintr(struct intrspec *, int);
470Sstevel@tonic-gate static void obio_print(uintptr_t, int);
480Sstevel@tonic-gate static void pcmcia_printregs(struct pcm_regs *, int);
490Sstevel@tonic-gate static void pcmcia_printintr(struct intrspec *, int);
500Sstevel@tonic-gate static void pcmcia_print(uintptr_t, int);
510Sstevel@tonic-gate static void sbus_print(uintptr_t, int);
520Sstevel@tonic-gate static struct priv_data *match_priv_data(di_node_t);
530Sstevel@tonic-gate
540Sstevel@tonic-gate /*
550Sstevel@tonic-gate * This is a hardcoded list of drivers we print parent private
560Sstevel@tonic-gate * data as of Solaris 7.
570Sstevel@tonic-gate */
580Sstevel@tonic-gate static struct di_priv_format ppd_format[] = {
590Sstevel@tonic-gate {
600Sstevel@tonic-gate /*
610Sstevel@tonic-gate * obio format: applies the following list
620Sstevel@tonic-gate * of nexus drivers. Note that obio driver
630Sstevel@tonic-gate * went away with sun4m.
640Sstevel@tonic-gate */
653285Sgovinda #ifdef __sparc
663285Sgovinda "central dma ebus fhc isa pci rootnex",
673285Sgovinda #else
68505Scth "central dma ebus fhc isa pci pci_pci rootnex",
693285Sgovinda #endif /* __sparc */
700Sstevel@tonic-gate sizeof (struct ddi_parent_private_data),
710Sstevel@tonic-gate
720Sstevel@tonic-gate sizeof (struct regspec), /* first pointer */
730Sstevel@tonic-gate offsetof(struct ddi_parent_private_data, par_reg),
740Sstevel@tonic-gate offsetof(struct ddi_parent_private_data, par_nreg),
750Sstevel@tonic-gate
760Sstevel@tonic-gate sizeof (struct intrspec), /* second pointer */
770Sstevel@tonic-gate offsetof(struct ddi_parent_private_data, par_intr),
780Sstevel@tonic-gate offsetof(struct ddi_parent_private_data, par_nintr),
790Sstevel@tonic-gate
800Sstevel@tonic-gate sizeof (struct rangespec), /* third pointer */
810Sstevel@tonic-gate offsetof(struct ddi_parent_private_data, par_rng),
820Sstevel@tonic-gate offsetof(struct ddi_parent_private_data, par_nrng),
830Sstevel@tonic-gate
840Sstevel@tonic-gate 0, 0, 0, /* no more pointers */
850Sstevel@tonic-gate 0, 0, 0
860Sstevel@tonic-gate },
870Sstevel@tonic-gate
880Sstevel@tonic-gate { /* pcmcia format */
89*11519SGarrett.Damore@Sun.COM "pcic",
900Sstevel@tonic-gate sizeof (struct pcmcia_parent_private),
910Sstevel@tonic-gate
920Sstevel@tonic-gate sizeof (struct pcm_regs), /* first pointer */
930Sstevel@tonic-gate offsetof(struct pcmcia_parent_private, ppd_reg),
940Sstevel@tonic-gate offsetof(struct pcmcia_parent_private, ppd_nreg),
950Sstevel@tonic-gate
960Sstevel@tonic-gate sizeof (struct intrspec), /* second pointer */
970Sstevel@tonic-gate offsetof(struct pcmcia_parent_private, ppd_intrspec),
980Sstevel@tonic-gate offsetof(struct pcmcia_parent_private, ppd_intr),
990Sstevel@tonic-gate
1000Sstevel@tonic-gate 0, 0, 0, /* no more pointers */
1010Sstevel@tonic-gate 0, 0, 0,
1020Sstevel@tonic-gate 0, 0, 0
1030Sstevel@tonic-gate },
1040Sstevel@tonic-gate
1050Sstevel@tonic-gate { /* sbus format--it's different on sun4u!! */
1060Sstevel@tonic-gate "sbus",
1070Sstevel@tonic-gate sizeof (struct ddi_parent_private_data),
1080Sstevel@tonic-gate
1090Sstevel@tonic-gate sizeof (struct regspec), /* first pointer */
1100Sstevel@tonic-gate offsetof(struct ddi_parent_private_data, par_reg),
1110Sstevel@tonic-gate offsetof(struct ddi_parent_private_data, par_nreg),
1120Sstevel@tonic-gate
1130Sstevel@tonic-gate sizeof (struct intrspec), /* second pointer */
1140Sstevel@tonic-gate offsetof(struct ddi_parent_private_data, par_intr),
1150Sstevel@tonic-gate offsetof(struct ddi_parent_private_data, par_nintr),
1160Sstevel@tonic-gate
1170Sstevel@tonic-gate sizeof (struct rangespec), /* third pointer */
1180Sstevel@tonic-gate offsetof(struct ddi_parent_private_data, par_rng),
1190Sstevel@tonic-gate offsetof(struct ddi_parent_private_data, par_nrng),
1200Sstevel@tonic-gate
1210Sstevel@tonic-gate 0, 0, 0, /* no more pointers */
1220Sstevel@tonic-gate 0, 0, 0
1230Sstevel@tonic-gate }
1240Sstevel@tonic-gate };
1250Sstevel@tonic-gate
1260Sstevel@tonic-gate static struct priv_data prt_priv_data[] = {
1270Sstevel@tonic-gate { ppd_format[0].drv_name, obio_print},
1280Sstevel@tonic-gate { ppd_format[1].drv_name, pcmcia_print},
1290Sstevel@tonic-gate { ppd_format[2].drv_name, sbus_print}
1300Sstevel@tonic-gate };
1310Sstevel@tonic-gate
1320Sstevel@tonic-gate static int nprt_priv_data = sizeof (prt_priv_data)/sizeof (struct priv_data);
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate void
init_priv_data(struct di_priv_data * fetch)1350Sstevel@tonic-gate init_priv_data(struct di_priv_data *fetch)
1360Sstevel@tonic-gate {
1370Sstevel@tonic-gate /* no driver private data */
1380Sstevel@tonic-gate fetch->version = DI_PRIVDATA_VERSION_0;
1390Sstevel@tonic-gate fetch->n_driver = 0;
1400Sstevel@tonic-gate fetch->driver = NULL;
1410Sstevel@tonic-gate
1420Sstevel@tonic-gate fetch->n_parent = nprt_priv_data;
1430Sstevel@tonic-gate fetch->parent = ppd_format;
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate static void
obio_printregs(struct regspec * rp,int ilev)1470Sstevel@tonic-gate obio_printregs(struct regspec *rp, int ilev)
1480Sstevel@tonic-gate {
1490Sstevel@tonic-gate indent_to_level(ilev);
1500Sstevel@tonic-gate (void) printf(" Bus Type=0x%x, Address=0x%x, Size=0x%x\n",
1510Sstevel@tonic-gate rp->regspec_bustype, rp->regspec_addr, rp->regspec_size);
1520Sstevel@tonic-gate }
1530Sstevel@tonic-gate
1540Sstevel@tonic-gate static void
obio_printranges(struct rangespec * rp,int ilev)1550Sstevel@tonic-gate obio_printranges(struct rangespec *rp, int ilev)
1560Sstevel@tonic-gate {
1570Sstevel@tonic-gate indent_to_level(ilev);
1580Sstevel@tonic-gate (void) printf(" Ch: %.2x,%.8x Pa: %.2x,%.8x, Sz: %x\n",
1590Sstevel@tonic-gate rp->rng_cbustype, rp->rng_coffset,
1600Sstevel@tonic-gate rp->rng_bustype, rp->rng_offset,
1610Sstevel@tonic-gate rp->rng_size);
1620Sstevel@tonic-gate }
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate static void
obio_printintr(struct intrspec * ip,int ilev)1650Sstevel@tonic-gate obio_printintr(struct intrspec *ip, int ilev)
1660Sstevel@tonic-gate {
1670Sstevel@tonic-gate indent_to_level(ilev);
1680Sstevel@tonic-gate (void) printf(" Interrupt Priority=0x%x (ipl %d)",
1690Sstevel@tonic-gate ip->intrspec_pri, INT_IPL(ip->intrspec_pri));
1700Sstevel@tonic-gate if (ip->intrspec_vec)
1710Sstevel@tonic-gate (void) printf(", vector=0x%x (%d)",
1720Sstevel@tonic-gate ip->intrspec_vec, ip->intrspec_vec);
1730Sstevel@tonic-gate (void) printf("\n");
1740Sstevel@tonic-gate }
1750Sstevel@tonic-gate
1760Sstevel@tonic-gate static void
obio_print(uintptr_t data,int ilev)1770Sstevel@tonic-gate obio_print(uintptr_t data, int ilev)
1780Sstevel@tonic-gate {
1790Sstevel@tonic-gate int i, nreg, nrng, nintr;
1800Sstevel@tonic-gate struct ddi_parent_private_data *dp;
1810Sstevel@tonic-gate struct regspec *reg;
1820Sstevel@tonic-gate struct intrspec *intr;
1830Sstevel@tonic-gate struct rangespec *rng;
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate dp = (struct ddi_parent_private_data *)data;
1860Sstevel@tonic-gate #ifdef DEBUG
1870Sstevel@tonic-gate dprintf("obio parent private data: nreg = 0x%x offset = 0x%x"
1880Sstevel@tonic-gate " nintr = 0x%x offset = 0x%x nrng = 0x%x offset = %x\n",
1890Sstevel@tonic-gate dp->par_nreg, *((di_off_t *)(&dp->par_reg)),
1900Sstevel@tonic-gate dp->par_nintr, *((di_off_t *)(&dp->par_intr)),
1910Sstevel@tonic-gate dp->par_nrng, *((di_off_t *)(&dp->par_rng)));
1920Sstevel@tonic-gate #endif /* DEBUG */
1930Sstevel@tonic-gate nreg = dp->par_nreg;
1940Sstevel@tonic-gate nintr = dp->par_nintr;
1950Sstevel@tonic-gate nrng = dp->par_nrng;
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate /*
1980Sstevel@tonic-gate * All pointers are translated to di_off_t by the devinfo driver.
1990Sstevel@tonic-gate * This is a private agreement between libdevinfo and prtconf.
2000Sstevel@tonic-gate */
2010Sstevel@tonic-gate if (nreg != 0) {
2020Sstevel@tonic-gate indent_to_level(ilev);
2030Sstevel@tonic-gate (void) printf("Register Specifications:\n");
2040Sstevel@tonic-gate
2050Sstevel@tonic-gate reg = (struct regspec *)(data + *(di_off_t *)(&dp->par_reg));
2060Sstevel@tonic-gate for (i = 0; i < nreg; ++i)
2070Sstevel@tonic-gate obio_printregs(reg + i, ilev);
2080Sstevel@tonic-gate }
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate if (nrng != 0) {
2110Sstevel@tonic-gate indent_to_level(ilev);
2120Sstevel@tonic-gate (void) printf("Range Specifications:\n");
2130Sstevel@tonic-gate
2140Sstevel@tonic-gate rng = (struct rangespec *)(data + *(di_off_t *)(&dp->par_rng));
2150Sstevel@tonic-gate for (i = 0; i < nrng; ++i)
2160Sstevel@tonic-gate obio_printranges(rng + i, ilev);
2170Sstevel@tonic-gate }
2180Sstevel@tonic-gate
2190Sstevel@tonic-gate if (nintr != 0) {
2200Sstevel@tonic-gate indent_to_level(ilev);
2210Sstevel@tonic-gate (void) printf("Interrupt Specifications:\n");
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate intr = (struct intrspec *)(data + *(di_off_t *)(&dp->par_intr));
2240Sstevel@tonic-gate for (i = 0; i < nintr; ++i)
2250Sstevel@tonic-gate obio_printintr(intr + i, ilev);
2260Sstevel@tonic-gate }
2270Sstevel@tonic-gate }
2280Sstevel@tonic-gate
2290Sstevel@tonic-gate static void
pcmcia_printregs(struct pcm_regs * rp,int ilev)2300Sstevel@tonic-gate pcmcia_printregs(struct pcm_regs *rp, int ilev)
2310Sstevel@tonic-gate {
2320Sstevel@tonic-gate indent_to_level(ilev);
2330Sstevel@tonic-gate (void) printf(" Phys hi=0x%x, Phys lo=0x%x, Phys len=%x\n",
2340Sstevel@tonic-gate rp->phys_hi, rp->phys_lo, rp->phys_len);
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate static void
pcmcia_printintr(struct intrspec * ip,int ilev)2380Sstevel@tonic-gate pcmcia_printintr(struct intrspec *ip, int ilev)
2390Sstevel@tonic-gate {
2400Sstevel@tonic-gate obio_printintr(ip, ilev);
2410Sstevel@tonic-gate }
2420Sstevel@tonic-gate
2430Sstevel@tonic-gate static void
pcmcia_print(uintptr_t data,int ilev)2440Sstevel@tonic-gate pcmcia_print(uintptr_t data, int ilev)
2450Sstevel@tonic-gate {
2460Sstevel@tonic-gate int i, nreg, nintr;
2470Sstevel@tonic-gate struct pcmcia_parent_private *dp;
2480Sstevel@tonic-gate struct pcm_regs *reg;
2490Sstevel@tonic-gate struct intrspec *intr;
2500Sstevel@tonic-gate
2510Sstevel@tonic-gate dp = (struct pcmcia_parent_private *)data;
2520Sstevel@tonic-gate #ifdef DEBUG
2530Sstevel@tonic-gate dprintf("pcmcia parent private data: nreg = 0x%x offset = 0x%x"
2540Sstevel@tonic-gate " intr = 0x%x offset = %x\n",
2550Sstevel@tonic-gate dp->ppd_nreg, *(di_off_t *)(&dp->ppd_reg),
2560Sstevel@tonic-gate dp->ppd_intr, *(di_off_t *)(&dp->ppd_intrspec));
2570Sstevel@tonic-gate #endif /* DEBUG */
2580Sstevel@tonic-gate nreg = dp->ppd_nreg;
2590Sstevel@tonic-gate nintr = dp->ppd_intr;
2600Sstevel@tonic-gate
2610Sstevel@tonic-gate /*
2620Sstevel@tonic-gate * All pointers are translated to di_off_t by the devinfo driver.
2630Sstevel@tonic-gate * This is a private agreement between libdevinfo and prtconf.
2640Sstevel@tonic-gate */
2650Sstevel@tonic-gate if (nreg != 0) {
2660Sstevel@tonic-gate indent_to_level(ilev);
2670Sstevel@tonic-gate (void) printf("Register Specifications:\n");
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate reg = (struct pcm_regs *)(data + *(di_off_t *)(&dp->ppd_reg));
2700Sstevel@tonic-gate for (i = 0; i < nreg; ++i)
2710Sstevel@tonic-gate pcmcia_printregs(reg + i, ilev);
2720Sstevel@tonic-gate }
2730Sstevel@tonic-gate
2740Sstevel@tonic-gate if (nintr != 0) {
2750Sstevel@tonic-gate indent_to_level(ilev);
2760Sstevel@tonic-gate (void) printf("Interrupt Specifications:\n");
2770Sstevel@tonic-gate
2780Sstevel@tonic-gate intr = (struct intrspec *)
2790Sstevel@tonic-gate (data + *(di_off_t *)(&dp->ppd_intrspec));
2800Sstevel@tonic-gate for (i = 0; i < nintr; ++i)
2810Sstevel@tonic-gate pcmcia_printintr(intr + i, ilev);
2820Sstevel@tonic-gate }
2830Sstevel@tonic-gate }
2840Sstevel@tonic-gate
2850Sstevel@tonic-gate static void
sbus_print(uintptr_t data,int ilev)2860Sstevel@tonic-gate sbus_print(uintptr_t data, int ilev)
2870Sstevel@tonic-gate {
2880Sstevel@tonic-gate int i, nreg, nrng, nintr;
2890Sstevel@tonic-gate struct ddi_parent_private_data *dp;
2900Sstevel@tonic-gate struct regspec *reg;
2910Sstevel@tonic-gate struct intrspec *intr;
2920Sstevel@tonic-gate struct rangespec *rng;
2930Sstevel@tonic-gate
2940Sstevel@tonic-gate dp = (struct ddi_parent_private_data *)data;
2950Sstevel@tonic-gate #ifdef DEBUG
2960Sstevel@tonic-gate dprintf("sbus parent private data: nreg = 0x%x offset = 0x%x"
2970Sstevel@tonic-gate " nintr = 0x%x offset = 0x%x nrng = 0x%x offset = %x\n",
2980Sstevel@tonic-gate dp->par_nreg, *((di_off_t *)(&dp->par_reg)),
2990Sstevel@tonic-gate dp->par_nintr, *((di_off_t *)(&dp->par_intr)),
3000Sstevel@tonic-gate dp->par_nrng, *((di_off_t *)(&dp->par_rng)));
3010Sstevel@tonic-gate #endif /* DEBUG */
3020Sstevel@tonic-gate nreg = dp->par_nreg;
3030Sstevel@tonic-gate nintr = dp->par_nintr;
3040Sstevel@tonic-gate nrng = dp->par_nrng;
3050Sstevel@tonic-gate
3060Sstevel@tonic-gate /*
3070Sstevel@tonic-gate * All pointers are translated to di_off_t by the devinfo driver.
3080Sstevel@tonic-gate * This is a private agreement between libdevinfo and prtconf.
3090Sstevel@tonic-gate */
3100Sstevel@tonic-gate if (nreg != 0) {
3110Sstevel@tonic-gate indent_to_level(ilev);
3120Sstevel@tonic-gate (void) printf("Register Specifications:\n");
3130Sstevel@tonic-gate
3140Sstevel@tonic-gate reg = (struct regspec *)(data + *(di_off_t *)(&dp->par_reg));
3150Sstevel@tonic-gate for (i = 0; i < nreg; ++i)
3160Sstevel@tonic-gate obio_printregs(reg + i, ilev);
3170Sstevel@tonic-gate }
3180Sstevel@tonic-gate
3190Sstevel@tonic-gate
3200Sstevel@tonic-gate if (nrng != 0) {
3210Sstevel@tonic-gate indent_to_level(ilev);
3220Sstevel@tonic-gate (void) printf("Range Specifications:\n");
3230Sstevel@tonic-gate
3240Sstevel@tonic-gate rng = (struct rangespec *)(data + *(di_off_t *)(&dp->par_rng));
3250Sstevel@tonic-gate for (i = 0; i < nrng; ++i)
3260Sstevel@tonic-gate obio_printranges(rng + i, ilev);
3270Sstevel@tonic-gate }
3280Sstevel@tonic-gate
3290Sstevel@tonic-gate /*
3300Sstevel@tonic-gate * To print interrupt property for children of sbus on sun4u requires
3310Sstevel@tonic-gate * definitions in sysiosbus.h.
3320Sstevel@tonic-gate *
3330Sstevel@tonic-gate * We can't #include <sys/sysiosbus.h> to have the build work on
3340Sstevel@tonic-gate * non sun4u machines. It's not right either to
3350Sstevel@tonic-gate * #include "../../uts/sun4u/sys/sysiosbus.h"
3360Sstevel@tonic-gate * As a result, we will not print the information.
3370Sstevel@tonic-gate */
3380Sstevel@tonic-gate if ((nintr != 0) && (strcmp(opts.o_uts.machine, "sun4u") != 0)) {
3390Sstevel@tonic-gate indent_to_level(ilev);
3400Sstevel@tonic-gate (void) printf("Interrupt Specifications:\n");
3410Sstevel@tonic-gate
3420Sstevel@tonic-gate for (i = 0; i < nintr; ++i) {
3430Sstevel@tonic-gate intr = (struct intrspec *)
3440Sstevel@tonic-gate (data + *(di_off_t *)(&dp->par_intr));
3450Sstevel@tonic-gate obio_printintr(intr + i, ilev);
3460Sstevel@tonic-gate }
3470Sstevel@tonic-gate }
3480Sstevel@tonic-gate }
3490Sstevel@tonic-gate
3500Sstevel@tonic-gate static struct priv_data *
match_priv_data(di_node_t node)3510Sstevel@tonic-gate match_priv_data(di_node_t node)
3520Sstevel@tonic-gate {
3530Sstevel@tonic-gate int i;
3540Sstevel@tonic-gate size_t len;
3550Sstevel@tonic-gate char *drv_name, *tmp;
3560Sstevel@tonic-gate di_node_t parent;
3570Sstevel@tonic-gate struct priv_data *pdp;
3580Sstevel@tonic-gate
3590Sstevel@tonic-gate if ((parent = di_parent_node(node)) == DI_NODE_NIL)
3600Sstevel@tonic-gate return (NULL);
3610Sstevel@tonic-gate
3620Sstevel@tonic-gate if ((drv_name = di_driver_name(parent)) == NULL)
3630Sstevel@tonic-gate return (NULL);
3640Sstevel@tonic-gate
3650Sstevel@tonic-gate pdp = prt_priv_data;
3660Sstevel@tonic-gate len = strlen(drv_name);
3670Sstevel@tonic-gate for (i = 0; i < nprt_priv_data; ++i, ++pdp) {
3680Sstevel@tonic-gate tmp = pdp->drv_name;
3690Sstevel@tonic-gate while (tmp && (*tmp != '\0')) {
3700Sstevel@tonic-gate if (strncmp(tmp, drv_name, len) == 0) {
3710Sstevel@tonic-gate #ifdef DEBUG
3720Sstevel@tonic-gate dprintf("matched parent private data"
3730Sstevel@tonic-gate " at Node <%s> parent driver <%s>\n",
3740Sstevel@tonic-gate di_node_name(node), drv_name);
3750Sstevel@tonic-gate #endif /* DEBUG */
3760Sstevel@tonic-gate return (pdp);
3770Sstevel@tonic-gate }
3780Sstevel@tonic-gate /*
3790Sstevel@tonic-gate * skip a white space
3800Sstevel@tonic-gate */
3810Sstevel@tonic-gate if (tmp = strchr(tmp, ' '))
3820Sstevel@tonic-gate tmp++;
3830Sstevel@tonic-gate }
3840Sstevel@tonic-gate }
3850Sstevel@tonic-gate
3860Sstevel@tonic-gate return (NULL);
3870Sstevel@tonic-gate }
3880Sstevel@tonic-gate
3890Sstevel@tonic-gate void
dump_priv_data(int ilev,di_node_t node)3900Sstevel@tonic-gate dump_priv_data(int ilev, di_node_t node)
3910Sstevel@tonic-gate {
3920Sstevel@tonic-gate uintptr_t priv;
3930Sstevel@tonic-gate struct priv_data *pdp;
3940Sstevel@tonic-gate
3950Sstevel@tonic-gate if ((priv = (uintptr_t)di_parent_private_data(node)) == NULL)
3960Sstevel@tonic-gate return;
3970Sstevel@tonic-gate
3980Sstevel@tonic-gate if ((pdp = match_priv_data(node)) == NULL) {
3990Sstevel@tonic-gate #ifdef DEBUG
4000Sstevel@tonic-gate dprintf("Error: parent private data format unknown\n");
4010Sstevel@tonic-gate #endif /* DEBUG */
4020Sstevel@tonic-gate return;
4030Sstevel@tonic-gate }
4040Sstevel@tonic-gate
4050Sstevel@tonic-gate pdp->pd_print(priv, ilev);
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate /* ignore driver private data for now */
4080Sstevel@tonic-gate }
4099074SJudy.Chen@Sun.COM
4109074SJudy.Chen@Sun.COM #define LOOKUP_PROP(proptype, ph, nodetype, dev, node, name, data) \
4119074SJudy.Chen@Sun.COM ((nodetype == DI_PROM_NODEID) ? \
4129074SJudy.Chen@Sun.COM di_prom_prop_lookup_##proptype(ph, node, name, data) : \
4139074SJudy.Chen@Sun.COM di_prop_lookup_##proptype(dev, node, name, data))
4149074SJudy.Chen@Sun.COM #define ISPCI(s) \
4159074SJudy.Chen@Sun.COM (((s) != NULL) && ((strcmp((s), "pci") == 0) || \
4169074SJudy.Chen@Sun.COM (strcmp((s), "pciex") == 0)))
4179074SJudy.Chen@Sun.COM /*
4189074SJudy.Chen@Sun.COM * Print vendor ID and device ID for PCI devices
4199074SJudy.Chen@Sun.COM */
4209074SJudy.Chen@Sun.COM int
print_pciid(di_node_t node,di_prom_handle_t ph)4219074SJudy.Chen@Sun.COM print_pciid(di_node_t node, di_prom_handle_t ph)
4229074SJudy.Chen@Sun.COM {
4239074SJudy.Chen@Sun.COM di_node_t pnode = di_parent_node(node);
4249074SJudy.Chen@Sun.COM char *s = NULL;
4259074SJudy.Chen@Sun.COM int *i, type = di_nodeid(node);
4269074SJudy.Chen@Sun.COM
4279074SJudy.Chen@Sun.COM if (LOOKUP_PROP(strings, ph, type, DDI_DEV_T_ANY, pnode,
4289074SJudy.Chen@Sun.COM "device_type", &s) <= 0)
4299074SJudy.Chen@Sun.COM return (0);
4309074SJudy.Chen@Sun.COM
4319074SJudy.Chen@Sun.COM if (!ISPCI(s))
4329074SJudy.Chen@Sun.COM return (0); /* not a pci device */
4339074SJudy.Chen@Sun.COM
4349074SJudy.Chen@Sun.COM (void) printf(" (%s", s);
4359074SJudy.Chen@Sun.COM if (LOOKUP_PROP(ints, ph, type, DDI_DEV_T_ANY, node,
4369074SJudy.Chen@Sun.COM "vendor-id", &i) > 0)
4379074SJudy.Chen@Sun.COM (void) printf("%x", i[0]);
4389074SJudy.Chen@Sun.COM
4399074SJudy.Chen@Sun.COM if (LOOKUP_PROP(ints, ph, type, DDI_DEV_T_ANY, node,
4409074SJudy.Chen@Sun.COM "device-id", &i) > 0)
4419074SJudy.Chen@Sun.COM (void) printf(",%x", i[0]);
4429074SJudy.Chen@Sun.COM (void) printf(")");
4439074SJudy.Chen@Sun.COM
4449074SJudy.Chen@Sun.COM return (1);
4459074SJudy.Chen@Sun.COM }
446