xref: /titanic_53/usr/src/cmd/mdb/common/modules/genunix/ndievents.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #include "ndievents.h"
30*7c478bd9Sstevel@tonic-gate #include <sys/sunndi.h>
31*7c478bd9Sstevel@tonic-gate #include <sys/ndi_impldefs.h>
32*7c478bd9Sstevel@tonic-gate #include <sys/dditypes.h>
33*7c478bd9Sstevel@tonic-gate #include <sys/ddi_impldefs.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
35*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate int
dip_to_pathname(struct dev_info * device,char * path,int buflen)39*7c478bd9Sstevel@tonic-gate dip_to_pathname(struct dev_info *device, char *path, int buflen) {
40*7c478bd9Sstevel@tonic-gate 
41*7c478bd9Sstevel@tonic-gate 	char *bp;
42*7c478bd9Sstevel@tonic-gate 	char *addr;
43*7c478bd9Sstevel@tonic-gate 	char addr_str[32];
44*7c478bd9Sstevel@tonic-gate 	char nodename[MAXNAMELEN];
45*7c478bd9Sstevel@tonic-gate 	struct dev_info devi_parent;
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate 	if (!device) {
48*7c478bd9Sstevel@tonic-gate 		mdb_warn("Unable to access devinfo.");
49*7c478bd9Sstevel@tonic-gate 		return (-1);
50*7c478bd9Sstevel@tonic-gate 	}
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate 	if (device->devi_parent == NULL) {
53*7c478bd9Sstevel@tonic-gate 		if (mdb_readstr(nodename, sizeof (nodename),
54*7c478bd9Sstevel@tonic-gate 		    (uintptr_t)device->devi_node_name) == -1) {
55*7c478bd9Sstevel@tonic-gate 		    return (-1);
56*7c478bd9Sstevel@tonic-gate 		}
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate 		if (sizeof (nodename) > (buflen - strlen(path))) {
59*7c478bd9Sstevel@tonic-gate 			return (-1);
60*7c478bd9Sstevel@tonic-gate 		}
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate 		strncpy(path, nodename, sizeof (nodename));
63*7c478bd9Sstevel@tonic-gate 		return (0);
64*7c478bd9Sstevel@tonic-gate 	}
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate 	if (mdb_vread(&devi_parent, sizeof (struct dev_info),
67*7c478bd9Sstevel@tonic-gate 	    (uintptr_t)device->devi_parent) == -1) {
68*7c478bd9Sstevel@tonic-gate 		mdb_warn("Unable to access devi_parent at %p",
69*7c478bd9Sstevel@tonic-gate 		    (uintptr_t)device->devi_parent);
70*7c478bd9Sstevel@tonic-gate 		return (-1);
71*7c478bd9Sstevel@tonic-gate 	}
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate 	if (dip_to_pathname(&devi_parent, path, buflen) == -1) {
74*7c478bd9Sstevel@tonic-gate 		return (-1);
75*7c478bd9Sstevel@tonic-gate 	}
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate 	if (mdb_readstr(nodename, sizeof (nodename),
78*7c478bd9Sstevel@tonic-gate 	    (uintptr_t)device->devi_node_name) == -1) {
79*7c478bd9Sstevel@tonic-gate 		return (-1);
80*7c478bd9Sstevel@tonic-gate 	}
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate 	if (device->devi_node_state < DS_INITIALIZED) {
83*7c478bd9Sstevel@tonic-gate 		strncpy(addr_str, '\0', sizeof ('\0'));
84*7c478bd9Sstevel@tonic-gate 	} else {
85*7c478bd9Sstevel@tonic-gate 		addr = device->devi_addr;
86*7c478bd9Sstevel@tonic-gate 		if (mdb_readstr(addr_str, sizeof (addr_str),
87*7c478bd9Sstevel@tonic-gate 		    (uintptr_t)addr) == -1) {
88*7c478bd9Sstevel@tonic-gate 			return (-1);
89*7c478bd9Sstevel@tonic-gate 		}
90*7c478bd9Sstevel@tonic-gate 	}
91*7c478bd9Sstevel@tonic-gate 
92*7c478bd9Sstevel@tonic-gate 	bp = path + strlen(path);
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate 	if (addr_str[0] == '\0') {
95*7c478bd9Sstevel@tonic-gate 		(void) mdb_snprintf(bp, buflen - strlen(path), "/%s", nodename);
96*7c478bd9Sstevel@tonic-gate 	} else {
97*7c478bd9Sstevel@tonic-gate 		(void) mdb_snprintf(bp, buflen - strlen(path), "/%s@%s",
98*7c478bd9Sstevel@tonic-gate 		    nodename, addr_str);
99*7c478bd9Sstevel@tonic-gate 	}
100*7c478bd9Sstevel@tonic-gate 	return (0);
101*7c478bd9Sstevel@tonic-gate 
102*7c478bd9Sstevel@tonic-gate }
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
105*7c478bd9Sstevel@tonic-gate int
ndi_callback_print(struct ndi_event_cookie * cookie,uint_t flags)106*7c478bd9Sstevel@tonic-gate ndi_callback_print(struct ndi_event_cookie *cookie, uint_t flags)
107*7c478bd9Sstevel@tonic-gate {
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate 	struct ndi_event_callbacks *callback_list;
110*7c478bd9Sstevel@tonic-gate 	struct ndi_event_callbacks cb;
111*7c478bd9Sstevel@tonic-gate 	char device_path[MAXPATHLEN];
112*7c478bd9Sstevel@tonic-gate 	struct dev_info devi;
113*7c478bd9Sstevel@tonic-gate 
114*7c478bd9Sstevel@tonic-gate 	if (!cookie) {
115*7c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
116*7c478bd9Sstevel@tonic-gate 	}
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate 	callback_list = cookie->callback_list;
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate 	while (callback_list != NULL) {
121*7c478bd9Sstevel@tonic-gate 		if (mdb_vread(&cb, sizeof (struct ndi_event_callbacks),
122*7c478bd9Sstevel@tonic-gate 			    (uintptr_t)callback_list) == -1) {
123*7c478bd9Sstevel@tonic-gate 			mdb_warn("Could not read callback structure at"
124*7c478bd9Sstevel@tonic-gate 			    " %p", callback_list);
125*7c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
126*7c478bd9Sstevel@tonic-gate 		}
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate 		if (mdb_vread(&devi, sizeof (struct dev_info),
129*7c478bd9Sstevel@tonic-gate 		    (uintptr_t)cb.ndi_evtcb_dip) == -1) {
130*7c478bd9Sstevel@tonic-gate 			mdb_warn("Could not read devinfo structure at"
131*7c478bd9Sstevel@tonic-gate 			    " %p", cb.ndi_evtcb_dip);
132*7c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
133*7c478bd9Sstevel@tonic-gate 		}
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate 		if (dip_to_pathname(&devi, device_path, sizeof (device_path))
136*7c478bd9Sstevel@tonic-gate 		    == -1) {
137*7c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
138*7c478bd9Sstevel@tonic-gate 		}
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate 		mdb_printf("\t\tCallback Registered By: %s\n", device_path);
141*7c478bd9Sstevel@tonic-gate 		mdb_printf("\t\t  Callback Address:\t%-?p\n"
142*7c478bd9Sstevel@tonic-gate 		    "\t\t  Callback Function:\t%-p\n"
143*7c478bd9Sstevel@tonic-gate 		    "\t\t  Callback Args:\t%-?p\n"
144*7c478bd9Sstevel@tonic-gate 		    "\t\t  Callback Cookie:\t%-?p\n",
145*7c478bd9Sstevel@tonic-gate 		    callback_list, cb.ndi_evtcb_callback, cb.ndi_evtcb_arg,
146*7c478bd9Sstevel@tonic-gate 		    cb.ndi_evtcb_cookie);
147*7c478bd9Sstevel@tonic-gate 
148*7c478bd9Sstevel@tonic-gate 		callback_list = cb.ndi_evtcb_next;
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate 	}
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
153*7c478bd9Sstevel@tonic-gate }
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate int
ndi_event_print(struct ndi_event_hdl * hdl,uint_t flags)156*7c478bd9Sstevel@tonic-gate ndi_event_print(struct ndi_event_hdl *hdl, uint_t flags)
157*7c478bd9Sstevel@tonic-gate {
158*7c478bd9Sstevel@tonic-gate 
159*7c478bd9Sstevel@tonic-gate 	struct 	ndi_event_definition def;
160*7c478bd9Sstevel@tonic-gate 	struct 	ndi_event_cookie cookie;
161*7c478bd9Sstevel@tonic-gate 	struct 	ndi_event_cookie *cookie_list;
162*7c478bd9Sstevel@tonic-gate 	char 	ndi_event_name[256];
163*7c478bd9Sstevel@tonic-gate 
164*7c478bd9Sstevel@tonic-gate 	if (!hdl)
165*7c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
166*7c478bd9Sstevel@tonic-gate 
167*7c478bd9Sstevel@tonic-gate 	cookie_list = hdl->ndi_evthdl_cookie_list;
168*7c478bd9Sstevel@tonic-gate 	if (cookie_list == NULL) {
169*7c478bd9Sstevel@tonic-gate 		mdb_printf("\tNo cookies defined for this handle.\n");
170*7c478bd9Sstevel@tonic-gate 		return (DCMD_OK);
171*7c478bd9Sstevel@tonic-gate 	}
172*7c478bd9Sstevel@tonic-gate 
173*7c478bd9Sstevel@tonic-gate 	while (cookie_list != NULL) {
174*7c478bd9Sstevel@tonic-gate 		if (mdb_vread(&cookie, sizeof (struct ndi_event_cookie),
175*7c478bd9Sstevel@tonic-gate 		    (uintptr_t)cookie_list) == -1) {
176*7c478bd9Sstevel@tonic-gate 			mdb_warn("Unable to access cookie list");
177*7c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
178*7c478bd9Sstevel@tonic-gate 		}
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate 		if (mdb_vread(&def, sizeof (struct ndi_event_definition),
181*7c478bd9Sstevel@tonic-gate 		    (uintptr_t)cookie.definition) == -1) {
182*7c478bd9Sstevel@tonic-gate 			mdb_warn("Unable to access definition at %p",
183*7c478bd9Sstevel@tonic-gate 			    cookie.definition);
184*7c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
185*7c478bd9Sstevel@tonic-gate 		}
186*7c478bd9Sstevel@tonic-gate 
187*7c478bd9Sstevel@tonic-gate 		if (mdb_readstr(ndi_event_name, sizeof (ndi_event_name),
188*7c478bd9Sstevel@tonic-gate 		    (uintptr_t)def.ndi_event_name) == -1) {
189*7c478bd9Sstevel@tonic-gate 			mdb_warn("Unable to read cookie name.");
190*7c478bd9Sstevel@tonic-gate 			return (DCMD_ERR);
191*7c478bd9Sstevel@tonic-gate 		}
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate 		mdb_printf("\tCookie(%s %p) :Plevel(%d)\n\tddip(%p)"
194*7c478bd9Sstevel@tonic-gate 		    " : Attr(%d)\n",
195*7c478bd9Sstevel@tonic-gate 		    ndi_event_name, cookie_list, def.ndi_event_plevel,
196*7c478bd9Sstevel@tonic-gate 		    cookie.ddip, def.ndi_event_attributes);
197*7c478bd9Sstevel@tonic-gate 
198*7c478bd9Sstevel@tonic-gate 		ndi_callback_print(&cookie, flags);
199*7c478bd9Sstevel@tonic-gate 		cookie_list = cookie.next_cookie;
200*7c478bd9Sstevel@tonic-gate 
201*7c478bd9Sstevel@tonic-gate 	}
202*7c478bd9Sstevel@tonic-gate 	return (0);
203*7c478bd9Sstevel@tonic-gate }
204*7c478bd9Sstevel@tonic-gate 
205*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
206*7c478bd9Sstevel@tonic-gate int
ndi_event_hdl(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)207*7c478bd9Sstevel@tonic-gate ndi_event_hdl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
208*7c478bd9Sstevel@tonic-gate {
209*7c478bd9Sstevel@tonic-gate 
210*7c478bd9Sstevel@tonic-gate 	struct dev_info devi;
211*7c478bd9Sstevel@tonic-gate 	struct ndi_event_hdl handle;
212*7c478bd9Sstevel@tonic-gate 	char path[MAXPATHLEN];
213*7c478bd9Sstevel@tonic-gate 	int done;
214*7c478bd9Sstevel@tonic-gate 
215*7c478bd9Sstevel@tonic-gate 	if (!(flags & DCMD_ADDRSPEC)) {
216*7c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
217*7c478bd9Sstevel@tonic-gate 	}
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 	if (mdb_vread(&handle, sizeof (struct ndi_event_hdl), addr) == -1) {
220*7c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read ndi_event_hdl at %p", addr);
221*7c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
222*7c478bd9Sstevel@tonic-gate 	}
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate 	if (mdb_vread(&devi, sizeof (struct dev_info),
225*7c478bd9Sstevel@tonic-gate 		    (uintptr_t)handle.ndi_evthdl_dip)
226*7c478bd9Sstevel@tonic-gate 	    == -1) {
227*7c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read devinfo node at %p",
228*7c478bd9Sstevel@tonic-gate 		    handle.ndi_evthdl_dip);
229*7c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
230*7c478bd9Sstevel@tonic-gate 	}
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate 	if (dip_to_pathname(&devi, path, sizeof (path)) == -1) {
233*7c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
234*7c478bd9Sstevel@tonic-gate 	}
235*7c478bd9Sstevel@tonic-gate 
236*7c478bd9Sstevel@tonic-gate 	done = 0;
237*7c478bd9Sstevel@tonic-gate 	while (!done) {
238*7c478bd9Sstevel@tonic-gate 
239*7c478bd9Sstevel@tonic-gate 		mdb_printf("%<b>Handle%</b> (%p) :%<b> Path%</b> (%s) : %<b>"
240*7c478bd9Sstevel@tonic-gate 		    "dip %</b>(%p) \n", addr, path, handle.ndi_evthdl_dip);
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate 		mdb_printf("mutexes:	handle(%p)	callback(%p)\n",
243*7c478bd9Sstevel@tonic-gate 		    handle.ndi_evthdl_mutex, handle.ndi_evthdl_cb_mutex);
244*7c478bd9Sstevel@tonic-gate 
245*7c478bd9Sstevel@tonic-gate 		ndi_event_print(&handle, flags);
246*7c478bd9Sstevel@tonic-gate 
247*7c478bd9Sstevel@tonic-gate 		if (handle.ndi_next_hdl == NULL) {
248*7c478bd9Sstevel@tonic-gate 			done = 1;
249*7c478bd9Sstevel@tonic-gate 		} else {
250*7c478bd9Sstevel@tonic-gate 			addr = (uintptr_t)handle.ndi_next_hdl;
251*7c478bd9Sstevel@tonic-gate 			if (mdb_vread(&handle, sizeof (struct ndi_event_hdl),
252*7c478bd9Sstevel@tonic-gate 			    (uintptr_t)addr) == -1) {
253*7c478bd9Sstevel@tonic-gate 			    mdb_warn("failed to read ndi_event_hdl at %p",
254*7c478bd9Sstevel@tonic-gate 			    addr);
255*7c478bd9Sstevel@tonic-gate 			    break;
256*7c478bd9Sstevel@tonic-gate 			}
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate 		}
259*7c478bd9Sstevel@tonic-gate 	}
260*7c478bd9Sstevel@tonic-gate 
261*7c478bd9Sstevel@tonic-gate 	return (0);
262*7c478bd9Sstevel@tonic-gate }
263