1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte /* 22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*fcf3ce44SJohn Forte * Use is subject to license terms. 24*fcf3ce44SJohn Forte */ 25*fcf3ce44SJohn Forte 26*fcf3ce44SJohn Forte #include <sys/types.h> 27*fcf3ce44SJohn Forte #include <sys/mdb_modapi.h> 28*fcf3ce44SJohn Forte #include <sys/ddi.h> 29*fcf3ce44SJohn Forte #include <sys/sunddi.h> 30*fcf3ce44SJohn Forte #include <sys/sunldi.h> 31*fcf3ce44SJohn Forte 32*fcf3ce44SJohn Forte #include <sys/nsctl/nsctl.h> 33*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s.h> 34*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_k.h> 35*fcf3ce44SJohn Forte 36*fcf3ce44SJohn Forte #include <sys/nsctl/sv.h> 37*fcf3ce44SJohn Forte #include <sys/nsctl/sv_impl.h> 38*fcf3ce44SJohn Forte 39*fcf3ce44SJohn Forte #include <sys/nsctl/nsvers.h> 40*fcf3ce44SJohn Forte 41*fcf3ce44SJohn Forte /* 42*fcf3ce44SJohn Forte * Walker for an array of sv_dev_t structures. 43*fcf3ce44SJohn Forte * A global walk is assumed to start at sv_devs. 44*fcf3ce44SJohn Forte */ 45*fcf3ce44SJohn Forte 46*fcf3ce44SJohn Forte struct sv_dev_winfo { 47*fcf3ce44SJohn Forte uintptr_t start; 48*fcf3ce44SJohn Forte uintptr_t end; 49*fcf3ce44SJohn Forte }; 50*fcf3ce44SJohn Forte 51*fcf3ce44SJohn Forte 52*fcf3ce44SJohn Forte static int 53*fcf3ce44SJohn Forte sv_dev_winit(mdb_walk_state_t *wsp) 54*fcf3ce44SJohn Forte { 55*fcf3ce44SJohn Forte struct sv_dev_winfo *winfo; 56*fcf3ce44SJohn Forte sv_dev_t *sv_devs; 57*fcf3ce44SJohn Forte int sv_max_devices; 58*fcf3ce44SJohn Forte 59*fcf3ce44SJohn Forte winfo = mdb_zalloc(sizeof (struct sv_dev_winfo), UM_SLEEP); 60*fcf3ce44SJohn Forte 61*fcf3ce44SJohn Forte if (mdb_readvar(&sv_devs, "sv_devs") == -1) { 62*fcf3ce44SJohn Forte mdb_warn("failed to read 'sv_devs'"); 63*fcf3ce44SJohn Forte mdb_free(winfo, sizeof (struct sv_dev_winfo)); 64*fcf3ce44SJohn Forte return (WALK_ERR); 65*fcf3ce44SJohn Forte } 66*fcf3ce44SJohn Forte 67*fcf3ce44SJohn Forte if (mdb_readvar(&sv_max_devices, "sv_max_devices") == -1) { 68*fcf3ce44SJohn Forte mdb_warn("failed to read 'sv_max_devices'"); 69*fcf3ce44SJohn Forte mdb_free(winfo, sizeof (struct sv_dev_winfo)); 70*fcf3ce44SJohn Forte return (WALK_ERR); 71*fcf3ce44SJohn Forte } 72*fcf3ce44SJohn Forte 73*fcf3ce44SJohn Forte winfo->start = (uintptr_t)sv_devs; 74*fcf3ce44SJohn Forte winfo->end = (uintptr_t)(sv_devs + sv_max_devices); 75*fcf3ce44SJohn Forte 76*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) 77*fcf3ce44SJohn Forte wsp->walk_addr = winfo->start; 78*fcf3ce44SJohn Forte 79*fcf3ce44SJohn Forte wsp->walk_data = winfo; 80*fcf3ce44SJohn Forte return (WALK_NEXT); 81*fcf3ce44SJohn Forte } 82*fcf3ce44SJohn Forte 83*fcf3ce44SJohn Forte 84*fcf3ce44SJohn Forte static int 85*fcf3ce44SJohn Forte sv_dev_wstep(mdb_walk_state_t *wsp) 86*fcf3ce44SJohn Forte { 87*fcf3ce44SJohn Forte struct sv_dev_winfo *winfo = wsp->walk_data; 88*fcf3ce44SJohn Forte int status; 89*fcf3ce44SJohn Forte 90*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) 91*fcf3ce44SJohn Forte return (WALK_DONE); 92*fcf3ce44SJohn Forte 93*fcf3ce44SJohn Forte if (wsp->walk_addr >= winfo->end) 94*fcf3ce44SJohn Forte return (WALK_DONE); 95*fcf3ce44SJohn Forte 96*fcf3ce44SJohn Forte status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 97*fcf3ce44SJohn Forte wsp->walk_cbdata); 98*fcf3ce44SJohn Forte 99*fcf3ce44SJohn Forte wsp->walk_addr += sizeof (sv_dev_t); 100*fcf3ce44SJohn Forte return (status); 101*fcf3ce44SJohn Forte } 102*fcf3ce44SJohn Forte 103*fcf3ce44SJohn Forte 104*fcf3ce44SJohn Forte static void 105*fcf3ce44SJohn Forte sv_dev_wfini(mdb_walk_state_t *wsp) 106*fcf3ce44SJohn Forte { 107*fcf3ce44SJohn Forte mdb_free(wsp->walk_data, sizeof (struct sv_dev_winfo)); 108*fcf3ce44SJohn Forte } 109*fcf3ce44SJohn Forte 110*fcf3ce44SJohn Forte 111*fcf3ce44SJohn Forte /* 112*fcf3ce44SJohn Forte * Walker for an sv hash chain. 113*fcf3ce44SJohn Forte * Global walks are disallowed. 114*fcf3ce44SJohn Forte */ 115*fcf3ce44SJohn Forte 116*fcf3ce44SJohn Forte static int 117*fcf3ce44SJohn Forte sv_hash_winit(mdb_walk_state_t *wsp) 118*fcf3ce44SJohn Forte { 119*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) 120*fcf3ce44SJohn Forte return (WALK_ERR); 121*fcf3ce44SJohn Forte 122*fcf3ce44SJohn Forte wsp->walk_data = mdb_zalloc(sizeof (sv_dev_t), UM_SLEEP); 123*fcf3ce44SJohn Forte 124*fcf3ce44SJohn Forte return (WALK_NEXT); 125*fcf3ce44SJohn Forte } 126*fcf3ce44SJohn Forte 127*fcf3ce44SJohn Forte 128*fcf3ce44SJohn Forte static int 129*fcf3ce44SJohn Forte sv_hash_wstep(mdb_walk_state_t *wsp) 130*fcf3ce44SJohn Forte { 131*fcf3ce44SJohn Forte int status; 132*fcf3ce44SJohn Forte 133*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) 134*fcf3ce44SJohn Forte return (WALK_DONE); 135*fcf3ce44SJohn Forte 136*fcf3ce44SJohn Forte if (mdb_vread(wsp->walk_data, 137*fcf3ce44SJohn Forte sizeof (sv_dev_t), wsp->walk_addr) == -1) { 138*fcf3ce44SJohn Forte mdb_warn("failed to read sv_dev at %p", wsp->walk_addr); 139*fcf3ce44SJohn Forte return (WALK_DONE); 140*fcf3ce44SJohn Forte } 141*fcf3ce44SJohn Forte 142*fcf3ce44SJohn Forte status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 143*fcf3ce44SJohn Forte wsp->walk_cbdata); 144*fcf3ce44SJohn Forte 145*fcf3ce44SJohn Forte wsp->walk_addr = (uintptr_t)(((sv_dev_t *)wsp->walk_data)->sv_hash); 146*fcf3ce44SJohn Forte return (status); 147*fcf3ce44SJohn Forte } 148*fcf3ce44SJohn Forte 149*fcf3ce44SJohn Forte 150*fcf3ce44SJohn Forte static void 151*fcf3ce44SJohn Forte sv_hash_wfini(mdb_walk_state_t *wsp) 152*fcf3ce44SJohn Forte { 153*fcf3ce44SJohn Forte mdb_free(wsp->walk_data, sizeof (sv_dev_t)); 154*fcf3ce44SJohn Forte } 155*fcf3ce44SJohn Forte 156*fcf3ce44SJohn Forte 157*fcf3ce44SJohn Forte /* 158*fcf3ce44SJohn Forte * Walker for an array of sv_maj_t structures. 159*fcf3ce44SJohn Forte * A global walk is assumed to start at sv_majors. 160*fcf3ce44SJohn Forte */ 161*fcf3ce44SJohn Forte 162*fcf3ce44SJohn Forte sv_maj_t *sv_majors[SV_MAJOR_HASH_CNT + 1] = {0}; 163*fcf3ce44SJohn Forte 164*fcf3ce44SJohn Forte static int 165*fcf3ce44SJohn Forte sv_maj_winit(mdb_walk_state_t *wsp) 166*fcf3ce44SJohn Forte { 167*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) { 168*fcf3ce44SJohn Forte if (mdb_readvar(&sv_majors, "sv_majors") == -1) { 169*fcf3ce44SJohn Forte mdb_warn("failed to read 'sv_majors'"); 170*fcf3ce44SJohn Forte return (WALK_ERR); 171*fcf3ce44SJohn Forte } 172*fcf3ce44SJohn Forte } else { 173*fcf3ce44SJohn Forte sv_majors[0] = (sv_maj_t *)wsp->walk_addr; 174*fcf3ce44SJohn Forte } 175*fcf3ce44SJohn Forte 176*fcf3ce44SJohn Forte wsp->walk_addr = (uintptr_t)&sv_majors[0]; 177*fcf3ce44SJohn Forte wsp->walk_data = mdb_zalloc(sizeof (sv_maj_t), UM_SLEEP); 178*fcf3ce44SJohn Forte 179*fcf3ce44SJohn Forte return (WALK_NEXT); 180*fcf3ce44SJohn Forte } 181*fcf3ce44SJohn Forte 182*fcf3ce44SJohn Forte 183*fcf3ce44SJohn Forte static int 184*fcf3ce44SJohn Forte sv_maj_wstep(mdb_walk_state_t *wsp) 185*fcf3ce44SJohn Forte { 186*fcf3ce44SJohn Forte uintptr_t addr; 187*fcf3ce44SJohn Forte int status = DCMD_OK; 188*fcf3ce44SJohn Forte 189*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) 190*fcf3ce44SJohn Forte return (WALK_DONE); 191*fcf3ce44SJohn Forte 192*fcf3ce44SJohn Forte if (wsp->walk_addr >= (uintptr_t)&sv_majors[SV_MAJOR_HASH_CNT]) 193*fcf3ce44SJohn Forte return (WALK_DONE); 194*fcf3ce44SJohn Forte 195*fcf3ce44SJohn Forte for (addr = *(uintptr_t *)wsp->walk_addr; addr; 196*fcf3ce44SJohn Forte addr = (uintptr_t)(((sv_maj_t *)wsp->walk_data)->sm_next)) { 197*fcf3ce44SJohn Forte 198*fcf3ce44SJohn Forte if (mdb_vread(wsp->walk_data, sizeof (sv_maj_t), addr) 199*fcf3ce44SJohn Forte != sizeof (sv_maj_t)) { 200*fcf3ce44SJohn Forte mdb_warn("failed to read sv_maj at %p", addr); 201*fcf3ce44SJohn Forte status = DCMD_ERR; 202*fcf3ce44SJohn Forte break; 203*fcf3ce44SJohn Forte } 204*fcf3ce44SJohn Forte 205*fcf3ce44SJohn Forte status = wsp->walk_callback(addr, wsp->walk_data, 206*fcf3ce44SJohn Forte wsp->walk_cbdata); 207*fcf3ce44SJohn Forte if (status != DCMD_OK) 208*fcf3ce44SJohn Forte break; 209*fcf3ce44SJohn Forte } 210*fcf3ce44SJohn Forte 211*fcf3ce44SJohn Forte wsp->walk_addr += sizeof (sv_maj_t *); 212*fcf3ce44SJohn Forte return (status); 213*fcf3ce44SJohn Forte } 214*fcf3ce44SJohn Forte 215*fcf3ce44SJohn Forte 216*fcf3ce44SJohn Forte static void 217*fcf3ce44SJohn Forte sv_maj_wfini(mdb_walk_state_t *wsp) 218*fcf3ce44SJohn Forte { 219*fcf3ce44SJohn Forte mdb_free(wsp->walk_data, sizeof (sv_maj_t)); 220*fcf3ce44SJohn Forte } 221*fcf3ce44SJohn Forte 222*fcf3ce44SJohn Forte 223*fcf3ce44SJohn Forte /* 224*fcf3ce44SJohn Forte * Walker for an sv gclient chain. 225*fcf3ce44SJohn Forte * A global walk is assumed to start at sv_gclients. 226*fcf3ce44SJohn Forte */ 227*fcf3ce44SJohn Forte 228*fcf3ce44SJohn Forte static int 229*fcf3ce44SJohn Forte sv_gclient_winit(mdb_walk_state_t *wsp) 230*fcf3ce44SJohn Forte { 231*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL && 232*fcf3ce44SJohn Forte mdb_readvar(&wsp->walk_addr, "sv_gclients") == -1) { 233*fcf3ce44SJohn Forte mdb_warn("unable to read 'sv_gclients'"); 234*fcf3ce44SJohn Forte return (WALK_ERR); 235*fcf3ce44SJohn Forte } 236*fcf3ce44SJohn Forte 237*fcf3ce44SJohn Forte wsp->walk_data = mdb_zalloc(sizeof (sv_gclient_t), UM_SLEEP); 238*fcf3ce44SJohn Forte 239*fcf3ce44SJohn Forte return (WALK_NEXT); 240*fcf3ce44SJohn Forte } 241*fcf3ce44SJohn Forte 242*fcf3ce44SJohn Forte 243*fcf3ce44SJohn Forte static int 244*fcf3ce44SJohn Forte sv_gclient_wstep(mdb_walk_state_t *wsp) 245*fcf3ce44SJohn Forte { 246*fcf3ce44SJohn Forte int status; 247*fcf3ce44SJohn Forte 248*fcf3ce44SJohn Forte if (wsp->walk_addr == NULL) 249*fcf3ce44SJohn Forte return (WALK_DONE); 250*fcf3ce44SJohn Forte 251*fcf3ce44SJohn Forte if (mdb_vread(wsp->walk_data, 252*fcf3ce44SJohn Forte sizeof (sv_gclient_t), wsp->walk_addr) == -1) { 253*fcf3ce44SJohn Forte mdb_warn("failed to read sv_gclient at %p", wsp->walk_addr); 254*fcf3ce44SJohn Forte return (WALK_DONE); 255*fcf3ce44SJohn Forte } 256*fcf3ce44SJohn Forte 257*fcf3ce44SJohn Forte status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, 258*fcf3ce44SJohn Forte wsp->walk_cbdata); 259*fcf3ce44SJohn Forte 260*fcf3ce44SJohn Forte wsp->walk_addr = (uintptr_t)(((sv_gclient_t *)wsp->walk_data)->sg_next); 261*fcf3ce44SJohn Forte return (status); 262*fcf3ce44SJohn Forte } 263*fcf3ce44SJohn Forte 264*fcf3ce44SJohn Forte 265*fcf3ce44SJohn Forte static void 266*fcf3ce44SJohn Forte sv_gclient_wfini(mdb_walk_state_t *wsp) 267*fcf3ce44SJohn Forte { 268*fcf3ce44SJohn Forte mdb_free(wsp->walk_data, sizeof (sv_gclient_t)); 269*fcf3ce44SJohn Forte } 270*fcf3ce44SJohn Forte 271*fcf3ce44SJohn Forte 272*fcf3ce44SJohn Forte /* 273*fcf3ce44SJohn Forte * Display a single sv_glcient_t structure. 274*fcf3ce44SJohn Forte * If called with no address, performs a global walk of all sv_gclients. 275*fcf3ce44SJohn Forte */ 276*fcf3ce44SJohn Forte static int 277*fcf3ce44SJohn Forte sv_gclient(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 278*fcf3ce44SJohn Forte { 279*fcf3ce44SJohn Forte sv_gclient_t sg; 280*fcf3ce44SJohn Forte char name[64]; 281*fcf3ce44SJohn Forte 282*fcf3ce44SJohn Forte if (argc != 0) 283*fcf3ce44SJohn Forte return (DCMD_USAGE); 284*fcf3ce44SJohn Forte 285*fcf3ce44SJohn Forte if (!(flags & DCMD_ADDRSPEC)) { 286*fcf3ce44SJohn Forte /* 287*fcf3ce44SJohn Forte * paranoid mode on: qualify walker name with module name 288*fcf3ce44SJohn Forte * using '`' syntax. 289*fcf3ce44SJohn Forte */ 290*fcf3ce44SJohn Forte if (mdb_walk_dcmd("sv`sv_gclient", 291*fcf3ce44SJohn Forte "sv`sv_gclient", argc, argv) == -1) { 292*fcf3ce44SJohn Forte mdb_warn("failed to walk 'sv_gclient'"); 293*fcf3ce44SJohn Forte return (DCMD_ERR); 294*fcf3ce44SJohn Forte } 295*fcf3ce44SJohn Forte return (DCMD_OK); 296*fcf3ce44SJohn Forte } 297*fcf3ce44SJohn Forte 298*fcf3ce44SJohn Forte if (mdb_vread(&sg, sizeof (sg), addr) != sizeof (sg)) { 299*fcf3ce44SJohn Forte mdb_warn("failed to read sv_gclient at %p", addr); 300*fcf3ce44SJohn Forte return (DCMD_ERR); 301*fcf3ce44SJohn Forte } 302*fcf3ce44SJohn Forte 303*fcf3ce44SJohn Forte if (DCMD_HDRSPEC(flags)) { 304*fcf3ce44SJohn Forte mdb_printf("%-?s %8T%-?s %8T%-16s %8T%s\n", 305*fcf3ce44SJohn Forte "ADDR", "NEXT", "ID", "NAME"); 306*fcf3ce44SJohn Forte } 307*fcf3ce44SJohn Forte 308*fcf3ce44SJohn Forte if (mdb_readstr(name, sizeof (name), (uintptr_t)sg.sg_name) == -1) { 309*fcf3ce44SJohn Forte mdb_warn("failed to read sv_gclient name at %p", addr); 310*fcf3ce44SJohn Forte return (DCMD_ERR); 311*fcf3ce44SJohn Forte } 312*fcf3ce44SJohn Forte 313*fcf3ce44SJohn Forte mdb_printf("%p %8T%p %8T%llx %8T%s", 314*fcf3ce44SJohn Forte addr, sg.sg_next, sg.sg_id, name); 315*fcf3ce44SJohn Forte 316*fcf3ce44SJohn Forte return (DCMD_OK); 317*fcf3ce44SJohn Forte } 318*fcf3ce44SJohn Forte 319*fcf3ce44SJohn Forte 320*fcf3ce44SJohn Forte /* 321*fcf3ce44SJohn Forte * Display a single sv_maj_t structure. 322*fcf3ce44SJohn Forte * If called with no address, performs a global walk of all sv_majs. 323*fcf3ce44SJohn Forte * -a : all (i.e. display all devices, even if disabled 324*fcf3ce44SJohn Forte * -v : verbose 325*fcf3ce44SJohn Forte */ 326*fcf3ce44SJohn Forte static int 327*fcf3ce44SJohn Forte sv_maj(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 328*fcf3ce44SJohn Forte { 329*fcf3ce44SJohn Forte sv_maj_t *maj; 330*fcf3ce44SJohn Forte int a_opt, v_opt; 331*fcf3ce44SJohn Forte int i; 332*fcf3ce44SJohn Forte 333*fcf3ce44SJohn Forte a_opt = v_opt = FALSE; 334*fcf3ce44SJohn Forte 335*fcf3ce44SJohn Forte if (mdb_getopts(argc, argv, 336*fcf3ce44SJohn Forte 'a', MDB_OPT_SETBITS, TRUE, &a_opt, 337*fcf3ce44SJohn Forte 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) 338*fcf3ce44SJohn Forte return (DCMD_USAGE); 339*fcf3ce44SJohn Forte 340*fcf3ce44SJohn Forte if (!(flags & DCMD_ADDRSPEC)) { 341*fcf3ce44SJohn Forte /* 342*fcf3ce44SJohn Forte * paranoid mode on: qualify walker name with module name 343*fcf3ce44SJohn Forte * using '`' syntax. 344*fcf3ce44SJohn Forte */ 345*fcf3ce44SJohn Forte if (mdb_walk_dcmd("sv`sv_maj", "sv`sv_maj", argc, argv) == -1) { 346*fcf3ce44SJohn Forte mdb_warn("failed to walk 'sv_maj'"); 347*fcf3ce44SJohn Forte return (DCMD_ERR); 348*fcf3ce44SJohn Forte } 349*fcf3ce44SJohn Forte return (DCMD_OK); 350*fcf3ce44SJohn Forte } 351*fcf3ce44SJohn Forte 352*fcf3ce44SJohn Forte if (DCMD_HDRSPEC(flags)) { 353*fcf3ce44SJohn Forte mdb_printf("%-?s %8T%s\n", "ADDR", "INUSE"); 354*fcf3ce44SJohn Forte } 355*fcf3ce44SJohn Forte 356*fcf3ce44SJohn Forte maj = mdb_zalloc(sizeof (*maj), UM_GC); 357*fcf3ce44SJohn Forte if (mdb_vread(maj, sizeof (*maj), addr) != sizeof (*maj)) { 358*fcf3ce44SJohn Forte mdb_warn("failed to read sv_maj at %p", addr); 359*fcf3ce44SJohn Forte return (DCMD_ERR); 360*fcf3ce44SJohn Forte } 361*fcf3ce44SJohn Forte 362*fcf3ce44SJohn Forte if (!a_opt && maj->sm_inuse == 0) 363*fcf3ce44SJohn Forte return (DCMD_OK); 364*fcf3ce44SJohn Forte 365*fcf3ce44SJohn Forte mdb_printf("%?p %8T%d\n", addr, maj->sm_inuse); 366*fcf3ce44SJohn Forte 367*fcf3ce44SJohn Forte if (!v_opt) 368*fcf3ce44SJohn Forte return (DCMD_OK); 369*fcf3ce44SJohn Forte 370*fcf3ce44SJohn Forte /* 371*fcf3ce44SJohn Forte * verbose - print the rest of the structure as well. 372*fcf3ce44SJohn Forte */ 373*fcf3ce44SJohn Forte 374*fcf3ce44SJohn Forte mdb_inc_indent(4); 375*fcf3ce44SJohn Forte mdb_printf("\n"); 376*fcf3ce44SJohn Forte 377*fcf3ce44SJohn Forte mdb_printf("dev_ops: %a (%p)\n", maj->sm_dev_ops, maj->sm_dev_ops); 378*fcf3ce44SJohn Forte mdb_printf("flag: %08x %8Tsequence: %d %8Tmajor: %d\n", 379*fcf3ce44SJohn Forte maj->sm_flag, maj->sm_seq, maj->sm_major); 380*fcf3ce44SJohn Forte 381*fcf3ce44SJohn Forte mdb_printf("function pointers:\n"); 382*fcf3ce44SJohn Forte mdb_inc_indent(4); 383*fcf3ce44SJohn Forte mdb_printf("%-20a%-20a%\n%-20a%-20a%\n%-20a%-20a%\n%-20a%-20a%\n", 384*fcf3ce44SJohn Forte maj->sm_open, maj->sm_close, 385*fcf3ce44SJohn Forte maj->sm_read, maj->sm_write, 386*fcf3ce44SJohn Forte maj->sm_aread, maj->sm_awrite, 387*fcf3ce44SJohn Forte maj->sm_strategy, maj->sm_ioctl); 388*fcf3ce44SJohn Forte mdb_dec_indent(4); 389*fcf3ce44SJohn Forte 390*fcf3ce44SJohn Forte 391*fcf3ce44SJohn Forte mdb_printf("hash chain:\n"); 392*fcf3ce44SJohn Forte mdb_inc_indent(4); 393*fcf3ce44SJohn Forte for (i = 0; i < SV_MINOR_HASH_CNT; i++) { 394*fcf3ce44SJohn Forte mdb_printf("%?p", maj->sm_hash[i]); 395*fcf3ce44SJohn Forte mdb_printf(((i % 4) == 3) ? "\n" : " %8T"); 396*fcf3ce44SJohn Forte } 397*fcf3ce44SJohn Forte mdb_printf("\n\n"); 398*fcf3ce44SJohn Forte mdb_dec_indent(4); 399*fcf3ce44SJohn Forte mdb_dec_indent(4); 400*fcf3ce44SJohn Forte return (DCMD_OK); 401*fcf3ce44SJohn Forte } 402*fcf3ce44SJohn Forte 403*fcf3ce44SJohn Forte 404*fcf3ce44SJohn Forte /* 405*fcf3ce44SJohn Forte * Display a sv_dev_t hash chain. 406*fcf3ce44SJohn Forte * Requires an address. 407*fcf3ce44SJohn Forte * Same options as sv_dev(). 408*fcf3ce44SJohn Forte */ 409*fcf3ce44SJohn Forte static int 410*fcf3ce44SJohn Forte sv_hash(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 411*fcf3ce44SJohn Forte { 412*fcf3ce44SJohn Forte if (!(flags & DCMD_ADDRSPEC)) 413*fcf3ce44SJohn Forte return (DCMD_USAGE); 414*fcf3ce44SJohn Forte 415*fcf3ce44SJohn Forte /* 416*fcf3ce44SJohn Forte * paranoid mode on: qualify walker name with module name 417*fcf3ce44SJohn Forte * using '`' syntax. 418*fcf3ce44SJohn Forte */ 419*fcf3ce44SJohn Forte if (mdb_pwalk_dcmd("sv`sv_hash", "sv`sv_dev", argc, argv, addr) == -1) { 420*fcf3ce44SJohn Forte mdb_warn("failed to walk sv_dev hash chain"); 421*fcf3ce44SJohn Forte return (DCMD_ERR); 422*fcf3ce44SJohn Forte } 423*fcf3ce44SJohn Forte 424*fcf3ce44SJohn Forte return (DCMD_OK); 425*fcf3ce44SJohn Forte } 426*fcf3ce44SJohn Forte 427*fcf3ce44SJohn Forte 428*fcf3ce44SJohn Forte /* 429*fcf3ce44SJohn Forte * Display a single sv_dev_t structure. 430*fcf3ce44SJohn Forte * If called with no address, performs a global walk of all sv_devs. 431*fcf3ce44SJohn Forte * -a : all (i.e. display all devices, even if disabled 432*fcf3ce44SJohn Forte * -v : verbose 433*fcf3ce44SJohn Forte */ 434*fcf3ce44SJohn Forte 435*fcf3ce44SJohn Forte const mdb_bitmask_t sv_flag_bits[] = { 436*fcf3ce44SJohn Forte { "NSC_DEVICE", NSC_DEVICE, NSC_DEVICE }, 437*fcf3ce44SJohn Forte { "NSC_CACHE", NSC_CACHE, NSC_CACHE }, 438*fcf3ce44SJohn Forte { NULL, 0, 0 } 439*fcf3ce44SJohn Forte }; 440*fcf3ce44SJohn Forte 441*fcf3ce44SJohn Forte static int 442*fcf3ce44SJohn Forte sv_dev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 443*fcf3ce44SJohn Forte { 444*fcf3ce44SJohn Forte sv_dev_t *svp; 445*fcf3ce44SJohn Forte int a_opt, v_opt; 446*fcf3ce44SJohn Forte int dev_t_chars; 447*fcf3ce44SJohn Forte 448*fcf3ce44SJohn Forte a_opt = v_opt = FALSE; 449*fcf3ce44SJohn Forte dev_t_chars = sizeof (dev_t) * 2; /* # chars to display dev_t */ 450*fcf3ce44SJohn Forte 451*fcf3ce44SJohn Forte if (mdb_getopts(argc, argv, 452*fcf3ce44SJohn Forte 'a', MDB_OPT_SETBITS, TRUE, &a_opt, 453*fcf3ce44SJohn Forte 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc) 454*fcf3ce44SJohn Forte return (DCMD_USAGE); 455*fcf3ce44SJohn Forte 456*fcf3ce44SJohn Forte svp = mdb_zalloc(sizeof (*svp), UM_GC); 457*fcf3ce44SJohn Forte 458*fcf3ce44SJohn Forte if (!(flags & DCMD_ADDRSPEC)) { 459*fcf3ce44SJohn Forte /* 460*fcf3ce44SJohn Forte * paranoid mode on: qualify walker name with module name 461*fcf3ce44SJohn Forte * using '`' syntax. 462*fcf3ce44SJohn Forte */ 463*fcf3ce44SJohn Forte if (mdb_walk_dcmd("sv`sv_dev", "sv`sv_dev", argc, argv) == -1) { 464*fcf3ce44SJohn Forte mdb_warn("failed to walk 'sv_dev'"); 465*fcf3ce44SJohn Forte return (DCMD_ERR); 466*fcf3ce44SJohn Forte } 467*fcf3ce44SJohn Forte return (DCMD_OK); 468*fcf3ce44SJohn Forte } 469*fcf3ce44SJohn Forte 470*fcf3ce44SJohn Forte if (DCMD_HDRSPEC(flags)) { 471*fcf3ce44SJohn Forte mdb_printf("%-?s %8T%-*s %8T%s\n", "ADDR", 472*fcf3ce44SJohn Forte dev_t_chars, "DEV", "STATE"); 473*fcf3ce44SJohn Forte } 474*fcf3ce44SJohn Forte 475*fcf3ce44SJohn Forte if (mdb_vread(svp, sizeof (*svp), addr) != sizeof (*svp)) { 476*fcf3ce44SJohn Forte mdb_warn("failed to read sv_dev at %p", addr); 477*fcf3ce44SJohn Forte return (DCMD_ERR); 478*fcf3ce44SJohn Forte } 479*fcf3ce44SJohn Forte 480*fcf3ce44SJohn Forte if (!a_opt && svp->sv_state == SV_DISABLE) 481*fcf3ce44SJohn Forte return (DCMD_OK); 482*fcf3ce44SJohn Forte 483*fcf3ce44SJohn Forte mdb_printf("%?p %8T%0*lx %8T", addr, dev_t_chars, svp->sv_dev); 484*fcf3ce44SJohn Forte 485*fcf3ce44SJohn Forte if (svp->sv_state == SV_DISABLE) 486*fcf3ce44SJohn Forte mdb_printf("disabled"); 487*fcf3ce44SJohn Forte else if (svp->sv_state == SV_PENDING) 488*fcf3ce44SJohn Forte mdb_printf("pending"); 489*fcf3ce44SJohn Forte else if (svp->sv_state == SV_ENABLE) 490*fcf3ce44SJohn Forte mdb_printf("enabled"); 491*fcf3ce44SJohn Forte 492*fcf3ce44SJohn Forte mdb_printf("\n"); 493*fcf3ce44SJohn Forte 494*fcf3ce44SJohn Forte if (!v_opt) 495*fcf3ce44SJohn Forte return (DCMD_OK); 496*fcf3ce44SJohn Forte 497*fcf3ce44SJohn Forte /* 498*fcf3ce44SJohn Forte * verbose - print the rest of the structure as well. 499*fcf3ce44SJohn Forte */ 500*fcf3ce44SJohn Forte 501*fcf3ce44SJohn Forte mdb_inc_indent(4); 502*fcf3ce44SJohn Forte mdb_printf("\n"); 503*fcf3ce44SJohn Forte 504*fcf3ce44SJohn Forte mdb_printf("hash chain: 0x%p %8Tlock: 0x%p %8Tolock: 0x%p\n", 505*fcf3ce44SJohn Forte svp->sv_hash, 506*fcf3ce44SJohn Forte addr + OFFSETOF(sv_dev_t, sv_lock), 507*fcf3ce44SJohn Forte addr + OFFSETOF(sv_dev_t, sv_olock)); 508*fcf3ce44SJohn Forte 509*fcf3ce44SJohn Forte mdb_printf("fd: 0x%p %8T\n", svp->sv_fd); 510*fcf3ce44SJohn Forte 511*fcf3ce44SJohn Forte mdb_printf("maxfbas: %d %8Tnblocks: %d %8Tstate: %d\n", 512*fcf3ce44SJohn Forte svp->sv_maxfbas, svp->sv_nblocks, svp->sv_state); 513*fcf3ce44SJohn Forte 514*fcf3ce44SJohn Forte mdb_printf("gclients: 0x%llx %8Tgkernel: 0x%llx\n", 515*fcf3ce44SJohn Forte svp->sv_gclients, svp->sv_gkernel); 516*fcf3ce44SJohn Forte 517*fcf3ce44SJohn Forte mdb_printf("openlcnt: %d %8Ttimestamp: 0x%lx\n", 518*fcf3ce44SJohn Forte svp->sv_openlcnt, svp->sv_timestamp); 519*fcf3ce44SJohn Forte 520*fcf3ce44SJohn Forte mdb_printf("flags: 0x%08x <%b>\n", 521*fcf3ce44SJohn Forte svp->sv_flag, svp->sv_flag, sv_flag_bits); 522*fcf3ce44SJohn Forte 523*fcf3ce44SJohn Forte mdb_printf("lh: 0x%p %8Tpending: 0x%p\n", 524*fcf3ce44SJohn Forte svp->sv_lh, svp->sv_pending); 525*fcf3ce44SJohn Forte 526*fcf3ce44SJohn Forte mdb_dec_indent(4); 527*fcf3ce44SJohn Forte return (DCMD_OK); 528*fcf3ce44SJohn Forte } 529*fcf3ce44SJohn Forte 530*fcf3ce44SJohn Forte 531*fcf3ce44SJohn Forte /* 532*fcf3ce44SJohn Forte * Display general sv module information. 533*fcf3ce44SJohn Forte */ 534*fcf3ce44SJohn Forte 535*fcf3ce44SJohn Forte #define sv_get_print(kvar, str, fmt, val) \ 536*fcf3ce44SJohn Forte if (mdb_readvar(&(val), #kvar) == -1) { \ 537*fcf3ce44SJohn Forte mdb_dec_indent(4); \ 538*fcf3ce44SJohn Forte mdb_warn("unable to read '" #kvar "'"); \ 539*fcf3ce44SJohn Forte return (DCMD_ERR); \ 540*fcf3ce44SJohn Forte } \ 541*fcf3ce44SJohn Forte mdb_printf("%-20s" fmt "\n", str ":", val) 542*fcf3ce44SJohn Forte 543*fcf3ce44SJohn Forte /* ARGSUSED */ 544*fcf3ce44SJohn Forte static int 545*fcf3ce44SJohn Forte sv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 546*fcf3ce44SJohn Forte { 547*fcf3ce44SJohn Forte clock_t clock; 548*fcf3ce44SJohn Forte int maj, min, mic, baseline, i; 549*fcf3ce44SJohn Forte 550*fcf3ce44SJohn Forte if (argc != 0) 551*fcf3ce44SJohn Forte return (DCMD_USAGE); 552*fcf3ce44SJohn Forte 553*fcf3ce44SJohn Forte if (mdb_readvar(&maj, "sv_major_rev") == -1) { 554*fcf3ce44SJohn Forte mdb_warn("unable to read 'sv_major_rev'"); 555*fcf3ce44SJohn Forte return (DCMD_ERR); 556*fcf3ce44SJohn Forte } 557*fcf3ce44SJohn Forte 558*fcf3ce44SJohn Forte if (mdb_readvar(&min, "sv_minor_rev") == -1) { 559*fcf3ce44SJohn Forte mdb_warn("unable to read 'sv_minor_rev'"); 560*fcf3ce44SJohn Forte return (DCMD_ERR); 561*fcf3ce44SJohn Forte } 562*fcf3ce44SJohn Forte 563*fcf3ce44SJohn Forte if (mdb_readvar(&mic, "sv_micro_rev") == -1) { 564*fcf3ce44SJohn Forte mdb_warn("unable to read 'sv_micro_rev'"); 565*fcf3ce44SJohn Forte return (DCMD_ERR); 566*fcf3ce44SJohn Forte } 567*fcf3ce44SJohn Forte 568*fcf3ce44SJohn Forte if (mdb_readvar(&baseline, "sv_baseline_rev") == -1) { 569*fcf3ce44SJohn Forte mdb_warn("unable to read 'sv_baseline_rev'"); 570*fcf3ce44SJohn Forte return (DCMD_ERR); 571*fcf3ce44SJohn Forte } 572*fcf3ce44SJohn Forte 573*fcf3ce44SJohn Forte mdb_printf("SV module version: kernel %d.%d.%d.%d; mdb %d.%d.%d.%d\n", 574*fcf3ce44SJohn Forte maj, min, mic, baseline, 575*fcf3ce44SJohn Forte ISS_VERSION_MAJ, ISS_VERSION_MIN, ISS_VERSION_MIC, ISS_VERSION_NUM); 576*fcf3ce44SJohn Forte mdb_inc_indent(4); 577*fcf3ce44SJohn Forte 578*fcf3ce44SJohn Forte sv_get_print(sv_config_time, "last config time", "0x%lx", clock); 579*fcf3ce44SJohn Forte sv_get_print(sv_stats_on, "stats on", "%d", i); 580*fcf3ce44SJohn Forte sv_get_print(sv_debug, "debug", "%d", i); 581*fcf3ce44SJohn Forte sv_get_print(sv_max_devices, "max sv devices", "%d", i); 582*fcf3ce44SJohn Forte 583*fcf3ce44SJohn Forte mdb_dec_indent(4); 584*fcf3ce44SJohn Forte return (DCMD_OK); 585*fcf3ce44SJohn Forte } 586*fcf3ce44SJohn Forte 587*fcf3ce44SJohn Forte 588*fcf3ce44SJohn Forte /* 589*fcf3ce44SJohn Forte * MDB module linkage information: 590*fcf3ce44SJohn Forte */ 591*fcf3ce44SJohn Forte 592*fcf3ce44SJohn Forte static const mdb_dcmd_t dcmds[] = { 593*fcf3ce44SJohn Forte { "sv", NULL, "display sv module info", sv }, 594*fcf3ce44SJohn Forte { "sv_dev", "?[-av]", "list sv_dev structure", sv_dev }, 595*fcf3ce44SJohn Forte { "sv_gclient", "?", "list sv_gclient structure", sv_gclient }, 596*fcf3ce44SJohn Forte { "sv_hash", ":[-av]", "display sv_dev hash chain", sv_hash }, 597*fcf3ce44SJohn Forte { "sv_maj", "?[-av]", "list sv_maj structure", sv_maj }, 598*fcf3ce44SJohn Forte { NULL } 599*fcf3ce44SJohn Forte }; 600*fcf3ce44SJohn Forte 601*fcf3ce44SJohn Forte 602*fcf3ce44SJohn Forte static const mdb_walker_t walkers[] = { 603*fcf3ce44SJohn Forte { "sv_dev", "walk array of sv_dev structures", 604*fcf3ce44SJohn Forte sv_dev_winit, sv_dev_wstep, sv_dev_wfini }, 605*fcf3ce44SJohn Forte { "sv_gclient", "walk sb_gclient chain", 606*fcf3ce44SJohn Forte sv_gclient_winit, sv_gclient_wstep, sv_gclient_wfini }, 607*fcf3ce44SJohn Forte { "sv_hash", "walk sv_dev hash chain", 608*fcf3ce44SJohn Forte sv_hash_winit, sv_hash_wstep, sv_hash_wfini }, 609*fcf3ce44SJohn Forte { "sv_maj", "walk array of sv_maj structures", 610*fcf3ce44SJohn Forte sv_maj_winit, sv_maj_wstep, sv_maj_wfini }, 611*fcf3ce44SJohn Forte { NULL } 612*fcf3ce44SJohn Forte }; 613*fcf3ce44SJohn Forte 614*fcf3ce44SJohn Forte 615*fcf3ce44SJohn Forte static const mdb_modinfo_t modinfo = { 616*fcf3ce44SJohn Forte MDB_API_VERSION, dcmds, walkers 617*fcf3ce44SJohn Forte }; 618*fcf3ce44SJohn Forte 619*fcf3ce44SJohn Forte 620*fcf3ce44SJohn Forte const mdb_modinfo_t * 621*fcf3ce44SJohn Forte _mdb_init(void) 622*fcf3ce44SJohn Forte { 623*fcf3ce44SJohn Forte return (&modinfo); 624*fcf3ce44SJohn Forte } 625