xref: /onnv-gate/usr/src/cmd/prtconf/prt_xxx.c (revision 11519:a95237058a37)
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