1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte /*
228d2b0ea9SPriya Krishnan  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23fcf3ce44SJohn Forte  * Use is subject to license terms.
24fcf3ce44SJohn Forte  */
25fcf3ce44SJohn Forte 
26fcf3ce44SJohn Forte #include <sys/dditypes.h>
27fcf3ce44SJohn Forte #include <sys/mdb_modapi.h>
28fcf3ce44SJohn Forte #include <sys/modctl.h>
29fcf3ce44SJohn Forte #include <sys/sunddi.h>
30fcf3ce44SJohn Forte #include <sys/lpif.h>
31fcf3ce44SJohn Forte #include <sys/stmf.h>
32fcf3ce44SJohn Forte #include <sys/portif.h>
33fcf3ce44SJohn Forte #include <stmf_impl.h>
34fcf3ce44SJohn Forte #include <lun_map.h>
35fcf3ce44SJohn Forte #include <stmf_state.h>
36fcf3ce44SJohn Forte 
37fcf3ce44SJohn Forte #include <sys/fct.h>
38fcf3ce44SJohn Forte #include <fct_impl.h>
39fcf3ce44SJohn Forte 
40fcf3ce44SJohn Forte #include "cmd_options.h"
41fcf3ce44SJohn Forte 
42fcf3ce44SJohn Forte static int
stmf_ilport_walk_i(mdb_walk_state_t * wsp)43fcf3ce44SJohn Forte stmf_ilport_walk_i(mdb_walk_state_t *wsp)
44fcf3ce44SJohn Forte {
45*892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
46fcf3ce44SJohn Forte 		struct stmf_state state;
47fcf3ce44SJohn Forte 
48fcf3ce44SJohn Forte 		if (mdb_readsym(&state, sizeof (struct stmf_state),
49fcf3ce44SJohn Forte 		    "stmf_state") == -1) {
50fcf3ce44SJohn Forte 			mdb_warn("failed to read stmf_state");
51fcf3ce44SJohn Forte 			return (WALK_ERR);
52fcf3ce44SJohn Forte 		}
53fcf3ce44SJohn Forte 		wsp->walk_addr = (uintptr_t)state.stmf_ilportlist;
54fcf3ce44SJohn Forte 	}
55fcf3ce44SJohn Forte 
56fcf3ce44SJohn Forte 	wsp->walk_data = mdb_alloc(sizeof (stmf_i_local_port_t), UM_SLEEP);
57fcf3ce44SJohn Forte 	return (WALK_NEXT);
58fcf3ce44SJohn Forte }
59fcf3ce44SJohn Forte 
60fcf3ce44SJohn Forte static int
stmf_ilport_walk_s(mdb_walk_state_t * wsp)61fcf3ce44SJohn Forte stmf_ilport_walk_s(mdb_walk_state_t *wsp)
62fcf3ce44SJohn Forte {
63fcf3ce44SJohn Forte 	int status = WALK_NEXT;
64fcf3ce44SJohn Forte 
65*892ad162SToomas Soome 	if (wsp->walk_addr == 0)
66fcf3ce44SJohn Forte 		return (WALK_DONE);
67fcf3ce44SJohn Forte 
68fcf3ce44SJohn Forte 	if (mdb_vread(wsp->walk_data, sizeof (struct stmf_i_local_port),
69fcf3ce44SJohn Forte 	    wsp->walk_addr) == -1) {
70fcf3ce44SJohn Forte 		mdb_warn("failed to read stmf_i_local_port_t at %p",
71fcf3ce44SJohn Forte 		    wsp->walk_addr);
72fcf3ce44SJohn Forte 		return (WALK_ERR);
73fcf3ce44SJohn Forte 	}
74fcf3ce44SJohn Forte 
75fcf3ce44SJohn Forte 	if (wsp->walk_callback)
76fcf3ce44SJohn Forte 		status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
77fcf3ce44SJohn Forte 		    wsp->walk_cbdata);
78fcf3ce44SJohn Forte 
79fcf3ce44SJohn Forte 	wsp->walk_addr = (uintptr_t)
80fcf3ce44SJohn Forte 	    (((struct stmf_i_local_port *)wsp->walk_data)->ilport_next);
81fcf3ce44SJohn Forte 
82fcf3ce44SJohn Forte 	return (status);
83fcf3ce44SJohn Forte }
84fcf3ce44SJohn Forte 
85fcf3ce44SJohn Forte static void
stmf_ilport_walk_f(mdb_walk_state_t * wsp)86fcf3ce44SJohn Forte stmf_ilport_walk_f(mdb_walk_state_t *wsp)
87fcf3ce44SJohn Forte {
88fcf3ce44SJohn Forte 	mdb_free(wsp->walk_data, sizeof (struct stmf_i_local_port));
89fcf3ce44SJohn Forte }
90fcf3ce44SJohn Forte 
91fcf3ce44SJohn Forte static int
dump_ilport(struct stmf_i_local_port * ilportp,int verbose)92fcf3ce44SJohn Forte dump_ilport(struct stmf_i_local_port *ilportp, int verbose)
93fcf3ce44SJohn Forte {
94fcf3ce44SJohn Forte 	if (ilportp == NULL)
95fcf3ce44SJohn Forte 		return (DCMD_OK);
96fcf3ce44SJohn Forte 
97fcf3ce44SJohn Forte 	mdb_printf("%p\n", ilportp);
98fcf3ce44SJohn Forte 
99fcf3ce44SJohn Forte 	if (verbose) {
100fcf3ce44SJohn Forte 		/* here assume the alias is maximumly 1024 bytes */
101fcf3ce44SJohn Forte 		char alias[255];
102fcf3ce44SJohn Forte 		struct stmf_local_port lport;
103fcf3ce44SJohn Forte 		struct stmf_i_local_port ilport;
104fcf3ce44SJohn Forte 
105fcf3ce44SJohn Forte 		if (mdb_vread(&ilport, sizeof (ilport), (uintptr_t)ilportp)
106fcf3ce44SJohn Forte 		    == -1) {
107fcf3ce44SJohn Forte 			mdb_warn("failed to read stmf_i_local_port at %p",
108fcf3ce44SJohn Forte 			    ilportp);
109fcf3ce44SJohn Forte 			return (DCMD_ERR);
110fcf3ce44SJohn Forte 		}
111fcf3ce44SJohn Forte 
112fcf3ce44SJohn Forte 		memset(alias, 0, sizeof (alias));
113fcf3ce44SJohn Forte 		if (mdb_vread(&lport, sizeof (lport),
114fcf3ce44SJohn Forte 		    (uintptr_t)ilport.ilport_lport) == -1) {
115fcf3ce44SJohn Forte 			mdb_warn("failed to read stmf_local_port at %p",
116fcf3ce44SJohn Forte 			    ilport.ilport_lport);
117fcf3ce44SJohn Forte 			return (DCMD_ERR);
118fcf3ce44SJohn Forte 		}
119fcf3ce44SJohn Forte 		if (lport.lport_alias && mdb_vread(alias, sizeof (alias),
120fcf3ce44SJohn Forte 		    (uintptr_t)lport.lport_alias) == -1) {
121fcf3ce44SJohn Forte 			mdb_warn("failed to read memory at %p",
122fcf3ce44SJohn Forte 			    lport.lport_alias);
123fcf3ce44SJohn Forte 			return (DCMD_ERR);
124fcf3ce44SJohn Forte 		}
125fcf3ce44SJohn Forte 
126fcf3ce44SJohn Forte 		mdb_printf("  lport: %p\n", ilport.ilport_lport);
127fcf3ce44SJohn Forte 		if (lport.lport_alias)
128fcf3ce44SJohn Forte 			mdb_printf("  port alias: %s\n", alias);
129fcf3ce44SJohn Forte 		mdb_printf("  port provider: %p\n", lport.lport_pp);
130fcf3ce44SJohn Forte 	}
131fcf3ce44SJohn Forte 
132fcf3ce44SJohn Forte 	return (DCMD_OK);
133fcf3ce44SJohn Forte }
134fcf3ce44SJohn Forte 
135fcf3ce44SJohn Forte /*ARGSUSED*/
136fcf3ce44SJohn Forte static int
stmf_ilports(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)137fcf3ce44SJohn Forte stmf_ilports(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
138fcf3ce44SJohn Forte {
139fcf3ce44SJohn Forte 	int i;
140fcf3ce44SJohn Forte 	int verbose = 0;
141fcf3ce44SJohn Forte 	mdb_walk_state_t ws = {NULL, };
142fcf3ce44SJohn Forte 
143fcf3ce44SJohn Forte 	for (i = 0; i < argc; i++) {
144fcf3ce44SJohn Forte 		char *ptr = (char *)argv[i].a_un.a_str;
145fcf3ce44SJohn Forte 
146fcf3ce44SJohn Forte 		if (ptr[0] == '-')
147fcf3ce44SJohn Forte 			ptr++;
148fcf3ce44SJohn Forte 		while (*ptr) {
149fcf3ce44SJohn Forte 			if (*ptr == 'v')
150fcf3ce44SJohn Forte 				verbose = 1;
151fcf3ce44SJohn Forte 			ptr++;
152fcf3ce44SJohn Forte 		}
153fcf3ce44SJohn Forte 	}
154fcf3ce44SJohn Forte 
155fcf3ce44SJohn Forte 	if (stmf_ilport_walk_i(&ws) == WALK_ERR)
156fcf3ce44SJohn Forte 		return (DCMD_ERR);
157fcf3ce44SJohn Forte 
158fcf3ce44SJohn Forte 	dump_ilport((stmf_i_local_port_t *)ws.walk_addr, verbose);
159fcf3ce44SJohn Forte 
160fcf3ce44SJohn Forte 	while (stmf_ilport_walk_s(&ws) == WALK_NEXT)
161fcf3ce44SJohn Forte 		dump_ilport((stmf_i_local_port_t *)ws.walk_addr, verbose);
162fcf3ce44SJohn Forte 
163fcf3ce44SJohn Forte 	stmf_ilport_walk_f(&ws);
164fcf3ce44SJohn Forte 	return (DCMD_OK);
165fcf3ce44SJohn Forte }
166fcf3ce44SJohn Forte 
167fcf3ce44SJohn Forte struct stmf_i_local_port *
next_stmf_port(mdb_walk_state_t * wsp)168fcf3ce44SJohn Forte next_stmf_port(mdb_walk_state_t *wsp)
169fcf3ce44SJohn Forte {
170*892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
171fcf3ce44SJohn Forte 		if (stmf_ilport_walk_i(wsp) == WALK_ERR) {
172fcf3ce44SJohn Forte 			stmf_ilport_walk_f(wsp);
173fcf3ce44SJohn Forte 			return (NULL);
174fcf3ce44SJohn Forte 		}
175*892ad162SToomas Soome 		if (wsp->walk_addr == 0)
176fcf3ce44SJohn Forte 			stmf_ilport_walk_f(wsp);
177fcf3ce44SJohn Forte 		return ((struct stmf_i_local_port *)wsp->walk_addr);
178fcf3ce44SJohn Forte 	}
179fcf3ce44SJohn Forte 
180fcf3ce44SJohn Forte 	if (stmf_ilport_walk_s(wsp) == WALK_ERR) {
181fcf3ce44SJohn Forte 		stmf_ilport_walk_f(wsp);
182fcf3ce44SJohn Forte 		return (NULL);
183fcf3ce44SJohn Forte 	}
184*892ad162SToomas Soome 	if (wsp->walk_addr == 0)
185fcf3ce44SJohn Forte 		stmf_ilport_walk_f(wsp);
186fcf3ce44SJohn Forte 	return ((struct stmf_i_local_port *)wsp->walk_addr);
187fcf3ce44SJohn Forte }
188fcf3ce44SJohn Forte 
189fcf3ce44SJohn Forte 
190fcf3ce44SJohn Forte /*ARGSUSED*/
191fcf3ce44SJohn Forte static int
stmf_iss(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)192fcf3ce44SJohn Forte stmf_iss(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
193fcf3ce44SJohn Forte {
194fcf3ce44SJohn Forte 	struct stmf_i_local_port iport;
195fcf3ce44SJohn Forte 	struct stmf_i_scsi_session *issp;
196fcf3ce44SJohn Forte 	struct stmf_i_scsi_session iss;
197fcf3ce44SJohn Forte 	int i;
198fcf3ce44SJohn Forte 	int verbose = 0;
199fcf3ce44SJohn Forte 
200fcf3ce44SJohn Forte 	for (i = 0; i < argc; i++) {
201fcf3ce44SJohn Forte 		char *ptr = (char *)argv[i].a_un.a_str;
202fcf3ce44SJohn Forte 
203fcf3ce44SJohn Forte 		if (ptr[0] == '-')
204fcf3ce44SJohn Forte 			ptr++;
205fcf3ce44SJohn Forte 		while (*ptr) {
206fcf3ce44SJohn Forte 			if (*ptr == 'v')
207fcf3ce44SJohn Forte 				verbose = 1;
208fcf3ce44SJohn Forte 			ptr++;
209fcf3ce44SJohn Forte 		}
210fcf3ce44SJohn Forte 	}
211fcf3ce44SJohn Forte 
212*892ad162SToomas Soome 	if (addr == 0) {
213fcf3ce44SJohn Forte 		mdb_warn("address of stmf_i_local_port should be specified\n");
214fcf3ce44SJohn Forte 		return (DCMD_ERR);
215fcf3ce44SJohn Forte 	}
216fcf3ce44SJohn Forte 
217fcf3ce44SJohn Forte 	/*
218fcf3ce44SJohn Forte 	 * Input should be stmf_i_local_port_t.
219fcf3ce44SJohn Forte 	 */
220fcf3ce44SJohn Forte 	if (mdb_vread(&iport, sizeof (struct stmf_i_local_port), addr)
221fcf3ce44SJohn Forte 	    != sizeof (struct stmf_i_local_port)) {
222fcf3ce44SJohn Forte 		mdb_warn("Unable to read in stmf_i_local_port at %p\n", addr);
223fcf3ce44SJohn Forte 		return (DCMD_ERR);
224fcf3ce44SJohn Forte 	}
225fcf3ce44SJohn Forte 
226fcf3ce44SJohn Forte 	issp = iport.ilport_ss_list;
227fcf3ce44SJohn Forte 
228fcf3ce44SJohn Forte 	while (issp) {
229fcf3ce44SJohn Forte 		if (mdb_vread(&iss, sizeof (iss), (uintptr_t)issp) == -1) {
230fcf3ce44SJohn Forte 			mdb_warn("failed to read stmf_i_scsi_session_t at %p",
231fcf3ce44SJohn Forte 			    issp);
232fcf3ce44SJohn Forte 			return (DCMD_ERR);
233fcf3ce44SJohn Forte 		}
234fcf3ce44SJohn Forte 
235fcf3ce44SJohn Forte 		mdb_printf("%p\n", issp);
236fcf3ce44SJohn Forte 		if (verbose) {
237fcf3ce44SJohn Forte 			mdb_printf("  scsi session: %p\n", iss.iss_ss);
238fcf3ce44SJohn Forte 		}
239fcf3ce44SJohn Forte 
240fcf3ce44SJohn Forte 		issp = iss.iss_next;
241fcf3ce44SJohn Forte 	}
242fcf3ce44SJohn Forte 
243fcf3ce44SJohn Forte 	return (DCMD_OK);
244fcf3ce44SJohn Forte }
245fcf3ce44SJohn Forte 
246fcf3ce44SJohn Forte /*ARGSUSED*/
247fcf3ce44SJohn Forte static int
stmf_ilus(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)248fcf3ce44SJohn Forte stmf_ilus(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
249fcf3ce44SJohn Forte {
250fcf3ce44SJohn Forte 	struct stmf_state state;
251fcf3ce44SJohn Forte 	struct stmf_i_lu ilu;
252fcf3ce44SJohn Forte 	struct stmf_i_lu *ilup;
253fcf3ce44SJohn Forte 	int i;
254fcf3ce44SJohn Forte 	int verbose = 0;
255fcf3ce44SJohn Forte 
256fcf3ce44SJohn Forte 	for (i = 0; i < argc; i++) {
257fcf3ce44SJohn Forte 		char *ptr = (char *)argv[i].a_un.a_str;
258fcf3ce44SJohn Forte 
259fcf3ce44SJohn Forte 		if (ptr[0] == '-')
260fcf3ce44SJohn Forte 			ptr++;
261fcf3ce44SJohn Forte 		while (*ptr) {
262fcf3ce44SJohn Forte 			if (*ptr == 'v')
263fcf3ce44SJohn Forte 				verbose = 1;
264fcf3ce44SJohn Forte 			ptr++;
265fcf3ce44SJohn Forte 		}
266fcf3ce44SJohn Forte 	}
267fcf3ce44SJohn Forte 
268fcf3ce44SJohn Forte 	if (mdb_readsym(&state, sizeof (struct stmf_state), "stmf_state")
269fcf3ce44SJohn Forte 	    == -1) {
270fcf3ce44SJohn Forte 		mdb_warn("failed to read stmf_state");
271fcf3ce44SJohn Forte 		return (DCMD_ERR);
272fcf3ce44SJohn Forte 	}
273fcf3ce44SJohn Forte 
274fcf3ce44SJohn Forte 	ilup = state.stmf_ilulist;
275fcf3ce44SJohn Forte 	while (ilup) {
276fcf3ce44SJohn Forte 		if (mdb_vread(&ilu, sizeof (struct stmf_i_lu), (uintptr_t)ilup)
277fcf3ce44SJohn Forte 		    == -1) {
278fcf3ce44SJohn Forte 			mdb_warn("failed to read stmf_i_lu_t at %p", ilup);
279fcf3ce44SJohn Forte 			return (DCMD_ERR);
280fcf3ce44SJohn Forte 		}
281fcf3ce44SJohn Forte 
282fcf3ce44SJohn Forte 		mdb_printf("%p\n", ilup);
283fcf3ce44SJohn Forte 		if (verbose) {
284fcf3ce44SJohn Forte 			mdb_printf("  lu: %p\n", ilu.ilu_lu);
285fcf3ce44SJohn Forte 
286fcf3ce44SJohn Forte 			/* XXX lu_alias? what is its size? */
287fcf3ce44SJohn Forte 		}
288fcf3ce44SJohn Forte 
289fcf3ce44SJohn Forte 		ilup = ilu.ilu_next;
290fcf3ce44SJohn Forte 	}
291fcf3ce44SJohn Forte 
292fcf3ce44SJohn Forte 	return (DCMD_OK);
293fcf3ce44SJohn Forte }
294fcf3ce44SJohn Forte 
295fcf3ce44SJohn Forte /*ARGSUSED*/
296fcf3ce44SJohn Forte static int
stmf_i_lu_providers(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)297fcf3ce44SJohn Forte stmf_i_lu_providers(uintptr_t addr, uint_t flags, int argc,
298fcf3ce44SJohn Forte     const mdb_arg_t *argv)
299fcf3ce44SJohn Forte {
300fcf3ce44SJohn Forte 	struct stmf_state state;
301fcf3ce44SJohn Forte 	struct stmf_i_lu_provider ilp;
302fcf3ce44SJohn Forte 	struct stmf_i_lu_provider *ilpp;
303fcf3ce44SJohn Forte 	int i;
304fcf3ce44SJohn Forte 	int verbose = 0;
305fcf3ce44SJohn Forte 
306fcf3ce44SJohn Forte 	for (i = 0; i < argc; i++) {
307fcf3ce44SJohn Forte 		char *ptr = (char *)argv[i].a_un.a_str;
308fcf3ce44SJohn Forte 
309fcf3ce44SJohn Forte 		if (ptr[0] == '-')
310fcf3ce44SJohn Forte 			ptr++;
311fcf3ce44SJohn Forte 		while (*ptr) {
312fcf3ce44SJohn Forte 			if (*ptr == 'v')
313fcf3ce44SJohn Forte 				verbose = 1;
314fcf3ce44SJohn Forte 			ptr++;
315fcf3ce44SJohn Forte 		}
316fcf3ce44SJohn Forte 	}
317fcf3ce44SJohn Forte 
318fcf3ce44SJohn Forte 	if (mdb_readsym(&state, sizeof (struct stmf_state), "stmf_state")
319fcf3ce44SJohn Forte 	    == -1) {
320fcf3ce44SJohn Forte 		mdb_warn("failed to read stmf_state");
321fcf3ce44SJohn Forte 		return (DCMD_ERR);
322fcf3ce44SJohn Forte 	}
323fcf3ce44SJohn Forte 
324fcf3ce44SJohn Forte 	ilpp = state.stmf_ilplist;
325fcf3ce44SJohn Forte 	while (ilpp) {
326fcf3ce44SJohn Forte 		if (mdb_vread(&ilp, sizeof (stmf_i_lu_provider_t),
327fcf3ce44SJohn Forte 		    (uintptr_t)ilpp) == -1) {
328fcf3ce44SJohn Forte 			mdb_warn("failed to read stmf_i_lu_provider_t at %p",
329fcf3ce44SJohn Forte 			    ilpp);
330fcf3ce44SJohn Forte 			return (DCMD_ERR);
331fcf3ce44SJohn Forte 		}
332fcf3ce44SJohn Forte 
333fcf3ce44SJohn Forte 		mdb_printf("%p\n", ilpp);
334fcf3ce44SJohn Forte 		if (verbose) {
335fcf3ce44SJohn Forte 			mdb_printf("  lu provider: %p\n", ilp.ilp_lp);
336fcf3ce44SJohn Forte 		}
337fcf3ce44SJohn Forte 
338fcf3ce44SJohn Forte 		ilpp = ilp.ilp_next;
339fcf3ce44SJohn Forte 	}
340fcf3ce44SJohn Forte 
341fcf3ce44SJohn Forte 	return (DCMD_OK);
342fcf3ce44SJohn Forte }
343fcf3ce44SJohn Forte 
344fcf3ce44SJohn Forte /*ARGSUSED*/
345fcf3ce44SJohn Forte static int
stmf_i_port_providers(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)346fcf3ce44SJohn Forte stmf_i_port_providers(uintptr_t addr, uint_t flags, int argc,
347fcf3ce44SJohn Forte     const mdb_arg_t *argv)
348fcf3ce44SJohn Forte {
349fcf3ce44SJohn Forte 	struct stmf_state state;
350fcf3ce44SJohn Forte 	struct stmf_i_port_provider ipp;
351fcf3ce44SJohn Forte 	struct stmf_i_port_provider *ippp;
352fcf3ce44SJohn Forte 	int i;
353fcf3ce44SJohn Forte 	int verbose = 0;
354fcf3ce44SJohn Forte 
355fcf3ce44SJohn Forte 	for (i = 0; i < argc; i++) {
356fcf3ce44SJohn Forte 		char *ptr = (char *)argv[i].a_un.a_str;
357fcf3ce44SJohn Forte 
358fcf3ce44SJohn Forte 		if (ptr[0] == '-')
359fcf3ce44SJohn Forte 			ptr++;
360fcf3ce44SJohn Forte 		while (*ptr) {
361fcf3ce44SJohn Forte 			if (*ptr == 'v')
362fcf3ce44SJohn Forte 				verbose = 1;
363fcf3ce44SJohn Forte 			ptr++;
364fcf3ce44SJohn Forte 		}
365fcf3ce44SJohn Forte 	}
366fcf3ce44SJohn Forte 
367fcf3ce44SJohn Forte 	if (mdb_readsym(&state, sizeof (struct stmf_state), "stmf_state")
368fcf3ce44SJohn Forte 	    == -1) {
369fcf3ce44SJohn Forte 		mdb_warn("failed to read stmf_state");
370fcf3ce44SJohn Forte 		return (DCMD_ERR);
371fcf3ce44SJohn Forte 	}
372fcf3ce44SJohn Forte 
373fcf3ce44SJohn Forte 	ippp = state.stmf_ipplist;
374fcf3ce44SJohn Forte 	while (ippp) {
375fcf3ce44SJohn Forte 		if (mdb_vread(&ipp, sizeof (stmf_i_port_provider_t),
376fcf3ce44SJohn Forte 		    (uintptr_t)ippp) == -1) {
377fcf3ce44SJohn Forte 			mdb_warn("failed to read stmf_i_port_provider_t at %p",
378fcf3ce44SJohn Forte 			    ippp);
379fcf3ce44SJohn Forte 			return (DCMD_ERR);
380fcf3ce44SJohn Forte 		}
381fcf3ce44SJohn Forte 
382fcf3ce44SJohn Forte 		mdb_printf("%p\n", ippp);
383fcf3ce44SJohn Forte 		if (verbose) {
384fcf3ce44SJohn Forte 			mdb_printf("  port provider: %p\n", ipp.ipp_pp);
385fcf3ce44SJohn Forte 		}
386fcf3ce44SJohn Forte 
387fcf3ce44SJohn Forte 		ippp = ipp.ipp_next;
388fcf3ce44SJohn Forte 	}
389fcf3ce44SJohn Forte 
390fcf3ce44SJohn Forte 	return (DCMD_OK);
391fcf3ce44SJohn Forte }
392fcf3ce44SJohn Forte 
393fcf3ce44SJohn Forte int string2wwn(const char *s, uint8_t wwn[8]);
394fcf3ce44SJohn Forte 
395fcf3ce44SJohn Forte static uint16_t port_max_logins;
396fcf3ce44SJohn Forte static int	rp_index;
397fcf3ce44SJohn Forte 
398fcf3ce44SJohn Forte /*
399fcf3ce44SJohn Forte  * Cervert stmf_i_local_port to fct_i_local_port
400fcf3ce44SJohn Forte  */
401fcf3ce44SJohn Forte /*ARGSUSED*/
402fcf3ce44SJohn Forte static struct fct_i_local_port *
__ilport2iport(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)403fcf3ce44SJohn Forte __ilport2iport(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
404fcf3ce44SJohn Forte {
405fcf3ce44SJohn Forte 	struct stmf_i_local_port iport;
406fcf3ce44SJohn Forte 	struct stmf_local_port   lport;
407fcf3ce44SJohn Forte 	struct fct_local_port    fport;
408fcf3ce44SJohn Forte 
409fcf3ce44SJohn Forte 	if (!(flags & DCMD_ADDRSPEC)) {
410fcf3ce44SJohn Forte 		mdb_warn("stmf_i_local_port address should be specified");
411fcf3ce44SJohn Forte 		return (NULL);
412fcf3ce44SJohn Forte 	}
413fcf3ce44SJohn Forte 
414fcf3ce44SJohn Forte 	/*
415fcf3ce44SJohn Forte 	 * Input should be stmf_i_local_port_t.
416fcf3ce44SJohn Forte 	 */
417fcf3ce44SJohn Forte 	if (mdb_vread(&iport, sizeof (struct stmf_i_local_port), addr)
418fcf3ce44SJohn Forte 	    != sizeof (struct stmf_i_local_port)) {
419fcf3ce44SJohn Forte 		mdb_warn("Unable to read in stmf_i_local_port\n");
420fcf3ce44SJohn Forte 		return (NULL);
421fcf3ce44SJohn Forte 	}
422fcf3ce44SJohn Forte 
423fcf3ce44SJohn Forte 	if (mdb_vread(&lport, sizeof (stmf_local_port_t),
424fcf3ce44SJohn Forte 	    (uintptr_t)iport.ilport_lport) != sizeof (stmf_local_port_t)) {
425fcf3ce44SJohn Forte 		mdb_warn("Unable to read in stmf_local_port\n");
426fcf3ce44SJohn Forte 		return (NULL);
427fcf3ce44SJohn Forte 	}
428fcf3ce44SJohn Forte 
429fcf3ce44SJohn Forte 	if (mdb_vread(&fport, sizeof (fct_local_port_t),
430fcf3ce44SJohn Forte 	    (uintptr_t)lport.lport_port_private)
431fcf3ce44SJohn Forte 	    != sizeof (fct_local_port_t)) {
432fcf3ce44SJohn Forte 		mdb_warn("Unable to read in fct_local_port\n");
433fcf3ce44SJohn Forte 		return (NULL);
434fcf3ce44SJohn Forte 	}
435fcf3ce44SJohn Forte 
436fcf3ce44SJohn Forte 	return (fport.port_fct_private);
437fcf3ce44SJohn Forte }
438fcf3ce44SJohn Forte 
439fcf3ce44SJohn Forte static int
ilport2iport(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)440fcf3ce44SJohn Forte ilport2iport(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
441fcf3ce44SJohn Forte {
442fcf3ce44SJohn Forte 	struct fct_i_local_port *iportp;
443fcf3ce44SJohn Forte 	int i;
444fcf3ce44SJohn Forte 	int verbose = 0;
445fcf3ce44SJohn Forte 
446fcf3ce44SJohn Forte 	for (i = 0; i < argc; i++) {
447fcf3ce44SJohn Forte 		char *ptr = (char *)argv[i].a_un.a_str;
448fcf3ce44SJohn Forte 
449fcf3ce44SJohn Forte 		if (ptr[0] == '-')
450fcf3ce44SJohn Forte 			ptr++;
451fcf3ce44SJohn Forte 		while (*ptr) {
452fcf3ce44SJohn Forte 			if (*ptr == 'v')
453fcf3ce44SJohn Forte 				verbose = 1;
454fcf3ce44SJohn Forte 			ptr++;
455fcf3ce44SJohn Forte 		}
456fcf3ce44SJohn Forte 	}
457fcf3ce44SJohn Forte 
458fcf3ce44SJohn Forte 
459fcf3ce44SJohn Forte 	iportp = __ilport2iport(addr, flags, argc, argv);
460fcf3ce44SJohn Forte 	if (iportp) {
461fcf3ce44SJohn Forte 		mdb_printf("%p\n", iportp);
462fcf3ce44SJohn Forte 		if (verbose) {
463fcf3ce44SJohn Forte 			struct fct_i_local_port iport;
464fcf3ce44SJohn Forte 			/* is the alias always 16 bytes in size ? */
465fcf3ce44SJohn Forte 			char alias[16];
466fcf3ce44SJohn Forte 
467fcf3ce44SJohn Forte 			memset(alias, 0, sizeof (alias));
468fcf3ce44SJohn Forte 			if (mdb_vread(&iport, sizeof (fct_i_local_port_t),
469fcf3ce44SJohn Forte 			    (uintptr_t)iportp)
470fcf3ce44SJohn Forte 			    != sizeof (fct_i_local_port_t)) {
471fcf3ce44SJohn Forte 				mdb_warn("Unable to read in fct_i_local_port"
472fcf3ce44SJohn Forte 				    "at %p\n", iportp);
473fcf3ce44SJohn Forte 				return (DCMD_ERR);
474fcf3ce44SJohn Forte 			}
475fcf3ce44SJohn Forte 			if (iport.iport_alias &&
476fcf3ce44SJohn Forte 			    mdb_vread(alias, sizeof (alias),
477fcf3ce44SJohn Forte 			    (uintptr_t)iport.iport_alias)
478fcf3ce44SJohn Forte 			    != sizeof (alias)) {
479fcf3ce44SJohn Forte 				mdb_warn("Unable to read in memory at %p",
480fcf3ce44SJohn Forte 				    iport.iport_alias);
481fcf3ce44SJohn Forte 				return (DCMD_ERR);
482fcf3ce44SJohn Forte 			}
483fcf3ce44SJohn Forte 			mdb_printf("  port: %p\n", iport.iport_port);
484fcf3ce44SJohn Forte 			if (iport.iport_alias)
485fcf3ce44SJohn Forte 				mdb_printf("  alias: %s\n", alias);
486fcf3ce44SJohn Forte 		}
487fcf3ce44SJohn Forte 	}
488fcf3ce44SJohn Forte 	return (DCMD_OK);
489fcf3ce44SJohn Forte }
490fcf3ce44SJohn Forte 
491fcf3ce44SJohn Forte /*
492fcf3ce44SJohn Forte  * by wwn, we can only find one local port
493fcf3ce44SJohn Forte  */
494fcf3ce44SJohn Forte static struct stmf_i_local_port *
find_lport_by_wwn(uint8_t wwn[8])495fcf3ce44SJohn Forte find_lport_by_wwn(uint8_t wwn[8])
496fcf3ce44SJohn Forte {
497fcf3ce44SJohn Forte 	struct stmf_i_local_port *siport;
498fcf3ce44SJohn Forte 	struct fct_i_local_port *fiport;
499fcf3ce44SJohn Forte 	struct fct_i_local_port iport;
500fcf3ce44SJohn Forte 	struct fct_local_port fport;
501fcf3ce44SJohn Forte 	mdb_walk_state_t ws = {NULL, };
502fcf3ce44SJohn Forte 
503fcf3ce44SJohn Forte 	while ((siport = next_stmf_port(&ws)) != NULL) {
504fcf3ce44SJohn Forte 		fiport = __ilport2iport((uintptr_t)siport, DCMD_ADDRSPEC,
505fcf3ce44SJohn Forte 		    0, NULL);
506fcf3ce44SJohn Forte 		if (fiport == NULL)
507fcf3ce44SJohn Forte 			return (NULL);
508fcf3ce44SJohn Forte 
509fcf3ce44SJohn Forte 		if (mdb_vread(&iport, sizeof (fct_i_local_port_t),
510fcf3ce44SJohn Forte 		    (uintptr_t)fiport)
511fcf3ce44SJohn Forte 		    != sizeof (fct_i_local_port_t)) {
512fcf3ce44SJohn Forte 			mdb_warn("Unable to read in fct_i_local_port\n");
513fcf3ce44SJohn Forte 			return (NULL);
514fcf3ce44SJohn Forte 		}
515fcf3ce44SJohn Forte 		if (mdb_vread(&fport, sizeof (fct_local_port_t),
516fcf3ce44SJohn Forte 		    (uintptr_t)iport.iport_port)
517fcf3ce44SJohn Forte 		    != sizeof (fct_local_port_t)) {
518fcf3ce44SJohn Forte 			mdb_warn("Unable to read in fct_local_port\n");
519fcf3ce44SJohn Forte 			return (NULL);
520fcf3ce44SJohn Forte 		}
521fcf3ce44SJohn Forte 
522fcf3ce44SJohn Forte #if 0
523fcf3ce44SJohn Forte 		mdb_printf("pwwn=%02x%02x%02x%02x%02x%02x%02x%02x\n",
524fcf3ce44SJohn Forte 		    fport.port_pwwn[0], fport.port_pwwn[1],
525fcf3ce44SJohn Forte 		    fport.port_pwwn[2], fport.port_pwwn[3],
526fcf3ce44SJohn Forte 		    fport.port_pwwn[4], fport.port_pwwn[5],
527fcf3ce44SJohn Forte 		    fport.port_pwwn[6], fport.port_pwwn[7]);
528fcf3ce44SJohn Forte #endif
529fcf3ce44SJohn Forte 		if (memcmp(fport.port_pwwn, wwn, 8) == 0) {
530fcf3ce44SJohn Forte 			return (siport);
531fcf3ce44SJohn Forte 		}
532fcf3ce44SJohn Forte 	}
533fcf3ce44SJohn Forte 
534fcf3ce44SJohn Forte 	return (NULL);
535fcf3ce44SJohn Forte }
536fcf3ce44SJohn Forte 
537fcf3ce44SJohn Forte /*ARGSUSED*/
538fcf3ce44SJohn Forte static int
stmf_find_ilport(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)539fcf3ce44SJohn Forte stmf_find_ilport(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
540fcf3ce44SJohn Forte {
541fcf3ce44SJohn Forte 	struct find_options *options;
542fcf3ce44SJohn Forte 	struct stmf_i_local_port *siport;
543fcf3ce44SJohn Forte 
544fcf3ce44SJohn Forte 	options = parse_options(argc, argv);
545fcf3ce44SJohn Forte 	/* need to free options manually ? */
546fcf3ce44SJohn Forte 	if (options == NULL || ! options->lpname_defined) {
547fcf3ce44SJohn Forte 		mdb_printf("lpname=<wwn.12345678 or 12345678> "
548fcf3ce44SJohn Forte 		    "should be specified\n");
549fcf3ce44SJohn Forte 		return (DCMD_OK);
550fcf3ce44SJohn Forte 	}
551fcf3ce44SJohn Forte 
552fcf3ce44SJohn Forte 	if ((siport = find_lport_by_wwn(options->lpname)) != NULL)
553fcf3ce44SJohn Forte 		mdb_printf("%p\n", siport);
554fcf3ce44SJohn Forte 
555fcf3ce44SJohn Forte 	return (DCMD_OK);
556fcf3ce44SJohn Forte }
557fcf3ce44SJohn Forte 
558fcf3ce44SJohn Forte static int
fct_irp_walk_i(mdb_walk_state_t * wsp)559fcf3ce44SJohn Forte fct_irp_walk_i(mdb_walk_state_t *wsp)
560fcf3ce44SJohn Forte {
561fcf3ce44SJohn Forte 	struct fct_local_port port;
562fcf3ce44SJohn Forte 	struct fct_i_local_port iport;
563fcf3ce44SJohn Forte 
564*892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
565fcf3ce44SJohn Forte 		mdb_warn("Can not perform global walk");
566fcf3ce44SJohn Forte 		return (WALK_ERR);
567fcf3ce44SJohn Forte 	}
568fcf3ce44SJohn Forte 
569fcf3ce44SJohn Forte 	/*
570fcf3ce44SJohn Forte 	 * Input should be fct_i_local_port_t.
571fcf3ce44SJohn Forte 	 */
572fcf3ce44SJohn Forte 	if (mdb_vread(&iport, sizeof (struct fct_i_local_port), wsp->walk_addr)
573fcf3ce44SJohn Forte 	    != sizeof (struct fct_i_local_port)) {
574fcf3ce44SJohn Forte 		mdb_warn("Unable to read in fct_i_local_port\n");
575fcf3ce44SJohn Forte 		return (WALK_ERR);
576fcf3ce44SJohn Forte 	}
577fcf3ce44SJohn Forte 
578fcf3ce44SJohn Forte 	if (mdb_vread(&port, sizeof (struct fct_local_port),
579fcf3ce44SJohn Forte 	    (uintptr_t)iport.iport_port)
580fcf3ce44SJohn Forte 	    != sizeof (struct fct_local_port)) {
581fcf3ce44SJohn Forte 		mdb_warn("Unable to read in fct_local_port\n");
582fcf3ce44SJohn Forte 		return (WALK_ERR);
583fcf3ce44SJohn Forte 	}
584fcf3ce44SJohn Forte 
585fcf3ce44SJohn Forte 	port_max_logins = port.port_max_logins;
586fcf3ce44SJohn Forte 	rp_index = 0;
587fcf3ce44SJohn Forte 	wsp->walk_addr = (uintptr_t)iport.iport_rp_slots;
588fcf3ce44SJohn Forte 
589fcf3ce44SJohn Forte 	return (WALK_NEXT);
590fcf3ce44SJohn Forte }
591fcf3ce44SJohn Forte 
592fcf3ce44SJohn Forte static int
fct_irp_walk_s(mdb_walk_state_t * wsp)593fcf3ce44SJohn Forte fct_irp_walk_s(mdb_walk_state_t *wsp)
594fcf3ce44SJohn Forte {
595fcf3ce44SJohn Forte 	int status = WALK_NEXT;
596fcf3ce44SJohn Forte 	fct_i_remote_port_t *rp;
597fcf3ce44SJohn Forte 
598*892ad162SToomas Soome 	if (wsp->walk_addr == 0)
599fcf3ce44SJohn Forte 		return (WALK_DONE);
600fcf3ce44SJohn Forte 
601fcf3ce44SJohn Forte 	if (rp_index++ >= port_max_logins)
602fcf3ce44SJohn Forte 		return (WALK_DONE);
603fcf3ce44SJohn Forte 
604fcf3ce44SJohn Forte 	if (mdb_vread(&rp, sizeof (fct_i_remote_port_t *),
605fcf3ce44SJohn Forte 	    wsp->walk_addr) == -1) {
606fcf3ce44SJohn Forte 		mdb_warn("failed to read address of fct_i_remote_port_t at %p",
607fcf3ce44SJohn Forte 		    wsp->walk_addr);
608fcf3ce44SJohn Forte 		return (WALK_DONE);
609fcf3ce44SJohn Forte 	}
610fcf3ce44SJohn Forte 
611fcf3ce44SJohn Forte 	if (rp != NULL && wsp->walk_callback != NULL)
612fcf3ce44SJohn Forte 		status = wsp->walk_callback((uintptr_t)rp, rp,
613fcf3ce44SJohn Forte 		    wsp->walk_cbdata);
614fcf3ce44SJohn Forte 
615fcf3ce44SJohn Forte 	wsp->walk_addr = (uintptr_t)
616fcf3ce44SJohn Forte 	    &(((fct_i_remote_port_t **)wsp->walk_addr)[1]);
617fcf3ce44SJohn Forte 
618fcf3ce44SJohn Forte 	return (status);
619fcf3ce44SJohn Forte }
620fcf3ce44SJohn Forte 
621fcf3ce44SJohn Forte static void
fct_irp_walk_f(mdb_walk_state_t * wsp)622fcf3ce44SJohn Forte fct_irp_walk_f(mdb_walk_state_t *wsp)
623fcf3ce44SJohn Forte {
624*892ad162SToomas Soome 	wsp->walk_addr = 0;
625fcf3ce44SJohn Forte }
626fcf3ce44SJohn Forte 
627fcf3ce44SJohn Forte /*
628fcf3ce44SJohn Forte  * to set remote_port
629fcf3ce44SJohn Forte  */
630fcf3ce44SJohn Forte /*ARGSUSED*/
631fcf3ce44SJohn Forte static int
walk_fct_irp_cb(uintptr_t p,const void * arg,void * cbdata)632fcf3ce44SJohn Forte walk_fct_irp_cb(uintptr_t p, const void * arg, void *cbdata)
633fcf3ce44SJohn Forte {
634fcf3ce44SJohn Forte 	*((uintptr_t *)cbdata) = p;
635fcf3ce44SJohn Forte 	return (WALK_NEXT);
636fcf3ce44SJohn Forte }
637fcf3ce44SJohn Forte 
638fcf3ce44SJohn Forte static int
fct_irps(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)639fcf3ce44SJohn Forte fct_irps(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
640fcf3ce44SJohn Forte {
641fcf3ce44SJohn Forte 	static uint64_t cbdata = 0;
642fcf3ce44SJohn Forte 	mdb_walk_state_t ws = {walk_fct_irp_cb, &cbdata, addr};
643fcf3ce44SJohn Forte 	fct_i_remote_port_t *irpp;
644fcf3ce44SJohn Forte 	int i;
645fcf3ce44SJohn Forte 	int verbose = 0;
646fcf3ce44SJohn Forte 
647fcf3ce44SJohn Forte 	for (i = 0; i < argc; i++) {
648fcf3ce44SJohn Forte 		char *ptr = (char *)argv[i].a_un.a_str;
649fcf3ce44SJohn Forte 
650fcf3ce44SJohn Forte 		if (ptr[0] == '-')
651fcf3ce44SJohn Forte 			ptr++;
652fcf3ce44SJohn Forte 		while (*ptr) {
653fcf3ce44SJohn Forte 			if (*ptr == 'v')
654fcf3ce44SJohn Forte 				verbose = 1;
655fcf3ce44SJohn Forte 			ptr++;
656fcf3ce44SJohn Forte 		}
657fcf3ce44SJohn Forte 	}
658fcf3ce44SJohn Forte 
659fcf3ce44SJohn Forte 	if (!(flags & DCMD_ADDRSPEC)) {
660fcf3ce44SJohn Forte 		mdb_warn("fct_i_local_port_t address should be specified");
661fcf3ce44SJohn Forte 		return (DCMD_ERR);
662fcf3ce44SJohn Forte 	}
663fcf3ce44SJohn Forte 
664fcf3ce44SJohn Forte 	fct_irp_walk_i(&ws);
665fcf3ce44SJohn Forte 	while (fct_irp_walk_s(&ws) == WALK_NEXT) {
666fcf3ce44SJohn Forte 		irpp = *((fct_i_remote_port_t **)ws.walk_cbdata);
667fcf3ce44SJohn Forte 
668fcf3ce44SJohn Forte 		if (irpp) {
669fcf3ce44SJohn Forte 			*((fct_i_remote_port_t **)ws.walk_cbdata) = NULL;
670fcf3ce44SJohn Forte 
671fcf3ce44SJohn Forte 			mdb_printf("%p\n", irpp);
672fcf3ce44SJohn Forte 			if (verbose) {
673fcf3ce44SJohn Forte 				fct_i_remote_port_t irp;
674fcf3ce44SJohn Forte 
675fcf3ce44SJohn Forte 				if (mdb_vread(&irp, sizeof (irp),
676fcf3ce44SJohn Forte 				    (uintptr_t)irpp) != sizeof (irp)) {
677fcf3ce44SJohn Forte 					mdb_warn("Unable to read in "
678fcf3ce44SJohn Forte 					    "fct_i_remote_port at %p\n", irpp);
679fcf3ce44SJohn Forte 					return (DCMD_ERR);
680fcf3ce44SJohn Forte 				}
681fcf3ce44SJohn Forte 				mdb_printf("  remote port: %p\n", irp.irp_rp);
682fcf3ce44SJohn Forte 				mdb_printf("  port id: %x\n", irp.irp_portid);
683fcf3ce44SJohn Forte 			}
684fcf3ce44SJohn Forte 		}
685fcf3ce44SJohn Forte 	}
686fcf3ce44SJohn Forte 	fct_irp_walk_f(&ws);
687fcf3ce44SJohn Forte 
688fcf3ce44SJohn Forte 	return (DCMD_OK);
689fcf3ce44SJohn Forte }
690fcf3ce44SJohn Forte 
691*892ad162SToomas Soome static uintptr_t cur_iport_for_irp_loop = 0;
692fcf3ce44SJohn Forte 
693fcf3ce44SJohn Forte static fct_i_remote_port_t *
next_rport(struct fct_i_local_port * iport)694fcf3ce44SJohn Forte next_rport(struct fct_i_local_port *iport)
695fcf3ce44SJohn Forte {
696fcf3ce44SJohn Forte 	static uint64_t cbdata = 0;
697fcf3ce44SJohn Forte 	static mdb_walk_state_t ws = {walk_fct_irp_cb, &cbdata};
698fcf3ce44SJohn Forte 	int ret;
699fcf3ce44SJohn Forte 	fct_i_remote_port_t *irp;
700fcf3ce44SJohn Forte 
701*892ad162SToomas Soome 	if (ws.walk_addr == 0 || cur_iport_for_irp_loop !=
702fcf3ce44SJohn Forte 	    (uintptr_t)iport) {
703fcf3ce44SJohn Forte 		*((fct_i_remote_port_t **)ws.walk_cbdata) = NULL;
704fcf3ce44SJohn Forte 		cur_iport_for_irp_loop = (uintptr_t)iport;
705fcf3ce44SJohn Forte 		ws.walk_addr = (uintptr_t)iport;
706fcf3ce44SJohn Forte 		if (fct_irp_walk_i(&ws) == WALK_ERR) {
707fcf3ce44SJohn Forte 			fct_irp_walk_f(&ws);
708fcf3ce44SJohn Forte 			return (NULL);
709fcf3ce44SJohn Forte 		}
710*892ad162SToomas Soome 		if (ws.walk_addr == 0) {
711fcf3ce44SJohn Forte 			fct_irp_walk_f(&ws);
712fcf3ce44SJohn Forte 			return (NULL);
713fcf3ce44SJohn Forte 		}
714fcf3ce44SJohn Forte 	}
715fcf3ce44SJohn Forte 
716fcf3ce44SJohn Forte 	while ((ret = fct_irp_walk_s(&ws)) == WALK_NEXT) {
717fcf3ce44SJohn Forte 		if (*((fct_i_remote_port_t **)ws.walk_cbdata) != 0) {
718fcf3ce44SJohn Forte 			irp = *((fct_i_remote_port_t **)ws.walk_cbdata);
719fcf3ce44SJohn Forte 			*((fct_i_remote_port_t **)ws.walk_cbdata) = NULL;
720fcf3ce44SJohn Forte 			return (irp);
721fcf3ce44SJohn Forte 		}
722fcf3ce44SJohn Forte 	}
723fcf3ce44SJohn Forte 	fct_irp_walk_f(&ws);
724fcf3ce44SJohn Forte 
725fcf3ce44SJohn Forte 	/*
726fcf3ce44SJohn Forte 	 * If it is WALK_DONE, there may be one remote port there
727fcf3ce44SJohn Forte 	 */
728fcf3ce44SJohn Forte 	if (ret == WALK_DONE) {
729fcf3ce44SJohn Forte 		irp = *((fct_i_remote_port_t **)ws.walk_cbdata);
730fcf3ce44SJohn Forte 		*((fct_i_remote_port_t **)ws.walk_cbdata) = NULL;
731fcf3ce44SJohn Forte 		return (irp);
732fcf3ce44SJohn Forte 	}
733fcf3ce44SJohn Forte 	return (NULL);
734fcf3ce44SJohn Forte }
735fcf3ce44SJohn Forte 
736fcf3ce44SJohn Forte static struct stmf_i_local_port *
irp_to_ilport(struct fct_i_remote_port * irpp)737fcf3ce44SJohn Forte irp_to_ilport(struct fct_i_remote_port *irpp)
738fcf3ce44SJohn Forte {
739fcf3ce44SJohn Forte 	struct fct_i_remote_port irp;
740fcf3ce44SJohn Forte 	struct fct_remote_port rp;
741fcf3ce44SJohn Forte 	struct fct_local_port port;
742fcf3ce44SJohn Forte 	struct stmf_local_port lport;
743fcf3ce44SJohn Forte 
744fcf3ce44SJohn Forte 	if (mdb_vread(&irp, sizeof (struct fct_i_remote_port),
745fcf3ce44SJohn Forte 	    (uintptr_t)irpp)
746fcf3ce44SJohn Forte 	    != sizeof (struct fct_i_remote_port)) {
747fcf3ce44SJohn Forte 		mdb_warn("Unable to read in fct_i_remote_port\n");
748fcf3ce44SJohn Forte 		return (NULL);
749fcf3ce44SJohn Forte 	}
750fcf3ce44SJohn Forte 	if (mdb_vread(&rp, sizeof (struct fct_remote_port),
751fcf3ce44SJohn Forte 	    (uintptr_t)irp.irp_rp)
752fcf3ce44SJohn Forte 	    != sizeof (struct fct_remote_port)) {
753fcf3ce44SJohn Forte 		mdb_warn("Unable to read in fct_remote_port\n");
754fcf3ce44SJohn Forte 		return (NULL);
755fcf3ce44SJohn Forte 	}
756fcf3ce44SJohn Forte 
757fcf3ce44SJohn Forte 	if (mdb_vread(&port, sizeof (struct fct_local_port),
758fcf3ce44SJohn Forte 	    (uintptr_t)rp.rp_port)
759fcf3ce44SJohn Forte 	    != sizeof (struct fct_local_port)) {
760fcf3ce44SJohn Forte 		mdb_warn("Unable to read in fct_local_port\n");
761fcf3ce44SJohn Forte 		return (NULL);
762fcf3ce44SJohn Forte 	}
763fcf3ce44SJohn Forte 	if (mdb_vread(&lport, sizeof (struct stmf_local_port),
764fcf3ce44SJohn Forte 	    (uintptr_t)port.port_lport)
765fcf3ce44SJohn Forte 	    != sizeof (struct stmf_local_port)) {
766fcf3ce44SJohn Forte 		mdb_warn("Unable to read in stmf_local_port\n");
767fcf3ce44SJohn Forte 		return (NULL);
768fcf3ce44SJohn Forte 	}
769fcf3ce44SJohn Forte 	return (lport.lport_stmf_private);
770fcf3ce44SJohn Forte }
771fcf3ce44SJohn Forte 
772fcf3ce44SJohn Forte /*
773fcf3ce44SJohn Forte  * by wwn, we may find more than one remote port, so we need to know its
774fcf3ce44SJohn Forte  * corresponding local port
775fcf3ce44SJohn Forte  */
776fcf3ce44SJohn Forte static struct fct_i_remote_port *
find_irp_by_wwn(struct stmf_i_local_port * siport,uint8_t wwn[8])777fcf3ce44SJohn Forte find_irp_by_wwn(struct stmf_i_local_port *siport, uint8_t wwn[8])
778fcf3ce44SJohn Forte {
779fcf3ce44SJohn Forte 	struct fct_i_local_port *fiport;
780fcf3ce44SJohn Forte 	fct_i_remote_port_t *irpp;
781fcf3ce44SJohn Forte 	struct fct_i_remote_port irp;
782fcf3ce44SJohn Forte 	struct fct_remote_port rp;
783fcf3ce44SJohn Forte 	fct_i_remote_port_t *ret = NULL;
784fcf3ce44SJohn Forte 
785fcf3ce44SJohn Forte 	fiport = __ilport2iport((uintptr_t)siport, DCMD_ADDRSPEC, 0, NULL);
786fcf3ce44SJohn Forte 	if (fiport == NULL)
787fcf3ce44SJohn Forte 		return (NULL);
788fcf3ce44SJohn Forte 
789fcf3ce44SJohn Forte 	while ((irpp = next_rport(fiport)) != NULL) {
790fcf3ce44SJohn Forte 		if (mdb_vread(&irp, sizeof (struct fct_i_remote_port),
791fcf3ce44SJohn Forte 		    (uintptr_t)irpp)
792fcf3ce44SJohn Forte 		    != sizeof (struct fct_i_remote_port)) {
793fcf3ce44SJohn Forte 			mdb_warn("Unable to read in fct_i_remote_port\n");
794fcf3ce44SJohn Forte 			break;
795fcf3ce44SJohn Forte 		}
796fcf3ce44SJohn Forte 		if (mdb_vread(&rp, sizeof (struct fct_remote_port),
797fcf3ce44SJohn Forte 		    (uintptr_t)irp.irp_rp)
798fcf3ce44SJohn Forte 		    != sizeof (struct fct_remote_port)) {
799fcf3ce44SJohn Forte 			mdb_warn("Unable to read in fct_remote_port\n");
800fcf3ce44SJohn Forte 			break;
801fcf3ce44SJohn Forte 		}
802fcf3ce44SJohn Forte 
803fcf3ce44SJohn Forte 		if (memcmp(rp.rp_pwwn, wwn, 8) == 0) {
804fcf3ce44SJohn Forte 			ret = irpp;
805fcf3ce44SJohn Forte 			break;
806fcf3ce44SJohn Forte 		}
807fcf3ce44SJohn Forte 	}
808*892ad162SToomas Soome 	cur_iport_for_irp_loop = 0;
809fcf3ce44SJohn Forte 	return (ret);
810fcf3ce44SJohn Forte }
811fcf3ce44SJohn Forte 
812fcf3ce44SJohn Forte /*ARGSUSED*/
813fcf3ce44SJohn Forte static int
stmf_find_fct_irp(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)814fcf3ce44SJohn Forte stmf_find_fct_irp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
815fcf3ce44SJohn Forte {
816fcf3ce44SJohn Forte 	struct stmf_i_local_port *siport;
817fcf3ce44SJohn Forte 	struct find_options *options;
818fcf3ce44SJohn Forte 	fct_i_remote_port_t *irpp;
819fcf3ce44SJohn Forte 	mdb_walk_state_t ws = {NULL, };
820fcf3ce44SJohn Forte 
821fcf3ce44SJohn Forte 	options = parse_options(argc, argv);
822fcf3ce44SJohn Forte 	/* need to free options manually ? */
823fcf3ce44SJohn Forte 	if (options == NULL || (options->rpname_defined == 0 &&
824fcf3ce44SJohn Forte 	    options->rp_defined == 0)) {
825fcf3ce44SJohn Forte 		mdb_printf("rpname=<wwn.12345678> or rp=<3000586778734>"
826fcf3ce44SJohn Forte 		    " should be specified\n");
827fcf3ce44SJohn Forte 		return (DCMD_OK);
828fcf3ce44SJohn Forte 	}
829fcf3ce44SJohn Forte 	if (options->rpname_defined && options->rp_defined) {
830fcf3ce44SJohn Forte 		mdb_printf("rpname=<wwn.12345678> or rp=<3000586778734>"
831fcf3ce44SJohn Forte 		    " should be specified, but not both\n");
832fcf3ce44SJohn Forte 		return (DCMD_OK);
833fcf3ce44SJohn Forte 	}
834fcf3ce44SJohn Forte 
835fcf3ce44SJohn Forte 	if (options->rp_defined) {
836fcf3ce44SJohn Forte 		siport = irp_to_ilport(options->rp);
837fcf3ce44SJohn Forte 		if (siport != NULL)
838fcf3ce44SJohn Forte 			mdb_printf("stmf_i_local_port=%p,"
839fcf3ce44SJohn Forte 			    " fct_i_remote_port=%p\n",
840fcf3ce44SJohn Forte 			    siport, options->rp);
841fcf3ce44SJohn Forte 		return (DCMD_OK);
842fcf3ce44SJohn Forte 	}
843fcf3ce44SJohn Forte 
844fcf3ce44SJohn Forte 	/* if options->rpname_defined */
845fcf3ce44SJohn Forte 	while ((siport = next_stmf_port(&ws)) != NULL) {
846fcf3ce44SJohn Forte 		if ((irpp = find_irp_by_wwn(siport, options->rpname)) != NULL)
847fcf3ce44SJohn Forte 			mdb_printf("stmf_i_local_port=%p, "
848fcf3ce44SJohn Forte 			    "fct_i_remote_port=%p\n",
849fcf3ce44SJohn Forte 			    siport, irpp);
850fcf3ce44SJohn Forte 	}
851fcf3ce44SJohn Forte 
852fcf3ce44SJohn Forte 	return (DCMD_OK);
853fcf3ce44SJohn Forte }
854fcf3ce44SJohn Forte 
855fcf3ce44SJohn Forte typedef void (*cmd_filter_t) (struct fct_i_cmd *,
856fcf3ce44SJohn Forte     struct find_options *, void *);
857fcf3ce44SJohn Forte 
858fcf3ce44SJohn Forte /*ARGSUSED*/
859fcf3ce44SJohn Forte static void
print_tasks(struct fct_i_cmd * icmdp,struct find_options * options,void * arg)860fcf3ce44SJohn Forte print_tasks(struct fct_i_cmd *icmdp, struct find_options *options, void *arg)
861fcf3ce44SJohn Forte {
862fcf3ce44SJohn Forte 	struct fct_i_cmd icmd;
863fcf3ce44SJohn Forte 	struct fct_cmd cmd;
864fcf3ce44SJohn Forte 
865fcf3ce44SJohn Forte 	if (mdb_vread(&icmd, sizeof (struct fct_i_cmd),
866fcf3ce44SJohn Forte 	    (uintptr_t)icmdp) != sizeof (struct fct_i_cmd)) {
867fcf3ce44SJohn Forte 		mdb_warn("Unable to read in fct_i_cmd\n");
868fcf3ce44SJohn Forte 		return;
869fcf3ce44SJohn Forte 	}
870fcf3ce44SJohn Forte 	if (mdb_vread(&cmd, sizeof (struct fct_cmd),
871fcf3ce44SJohn Forte 	    (uintptr_t)icmd.icmd_cmd) != sizeof (struct fct_cmd)) {
872fcf3ce44SJohn Forte 		mdb_warn("Unable to read in fct_cmd\n");
873fcf3ce44SJohn Forte 		return;
874fcf3ce44SJohn Forte 	}
875fcf3ce44SJohn Forte 
876fcf3ce44SJohn Forte 	if (cmd.cmd_type == FCT_CMD_FCP_XCHG) {
877fcf3ce44SJohn Forte 		struct scsi_task task;
878fcf3ce44SJohn Forte 		int colon_printed = 0;
879fcf3ce44SJohn Forte 
880fcf3ce44SJohn Forte 		if (mdb_vread(&task, sizeof (struct scsi_task),
881fcf3ce44SJohn Forte 		    (uintptr_t)cmd.cmd_specific)
882fcf3ce44SJohn Forte 		    != sizeof (struct scsi_task)) {
883fcf3ce44SJohn Forte 			mdb_warn("Unable to read in scsi_task\n");
884fcf3ce44SJohn Forte 			return;
885fcf3ce44SJohn Forte 		}
886fcf3ce44SJohn Forte 
887fcf3ce44SJohn Forte 		mdb_printf("%p", cmd.cmd_specific);
888fcf3ce44SJohn Forte 		if (options->show_task_flags) {
889fcf3ce44SJohn Forte 			mdb_printf(":");
890fcf3ce44SJohn Forte 			colon_printed = 1;
891fcf3ce44SJohn Forte 			mdb_printf(" task_flags=%x", task.task_flags);
892fcf3ce44SJohn Forte 		}
893fcf3ce44SJohn Forte 
894fcf3ce44SJohn Forte 		if (options->show_lport) {
895fcf3ce44SJohn Forte 			if (colon_printed == 0) {
896fcf3ce44SJohn Forte 				mdb_printf(":");
897fcf3ce44SJohn Forte 				colon_printed = 1;
898fcf3ce44SJohn Forte 			}
899fcf3ce44SJohn Forte 			mdb_printf(" lport=%p", task.task_lport);
900fcf3ce44SJohn Forte 		}
901fcf3ce44SJohn Forte 		mdb_printf("\n");
902fcf3ce44SJohn Forte 	}
903fcf3ce44SJohn Forte }
904fcf3ce44SJohn Forte 
905fcf3ce44SJohn Forte static void
print_tasks_on_rp(struct fct_i_cmd * icmdp,struct find_options * options,void * arg)906fcf3ce44SJohn Forte print_tasks_on_rp(struct fct_i_cmd *icmdp, struct find_options *options,
907fcf3ce44SJohn Forte     void *arg)
908fcf3ce44SJohn Forte {
909fcf3ce44SJohn Forte 	struct fct_i_cmd icmd;
910fcf3ce44SJohn Forte 	struct fct_cmd cmd;
911fcf3ce44SJohn Forte 	fct_i_remote_port_t irp;
912fcf3ce44SJohn Forte 
913fcf3ce44SJohn Forte 	if (mdb_vread(&icmd, sizeof (struct fct_i_cmd),
914fcf3ce44SJohn Forte 	    (uintptr_t)icmdp) != sizeof (struct fct_i_cmd)) {
915fcf3ce44SJohn Forte 		mdb_warn("Unable to read in fct_i_cmd\n");
916fcf3ce44SJohn Forte 		return;
917fcf3ce44SJohn Forte 	}
918fcf3ce44SJohn Forte 	if (mdb_vread(&cmd, sizeof (struct fct_cmd),
919fcf3ce44SJohn Forte 	    (uintptr_t)icmd.icmd_cmd) != sizeof (struct fct_cmd)) {
920fcf3ce44SJohn Forte 		mdb_warn("Unable to read in fct_cmd\n");
921fcf3ce44SJohn Forte 		return;
922fcf3ce44SJohn Forte 	}
923fcf3ce44SJohn Forte 
924fcf3ce44SJohn Forte 	/* arg is a pointer to fct_i_remote_port */
925fcf3ce44SJohn Forte 	if (mdb_vread(&irp, sizeof (struct fct_i_remote_port),
926fcf3ce44SJohn Forte 	    (uintptr_t)arg) != sizeof (struct fct_i_remote_port)) {
927fcf3ce44SJohn Forte 		mdb_warn("Unable to read in fct_i_remote_port\n");
928fcf3ce44SJohn Forte 		return;
929fcf3ce44SJohn Forte 	}
930fcf3ce44SJohn Forte 
931fcf3ce44SJohn Forte 	if (cmd.cmd_type == FCT_CMD_FCP_XCHG && cmd.cmd_rp == irp.irp_rp) {
932fcf3ce44SJohn Forte 		struct scsi_task task;
933fcf3ce44SJohn Forte 		int colon_printed = 0;
934fcf3ce44SJohn Forte 
935fcf3ce44SJohn Forte 		if (mdb_vread(&task, sizeof (struct scsi_task),
936fcf3ce44SJohn Forte 		    (uintptr_t)cmd.cmd_specific)
937fcf3ce44SJohn Forte 		    != sizeof (struct scsi_task)) {
938fcf3ce44SJohn Forte 			mdb_warn("Unable to read in scsi_task\n");
939fcf3ce44SJohn Forte 			return;
940fcf3ce44SJohn Forte 		}
941fcf3ce44SJohn Forte 
942fcf3ce44SJohn Forte 		mdb_printf("%p", cmd.cmd_specific);
943fcf3ce44SJohn Forte 		if (options->show_task_flags) {
944fcf3ce44SJohn Forte 			mdb_printf(":");
945fcf3ce44SJohn Forte 			colon_printed = 1;
946fcf3ce44SJohn Forte 			mdb_printf(" task_flags=%x", task.task_flags);
947fcf3ce44SJohn Forte 		}
948fcf3ce44SJohn Forte 
949fcf3ce44SJohn Forte 		if (options->show_lport) {
950fcf3ce44SJohn Forte 			if (colon_printed == 0) {
951fcf3ce44SJohn Forte 				mdb_printf(":");
952fcf3ce44SJohn Forte 				colon_printed = 1;
953fcf3ce44SJohn Forte 			}
954fcf3ce44SJohn Forte 			mdb_printf(" lport=%p", task.task_lport);
955fcf3ce44SJohn Forte 		}
956fcf3ce44SJohn Forte 		mdb_printf("\n");
957fcf3ce44SJohn Forte 	}
958fcf3ce44SJohn Forte }
959fcf3ce44SJohn Forte 
960fcf3ce44SJohn Forte /*ARGSUSED*/
961fcf3ce44SJohn Forte static void
print_all_cmds(struct fct_i_cmd * icmd,struct find_options * options,void * arg)962fcf3ce44SJohn Forte print_all_cmds(struct fct_i_cmd *icmd, struct find_options *options, void *arg)
963fcf3ce44SJohn Forte {
964fcf3ce44SJohn Forte 	mdb_printf("%p\n", icmd);
965fcf3ce44SJohn Forte }
966fcf3ce44SJohn Forte 
967fcf3ce44SJohn Forte /*
968fcf3ce44SJohn Forte  * find outstanding cmds (fct_i_cmd) on local port
969fcf3ce44SJohn Forte  */
970fcf3ce44SJohn Forte static int
outstanding_cmds_on_lport(struct stmf_i_local_port * siport,cmd_filter_t filter,struct find_options * options,void * arg)971fcf3ce44SJohn Forte outstanding_cmds_on_lport(struct stmf_i_local_port *siport, cmd_filter_t filter,
972fcf3ce44SJohn Forte     struct find_options *options, void *arg)
973fcf3ce44SJohn Forte {
974fcf3ce44SJohn Forte 	struct fct_i_local_port *iportp;
975fcf3ce44SJohn Forte 	struct fct_i_local_port iport;
976fcf3ce44SJohn Forte 	struct fct_local_port port;
977fcf3ce44SJohn Forte 	struct fct_cmd_slot *slotp;
978fcf3ce44SJohn Forte 	struct fct_cmd_slot slot;
979fcf3ce44SJohn Forte 	int i;
980fcf3ce44SJohn Forte 
981fcf3ce44SJohn Forte 	iportp = __ilport2iport((uintptr_t)siport, DCMD_ADDRSPEC, 0, NULL);
982fcf3ce44SJohn Forte 	if (iportp == NULL)
983fcf3ce44SJohn Forte 		return (DCMD_ERR);
984fcf3ce44SJohn Forte 
985fcf3ce44SJohn Forte 	if (mdb_vread(&iport, sizeof (struct fct_i_local_port),
986fcf3ce44SJohn Forte 	    (uintptr_t)iportp) != sizeof (struct fct_i_local_port)) {
987fcf3ce44SJohn Forte 		mdb_warn("Unable to read in fct_i_local_port\n");
988fcf3ce44SJohn Forte 		return (DCMD_ERR);
989fcf3ce44SJohn Forte 	}
990fcf3ce44SJohn Forte 	if (mdb_vread(&port, sizeof (struct fct_local_port),
991fcf3ce44SJohn Forte 	    (uintptr_t)iport.iport_port) != sizeof (struct fct_local_port)) {
992fcf3ce44SJohn Forte 		mdb_warn("Unable to read in fct_local_port\n");
993fcf3ce44SJohn Forte 		return (DCMD_ERR);
994fcf3ce44SJohn Forte 	}
995fcf3ce44SJohn Forte 
996fcf3ce44SJohn Forte 	slotp = iport.iport_cmd_slots;
997fcf3ce44SJohn Forte 	for (i = 0; i < port.port_max_xchges; i++) {
998fcf3ce44SJohn Forte 		if (mdb_vread(&slot, sizeof (struct fct_cmd_slot),
999fcf3ce44SJohn Forte 		    (uintptr_t)slotp) != sizeof (struct fct_cmd_slot)) {
1000fcf3ce44SJohn Forte 			mdb_warn("Unable to read in fct_cmd_slot\n");
1001fcf3ce44SJohn Forte 			return (DCMD_ERR);
1002fcf3ce44SJohn Forte 		}
1003fcf3ce44SJohn Forte 		if (slot.slot_cmd != NULL) {
1004fcf3ce44SJohn Forte 			if (filter == NULL)
1005fcf3ce44SJohn Forte 				mdb_printf("%p\n", slot.slot_cmd);
1006fcf3ce44SJohn Forte 			else
1007fcf3ce44SJohn Forte 				filter(slot.slot_cmd, options, arg);
1008fcf3ce44SJohn Forte 		}
1009fcf3ce44SJohn Forte 		slotp ++;
1010fcf3ce44SJohn Forte 	}
1011fcf3ce44SJohn Forte 
1012fcf3ce44SJohn Forte 	return (DCMD_OK);
1013fcf3ce44SJohn Forte }
1014fcf3ce44SJohn Forte 
1015fcf3ce44SJohn Forte /*ARGSUSED*/
1016fcf3ce44SJohn Forte static int
stmf_find_tasks(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1017fcf3ce44SJohn Forte stmf_find_tasks(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1018fcf3ce44SJohn Forte {
1019fcf3ce44SJohn Forte 	struct find_options *options;
1020fcf3ce44SJohn Forte 	struct stmf_i_local_port *siport;
1021fcf3ce44SJohn Forte 
1022fcf3ce44SJohn Forte 	options = parse_options(argc, argv);
1023fcf3ce44SJohn Forte 	if (options == NULL ||
1024fcf3ce44SJohn Forte 	    (options->lpname_defined == 0 && options->rpname_defined == 0)) {
1025fcf3ce44SJohn Forte 		mdb_printf("lpname=<wwn.12345678> or rpname=<wwn.12345678>"
1026fcf3ce44SJohn Forte 		    " should be specified\n");
1027fcf3ce44SJohn Forte 		return (DCMD_OK);
1028fcf3ce44SJohn Forte 	}
1029fcf3ce44SJohn Forte 
1030fcf3ce44SJohn Forte 	if (options->lpname_defined) {
1031fcf3ce44SJohn Forte 		siport = find_lport_by_wwn(options->lpname);
1032fcf3ce44SJohn Forte 		if (siport == NULL)
1033fcf3ce44SJohn Forte 			return (DCMD_ERR);
1034fcf3ce44SJohn Forte 
1035fcf3ce44SJohn Forte 		outstanding_cmds_on_lport(siport, print_tasks, options, NULL);
1036fcf3ce44SJohn Forte 		return (DCMD_OK);
1037fcf3ce44SJohn Forte 	}
1038fcf3ce44SJohn Forte 
1039fcf3ce44SJohn Forte 	if (options->rpname_defined) {
1040fcf3ce44SJohn Forte 		mdb_walk_state_t ws = {NULL, };
1041fcf3ce44SJohn Forte 		fct_i_remote_port_t *irpp;
1042fcf3ce44SJohn Forte 
1043fcf3ce44SJohn Forte 		while ((siport = next_stmf_port(&ws)) != NULL) {
1044fcf3ce44SJohn Forte 			if ((irpp = find_irp_by_wwn(siport, options->rpname))
1045fcf3ce44SJohn Forte 			    != NULL) {
1046fcf3ce44SJohn Forte 				outstanding_cmds_on_lport(siport,
1047fcf3ce44SJohn Forte 				    print_tasks_on_rp, options, irpp);
1048fcf3ce44SJohn Forte 			}
1049fcf3ce44SJohn Forte 		}
1050fcf3ce44SJohn Forte 	}
1051fcf3ce44SJohn Forte 
1052fcf3ce44SJohn Forte 	return (DCMD_OK);
1053fcf3ce44SJohn Forte }
1054fcf3ce44SJohn Forte 
1055fcf3ce44SJohn Forte /*ARGSUSED*/
1056fcf3ce44SJohn Forte static int
fct_find_cmds(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1057fcf3ce44SJohn Forte fct_find_cmds(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1058fcf3ce44SJohn Forte {
1059fcf3ce44SJohn Forte 	struct find_options *options;
1060fcf3ce44SJohn Forte 	struct stmf_i_local_port *siport;
1061fcf3ce44SJohn Forte 
1062fcf3ce44SJohn Forte 	options = parse_options(argc, argv);
1063fcf3ce44SJohn Forte 	if (options == NULL || options->lpname_defined == 0) {
1064fcf3ce44SJohn Forte 		mdb_printf("lpname=<wwn.12345678> should be specified\n");
1065fcf3ce44SJohn Forte 		return (DCMD_OK);
1066fcf3ce44SJohn Forte 	}
1067fcf3ce44SJohn Forte 
1068fcf3ce44SJohn Forte 	siport = find_lport_by_wwn(options->lpname);
1069fcf3ce44SJohn Forte 	if (siport == NULL)
1070fcf3ce44SJohn Forte 		return (DCMD_ERR);
1071fcf3ce44SJohn Forte 
1072fcf3ce44SJohn Forte 	outstanding_cmds_on_lport(siport, print_all_cmds, options, NULL);
1073fcf3ce44SJohn Forte 	return (DCMD_OK);
1074fcf3ce44SJohn Forte }
1075fcf3ce44SJohn Forte 
1076fcf3ce44SJohn Forte static int
fct_icmds(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1077fcf3ce44SJohn Forte fct_icmds(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1078fcf3ce44SJohn Forte {
1079fcf3ce44SJohn Forte 	struct fct_i_local_port iport;
1080fcf3ce44SJohn Forte 	struct fct_i_cmd icmd;
1081fcf3ce44SJohn Forte 	struct fct_i_cmd *icmdp;
1082fcf3ce44SJohn Forte 	int i;
1083fcf3ce44SJohn Forte 	int verbose = 0;
1084fcf3ce44SJohn Forte 
1085fcf3ce44SJohn Forte 	for (i = 0; i < argc; i++) {
1086fcf3ce44SJohn Forte 		char *ptr = (char *)argv[i].a_un.a_str;
1087fcf3ce44SJohn Forte 
1088fcf3ce44SJohn Forte 		if (ptr[0] == '-')
1089fcf3ce44SJohn Forte 			ptr++;
1090fcf3ce44SJohn Forte 		while (*ptr) {
1091fcf3ce44SJohn Forte 			if (*ptr == 'v')
1092fcf3ce44SJohn Forte 				verbose = 1;
1093fcf3ce44SJohn Forte 			ptr++;
1094fcf3ce44SJohn Forte 		}
1095fcf3ce44SJohn Forte 	}
1096fcf3ce44SJohn Forte 
1097fcf3ce44SJohn Forte 	if (!(flags & DCMD_ADDRSPEC)) {
1098fcf3ce44SJohn Forte 		mdb_warn("fct_i_local_port_t address should be specified");
1099fcf3ce44SJohn Forte 		return (DCMD_ERR);
1100fcf3ce44SJohn Forte 	}
1101fcf3ce44SJohn Forte 
1102fcf3ce44SJohn Forte 	if (mdb_vread(&iport, sizeof (struct fct_i_local_port), addr)
1103fcf3ce44SJohn Forte 	    != sizeof (struct fct_i_local_port)) {
1104fcf3ce44SJohn Forte 		mdb_warn("Unable to read in fct_i_local_port at %p\n", addr);
1105fcf3ce44SJohn Forte 		return (DCMD_ERR);
1106fcf3ce44SJohn Forte 	}
1107fcf3ce44SJohn Forte 
1108fcf3ce44SJohn Forte 	icmdp = iport.iport_cached_cmdlist;
1109fcf3ce44SJohn Forte 	while (icmdp) {
1110fcf3ce44SJohn Forte 		if (mdb_vread(&icmd, sizeof (struct fct_i_cmd),
1111fcf3ce44SJohn Forte 		    (uintptr_t)icmdp) == -1) {
1112fcf3ce44SJohn Forte 			mdb_warn("failed to read fct_i_cmd at %p", icmdp);
1113fcf3ce44SJohn Forte 			return (DCMD_ERR);
1114fcf3ce44SJohn Forte 		}
1115fcf3ce44SJohn Forte 
1116fcf3ce44SJohn Forte 		mdb_printf("%p\n", icmdp);
1117fcf3ce44SJohn Forte 		if (verbose) {
1118fcf3ce44SJohn Forte 			mdb_printf("  fct cmd: %p\n", icmd.icmd_cmd);
1119fcf3ce44SJohn Forte 		}
1120fcf3ce44SJohn Forte 
1121fcf3ce44SJohn Forte 		icmdp = icmd.icmd_next;
1122fcf3ce44SJohn Forte 	}
1123fcf3ce44SJohn Forte 
1124fcf3ce44SJohn Forte 	return (DCMD_OK);
1125fcf3ce44SJohn Forte }
1126fcf3ce44SJohn Forte 
11278d2b0ea9SPriya Krishnan /*
11288d2b0ea9SPriya Krishnan  * Walker to list the addresses of all the active STMF scsi tasks (scsi_task_t),
11298d2b0ea9SPriya Krishnan  * given a stmf_worker address
11308d2b0ea9SPriya Krishnan  *
11318d2b0ea9SPriya Krishnan  * To list all the active STMF scsi tasks, use
11328d2b0ea9SPriya Krishnan  * "::walk stmf_worker |::walk stmf_scsi_task"
11338d2b0ea9SPriya Krishnan  * To list the active tasks of a particular worker, use
11348d2b0ea9SPriya Krishnan  * <stmf_worker addr>::walk stmf_scsi_task
11358d2b0ea9SPriya Krishnan  */
11368d2b0ea9SPriya Krishnan static int
stmf_scsi_task_walk_init(mdb_walk_state_t * wsp)11378d2b0ea9SPriya Krishnan stmf_scsi_task_walk_init(mdb_walk_state_t *wsp)
11388d2b0ea9SPriya Krishnan {
11398d2b0ea9SPriya Krishnan 	stmf_worker_t	worker;
11408d2b0ea9SPriya Krishnan 
11418d2b0ea9SPriya Krishnan 	/*
11428d2b0ea9SPriya Krishnan 	 * Input should be a stmf_worker, so read it to get the
11438d2b0ea9SPriya Krishnan 	 * worker_task_head to get the start of the task list
11448d2b0ea9SPriya Krishnan 	 */
1145*892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
11468d2b0ea9SPriya Krishnan 		mdb_warn("<worker addr>::walk stmf_scsi_task\n");
11478d2b0ea9SPriya Krishnan 		return (WALK_ERR);
11488d2b0ea9SPriya Krishnan 	}
11498d2b0ea9SPriya Krishnan 
11508d2b0ea9SPriya Krishnan 	if (mdb_vread(&worker, sizeof (stmf_worker_t), wsp->walk_addr) !=
11518d2b0ea9SPriya Krishnan 	    sizeof (stmf_worker_t)) {
11528d2b0ea9SPriya Krishnan 		mdb_warn("failed to read in the task address\n");
11538d2b0ea9SPriya Krishnan 		return (WALK_ERR);
11548d2b0ea9SPriya Krishnan 	}
11558d2b0ea9SPriya Krishnan 
11568d2b0ea9SPriya Krishnan 	wsp->walk_addr = (uintptr_t)(worker.worker_task_head);
11578d2b0ea9SPriya Krishnan 	wsp->walk_data = mdb_alloc(sizeof (scsi_task_t), UM_SLEEP);
11588d2b0ea9SPriya Krishnan 
11598d2b0ea9SPriya Krishnan 	return (WALK_NEXT);
11608d2b0ea9SPriya Krishnan }
11618d2b0ea9SPriya Krishnan 
11628d2b0ea9SPriya Krishnan static int
stmf_scsi_task_walk_step(mdb_walk_state_t * wsp)11638d2b0ea9SPriya Krishnan stmf_scsi_task_walk_step(mdb_walk_state_t *wsp)
11648d2b0ea9SPriya Krishnan {
11658d2b0ea9SPriya Krishnan 	stmf_i_scsi_task_t	itask;
11668d2b0ea9SPriya Krishnan 	int			status;
11678d2b0ea9SPriya Krishnan 
1168*892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
11698d2b0ea9SPriya Krishnan 		return (WALK_DONE);
11708d2b0ea9SPriya Krishnan 	}
11718d2b0ea9SPriya Krishnan 
11728d2b0ea9SPriya Krishnan 	/* Save the stmf_i_scsi_task for use later to get the next entry */
11738d2b0ea9SPriya Krishnan 	if (mdb_vread(&itask, sizeof (stmf_i_scsi_task_t),
11748d2b0ea9SPriya Krishnan 	    wsp->walk_addr) != sizeof (stmf_i_scsi_task_t)) {
11758d2b0ea9SPriya Krishnan 		mdb_warn("failed to read stmf_i_scsi_task at %p",
11768d2b0ea9SPriya Krishnan 		    wsp->walk_addr);
11778d2b0ea9SPriya Krishnan 		return (WALK_DONE);
11788d2b0ea9SPriya Krishnan 	}
11798d2b0ea9SPriya Krishnan 
11808d2b0ea9SPriya Krishnan 	wsp->walk_addr = (uintptr_t)itask.itask_task;
11818d2b0ea9SPriya Krishnan 
11828d2b0ea9SPriya Krishnan 	if (mdb_vread(wsp->walk_data, sizeof (scsi_task_t),
11838d2b0ea9SPriya Krishnan 	    wsp->walk_addr) != sizeof (scsi_task_t)) {
11848d2b0ea9SPriya Krishnan 		mdb_warn("failed to read scsi_task_t at %p", wsp->walk_addr);
11858d2b0ea9SPriya Krishnan 		return (DCMD_ERR);
11868d2b0ea9SPriya Krishnan 	}
11878d2b0ea9SPriya Krishnan 
11888d2b0ea9SPriya Krishnan 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
11898d2b0ea9SPriya Krishnan 	    wsp->walk_cbdata);
11908d2b0ea9SPriya Krishnan 
11918d2b0ea9SPriya Krishnan 	wsp->walk_addr = (uintptr_t)(itask.itask_worker_next);
11928d2b0ea9SPriya Krishnan 
11938d2b0ea9SPriya Krishnan 	return (status);
11948d2b0ea9SPriya Krishnan }
11958d2b0ea9SPriya Krishnan 
11968d2b0ea9SPriya Krishnan static void
stmf_scsi_task_walk_fini(mdb_walk_state_t * wsp)11978d2b0ea9SPriya Krishnan stmf_scsi_task_walk_fini(mdb_walk_state_t *wsp)
11988d2b0ea9SPriya Krishnan {
11998d2b0ea9SPriya Krishnan 	mdb_free(wsp->walk_data, sizeof (scsi_task_t));
12008d2b0ea9SPriya Krishnan }
12018d2b0ea9SPriya Krishnan 
12028d2b0ea9SPriya Krishnan /*ARGSUSED*/
12038d2b0ea9SPriya Krishnan static int
stmf_scsi_task(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)12048d2b0ea9SPriya Krishnan stmf_scsi_task(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
12058d2b0ea9SPriya Krishnan {
12068d2b0ea9SPriya Krishnan 	stmf_worker_t		worker;
12078d2b0ea9SPriya Krishnan 	stmf_i_scsi_task_t	itask;
12088d2b0ea9SPriya Krishnan 	scsi_task_t		*task_addr, task;
12098d2b0ea9SPriya Krishnan 
12108d2b0ea9SPriya Krishnan 	/*
12118d2b0ea9SPriya Krishnan 	 * A stmf_worker address is given to the left of ::stmf_scsi_task
12128d2b0ea9SPriya Krishnan 	 * i.e. display the scsi_task for the given worker
12138d2b0ea9SPriya Krishnan 	 */
12148d2b0ea9SPriya Krishnan 	if (!(flags & DCMD_ADDRSPEC)) {
12158d2b0ea9SPriya Krishnan 		if (mdb_walk_dcmd("stmf_worker", "stmf_scsi_task", argc,
12168d2b0ea9SPriya Krishnan 		    argv) == -1) {
12178d2b0ea9SPriya Krishnan 			mdb_warn("Failed to walk the stmf_scsi_task entries");
12188d2b0ea9SPriya Krishnan 			return (DCMD_ERR);
12198d2b0ea9SPriya Krishnan 		}
12208d2b0ea9SPriya Krishnan 		return (DCMD_OK);
12218d2b0ea9SPriya Krishnan 	}
12228d2b0ea9SPriya Krishnan 
12238d2b0ea9SPriya Krishnan 	if (DCMD_HDRSPEC(flags) && (!(flags & DCMD_PIPE_OUT))) {
12248d2b0ea9SPriya Krishnan 		mdb_printf("%<u>%-19s %-10s %-19s%</u>\n",
12258d2b0ea9SPriya Krishnan 		    "scsi_task_t", "Flags", "LPort");
12268d2b0ea9SPriya Krishnan 	}
12278d2b0ea9SPriya Krishnan 
12288d2b0ea9SPriya Krishnan 	if (mdb_vread(&worker, sizeof (stmf_worker_t),
12298d2b0ea9SPriya Krishnan 	    addr) != sizeof (stmf_worker_t)) {
12308d2b0ea9SPriya Krishnan 		mdb_warn("failed to read in the worker address");
12318d2b0ea9SPriya Krishnan 		return (DCMD_ERR);
12328d2b0ea9SPriya Krishnan 	}
12338d2b0ea9SPriya Krishnan 
12348d2b0ea9SPriya Krishnan 	/* Read the scsi_task */
12358d2b0ea9SPriya Krishnan 	if (worker.worker_task_head == NULL) {
12368d2b0ea9SPriya Krishnan 		return (DCMD_OK);
12378d2b0ea9SPriya Krishnan 	}
12388d2b0ea9SPriya Krishnan 
12398d2b0ea9SPriya Krishnan 	if (mdb_vread(&itask, sizeof (stmf_i_scsi_task_t),
12408d2b0ea9SPriya Krishnan 	    (uintptr_t)worker.worker_task_head) == -1) {
12418d2b0ea9SPriya Krishnan 		mdb_warn("failed to read stmf_i_scsi_task_t at %p",
12428d2b0ea9SPriya Krishnan 		    worker.worker_task_head);
12438d2b0ea9SPriya Krishnan 		return (DCMD_ERR);
12448d2b0ea9SPriya Krishnan 	}
12458d2b0ea9SPriya Krishnan 
12468d2b0ea9SPriya Krishnan 	task_addr = itask.itask_task;
12478d2b0ea9SPriya Krishnan 
12488d2b0ea9SPriya Krishnan 	if (mdb_vread(&task, sizeof (scsi_task_t),
12498d2b0ea9SPriya Krishnan 	    (uintptr_t)task_addr) != sizeof (scsi_task_t)) {
12508d2b0ea9SPriya Krishnan 		mdb_warn("failed to read scsi_task_t at %p", task_addr);
12518d2b0ea9SPriya Krishnan 		return (DCMD_ERR);
12528d2b0ea9SPriya Krishnan 	}
12538d2b0ea9SPriya Krishnan 
12548d2b0ea9SPriya Krishnan 	if ((flags & DCMD_PIPE_OUT)) {
12558d2b0ea9SPriya Krishnan 		mdb_printf("%p\n", task_addr);
12568d2b0ea9SPriya Krishnan 	} else {
12578d2b0ea9SPriya Krishnan 		/* pretty print */
12588d2b0ea9SPriya Krishnan 		mdb_printf("%-19p %-10x %-19p\n",
12598d2b0ea9SPriya Krishnan 		    task_addr, task.task_flags, task.task_lport);
12608d2b0ea9SPriya Krishnan 	}
12618d2b0ea9SPriya Krishnan 
12628d2b0ea9SPriya Krishnan 	return (DCMD_OK);
12638d2b0ea9SPriya Krishnan }
12648d2b0ea9SPriya Krishnan 
12658d2b0ea9SPriya Krishnan /*
12668d2b0ea9SPriya Krishnan  * Walker to list the addresses of all the stmf_worker in the queue
12678d2b0ea9SPriya Krishnan  */
12688d2b0ea9SPriya Krishnan typedef struct stmf_worker_walk_data {
12698d2b0ea9SPriya Krishnan 	int		worker_current;
12708d2b0ea9SPriya Krishnan 	int		worker_count;
12718d2b0ea9SPriya Krishnan } stmf_worker_walk_data_t;
12728d2b0ea9SPriya Krishnan 
12738d2b0ea9SPriya Krishnan /* stmf_workers_state definition from stmf.c (static) */
12748d2b0ea9SPriya Krishnan enum {
12758d2b0ea9SPriya Krishnan 	STMF_WORKERS_DISABLED = 0,
12768d2b0ea9SPriya Krishnan 	STMF_WORKERS_ENABLING,
12778d2b0ea9SPriya Krishnan 	STMF_WORKERS_ENABLED
12788d2b0ea9SPriya Krishnan } stmf_workers_state;
12798d2b0ea9SPriya Krishnan 
12808d2b0ea9SPriya Krishnan /*
12818d2b0ea9SPriya Krishnan  * Initialize the stmf_worker_t walker by either using the given starting
12828d2b0ea9SPriya Krishnan  * address, or reading the value of the kernel's global stmf_workers pointer.
12838d2b0ea9SPriya Krishnan  */
12848d2b0ea9SPriya Krishnan /*ARGSUSED*/
12858d2b0ea9SPriya Krishnan static int
stmf_worker_walk_init(mdb_walk_state_t * wsp)12868d2b0ea9SPriya Krishnan stmf_worker_walk_init(mdb_walk_state_t *wsp)
12878d2b0ea9SPriya Krishnan {
12888d2b0ea9SPriya Krishnan 	int			worker_state;
12898d2b0ea9SPriya Krishnan 	int			nworkers;
12908d2b0ea9SPriya Krishnan 	stmf_worker_t		*worker;
12918d2b0ea9SPriya Krishnan 	stmf_worker_walk_data_t	*walk_data;
12928d2b0ea9SPriya Krishnan 
12938d2b0ea9SPriya Krishnan 	if (mdb_readvar(&worker_state, "stmf_workers_state") == -1) {
12948d2b0ea9SPriya Krishnan 		mdb_warn("failed to read stmf_workers_state");
12958d2b0ea9SPriya Krishnan 		return (WALK_ERR);
12968d2b0ea9SPriya Krishnan 	}
12978d2b0ea9SPriya Krishnan 	if (worker_state != STMF_WORKERS_ENABLED) {
12988d2b0ea9SPriya Krishnan 		mdb_warn("stmf_workers_state not initialized");
12998d2b0ea9SPriya Krishnan 		return (WALK_ERR);
13008d2b0ea9SPriya Krishnan 	}
13018d2b0ea9SPriya Krishnan 
13028d2b0ea9SPriya Krishnan 	/*
13038d2b0ea9SPriya Krishnan 	 * Look up the stmf_nworkers_accepting_cmds to
13048d2b0ea9SPriya Krishnan 	 * determine number of entries in the worker queue
13058d2b0ea9SPriya Krishnan 	 */
13068d2b0ea9SPriya Krishnan 	if (mdb_readvar(&nworkers, "stmf_nworkers_accepting_cmds") == -1) {
13078d2b0ea9SPriya Krishnan 		mdb_warn("failed to read stmf_nworkers_accepting_cmds");
13088d2b0ea9SPriya Krishnan 		return (WALK_ERR);
13098d2b0ea9SPriya Krishnan 	}
13108d2b0ea9SPriya Krishnan 
13118d2b0ea9SPriya Krishnan 	if (mdb_readvar(&worker, "stmf_workers") == -1) {
13128d2b0ea9SPriya Krishnan 		mdb_warn("failed to read stmf_workers");
13138d2b0ea9SPriya Krishnan 		return (WALK_ERR);
13148d2b0ea9SPriya Krishnan 	}
13158d2b0ea9SPriya Krishnan 
13168d2b0ea9SPriya Krishnan 	walk_data = mdb_alloc(sizeof (stmf_worker_walk_data_t), UM_SLEEP);
13178d2b0ea9SPriya Krishnan 	walk_data->worker_current	= 0;
13188d2b0ea9SPriya Krishnan 	walk_data->worker_count		= nworkers;
13198d2b0ea9SPriya Krishnan 
13208d2b0ea9SPriya Krishnan 	wsp->walk_addr = (uintptr_t)worker;
13218d2b0ea9SPriya Krishnan 	wsp->walk_data = walk_data;
13228d2b0ea9SPriya Krishnan 
13238d2b0ea9SPriya Krishnan 	return (WALK_NEXT);
13248d2b0ea9SPriya Krishnan }
13258d2b0ea9SPriya Krishnan 
13268d2b0ea9SPriya Krishnan static int
stmf_worker_walk_step(mdb_walk_state_t * wsp)13278d2b0ea9SPriya Krishnan stmf_worker_walk_step(mdb_walk_state_t *wsp)
13288d2b0ea9SPriya Krishnan {
13298d2b0ea9SPriya Krishnan 	stmf_worker_walk_data_t	*walk_data = wsp->walk_data;
13308d2b0ea9SPriya Krishnan 	int			status;
13318d2b0ea9SPriya Krishnan 
1332*892ad162SToomas Soome 	if (wsp->walk_addr == 0) {
13338d2b0ea9SPriya Krishnan 		return (WALK_DONE);
13348d2b0ea9SPriya Krishnan 	}
13358d2b0ea9SPriya Krishnan 
13368d2b0ea9SPriya Krishnan 	if (walk_data->worker_current >= walk_data->worker_count) {
13378d2b0ea9SPriya Krishnan 		return (WALK_DONE);
13388d2b0ea9SPriya Krishnan 	}
13398d2b0ea9SPriya Krishnan 
13408d2b0ea9SPriya Krishnan 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
13418d2b0ea9SPriya Krishnan 	    wsp->walk_cbdata);
13428d2b0ea9SPriya Krishnan 
13438d2b0ea9SPriya Krishnan 	walk_data->worker_current++;
13448d2b0ea9SPriya Krishnan 	wsp->walk_addr += sizeof (stmf_worker_t);
13458d2b0ea9SPriya Krishnan 
13468d2b0ea9SPriya Krishnan 	return (status);
13478d2b0ea9SPriya Krishnan }
13488d2b0ea9SPriya Krishnan 
13498d2b0ea9SPriya Krishnan static void
stmf_worker_walk_fini(mdb_walk_state_t * wsp)13508d2b0ea9SPriya Krishnan stmf_worker_walk_fini(mdb_walk_state_t *wsp)
13518d2b0ea9SPriya Krishnan {
13528d2b0ea9SPriya Krishnan 	mdb_free(wsp->walk_data, sizeof (stmf_worker_walk_data_t));
13538d2b0ea9SPriya Krishnan }
13548d2b0ea9SPriya Krishnan 
13558d2b0ea9SPriya Krishnan int
stmf_worker(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)13568d2b0ea9SPriya Krishnan stmf_worker(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
13578d2b0ea9SPriya Krishnan {
13588d2b0ea9SPriya Krishnan 	stmf_worker_t		worker;
13598d2b0ea9SPriya Krishnan 
13608d2b0ea9SPriya Krishnan 	if (!(flags & DCMD_ADDRSPEC)) {
13618d2b0ea9SPriya Krishnan 		if (mdb_walk_dcmd("stmf_worker", "stmf_worker", argc,
13628d2b0ea9SPriya Krishnan 		    argv) == -1) {
13638d2b0ea9SPriya Krishnan 			mdb_warn("Failed to walk the stmf_worker entries");
13648d2b0ea9SPriya Krishnan 			return (DCMD_ERR);
13658d2b0ea9SPriya Krishnan 		}
13668d2b0ea9SPriya Krishnan 		return (DCMD_OK);
13678d2b0ea9SPriya Krishnan 	}
13688d2b0ea9SPriya Krishnan 
13698d2b0ea9SPriya Krishnan 	if (mdb_vread(&worker, sizeof (stmf_worker_t),
13708d2b0ea9SPriya Krishnan 	    addr) != sizeof (stmf_worker_t)) {
13718d2b0ea9SPriya Krishnan 		mdb_warn("failed to read stmf_worker at %p", addr);
13728d2b0ea9SPriya Krishnan 		return (DCMD_ERR);
13738d2b0ea9SPriya Krishnan 	}
13748d2b0ea9SPriya Krishnan 
13758d2b0ea9SPriya Krishnan 	if (flags & DCMD_PIPE_OUT) {
13768d2b0ea9SPriya Krishnan 		mdb_printf("%-19p\n", addr);
13778d2b0ea9SPriya Krishnan 	} else {
13788d2b0ea9SPriya Krishnan 		/* pretty print */
13798d2b0ea9SPriya Krishnan 		if (DCMD_HDRSPEC(flags)) {
13808d2b0ea9SPriya Krishnan 			mdb_printf("%<u>%-19s %-10s %-10s %-10s%</u>\n",
13818d2b0ea9SPriya Krishnan 			    "stmf_worker_t", "State", "Ref_Count", "Tasks");
13828d2b0ea9SPriya Krishnan 		}
13838d2b0ea9SPriya Krishnan 
13848d2b0ea9SPriya Krishnan 		mdb_printf("%-19p %-10s %-10d %-5d%\n", addr,
13858d2b0ea9SPriya Krishnan 		    (worker.worker_flags == STMF_WORKER_STARTED) ? "STARTED" :
138694360ae1SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		    (worker.worker_flags & STMF_WORKER_ACTIVE) ?
13878d2b0ea9SPriya Krishnan 		    "ACTIVE" : "TERMINATED",
13888d2b0ea9SPriya Krishnan 		    worker.worker_ref_count,
13898d2b0ea9SPriya Krishnan 		    worker.worker_queue_depth);
13908d2b0ea9SPriya Krishnan 	}
13918d2b0ea9SPriya Krishnan 
13928d2b0ea9SPriya Krishnan 	return (DCMD_OK);
13938d2b0ea9SPriya Krishnan }
13948d2b0ea9SPriya Krishnan 
1395fcf3ce44SJohn Forte struct find_options *
parse_options(int argc,const mdb_arg_t * argv)1396fcf3ce44SJohn Forte parse_options(int argc, const mdb_arg_t *argv)
1397fcf3ce44SJohn Forte {
1398fcf3ce44SJohn Forte 	int i;
1399fcf3ce44SJohn Forte 	struct find_options *options;
1400fcf3ce44SJohn Forte 	int len;
1401fcf3ce44SJohn Forte 	char *ptr;
1402fcf3ce44SJohn Forte 	int ret;
1403fcf3ce44SJohn Forte 
1404fcf3ce44SJohn Forte 	if (argc == 0)
1405fcf3ce44SJohn Forte 		return (NULL);
1406fcf3ce44SJohn Forte 	options = mdb_zalloc(sizeof (struct find_options), UM_SLEEP);
1407fcf3ce44SJohn Forte 	for (i = 0; i < argc; i++) {
1408fcf3ce44SJohn Forte 		switch (argv[i].a_type) {
1409fcf3ce44SJohn Forte 		case MDB_TYPE_STRING:
1410fcf3ce44SJohn Forte 			break;
1411fcf3ce44SJohn Forte 		case MDB_TYPE_IMMEDIATE:
1412fcf3ce44SJohn Forte 		case MDB_TYPE_CHAR:
1413fcf3ce44SJohn Forte 			mdb_printf("unknown type\n");
1414fcf3ce44SJohn Forte 		}
1415fcf3ce44SJohn Forte 		if ((ptr = strchr(argv[i].a_un.a_str, '=')) == NULL) {
1416fcf3ce44SJohn Forte 			mdb_printf("invalid argument: %s\n",
1417fcf3ce44SJohn Forte 			    argv[i].a_un.a_str);
1418fcf3ce44SJohn Forte 			goto out;
1419fcf3ce44SJohn Forte 		}
1420fcf3ce44SJohn Forte 		len = ptr - argv[i].a_un.a_str;
1421fcf3ce44SJohn Forte 		ptr++;	/* point to value now */
1422fcf3ce44SJohn Forte 
1423fcf3ce44SJohn Forte 		if (len == strlen("lpname") &&
1424fcf3ce44SJohn Forte 		    strncmp(argv[i].a_un.a_str, "lpname", len) == 0) {
1425fcf3ce44SJohn Forte 			if (strstr(ptr, "wwn.") == ptr)
1426fcf3ce44SJohn Forte 				ptr += 4;
1427fcf3ce44SJohn Forte 			ret = string2wwn(ptr, options->lpname);
1428fcf3ce44SJohn Forte 			if (ret == -1)
1429fcf3ce44SJohn Forte 				goto out;
1430fcf3ce44SJohn Forte #if 0
1431fcf3ce44SJohn Forte 	mdb_printf("wwn=%02x%02x%02x%02x%02x%02x%02x%02x\n",
1432fcf3ce44SJohn Forte 	    wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
1433fcf3ce44SJohn Forte #endif
1434fcf3ce44SJohn Forte 			options->lpname_defined = 1;
1435fcf3ce44SJohn Forte 
1436fcf3ce44SJohn Forte 		} else if (len == strlen("rp") &&
1437fcf3ce44SJohn Forte 		    strncmp(argv[i].a_un.a_str, "rp", len) == 0) {
1438fcf3ce44SJohn Forte 			options->rp_defined = 1;
1439fcf3ce44SJohn Forte 			options->rp =
1440fcf3ce44SJohn Forte 			    (void *)(unsigned long)mdb_strtoull(ptr);
1441fcf3ce44SJohn Forte 
1442fcf3ce44SJohn Forte 		} else if (len == strlen("rpname") &&
1443fcf3ce44SJohn Forte 		    strncmp(argv[i].a_un.a_str, "rpname", len) == 0) {
1444fcf3ce44SJohn Forte 			if (strstr(ptr, "wwn.") == ptr)
1445fcf3ce44SJohn Forte 				ptr += 4;
1446fcf3ce44SJohn Forte 			ret = string2wwn(ptr, options->rpname);
1447fcf3ce44SJohn Forte 			if (ret == -1)
1448fcf3ce44SJohn Forte 				goto out;
1449fcf3ce44SJohn Forte 			options->rpname_defined = 1;
1450fcf3ce44SJohn Forte 
1451fcf3ce44SJohn Forte 		} else if (len == strlen("show") &&
1452fcf3ce44SJohn Forte 		    strncmp(argv[i].a_un.a_str, "show", len) == 0) {
1453fcf3ce44SJohn Forte 			char *s;
1454fcf3ce44SJohn Forte 			int l;
1455fcf3ce44SJohn Forte 
1456fcf3ce44SJohn Forte 			for (;;) {
1457fcf3ce44SJohn Forte 				s = strchr(ptr, ',');
1458fcf3ce44SJohn Forte 				if (s)
1459fcf3ce44SJohn Forte 					l = s - ptr;
1460fcf3ce44SJohn Forte 				else
1461fcf3ce44SJohn Forte 					l = strlen(ptr);
1462fcf3ce44SJohn Forte 				if (l == strlen("task_flags") &&
1463fcf3ce44SJohn Forte 				    strncmp(ptr, "task_flags", l) == 0)
1464fcf3ce44SJohn Forte 					options->show_task_flags = 1;
1465fcf3ce44SJohn Forte 				else if (l == strlen("lport") &&
1466fcf3ce44SJohn Forte 				    strncmp(ptr, "lport", l) == 0)
1467fcf3ce44SJohn Forte 					options->show_lport = 1;
1468fcf3ce44SJohn Forte 				else {
1469fcf3ce44SJohn Forte 					mdb_printf("unknown shower: %s\n",
1470fcf3ce44SJohn Forte 					    ptr);
1471fcf3ce44SJohn Forte 					goto out;
1472fcf3ce44SJohn Forte 				}
1473fcf3ce44SJohn Forte 				if (s == NULL)
1474fcf3ce44SJohn Forte 					break;
1475fcf3ce44SJohn Forte 				ptr = s + 1;
1476fcf3ce44SJohn Forte 			}
1477fcf3ce44SJohn Forte 		} else {
1478fcf3ce44SJohn Forte 			mdb_printf("unknown argument: %s\n",
1479fcf3ce44SJohn Forte 			    argv[i].a_un.a_str);
1480fcf3ce44SJohn Forte 			goto out;
1481fcf3ce44SJohn Forte 		}
1482fcf3ce44SJohn Forte 	}
1483fcf3ce44SJohn Forte 
1484fcf3ce44SJohn Forte 	return (options);
1485fcf3ce44SJohn Forte out:
1486fcf3ce44SJohn Forte 	mdb_free(options, sizeof (struct find_options));
1487fcf3ce44SJohn Forte 	return (NULL);
1488fcf3ce44SJohn Forte }
1489fcf3ce44SJohn Forte 
1490fcf3ce44SJohn Forte int
string2wwn(const char * s,uint8_t wwn[8])1491fcf3ce44SJohn Forte string2wwn(const char *s, uint8_t wwn[8])
1492fcf3ce44SJohn Forte {
1493fcf3ce44SJohn Forte 	int i;
1494fcf3ce44SJohn Forte 	char tmp[17];
1495fcf3ce44SJohn Forte 	char *p;
1496fcf3ce44SJohn Forte 
1497fcf3ce44SJohn Forte 	if (strlen(s) > 16) {
1498fcf3ce44SJohn Forte 		mdb_printf("invalid wwn %s\n", s);
1499fcf3ce44SJohn Forte 		return (-1);
1500fcf3ce44SJohn Forte 	}
1501fcf3ce44SJohn Forte 
1502fcf3ce44SJohn Forte 	strcpy(tmp, s);
1503fcf3ce44SJohn Forte 	p = tmp + strlen(tmp) - 2;
1504fcf3ce44SJohn Forte 	memset(wwn, 0, 8);
1505fcf3ce44SJohn Forte 	/* figure out wwn from the tail to beginning */
1506fcf3ce44SJohn Forte 	for (i = 7; i >= 0 && p >= tmp; i--, p -= 2) {
1507fcf3ce44SJohn Forte 		wwn[i] = mdb_strtoull(p);
1508fcf3ce44SJohn Forte 		*p = 0;
1509fcf3ce44SJohn Forte 	}
1510fcf3ce44SJohn Forte 	return (0);
1511fcf3ce44SJohn Forte }
1512fcf3ce44SJohn Forte 
1513fcf3ce44SJohn Forte void
fct_find_cmds_help(void)1514fcf3ce44SJohn Forte fct_find_cmds_help(void)
1515fcf3ce44SJohn Forte {
1516fcf3ce44SJohn Forte 	mdb_printf(
1517fcf3ce44SJohn Forte 	    "Find all cached fct_i_cmd_t for a local port. If a local port \n"
1518fcf3ce44SJohn Forte 	    "name is specified, find all pending cmds for it and print the \n"
1519fcf3ce44SJohn Forte 	    "address. Example:\n"
1520fcf3ce44SJohn Forte 	    "    fct_find_cmds lpname=<wwn.12345678 or 12345678>\n");
1521fcf3ce44SJohn Forte }
1522fcf3ce44SJohn Forte void
stmf_find_ilport_help(void)1523fcf3ce44SJohn Forte stmf_find_ilport_help(void)
1524fcf3ce44SJohn Forte {
1525fcf3ce44SJohn Forte 	mdb_printf(
1526fcf3ce44SJohn Forte 	    "Find the fct_i_local_port if local port name is "
1527fcf3ce44SJohn Forte 	    "specified. Example:\n"
1528fcf3ce44SJohn Forte 	    "    stmf_find_ilport lpname=<wwn.12345678 or 12345678>\n");
1529fcf3ce44SJohn Forte }
1530fcf3ce44SJohn Forte void
stmf_find_fct_irp_help(void)1531fcf3ce44SJohn Forte stmf_find_fct_irp_help(void)
1532fcf3ce44SJohn Forte {
1533fcf3ce44SJohn Forte 	mdb_printf(
1534fcf3ce44SJohn Forte 	    "If a remote port name or stmf_i_remote_port_t address is\n"
1535fcf3ce44SJohn Forte 	    "specified, loop through all local ports, to which this remote \n"
1536fcf3ce44SJohn Forte 	    "port has logged in, print address for stmf_i_local_port_t and \n"
1537fcf3ce44SJohn Forte 	    "stmf_i_remote_port. Example:\n"
1538fcf3ce44SJohn Forte 	    "    stmf_find_fct_irp rpname=<wwn.12345678 or 12345678>\n"
1539fcf3ce44SJohn Forte 	    "    stmf_find_fct_irp rp=<3000586778734>\n");
1540fcf3ce44SJohn Forte }
15418d2b0ea9SPriya Krishnan 
1542fcf3ce44SJohn Forte void
stmf_find_tasks_help(void)1543fcf3ce44SJohn Forte stmf_find_tasks_help(void)
1544fcf3ce44SJohn Forte {
1545fcf3ce44SJohn Forte 	mdb_printf(
1546fcf3ce44SJohn Forte 	    "Find all pending scsi_task_t for a given local port and/or\n"
1547fcf3ce44SJohn Forte 	    "remote port. Various different fields for each task are printed\n"
1548fcf3ce44SJohn Forte 	    "depending on what is requested. Example:\n"
1549fcf3ce44SJohn Forte 	    "    stmf_find_tasks rpname=<wwn.12345678 or 12345678>\n"
1550fcf3ce44SJohn Forte 	    "    stmf_find_tasks lpname=<wwn.12345678 or 12345678> "
1551fcf3ce44SJohn Forte 	    "show=task_flags,lport\n");
1552fcf3ce44SJohn Forte }
1553fcf3ce44SJohn Forte 
15548d2b0ea9SPriya Krishnan void
stmf_scsi_task_help(void)15558d2b0ea9SPriya Krishnan stmf_scsi_task_help(void)
15568d2b0ea9SPriya Krishnan {
15578d2b0ea9SPriya Krishnan 	mdb_printf(
15588d2b0ea9SPriya Krishnan 	    "List all active scsi_task_t on a given stmf_worker_t. Example\n"
15598d2b0ea9SPriya Krishnan 	    "    addr::stmf_scsi_task\n");
15608d2b0ea9SPriya Krishnan }
15618d2b0ea9SPriya Krishnan 
1562fcf3ce44SJohn Forte static const mdb_dcmd_t dcmds[] = {
1563fcf3ce44SJohn Forte 	{ "stmf_ilports", "[-v]",
1564fcf3ce44SJohn Forte 	    "Print a list of stmf_i_local_port", stmf_ilports },
1565fcf3ce44SJohn Forte 	{ "ilport2iport", "?[-v]",
1566fcf3ce44SJohn Forte 	    "Convert stmf_i_local_port to corresponding fct_i_local_port",
1567fcf3ce44SJohn Forte 	    ilport2iport },
1568fcf3ce44SJohn Forte 	{ "stmf_iss", "?[-v]",
1569fcf3ce44SJohn Forte 	    "List all active sessions for a given local port",
1570fcf3ce44SJohn Forte 	    stmf_iss },
1571fcf3ce44SJohn Forte 	{ "stmf_ilus", "[-v]", "Print a list of stmf_i_lu", stmf_ilus },
1572fcf3ce44SJohn Forte 	{ "stmf_i_lu_providers", "[-v]",
1573fcf3ce44SJohn Forte 	    "Print a list of stmf_i_lu_provider", stmf_i_lu_providers },
1574fcf3ce44SJohn Forte 	{ "stmf_i_port_providers", "[-v]",
1575fcf3ce44SJohn Forte 	    "Print a list of stmf_i_port_provider", stmf_i_port_providers },
1576fcf3ce44SJohn Forte 	{ "fct_irps", "?[-v]",
1577fcf3ce44SJohn Forte 	    "Print all fct_i_remote_port for a given fct_i_local_port",
1578fcf3ce44SJohn Forte 	    fct_irps },
1579fcf3ce44SJohn Forte 	{ "fct_icmds", "?[-v]",
1580fcf3ce44SJohn Forte 	    "Print all cached fct_i_cmd_t on fct_i_local_port",
1581fcf3ce44SJohn Forte 	    fct_icmds },
1582fcf3ce44SJohn Forte 	{ "fct_find_cmds", "lpname",
1583fcf3ce44SJohn Forte 	    "Find all fct_i_cmd_t for a given local port",
1584fcf3ce44SJohn Forte 	    fct_find_cmds, fct_find_cmds_help},
1585fcf3ce44SJohn Forte 	{ "stmf_find_ilport", "lpname",
1586fcf3ce44SJohn Forte 	    "Find local port information based on its wwn",
1587fcf3ce44SJohn Forte 	    stmf_find_ilport, stmf_find_ilport_help},
1588fcf3ce44SJohn Forte 	{ "stmf_find_fct_irp", "rpname|rp",
1589fcf3ce44SJohn Forte 	    "Print fct remote port information based on its wwn",
1590fcf3ce44SJohn Forte 	    stmf_find_fct_irp, stmf_find_fct_irp_help},
1591fcf3ce44SJohn Forte 	{ "stmf_find_tasks", "lpname|rpname [show]",
1592fcf3ce44SJohn Forte 	    "Find all pending task for a local port or remote port",
1593fcf3ce44SJohn Forte 	    stmf_find_tasks, stmf_find_tasks_help},
15948d2b0ea9SPriya Krishnan 	{ "stmf_worker", "?", "List all the stmf_worker entries", stmf_worker},
15958d2b0ea9SPriya Krishnan 	{ "stmf_scsi_task", ":",
15968d2b0ea9SPriya Krishnan 	    "List all the active STMF SCSI tasks per worker", stmf_scsi_task,
15978d2b0ea9SPriya Krishnan 	    stmf_scsi_task_help},
1598fcf3ce44SJohn Forte 	{ NULL }
1599fcf3ce44SJohn Forte };
1600fcf3ce44SJohn Forte 
1601fcf3ce44SJohn Forte static const mdb_walker_t walkers[] = {
16028d2b0ea9SPriya Krishnan 	{ "stmf_worker", "Walk STMF worker queue", stmf_worker_walk_init,
16038d2b0ea9SPriya Krishnan 	    stmf_worker_walk_step, stmf_worker_walk_fini},
16048d2b0ea9SPriya Krishnan 	{ "stmf_scsi_task", "Walk active STMF SCSI tasks per worker",
16058d2b0ea9SPriya Krishnan 	    stmf_scsi_task_walk_init,
16068d2b0ea9SPriya Krishnan 	    stmf_scsi_task_walk_step, stmf_scsi_task_walk_fini },
1607fcf3ce44SJohn Forte 	{ NULL }
1608fcf3ce44SJohn Forte };
1609fcf3ce44SJohn Forte 
1610fcf3ce44SJohn Forte static const mdb_modinfo_t modinfo = {
1611fcf3ce44SJohn Forte 	MDB_API_VERSION, dcmds, walkers
1612fcf3ce44SJohn Forte };
1613fcf3ce44SJohn Forte 
1614fcf3ce44SJohn Forte const mdb_modinfo_t *
_mdb_init(void)1615fcf3ce44SJohn Forte _mdb_init(void)
1616fcf3ce44SJohn Forte {
1617fcf3ce44SJohn Forte 	return (&modinfo);
1618fcf3ce44SJohn Forte }
1619