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