xref: /titanic_41/usr/src/cmd/mdb/common/modules/sv/sv.c (revision fcf3ce441efd61da9bb2884968af01cb7c1452cc)
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