xref: /onnv-gate/usr/src/cmd/mdb/common/modules/stmf/stmf.c (revision 10524:80ac731fde86)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
217836SJohn.Forte@Sun.COM /*
229176SPriya.Krishnan@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237836SJohn.Forte@Sun.COM  * Use is subject to license terms.
247836SJohn.Forte@Sun.COM  */
257836SJohn.Forte@Sun.COM 
267836SJohn.Forte@Sun.COM #include <sys/dditypes.h>
277836SJohn.Forte@Sun.COM #include <sys/mdb_modapi.h>
287836SJohn.Forte@Sun.COM #include <sys/modctl.h>
297836SJohn.Forte@Sun.COM #include <sys/sunddi.h>
307836SJohn.Forte@Sun.COM #include <sys/lpif.h>
317836SJohn.Forte@Sun.COM #include <sys/stmf.h>
327836SJohn.Forte@Sun.COM #include <sys/portif.h>
337836SJohn.Forte@Sun.COM #include <stmf_impl.h>
347836SJohn.Forte@Sun.COM #include <lun_map.h>
357836SJohn.Forte@Sun.COM #include <stmf_state.h>
367836SJohn.Forte@Sun.COM 
377836SJohn.Forte@Sun.COM #include <sys/fct.h>
387836SJohn.Forte@Sun.COM #include <fct_impl.h>
397836SJohn.Forte@Sun.COM 
407836SJohn.Forte@Sun.COM #include "cmd_options.h"
417836SJohn.Forte@Sun.COM 
427836SJohn.Forte@Sun.COM static int
stmf_ilport_walk_i(mdb_walk_state_t * wsp)437836SJohn.Forte@Sun.COM stmf_ilport_walk_i(mdb_walk_state_t *wsp)
447836SJohn.Forte@Sun.COM {
457836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
467836SJohn.Forte@Sun.COM 		struct stmf_state state;
477836SJohn.Forte@Sun.COM 
487836SJohn.Forte@Sun.COM 		if (mdb_readsym(&state, sizeof (struct stmf_state),
497836SJohn.Forte@Sun.COM 		    "stmf_state") == -1) {
507836SJohn.Forte@Sun.COM 			mdb_warn("failed to read stmf_state");
517836SJohn.Forte@Sun.COM 			return (WALK_ERR);
527836SJohn.Forte@Sun.COM 		}
537836SJohn.Forte@Sun.COM 		wsp->walk_addr = (uintptr_t)state.stmf_ilportlist;
547836SJohn.Forte@Sun.COM 	}
557836SJohn.Forte@Sun.COM 
567836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (stmf_i_local_port_t), UM_SLEEP);
577836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
587836SJohn.Forte@Sun.COM }
597836SJohn.Forte@Sun.COM 
607836SJohn.Forte@Sun.COM static int
stmf_ilport_walk_s(mdb_walk_state_t * wsp)617836SJohn.Forte@Sun.COM stmf_ilport_walk_s(mdb_walk_state_t *wsp)
627836SJohn.Forte@Sun.COM {
637836SJohn.Forte@Sun.COM 	int status = WALK_NEXT;
647836SJohn.Forte@Sun.COM 
657836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL)
667836SJohn.Forte@Sun.COM 		return (WALK_DONE);
677836SJohn.Forte@Sun.COM 
687836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (struct stmf_i_local_port),
697836SJohn.Forte@Sun.COM 	    wsp->walk_addr) == -1) {
707836SJohn.Forte@Sun.COM 		mdb_warn("failed to read stmf_i_local_port_t at %p",
717836SJohn.Forte@Sun.COM 		    wsp->walk_addr);
727836SJohn.Forte@Sun.COM 		return (WALK_ERR);
737836SJohn.Forte@Sun.COM 	}
747836SJohn.Forte@Sun.COM 
757836SJohn.Forte@Sun.COM 	if (wsp->walk_callback)
767836SJohn.Forte@Sun.COM 		status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
777836SJohn.Forte@Sun.COM 		    wsp->walk_cbdata);
787836SJohn.Forte@Sun.COM 
797836SJohn.Forte@Sun.COM 	wsp->walk_addr = (uintptr_t)
807836SJohn.Forte@Sun.COM 	    (((struct stmf_i_local_port *)wsp->walk_data)->ilport_next);
817836SJohn.Forte@Sun.COM 
827836SJohn.Forte@Sun.COM 	return (status);
837836SJohn.Forte@Sun.COM }
847836SJohn.Forte@Sun.COM 
857836SJohn.Forte@Sun.COM static void
stmf_ilport_walk_f(mdb_walk_state_t * wsp)867836SJohn.Forte@Sun.COM stmf_ilport_walk_f(mdb_walk_state_t *wsp)
877836SJohn.Forte@Sun.COM {
887836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (struct stmf_i_local_port));
897836SJohn.Forte@Sun.COM }
907836SJohn.Forte@Sun.COM 
917836SJohn.Forte@Sun.COM static int
dump_ilport(struct stmf_i_local_port * ilportp,int verbose)927836SJohn.Forte@Sun.COM dump_ilport(struct stmf_i_local_port *ilportp, int verbose)
937836SJohn.Forte@Sun.COM {
947836SJohn.Forte@Sun.COM 	if (ilportp == NULL)
957836SJohn.Forte@Sun.COM 		return (DCMD_OK);
967836SJohn.Forte@Sun.COM 
977836SJohn.Forte@Sun.COM 	mdb_printf("%p\n", ilportp);
987836SJohn.Forte@Sun.COM 
997836SJohn.Forte@Sun.COM 	if (verbose) {
1007836SJohn.Forte@Sun.COM 		/* here assume the alias is maximumly 1024 bytes */
1017836SJohn.Forte@Sun.COM 		char alias[255];
1027836SJohn.Forte@Sun.COM 		struct stmf_local_port lport;
1037836SJohn.Forte@Sun.COM 		struct stmf_i_local_port ilport;
1047836SJohn.Forte@Sun.COM 
1057836SJohn.Forte@Sun.COM 		if (mdb_vread(&ilport, sizeof (ilport), (uintptr_t)ilportp)
1067836SJohn.Forte@Sun.COM 		    == -1) {
1077836SJohn.Forte@Sun.COM 			mdb_warn("failed to read stmf_i_local_port at %p",
1087836SJohn.Forte@Sun.COM 			    ilportp);
1097836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
1107836SJohn.Forte@Sun.COM 		}
1117836SJohn.Forte@Sun.COM 
1127836SJohn.Forte@Sun.COM 		memset(alias, 0, sizeof (alias));
1137836SJohn.Forte@Sun.COM 		if (mdb_vread(&lport, sizeof (lport),
1147836SJohn.Forte@Sun.COM 		    (uintptr_t)ilport.ilport_lport) == -1) {
1157836SJohn.Forte@Sun.COM 			mdb_warn("failed to read stmf_local_port at %p",
1167836SJohn.Forte@Sun.COM 			    ilport.ilport_lport);
1177836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
1187836SJohn.Forte@Sun.COM 		}
1197836SJohn.Forte@Sun.COM 		if (lport.lport_alias && mdb_vread(alias, sizeof (alias),
1207836SJohn.Forte@Sun.COM 		    (uintptr_t)lport.lport_alias) == -1) {
1217836SJohn.Forte@Sun.COM 			mdb_warn("failed to read memory at %p",
1227836SJohn.Forte@Sun.COM 			    lport.lport_alias);
1237836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
1247836SJohn.Forte@Sun.COM 		}
1257836SJohn.Forte@Sun.COM 
1267836SJohn.Forte@Sun.COM 		mdb_printf("  lport: %p\n", ilport.ilport_lport);
1277836SJohn.Forte@Sun.COM 		if (lport.lport_alias)
1287836SJohn.Forte@Sun.COM 			mdb_printf("  port alias: %s\n", alias);
1297836SJohn.Forte@Sun.COM 		mdb_printf("  port provider: %p\n", lport.lport_pp);
1307836SJohn.Forte@Sun.COM 	}
1317836SJohn.Forte@Sun.COM 
1327836SJohn.Forte@Sun.COM 	return (DCMD_OK);
1337836SJohn.Forte@Sun.COM }
1347836SJohn.Forte@Sun.COM 
1357836SJohn.Forte@Sun.COM /*ARGSUSED*/
1367836SJohn.Forte@Sun.COM static int
stmf_ilports(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1377836SJohn.Forte@Sun.COM stmf_ilports(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1387836SJohn.Forte@Sun.COM {
1397836SJohn.Forte@Sun.COM 	int i;
1407836SJohn.Forte@Sun.COM 	int verbose = 0;
1417836SJohn.Forte@Sun.COM 	mdb_walk_state_t ws = {NULL, };
1427836SJohn.Forte@Sun.COM 
1437836SJohn.Forte@Sun.COM 	for (i = 0; i < argc; i++) {
1447836SJohn.Forte@Sun.COM 		char *ptr = (char *)argv[i].a_un.a_str;
1457836SJohn.Forte@Sun.COM 
1467836SJohn.Forte@Sun.COM 		if (ptr[0] == '-')
1477836SJohn.Forte@Sun.COM 			ptr++;
1487836SJohn.Forte@Sun.COM 		while (*ptr) {
1497836SJohn.Forte@Sun.COM 			if (*ptr == 'v')
1507836SJohn.Forte@Sun.COM 				verbose = 1;
1517836SJohn.Forte@Sun.COM 			ptr++;
1527836SJohn.Forte@Sun.COM 		}
1537836SJohn.Forte@Sun.COM 	}
1547836SJohn.Forte@Sun.COM 
1557836SJohn.Forte@Sun.COM 	if (stmf_ilport_walk_i(&ws) == WALK_ERR)
1567836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
1577836SJohn.Forte@Sun.COM 
1587836SJohn.Forte@Sun.COM 	dump_ilport((stmf_i_local_port_t *)ws.walk_addr, verbose);
1597836SJohn.Forte@Sun.COM 
1607836SJohn.Forte@Sun.COM 	while (stmf_ilport_walk_s(&ws) == WALK_NEXT)
1617836SJohn.Forte@Sun.COM 		dump_ilport((stmf_i_local_port_t *)ws.walk_addr, verbose);
1627836SJohn.Forte@Sun.COM 
1637836SJohn.Forte@Sun.COM 	stmf_ilport_walk_f(&ws);
1647836SJohn.Forte@Sun.COM 	return (DCMD_OK);
1657836SJohn.Forte@Sun.COM }
1667836SJohn.Forte@Sun.COM 
1677836SJohn.Forte@Sun.COM struct stmf_i_local_port *
next_stmf_port(mdb_walk_state_t * wsp)1687836SJohn.Forte@Sun.COM next_stmf_port(mdb_walk_state_t *wsp)
1697836SJohn.Forte@Sun.COM {
1707836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
1717836SJohn.Forte@Sun.COM 		if (stmf_ilport_walk_i(wsp) == WALK_ERR) {
1727836SJohn.Forte@Sun.COM 			stmf_ilport_walk_f(wsp);
1737836SJohn.Forte@Sun.COM 			return (NULL);
1747836SJohn.Forte@Sun.COM 		}
1757836SJohn.Forte@Sun.COM 		if (wsp->walk_addr == NULL)
1767836SJohn.Forte@Sun.COM 			stmf_ilport_walk_f(wsp);
1777836SJohn.Forte@Sun.COM 		return ((struct stmf_i_local_port *)wsp->walk_addr);
1787836SJohn.Forte@Sun.COM 	}
1797836SJohn.Forte@Sun.COM 
1807836SJohn.Forte@Sun.COM 	if (stmf_ilport_walk_s(wsp) == WALK_ERR) {
1817836SJohn.Forte@Sun.COM 		stmf_ilport_walk_f(wsp);
1827836SJohn.Forte@Sun.COM 		return (NULL);
1837836SJohn.Forte@Sun.COM 	}
1847836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL)
1857836SJohn.Forte@Sun.COM 		stmf_ilport_walk_f(wsp);
1867836SJohn.Forte@Sun.COM 	return ((struct stmf_i_local_port *)wsp->walk_addr);
1877836SJohn.Forte@Sun.COM }
1887836SJohn.Forte@Sun.COM 
1897836SJohn.Forte@Sun.COM 
1907836SJohn.Forte@Sun.COM /*ARGSUSED*/
1917836SJohn.Forte@Sun.COM static int
stmf_iss(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1927836SJohn.Forte@Sun.COM stmf_iss(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1937836SJohn.Forte@Sun.COM {
1947836SJohn.Forte@Sun.COM 	struct stmf_i_local_port iport;
1957836SJohn.Forte@Sun.COM 	struct stmf_i_scsi_session *issp;
1967836SJohn.Forte@Sun.COM 	struct stmf_i_scsi_session iss;
1977836SJohn.Forte@Sun.COM 	int i;
1987836SJohn.Forte@Sun.COM 	int verbose = 0;
1997836SJohn.Forte@Sun.COM 
2007836SJohn.Forte@Sun.COM 	for (i = 0; i < argc; i++) {
2017836SJohn.Forte@Sun.COM 		char *ptr = (char *)argv[i].a_un.a_str;
2027836SJohn.Forte@Sun.COM 
2037836SJohn.Forte@Sun.COM 		if (ptr[0] == '-')
2047836SJohn.Forte@Sun.COM 			ptr++;
2057836SJohn.Forte@Sun.COM 		while (*ptr) {
2067836SJohn.Forte@Sun.COM 			if (*ptr == 'v')
2077836SJohn.Forte@Sun.COM 				verbose = 1;
2087836SJohn.Forte@Sun.COM 			ptr++;
2097836SJohn.Forte@Sun.COM 		}
2107836SJohn.Forte@Sun.COM 	}
2117836SJohn.Forte@Sun.COM 
2127836SJohn.Forte@Sun.COM 	if (addr == NULL) {
2137836SJohn.Forte@Sun.COM 		mdb_warn("address of stmf_i_local_port should be specified\n");
2147836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
2157836SJohn.Forte@Sun.COM 	}
2167836SJohn.Forte@Sun.COM 
2177836SJohn.Forte@Sun.COM 	/*
2187836SJohn.Forte@Sun.COM 	 * Input should be stmf_i_local_port_t.
2197836SJohn.Forte@Sun.COM 	 */
2207836SJohn.Forte@Sun.COM 	if (mdb_vread(&iport, sizeof (struct stmf_i_local_port), addr)
2217836SJohn.Forte@Sun.COM 	    != sizeof (struct stmf_i_local_port)) {
2227836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in stmf_i_local_port at %p\n", addr);
2237836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
2247836SJohn.Forte@Sun.COM 	}
2257836SJohn.Forte@Sun.COM 
2267836SJohn.Forte@Sun.COM 	issp = iport.ilport_ss_list;
2277836SJohn.Forte@Sun.COM 
2287836SJohn.Forte@Sun.COM 	while (issp) {
2297836SJohn.Forte@Sun.COM 		if (mdb_vread(&iss, sizeof (iss), (uintptr_t)issp) == -1) {
2307836SJohn.Forte@Sun.COM 			mdb_warn("failed to read stmf_i_scsi_session_t at %p",
2317836SJohn.Forte@Sun.COM 			    issp);
2327836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
2337836SJohn.Forte@Sun.COM 		}
2347836SJohn.Forte@Sun.COM 
2357836SJohn.Forte@Sun.COM 		mdb_printf("%p\n", issp);
2367836SJohn.Forte@Sun.COM 		if (verbose) {
2377836SJohn.Forte@Sun.COM 			mdb_printf("  scsi session: %p\n", iss.iss_ss);
2387836SJohn.Forte@Sun.COM 		}
2397836SJohn.Forte@Sun.COM 
2407836SJohn.Forte@Sun.COM 		issp = iss.iss_next;
2417836SJohn.Forte@Sun.COM 	}
2427836SJohn.Forte@Sun.COM 
2437836SJohn.Forte@Sun.COM 	return (DCMD_OK);
2447836SJohn.Forte@Sun.COM }
2457836SJohn.Forte@Sun.COM 
2467836SJohn.Forte@Sun.COM /*ARGSUSED*/
2477836SJohn.Forte@Sun.COM static int
stmf_ilus(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2487836SJohn.Forte@Sun.COM stmf_ilus(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2497836SJohn.Forte@Sun.COM {
2507836SJohn.Forte@Sun.COM 	struct stmf_state state;
2517836SJohn.Forte@Sun.COM 	struct stmf_i_lu ilu;
2527836SJohn.Forte@Sun.COM 	struct stmf_i_lu *ilup;
2537836SJohn.Forte@Sun.COM 	int i;
2547836SJohn.Forte@Sun.COM 	int verbose = 0;
2557836SJohn.Forte@Sun.COM 
2567836SJohn.Forte@Sun.COM 	for (i = 0; i < argc; i++) {
2577836SJohn.Forte@Sun.COM 		char *ptr = (char *)argv[i].a_un.a_str;
2587836SJohn.Forte@Sun.COM 
2597836SJohn.Forte@Sun.COM 		if (ptr[0] == '-')
2607836SJohn.Forte@Sun.COM 			ptr++;
2617836SJohn.Forte@Sun.COM 		while (*ptr) {
2627836SJohn.Forte@Sun.COM 			if (*ptr == 'v')
2637836SJohn.Forte@Sun.COM 				verbose = 1;
2647836SJohn.Forte@Sun.COM 			ptr++;
2657836SJohn.Forte@Sun.COM 		}
2667836SJohn.Forte@Sun.COM 	}
2677836SJohn.Forte@Sun.COM 
2687836SJohn.Forte@Sun.COM 	if (mdb_readsym(&state, sizeof (struct stmf_state), "stmf_state")
2697836SJohn.Forte@Sun.COM 	    == -1) {
2707836SJohn.Forte@Sun.COM 		mdb_warn("failed to read stmf_state");
2717836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
2727836SJohn.Forte@Sun.COM 	}
2737836SJohn.Forte@Sun.COM 
2747836SJohn.Forte@Sun.COM 	ilup = state.stmf_ilulist;
2757836SJohn.Forte@Sun.COM 	while (ilup) {
2767836SJohn.Forte@Sun.COM 		if (mdb_vread(&ilu, sizeof (struct stmf_i_lu), (uintptr_t)ilup)
2777836SJohn.Forte@Sun.COM 		    == -1) {
2787836SJohn.Forte@Sun.COM 			mdb_warn("failed to read stmf_i_lu_t at %p", ilup);
2797836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
2807836SJohn.Forte@Sun.COM 		}
2817836SJohn.Forte@Sun.COM 
2827836SJohn.Forte@Sun.COM 		mdb_printf("%p\n", ilup);
2837836SJohn.Forte@Sun.COM 		if (verbose) {
2847836SJohn.Forte@Sun.COM 			mdb_printf("  lu: %p\n", ilu.ilu_lu);
2857836SJohn.Forte@Sun.COM 
2867836SJohn.Forte@Sun.COM 			/* XXX lu_alias? what is its size? */
2877836SJohn.Forte@Sun.COM 		}
2887836SJohn.Forte@Sun.COM 
2897836SJohn.Forte@Sun.COM 		ilup = ilu.ilu_next;
2907836SJohn.Forte@Sun.COM 	}
2917836SJohn.Forte@Sun.COM 
2927836SJohn.Forte@Sun.COM 	return (DCMD_OK);
2937836SJohn.Forte@Sun.COM }
2947836SJohn.Forte@Sun.COM 
2957836SJohn.Forte@Sun.COM /*ARGSUSED*/
2967836SJohn.Forte@Sun.COM static int
stmf_i_lu_providers(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2977836SJohn.Forte@Sun.COM stmf_i_lu_providers(uintptr_t addr, uint_t flags, int argc,
2987836SJohn.Forte@Sun.COM     const mdb_arg_t *argv)
2997836SJohn.Forte@Sun.COM {
3007836SJohn.Forte@Sun.COM 	struct stmf_state state;
3017836SJohn.Forte@Sun.COM 	struct stmf_i_lu_provider ilp;
3027836SJohn.Forte@Sun.COM 	struct stmf_i_lu_provider *ilpp;
3037836SJohn.Forte@Sun.COM 	int i;
3047836SJohn.Forte@Sun.COM 	int verbose = 0;
3057836SJohn.Forte@Sun.COM 
3067836SJohn.Forte@Sun.COM 	for (i = 0; i < argc; i++) {
3077836SJohn.Forte@Sun.COM 		char *ptr = (char *)argv[i].a_un.a_str;
3087836SJohn.Forte@Sun.COM 
3097836SJohn.Forte@Sun.COM 		if (ptr[0] == '-')
3107836SJohn.Forte@Sun.COM 			ptr++;
3117836SJohn.Forte@Sun.COM 		while (*ptr) {
3127836SJohn.Forte@Sun.COM 			if (*ptr == 'v')
3137836SJohn.Forte@Sun.COM 				verbose = 1;
3147836SJohn.Forte@Sun.COM 			ptr++;
3157836SJohn.Forte@Sun.COM 		}
3167836SJohn.Forte@Sun.COM 	}
3177836SJohn.Forte@Sun.COM 
3187836SJohn.Forte@Sun.COM 	if (mdb_readsym(&state, sizeof (struct stmf_state), "stmf_state")
3197836SJohn.Forte@Sun.COM 	    == -1) {
3207836SJohn.Forte@Sun.COM 		mdb_warn("failed to read stmf_state");
3217836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
3227836SJohn.Forte@Sun.COM 	}
3237836SJohn.Forte@Sun.COM 
3247836SJohn.Forte@Sun.COM 	ilpp = state.stmf_ilplist;
3257836SJohn.Forte@Sun.COM 	while (ilpp) {
3267836SJohn.Forte@Sun.COM 		if (mdb_vread(&ilp, sizeof (stmf_i_lu_provider_t),
3277836SJohn.Forte@Sun.COM 		    (uintptr_t)ilpp) == -1) {
3287836SJohn.Forte@Sun.COM 			mdb_warn("failed to read stmf_i_lu_provider_t at %p",
3297836SJohn.Forte@Sun.COM 			    ilpp);
3307836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
3317836SJohn.Forte@Sun.COM 		}
3327836SJohn.Forte@Sun.COM 
3337836SJohn.Forte@Sun.COM 		mdb_printf("%p\n", ilpp);
3347836SJohn.Forte@Sun.COM 		if (verbose) {
3357836SJohn.Forte@Sun.COM 			mdb_printf("  lu provider: %p\n", ilp.ilp_lp);
3367836SJohn.Forte@Sun.COM 		}
3377836SJohn.Forte@Sun.COM 
3387836SJohn.Forte@Sun.COM 		ilpp = ilp.ilp_next;
3397836SJohn.Forte@Sun.COM 	}
3407836SJohn.Forte@Sun.COM 
3417836SJohn.Forte@Sun.COM 	return (DCMD_OK);
3427836SJohn.Forte@Sun.COM }
3437836SJohn.Forte@Sun.COM 
3447836SJohn.Forte@Sun.COM /*ARGSUSED*/
3457836SJohn.Forte@Sun.COM static int
stmf_i_port_providers(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)3467836SJohn.Forte@Sun.COM stmf_i_port_providers(uintptr_t addr, uint_t flags, int argc,
3477836SJohn.Forte@Sun.COM     const mdb_arg_t *argv)
3487836SJohn.Forte@Sun.COM {
3497836SJohn.Forte@Sun.COM 	struct stmf_state state;
3507836SJohn.Forte@Sun.COM 	struct stmf_i_port_provider ipp;
3517836SJohn.Forte@Sun.COM 	struct stmf_i_port_provider *ippp;
3527836SJohn.Forte@Sun.COM 	int i;
3537836SJohn.Forte@Sun.COM 	int verbose = 0;
3547836SJohn.Forte@Sun.COM 
3557836SJohn.Forte@Sun.COM 	for (i = 0; i < argc; i++) {
3567836SJohn.Forte@Sun.COM 		char *ptr = (char *)argv[i].a_un.a_str;
3577836SJohn.Forte@Sun.COM 
3587836SJohn.Forte@Sun.COM 		if (ptr[0] == '-')
3597836SJohn.Forte@Sun.COM 			ptr++;
3607836SJohn.Forte@Sun.COM 		while (*ptr) {
3617836SJohn.Forte@Sun.COM 			if (*ptr == 'v')
3627836SJohn.Forte@Sun.COM 				verbose = 1;
3637836SJohn.Forte@Sun.COM 			ptr++;
3647836SJohn.Forte@Sun.COM 		}
3657836SJohn.Forte@Sun.COM 	}
3667836SJohn.Forte@Sun.COM 
3677836SJohn.Forte@Sun.COM 	if (mdb_readsym(&state, sizeof (struct stmf_state), "stmf_state")
3687836SJohn.Forte@Sun.COM 	    == -1) {
3697836SJohn.Forte@Sun.COM 		mdb_warn("failed to read stmf_state");
3707836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
3717836SJohn.Forte@Sun.COM 	}
3727836SJohn.Forte@Sun.COM 
3737836SJohn.Forte@Sun.COM 	ippp = state.stmf_ipplist;
3747836SJohn.Forte@Sun.COM 	while (ippp) {
3757836SJohn.Forte@Sun.COM 		if (mdb_vread(&ipp, sizeof (stmf_i_port_provider_t),
3767836SJohn.Forte@Sun.COM 		    (uintptr_t)ippp) == -1) {
3777836SJohn.Forte@Sun.COM 			mdb_warn("failed to read stmf_i_port_provider_t at %p",
3787836SJohn.Forte@Sun.COM 			    ippp);
3797836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
3807836SJohn.Forte@Sun.COM 		}
3817836SJohn.Forte@Sun.COM 
3827836SJohn.Forte@Sun.COM 		mdb_printf("%p\n", ippp);
3837836SJohn.Forte@Sun.COM 		if (verbose) {
3847836SJohn.Forte@Sun.COM 			mdb_printf("  port provider: %p\n", ipp.ipp_pp);
3857836SJohn.Forte@Sun.COM 		}
3867836SJohn.Forte@Sun.COM 
3877836SJohn.Forte@Sun.COM 		ippp = ipp.ipp_next;
3887836SJohn.Forte@Sun.COM 	}
3897836SJohn.Forte@Sun.COM 
3907836SJohn.Forte@Sun.COM 	return (DCMD_OK);
3917836SJohn.Forte@Sun.COM }
3927836SJohn.Forte@Sun.COM 
3937836SJohn.Forte@Sun.COM int string2wwn(const char *s, uint8_t wwn[8]);
3947836SJohn.Forte@Sun.COM 
3957836SJohn.Forte@Sun.COM static uint16_t port_max_logins;
3967836SJohn.Forte@Sun.COM static int	rp_index;
3977836SJohn.Forte@Sun.COM 
3987836SJohn.Forte@Sun.COM /*
3997836SJohn.Forte@Sun.COM  * Cervert stmf_i_local_port to fct_i_local_port
4007836SJohn.Forte@Sun.COM  */
4017836SJohn.Forte@Sun.COM /*ARGSUSED*/
4027836SJohn.Forte@Sun.COM static struct fct_i_local_port *
__ilport2iport(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)4037836SJohn.Forte@Sun.COM __ilport2iport(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
4047836SJohn.Forte@Sun.COM {
4057836SJohn.Forte@Sun.COM 	struct stmf_i_local_port iport;
4067836SJohn.Forte@Sun.COM 	struct stmf_local_port   lport;
4077836SJohn.Forte@Sun.COM 	struct fct_local_port    fport;
4087836SJohn.Forte@Sun.COM 
4097836SJohn.Forte@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
4107836SJohn.Forte@Sun.COM 		mdb_warn("stmf_i_local_port address should be specified");
4117836SJohn.Forte@Sun.COM 		return (NULL);
4127836SJohn.Forte@Sun.COM 	}
4137836SJohn.Forte@Sun.COM 
4147836SJohn.Forte@Sun.COM 	/*
4157836SJohn.Forte@Sun.COM 	 * Input should be stmf_i_local_port_t.
4167836SJohn.Forte@Sun.COM 	 */
4177836SJohn.Forte@Sun.COM 	if (mdb_vread(&iport, sizeof (struct stmf_i_local_port), addr)
4187836SJohn.Forte@Sun.COM 	    != sizeof (struct stmf_i_local_port)) {
4197836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in stmf_i_local_port\n");
4207836SJohn.Forte@Sun.COM 		return (NULL);
4217836SJohn.Forte@Sun.COM 	}
4227836SJohn.Forte@Sun.COM 
4237836SJohn.Forte@Sun.COM 	if (mdb_vread(&lport, sizeof (stmf_local_port_t),
4247836SJohn.Forte@Sun.COM 	    (uintptr_t)iport.ilport_lport) != sizeof (stmf_local_port_t)) {
4257836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in stmf_local_port\n");
4267836SJohn.Forte@Sun.COM 		return (NULL);
4277836SJohn.Forte@Sun.COM 	}
4287836SJohn.Forte@Sun.COM 
4297836SJohn.Forte@Sun.COM 	if (mdb_vread(&fport, sizeof (fct_local_port_t),
4307836SJohn.Forte@Sun.COM 	    (uintptr_t)lport.lport_port_private)
4317836SJohn.Forte@Sun.COM 	    != sizeof (fct_local_port_t)) {
4327836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in fct_local_port\n");
4337836SJohn.Forte@Sun.COM 		return (NULL);
4347836SJohn.Forte@Sun.COM 	}
4357836SJohn.Forte@Sun.COM 
4367836SJohn.Forte@Sun.COM 	return (fport.port_fct_private);
4377836SJohn.Forte@Sun.COM }
4387836SJohn.Forte@Sun.COM 
4397836SJohn.Forte@Sun.COM static int
ilport2iport(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)4407836SJohn.Forte@Sun.COM ilport2iport(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
4417836SJohn.Forte@Sun.COM {
4427836SJohn.Forte@Sun.COM 	struct fct_i_local_port *iportp;
4437836SJohn.Forte@Sun.COM 	int i;
4447836SJohn.Forte@Sun.COM 	int verbose = 0;
4457836SJohn.Forte@Sun.COM 
4467836SJohn.Forte@Sun.COM 	for (i = 0; i < argc; i++) {
4477836SJohn.Forte@Sun.COM 		char *ptr = (char *)argv[i].a_un.a_str;
4487836SJohn.Forte@Sun.COM 
4497836SJohn.Forte@Sun.COM 		if (ptr[0] == '-')
4507836SJohn.Forte@Sun.COM 			ptr++;
4517836SJohn.Forte@Sun.COM 		while (*ptr) {
4527836SJohn.Forte@Sun.COM 			if (*ptr == 'v')
4537836SJohn.Forte@Sun.COM 				verbose = 1;
4547836SJohn.Forte@Sun.COM 			ptr++;
4557836SJohn.Forte@Sun.COM 		}
4567836SJohn.Forte@Sun.COM 	}
4577836SJohn.Forte@Sun.COM 
4587836SJohn.Forte@Sun.COM 
4597836SJohn.Forte@Sun.COM 	iportp = __ilport2iport(addr, flags, argc, argv);
4607836SJohn.Forte@Sun.COM 	if (iportp) {
4617836SJohn.Forte@Sun.COM 		mdb_printf("%p\n", iportp);
4627836SJohn.Forte@Sun.COM 		if (verbose) {
4637836SJohn.Forte@Sun.COM 			struct fct_i_local_port iport;
4647836SJohn.Forte@Sun.COM 			/* is the alias always 16 bytes in size ? */
4657836SJohn.Forte@Sun.COM 			char alias[16];
4667836SJohn.Forte@Sun.COM 
4677836SJohn.Forte@Sun.COM 			memset(alias, 0, sizeof (alias));
4687836SJohn.Forte@Sun.COM 			if (mdb_vread(&iport, sizeof (fct_i_local_port_t),
4697836SJohn.Forte@Sun.COM 			    (uintptr_t)iportp)
4707836SJohn.Forte@Sun.COM 			    != sizeof (fct_i_local_port_t)) {
4717836SJohn.Forte@Sun.COM 				mdb_warn("Unable to read in fct_i_local_port"
4727836SJohn.Forte@Sun.COM 				    "at %p\n", iportp);
4737836SJohn.Forte@Sun.COM 				return (DCMD_ERR);
4747836SJohn.Forte@Sun.COM 			}
4757836SJohn.Forte@Sun.COM 			if (iport.iport_alias &&
4767836SJohn.Forte@Sun.COM 			    mdb_vread(alias, sizeof (alias),
4777836SJohn.Forte@Sun.COM 			    (uintptr_t)iport.iport_alias)
4787836SJohn.Forte@Sun.COM 			    != sizeof (alias)) {
4797836SJohn.Forte@Sun.COM 				mdb_warn("Unable to read in memory at %p",
4807836SJohn.Forte@Sun.COM 				    iport.iport_alias);
4817836SJohn.Forte@Sun.COM 				return (DCMD_ERR);
4827836SJohn.Forte@Sun.COM 			}
4837836SJohn.Forte@Sun.COM 			mdb_printf("  port: %p\n", iport.iport_port);
4847836SJohn.Forte@Sun.COM 			if (iport.iport_alias)
4857836SJohn.Forte@Sun.COM 				mdb_printf("  alias: %s\n", alias);
4867836SJohn.Forte@Sun.COM 		}
4877836SJohn.Forte@Sun.COM 	}
4887836SJohn.Forte@Sun.COM 	return (DCMD_OK);
4897836SJohn.Forte@Sun.COM }
4907836SJohn.Forte@Sun.COM 
4917836SJohn.Forte@Sun.COM /*
4927836SJohn.Forte@Sun.COM  * by wwn, we can only find one local port
4937836SJohn.Forte@Sun.COM  */
4947836SJohn.Forte@Sun.COM static struct stmf_i_local_port *
find_lport_by_wwn(uint8_t wwn[8])4957836SJohn.Forte@Sun.COM find_lport_by_wwn(uint8_t wwn[8])
4967836SJohn.Forte@Sun.COM {
4977836SJohn.Forte@Sun.COM 	struct stmf_i_local_port *siport;
4987836SJohn.Forte@Sun.COM 	struct fct_i_local_port *fiport;
4997836SJohn.Forte@Sun.COM 	struct fct_i_local_port iport;
5007836SJohn.Forte@Sun.COM 	struct fct_local_port fport;
5017836SJohn.Forte@Sun.COM 	mdb_walk_state_t ws = {NULL, };
5027836SJohn.Forte@Sun.COM 
5037836SJohn.Forte@Sun.COM 	while ((siport = next_stmf_port(&ws)) != NULL) {
5047836SJohn.Forte@Sun.COM 		fiport = __ilport2iport((uintptr_t)siport, DCMD_ADDRSPEC,
5057836SJohn.Forte@Sun.COM 		    0, NULL);
5067836SJohn.Forte@Sun.COM 		if (fiport == NULL)
5077836SJohn.Forte@Sun.COM 			return (NULL);
5087836SJohn.Forte@Sun.COM 
5097836SJohn.Forte@Sun.COM 		if (mdb_vread(&iport, sizeof (fct_i_local_port_t),
5107836SJohn.Forte@Sun.COM 		    (uintptr_t)fiport)
5117836SJohn.Forte@Sun.COM 		    != sizeof (fct_i_local_port_t)) {
5127836SJohn.Forte@Sun.COM 			mdb_warn("Unable to read in fct_i_local_port\n");
5137836SJohn.Forte@Sun.COM 			return (NULL);
5147836SJohn.Forte@Sun.COM 		}
5157836SJohn.Forte@Sun.COM 		if (mdb_vread(&fport, sizeof (fct_local_port_t),
5167836SJohn.Forte@Sun.COM 		    (uintptr_t)iport.iport_port)
5177836SJohn.Forte@Sun.COM 		    != sizeof (fct_local_port_t)) {
5187836SJohn.Forte@Sun.COM 			mdb_warn("Unable to read in fct_local_port\n");
5197836SJohn.Forte@Sun.COM 			return (NULL);
5207836SJohn.Forte@Sun.COM 		}
5217836SJohn.Forte@Sun.COM 
5227836SJohn.Forte@Sun.COM #if 0
5237836SJohn.Forte@Sun.COM 		mdb_printf("pwwn=%02x%02x%02x%02x%02x%02x%02x%02x\n",
5247836SJohn.Forte@Sun.COM 		    fport.port_pwwn[0], fport.port_pwwn[1],
5257836SJohn.Forte@Sun.COM 		    fport.port_pwwn[2], fport.port_pwwn[3],
5267836SJohn.Forte@Sun.COM 		    fport.port_pwwn[4], fport.port_pwwn[5],
5277836SJohn.Forte@Sun.COM 		    fport.port_pwwn[6], fport.port_pwwn[7]);
5287836SJohn.Forte@Sun.COM #endif
5297836SJohn.Forte@Sun.COM 		if (memcmp(fport.port_pwwn, wwn, 8) == 0) {
5307836SJohn.Forte@Sun.COM 			return (siport);
5317836SJohn.Forte@Sun.COM 		}
5327836SJohn.Forte@Sun.COM 	}
5337836SJohn.Forte@Sun.COM 
5347836SJohn.Forte@Sun.COM 	return (NULL);
5357836SJohn.Forte@Sun.COM }
5367836SJohn.Forte@Sun.COM 
5377836SJohn.Forte@Sun.COM /*ARGSUSED*/
5387836SJohn.Forte@Sun.COM static int
stmf_find_ilport(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)5397836SJohn.Forte@Sun.COM stmf_find_ilport(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
5407836SJohn.Forte@Sun.COM {
5417836SJohn.Forte@Sun.COM 	struct find_options *options;
5427836SJohn.Forte@Sun.COM 	struct stmf_i_local_port *siport;
5437836SJohn.Forte@Sun.COM 
5447836SJohn.Forte@Sun.COM 	options = parse_options(argc, argv);
5457836SJohn.Forte@Sun.COM 	/* need to free options manually ? */
5467836SJohn.Forte@Sun.COM 	if (options == NULL || ! options->lpname_defined) {
5477836SJohn.Forte@Sun.COM 		mdb_printf("lpname=<wwn.12345678 or 12345678> "
5487836SJohn.Forte@Sun.COM 		    "should be specified\n");
5497836SJohn.Forte@Sun.COM 		return (DCMD_OK);
5507836SJohn.Forte@Sun.COM 	}
5517836SJohn.Forte@Sun.COM 
5527836SJohn.Forte@Sun.COM 	if ((siport = find_lport_by_wwn(options->lpname)) != NULL)
5537836SJohn.Forte@Sun.COM 		mdb_printf("%p\n", siport);
5547836SJohn.Forte@Sun.COM 
5557836SJohn.Forte@Sun.COM 	return (DCMD_OK);
5567836SJohn.Forte@Sun.COM }
5577836SJohn.Forte@Sun.COM 
5587836SJohn.Forte@Sun.COM static int
fct_irp_walk_i(mdb_walk_state_t * wsp)5597836SJohn.Forte@Sun.COM fct_irp_walk_i(mdb_walk_state_t *wsp)
5607836SJohn.Forte@Sun.COM {
5617836SJohn.Forte@Sun.COM 	struct fct_local_port port;
5627836SJohn.Forte@Sun.COM 	struct fct_i_local_port iport;
5637836SJohn.Forte@Sun.COM 
5647836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
5657836SJohn.Forte@Sun.COM 		mdb_warn("Can not perform global walk");
5667836SJohn.Forte@Sun.COM 		return (WALK_ERR);
5677836SJohn.Forte@Sun.COM 	}
5687836SJohn.Forte@Sun.COM 
5697836SJohn.Forte@Sun.COM 	/*
5707836SJohn.Forte@Sun.COM 	 * Input should be fct_i_local_port_t.
5717836SJohn.Forte@Sun.COM 	 */
5727836SJohn.Forte@Sun.COM 	if (mdb_vread(&iport, sizeof (struct fct_i_local_port), wsp->walk_addr)
5737836SJohn.Forte@Sun.COM 	    != sizeof (struct fct_i_local_port)) {
5747836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in fct_i_local_port\n");
5757836SJohn.Forte@Sun.COM 		return (WALK_ERR);
5767836SJohn.Forte@Sun.COM 	}
5777836SJohn.Forte@Sun.COM 
5787836SJohn.Forte@Sun.COM 	if (mdb_vread(&port, sizeof (struct fct_local_port),
5797836SJohn.Forte@Sun.COM 	    (uintptr_t)iport.iport_port)
5807836SJohn.Forte@Sun.COM 	    != sizeof (struct fct_local_port)) {
5817836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in fct_local_port\n");
5827836SJohn.Forte@Sun.COM 		return (WALK_ERR);
5837836SJohn.Forte@Sun.COM 	}
5847836SJohn.Forte@Sun.COM 
5857836SJohn.Forte@Sun.COM 	port_max_logins = port.port_max_logins;
5867836SJohn.Forte@Sun.COM 	rp_index = 0;
5877836SJohn.Forte@Sun.COM 	wsp->walk_addr = (uintptr_t)iport.iport_rp_slots;
5887836SJohn.Forte@Sun.COM 
5897836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
5907836SJohn.Forte@Sun.COM }
5917836SJohn.Forte@Sun.COM 
5927836SJohn.Forte@Sun.COM static int
fct_irp_walk_s(mdb_walk_state_t * wsp)5937836SJohn.Forte@Sun.COM fct_irp_walk_s(mdb_walk_state_t *wsp)
5947836SJohn.Forte@Sun.COM {
5957836SJohn.Forte@Sun.COM 	int status = WALK_NEXT;
5967836SJohn.Forte@Sun.COM 	fct_i_remote_port_t *rp;
5977836SJohn.Forte@Sun.COM 
5987836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL)
5997836SJohn.Forte@Sun.COM 		return (WALK_DONE);
6007836SJohn.Forte@Sun.COM 
6017836SJohn.Forte@Sun.COM 	if (rp_index++ >= port_max_logins)
6027836SJohn.Forte@Sun.COM 		return (WALK_DONE);
6037836SJohn.Forte@Sun.COM 
6047836SJohn.Forte@Sun.COM 	if (mdb_vread(&rp, sizeof (fct_i_remote_port_t *),
6057836SJohn.Forte@Sun.COM 	    wsp->walk_addr) == -1) {
6067836SJohn.Forte@Sun.COM 		mdb_warn("failed to read address of fct_i_remote_port_t at %p",
6077836SJohn.Forte@Sun.COM 		    wsp->walk_addr);
6087836SJohn.Forte@Sun.COM 		return (WALK_DONE);
6097836SJohn.Forte@Sun.COM 	}
6107836SJohn.Forte@Sun.COM 
6117836SJohn.Forte@Sun.COM 	if (rp != NULL && wsp->walk_callback != NULL)
6127836SJohn.Forte@Sun.COM 		status = wsp->walk_callback((uintptr_t)rp, rp,
6137836SJohn.Forte@Sun.COM 		    wsp->walk_cbdata);
6147836SJohn.Forte@Sun.COM 
6157836SJohn.Forte@Sun.COM 	wsp->walk_addr = (uintptr_t)
6167836SJohn.Forte@Sun.COM 	    &(((fct_i_remote_port_t **)wsp->walk_addr)[1]);
6177836SJohn.Forte@Sun.COM 
6187836SJohn.Forte@Sun.COM 	return (status);
6197836SJohn.Forte@Sun.COM }
6207836SJohn.Forte@Sun.COM 
6217836SJohn.Forte@Sun.COM static void
fct_irp_walk_f(mdb_walk_state_t * wsp)6227836SJohn.Forte@Sun.COM fct_irp_walk_f(mdb_walk_state_t *wsp)
6237836SJohn.Forte@Sun.COM {
6247836SJohn.Forte@Sun.COM 	wsp->walk_addr = NULL;
6257836SJohn.Forte@Sun.COM }
6267836SJohn.Forte@Sun.COM 
6277836SJohn.Forte@Sun.COM /*
6287836SJohn.Forte@Sun.COM  * to set remote_port
6297836SJohn.Forte@Sun.COM  */
6307836SJohn.Forte@Sun.COM /*ARGSUSED*/
6317836SJohn.Forte@Sun.COM static int
walk_fct_irp_cb(uintptr_t p,const void * arg,void * cbdata)6327836SJohn.Forte@Sun.COM walk_fct_irp_cb(uintptr_t p, const void * arg, void *cbdata)
6337836SJohn.Forte@Sun.COM {
6347836SJohn.Forte@Sun.COM 	*((uintptr_t *)cbdata) = p;
6357836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
6367836SJohn.Forte@Sun.COM }
6377836SJohn.Forte@Sun.COM 
6387836SJohn.Forte@Sun.COM static int
fct_irps(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)6397836SJohn.Forte@Sun.COM fct_irps(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
6407836SJohn.Forte@Sun.COM {
6417836SJohn.Forte@Sun.COM 	static uint64_t cbdata = 0;
6427836SJohn.Forte@Sun.COM 	mdb_walk_state_t ws = {walk_fct_irp_cb, &cbdata, addr};
6437836SJohn.Forte@Sun.COM 	fct_i_remote_port_t *irpp;
6447836SJohn.Forte@Sun.COM 	int i;
6457836SJohn.Forte@Sun.COM 	int verbose = 0;
6467836SJohn.Forte@Sun.COM 
6477836SJohn.Forte@Sun.COM 	for (i = 0; i < argc; i++) {
6487836SJohn.Forte@Sun.COM 		char *ptr = (char *)argv[i].a_un.a_str;
6497836SJohn.Forte@Sun.COM 
6507836SJohn.Forte@Sun.COM 		if (ptr[0] == '-')
6517836SJohn.Forte@Sun.COM 			ptr++;
6527836SJohn.Forte@Sun.COM 		while (*ptr) {
6537836SJohn.Forte@Sun.COM 			if (*ptr == 'v')
6547836SJohn.Forte@Sun.COM 				verbose = 1;
6557836SJohn.Forte@Sun.COM 			ptr++;
6567836SJohn.Forte@Sun.COM 		}
6577836SJohn.Forte@Sun.COM 	}
6587836SJohn.Forte@Sun.COM 
6597836SJohn.Forte@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
6607836SJohn.Forte@Sun.COM 		mdb_warn("fct_i_local_port_t address should be specified");
6617836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
6627836SJohn.Forte@Sun.COM 	}
6637836SJohn.Forte@Sun.COM 
6647836SJohn.Forte@Sun.COM 	fct_irp_walk_i(&ws);
6657836SJohn.Forte@Sun.COM 	while (fct_irp_walk_s(&ws) == WALK_NEXT) {
6667836SJohn.Forte@Sun.COM 		irpp = *((fct_i_remote_port_t **)ws.walk_cbdata);
6677836SJohn.Forte@Sun.COM 
6687836SJohn.Forte@Sun.COM 		if (irpp) {
6697836SJohn.Forte@Sun.COM 			*((fct_i_remote_port_t **)ws.walk_cbdata) = NULL;
6707836SJohn.Forte@Sun.COM 
6717836SJohn.Forte@Sun.COM 			mdb_printf("%p\n", irpp);
6727836SJohn.Forte@Sun.COM 			if (verbose) {
6737836SJohn.Forte@Sun.COM 				fct_i_remote_port_t irp;
6747836SJohn.Forte@Sun.COM 
6757836SJohn.Forte@Sun.COM 				if (mdb_vread(&irp, sizeof (irp),
6767836SJohn.Forte@Sun.COM 				    (uintptr_t)irpp) != sizeof (irp)) {
6777836SJohn.Forte@Sun.COM 					mdb_warn("Unable to read in "
6787836SJohn.Forte@Sun.COM 					    "fct_i_remote_port at %p\n", irpp);
6797836SJohn.Forte@Sun.COM 					return (DCMD_ERR);
6807836SJohn.Forte@Sun.COM 				}
6817836SJohn.Forte@Sun.COM 				mdb_printf("  remote port: %p\n", irp.irp_rp);
6827836SJohn.Forte@Sun.COM 				mdb_printf("  port id: %x\n", irp.irp_portid);
6837836SJohn.Forte@Sun.COM 			}
6847836SJohn.Forte@Sun.COM 		}
6857836SJohn.Forte@Sun.COM 	}
6867836SJohn.Forte@Sun.COM 	fct_irp_walk_f(&ws);
6877836SJohn.Forte@Sun.COM 
6887836SJohn.Forte@Sun.COM 	return (DCMD_OK);
6897836SJohn.Forte@Sun.COM }
6907836SJohn.Forte@Sun.COM 
6917836SJohn.Forte@Sun.COM static uintptr_t cur_iport_for_irp_loop = NULL;
6927836SJohn.Forte@Sun.COM 
6937836SJohn.Forte@Sun.COM static fct_i_remote_port_t *
next_rport(struct fct_i_local_port * iport)6947836SJohn.Forte@Sun.COM next_rport(struct fct_i_local_port *iport)
6957836SJohn.Forte@Sun.COM {
6967836SJohn.Forte@Sun.COM 	static uint64_t cbdata = 0;
6977836SJohn.Forte@Sun.COM 	static mdb_walk_state_t ws = {walk_fct_irp_cb, &cbdata};
6987836SJohn.Forte@Sun.COM 	int ret;
6997836SJohn.Forte@Sun.COM 	fct_i_remote_port_t *irp;
7007836SJohn.Forte@Sun.COM 
7017836SJohn.Forte@Sun.COM 	if (ws.walk_addr == NULL || cur_iport_for_irp_loop !=
7027836SJohn.Forte@Sun.COM 	    (uintptr_t)iport) {
7037836SJohn.Forte@Sun.COM 		*((fct_i_remote_port_t **)ws.walk_cbdata) = NULL;
7047836SJohn.Forte@Sun.COM 		cur_iport_for_irp_loop = (uintptr_t)iport;
7057836SJohn.Forte@Sun.COM 		ws.walk_addr = (uintptr_t)iport;
7067836SJohn.Forte@Sun.COM 		if (fct_irp_walk_i(&ws) == WALK_ERR) {
7077836SJohn.Forte@Sun.COM 			fct_irp_walk_f(&ws);
7087836SJohn.Forte@Sun.COM 			return (NULL);
7097836SJohn.Forte@Sun.COM 		}
7107836SJohn.Forte@Sun.COM 		if (ws.walk_addr == NULL) {
7117836SJohn.Forte@Sun.COM 			fct_irp_walk_f(&ws);
7127836SJohn.Forte@Sun.COM 			return (NULL);
7137836SJohn.Forte@Sun.COM 		}
7147836SJohn.Forte@Sun.COM 	}
7157836SJohn.Forte@Sun.COM 
7167836SJohn.Forte@Sun.COM 	while ((ret = fct_irp_walk_s(&ws)) == WALK_NEXT) {
7177836SJohn.Forte@Sun.COM 		if (*((fct_i_remote_port_t **)ws.walk_cbdata) != 0) {
7187836SJohn.Forte@Sun.COM 			irp = *((fct_i_remote_port_t **)ws.walk_cbdata);
7197836SJohn.Forte@Sun.COM 			*((fct_i_remote_port_t **)ws.walk_cbdata) = NULL;
7207836SJohn.Forte@Sun.COM 			return (irp);
7217836SJohn.Forte@Sun.COM 		}
7227836SJohn.Forte@Sun.COM 	}
7237836SJohn.Forte@Sun.COM 	fct_irp_walk_f(&ws);
7247836SJohn.Forte@Sun.COM 
7257836SJohn.Forte@Sun.COM 	/*
7267836SJohn.Forte@Sun.COM 	 * If it is WALK_DONE, there may be one remote port there
7277836SJohn.Forte@Sun.COM 	 */
7287836SJohn.Forte@Sun.COM 	if (ret == WALK_DONE) {
7297836SJohn.Forte@Sun.COM 		irp = *((fct_i_remote_port_t **)ws.walk_cbdata);
7307836SJohn.Forte@Sun.COM 		*((fct_i_remote_port_t **)ws.walk_cbdata) = NULL;
7317836SJohn.Forte@Sun.COM 		return (irp);
7327836SJohn.Forte@Sun.COM 	}
7337836SJohn.Forte@Sun.COM 	return (NULL);
7347836SJohn.Forte@Sun.COM }
7357836SJohn.Forte@Sun.COM 
7367836SJohn.Forte@Sun.COM static struct stmf_i_local_port *
irp_to_ilport(struct fct_i_remote_port * irpp)7377836SJohn.Forte@Sun.COM irp_to_ilport(struct fct_i_remote_port *irpp)
7387836SJohn.Forte@Sun.COM {
7397836SJohn.Forte@Sun.COM 	struct fct_i_remote_port irp;
7407836SJohn.Forte@Sun.COM 	struct fct_remote_port rp;
7417836SJohn.Forte@Sun.COM 	struct fct_local_port port;
7427836SJohn.Forte@Sun.COM 	struct stmf_local_port lport;
7437836SJohn.Forte@Sun.COM 
7447836SJohn.Forte@Sun.COM 	if (mdb_vread(&irp, sizeof (struct fct_i_remote_port),
7457836SJohn.Forte@Sun.COM 	    (uintptr_t)irpp)
7467836SJohn.Forte@Sun.COM 	    != sizeof (struct fct_i_remote_port)) {
7477836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in fct_i_remote_port\n");
7487836SJohn.Forte@Sun.COM 		return (NULL);
7497836SJohn.Forte@Sun.COM 	}
7507836SJohn.Forte@Sun.COM 	if (mdb_vread(&rp, sizeof (struct fct_remote_port),
7517836SJohn.Forte@Sun.COM 	    (uintptr_t)irp.irp_rp)
7527836SJohn.Forte@Sun.COM 	    != sizeof (struct fct_remote_port)) {
7537836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in fct_remote_port\n");
7547836SJohn.Forte@Sun.COM 		return (NULL);
7557836SJohn.Forte@Sun.COM 	}
7567836SJohn.Forte@Sun.COM 
7577836SJohn.Forte@Sun.COM 	if (mdb_vread(&port, sizeof (struct fct_local_port),
7587836SJohn.Forte@Sun.COM 	    (uintptr_t)rp.rp_port)
7597836SJohn.Forte@Sun.COM 	    != sizeof (struct fct_local_port)) {
7607836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in fct_local_port\n");
7617836SJohn.Forte@Sun.COM 		return (NULL);
7627836SJohn.Forte@Sun.COM 	}
7637836SJohn.Forte@Sun.COM 	if (mdb_vread(&lport, sizeof (struct stmf_local_port),
7647836SJohn.Forte@Sun.COM 	    (uintptr_t)port.port_lport)
7657836SJohn.Forte@Sun.COM 	    != sizeof (struct stmf_local_port)) {
7667836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in stmf_local_port\n");
7677836SJohn.Forte@Sun.COM 		return (NULL);
7687836SJohn.Forte@Sun.COM 	}
7697836SJohn.Forte@Sun.COM 	return (lport.lport_stmf_private);
7707836SJohn.Forte@Sun.COM }
7717836SJohn.Forte@Sun.COM 
7727836SJohn.Forte@Sun.COM /*
7737836SJohn.Forte@Sun.COM  * by wwn, we may find more than one remote port, so we need to know its
7747836SJohn.Forte@Sun.COM  * corresponding local port
7757836SJohn.Forte@Sun.COM  */
7767836SJohn.Forte@Sun.COM static struct fct_i_remote_port *
find_irp_by_wwn(struct stmf_i_local_port * siport,uint8_t wwn[8])7777836SJohn.Forte@Sun.COM find_irp_by_wwn(struct stmf_i_local_port *siport, uint8_t wwn[8])
7787836SJohn.Forte@Sun.COM {
7797836SJohn.Forte@Sun.COM 	struct fct_i_local_port *fiport;
7807836SJohn.Forte@Sun.COM 	fct_i_remote_port_t *irpp;
7817836SJohn.Forte@Sun.COM 	struct fct_i_remote_port irp;
7827836SJohn.Forte@Sun.COM 	struct fct_remote_port rp;
7837836SJohn.Forte@Sun.COM 	fct_i_remote_port_t *ret = NULL;
7847836SJohn.Forte@Sun.COM 
7857836SJohn.Forte@Sun.COM 	fiport = __ilport2iport((uintptr_t)siport, DCMD_ADDRSPEC, 0, NULL);
7867836SJohn.Forte@Sun.COM 	if (fiport == NULL)
7877836SJohn.Forte@Sun.COM 		return (NULL);
7887836SJohn.Forte@Sun.COM 
7897836SJohn.Forte@Sun.COM 	while ((irpp = next_rport(fiport)) != NULL) {
7907836SJohn.Forte@Sun.COM 		if (mdb_vread(&irp, sizeof (struct fct_i_remote_port),
7917836SJohn.Forte@Sun.COM 		    (uintptr_t)irpp)
7927836SJohn.Forte@Sun.COM 		    != sizeof (struct fct_i_remote_port)) {
7937836SJohn.Forte@Sun.COM 			mdb_warn("Unable to read in fct_i_remote_port\n");
7947836SJohn.Forte@Sun.COM 			break;
7957836SJohn.Forte@Sun.COM 		}
7967836SJohn.Forte@Sun.COM 		if (mdb_vread(&rp, sizeof (struct fct_remote_port),
7977836SJohn.Forte@Sun.COM 		    (uintptr_t)irp.irp_rp)
7987836SJohn.Forte@Sun.COM 		    != sizeof (struct fct_remote_port)) {
7997836SJohn.Forte@Sun.COM 			mdb_warn("Unable to read in fct_remote_port\n");
8007836SJohn.Forte@Sun.COM 			break;
8017836SJohn.Forte@Sun.COM 		}
8027836SJohn.Forte@Sun.COM 
8037836SJohn.Forte@Sun.COM 		if (memcmp(rp.rp_pwwn, wwn, 8) == 0) {
8047836SJohn.Forte@Sun.COM 			ret = irpp;
8057836SJohn.Forte@Sun.COM 			break;
8067836SJohn.Forte@Sun.COM 		}
8077836SJohn.Forte@Sun.COM 	}
8087836SJohn.Forte@Sun.COM 	cur_iport_for_irp_loop = NULL;
8097836SJohn.Forte@Sun.COM 	return (ret);
8107836SJohn.Forte@Sun.COM }
8117836SJohn.Forte@Sun.COM 
8127836SJohn.Forte@Sun.COM /*ARGSUSED*/
8137836SJohn.Forte@Sun.COM static int
stmf_find_fct_irp(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)8147836SJohn.Forte@Sun.COM stmf_find_fct_irp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
8157836SJohn.Forte@Sun.COM {
8167836SJohn.Forte@Sun.COM 	struct stmf_i_local_port *siport;
8177836SJohn.Forte@Sun.COM 	struct find_options *options;
8187836SJohn.Forte@Sun.COM 	fct_i_remote_port_t *irpp;
8197836SJohn.Forte@Sun.COM 	mdb_walk_state_t ws = {NULL, };
8207836SJohn.Forte@Sun.COM 
8217836SJohn.Forte@Sun.COM 	options = parse_options(argc, argv);
8227836SJohn.Forte@Sun.COM 	/* need to free options manually ? */
8237836SJohn.Forte@Sun.COM 	if (options == NULL || (options->rpname_defined == 0 &&
8247836SJohn.Forte@Sun.COM 	    options->rp_defined == 0)) {
8257836SJohn.Forte@Sun.COM 		mdb_printf("rpname=<wwn.12345678> or rp=<3000586778734>"
8267836SJohn.Forte@Sun.COM 		    " should be specified\n");
8277836SJohn.Forte@Sun.COM 		return (DCMD_OK);
8287836SJohn.Forte@Sun.COM 	}
8297836SJohn.Forte@Sun.COM 	if (options->rpname_defined && options->rp_defined) {
8307836SJohn.Forte@Sun.COM 		mdb_printf("rpname=<wwn.12345678> or rp=<3000586778734>"
8317836SJohn.Forte@Sun.COM 		    " should be specified, but not both\n");
8327836SJohn.Forte@Sun.COM 		return (DCMD_OK);
8337836SJohn.Forte@Sun.COM 	}
8347836SJohn.Forte@Sun.COM 
8357836SJohn.Forte@Sun.COM 	if (options->rp_defined) {
8367836SJohn.Forte@Sun.COM 		siport = irp_to_ilport(options->rp);
8377836SJohn.Forte@Sun.COM 		if (siport != NULL)
8387836SJohn.Forte@Sun.COM 			mdb_printf("stmf_i_local_port=%p,"
8397836SJohn.Forte@Sun.COM 			    " fct_i_remote_port=%p\n",
8407836SJohn.Forte@Sun.COM 			    siport, options->rp);
8417836SJohn.Forte@Sun.COM 		return (DCMD_OK);
8427836SJohn.Forte@Sun.COM 	}
8437836SJohn.Forte@Sun.COM 
8447836SJohn.Forte@Sun.COM 	/* if options->rpname_defined */
8457836SJohn.Forte@Sun.COM 	while ((siport = next_stmf_port(&ws)) != NULL) {
8467836SJohn.Forte@Sun.COM 		if ((irpp = find_irp_by_wwn(siport, options->rpname)) != NULL)
8477836SJohn.Forte@Sun.COM 			mdb_printf("stmf_i_local_port=%p, "
8487836SJohn.Forte@Sun.COM 			    "fct_i_remote_port=%p\n",
8497836SJohn.Forte@Sun.COM 			    siport, irpp);
8507836SJohn.Forte@Sun.COM 	}
8517836SJohn.Forte@Sun.COM 
8527836SJohn.Forte@Sun.COM 	return (DCMD_OK);
8537836SJohn.Forte@Sun.COM }
8547836SJohn.Forte@Sun.COM 
8557836SJohn.Forte@Sun.COM typedef void (*cmd_filter_t) (struct fct_i_cmd *,
8567836SJohn.Forte@Sun.COM     struct find_options *, void *);
8577836SJohn.Forte@Sun.COM 
8587836SJohn.Forte@Sun.COM /*ARGSUSED*/
8597836SJohn.Forte@Sun.COM static void
print_tasks(struct fct_i_cmd * icmdp,struct find_options * options,void * arg)8607836SJohn.Forte@Sun.COM print_tasks(struct fct_i_cmd *icmdp, struct find_options *options, void *arg)
8617836SJohn.Forte@Sun.COM {
8627836SJohn.Forte@Sun.COM 	struct fct_i_cmd icmd;
8637836SJohn.Forte@Sun.COM 	struct fct_cmd cmd;
8647836SJohn.Forte@Sun.COM 
8657836SJohn.Forte@Sun.COM 	if (mdb_vread(&icmd, sizeof (struct fct_i_cmd),
8667836SJohn.Forte@Sun.COM 	    (uintptr_t)icmdp) != sizeof (struct fct_i_cmd)) {
8677836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in fct_i_cmd\n");
8687836SJohn.Forte@Sun.COM 		return;
8697836SJohn.Forte@Sun.COM 	}
8707836SJohn.Forte@Sun.COM 	if (mdb_vread(&cmd, sizeof (struct fct_cmd),
8717836SJohn.Forte@Sun.COM 	    (uintptr_t)icmd.icmd_cmd) != sizeof (struct fct_cmd)) {
8727836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in fct_cmd\n");
8737836SJohn.Forte@Sun.COM 		return;
8747836SJohn.Forte@Sun.COM 	}
8757836SJohn.Forte@Sun.COM 
8767836SJohn.Forte@Sun.COM 	if (cmd.cmd_type == FCT_CMD_FCP_XCHG) {
8777836SJohn.Forte@Sun.COM 		struct scsi_task task;
8787836SJohn.Forte@Sun.COM 		int colon_printed = 0;
8797836SJohn.Forte@Sun.COM 
8807836SJohn.Forte@Sun.COM 		if (mdb_vread(&task, sizeof (struct scsi_task),
8817836SJohn.Forte@Sun.COM 		    (uintptr_t)cmd.cmd_specific)
8827836SJohn.Forte@Sun.COM 		    != sizeof (struct scsi_task)) {
8837836SJohn.Forte@Sun.COM 			mdb_warn("Unable to read in scsi_task\n");
8847836SJohn.Forte@Sun.COM 			return;
8857836SJohn.Forte@Sun.COM 		}
8867836SJohn.Forte@Sun.COM 
8877836SJohn.Forte@Sun.COM 		mdb_printf("%p", cmd.cmd_specific);
8887836SJohn.Forte@Sun.COM 		if (options->show_task_flags) {
8897836SJohn.Forte@Sun.COM 			mdb_printf(":");
8907836SJohn.Forte@Sun.COM 			colon_printed = 1;
8917836SJohn.Forte@Sun.COM 			mdb_printf(" task_flags=%x", task.task_flags);
8927836SJohn.Forte@Sun.COM 		}
8937836SJohn.Forte@Sun.COM 
8947836SJohn.Forte@Sun.COM 		if (options->show_lport) {
8957836SJohn.Forte@Sun.COM 			if (colon_printed == 0) {
8967836SJohn.Forte@Sun.COM 				mdb_printf(":");
8977836SJohn.Forte@Sun.COM 				colon_printed = 1;
8987836SJohn.Forte@Sun.COM 			}
8997836SJohn.Forte@Sun.COM 			mdb_printf(" lport=%p", task.task_lport);
9007836SJohn.Forte@Sun.COM 		}
9017836SJohn.Forte@Sun.COM 		mdb_printf("\n");
9027836SJohn.Forte@Sun.COM 	}
9037836SJohn.Forte@Sun.COM }
9047836SJohn.Forte@Sun.COM 
9057836SJohn.Forte@Sun.COM static void
print_tasks_on_rp(struct fct_i_cmd * icmdp,struct find_options * options,void * arg)9067836SJohn.Forte@Sun.COM print_tasks_on_rp(struct fct_i_cmd *icmdp, struct find_options *options,
9077836SJohn.Forte@Sun.COM     void *arg)
9087836SJohn.Forte@Sun.COM {
9097836SJohn.Forte@Sun.COM 	struct fct_i_cmd icmd;
9107836SJohn.Forte@Sun.COM 	struct fct_cmd cmd;
9117836SJohn.Forte@Sun.COM 	fct_i_remote_port_t irp;
9127836SJohn.Forte@Sun.COM 
9137836SJohn.Forte@Sun.COM 	if (mdb_vread(&icmd, sizeof (struct fct_i_cmd),
9147836SJohn.Forte@Sun.COM 	    (uintptr_t)icmdp) != sizeof (struct fct_i_cmd)) {
9157836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in fct_i_cmd\n");
9167836SJohn.Forte@Sun.COM 		return;
9177836SJohn.Forte@Sun.COM 	}
9187836SJohn.Forte@Sun.COM 	if (mdb_vread(&cmd, sizeof (struct fct_cmd),
9197836SJohn.Forte@Sun.COM 	    (uintptr_t)icmd.icmd_cmd) != sizeof (struct fct_cmd)) {
9207836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in fct_cmd\n");
9217836SJohn.Forte@Sun.COM 		return;
9227836SJohn.Forte@Sun.COM 	}
9237836SJohn.Forte@Sun.COM 
9247836SJohn.Forte@Sun.COM 	/* arg is a pointer to fct_i_remote_port */
9257836SJohn.Forte@Sun.COM 	if (mdb_vread(&irp, sizeof (struct fct_i_remote_port),
9267836SJohn.Forte@Sun.COM 	    (uintptr_t)arg) != sizeof (struct fct_i_remote_port)) {
9277836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in fct_i_remote_port\n");
9287836SJohn.Forte@Sun.COM 		return;
9297836SJohn.Forte@Sun.COM 	}
9307836SJohn.Forte@Sun.COM 
9317836SJohn.Forte@Sun.COM 	if (cmd.cmd_type == FCT_CMD_FCP_XCHG && cmd.cmd_rp == irp.irp_rp) {
9327836SJohn.Forte@Sun.COM 		struct scsi_task task;
9337836SJohn.Forte@Sun.COM 		int colon_printed = 0;
9347836SJohn.Forte@Sun.COM 
9357836SJohn.Forte@Sun.COM 		if (mdb_vread(&task, sizeof (struct scsi_task),
9367836SJohn.Forte@Sun.COM 		    (uintptr_t)cmd.cmd_specific)
9377836SJohn.Forte@Sun.COM 		    != sizeof (struct scsi_task)) {
9387836SJohn.Forte@Sun.COM 			mdb_warn("Unable to read in scsi_task\n");
9397836SJohn.Forte@Sun.COM 			return;
9407836SJohn.Forte@Sun.COM 		}
9417836SJohn.Forte@Sun.COM 
9427836SJohn.Forte@Sun.COM 		mdb_printf("%p", cmd.cmd_specific);
9437836SJohn.Forte@Sun.COM 		if (options->show_task_flags) {
9447836SJohn.Forte@Sun.COM 			mdb_printf(":");
9457836SJohn.Forte@Sun.COM 			colon_printed = 1;
9467836SJohn.Forte@Sun.COM 			mdb_printf(" task_flags=%x", task.task_flags);
9477836SJohn.Forte@Sun.COM 		}
9487836SJohn.Forte@Sun.COM 
9497836SJohn.Forte@Sun.COM 		if (options->show_lport) {
9507836SJohn.Forte@Sun.COM 			if (colon_printed == 0) {
9517836SJohn.Forte@Sun.COM 				mdb_printf(":");
9527836SJohn.Forte@Sun.COM 				colon_printed = 1;
9537836SJohn.Forte@Sun.COM 			}
9547836SJohn.Forte@Sun.COM 			mdb_printf(" lport=%p", task.task_lport);
9557836SJohn.Forte@Sun.COM 		}
9567836SJohn.Forte@Sun.COM 		mdb_printf("\n");
9577836SJohn.Forte@Sun.COM 	}
9587836SJohn.Forte@Sun.COM }
9597836SJohn.Forte@Sun.COM 
9607836SJohn.Forte@Sun.COM /*ARGSUSED*/
9617836SJohn.Forte@Sun.COM static void
print_all_cmds(struct fct_i_cmd * icmd,struct find_options * options,void * arg)9627836SJohn.Forte@Sun.COM print_all_cmds(struct fct_i_cmd *icmd, struct find_options *options, void *arg)
9637836SJohn.Forte@Sun.COM {
9647836SJohn.Forte@Sun.COM 	mdb_printf("%p\n", icmd);
9657836SJohn.Forte@Sun.COM }
9667836SJohn.Forte@Sun.COM 
9677836SJohn.Forte@Sun.COM /*
9687836SJohn.Forte@Sun.COM  * find outstanding cmds (fct_i_cmd) on local port
9697836SJohn.Forte@Sun.COM  */
9707836SJohn.Forte@Sun.COM static int
outstanding_cmds_on_lport(struct stmf_i_local_port * siport,cmd_filter_t filter,struct find_options * options,void * arg)9717836SJohn.Forte@Sun.COM outstanding_cmds_on_lport(struct stmf_i_local_port *siport, cmd_filter_t filter,
9727836SJohn.Forte@Sun.COM     struct find_options *options, void *arg)
9737836SJohn.Forte@Sun.COM {
9747836SJohn.Forte@Sun.COM 	struct fct_i_local_port *iportp;
9757836SJohn.Forte@Sun.COM 	struct fct_i_local_port iport;
9767836SJohn.Forte@Sun.COM 	struct fct_local_port port;
9777836SJohn.Forte@Sun.COM 	struct fct_cmd_slot *slotp;
9787836SJohn.Forte@Sun.COM 	struct fct_cmd_slot slot;
9797836SJohn.Forte@Sun.COM 	int i;
9807836SJohn.Forte@Sun.COM 
9817836SJohn.Forte@Sun.COM 	iportp = __ilport2iport((uintptr_t)siport, DCMD_ADDRSPEC, 0, NULL);
9827836SJohn.Forte@Sun.COM 	if (iportp == NULL)
9837836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
9847836SJohn.Forte@Sun.COM 
9857836SJohn.Forte@Sun.COM 	if (mdb_vread(&iport, sizeof (struct fct_i_local_port),
9867836SJohn.Forte@Sun.COM 	    (uintptr_t)iportp) != sizeof (struct fct_i_local_port)) {
9877836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in fct_i_local_port\n");
9887836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
9897836SJohn.Forte@Sun.COM 	}
9907836SJohn.Forte@Sun.COM 	if (mdb_vread(&port, sizeof (struct fct_local_port),
9917836SJohn.Forte@Sun.COM 	    (uintptr_t)iport.iport_port) != sizeof (struct fct_local_port)) {
9927836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in fct_local_port\n");
9937836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
9947836SJohn.Forte@Sun.COM 	}
9957836SJohn.Forte@Sun.COM 
9967836SJohn.Forte@Sun.COM 	slotp = iport.iport_cmd_slots;
9977836SJohn.Forte@Sun.COM 	for (i = 0; i < port.port_max_xchges; i++) {
9987836SJohn.Forte@Sun.COM 		if (mdb_vread(&slot, sizeof (struct fct_cmd_slot),
9997836SJohn.Forte@Sun.COM 		    (uintptr_t)slotp) != sizeof (struct fct_cmd_slot)) {
10007836SJohn.Forte@Sun.COM 			mdb_warn("Unable to read in fct_cmd_slot\n");
10017836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
10027836SJohn.Forte@Sun.COM 		}
10037836SJohn.Forte@Sun.COM 		if (slot.slot_cmd != NULL) {
10047836SJohn.Forte@Sun.COM 			if (filter == NULL)
10057836SJohn.Forte@Sun.COM 				mdb_printf("%p\n", slot.slot_cmd);
10067836SJohn.Forte@Sun.COM 			else
10077836SJohn.Forte@Sun.COM 				filter(slot.slot_cmd, options, arg);
10087836SJohn.Forte@Sun.COM 		}
10097836SJohn.Forte@Sun.COM 		slotp ++;
10107836SJohn.Forte@Sun.COM 	}
10117836SJohn.Forte@Sun.COM 
10127836SJohn.Forte@Sun.COM 	return (DCMD_OK);
10137836SJohn.Forte@Sun.COM }
10147836SJohn.Forte@Sun.COM 
10157836SJohn.Forte@Sun.COM /*ARGSUSED*/
10167836SJohn.Forte@Sun.COM static int
stmf_find_tasks(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)10177836SJohn.Forte@Sun.COM stmf_find_tasks(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
10187836SJohn.Forte@Sun.COM {
10197836SJohn.Forte@Sun.COM 	struct find_options *options;
10207836SJohn.Forte@Sun.COM 	struct stmf_i_local_port *siport;
10217836SJohn.Forte@Sun.COM 
10227836SJohn.Forte@Sun.COM 	options = parse_options(argc, argv);
10237836SJohn.Forte@Sun.COM 	if (options == NULL ||
10247836SJohn.Forte@Sun.COM 	    (options->lpname_defined == 0 && options->rpname_defined == 0)) {
10257836SJohn.Forte@Sun.COM 		mdb_printf("lpname=<wwn.12345678> or rpname=<wwn.12345678>"
10267836SJohn.Forte@Sun.COM 		    " should be specified\n");
10277836SJohn.Forte@Sun.COM 		return (DCMD_OK);
10287836SJohn.Forte@Sun.COM 	}
10297836SJohn.Forte@Sun.COM 
10307836SJohn.Forte@Sun.COM 	if (options->lpname_defined) {
10317836SJohn.Forte@Sun.COM 		siport = find_lport_by_wwn(options->lpname);
10327836SJohn.Forte@Sun.COM 		if (siport == NULL)
10337836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
10347836SJohn.Forte@Sun.COM 
10357836SJohn.Forte@Sun.COM 		outstanding_cmds_on_lport(siport, print_tasks, options, NULL);
10367836SJohn.Forte@Sun.COM 		return (DCMD_OK);
10377836SJohn.Forte@Sun.COM 	}
10387836SJohn.Forte@Sun.COM 
10397836SJohn.Forte@Sun.COM 	if (options->rpname_defined) {
10407836SJohn.Forte@Sun.COM 		mdb_walk_state_t ws = {NULL, };
10417836SJohn.Forte@Sun.COM 		fct_i_remote_port_t *irpp;
10427836SJohn.Forte@Sun.COM 
10437836SJohn.Forte@Sun.COM 		while ((siport = next_stmf_port(&ws)) != NULL) {
10447836SJohn.Forte@Sun.COM 			if ((irpp = find_irp_by_wwn(siport, options->rpname))
10457836SJohn.Forte@Sun.COM 			    != NULL) {
10467836SJohn.Forte@Sun.COM 				outstanding_cmds_on_lport(siport,
10477836SJohn.Forte@Sun.COM 				    print_tasks_on_rp, options, irpp);
10487836SJohn.Forte@Sun.COM 			}
10497836SJohn.Forte@Sun.COM 		}
10507836SJohn.Forte@Sun.COM 	}
10517836SJohn.Forte@Sun.COM 
10527836SJohn.Forte@Sun.COM 	return (DCMD_OK);
10537836SJohn.Forte@Sun.COM }
10547836SJohn.Forte@Sun.COM 
10557836SJohn.Forte@Sun.COM /*ARGSUSED*/
10567836SJohn.Forte@Sun.COM static int
fct_find_cmds(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)10577836SJohn.Forte@Sun.COM fct_find_cmds(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
10587836SJohn.Forte@Sun.COM {
10597836SJohn.Forte@Sun.COM 	struct find_options *options;
10607836SJohn.Forte@Sun.COM 	struct stmf_i_local_port *siport;
10617836SJohn.Forte@Sun.COM 
10627836SJohn.Forte@Sun.COM 	options = parse_options(argc, argv);
10637836SJohn.Forte@Sun.COM 	if (options == NULL || options->lpname_defined == 0) {
10647836SJohn.Forte@Sun.COM 		mdb_printf("lpname=<wwn.12345678> should be specified\n");
10657836SJohn.Forte@Sun.COM 		return (DCMD_OK);
10667836SJohn.Forte@Sun.COM 	}
10677836SJohn.Forte@Sun.COM 
10687836SJohn.Forte@Sun.COM 	siport = find_lport_by_wwn(options->lpname);
10697836SJohn.Forte@Sun.COM 	if (siport == NULL)
10707836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
10717836SJohn.Forte@Sun.COM 
10727836SJohn.Forte@Sun.COM 	outstanding_cmds_on_lport(siport, print_all_cmds, options, NULL);
10737836SJohn.Forte@Sun.COM 	return (DCMD_OK);
10747836SJohn.Forte@Sun.COM }
10757836SJohn.Forte@Sun.COM 
10767836SJohn.Forte@Sun.COM static int
fct_icmds(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)10777836SJohn.Forte@Sun.COM fct_icmds(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
10787836SJohn.Forte@Sun.COM {
10797836SJohn.Forte@Sun.COM 	struct fct_i_local_port iport;
10807836SJohn.Forte@Sun.COM 	struct fct_i_cmd icmd;
10817836SJohn.Forte@Sun.COM 	struct fct_i_cmd *icmdp;
10827836SJohn.Forte@Sun.COM 	int i;
10837836SJohn.Forte@Sun.COM 	int verbose = 0;
10847836SJohn.Forte@Sun.COM 
10857836SJohn.Forte@Sun.COM 	for (i = 0; i < argc; i++) {
10867836SJohn.Forte@Sun.COM 		char *ptr = (char *)argv[i].a_un.a_str;
10877836SJohn.Forte@Sun.COM 
10887836SJohn.Forte@Sun.COM 		if (ptr[0] == '-')
10897836SJohn.Forte@Sun.COM 			ptr++;
10907836SJohn.Forte@Sun.COM 		while (*ptr) {
10917836SJohn.Forte@Sun.COM 			if (*ptr == 'v')
10927836SJohn.Forte@Sun.COM 				verbose = 1;
10937836SJohn.Forte@Sun.COM 			ptr++;
10947836SJohn.Forte@Sun.COM 		}
10957836SJohn.Forte@Sun.COM 	}
10967836SJohn.Forte@Sun.COM 
10977836SJohn.Forte@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
10987836SJohn.Forte@Sun.COM 		mdb_warn("fct_i_local_port_t address should be specified");
10997836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
11007836SJohn.Forte@Sun.COM 	}
11017836SJohn.Forte@Sun.COM 
11027836SJohn.Forte@Sun.COM 	if (mdb_vread(&iport, sizeof (struct fct_i_local_port), addr)
11037836SJohn.Forte@Sun.COM 	    != sizeof (struct fct_i_local_port)) {
11047836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in fct_i_local_port at %p\n", addr);
11057836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
11067836SJohn.Forte@Sun.COM 	}
11077836SJohn.Forte@Sun.COM 
11087836SJohn.Forte@Sun.COM 	icmdp = iport.iport_cached_cmdlist;
11097836SJohn.Forte@Sun.COM 	while (icmdp) {
11107836SJohn.Forte@Sun.COM 		if (mdb_vread(&icmd, sizeof (struct fct_i_cmd),
11117836SJohn.Forte@Sun.COM 		    (uintptr_t)icmdp) == -1) {
11127836SJohn.Forte@Sun.COM 			mdb_warn("failed to read fct_i_cmd at %p", icmdp);
11137836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
11147836SJohn.Forte@Sun.COM 		}
11157836SJohn.Forte@Sun.COM 
11167836SJohn.Forte@Sun.COM 		mdb_printf("%p\n", icmdp);
11177836SJohn.Forte@Sun.COM 		if (verbose) {
11187836SJohn.Forte@Sun.COM 			mdb_printf("  fct cmd: %p\n", icmd.icmd_cmd);
11197836SJohn.Forte@Sun.COM 		}
11207836SJohn.Forte@Sun.COM 
11217836SJohn.Forte@Sun.COM 		icmdp = icmd.icmd_next;
11227836SJohn.Forte@Sun.COM 	}
11237836SJohn.Forte@Sun.COM 
11247836SJohn.Forte@Sun.COM 	return (DCMD_OK);
11257836SJohn.Forte@Sun.COM }
11267836SJohn.Forte@Sun.COM 
11279176SPriya.Krishnan@Sun.COM /*
11289176SPriya.Krishnan@Sun.COM  * Walker to list the addresses of all the active STMF scsi tasks (scsi_task_t),
11299176SPriya.Krishnan@Sun.COM  * given a stmf_worker address
11309176SPriya.Krishnan@Sun.COM  *
11319176SPriya.Krishnan@Sun.COM  * To list all the active STMF scsi tasks, use
11329176SPriya.Krishnan@Sun.COM  * "::walk stmf_worker |::walk stmf_scsi_task"
11339176SPriya.Krishnan@Sun.COM  * To list the active tasks of a particular worker, use
11349176SPriya.Krishnan@Sun.COM  * <stmf_worker addr>::walk stmf_scsi_task
11359176SPriya.Krishnan@Sun.COM  */
11369176SPriya.Krishnan@Sun.COM static int
stmf_scsi_task_walk_init(mdb_walk_state_t * wsp)11379176SPriya.Krishnan@Sun.COM stmf_scsi_task_walk_init(mdb_walk_state_t *wsp)
11389176SPriya.Krishnan@Sun.COM {
11399176SPriya.Krishnan@Sun.COM 	stmf_worker_t	worker;
11409176SPriya.Krishnan@Sun.COM 
11419176SPriya.Krishnan@Sun.COM 	/*
11429176SPriya.Krishnan@Sun.COM 	 * Input should be a stmf_worker, so read it to get the
11439176SPriya.Krishnan@Sun.COM 	 * worker_task_head to get the start of the task list
11449176SPriya.Krishnan@Sun.COM 	 */
11459176SPriya.Krishnan@Sun.COM 	if (wsp->walk_addr == NULL) {
11469176SPriya.Krishnan@Sun.COM 		mdb_warn("<worker addr>::walk stmf_scsi_task\n");
11479176SPriya.Krishnan@Sun.COM 		return (WALK_ERR);
11489176SPriya.Krishnan@Sun.COM 	}
11499176SPriya.Krishnan@Sun.COM 
11509176SPriya.Krishnan@Sun.COM 	if (mdb_vread(&worker, sizeof (stmf_worker_t), wsp->walk_addr) !=
11519176SPriya.Krishnan@Sun.COM 	    sizeof (stmf_worker_t)) {
11529176SPriya.Krishnan@Sun.COM 		mdb_warn("failed to read in the task address\n");
11539176SPriya.Krishnan@Sun.COM 		return (WALK_ERR);
11549176SPriya.Krishnan@Sun.COM 	}
11559176SPriya.Krishnan@Sun.COM 
11569176SPriya.Krishnan@Sun.COM 	wsp->walk_addr = (uintptr_t)(worker.worker_task_head);
11579176SPriya.Krishnan@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (scsi_task_t), UM_SLEEP);
11589176SPriya.Krishnan@Sun.COM 
11599176SPriya.Krishnan@Sun.COM 	return (WALK_NEXT);
11609176SPriya.Krishnan@Sun.COM }
11619176SPriya.Krishnan@Sun.COM 
11629176SPriya.Krishnan@Sun.COM static int
stmf_scsi_task_walk_step(mdb_walk_state_t * wsp)11639176SPriya.Krishnan@Sun.COM stmf_scsi_task_walk_step(mdb_walk_state_t *wsp)
11649176SPriya.Krishnan@Sun.COM {
11659176SPriya.Krishnan@Sun.COM 	stmf_i_scsi_task_t	itask;
11669176SPriya.Krishnan@Sun.COM 	int			status;
11679176SPriya.Krishnan@Sun.COM 
11689176SPriya.Krishnan@Sun.COM 	if (wsp->walk_addr == NULL) {
11699176SPriya.Krishnan@Sun.COM 		return (WALK_DONE);
11709176SPriya.Krishnan@Sun.COM 	}
11719176SPriya.Krishnan@Sun.COM 
11729176SPriya.Krishnan@Sun.COM 	/* Save the stmf_i_scsi_task for use later to get the next entry */
11739176SPriya.Krishnan@Sun.COM 	if (mdb_vread(&itask, sizeof (stmf_i_scsi_task_t),
11749176SPriya.Krishnan@Sun.COM 	    wsp->walk_addr) != sizeof (stmf_i_scsi_task_t)) {
11759176SPriya.Krishnan@Sun.COM 		mdb_warn("failed to read stmf_i_scsi_task at %p",
11769176SPriya.Krishnan@Sun.COM 		    wsp->walk_addr);
11779176SPriya.Krishnan@Sun.COM 		return (WALK_DONE);
11789176SPriya.Krishnan@Sun.COM 	}
11799176SPriya.Krishnan@Sun.COM 
11809176SPriya.Krishnan@Sun.COM 	wsp->walk_addr = (uintptr_t)itask.itask_task;
11819176SPriya.Krishnan@Sun.COM 
11829176SPriya.Krishnan@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (scsi_task_t),
11839176SPriya.Krishnan@Sun.COM 	    wsp->walk_addr) != sizeof (scsi_task_t)) {
11849176SPriya.Krishnan@Sun.COM 		mdb_warn("failed to read scsi_task_t at %p", wsp->walk_addr);
11859176SPriya.Krishnan@Sun.COM 		return (DCMD_ERR);
11869176SPriya.Krishnan@Sun.COM 	}
11879176SPriya.Krishnan@Sun.COM 
11889176SPriya.Krishnan@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
11899176SPriya.Krishnan@Sun.COM 	    wsp->walk_cbdata);
11909176SPriya.Krishnan@Sun.COM 
11919176SPriya.Krishnan@Sun.COM 	wsp->walk_addr = (uintptr_t)(itask.itask_worker_next);
11929176SPriya.Krishnan@Sun.COM 
11939176SPriya.Krishnan@Sun.COM 	return (status);
11949176SPriya.Krishnan@Sun.COM }
11959176SPriya.Krishnan@Sun.COM 
11969176SPriya.Krishnan@Sun.COM static void
stmf_scsi_task_walk_fini(mdb_walk_state_t * wsp)11979176SPriya.Krishnan@Sun.COM stmf_scsi_task_walk_fini(mdb_walk_state_t *wsp)
11989176SPriya.Krishnan@Sun.COM {
11999176SPriya.Krishnan@Sun.COM 	mdb_free(wsp->walk_data, sizeof (scsi_task_t));
12009176SPriya.Krishnan@Sun.COM }
12019176SPriya.Krishnan@Sun.COM 
12029176SPriya.Krishnan@Sun.COM /*ARGSUSED*/
12039176SPriya.Krishnan@Sun.COM static int
stmf_scsi_task(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)12049176SPriya.Krishnan@Sun.COM stmf_scsi_task(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
12059176SPriya.Krishnan@Sun.COM {
12069176SPriya.Krishnan@Sun.COM 	stmf_worker_t		worker;
12079176SPriya.Krishnan@Sun.COM 	stmf_i_scsi_task_t	itask;
12089176SPriya.Krishnan@Sun.COM 	scsi_task_t		*task_addr, task;
12099176SPriya.Krishnan@Sun.COM 
12109176SPriya.Krishnan@Sun.COM 	/*
12119176SPriya.Krishnan@Sun.COM 	 * A stmf_worker address is given to the left of ::stmf_scsi_task
12129176SPriya.Krishnan@Sun.COM 	 * i.e. display the scsi_task for the given worker
12139176SPriya.Krishnan@Sun.COM 	 */
12149176SPriya.Krishnan@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
12159176SPriya.Krishnan@Sun.COM 		if (mdb_walk_dcmd("stmf_worker", "stmf_scsi_task", argc,
12169176SPriya.Krishnan@Sun.COM 		    argv) == -1) {
12179176SPriya.Krishnan@Sun.COM 			mdb_warn("Failed to walk the stmf_scsi_task entries");
12189176SPriya.Krishnan@Sun.COM 			return (DCMD_ERR);
12199176SPriya.Krishnan@Sun.COM 		}
12209176SPriya.Krishnan@Sun.COM 		return (DCMD_OK);
12219176SPriya.Krishnan@Sun.COM 	}
12229176SPriya.Krishnan@Sun.COM 
12239176SPriya.Krishnan@Sun.COM 	if (DCMD_HDRSPEC(flags) && (!(flags & DCMD_PIPE_OUT))) {
12249176SPriya.Krishnan@Sun.COM 		mdb_printf("%<u>%-19s %-10s %-19s%</u>\n",
12259176SPriya.Krishnan@Sun.COM 		    "scsi_task_t", "Flags", "LPort");
12269176SPriya.Krishnan@Sun.COM 	}
12279176SPriya.Krishnan@Sun.COM 
12289176SPriya.Krishnan@Sun.COM 	if (mdb_vread(&worker, sizeof (stmf_worker_t),
12299176SPriya.Krishnan@Sun.COM 	    addr) != sizeof (stmf_worker_t)) {
12309176SPriya.Krishnan@Sun.COM 		mdb_warn("failed to read in the worker address");
12319176SPriya.Krishnan@Sun.COM 		return (DCMD_ERR);
12329176SPriya.Krishnan@Sun.COM 	}
12339176SPriya.Krishnan@Sun.COM 
12349176SPriya.Krishnan@Sun.COM 	/* Read the scsi_task */
12359176SPriya.Krishnan@Sun.COM 	if (worker.worker_task_head == NULL) {
12369176SPriya.Krishnan@Sun.COM 		return (DCMD_OK);
12379176SPriya.Krishnan@Sun.COM 	}
12389176SPriya.Krishnan@Sun.COM 
12399176SPriya.Krishnan@Sun.COM 	if (mdb_vread(&itask, sizeof (stmf_i_scsi_task_t),
12409176SPriya.Krishnan@Sun.COM 	    (uintptr_t)worker.worker_task_head) == -1) {
12419176SPriya.Krishnan@Sun.COM 		mdb_warn("failed to read stmf_i_scsi_task_t at %p",
12429176SPriya.Krishnan@Sun.COM 		    worker.worker_task_head);
12439176SPriya.Krishnan@Sun.COM 		return (DCMD_ERR);
12449176SPriya.Krishnan@Sun.COM 	}
12459176SPriya.Krishnan@Sun.COM 
12469176SPriya.Krishnan@Sun.COM 	task_addr = itask.itask_task;
12479176SPriya.Krishnan@Sun.COM 
12489176SPriya.Krishnan@Sun.COM 	if (mdb_vread(&task, sizeof (scsi_task_t),
12499176SPriya.Krishnan@Sun.COM 	    (uintptr_t)task_addr) != sizeof (scsi_task_t)) {
12509176SPriya.Krishnan@Sun.COM 		mdb_warn("failed to read scsi_task_t at %p", task_addr);
12519176SPriya.Krishnan@Sun.COM 		return (DCMD_ERR);
12529176SPriya.Krishnan@Sun.COM 	}
12539176SPriya.Krishnan@Sun.COM 
12549176SPriya.Krishnan@Sun.COM 	if ((flags & DCMD_PIPE_OUT)) {
12559176SPriya.Krishnan@Sun.COM 		mdb_printf("%p\n", task_addr);
12569176SPriya.Krishnan@Sun.COM 	} else {
12579176SPriya.Krishnan@Sun.COM 		/* pretty print */
12589176SPriya.Krishnan@Sun.COM 		mdb_printf("%-19p %-10x %-19p\n",
12599176SPriya.Krishnan@Sun.COM 		    task_addr, task.task_flags, task.task_lport);
12609176SPriya.Krishnan@Sun.COM 	}
12619176SPriya.Krishnan@Sun.COM 
12629176SPriya.Krishnan@Sun.COM 	return (DCMD_OK);
12639176SPriya.Krishnan@Sun.COM }
12649176SPriya.Krishnan@Sun.COM 
12659176SPriya.Krishnan@Sun.COM /*
12669176SPriya.Krishnan@Sun.COM  * Walker to list the addresses of all the stmf_worker in the queue
12679176SPriya.Krishnan@Sun.COM  */
12689176SPriya.Krishnan@Sun.COM typedef struct stmf_worker_walk_data {
12699176SPriya.Krishnan@Sun.COM 	int		worker_current;
12709176SPriya.Krishnan@Sun.COM 	int		worker_count;
12719176SPriya.Krishnan@Sun.COM } stmf_worker_walk_data_t;
12729176SPriya.Krishnan@Sun.COM 
12739176SPriya.Krishnan@Sun.COM /* stmf_workers_state definition from stmf.c (static) */
12749176SPriya.Krishnan@Sun.COM enum {
12759176SPriya.Krishnan@Sun.COM 	STMF_WORKERS_DISABLED = 0,
12769176SPriya.Krishnan@Sun.COM 	STMF_WORKERS_ENABLING,
12779176SPriya.Krishnan@Sun.COM 	STMF_WORKERS_ENABLED
12789176SPriya.Krishnan@Sun.COM } stmf_workers_state;
12799176SPriya.Krishnan@Sun.COM 
12809176SPriya.Krishnan@Sun.COM /*
12819176SPriya.Krishnan@Sun.COM  * Initialize the stmf_worker_t walker by either using the given starting
12829176SPriya.Krishnan@Sun.COM  * address, or reading the value of the kernel's global stmf_workers pointer.
12839176SPriya.Krishnan@Sun.COM  */
12849176SPriya.Krishnan@Sun.COM /*ARGSUSED*/
12859176SPriya.Krishnan@Sun.COM static int
stmf_worker_walk_init(mdb_walk_state_t * wsp)12869176SPriya.Krishnan@Sun.COM stmf_worker_walk_init(mdb_walk_state_t *wsp)
12879176SPriya.Krishnan@Sun.COM {
12889176SPriya.Krishnan@Sun.COM 	int			worker_state;
12899176SPriya.Krishnan@Sun.COM 	int			nworkers;
12909176SPriya.Krishnan@Sun.COM 	stmf_worker_t		*worker;
12919176SPriya.Krishnan@Sun.COM 	stmf_worker_walk_data_t	*walk_data;
12929176SPriya.Krishnan@Sun.COM 
12939176SPriya.Krishnan@Sun.COM 	if (mdb_readvar(&worker_state, "stmf_workers_state") == -1) {
12949176SPriya.Krishnan@Sun.COM 		mdb_warn("failed to read stmf_workers_state");
12959176SPriya.Krishnan@Sun.COM 		return (WALK_ERR);
12969176SPriya.Krishnan@Sun.COM 	}
12979176SPriya.Krishnan@Sun.COM 	if (worker_state != STMF_WORKERS_ENABLED) {
12989176SPriya.Krishnan@Sun.COM 		mdb_warn("stmf_workers_state not initialized");
12999176SPriya.Krishnan@Sun.COM 		return (WALK_ERR);
13009176SPriya.Krishnan@Sun.COM 	}
13019176SPriya.Krishnan@Sun.COM 
13029176SPriya.Krishnan@Sun.COM 	/*
13039176SPriya.Krishnan@Sun.COM 	 * Look up the stmf_nworkers_accepting_cmds to
13049176SPriya.Krishnan@Sun.COM 	 * determine number of entries in the worker queue
13059176SPriya.Krishnan@Sun.COM 	 */
13069176SPriya.Krishnan@Sun.COM 	if (mdb_readvar(&nworkers, "stmf_nworkers_accepting_cmds") == -1) {
13079176SPriya.Krishnan@Sun.COM 		mdb_warn("failed to read stmf_nworkers_accepting_cmds");
13089176SPriya.Krishnan@Sun.COM 		return (WALK_ERR);
13099176SPriya.Krishnan@Sun.COM 	}
13109176SPriya.Krishnan@Sun.COM 
13119176SPriya.Krishnan@Sun.COM 	if (mdb_readvar(&worker, "stmf_workers") == -1) {
13129176SPriya.Krishnan@Sun.COM 		mdb_warn("failed to read stmf_workers");
13139176SPriya.Krishnan@Sun.COM 		return (WALK_ERR);
13149176SPriya.Krishnan@Sun.COM 	}
13159176SPriya.Krishnan@Sun.COM 
13169176SPriya.Krishnan@Sun.COM 	walk_data = mdb_alloc(sizeof (stmf_worker_walk_data_t), UM_SLEEP);
13179176SPriya.Krishnan@Sun.COM 	walk_data->worker_current	= 0;
13189176SPriya.Krishnan@Sun.COM 	walk_data->worker_count		= nworkers;
13199176SPriya.Krishnan@Sun.COM 
13209176SPriya.Krishnan@Sun.COM 	wsp->walk_addr = (uintptr_t)worker;
13219176SPriya.Krishnan@Sun.COM 	wsp->walk_data = walk_data;
13229176SPriya.Krishnan@Sun.COM 
13239176SPriya.Krishnan@Sun.COM 	return (WALK_NEXT);
13249176SPriya.Krishnan@Sun.COM }
13259176SPriya.Krishnan@Sun.COM 
13269176SPriya.Krishnan@Sun.COM static int
stmf_worker_walk_step(mdb_walk_state_t * wsp)13279176SPriya.Krishnan@Sun.COM stmf_worker_walk_step(mdb_walk_state_t *wsp)
13289176SPriya.Krishnan@Sun.COM {
13299176SPriya.Krishnan@Sun.COM 	stmf_worker_walk_data_t	*walk_data = wsp->walk_data;
13309176SPriya.Krishnan@Sun.COM 	int			status;
13319176SPriya.Krishnan@Sun.COM 
13329176SPriya.Krishnan@Sun.COM 	if (wsp->walk_addr == NULL) {
13339176SPriya.Krishnan@Sun.COM 		return (WALK_DONE);
13349176SPriya.Krishnan@Sun.COM 	}
13359176SPriya.Krishnan@Sun.COM 
13369176SPriya.Krishnan@Sun.COM 	if (walk_data->worker_current >= walk_data->worker_count) {
13379176SPriya.Krishnan@Sun.COM 		return (WALK_DONE);
13389176SPriya.Krishnan@Sun.COM 	}
13399176SPriya.Krishnan@Sun.COM 
13409176SPriya.Krishnan@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
13419176SPriya.Krishnan@Sun.COM 	    wsp->walk_cbdata);
13429176SPriya.Krishnan@Sun.COM 
13439176SPriya.Krishnan@Sun.COM 	walk_data->worker_current++;
13449176SPriya.Krishnan@Sun.COM 	wsp->walk_addr += sizeof (stmf_worker_t);
13459176SPriya.Krishnan@Sun.COM 
13469176SPriya.Krishnan@Sun.COM 	return (status);
13479176SPriya.Krishnan@Sun.COM }
13489176SPriya.Krishnan@Sun.COM 
13499176SPriya.Krishnan@Sun.COM static void
stmf_worker_walk_fini(mdb_walk_state_t * wsp)13509176SPriya.Krishnan@Sun.COM stmf_worker_walk_fini(mdb_walk_state_t *wsp)
13519176SPriya.Krishnan@Sun.COM {
13529176SPriya.Krishnan@Sun.COM 	mdb_free(wsp->walk_data, sizeof (stmf_worker_walk_data_t));
13539176SPriya.Krishnan@Sun.COM }
13549176SPriya.Krishnan@Sun.COM 
13559176SPriya.Krishnan@Sun.COM int
stmf_worker(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)13569176SPriya.Krishnan@Sun.COM stmf_worker(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
13579176SPriya.Krishnan@Sun.COM {
13589176SPriya.Krishnan@Sun.COM 	stmf_worker_t		worker;
13599176SPriya.Krishnan@Sun.COM 
13609176SPriya.Krishnan@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
13619176SPriya.Krishnan@Sun.COM 		if (mdb_walk_dcmd("stmf_worker", "stmf_worker", argc,
13629176SPriya.Krishnan@Sun.COM 		    argv) == -1) {
13639176SPriya.Krishnan@Sun.COM 			mdb_warn("Failed to walk the stmf_worker entries");
13649176SPriya.Krishnan@Sun.COM 			return (DCMD_ERR);
13659176SPriya.Krishnan@Sun.COM 		}
13669176SPriya.Krishnan@Sun.COM 		return (DCMD_OK);
13679176SPriya.Krishnan@Sun.COM 	}
13689176SPriya.Krishnan@Sun.COM 
13699176SPriya.Krishnan@Sun.COM 	if (mdb_vread(&worker, sizeof (stmf_worker_t),
13709176SPriya.Krishnan@Sun.COM 	    addr) != sizeof (stmf_worker_t)) {
13719176SPriya.Krishnan@Sun.COM 		mdb_warn("failed to read stmf_worker at %p", addr);
13729176SPriya.Krishnan@Sun.COM 		return (DCMD_ERR);
13739176SPriya.Krishnan@Sun.COM 	}
13749176SPriya.Krishnan@Sun.COM 
13759176SPriya.Krishnan@Sun.COM 	if (flags & DCMD_PIPE_OUT) {
13769176SPriya.Krishnan@Sun.COM 		mdb_printf("%-19p\n", addr);
13779176SPriya.Krishnan@Sun.COM 	} else {
13789176SPriya.Krishnan@Sun.COM 		/* pretty print */
13799176SPriya.Krishnan@Sun.COM 		if (DCMD_HDRSPEC(flags)) {
13809176SPriya.Krishnan@Sun.COM 			mdb_printf("%<u>%-19s %-10s %-10s %-10s%</u>\n",
13819176SPriya.Krishnan@Sun.COM 			    "stmf_worker_t", "State", "Ref_Count", "Tasks");
13829176SPriya.Krishnan@Sun.COM 		}
13839176SPriya.Krishnan@Sun.COM 
13849176SPriya.Krishnan@Sun.COM 		mdb_printf("%-19p %-10s %-10d %-5d%\n", addr,
13859176SPriya.Krishnan@Sun.COM 		    (worker.worker_flags == STMF_WORKER_STARTED) ? "STARTED" :
1386*10524SPeter.Cudhea@Sun.COM 		    (worker.worker_flags & STMF_WORKER_ACTIVE) ?
13879176SPriya.Krishnan@Sun.COM 		    "ACTIVE" : "TERMINATED",
13889176SPriya.Krishnan@Sun.COM 		    worker.worker_ref_count,
13899176SPriya.Krishnan@Sun.COM 		    worker.worker_queue_depth);
13909176SPriya.Krishnan@Sun.COM 	}
13919176SPriya.Krishnan@Sun.COM 
13929176SPriya.Krishnan@Sun.COM 	return (DCMD_OK);
13939176SPriya.Krishnan@Sun.COM }
13949176SPriya.Krishnan@Sun.COM 
13957836SJohn.Forte@Sun.COM struct find_options *
parse_options(int argc,const mdb_arg_t * argv)13967836SJohn.Forte@Sun.COM parse_options(int argc, const mdb_arg_t *argv)
13977836SJohn.Forte@Sun.COM {
13987836SJohn.Forte@Sun.COM 	int i;
13997836SJohn.Forte@Sun.COM 	struct find_options *options;
14007836SJohn.Forte@Sun.COM 	int len;
14017836SJohn.Forte@Sun.COM 	char *ptr;
14027836SJohn.Forte@Sun.COM 	int ret;
14037836SJohn.Forte@Sun.COM 
14047836SJohn.Forte@Sun.COM 	if (argc == 0)
14057836SJohn.Forte@Sun.COM 		return (NULL);
14067836SJohn.Forte@Sun.COM 	options = mdb_zalloc(sizeof (struct find_options), UM_SLEEP);
14077836SJohn.Forte@Sun.COM 	for (i = 0; i < argc; i++) {
14087836SJohn.Forte@Sun.COM 		switch (argv[i].a_type) {
14097836SJohn.Forte@Sun.COM 		case MDB_TYPE_STRING:
14107836SJohn.Forte@Sun.COM 			break;
14117836SJohn.Forte@Sun.COM 		case MDB_TYPE_IMMEDIATE:
14127836SJohn.Forte@Sun.COM 		case MDB_TYPE_CHAR:
14137836SJohn.Forte@Sun.COM 			mdb_printf("unknown type\n");
14147836SJohn.Forte@Sun.COM 		}
14157836SJohn.Forte@Sun.COM 		if ((ptr = strchr(argv[i].a_un.a_str, '=')) == NULL) {
14167836SJohn.Forte@Sun.COM 			mdb_printf("invalid argument: %s\n",
14177836SJohn.Forte@Sun.COM 			    argv[i].a_un.a_str);
14187836SJohn.Forte@Sun.COM 			goto out;
14197836SJohn.Forte@Sun.COM 		}
14207836SJohn.Forte@Sun.COM 		len = ptr - argv[i].a_un.a_str;
14217836SJohn.Forte@Sun.COM 		ptr++;	/* point to value now */
14227836SJohn.Forte@Sun.COM 
14237836SJohn.Forte@Sun.COM 		if (len == strlen("lpname") &&
14247836SJohn.Forte@Sun.COM 		    strncmp(argv[i].a_un.a_str, "lpname", len) == 0) {
14257836SJohn.Forte@Sun.COM 			if (strstr(ptr, "wwn.") == ptr)
14267836SJohn.Forte@Sun.COM 				ptr += 4;
14277836SJohn.Forte@Sun.COM 			ret = string2wwn(ptr, options->lpname);
14287836SJohn.Forte@Sun.COM 			if (ret == -1)
14297836SJohn.Forte@Sun.COM 				goto out;
14307836SJohn.Forte@Sun.COM #if 0
14317836SJohn.Forte@Sun.COM 	mdb_printf("wwn=%02x%02x%02x%02x%02x%02x%02x%02x\n",
14327836SJohn.Forte@Sun.COM 	    wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
14337836SJohn.Forte@Sun.COM #endif
14347836SJohn.Forte@Sun.COM 			options->lpname_defined = 1;
14357836SJohn.Forte@Sun.COM 
14367836SJohn.Forte@Sun.COM 		} else if (len == strlen("rp") &&
14377836SJohn.Forte@Sun.COM 		    strncmp(argv[i].a_un.a_str, "rp", len) == 0) {
14387836SJohn.Forte@Sun.COM 			options->rp_defined = 1;
14397836SJohn.Forte@Sun.COM 			options->rp =
14407836SJohn.Forte@Sun.COM 			    (void *)(unsigned long)mdb_strtoull(ptr);
14417836SJohn.Forte@Sun.COM 
14427836SJohn.Forte@Sun.COM 		} else if (len == strlen("rpname") &&
14437836SJohn.Forte@Sun.COM 		    strncmp(argv[i].a_un.a_str, "rpname", len) == 0) {
14447836SJohn.Forte@Sun.COM 			if (strstr(ptr, "wwn.") == ptr)
14457836SJohn.Forte@Sun.COM 				ptr += 4;
14467836SJohn.Forte@Sun.COM 			ret = string2wwn(ptr, options->rpname);
14477836SJohn.Forte@Sun.COM 			if (ret == -1)
14487836SJohn.Forte@Sun.COM 				goto out;
14497836SJohn.Forte@Sun.COM 			options->rpname_defined = 1;
14507836SJohn.Forte@Sun.COM 
14517836SJohn.Forte@Sun.COM 		} else if (len == strlen("show") &&
14527836SJohn.Forte@Sun.COM 		    strncmp(argv[i].a_un.a_str, "show", len) == 0) {
14537836SJohn.Forte@Sun.COM 			char *s;
14547836SJohn.Forte@Sun.COM 			int l;
14557836SJohn.Forte@Sun.COM 
14567836SJohn.Forte@Sun.COM 			for (;;) {
14577836SJohn.Forte@Sun.COM 				s = strchr(ptr, ',');
14587836SJohn.Forte@Sun.COM 				if (s)
14597836SJohn.Forte@Sun.COM 					l = s - ptr;
14607836SJohn.Forte@Sun.COM 				else
14617836SJohn.Forte@Sun.COM 					l = strlen(ptr);
14627836SJohn.Forte@Sun.COM 				if (l == strlen("task_flags") &&
14637836SJohn.Forte@Sun.COM 				    strncmp(ptr, "task_flags", l) == 0)
14647836SJohn.Forte@Sun.COM 					options->show_task_flags = 1;
14657836SJohn.Forte@Sun.COM 				else if (l == strlen("lport") &&
14667836SJohn.Forte@Sun.COM 				    strncmp(ptr, "lport", l) == 0)
14677836SJohn.Forte@Sun.COM 					options->show_lport = 1;
14687836SJohn.Forte@Sun.COM 				else {
14697836SJohn.Forte@Sun.COM 					mdb_printf("unknown shower: %s\n",
14707836SJohn.Forte@Sun.COM 					    ptr);
14717836SJohn.Forte@Sun.COM 					goto out;
14727836SJohn.Forte@Sun.COM 				}
14737836SJohn.Forte@Sun.COM 				if (s == NULL)
14747836SJohn.Forte@Sun.COM 					break;
14757836SJohn.Forte@Sun.COM 				ptr = s + 1;
14767836SJohn.Forte@Sun.COM 			}
14777836SJohn.Forte@Sun.COM 		} else {
14787836SJohn.Forte@Sun.COM 			mdb_printf("unknown argument: %s\n",
14797836SJohn.Forte@Sun.COM 			    argv[i].a_un.a_str);
14807836SJohn.Forte@Sun.COM 			goto out;
14817836SJohn.Forte@Sun.COM 		}
14827836SJohn.Forte@Sun.COM 	}
14837836SJohn.Forte@Sun.COM 
14847836SJohn.Forte@Sun.COM 	return (options);
14857836SJohn.Forte@Sun.COM out:
14867836SJohn.Forte@Sun.COM 	mdb_free(options, sizeof (struct find_options));
14877836SJohn.Forte@Sun.COM 	return (NULL);
14887836SJohn.Forte@Sun.COM }
14897836SJohn.Forte@Sun.COM 
14907836SJohn.Forte@Sun.COM int
string2wwn(const char * s,uint8_t wwn[8])14917836SJohn.Forte@Sun.COM string2wwn(const char *s, uint8_t wwn[8])
14927836SJohn.Forte@Sun.COM {
14937836SJohn.Forte@Sun.COM 	int i;
14947836SJohn.Forte@Sun.COM 	char tmp[17];
14957836SJohn.Forte@Sun.COM 	char *p;
14967836SJohn.Forte@Sun.COM 
14977836SJohn.Forte@Sun.COM 	if (strlen(s) > 16) {
14987836SJohn.Forte@Sun.COM 		mdb_printf("invalid wwn %s\n", s);
14997836SJohn.Forte@Sun.COM 		return (-1);
15007836SJohn.Forte@Sun.COM 	}
15017836SJohn.Forte@Sun.COM 
15027836SJohn.Forte@Sun.COM 	strcpy(tmp, s);
15037836SJohn.Forte@Sun.COM 	p = tmp + strlen(tmp) - 2;
15047836SJohn.Forte@Sun.COM 	memset(wwn, 0, 8);
15057836SJohn.Forte@Sun.COM 	/* figure out wwn from the tail to beginning */
15067836SJohn.Forte@Sun.COM 	for (i = 7; i >= 0 && p >= tmp; i--, p -= 2) {
15077836SJohn.Forte@Sun.COM 		wwn[i] = mdb_strtoull(p);
15087836SJohn.Forte@Sun.COM 		*p = 0;
15097836SJohn.Forte@Sun.COM 	}
15107836SJohn.Forte@Sun.COM 	return (0);
15117836SJohn.Forte@Sun.COM }
15127836SJohn.Forte@Sun.COM 
15137836SJohn.Forte@Sun.COM void
fct_find_cmds_help(void)15147836SJohn.Forte@Sun.COM fct_find_cmds_help(void)
15157836SJohn.Forte@Sun.COM {
15167836SJohn.Forte@Sun.COM 	mdb_printf(
15177836SJohn.Forte@Sun.COM 	    "Find all cached fct_i_cmd_t for a local port. If a local port \n"
15187836SJohn.Forte@Sun.COM 	    "name is specified, find all pending cmds for it and print the \n"
15197836SJohn.Forte@Sun.COM 	    "address. Example:\n"
15207836SJohn.Forte@Sun.COM 	    "    fct_find_cmds lpname=<wwn.12345678 or 12345678>\n");
15217836SJohn.Forte@Sun.COM }
15227836SJohn.Forte@Sun.COM void
stmf_find_ilport_help(void)15237836SJohn.Forte@Sun.COM stmf_find_ilport_help(void)
15247836SJohn.Forte@Sun.COM {
15257836SJohn.Forte@Sun.COM 	mdb_printf(
15267836SJohn.Forte@Sun.COM 	    "Find the fct_i_local_port if local port name is "
15277836SJohn.Forte@Sun.COM 	    "specified. Example:\n"
15287836SJohn.Forte@Sun.COM 	    "    stmf_find_ilport lpname=<wwn.12345678 or 12345678>\n");
15297836SJohn.Forte@Sun.COM }
15307836SJohn.Forte@Sun.COM void
stmf_find_fct_irp_help(void)15317836SJohn.Forte@Sun.COM stmf_find_fct_irp_help(void)
15327836SJohn.Forte@Sun.COM {
15337836SJohn.Forte@Sun.COM 	mdb_printf(
15347836SJohn.Forte@Sun.COM 	    "If a remote port name or stmf_i_remote_port_t address is\n"
15357836SJohn.Forte@Sun.COM 	    "specified, loop through all local ports, to which this remote \n"
15367836SJohn.Forte@Sun.COM 	    "port has logged in, print address for stmf_i_local_port_t and \n"
15377836SJohn.Forte@Sun.COM 	    "stmf_i_remote_port. Example:\n"
15387836SJohn.Forte@Sun.COM 	    "    stmf_find_fct_irp rpname=<wwn.12345678 or 12345678>\n"
15397836SJohn.Forte@Sun.COM 	    "    stmf_find_fct_irp rp=<3000586778734>\n");
15407836SJohn.Forte@Sun.COM }
15419176SPriya.Krishnan@Sun.COM 
15427836SJohn.Forte@Sun.COM void
stmf_find_tasks_help(void)15437836SJohn.Forte@Sun.COM stmf_find_tasks_help(void)
15447836SJohn.Forte@Sun.COM {
15457836SJohn.Forte@Sun.COM 	mdb_printf(
15467836SJohn.Forte@Sun.COM 	    "Find all pending scsi_task_t for a given local port and/or\n"
15477836SJohn.Forte@Sun.COM 	    "remote port. Various different fields for each task are printed\n"
15487836SJohn.Forte@Sun.COM 	    "depending on what is requested. Example:\n"
15497836SJohn.Forte@Sun.COM 	    "    stmf_find_tasks rpname=<wwn.12345678 or 12345678>\n"
15507836SJohn.Forte@Sun.COM 	    "    stmf_find_tasks lpname=<wwn.12345678 or 12345678> "
15517836SJohn.Forte@Sun.COM 	    "show=task_flags,lport\n");
15527836SJohn.Forte@Sun.COM }
15537836SJohn.Forte@Sun.COM 
15549176SPriya.Krishnan@Sun.COM void
stmf_scsi_task_help(void)15559176SPriya.Krishnan@Sun.COM stmf_scsi_task_help(void)
15569176SPriya.Krishnan@Sun.COM {
15579176SPriya.Krishnan@Sun.COM 	mdb_printf(
15589176SPriya.Krishnan@Sun.COM 	    "List all active scsi_task_t on a given stmf_worker_t. Example\n"
15599176SPriya.Krishnan@Sun.COM 	    "    addr::stmf_scsi_task\n");
15609176SPriya.Krishnan@Sun.COM }
15619176SPriya.Krishnan@Sun.COM 
15627836SJohn.Forte@Sun.COM static const mdb_dcmd_t dcmds[] = {
15637836SJohn.Forte@Sun.COM 	{ "stmf_ilports", "[-v]",
15647836SJohn.Forte@Sun.COM 	    "Print a list of stmf_i_local_port", stmf_ilports },
15657836SJohn.Forte@Sun.COM 	{ "ilport2iport", "?[-v]",
15667836SJohn.Forte@Sun.COM 	    "Convert stmf_i_local_port to corresponding fct_i_local_port",
15677836SJohn.Forte@Sun.COM 	    ilport2iport },
15687836SJohn.Forte@Sun.COM 	{ "stmf_iss", "?[-v]",
15697836SJohn.Forte@Sun.COM 	    "List all active sessions for a given local port",
15707836SJohn.Forte@Sun.COM 	    stmf_iss },
15717836SJohn.Forte@Sun.COM 	{ "stmf_ilus", "[-v]", "Print a list of stmf_i_lu", stmf_ilus },
15727836SJohn.Forte@Sun.COM 	{ "stmf_i_lu_providers", "[-v]",
15737836SJohn.Forte@Sun.COM 	    "Print a list of stmf_i_lu_provider", stmf_i_lu_providers },
15747836SJohn.Forte@Sun.COM 	{ "stmf_i_port_providers", "[-v]",
15757836SJohn.Forte@Sun.COM 	    "Print a list of stmf_i_port_provider", stmf_i_port_providers },
15767836SJohn.Forte@Sun.COM 	{ "fct_irps", "?[-v]",
15777836SJohn.Forte@Sun.COM 	    "Print all fct_i_remote_port for a given fct_i_local_port",
15787836SJohn.Forte@Sun.COM 	    fct_irps },
15797836SJohn.Forte@Sun.COM 	{ "fct_icmds", "?[-v]",
15807836SJohn.Forte@Sun.COM 	    "Print all cached fct_i_cmd_t on fct_i_local_port",
15817836SJohn.Forte@Sun.COM 	    fct_icmds },
15827836SJohn.Forte@Sun.COM 	{ "fct_find_cmds", "lpname",
15837836SJohn.Forte@Sun.COM 	    "Find all fct_i_cmd_t for a given local port",
15847836SJohn.Forte@Sun.COM 	    fct_find_cmds, fct_find_cmds_help},
15857836SJohn.Forte@Sun.COM 	{ "stmf_find_ilport", "lpname",
15867836SJohn.Forte@Sun.COM 	    "Find local port information based on its wwn",
15877836SJohn.Forte@Sun.COM 	    stmf_find_ilport, stmf_find_ilport_help},
15887836SJohn.Forte@Sun.COM 	{ "stmf_find_fct_irp", "rpname|rp",
15897836SJohn.Forte@Sun.COM 	    "Print fct remote port information based on its wwn",
15907836SJohn.Forte@Sun.COM 	    stmf_find_fct_irp, stmf_find_fct_irp_help},
15917836SJohn.Forte@Sun.COM 	{ "stmf_find_tasks", "lpname|rpname [show]",
15927836SJohn.Forte@Sun.COM 	    "Find all pending task for a local port or remote port",
15937836SJohn.Forte@Sun.COM 	    stmf_find_tasks, stmf_find_tasks_help},
15949176SPriya.Krishnan@Sun.COM 	{ "stmf_worker", "?", "List all the stmf_worker entries", stmf_worker},
15959176SPriya.Krishnan@Sun.COM 	{ "stmf_scsi_task", ":",
15969176SPriya.Krishnan@Sun.COM 	    "List all the active STMF SCSI tasks per worker", stmf_scsi_task,
15979176SPriya.Krishnan@Sun.COM 	    stmf_scsi_task_help},
15987836SJohn.Forte@Sun.COM 	{ NULL }
15997836SJohn.Forte@Sun.COM };
16007836SJohn.Forte@Sun.COM 
16017836SJohn.Forte@Sun.COM static const mdb_walker_t walkers[] = {
16029176SPriya.Krishnan@Sun.COM 	{ "stmf_worker", "Walk STMF worker queue", stmf_worker_walk_init,
16039176SPriya.Krishnan@Sun.COM 	    stmf_worker_walk_step, stmf_worker_walk_fini},
16049176SPriya.Krishnan@Sun.COM 	{ "stmf_scsi_task", "Walk active STMF SCSI tasks per worker",
16059176SPriya.Krishnan@Sun.COM 	    stmf_scsi_task_walk_init,
16069176SPriya.Krishnan@Sun.COM 	    stmf_scsi_task_walk_step, stmf_scsi_task_walk_fini },
16077836SJohn.Forte@Sun.COM 	{ NULL }
16087836SJohn.Forte@Sun.COM };
16097836SJohn.Forte@Sun.COM 
16107836SJohn.Forte@Sun.COM static const mdb_modinfo_t modinfo = {
16117836SJohn.Forte@Sun.COM 	MDB_API_VERSION, dcmds, walkers
16127836SJohn.Forte@Sun.COM };
16137836SJohn.Forte@Sun.COM 
16147836SJohn.Forte@Sun.COM const mdb_modinfo_t *
_mdb_init(void)16157836SJohn.Forte@Sun.COM _mdb_init(void)
16167836SJohn.Forte@Sun.COM {
16177836SJohn.Forte@Sun.COM 	return (&modinfo);
16187836SJohn.Forte@Sun.COM }
1619