xref: /onnv-gate/usr/src/cmd/mdb/sparc/modules/intr/intr.c (revision 2973:55b674bffad9)
1909Segillett /*
2909Segillett  * CDDL HEADER START
3909Segillett  *
4909Segillett  * The contents of this file are subject to the terms of the
51725Segillett  * Common Development and Distribution License (the "License").
61725Segillett  * You may not use this file except in compliance with the License.
7909Segillett  *
8909Segillett  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9909Segillett  * or http://www.opensolaris.org/os/licensing.
10909Segillett  * See the License for the specific language governing permissions
11909Segillett  * and limitations under the License.
12909Segillett  *
13909Segillett  * When distributing Covered Code, include this CDDL HEADER in each
14909Segillett  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15909Segillett  * If applicable, add the following below this CDDL HEADER, with the
16909Segillett  * fields enclosed by brackets "[]" replaced with your own identifying
17909Segillett  * information: Portions Copyright [yyyy] [name of copyright owner]
18909Segillett  *
19909Segillett  * CDDL HEADER END
20909Segillett  */
21909Segillett /*
221725Segillett  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23909Segillett  * Use is subject to license terms.
24909Segillett  */
25909Segillett 
26909Segillett #pragma ident	"%Z%%M%	%I%	%E% SMI"
27909Segillett 
28909Segillett #include <sys/mdb_modapi.h>
29909Segillett #include <mdb/mdb_ks.h>
30909Segillett #include <sys/async.h>		/* ecc_flt for pci_ecc.h */
31909Segillett #include <sys/ddi_subrdefs.h>
32909Segillett #include <sys/pci/pci_obj.h>
33909Segillett #include "px_obj.h"
34909Segillett 
35909Segillett static int intr_pci_walk_step(mdb_walk_state_t *);
36909Segillett static int intr_px_walk_step(mdb_walk_state_t *);
37909Segillett static void intr_pci_print_items(mdb_walk_state_t *);
38909Segillett static void intr_px_print_items(mdb_walk_state_t *);
391725Segillett static char *intr_get_intr_type(uint16_t type);
40909Segillett static void intr_print_banner(void);
41909Segillett 
42909Segillett typedef struct intr_info {
43909Segillett 	uint32_t	cpuid;
44909Segillett 	uint32_t	inum;
45909Segillett 	uint32_t	num;
46909Segillett 	uint32_t	pil;
471725Segillett 	uint16_t	intr_type;
48909Segillett 	uint16_t	mondo;
49909Segillett 	uint8_t		ino_ino;
50909Segillett 	uint_t		intr_state;
51909Segillett 	int		instance;
52909Segillett 	int		shared;
53909Segillett 	char		driver_name[12];
54909Segillett 	char		pathname[MAXNAMELEN];
55909Segillett }
56909Segillett intr_info_t;
57909Segillett 
58909Segillett static void intr_print_elements(intr_info_t);
59909Segillett static int detailed = 0; /* Print detailed view */
60909Segillett 
61909Segillett 
62909Segillett static int
63909Segillett intr_walk_init(mdb_walk_state_t *wsp)
64909Segillett {
65909Segillett 	wsp->walk_addr = NULL;
66909Segillett 
67909Segillett 	return (WALK_NEXT);
68909Segillett }
69909Segillett 
70909Segillett static int
71909Segillett intr_walk_step(mdb_walk_state_t *wsp)
72909Segillett {
73909Segillett 	pci_t		*pci_per_p;
74909Segillett 	px_t		*px_state_p;
75909Segillett 
76909Segillett 	/* read globally declared structures in the pci driver */
77909Segillett 	if (mdb_readvar(&pci_per_p, "per_pci_state") != -1) {
78909Segillett 		wsp->walk_addr = (uintptr_t)pci_per_p;
79909Segillett 		intr_pci_walk_step(wsp);
80909Segillett 	}
81909Segillett 
82909Segillett 	/* read globally declared structures in the px driver */
83909Segillett 	if (mdb_readvar(&px_state_p, "px_state_p") != -1) {
84909Segillett 		wsp->walk_addr = (uintptr_t)px_state_p;
85909Segillett 		intr_px_walk_step(wsp);
86909Segillett 	}
87909Segillett 
88909Segillett 	return (WALK_DONE);
89909Segillett }
90909Segillett 
91909Segillett static int
92909Segillett intr_pci_walk_step(mdb_walk_state_t *wsp)
93909Segillett {
94909Segillett 	pci_t		*pci_per_p;
95909Segillett 	pci_t		pci_per;
96909Segillett 	uintptr_t	start_addr;
97909Segillett 
98909Segillett 	/* Read start of state structure array */
99909Segillett 	if (mdb_vread(&pci_per_p, sizeof (uintptr_t),
100909Segillett 	    (uintptr_t)wsp->walk_addr) == -1) {
101909Segillett 		mdb_warn("intr: failed to read the initial pci_per_p "
102909Segillett 		    "structure\n");
103909Segillett 		return (WALK_ERR);
104909Segillett 	}
105909Segillett 
106909Segillett 	/* Figure out how many items are here */
107909Segillett 	start_addr = (uintptr_t)pci_per_p;
108909Segillett 
109965Sgovinda 	intr_print_banner();
110965Sgovinda 
111909Segillett 	while (mdb_vread(&pci_per_p, sizeof (uintptr_t),
112909Segillett 	    (uintptr_t)start_addr) != -1) {
113909Segillett 		/* Read until nothing is left */
114909Segillett 		if (mdb_vread(&pci_per, sizeof (pci_t),
115909Segillett 		    (uintptr_t)pci_per_p) == -1) {
116909Segillett 			return (WALK_DONE);
117909Segillett 		}
118909Segillett 
119909Segillett 		wsp->walk_addr = (uintptr_t)pci_per.pci_ib_p;
120909Segillett 		intr_pci_print_items(wsp);
121909Segillett 
122909Segillett 		start_addr += sizeof (uintptr_t);
123909Segillett 	}
124909Segillett 
125909Segillett 	return (WALK_DONE);
126909Segillett }
127909Segillett 
128909Segillett static int
129909Segillett intr_px_walk_step(mdb_walk_state_t *wsp)
130909Segillett {
131909Segillett 	px_t		*px_state_p;
132909Segillett 	px_t		px_state;
133909Segillett 	uintptr_t	start_addr;
134909Segillett 
135909Segillett 	/* Read start of state structure array */
136909Segillett 	if (mdb_vread(&px_state_p, sizeof (uintptr_t),
137909Segillett 	    (uintptr_t)wsp->walk_addr) == -1) {
138909Segillett 		mdb_warn("intr: failed to read the initial px_per_p "
139909Segillett 		    "structure\n");
140909Segillett 		return (WALK_ERR);
141909Segillett 	}
142909Segillett 
143909Segillett 	/* Figure out how many items are here */
144909Segillett 	start_addr = (uintptr_t)px_state_p;
145909Segillett 
146965Sgovinda 	intr_print_banner();
147965Sgovinda 
148909Segillett 	while (mdb_vread(&px_state_p, sizeof (uintptr_t),
149909Segillett 	    (uintptr_t)start_addr) != -1) {
150909Segillett 		/* Read until nothing is left */
151909Segillett 		if (mdb_vread(&px_state, sizeof (px_t),
152909Segillett 		    (uintptr_t)px_state_p) == -1) {
153909Segillett 			return (WALK_DONE);
154909Segillett 		}
155909Segillett 
156909Segillett 		wsp->walk_addr = (uintptr_t)px_state.px_ib_p;
157909Segillett 		intr_px_print_items(wsp);
158909Segillett 
159909Segillett 		start_addr += sizeof (uintptr_t);
160909Segillett 	}
161909Segillett 
162909Segillett 	return (WALK_DONE);
163909Segillett }
164909Segillett 
165909Segillett static void
166909Segillett intr_pci_print_items(mdb_walk_state_t *wsp)
167909Segillett {
168*2973Sgovinda 	ib_t			ib;
169*2973Sgovinda 	ib_ino_info_t		ino;
170*2973Sgovinda 	ib_ino_pil_t		ipil;
171909Segillett 	ih_t			ih;
172909Segillett 	int			count;
173909Segillett 	char			name[MODMAXNAMELEN + 1];
174*2973Sgovinda 	struct dev_info		dev;
175909Segillett 	intr_info_t		info;
176909Segillett 
177*2973Sgovinda 	if (mdb_vread(&ib, sizeof (ib_t),
178909Segillett 	    (uintptr_t)wsp->walk_addr) == -1) {
179909Segillett 		mdb_warn("intr: failed to read pci interrupt block "
180909Segillett 		    "structure\n");
181909Segillett 		return;
182909Segillett 	}
183909Segillett 
184909Segillett 	/* Read in ib_ino_info_t structure at address */
185*2973Sgovinda 	if (mdb_vread(&ino, sizeof (ib_ino_info_t),
186*2973Sgovinda 	    (uintptr_t)ib.ib_ino_lst) == -1) {
187909Segillett 		/* Nothing here to read from */
188909Segillett 		return;
189909Segillett 	}
190909Segillett 
191909Segillett 	do {
192*2973Sgovinda 		if (mdb_vread(&ipil, sizeof (ib_ino_pil_t),
193*2973Sgovinda 		    (uintptr_t)ino.ino_ipil_p) == -1) {
194*2973Sgovinda 			mdb_warn("intr: failed to read pci interrupt "
195*2973Sgovinda 			    "ib_ino_pil_t structure\n");
196909Segillett 			return;
197909Segillett 		}
198909Segillett 
199909Segillett 		do {
200*2973Sgovinda 			if (mdb_vread(&ih, sizeof (ih_t),
201*2973Sgovinda 			    (uintptr_t)ipil.ipil_ih_start) == -1) {
202*2973Sgovinda 				mdb_warn("intr: failed to read pci interrupt "
203*2973Sgovinda 				    "ih_t structure\n");
204909Segillett 				return;
205909Segillett 			}
206909Segillett 
207*2973Sgovinda 			count = 0;
208*2973Sgovinda 
209*2973Sgovinda 			do {
210*2973Sgovinda 				bzero((void *)&info, sizeof (intr_info_t));
211*2973Sgovinda 
212*2973Sgovinda 				if ((ino.ino_ipil_size > 1) ||
213*2973Sgovinda 				    (ipil.ipil_ih_size > 1)) {
214*2973Sgovinda 					info.shared = 1;
215*2973Sgovinda 				}
216*2973Sgovinda 
217*2973Sgovinda 				(void) mdb_devinfo2driver((uintptr_t)ih.ih_dip,
218*2973Sgovinda 				    name, sizeof (name));
219*2973Sgovinda 
220*2973Sgovinda 				(void) mdb_ddi_pathname((uintptr_t)ih.ih_dip,
221*2973Sgovinda 				    info.pathname, sizeof (info.pathname));
222*2973Sgovinda 
223*2973Sgovinda 				/* Get instance */
224*2973Sgovinda 				if (mdb_vread(&dev, sizeof (struct dev_info),
225*2973Sgovinda 				    (uintptr_t)ih.ih_dip) == -1) {
226*2973Sgovinda 					mdb_warn("intr: failed to read DIP "
227*2973Sgovinda 					    "structure\n");
228*2973Sgovinda 					return;
229*2973Sgovinda 				}
230909Segillett 
231*2973Sgovinda 				/* Make sure the name doesn't over run */
232*2973Sgovinda 				(void) mdb_snprintf(info.driver_name,
233*2973Sgovinda 				    sizeof (info.driver_name), "%s", name);
234*2973Sgovinda 
235*2973Sgovinda 				info.instance = dev.devi_instance;
236*2973Sgovinda 				info.inum = ih.ih_inum;
237*2973Sgovinda 				info.intr_type = DDI_INTR_TYPE_FIXED;
238*2973Sgovinda 				info.num = 0;
239*2973Sgovinda 				info.intr_state = ih.ih_intr_state;
240*2973Sgovinda 				info.ino_ino = ino.ino_ino;
241*2973Sgovinda 				info.mondo = ino.ino_mondo;
242*2973Sgovinda 				info.pil = ipil.ipil_pil;
243*2973Sgovinda 				info.cpuid = ino.ino_cpuid;
244909Segillett 
245*2973Sgovinda 				intr_print_elements(info);
246*2973Sgovinda 				count++;
247*2973Sgovinda 
248*2973Sgovinda 				(void) mdb_vread(&ih, sizeof (ih_t),
249*2973Sgovinda 				    (uintptr_t)ih.ih_next);
250909Segillett 
251*2973Sgovinda 			} while (count < ipil.ipil_ih_size);
252909Segillett 
253*2973Sgovinda 		} while (mdb_vread(&ipil, sizeof (ib_ino_pil_t),
254*2973Sgovinda 		    (uintptr_t)ipil.ipil_next_p) != -1);
255909Segillett 
256*2973Sgovinda 	} while (mdb_vread(&ino, sizeof (ib_ino_info_t),
257*2973Sgovinda 	    (uintptr_t)ino.ino_next_p) != -1);
258909Segillett }
259909Segillett 
260909Segillett static void
261909Segillett intr_px_print_items(mdb_walk_state_t *wsp)
262909Segillett {
263*2973Sgovinda 	px_ib_t		ib;
264*2973Sgovinda 	px_ino_t	ino;
265*2973Sgovinda 	px_ino_pil_t	ipil;
266*2973Sgovinda 	px_ih_t		ih;
267*2973Sgovinda 	int		count;
268*2973Sgovinda 	char		name[MODMAXNAMELEN + 1];
269*2973Sgovinda 	struct dev_info	dev;
270*2973Sgovinda 	intr_info_t	info;
271*2973Sgovinda 	devinfo_intr_t	intr_p;
272909Segillett 
273*2973Sgovinda 	if (mdb_vread(&ib, sizeof (px_ib_t), wsp->walk_addr) == -1) {
274909Segillett 		mdb_warn("intr: failed to read px interrupt block "
275909Segillett 		    "structure\n");
276909Segillett 		return;
277909Segillett 	}
278909Segillett 
279*2973Sgovinda 	/* Read in px_ino_t structure at address */
280*2973Sgovinda 	if (mdb_vread(&ino, sizeof (px_ino_t),
281*2973Sgovinda 	    (uintptr_t)ib.ib_ino_lst) == -1) {
282909Segillett 		/* Nothing here to read from */
283909Segillett 		return;
284909Segillett 	}
285909Segillett 
286909Segillett 	do {
287*2973Sgovinda 		if (mdb_vread(&ipil, sizeof (px_ino_pil_t),
288*2973Sgovinda 		    (uintptr_t)ino.ino_ipil_p) == -1) {
289*2973Sgovinda 			mdb_warn("intr: failed to read px interrupt "
290*2973Sgovinda 			    "px_ino_pil_t structure\n");
291909Segillett 			return;
292909Segillett 		}
293909Segillett 
294909Segillett 		do {
295*2973Sgovinda 			if (mdb_vread(&ih, sizeof (px_ih_t),
296*2973Sgovinda 			    (uintptr_t)ipil.ipil_ih_start) == -1) {
297*2973Sgovinda 				mdb_warn("intr: failed to read px interrupt "
298*2973Sgovinda 				    "px_ih_t structure\n");
299909Segillett 				return;
300909Segillett 			}
301909Segillett 
302*2973Sgovinda 			count = 0;
303*2973Sgovinda 
304*2973Sgovinda 			do {
305*2973Sgovinda 				bzero((void *)&info, sizeof (intr_info_t));
306909Segillett 
307*2973Sgovinda 				(void) mdb_devinfo2driver((uintptr_t)ih.ih_dip,
308*2973Sgovinda 				    name, sizeof (name));
309*2973Sgovinda 
310*2973Sgovinda 				(void) mdb_ddi_pathname((uintptr_t)ih.ih_dip,
311*2973Sgovinda 				    info.pathname, sizeof (info.pathname));
3121725Segillett 
313*2973Sgovinda 				/* Get instance */
314*2973Sgovinda 				if (mdb_vread(&dev, sizeof (struct dev_info),
315*2973Sgovinda 				    (uintptr_t)ih.ih_dip) == -1) {
316*2973Sgovinda 					mdb_warn("intr: failed to read DIP "
317*2973Sgovinda 					    "structure\n");
318*2973Sgovinda 					return;
319*2973Sgovinda 				}
320*2973Sgovinda 
321*2973Sgovinda 				/* Make sure the name doesn't over run */
322*2973Sgovinda 				(void) mdb_snprintf(info.driver_name,
323*2973Sgovinda 				    sizeof (info.driver_name), "%s", name);
324*2973Sgovinda 
325*2973Sgovinda 				info.instance = dev.devi_instance;
326*2973Sgovinda 				info.inum = ih.ih_inum;
3271725Segillett 
328*2973Sgovinda 				/*
329*2973Sgovinda 				 * Read the type used, keep PCIe messages
330*2973Sgovinda 				 * separate.
331*2973Sgovinda 				 */
332*2973Sgovinda 				(void) mdb_vread(&intr_p,
333*2973Sgovinda 				    sizeof (devinfo_intr_t),
334*2973Sgovinda 				    (uintptr_t)dev.devi_intr_p);
335*2973Sgovinda 
336*2973Sgovinda 				if (ih.ih_rec_type != MSG_REC) {
337*2973Sgovinda 					info.intr_type =
338*2973Sgovinda 					    intr_p.devi_intr_curr_type;
339*2973Sgovinda 				}
340*2973Sgovinda 
341*2973Sgovinda 				if ((info.intr_type == DDI_INTR_TYPE_FIXED) &&
342*2973Sgovinda 				    ((ino.ino_ipil_size > 1) ||
343*2973Sgovinda 				    (ipil.ipil_ih_size > 1))) {
344*2973Sgovinda 					info.shared = 1;
345*2973Sgovinda 				}
346909Segillett 
347*2973Sgovinda 				info.num = ih.ih_msg_code;
348*2973Sgovinda 				info.intr_state = ih.ih_intr_state;
349*2973Sgovinda 				info.ino_ino = ino.ino_ino;
350*2973Sgovinda 				info.mondo = ino.ino_sysino;
351*2973Sgovinda 				info.pil = ipil.ipil_pil;
352*2973Sgovinda 				info.cpuid = ino.ino_cpuid;
353*2973Sgovinda 
354*2973Sgovinda 				intr_print_elements(info);
355*2973Sgovinda 				count++;
356909Segillett 
357*2973Sgovinda 				(void) mdb_vread(&ih, sizeof (px_ih_t),
358*2973Sgovinda 				    (uintptr_t)ih.ih_next);
359*2973Sgovinda 
360*2973Sgovinda 			} while (count < ipil.ipil_ih_size);
361909Segillett 
362*2973Sgovinda 		} while (mdb_vread(&ipil, sizeof (px_ino_pil_t),
363*2973Sgovinda 		    (uintptr_t)ipil.ipil_next_p) != -1);
364909Segillett 
365*2973Sgovinda 	} while (mdb_vread(&ino, sizeof (px_ino_t),
366*2973Sgovinda 	    (uintptr_t)ino.ino_next_p) != -1);
367909Segillett }
368909Segillett 
369909Segillett static char *
3701725Segillett intr_get_intr_type(uint16_t type)
371909Segillett {
3721725Segillett 	switch (type) {
3731725Segillett 		case	DDI_INTR_TYPE_FIXED:
3741725Segillett 			return ("Fixed");
3751725Segillett 		case	DDI_INTR_TYPE_MSI:
3761725Segillett 			return ("MSI");
3771725Segillett 		case	DDI_INTR_TYPE_MSIX:
3781725Segillett 			return ("MSI-X");
3791725Segillett 		default:
380909Segillett 			return ("PCIe");
381909Segillett 	}
382909Segillett }
383909Segillett 
384909Segillett static void
385909Segillett intr_print_banner(void)
386909Segillett {
387909Segillett 	if (!detailed) {
388965Sgovinda 		mdb_printf("\n%<u>\tDevice\t"
389965Sgovinda 		    " Shared\t"
390965Sgovinda 		    " Type\t"
391965Sgovinda 		    " MSG #\t"
392965Sgovinda 		    " State\t"
393965Sgovinda 		    " INO\t"
394965Sgovinda 		    " Mondo\t"
395965Sgovinda 		    "  Pil\t"
396965Sgovinda 		    " CPU   %</u>"
397965Sgovinda 		    "\n");
398909Segillett 	}
399909Segillett }
400909Segillett 
401909Segillett static void
402909Segillett intr_print_elements(intr_info_t info)
403909Segillett {
404909Segillett 	if (!detailed) {
405965Sgovinda 		mdb_printf(" %11s#%d\t", info.driver_name, info.instance);
406965Sgovinda 		mdb_printf(" %5s\t",
407909Segillett 		    info.shared ? "yes" : "no");
408965Sgovinda 		mdb_printf(" %s\t", intr_get_intr_type(info.intr_type));
4091725Segillett 		if (info.intr_type == DDI_INTR_TYPE_FIXED) {
410965Sgovinda 			mdb_printf("  --- \t");
411909Segillett 		} else {
412965Sgovinda 			mdb_printf(" %4d\t", info.num);
413909Segillett 		}
414909Segillett 
415965Sgovinda 		mdb_printf(" %2s\t",
416909Segillett 		    info.intr_state ? "enbl" : "disbl");
417965Sgovinda 		mdb_printf(" 0x%x\t", info.ino_ino);
418965Sgovinda 		mdb_printf(" 0x%x\t", info.mondo);
419965Sgovinda 		mdb_printf(" %4d\t", info.pil);
420965Sgovinda 		mdb_printf(" %3d \n", info.cpuid);
421909Segillett 	} else {
422909Segillett 		mdb_printf("\n-------------------------------------------\n");
423909Segillett 		mdb_printf("Device:\t\t%s\n", info.driver_name);
424909Segillett 		mdb_printf("Instance:\t%d\n", info.instance);
425909Segillett 		mdb_printf("Path:\t\t%s\n", info.pathname);
426909Segillett 		mdb_printf("Inum:\t\t%d\n", info.inum);
427909Segillett 		mdb_printf("Interrupt Type:\t%s\n",
428909Segillett 		    intr_get_intr_type(info.intr_type));
4291725Segillett 		if (info.intr_type == DDI_INTR_TYPE_MSI) {
4301725Segillett 			mdb_printf("MSI Number:\t%d\n", info.num);
4311725Segillett 		} else if (info.intr_type == DDI_INTR_TYPE_MSIX) {
4321725Segillett 			mdb_printf("MSI-X Number:\t%d\n", info.num);
4331725Segillett 		} else if (!info.intr_type) {
4341725Segillett 			mdb_printf("PCIe Message #:\t%d\n", info.num);
4351725Segillett 		}
436909Segillett 
437909Segillett 		mdb_printf("Shared Intr:\t%s\n",
438909Segillett 		    info.shared ? "yes" : "no");
439909Segillett 		mdb_printf("State:\t\t%d (%s)\n", info.intr_state,
440909Segillett 		    info.intr_state ? "Enabled" : "Disabled");
441909Segillett 		mdb_printf("INO:\t\t0x%x\n", info.ino_ino);
442909Segillett 		mdb_printf("Mondo:\t\t0x%x\n", info.mondo);
443909Segillett 		mdb_printf("Pil:\t\t%d\n", info.pil);
444909Segillett 		mdb_printf("CPU:\t\t%d\n", info.cpuid);
445909Segillett 	}
446909Segillett }
447909Segillett 
448909Segillett /*ARGSUSED*/
449909Segillett static void
450909Segillett intr_walk_fini(mdb_walk_state_t *wsp)
451909Segillett {
452909Segillett 	/* Nothing to do here */
453909Segillett }
454909Segillett 
455909Segillett /*ARGSUSED*/
456909Segillett static int
457909Segillett intr_intr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
458909Segillett {
459909Segillett 	detailed = 0;
460909Segillett 
461909Segillett 	if (mdb_getopts(argc, argv, 'd', MDB_OPT_SETBITS, TRUE, &detailed,
462909Segillett 	    NULL) != argc)
463909Segillett 		return (DCMD_USAGE);
464909Segillett 
465909Segillett 	if (!(flags & DCMD_ADDRSPEC)) {
466909Segillett 		if (mdb_walk_dcmd("interrupts", "interrupts", argc, argv)
467909Segillett 		    == -1) {
468909Segillett 			mdb_warn("can't walk pci/px buffer entries\n");
469909Segillett 			return (DCMD_ERR);
470909Segillett 		}
471909Segillett 		return (DCMD_OK);
472909Segillett 	}
473909Segillett 
474909Segillett 	return (DCMD_OK);
475909Segillett }
476909Segillett 
477909Segillett /*
478909Segillett  * MDB module linkage information:
479909Segillett  */
480909Segillett 
481909Segillett static const mdb_dcmd_t dcmds[] = {
482909Segillett 	{ "interrupts", "[-d]", "display the interrupt info registered with "
483909Segillett 	    "the PCI/PX nexus drivers", intr_intr },
484909Segillett 	{ NULL }
485909Segillett };
486909Segillett 
487909Segillett static const mdb_walker_t walkers[] = {
488909Segillett 	{ "interrupts", "walk PCI/PX interrupt structures",
489909Segillett 		intr_walk_init, intr_walk_step, intr_walk_fini },
490909Segillett 	{ NULL }
491909Segillett };
492909Segillett 
493909Segillett static const mdb_modinfo_t modinfo = {
494909Segillett 	MDB_API_VERSION, dcmds, walkers
495909Segillett };
496909Segillett 
497909Segillett const mdb_modinfo_t *
498909Segillett _mdb_init(void)
499909Segillett {
500909Segillett 	return (&modinfo);
501909Segillett }
502