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 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 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 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 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