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