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
sv_dev_winit(mdb_walk_state_t * wsp)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
sv_dev_wstep(mdb_walk_state_t * wsp)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
sv_dev_wfini(mdb_walk_state_t * wsp)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
sv_hash_winit(mdb_walk_state_t * wsp)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
sv_hash_wstep(mdb_walk_state_t * wsp)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
sv_hash_wfini(mdb_walk_state_t * wsp)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
sv_maj_winit(mdb_walk_state_t * wsp)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
sv_maj_wstep(mdb_walk_state_t * wsp)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
sv_maj_wfini(mdb_walk_state_t * wsp)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
sv_gclient_winit(mdb_walk_state_t * wsp)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
sv_gclient_wstep(mdb_walk_state_t * wsp)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
sv_gclient_wfini(mdb_walk_state_t * wsp)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
sv_gclient(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)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
sv_maj(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)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
sv_hash(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)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
sv_dev(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)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
sv(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)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 *
_mdb_init(void)621*fcf3ce44SJohn Forte _mdb_init(void)
622*fcf3ce44SJohn Forte {
623*fcf3ce44SJohn Forte return (&modinfo);
624*fcf3ce44SJohn Forte }
625