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