xref: /onnv-gate/usr/src/cmd/mdb/common/modules/fctl/fctl.c (revision 8919:3728abeba5af)
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 /*
22*8919SRenia.Miao@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 
277836SJohn.Forte@Sun.COM #include <sys/mdb_modapi.h>
287836SJohn.Forte@Sun.COM #include <sys/mutex.h>
297836SJohn.Forte@Sun.COM #include <sys/modctl.h>
307836SJohn.Forte@Sun.COM #include <time.h>
317836SJohn.Forte@Sun.COM #include <sys/fibre-channel/fc.h>
327836SJohn.Forte@Sun.COM #include <sys/fibre-channel/impl/fctl_private.h>
337836SJohn.Forte@Sun.COM #include <sys/fibre-channel/impl/fc_ulpif.h>
347836SJohn.Forte@Sun.COM #include <sys/fibre-channel/impl/fc_portif.h>
357836SJohn.Forte@Sun.COM #include <sys/fibre-channel/impl/fc_fcaif.h>
367836SJohn.Forte@Sun.COM 
377836SJohn.Forte@Sun.COM 
387836SJohn.Forte@Sun.COM /*
397836SJohn.Forte@Sun.COM  * If we #include <string.h> then other definitions fail. This is
407836SJohn.Forte@Sun.COM  * the easiest way of getting access to the function
417836SJohn.Forte@Sun.COM  */
427836SJohn.Forte@Sun.COM extern char *strtok(char *string, const char *sepset);
437836SJohn.Forte@Sun.COM 
447836SJohn.Forte@Sun.COM /* we need 26 bytes for the cftime() call */
457836SJohn.Forte@Sun.COM #define	TIMESTAMPSIZE	26 * sizeof (char)
467836SJohn.Forte@Sun.COM 
477836SJohn.Forte@Sun.COM /* for backward compatibility */
487836SJohn.Forte@Sun.COM typedef struct fc_trace_dmsgv1 {
497836SJohn.Forte@Sun.COM 	int			id_size;
507836SJohn.Forte@Sun.COM 	int			id_flag;
517836SJohn.Forte@Sun.COM 	time_t			id_time;
527836SJohn.Forte@Sun.COM 	caddr_t			id_buf;
537836SJohn.Forte@Sun.COM 	struct fc_trace_dmsgv1	*id_next;
547836SJohn.Forte@Sun.COM } fc_trace_dmsgv1_t;
557836SJohn.Forte@Sun.COM 
567836SJohn.Forte@Sun.COM static struct pwwn_hash *fp_pwwn_table;
577836SJohn.Forte@Sun.COM static struct d_id_hash *fp_did_table;
587836SJohn.Forte@Sun.COM static uint32_t pd_hash_index;
597836SJohn.Forte@Sun.COM struct fc_local_port port;
607836SJohn.Forte@Sun.COM 
617836SJohn.Forte@Sun.COM /*
627836SJohn.Forte@Sun.COM  * Leadville port walker/dcmd code
637836SJohn.Forte@Sun.COM  */
647836SJohn.Forte@Sun.COM 
657836SJohn.Forte@Sun.COM /*
667836SJohn.Forte@Sun.COM  * Initialize the fc_fca_port_t walker by either using the given starting
677836SJohn.Forte@Sun.COM  * address, or reading the value of the kernel's fctl_fca_portlist pointer.
687836SJohn.Forte@Sun.COM  * We also allocate a fc_fca_port_t for storage, and save this using the
697836SJohn.Forte@Sun.COM  * walk_data pointer.
707836SJohn.Forte@Sun.COM  */
717836SJohn.Forte@Sun.COM static int
port_walk_i(mdb_walk_state_t * wsp)727836SJohn.Forte@Sun.COM port_walk_i(mdb_walk_state_t *wsp)
737836SJohn.Forte@Sun.COM {
747836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL &&
757836SJohn.Forte@Sun.COM 	    mdb_readvar(&wsp->walk_addr, "fctl_fca_portlist") == -1) {
767836SJohn.Forte@Sun.COM 		mdb_warn("failed to read 'fctl_fca_portlist'");
777836SJohn.Forte@Sun.COM 		return (WALK_ERR);
787836SJohn.Forte@Sun.COM 	}
797836SJohn.Forte@Sun.COM 
807836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (fc_fca_port_t), UM_SLEEP);
817836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
827836SJohn.Forte@Sun.COM }
837836SJohn.Forte@Sun.COM 
847836SJohn.Forte@Sun.COM /*
857836SJohn.Forte@Sun.COM  * At each step, read a fc_fca_port_t into our private storage, and then invoke
867836SJohn.Forte@Sun.COM  * the callback function.  We terminate when we reach a NULL p_next pointer.
877836SJohn.Forte@Sun.COM  */
887836SJohn.Forte@Sun.COM static int
port_walk_s(mdb_walk_state_t * wsp)897836SJohn.Forte@Sun.COM port_walk_s(mdb_walk_state_t *wsp)
907836SJohn.Forte@Sun.COM {
917836SJohn.Forte@Sun.COM 	int status;
927836SJohn.Forte@Sun.COM 
937836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL)
947836SJohn.Forte@Sun.COM 		return (WALK_DONE);
957836SJohn.Forte@Sun.COM 
967836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (fc_fca_port_t), wsp->walk_addr)
977836SJohn.Forte@Sun.COM 	    == -1) {
987836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fc_fca_port_t at %p", wsp->walk_addr);
997836SJohn.Forte@Sun.COM 		return (WALK_DONE);
1007836SJohn.Forte@Sun.COM 	}
1017836SJohn.Forte@Sun.COM 
1027836SJohn.Forte@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
1037836SJohn.Forte@Sun.COM 	    wsp->walk_cbdata);
1047836SJohn.Forte@Sun.COM 
1057836SJohn.Forte@Sun.COM 	wsp->walk_addr =
1067836SJohn.Forte@Sun.COM 	    (uintptr_t)(((fc_fca_port_t *)wsp->walk_data)->port_next);
1077836SJohn.Forte@Sun.COM 
1087836SJohn.Forte@Sun.COM 	return (status);
1097836SJohn.Forte@Sun.COM }
1107836SJohn.Forte@Sun.COM 
1117836SJohn.Forte@Sun.COM /*
1127836SJohn.Forte@Sun.COM  * The walker's fini function is invoked at the end of each walk.  Since we
1137836SJohn.Forte@Sun.COM  * dynamically allocated a fc_fca_port_t in port_walk_i, we must free it now.
1147836SJohn.Forte@Sun.COM  */
1157836SJohn.Forte@Sun.COM static void
port_walk_f(mdb_walk_state_t * wsp)1167836SJohn.Forte@Sun.COM port_walk_f(mdb_walk_state_t *wsp)
1177836SJohn.Forte@Sun.COM {
1187836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (fc_fca_port_t));
1197836SJohn.Forte@Sun.COM }
1207836SJohn.Forte@Sun.COM 
1217836SJohn.Forte@Sun.COM 
1227836SJohn.Forte@Sun.COM static int
ports(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1237836SJohn.Forte@Sun.COM ports(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1247836SJohn.Forte@Sun.COM {
1257836SJohn.Forte@Sun.COM 	fc_fca_port_t	portlist;
1267836SJohn.Forte@Sun.COM 	fc_local_port_t port;
1277836SJohn.Forte@Sun.COM 	int		longlist = FALSE;
1287836SJohn.Forte@Sun.COM 
1297836SJohn.Forte@Sun.COM 	if (argc > 1) {
1307836SJohn.Forte@Sun.COM 		return (DCMD_USAGE);
1317836SJohn.Forte@Sun.COM 	}
1327836SJohn.Forte@Sun.COM 
1337836SJohn.Forte@Sun.COM 	if (mdb_getopts(argc, argv,
1347836SJohn.Forte@Sun.COM 	    'l', MDB_OPT_SETBITS, TRUE, &longlist) != argc) {
1357836SJohn.Forte@Sun.COM 		return (DCMD_USAGE);
1367836SJohn.Forte@Sun.COM 	}
1377836SJohn.Forte@Sun.COM 
1387836SJohn.Forte@Sun.COM 
1397836SJohn.Forte@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
1407836SJohn.Forte@Sun.COM 		if (longlist == 0) {
1417836SJohn.Forte@Sun.COM 			if (mdb_walk_dcmd("ports", "ports",
1427836SJohn.Forte@Sun.COM 			    argc, argv) == -1) {
1437836SJohn.Forte@Sun.COM 				mdb_warn("failed to walk 'fctl_fca_portlist'");
1447836SJohn.Forte@Sun.COM 				return (DCMD_ERR);
1457836SJohn.Forte@Sun.COM 			}
1467836SJohn.Forte@Sun.COM 		} else {
1477836SJohn.Forte@Sun.COM 			if (mdb_walk_dcmd("ports", "fcport",
1487836SJohn.Forte@Sun.COM 			    argc, argv) == -1) {
1497836SJohn.Forte@Sun.COM 				mdb_warn("failed to walk 'fctl_fca_portlist'");
1507836SJohn.Forte@Sun.COM 				return (DCMD_ERR);
1517836SJohn.Forte@Sun.COM 			}
1527836SJohn.Forte@Sun.COM 		}
1537836SJohn.Forte@Sun.COM 
1547836SJohn.Forte@Sun.COM 		return (DCMD_OK);
1557836SJohn.Forte@Sun.COM 	}
1567836SJohn.Forte@Sun.COM 
1577836SJohn.Forte@Sun.COM 	/*
1587836SJohn.Forte@Sun.COM 	 * If this is the first invocation of the command, print a nice
1597836SJohn.Forte@Sun.COM 	 * header line for the output that will follow.
1607836SJohn.Forte@Sun.COM 	 */
1617836SJohn.Forte@Sun.COM 	if (DCMD_HDRSPEC(flags))
1627836SJohn.Forte@Sun.COM 		mdb_printf("%16s %-2s %4s %-4s%16s %16s %16s\n",
1637836SJohn.Forte@Sun.COM 		    "Port", "I#", "State", "Soft", "FCA Handle",
1647836SJohn.Forte@Sun.COM 		    "Port DIP", "FCA Port DIP");
1657836SJohn.Forte@Sun.COM 
1667836SJohn.Forte@Sun.COM 	/*
1677836SJohn.Forte@Sun.COM 	 * For each port, we just need to read the fc_fca_port_t struct, read
1687836SJohn.Forte@Sun.COM 	 * the port_handle
1697836SJohn.Forte@Sun.COM 	 */
1707836SJohn.Forte@Sun.COM 	if (mdb_vread(&portlist, sizeof (fc_fca_port_t), addr) ==
1717836SJohn.Forte@Sun.COM 	    sizeof (fc_fca_port_t)) {
1727836SJohn.Forte@Sun.COM 		/*
1737836SJohn.Forte@Sun.COM 		 * Now read that port in
1747836SJohn.Forte@Sun.COM 		 */
1757836SJohn.Forte@Sun.COM 
1767836SJohn.Forte@Sun.COM 		if (mdb_vread(&port, sizeof (fc_local_port_t), (uintptr_t)
1777836SJohn.Forte@Sun.COM 		    portlist.port_handle) == sizeof (fc_local_port_t)) {
1787836SJohn.Forte@Sun.COM 			mdb_printf("%16p %2d %4x %4x %16p %16p %16p\n",
1797836SJohn.Forte@Sun.COM 			    portlist.port_handle, port.fp_instance,
1807836SJohn.Forte@Sun.COM 			    port.fp_state, port.fp_soft_state,
1817836SJohn.Forte@Sun.COM 			    port.fp_fca_handle, port.fp_port_dip,
1827836SJohn.Forte@Sun.COM 			    port.fp_fca_dip);
1837836SJohn.Forte@Sun.COM 		} else
1847836SJohn.Forte@Sun.COM 			mdb_warn("failed to read port at %p",
1857836SJohn.Forte@Sun.COM 			    portlist.port_handle);
1867836SJohn.Forte@Sun.COM 
1877836SJohn.Forte@Sun.COM 	} else
1887836SJohn.Forte@Sun.COM 		mdb_warn("failed to read port info at %p", addr);
1897836SJohn.Forte@Sun.COM 
1907836SJohn.Forte@Sun.COM 	return (DCMD_OK);
1917836SJohn.Forte@Sun.COM }
1927836SJohn.Forte@Sun.COM 
1937836SJohn.Forte@Sun.COM 
1947836SJohn.Forte@Sun.COM /*
1957836SJohn.Forte@Sun.COM  * Leadville ULP walker/dcmd code
1967836SJohn.Forte@Sun.COM  */
1977836SJohn.Forte@Sun.COM 
1987836SJohn.Forte@Sun.COM static int
ulp_walk_i(mdb_walk_state_t * wsp)1997836SJohn.Forte@Sun.COM ulp_walk_i(mdb_walk_state_t *wsp)
2007836SJohn.Forte@Sun.COM {
2017836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL &&
2027836SJohn.Forte@Sun.COM 	    mdb_readvar(&wsp->walk_addr, "fctl_ulp_list") == -1) {
2037836SJohn.Forte@Sun.COM 		mdb_warn("failed to read 'fctl_ulp_list'");
2047836SJohn.Forte@Sun.COM 		return (WALK_ERR);
2057836SJohn.Forte@Sun.COM 	}
2067836SJohn.Forte@Sun.COM 
2077836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (fc_ulp_list_t), UM_SLEEP);
2087836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
2097836SJohn.Forte@Sun.COM }
2107836SJohn.Forte@Sun.COM 
2117836SJohn.Forte@Sun.COM 
2127836SJohn.Forte@Sun.COM 
2137836SJohn.Forte@Sun.COM static int
ulp_walk_s(mdb_walk_state_t * wsp)2147836SJohn.Forte@Sun.COM ulp_walk_s(mdb_walk_state_t *wsp)
2157836SJohn.Forte@Sun.COM {
2167836SJohn.Forte@Sun.COM 	int status;
2177836SJohn.Forte@Sun.COM 
2187836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL)
2197836SJohn.Forte@Sun.COM 		return (WALK_DONE);
2207836SJohn.Forte@Sun.COM 
2217836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (fc_ulp_list_t), wsp->walk_addr)
2227836SJohn.Forte@Sun.COM 	    == -1) {
2237836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fctl_ulp_list %p", wsp->walk_addr);
2247836SJohn.Forte@Sun.COM 		return (WALK_DONE);
2257836SJohn.Forte@Sun.COM 	}
2267836SJohn.Forte@Sun.COM 
2277836SJohn.Forte@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
2287836SJohn.Forte@Sun.COM 	    wsp->walk_cbdata);
2297836SJohn.Forte@Sun.COM 
2307836SJohn.Forte@Sun.COM 	wsp->walk_addr =
2317836SJohn.Forte@Sun.COM 	    (uintptr_t)(((fc_ulp_list_t *)wsp->walk_data)->ulp_next);
2327836SJohn.Forte@Sun.COM 
2337836SJohn.Forte@Sun.COM 	return (status);
2347836SJohn.Forte@Sun.COM }
2357836SJohn.Forte@Sun.COM 
2367836SJohn.Forte@Sun.COM 
2377836SJohn.Forte@Sun.COM static void
ulp_walk_f(mdb_walk_state_t * wsp)2387836SJohn.Forte@Sun.COM ulp_walk_f(mdb_walk_state_t *wsp)
2397836SJohn.Forte@Sun.COM {
2407836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (fc_ulp_list_t));
2417836SJohn.Forte@Sun.COM }
2427836SJohn.Forte@Sun.COM 
2437836SJohn.Forte@Sun.COM 
2447836SJohn.Forte@Sun.COM static int
ulps(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2457836SJohn.Forte@Sun.COM ulps(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2467836SJohn.Forte@Sun.COM {
2477836SJohn.Forte@Sun.COM 	fc_ulp_list_t 		ulplist;
2487836SJohn.Forte@Sun.COM 	fc_ulp_modinfo_t	ulp;
2497836SJohn.Forte@Sun.COM 	char			ulp_name[30];
2507836SJohn.Forte@Sun.COM 
2517836SJohn.Forte@Sun.COM 	if (argc != 0) {
2527836SJohn.Forte@Sun.COM 		return (DCMD_USAGE);
2537836SJohn.Forte@Sun.COM 	}
2547836SJohn.Forte@Sun.COM 
2557836SJohn.Forte@Sun.COM 	/*
2567836SJohn.Forte@Sun.COM 	 * If no fc_ulp_list_t address was specified on the command line, we can
2577836SJohn.Forte@Sun.COM 	 * print out all processes by invoking the walker, using this
2587836SJohn.Forte@Sun.COM 	 * dcmd itself as the callback.
2597836SJohn.Forte@Sun.COM 	 */
2607836SJohn.Forte@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
2617836SJohn.Forte@Sun.COM 		if (mdb_walk_dcmd("ulps", "ulps", argc, argv) == -1) {
2627836SJohn.Forte@Sun.COM 			mdb_warn("failed to walk 'fc_ulp_list_t'");
2637836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
2647836SJohn.Forte@Sun.COM 		}
2657836SJohn.Forte@Sun.COM 		return (DCMD_OK);
2667836SJohn.Forte@Sun.COM 	}
2677836SJohn.Forte@Sun.COM 
2687836SJohn.Forte@Sun.COM 	/*
2697836SJohn.Forte@Sun.COM 	 * If this is the first invocation of the command, print a nice
2707836SJohn.Forte@Sun.COM 	 * header line for the output that will follow.
2717836SJohn.Forte@Sun.COM 	 */
2727836SJohn.Forte@Sun.COM 	if (DCMD_HDRSPEC(flags))
2737836SJohn.Forte@Sun.COM 		mdb_printf("%30s %4s %8s\n", "ULP Name", "Type", "Revision");
2747836SJohn.Forte@Sun.COM 
2757836SJohn.Forte@Sun.COM 	/*
2767836SJohn.Forte@Sun.COM 	 * For each port, we just need to read the fc_fca_port_t struct, read
2777836SJohn.Forte@Sun.COM 	 * the port_handle
2787836SJohn.Forte@Sun.COM 	 */
2797836SJohn.Forte@Sun.COM 	if (mdb_vread(&ulplist, sizeof (fc_ulp_list_t), addr) ==
2807836SJohn.Forte@Sun.COM 	    sizeof (fc_ulp_list_t)) {
2817836SJohn.Forte@Sun.COM 		/*
2827836SJohn.Forte@Sun.COM 		 * Now read that port in
2837836SJohn.Forte@Sun.COM 		 */
2847836SJohn.Forte@Sun.COM 
2857836SJohn.Forte@Sun.COM 		if (mdb_vread(&ulp, sizeof (fc_ulp_modinfo_t),
2867836SJohn.Forte@Sun.COM 		    (uintptr_t)ulplist.ulp_info) == sizeof (fc_ulp_modinfo_t)) {
2877836SJohn.Forte@Sun.COM 			if (mdb_vread(&ulp_name, 30,
2887836SJohn.Forte@Sun.COM 			    (uintptr_t)ulp.ulp_name) > 0) {
2897836SJohn.Forte@Sun.COM 				mdb_printf("%30s %4x %8x\n",
2907836SJohn.Forte@Sun.COM 				    ulp_name, ulp.ulp_type, ulp.ulp_rev);
2917836SJohn.Forte@Sun.COM 			}
2927836SJohn.Forte@Sun.COM 		} else
2937836SJohn.Forte@Sun.COM 			mdb_warn("failed to read ulp at %p",
2947836SJohn.Forte@Sun.COM 			    ulplist.ulp_info);
2957836SJohn.Forte@Sun.COM 
2967836SJohn.Forte@Sun.COM 	} else
2977836SJohn.Forte@Sun.COM 		mdb_warn("failed to read ulplist at %p", addr);
2987836SJohn.Forte@Sun.COM 
2997836SJohn.Forte@Sun.COM 	return (DCMD_OK);
3007836SJohn.Forte@Sun.COM }
3017836SJohn.Forte@Sun.COM 
3027836SJohn.Forte@Sun.COM 
3037836SJohn.Forte@Sun.COM 
3047836SJohn.Forte@Sun.COM /*
3057836SJohn.Forte@Sun.COM  * Leadville ULP module walker/dcmd code
3067836SJohn.Forte@Sun.COM  */
3077836SJohn.Forte@Sun.COM 
3087836SJohn.Forte@Sun.COM static int
ulpmod_walk_i(mdb_walk_state_t * wsp)3097836SJohn.Forte@Sun.COM ulpmod_walk_i(mdb_walk_state_t *wsp)
3107836SJohn.Forte@Sun.COM {
3117836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL &&
3127836SJohn.Forte@Sun.COM 	    mdb_readvar(&wsp->walk_addr, "fctl_ulp_modules") == -1) {
3137836SJohn.Forte@Sun.COM 		mdb_warn("failed to read 'fctl_ulp_modules'");
3147836SJohn.Forte@Sun.COM 		return (WALK_ERR);
3157836SJohn.Forte@Sun.COM 	}
3167836SJohn.Forte@Sun.COM 
3177836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (fc_ulp_module_t), UM_SLEEP);
3187836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
3197836SJohn.Forte@Sun.COM }
3207836SJohn.Forte@Sun.COM 
3217836SJohn.Forte@Sun.COM 
3227836SJohn.Forte@Sun.COM 
3237836SJohn.Forte@Sun.COM static int
ulpmod_walk_s(mdb_walk_state_t * wsp)3247836SJohn.Forte@Sun.COM ulpmod_walk_s(mdb_walk_state_t *wsp)
3257836SJohn.Forte@Sun.COM {
3267836SJohn.Forte@Sun.COM 	int status;
3277836SJohn.Forte@Sun.COM 
3287836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL)
3297836SJohn.Forte@Sun.COM 		return (WALK_DONE);
3307836SJohn.Forte@Sun.COM 
3317836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (fc_ulp_module_t), wsp->walk_addr)
3327836SJohn.Forte@Sun.COM 	    == -1) {
3337836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fctl_ulp_modules %p", wsp->walk_addr);
3347836SJohn.Forte@Sun.COM 		return (WALK_DONE);
3357836SJohn.Forte@Sun.COM 	}
3367836SJohn.Forte@Sun.COM 
3377836SJohn.Forte@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
3387836SJohn.Forte@Sun.COM 	    wsp->walk_cbdata);
3397836SJohn.Forte@Sun.COM 
3407836SJohn.Forte@Sun.COM 	wsp->walk_addr =
3417836SJohn.Forte@Sun.COM 	    (uintptr_t)(((fc_ulp_module_t *)wsp->walk_data)->mod_next);
3427836SJohn.Forte@Sun.COM 
3437836SJohn.Forte@Sun.COM 	return (status);
3447836SJohn.Forte@Sun.COM }
3457836SJohn.Forte@Sun.COM 
3467836SJohn.Forte@Sun.COM 
3477836SJohn.Forte@Sun.COM static void
ulpmod_walk_f(mdb_walk_state_t * wsp)3487836SJohn.Forte@Sun.COM ulpmod_walk_f(mdb_walk_state_t *wsp)
3497836SJohn.Forte@Sun.COM {
3507836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (fc_ulp_module_t));
3517836SJohn.Forte@Sun.COM }
3527836SJohn.Forte@Sun.COM 
3537836SJohn.Forte@Sun.COM 
3547836SJohn.Forte@Sun.COM static int
ulpmods(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)3557836SJohn.Forte@Sun.COM ulpmods(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3567836SJohn.Forte@Sun.COM {
3577836SJohn.Forte@Sun.COM 	fc_ulp_module_t 	modlist;
3587836SJohn.Forte@Sun.COM 	fc_ulp_modinfo_t	modinfo;
3597836SJohn.Forte@Sun.COM 	fc_ulp_ports_t		ulp_port;
3607836SJohn.Forte@Sun.COM 
3617836SJohn.Forte@Sun.COM 	if (argc != 0) {
3627836SJohn.Forte@Sun.COM 		return (DCMD_USAGE);
3637836SJohn.Forte@Sun.COM 	}
3647836SJohn.Forte@Sun.COM 
3657836SJohn.Forte@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
3667836SJohn.Forte@Sun.COM 		if (mdb_walk_dcmd("ulpmods", "ulpmods", argc, argv)
3677836SJohn.Forte@Sun.COM 		    == -1) {
3687836SJohn.Forte@Sun.COM 			mdb_warn("failed to walk 'fc_ulp_module_t'");
3697836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
3707836SJohn.Forte@Sun.COM 		}
3717836SJohn.Forte@Sun.COM 		return (DCMD_OK);
3727836SJohn.Forte@Sun.COM 	}
3737836SJohn.Forte@Sun.COM 
3747836SJohn.Forte@Sun.COM 	/*
3757836SJohn.Forte@Sun.COM 	 * If this is the first invocation of the command, print a nice
3767836SJohn.Forte@Sun.COM 	 * header line for the output that will follow.
3777836SJohn.Forte@Sun.COM 	 */
3787836SJohn.Forte@Sun.COM 	if (DCMD_HDRSPEC(flags))
3797836SJohn.Forte@Sun.COM 		mdb_printf("%4s %16s %8s %8s\n",
3807836SJohn.Forte@Sun.COM 		    "Type", "Port Handle", "dstate", "statec");
3817836SJohn.Forte@Sun.COM 
3827836SJohn.Forte@Sun.COM 	/*
3837836SJohn.Forte@Sun.COM 	 * For each port, we just need to read the fc_fca_port_t struct, read
3847836SJohn.Forte@Sun.COM 	 * the port_handle
3857836SJohn.Forte@Sun.COM 	 */
3867836SJohn.Forte@Sun.COM 	if (mdb_vread(&modlist, sizeof (fc_ulp_module_t), addr) ==
3877836SJohn.Forte@Sun.COM 	    sizeof (fc_ulp_module_t)) {
3887836SJohn.Forte@Sun.COM 		/*
3897836SJohn.Forte@Sun.COM 		 * Now read that module info in
3907836SJohn.Forte@Sun.COM 		 */
3917836SJohn.Forte@Sun.COM 
3927836SJohn.Forte@Sun.COM 		if (mdb_vread(&modinfo, sizeof (fc_ulp_modinfo_t),
3937836SJohn.Forte@Sun.COM 		    (uintptr_t)modlist.mod_info) == sizeof (fc_ulp_modinfo_t)) {
3947836SJohn.Forte@Sun.COM 			/* Now read all the ports for this module */
3957836SJohn.Forte@Sun.COM 			if (mdb_vread(&ulp_port, sizeof (fc_ulp_ports_t),
3967836SJohn.Forte@Sun.COM 			    (uintptr_t)modlist.mod_ports) ==
3977836SJohn.Forte@Sun.COM 			    sizeof (fc_ulp_ports_t)) {
3987836SJohn.Forte@Sun.COM 				while (ulp_port.port_handle != NULL) {
3997836SJohn.Forte@Sun.COM 					mdb_printf("%4x %16p %8x %8x\n",
4007836SJohn.Forte@Sun.COM 					    modinfo.ulp_type,
4017836SJohn.Forte@Sun.COM 					    ulp_port.port_handle,
4027836SJohn.Forte@Sun.COM 					    ulp_port.port_dstate,
4037836SJohn.Forte@Sun.COM 					    ulp_port.port_statec);
4047836SJohn.Forte@Sun.COM 
4057836SJohn.Forte@Sun.COM 					if (ulp_port.port_next == NULL)
4067836SJohn.Forte@Sun.COM 						break;
4077836SJohn.Forte@Sun.COM 
4087836SJohn.Forte@Sun.COM 					mdb_vread(&ulp_port,
4097836SJohn.Forte@Sun.COM 					    sizeof (fc_ulp_ports_t),
4107836SJohn.Forte@Sun.COM 					    (uintptr_t)ulp_port.port_next);
4117836SJohn.Forte@Sun.COM 				}
4127836SJohn.Forte@Sun.COM 			}
4137836SJohn.Forte@Sun.COM 		} else
4147836SJohn.Forte@Sun.COM 			mdb_warn("failed to read modinfo at %p",
4157836SJohn.Forte@Sun.COM 			    modlist.mod_info);
4167836SJohn.Forte@Sun.COM 
4177836SJohn.Forte@Sun.COM 	} else
4187836SJohn.Forte@Sun.COM 		mdb_warn("failed to read modlist at %p", addr);
4197836SJohn.Forte@Sun.COM 
4207836SJohn.Forte@Sun.COM 	return (DCMD_OK);
4217836SJohn.Forte@Sun.COM }
4227836SJohn.Forte@Sun.COM 
4237836SJohn.Forte@Sun.COM 
4247836SJohn.Forte@Sun.COM /*
4257836SJohn.Forte@Sun.COM  * Display an fc_local_port_t struct
4267836SJohn.Forte@Sun.COM  */
4277836SJohn.Forte@Sun.COM static int
fcport(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)4287836SJohn.Forte@Sun.COM fcport(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
4297836SJohn.Forte@Sun.COM {
4307836SJohn.Forte@Sun.COM 	fc_fca_port_t	portlist;
4317836SJohn.Forte@Sun.COM 	fc_local_port_t	port;
4327836SJohn.Forte@Sun.COM 	int		idx;
4337836SJohn.Forte@Sun.COM 	int		first = 1;
4347836SJohn.Forte@Sun.COM 	int		walking_fc_fca_portlist = 0;
4357836SJohn.Forte@Sun.COM 
4367836SJohn.Forte@Sun.COM 	if (argc != 0) {
4377836SJohn.Forte@Sun.COM 		int result;
4387836SJohn.Forte@Sun.COM 
4397836SJohn.Forte@Sun.COM 		if (argc != 1)
4407836SJohn.Forte@Sun.COM 			return (DCMD_USAGE);
4417836SJohn.Forte@Sun.COM 
4427836SJohn.Forte@Sun.COM 		if (argv->a_type != MDB_TYPE_STRING)
4437836SJohn.Forte@Sun.COM 			return (DCMD_USAGE);
4447836SJohn.Forte@Sun.COM 
4457836SJohn.Forte@Sun.COM 		walking_fc_fca_portlist = 1;
4467836SJohn.Forte@Sun.COM 	}
4477836SJohn.Forte@Sun.COM 
4487836SJohn.Forte@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
4497836SJohn.Forte@Sun.COM 		mdb_printf("Sorry, you must provide an address\n");
4507836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
4517836SJohn.Forte@Sun.COM 	}
4527836SJohn.Forte@Sun.COM 
4537836SJohn.Forte@Sun.COM 	if (walking_fc_fca_portlist) {
4547836SJohn.Forte@Sun.COM 		/*
4557836SJohn.Forte@Sun.COM 		 * Must read the fc_fca_portlist to get the fc_local_port addr
4567836SJohn.Forte@Sun.COM 		 */
4577836SJohn.Forte@Sun.COM 		if (mdb_vread(&portlist, sizeof (fc_fca_port_t), addr) ==
4587836SJohn.Forte@Sun.COM 		    sizeof (fc_fca_port_t)) {
4597836SJohn.Forte@Sun.COM 			addr = (uintptr_t)portlist.port_handle;
4607836SJohn.Forte@Sun.COM 		}
4617836SJohn.Forte@Sun.COM 	}
4627836SJohn.Forte@Sun.COM 
4637836SJohn.Forte@Sun.COM 	mdb_printf("Reading fc_local_port_t at %p:\n", addr);
4647836SJohn.Forte@Sun.COM 
4657836SJohn.Forte@Sun.COM 	/*
4667836SJohn.Forte@Sun.COM 	 * For each port, we just need to read the fc_local_port_t struct
4677836SJohn.Forte@Sun.COM 	 */
4687836SJohn.Forte@Sun.COM 
4697836SJohn.Forte@Sun.COM 	if (mdb_vread(&port, sizeof (fc_local_port_t),
4707836SJohn.Forte@Sun.COM 	    addr) == sizeof (fc_local_port_t)) {
4717836SJohn.Forte@Sun.COM 		mdb_printf("  fp_mutex          : 0x%p\n", port.fp_mutex);
4727836SJohn.Forte@Sun.COM 		mdb_printf("  fp_state          : 0x%-8x\n", port.fp_state);
4737836SJohn.Forte@Sun.COM 		mdb_printf("  fp_port_id        : 0x%-06x\n",
4747836SJohn.Forte@Sun.COM 		    port.fp_port_id.port_id);
4757836SJohn.Forte@Sun.COM 		mdb_printf("  fp_fca_handle     : 0x%p\n", port.fp_fca_handle);
4767836SJohn.Forte@Sun.COM 		mdb_printf("  fp_fca_tran       : 0x%p\n", port.fp_fca_tran);
4777836SJohn.Forte@Sun.COM 		mdb_printf("  fp_job_head       : 0x%p\n", port.fp_job_head);
4787836SJohn.Forte@Sun.COM 		mdb_printf("  fp_job_tail       : 0x%p\n", port.fp_job_tail);
4797836SJohn.Forte@Sun.COM 		mdb_printf("  fp_wait_head      : 0x%p\n", port.fp_wait_head);
4807836SJohn.Forte@Sun.COM 		mdb_printf("  fp_wait_tail      : 0x%p\n", port.fp_wait_tail);
4817836SJohn.Forte@Sun.COM 		mdb_printf("  fp_topology       : %u\n", port.fp_topology);
4827836SJohn.Forte@Sun.COM 		mdb_printf("  fp_task           : %d\n", port.fp_task);
4837836SJohn.Forte@Sun.COM 		mdb_printf("  fp_last_task      : %d\n", port.fp_last_task);
4847836SJohn.Forte@Sun.COM 		mdb_printf("  fp_soft_state     : 0x%-4x\n",
4857836SJohn.Forte@Sun.COM 		    port.fp_soft_state);
4867836SJohn.Forte@Sun.COM 		mdb_printf("  fp_flag           : 0x%-2x\n", port.fp_flag);
4877836SJohn.Forte@Sun.COM 		mdb_printf("  fp_statec_busy    : 0x%-8x\n",
4887836SJohn.Forte@Sun.COM 		    port.fp_statec_busy);
4897836SJohn.Forte@Sun.COM 		mdb_printf("  fp_port_num       : %d\n", port.fp_port_num);
4907836SJohn.Forte@Sun.COM 		mdb_printf("  fp_instance       : %d\n", port.fp_instance);
4917836SJohn.Forte@Sun.COM 		mdb_printf("  fp_ulp_attach     : %d\n", port.fp_ulp_attach);
4927836SJohn.Forte@Sun.COM 		mdb_printf("  fp_dev_count      : %d\n", port.fp_dev_count);
4937836SJohn.Forte@Sun.COM 		mdb_printf("  fp_total_devices  : %d\n", port.fp_total_devices);
4947836SJohn.Forte@Sun.COM 		mdb_printf("  fp_bind_state     : 0x%-8x\n",
4957836SJohn.Forte@Sun.COM 		    port.fp_bind_state);
4967836SJohn.Forte@Sun.COM 		mdb_printf("  fp_options        : 0x%-8x\n", port.fp_options);
4977836SJohn.Forte@Sun.COM 		mdb_printf("  fp_port_type      : 0x%-2x\n",
4987836SJohn.Forte@Sun.COM 		    port.fp_port_type.port_type);
4997836SJohn.Forte@Sun.COM 		mdb_printf("  fp_ub_count       : %d\n", port.fp_ub_count);
5007836SJohn.Forte@Sun.COM 		mdb_printf("  fp_active_ubs     : %d\n", port.fp_active_ubs);
5017836SJohn.Forte@Sun.COM 		mdb_printf("  fp_port_dip       : 0x%p\n", port.fp_port_dip);
5027836SJohn.Forte@Sun.COM 		mdb_printf("  fp_fca_dip        : 0x%p\n", port.fp_fca_dip);
5037836SJohn.Forte@Sun.COM 
5047836SJohn.Forte@Sun.COM 		for (idx = 0; idx < 16; idx++) {
5057836SJohn.Forte@Sun.COM 			if (port.fp_ip_addr[idx] != 0)
5067836SJohn.Forte@Sun.COM 				break;
5077836SJohn.Forte@Sun.COM 		}
5087836SJohn.Forte@Sun.COM 
5097836SJohn.Forte@Sun.COM 		if (idx != 16) {
5107836SJohn.Forte@Sun.COM 			mdb_printf("  fp_ip_addr        : %-2x:%-2x:%-2x:%-2x:"
5117836SJohn.Forte@Sun.COM 			    "%-2x:%-2x:%-2x:%-2x:%-2x:%-2x:%-2x:%-2x:%-2x:%-2x"
5127836SJohn.Forte@Sun.COM 			    ":%-2x:%-2x\n",
5137836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[0], port.fp_ip_addr[1],
5147836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[2], port.fp_ip_addr[3],
5157836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[4], port.fp_ip_addr[5],
5167836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[6], port.fp_ip_addr[7],
5177836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[8], port.fp_ip_addr[9],
5187836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[10], port.fp_ip_addr[11],
5197836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[12], port.fp_ip_addr[13],
5207836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[14], port.fp_ip_addr[15]);
5217836SJohn.Forte@Sun.COM 		} else {
5227836SJohn.Forte@Sun.COM 			mdb_printf("  fp_ip_addr        : N/A\n");
5237836SJohn.Forte@Sun.COM 		}
5247836SJohn.Forte@Sun.COM 
5257836SJohn.Forte@Sun.COM 		mdb_printf("  fp_fc4_types      : ");
5267836SJohn.Forte@Sun.COM 
5277836SJohn.Forte@Sun.COM 		for (idx = 0; idx < 8; idx++) {
5287836SJohn.Forte@Sun.COM 			if (port.fp_fc4_types[idx] != 0) {
5297836SJohn.Forte@Sun.COM 				if (first) {
5307836SJohn.Forte@Sun.COM 					mdb_printf("%d",
5317836SJohn.Forte@Sun.COM 					    port.fp_fc4_types[idx]);
5327836SJohn.Forte@Sun.COM 					first = 0;
5337836SJohn.Forte@Sun.COM 				} else {
5347836SJohn.Forte@Sun.COM 					mdb_printf(", %d",
5357836SJohn.Forte@Sun.COM 					    port.fp_fc4_types[idx]);
5367836SJohn.Forte@Sun.COM 				}
5377836SJohn.Forte@Sun.COM 			}
5387836SJohn.Forte@Sun.COM 		}
5397836SJohn.Forte@Sun.COM 
5407836SJohn.Forte@Sun.COM 		if (first) {
5417836SJohn.Forte@Sun.COM 			mdb_printf("None\n");
5427836SJohn.Forte@Sun.COM 		} else {
5437836SJohn.Forte@Sun.COM 			mdb_printf("\n");
5447836SJohn.Forte@Sun.COM 		}
5457836SJohn.Forte@Sun.COM 
5467836SJohn.Forte@Sun.COM 		mdb_printf("  fp_pm_level       : %d\n", port.fp_pm_level);
5477836SJohn.Forte@Sun.COM 		mdb_printf("  fp_pm_busy        : %d\n", port.fp_pm_busy);
5487836SJohn.Forte@Sun.COM 		mdb_printf("  fp_pm_busy_nocomp : 0x%-8x\n",
5497836SJohn.Forte@Sun.COM 		    port.fp_pm_busy_nocomp);
5507836SJohn.Forte@Sun.COM 		mdb_printf("  fp_hard_addr      : 0x%-6x\n",
5517836SJohn.Forte@Sun.COM 		    port.fp_hard_addr.hard_addr);
5527836SJohn.Forte@Sun.COM 		mdb_printf("  fp_sym_port_name  : \"%s\"\n",
5537836SJohn.Forte@Sun.COM 		    port.fp_sym_port_name);
5547836SJohn.Forte@Sun.COM 		mdb_printf("  fp_sym_node_name  : \"%s\"\n",
5557836SJohn.Forte@Sun.COM 		    port.fp_sym_node_name);
5567836SJohn.Forte@Sun.COM 		mdb_printf("  fp_rscn_count     : %d\n", port.fp_rscn_count);
5577836SJohn.Forte@Sun.COM 	} else {
5587836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fc_local_port_t at 0x%p", addr);
5597836SJohn.Forte@Sun.COM 	}
5607836SJohn.Forte@Sun.COM 
5617836SJohn.Forte@Sun.COM 	mdb_printf("\n");
5627836SJohn.Forte@Sun.COM 
5637836SJohn.Forte@Sun.COM 	return (DCMD_OK);
5647836SJohn.Forte@Sun.COM }
5657836SJohn.Forte@Sun.COM 
5667836SJohn.Forte@Sun.COM 
5677836SJohn.Forte@Sun.COM /*
5687836SJohn.Forte@Sun.COM  * Leadville remote_port walker/dcmd code
5697836SJohn.Forte@Sun.COM  */
5707836SJohn.Forte@Sun.COM 
5717836SJohn.Forte@Sun.COM /*
5727836SJohn.Forte@Sun.COM  * We need to be given the address of a port structure in order to start
5737836SJohn.Forte@Sun.COM  * walking.  From that, we can read the pwwn table.
5747836SJohn.Forte@Sun.COM  */
5757836SJohn.Forte@Sun.COM static int
pd_by_pwwn_walk_i(mdb_walk_state_t * wsp)5767836SJohn.Forte@Sun.COM pd_by_pwwn_walk_i(mdb_walk_state_t *wsp)
5777836SJohn.Forte@Sun.COM {
5787836SJohn.Forte@Sun.COM 	fc_local_port_t port;
5797836SJohn.Forte@Sun.COM 
5807836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
5817836SJohn.Forte@Sun.COM 		mdb_warn("pd_by_pwwn walk doesn't support global walks\n");
5827836SJohn.Forte@Sun.COM 		return (WALK_ERR);
5837836SJohn.Forte@Sun.COM 	}
5847836SJohn.Forte@Sun.COM 
5857836SJohn.Forte@Sun.COM 	/*
5867836SJohn.Forte@Sun.COM 	 * Allocate space for the pwwn_hash table
5877836SJohn.Forte@Sun.COM 	 */
5887836SJohn.Forte@Sun.COM 
5897836SJohn.Forte@Sun.COM 	fp_pwwn_table = mdb_alloc(sizeof (struct pwwn_hash) *
5907836SJohn.Forte@Sun.COM 	    PWWN_HASH_TABLE_SIZE, UM_SLEEP);
5917836SJohn.Forte@Sun.COM 
5927836SJohn.Forte@Sun.COM 	/*
5937836SJohn.Forte@Sun.COM 	 * Input should be an fc_local_port_t, so read it to get the pwwn
5947836SJohn.Forte@Sun.COM 	 * table's head
5957836SJohn.Forte@Sun.COM 	 */
5967836SJohn.Forte@Sun.COM 
5977836SJohn.Forte@Sun.COM 	if (mdb_vread(&port, sizeof (fc_local_port_t), wsp->walk_addr) !=
5987836SJohn.Forte@Sun.COM 	    sizeof (fc_local_port_t)) {
5997836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in the port structure address\n");
6007836SJohn.Forte@Sun.COM 		return (WALK_ERR);
6017836SJohn.Forte@Sun.COM 	}
6027836SJohn.Forte@Sun.COM 
6037836SJohn.Forte@Sun.COM 	if (mdb_vread(fp_pwwn_table, sizeof (struct pwwn_hash) *
6047836SJohn.Forte@Sun.COM 	    PWWN_HASH_TABLE_SIZE, (uintptr_t)port.fp_pwwn_table) == -1) {
6057836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in the pwwn hash table\n");
6067836SJohn.Forte@Sun.COM 		return (WALK_ERR);
6077836SJohn.Forte@Sun.COM 	}
6087836SJohn.Forte@Sun.COM 
6097836SJohn.Forte@Sun.COM 	pd_hash_index = 0;
6107836SJohn.Forte@Sun.COM 
6117836SJohn.Forte@Sun.COM 	while ((fp_pwwn_table[pd_hash_index].pwwn_head == NULL) &&
6127836SJohn.Forte@Sun.COM 	    (pd_hash_index < PWWN_HASH_TABLE_SIZE)) {
6137836SJohn.Forte@Sun.COM 		pd_hash_index++;
6147836SJohn.Forte@Sun.COM 	}
6157836SJohn.Forte@Sun.COM 
6167836SJohn.Forte@Sun.COM 	wsp->walk_addr = (uintptr_t)fp_pwwn_table[pd_hash_index].pwwn_head;
6177836SJohn.Forte@Sun.COM 
6187836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (fc_remote_port_t), UM_SLEEP);
6197836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
6207836SJohn.Forte@Sun.COM }
6217836SJohn.Forte@Sun.COM 
6227836SJohn.Forte@Sun.COM /*
6237836SJohn.Forte@Sun.COM  * At each step, read a fc_remote_port_t into our private storage, and then
6247836SJohn.Forte@Sun.COM  * invoke the callback function.  We terminate when we reach a NULL p_next
6257836SJohn.Forte@Sun.COM  * pointer.
6267836SJohn.Forte@Sun.COM  */
6277836SJohn.Forte@Sun.COM static int
pd_by_pwwn_walk_s(mdb_walk_state_t * wsp)6287836SJohn.Forte@Sun.COM pd_by_pwwn_walk_s(mdb_walk_state_t *wsp)
6297836SJohn.Forte@Sun.COM {
6307836SJohn.Forte@Sun.COM 	int status;
6317836SJohn.Forte@Sun.COM 
6327836SJohn.Forte@Sun.COM 	if ((wsp->walk_addr == NULL) &&
6337836SJohn.Forte@Sun.COM 	    (pd_hash_index >= (PWWN_HASH_TABLE_SIZE - 1))) {
6347836SJohn.Forte@Sun.COM 		return (WALK_DONE);
6357836SJohn.Forte@Sun.COM 	}
6367836SJohn.Forte@Sun.COM 
6377836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (fc_remote_port_t), wsp->walk_addr)
6387836SJohn.Forte@Sun.COM 	    == -1) {
6397836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fc_remote_port at %p", wsp->walk_addr);
6407836SJohn.Forte@Sun.COM 		return (WALK_DONE);
6417836SJohn.Forte@Sun.COM 	}
6427836SJohn.Forte@Sun.COM 
6437836SJohn.Forte@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
6447836SJohn.Forte@Sun.COM 	    wsp->walk_cbdata);
6457836SJohn.Forte@Sun.COM 
6467836SJohn.Forte@Sun.COM 	wsp->walk_addr =
6477836SJohn.Forte@Sun.COM 	    (uintptr_t)(((fc_remote_port_t *)wsp->walk_data)->pd_wwn_hnext);
6487836SJohn.Forte@Sun.COM 
6497836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
6507836SJohn.Forte@Sun.COM 		/*
6517836SJohn.Forte@Sun.COM 		 * Try the next hash list, if there is one.
6527836SJohn.Forte@Sun.COM 		 */
6537836SJohn.Forte@Sun.COM 
6547836SJohn.Forte@Sun.COM 		pd_hash_index++;
6557836SJohn.Forte@Sun.COM 
6567836SJohn.Forte@Sun.COM 		while ((fp_pwwn_table[pd_hash_index].pwwn_head == NULL) &&
6577836SJohn.Forte@Sun.COM 		    (pd_hash_index < PWWN_HASH_TABLE_SIZE)) {
6587836SJohn.Forte@Sun.COM 			pd_hash_index++;
6597836SJohn.Forte@Sun.COM 		}
6607836SJohn.Forte@Sun.COM 
6617836SJohn.Forte@Sun.COM 		if (pd_hash_index == PWWN_HASH_TABLE_SIZE) {
6627836SJohn.Forte@Sun.COM 			/* We're done */
6637836SJohn.Forte@Sun.COM 			return (status);
6647836SJohn.Forte@Sun.COM 		}
6657836SJohn.Forte@Sun.COM 
6667836SJohn.Forte@Sun.COM 		wsp->walk_addr =
6677836SJohn.Forte@Sun.COM 		    (uintptr_t)fp_pwwn_table[pd_hash_index].pwwn_head;
6687836SJohn.Forte@Sun.COM 	}
6697836SJohn.Forte@Sun.COM 
6707836SJohn.Forte@Sun.COM 	return (status);
6717836SJohn.Forte@Sun.COM }
6727836SJohn.Forte@Sun.COM 
6737836SJohn.Forte@Sun.COM /*
6747836SJohn.Forte@Sun.COM  * The walker's fini function is invoked at the end of each walk.
6757836SJohn.Forte@Sun.COM  */
6767836SJohn.Forte@Sun.COM static void
pd_by_pwwn_walk_f(mdb_walk_state_t * wsp)6777836SJohn.Forte@Sun.COM pd_by_pwwn_walk_f(mdb_walk_state_t *wsp)
6787836SJohn.Forte@Sun.COM {
6797836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (fc_remote_port_t));
6807836SJohn.Forte@Sun.COM 	mdb_free(fp_pwwn_table, sizeof (struct pwwn_hash) *
6817836SJohn.Forte@Sun.COM 	    PWWN_HASH_TABLE_SIZE);
6827836SJohn.Forte@Sun.COM 	fp_pwwn_table = NULL;
6837836SJohn.Forte@Sun.COM }
6847836SJohn.Forte@Sun.COM 
6857836SJohn.Forte@Sun.COM /*
6867836SJohn.Forte@Sun.COM  * This is the same walker as pd_by_pwwn, but we walk the D_ID hash table
6877836SJohn.Forte@Sun.COM  */
6887836SJohn.Forte@Sun.COM 
6897836SJohn.Forte@Sun.COM static int
pd_by_did_walk_i(mdb_walk_state_t * wsp)6907836SJohn.Forte@Sun.COM pd_by_did_walk_i(mdb_walk_state_t *wsp)
6917836SJohn.Forte@Sun.COM {
6927836SJohn.Forte@Sun.COM 	fc_local_port_t port;
6937836SJohn.Forte@Sun.COM 
6947836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
6957836SJohn.Forte@Sun.COM 		mdb_warn("pd_by_did walk doesn't support global walks\n");
6967836SJohn.Forte@Sun.COM 		return (WALK_ERR);
6977836SJohn.Forte@Sun.COM 	}
6987836SJohn.Forte@Sun.COM 
6997836SJohn.Forte@Sun.COM 	/*
7007836SJohn.Forte@Sun.COM 	 * Allocate space for the did_hash table
7017836SJohn.Forte@Sun.COM 	 */
7027836SJohn.Forte@Sun.COM 
7037836SJohn.Forte@Sun.COM 	fp_did_table = mdb_alloc(sizeof (struct d_id_hash) *
7047836SJohn.Forte@Sun.COM 	    D_ID_HASH_TABLE_SIZE, UM_SLEEP);
7057836SJohn.Forte@Sun.COM 
7067836SJohn.Forte@Sun.COM 	/*
7077836SJohn.Forte@Sun.COM 	 * Input should be an fc_local_port_t, so read it to get the d_id
7087836SJohn.Forte@Sun.COM 	 * table's head
7097836SJohn.Forte@Sun.COM 	 */
7107836SJohn.Forte@Sun.COM 
7117836SJohn.Forte@Sun.COM 	if (mdb_vread(&port, sizeof (fc_local_port_t), wsp->walk_addr) !=
7127836SJohn.Forte@Sun.COM 	    sizeof (fc_local_port_t)) {
7137836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in the port structure address\n");
7147836SJohn.Forte@Sun.COM 		return (WALK_ERR);
7157836SJohn.Forte@Sun.COM 	}
7167836SJohn.Forte@Sun.COM 
7177836SJohn.Forte@Sun.COM 	if (mdb_vread(fp_did_table, sizeof (struct d_id_hash) *
7187836SJohn.Forte@Sun.COM 	    D_ID_HASH_TABLE_SIZE, (uintptr_t)port.fp_did_table) == -1) {
7197836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in the D_ID hash table\n");
7207836SJohn.Forte@Sun.COM 		return (WALK_ERR);
7217836SJohn.Forte@Sun.COM 	}
7227836SJohn.Forte@Sun.COM 	pd_hash_index = 0;
7237836SJohn.Forte@Sun.COM 
7247836SJohn.Forte@Sun.COM 	while ((fp_did_table[pd_hash_index].d_id_head == NULL) &&
7257836SJohn.Forte@Sun.COM 	    (pd_hash_index < D_ID_HASH_TABLE_SIZE)) {
7267836SJohn.Forte@Sun.COM 		pd_hash_index++;
7277836SJohn.Forte@Sun.COM 	}
7287836SJohn.Forte@Sun.COM 
7297836SJohn.Forte@Sun.COM 	wsp->walk_addr = (uintptr_t)fp_did_table[pd_hash_index].d_id_head;
7307836SJohn.Forte@Sun.COM 
7317836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (fc_remote_port_t), UM_SLEEP);
7327836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
7337836SJohn.Forte@Sun.COM }
7347836SJohn.Forte@Sun.COM 
7357836SJohn.Forte@Sun.COM /*
7367836SJohn.Forte@Sun.COM  * At each step, read a fc_remote_port_t into our private storage, and then
7377836SJohn.Forte@Sun.COM  * invoke the callback function.  We terminate when we reach a NULL p_next
7387836SJohn.Forte@Sun.COM  * pointer.
7397836SJohn.Forte@Sun.COM  */
7407836SJohn.Forte@Sun.COM static int
pd_by_did_walk_s(mdb_walk_state_t * wsp)7417836SJohn.Forte@Sun.COM pd_by_did_walk_s(mdb_walk_state_t *wsp)
7427836SJohn.Forte@Sun.COM {
7437836SJohn.Forte@Sun.COM 	int status;
7447836SJohn.Forte@Sun.COM 
7457836SJohn.Forte@Sun.COM 	if ((wsp->walk_addr == NULL) &&
7467836SJohn.Forte@Sun.COM 	    (pd_hash_index >= (D_ID_HASH_TABLE_SIZE - 1))) {
7477836SJohn.Forte@Sun.COM 		return (WALK_DONE);
7487836SJohn.Forte@Sun.COM 	}
7497836SJohn.Forte@Sun.COM 
7507836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (fc_remote_port_t), wsp->walk_addr)
7517836SJohn.Forte@Sun.COM 	    == -1) {
7527836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fc_remote_port at %p", wsp->walk_addr);
7537836SJohn.Forte@Sun.COM 		return (WALK_DONE);
7547836SJohn.Forte@Sun.COM 	}
7557836SJohn.Forte@Sun.COM 
7567836SJohn.Forte@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
7577836SJohn.Forte@Sun.COM 	    wsp->walk_cbdata);
7587836SJohn.Forte@Sun.COM 
7597836SJohn.Forte@Sun.COM 	wsp->walk_addr =
7607836SJohn.Forte@Sun.COM 	    (uintptr_t)(((fc_remote_port_t *)wsp->walk_data)->pd_did_hnext);
7617836SJohn.Forte@Sun.COM 
7627836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
7637836SJohn.Forte@Sun.COM 		/*
7647836SJohn.Forte@Sun.COM 		 * Try the next hash list, if there is one.
7657836SJohn.Forte@Sun.COM 		 */
7667836SJohn.Forte@Sun.COM 
7677836SJohn.Forte@Sun.COM 		pd_hash_index++;
7687836SJohn.Forte@Sun.COM 
7697836SJohn.Forte@Sun.COM 		while ((fp_did_table[pd_hash_index].d_id_head == NULL) &&
7707836SJohn.Forte@Sun.COM 		    (pd_hash_index < D_ID_HASH_TABLE_SIZE)) {
7717836SJohn.Forte@Sun.COM 			pd_hash_index++;
7727836SJohn.Forte@Sun.COM 		}
7737836SJohn.Forte@Sun.COM 
7747836SJohn.Forte@Sun.COM 		if (pd_hash_index == D_ID_HASH_TABLE_SIZE) {
7757836SJohn.Forte@Sun.COM 			/* We're done */
7767836SJohn.Forte@Sun.COM 			return (status);
7777836SJohn.Forte@Sun.COM 		}
7787836SJohn.Forte@Sun.COM 
7797836SJohn.Forte@Sun.COM 		wsp->walk_addr =
7807836SJohn.Forte@Sun.COM 		    (uintptr_t)fp_did_table[pd_hash_index].d_id_head;
7817836SJohn.Forte@Sun.COM 	}
7827836SJohn.Forte@Sun.COM 
7837836SJohn.Forte@Sun.COM 	return (status);
7847836SJohn.Forte@Sun.COM }
7857836SJohn.Forte@Sun.COM 
7867836SJohn.Forte@Sun.COM /*
7877836SJohn.Forte@Sun.COM  * The walker's fini function is invoked at the end of each walk.
7887836SJohn.Forte@Sun.COM  */
7897836SJohn.Forte@Sun.COM static void
pd_by_did_walk_f(mdb_walk_state_t * wsp)7907836SJohn.Forte@Sun.COM pd_by_did_walk_f(mdb_walk_state_t *wsp)
7917836SJohn.Forte@Sun.COM {
7927836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (fc_remote_port_t));
7937836SJohn.Forte@Sun.COM 	mdb_free(fp_did_table, sizeof (struct d_id_hash) *
7947836SJohn.Forte@Sun.COM 	    D_ID_HASH_TABLE_SIZE);
7957836SJohn.Forte@Sun.COM 	fp_did_table = NULL;
7967836SJohn.Forte@Sun.COM }
7977836SJohn.Forte@Sun.COM 
7987836SJohn.Forte@Sun.COM 
7997836SJohn.Forte@Sun.COM /*
8007836SJohn.Forte@Sun.COM  * Display a remote_port structure
8017836SJohn.Forte@Sun.COM  */
8027836SJohn.Forte@Sun.COM static int
remote_port(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)8037836SJohn.Forte@Sun.COM remote_port(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
8047836SJohn.Forte@Sun.COM {
8057836SJohn.Forte@Sun.COM 	fc_remote_port_t	pd;
8067836SJohn.Forte@Sun.COM 	int			idx;
8077836SJohn.Forte@Sun.COM 	int			first = 1;
8087836SJohn.Forte@Sun.COM 
8097836SJohn.Forte@Sun.COM 	if (argc > 0) {
8107836SJohn.Forte@Sun.COM 		return (DCMD_USAGE);
8117836SJohn.Forte@Sun.COM 	}
8127836SJohn.Forte@Sun.COM 
8137836SJohn.Forte@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
8147836SJohn.Forte@Sun.COM 		mdb_printf("Sorry, you must provide an address\n");
8157836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
8167836SJohn.Forte@Sun.COM 	}
8177836SJohn.Forte@Sun.COM 
8187836SJohn.Forte@Sun.COM 	if (mdb_vread(&pd, sizeof (fc_remote_port_t), addr) !=
8197836SJohn.Forte@Sun.COM 	    sizeof (fc_remote_port_t)) {
8207836SJohn.Forte@Sun.COM 		mdb_warn("Error reading pd at 0x%x\n", addr);
8217836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
8227836SJohn.Forte@Sun.COM 	}
8237836SJohn.Forte@Sun.COM 
8247836SJohn.Forte@Sun.COM 	mdb_printf("Reading remote_port at 0x%p\n", addr);
8257836SJohn.Forte@Sun.COM 	mdb_printf("  mutex          : 0x%p\n", pd.pd_mutex);
8267836SJohn.Forte@Sun.COM 	mdb_printf("  port_id        : 0x%-8x\n", pd.pd_port_id);
8277836SJohn.Forte@Sun.COM 	mdb_printf("  port_name      : 0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
8287836SJohn.Forte@Sun.COM 	    pd.pd_port_name.raw_wwn[0], pd.pd_port_name.raw_wwn[1],
8297836SJohn.Forte@Sun.COM 	    pd.pd_port_name.raw_wwn[2], pd.pd_port_name.raw_wwn[3],
8307836SJohn.Forte@Sun.COM 	    pd.pd_port_name.raw_wwn[4], pd.pd_port_name.raw_wwn[5],
8317836SJohn.Forte@Sun.COM 	    pd.pd_port_name.raw_wwn[6], pd.pd_port_name.raw_wwn[7]);
8327836SJohn.Forte@Sun.COM 	mdb_printf("  login_count    : %d\n", pd.pd_login_count);
8337836SJohn.Forte@Sun.COM 	mdb_printf("  state          : 0x%x ", pd.pd_state);
8347836SJohn.Forte@Sun.COM 
8357836SJohn.Forte@Sun.COM 	switch (pd.pd_state) {
8367836SJohn.Forte@Sun.COM 	case PORT_DEVICE_INVALID:
8377836SJohn.Forte@Sun.COM 		mdb_printf("(invalid)\n");
8387836SJohn.Forte@Sun.COM 		break;
8397836SJohn.Forte@Sun.COM 	case PORT_DEVICE_VALID:
8407836SJohn.Forte@Sun.COM 		mdb_printf("(valid)\n");
8417836SJohn.Forte@Sun.COM 		break;
8427836SJohn.Forte@Sun.COM 	case PORT_DEVICE_LOGGED_IN:
8437836SJohn.Forte@Sun.COM 		mdb_printf("(logged in)\n");
8447836SJohn.Forte@Sun.COM 		break;
8457836SJohn.Forte@Sun.COM 	default:
8467836SJohn.Forte@Sun.COM 		mdb_printf("(Unknown state)\n");
8477836SJohn.Forte@Sun.COM 	}
8487836SJohn.Forte@Sun.COM 
8497836SJohn.Forte@Sun.COM 	mdb_printf("  remote node    : 0x%p\n", pd.pd_remote_nodep);
8507836SJohn.Forte@Sun.COM 	mdb_printf("  hard_addr      : 0x%x\n", pd.pd_hard_addr);
8517836SJohn.Forte@Sun.COM 	mdb_printf("  local port     : 0x%p\n", pd.pd_port);
8527836SJohn.Forte@Sun.COM 	mdb_printf("  type           : %d ", pd.pd_type);
8537836SJohn.Forte@Sun.COM 
8547836SJohn.Forte@Sun.COM 	switch (pd.pd_type) {
8557836SJohn.Forte@Sun.COM 	case PORT_DEVICE_NOCHANGE:
8567836SJohn.Forte@Sun.COM 		mdb_printf("(No change)\n");
8577836SJohn.Forte@Sun.COM 		break;
8587836SJohn.Forte@Sun.COM 	case PORT_DEVICE_NEW:
8597836SJohn.Forte@Sun.COM 		mdb_printf("(New)\n");
8607836SJohn.Forte@Sun.COM 		break;
8617836SJohn.Forte@Sun.COM 	case PORT_DEVICE_OLD:
8627836SJohn.Forte@Sun.COM 		mdb_printf("(Old)\n");
8637836SJohn.Forte@Sun.COM 		break;
8647836SJohn.Forte@Sun.COM 	case PORT_DEVICE_CHANGED:
8657836SJohn.Forte@Sun.COM 		mdb_printf("(Changed)\n");
8667836SJohn.Forte@Sun.COM 		break;
8677836SJohn.Forte@Sun.COM 	case PORT_DEVICE_DELETE:
8687836SJohn.Forte@Sun.COM 		mdb_printf("(Delete)\n");
8697836SJohn.Forte@Sun.COM 		break;
8707836SJohn.Forte@Sun.COM 	case PORT_DEVICE_USER_LOGIN:
8717836SJohn.Forte@Sun.COM 		mdb_printf("(User login)\n");
8727836SJohn.Forte@Sun.COM 		break;
8737836SJohn.Forte@Sun.COM 	case PORT_DEVICE_USER_LOGOUT:
8747836SJohn.Forte@Sun.COM 		mdb_printf("(User logout)\n");
8757836SJohn.Forte@Sun.COM 		break;
8767836SJohn.Forte@Sun.COM 	case PORT_DEVICE_USER_CREATE:
8777836SJohn.Forte@Sun.COM 		mdb_printf("(User create)\n");
8787836SJohn.Forte@Sun.COM 		break;
8797836SJohn.Forte@Sun.COM 	case PORT_DEVICE_USER_DELETE:
8807836SJohn.Forte@Sun.COM 		mdb_printf("(User delete)\n");
8817836SJohn.Forte@Sun.COM 		break;
8827836SJohn.Forte@Sun.COM 	default:
8837836SJohn.Forte@Sun.COM 		mdb_printf("(Unknown type)\n");
8847836SJohn.Forte@Sun.COM 	}
8857836SJohn.Forte@Sun.COM 
8867836SJohn.Forte@Sun.COM 	mdb_printf("  flags          : 0x%x ", pd.pd_flags);
8877836SJohn.Forte@Sun.COM 
8887836SJohn.Forte@Sun.COM 	switch (pd.pd_flags) {
8897836SJohn.Forte@Sun.COM 	case PD_IDLE:
8907836SJohn.Forte@Sun.COM 		mdb_printf("(Idle)\n");
8917836SJohn.Forte@Sun.COM 		break;
8927836SJohn.Forte@Sun.COM 	case PD_ELS_IN_PROGRESS:
8937836SJohn.Forte@Sun.COM 		mdb_printf("(ELS in progress)\n");
8947836SJohn.Forte@Sun.COM 		break;
8957836SJohn.Forte@Sun.COM 	case PD_ELS_MARK:
8967836SJohn.Forte@Sun.COM 		mdb_printf("(Mark)\n");
8977836SJohn.Forte@Sun.COM 		break;
8987836SJohn.Forte@Sun.COM 	default:
8997836SJohn.Forte@Sun.COM 		mdb_printf("(Unknown flag value)\n");
9007836SJohn.Forte@Sun.COM 	}
9017836SJohn.Forte@Sun.COM 
9027836SJohn.Forte@Sun.COM 	mdb_printf("  login_class    : 0x%x\n", pd.pd_login_class);
9037836SJohn.Forte@Sun.COM 	mdb_printf("  recipient      : %d\n", pd.pd_recepient);
9047836SJohn.Forte@Sun.COM 	mdb_printf("  ref_count      : %d\n", pd.pd_ref_count);
9057836SJohn.Forte@Sun.COM 	mdb_printf("  aux_flags      : 0x%x ", pd.pd_aux_flags);
9067836SJohn.Forte@Sun.COM 
9077836SJohn.Forte@Sun.COM 	first = 1;
9087836SJohn.Forte@Sun.COM 	if (pd.pd_aux_flags & PD_IN_DID_QUEUE) {
9097836SJohn.Forte@Sun.COM 		mdb_printf("(IN_DID_QUEUE");
9107836SJohn.Forte@Sun.COM 		first = 0;
9117836SJohn.Forte@Sun.COM 	}
9127836SJohn.Forte@Sun.COM 
9137836SJohn.Forte@Sun.COM 	if (pd.pd_aux_flags & PD_DISABLE_RELOGIN) {
9147836SJohn.Forte@Sun.COM 		if (first) {
9157836SJohn.Forte@Sun.COM 			mdb_printf("(DISABLE_RELOGIN");
9167836SJohn.Forte@Sun.COM 		} else {
9177836SJohn.Forte@Sun.COM 			mdb_printf(", DISABLE_RELOGIN");
9187836SJohn.Forte@Sun.COM 		}
9197836SJohn.Forte@Sun.COM 		first = 0;
9207836SJohn.Forte@Sun.COM 	}
9217836SJohn.Forte@Sun.COM 
9227836SJohn.Forte@Sun.COM 	if (pd.pd_aux_flags & PD_NEEDS_REMOVAL) {
9237836SJohn.Forte@Sun.COM 		if (first) {
9247836SJohn.Forte@Sun.COM 			mdb_printf("(NEEDS_REMOVAL");
9257836SJohn.Forte@Sun.COM 		} else {
9267836SJohn.Forte@Sun.COM 			mdb_printf(", NEEDS_REMOVAL");
9277836SJohn.Forte@Sun.COM 		}
9287836SJohn.Forte@Sun.COM 		first = 0;
9297836SJohn.Forte@Sun.COM 	}
9307836SJohn.Forte@Sun.COM 
9317836SJohn.Forte@Sun.COM 	if (pd.pd_aux_flags & PD_LOGGED_OUT) {
9327836SJohn.Forte@Sun.COM 		if (first) {
9337836SJohn.Forte@Sun.COM 			mdb_printf("(LOGGED_OUT");
9347836SJohn.Forte@Sun.COM 		} else {
9357836SJohn.Forte@Sun.COM 			mdb_printf(", LOGGED_OUT");
9367836SJohn.Forte@Sun.COM 		}
9377836SJohn.Forte@Sun.COM 		first = 0;
9387836SJohn.Forte@Sun.COM 	}
9397836SJohn.Forte@Sun.COM 
9407836SJohn.Forte@Sun.COM 	if (pd.pd_aux_flags & PD_GIVEN_TO_ULPS) {
9417836SJohn.Forte@Sun.COM 		if (first) {
9427836SJohn.Forte@Sun.COM 			mdb_printf("(GIVEN_TO_ULPS");
9437836SJohn.Forte@Sun.COM 		} else {
9447836SJohn.Forte@Sun.COM 			mdb_printf(", GIVEN_TO_ULPS");
9457836SJohn.Forte@Sun.COM 		}
9467836SJohn.Forte@Sun.COM 		first = 0;
9477836SJohn.Forte@Sun.COM 	}
9487836SJohn.Forte@Sun.COM 
9497836SJohn.Forte@Sun.COM 	if (first == 0) {
9507836SJohn.Forte@Sun.COM 		mdb_printf(")\n");
9517836SJohn.Forte@Sun.COM 	} else {
9527836SJohn.Forte@Sun.COM 		mdb_printf("\n");
9537836SJohn.Forte@Sun.COM 	}
9547836SJohn.Forte@Sun.COM 
9557836SJohn.Forte@Sun.COM 	mdb_printf("  sig            : %p\n", pd.pd_logo_tc.sig);
9567836SJohn.Forte@Sun.COM 	mdb_printf("  active         : %d\n", pd.pd_logo_tc.active);
9577836SJohn.Forte@Sun.COM 	mdb_printf("  counter        : %d\n", pd.pd_logo_tc.counter);
9587836SJohn.Forte@Sun.COM 	mdb_printf("  max_value      : %d\n", pd.pd_logo_tc.max_value);
9597836SJohn.Forte@Sun.COM 	mdb_printf("  timer          : %d\n", pd.pd_logo_tc.timer);
9607836SJohn.Forte@Sun.COM 	mdb_printf("\n");
9617836SJohn.Forte@Sun.COM 
9627836SJohn.Forte@Sun.COM 	return (DCMD_OK);
9637836SJohn.Forte@Sun.COM }
9647836SJohn.Forte@Sun.COM 
9657836SJohn.Forte@Sun.COM int
fc_dump_logmsg(fc_trace_dmsg_t * addr,uint_t pktstart,uint_t pktend,uint_t * printed)9667836SJohn.Forte@Sun.COM fc_dump_logmsg(fc_trace_dmsg_t *addr, uint_t pktstart, uint_t pktend,
9677836SJohn.Forte@Sun.COM     uint_t *printed)
9687836SJohn.Forte@Sun.COM {
9697836SJohn.Forte@Sun.COM 	fc_trace_dmsg_t	msg;
9707836SJohn.Forte@Sun.COM 	caddr_t		buf;
9717836SJohn.Forte@Sun.COM 	char		merge[1024];
9727836SJohn.Forte@Sun.COM 	caddr_t		tmppkt;
9737836SJohn.Forte@Sun.COM 	char		*tmpbuf; /* for tokenising the buffer */
9747836SJohn.Forte@Sun.COM 	uint_t		pktnum = 0;
9757836SJohn.Forte@Sun.COM 
9767836SJohn.Forte@Sun.COM 	while (addr != NULL) {
9777836SJohn.Forte@Sun.COM 		if (mdb_vread(&msg, sizeof (msg), (uintptr_t)addr) !=
9787836SJohn.Forte@Sun.COM 		    sizeof (msg)) {
9797836SJohn.Forte@Sun.COM 			mdb_warn("failed to read message pointer in kernel");
9807836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
9817836SJohn.Forte@Sun.COM 		}
9827836SJohn.Forte@Sun.COM 
9837836SJohn.Forte@Sun.COM 		if (msg.id_size) {
9847836SJohn.Forte@Sun.COM 
9857836SJohn.Forte@Sun.COM 			buf = mdb_alloc(msg.id_size + 1, UM_SLEEP);
9867836SJohn.Forte@Sun.COM 			tmppkt = mdb_alloc(msg.id_size + 1, UM_SLEEP);
9877836SJohn.Forte@Sun.COM 
9887836SJohn.Forte@Sun.COM 			if (mdb_vread(buf, msg.id_size,
9897836SJohn.Forte@Sun.COM 			    (uintptr_t)msg.id_buf) != msg.id_size) {
9907836SJohn.Forte@Sun.COM 				mdb_warn("failed to read buffer contents"
9917836SJohn.Forte@Sun.COM 				    " in kernel");
9927836SJohn.Forte@Sun.COM 				mdb_free(buf, msg.id_size + 1);
9937836SJohn.Forte@Sun.COM 				return (DCMD_ERR);
9947836SJohn.Forte@Sun.COM 			}
9957836SJohn.Forte@Sun.COM 
9967836SJohn.Forte@Sun.COM 			if (buf[0] == '\n') {
9977836SJohn.Forte@Sun.COM 				mdb_printf("There is a problem in"
9987836SJohn.Forte@Sun.COM 				    "the buffer\n");
9997836SJohn.Forte@Sun.COM 			}
10007836SJohn.Forte@Sun.COM 			/* funky packet processing stuff */
10017836SJohn.Forte@Sun.COM 			bcopy(buf, tmppkt, msg.id_size + 1);
10027836SJohn.Forte@Sun.COM 
10037836SJohn.Forte@Sun.COM 			/* find the equals sign, and put a null there */
10047836SJohn.Forte@Sun.COM 			tmpbuf = strchr(tmppkt, '=');
10057836SJohn.Forte@Sun.COM 			*tmpbuf = 0;
10067836SJohn.Forte@Sun.COM 			pktnum = (uint_t)mdb_strtoull(tmppkt);
10077836SJohn.Forte@Sun.COM 
10087836SJohn.Forte@Sun.COM 			if ((pktnum >= pktstart) && (pktnum <= pktend)) {
10097836SJohn.Forte@Sun.COM 				(void) mdb_snprintf(merge, sizeof (merge),
1010*8919SRenia.Miao@Sun.COM 				    "[%Y:%03d:%03d:%03d] %s",
1011*8919SRenia.Miao@Sun.COM 				    msg.id_time.tv_sec,
10127836SJohn.Forte@Sun.COM 				    (int)msg.id_time.tv_nsec/1000000,
10137836SJohn.Forte@Sun.COM 				    (int)(msg.id_time.tv_nsec/1000)%1000,
1014*8919SRenia.Miao@Sun.COM 				    (int)msg.id_time.tv_nsec%1000, buf);
10157836SJohn.Forte@Sun.COM 				mdb_printf("%s", merge);
10167836SJohn.Forte@Sun.COM 				if (printed != NULL)
10177836SJohn.Forte@Sun.COM 					(*printed) ++;
10187836SJohn.Forte@Sun.COM 			}
10197836SJohn.Forte@Sun.COM 			mdb_free(buf, msg.id_size + 1);
10207836SJohn.Forte@Sun.COM 			mdb_free(tmppkt, msg.id_size + 1);
10217836SJohn.Forte@Sun.COM 		}
10227836SJohn.Forte@Sun.COM 		addr = msg.id_next;
10237836SJohn.Forte@Sun.COM 	}
10247836SJohn.Forte@Sun.COM 
10257836SJohn.Forte@Sun.COM 	return (DCMD_OK);
10267836SJohn.Forte@Sun.COM }
10277836SJohn.Forte@Sun.COM 
10287836SJohn.Forte@Sun.COM int
fc_dump_old_logmsg(fc_trace_dmsgv1_t * addr,uint_t pktstart,uint_t pktend,uint_t * printed)10297836SJohn.Forte@Sun.COM fc_dump_old_logmsg(fc_trace_dmsgv1_t *addr, uint_t pktstart, uint_t pktend,
10307836SJohn.Forte@Sun.COM     uint_t *printed)
10317836SJohn.Forte@Sun.COM {
10327836SJohn.Forte@Sun.COM 	fc_trace_dmsgv1_t	msg;
10337836SJohn.Forte@Sun.COM 	caddr_t			buf;
10347836SJohn.Forte@Sun.COM 	char			merge[1024];
10357836SJohn.Forte@Sun.COM 	caddr_t			tmppkt;
10367836SJohn.Forte@Sun.COM 	char			*tmpbuf; /* for tokenising the buffer */
10377836SJohn.Forte@Sun.COM 	uint_t			pktnum = 0;
10387836SJohn.Forte@Sun.COM 
10397836SJohn.Forte@Sun.COM 	while (addr != NULL) {
10407836SJohn.Forte@Sun.COM 		if (mdb_vread(&msg, sizeof (msg), (uintptr_t)addr) !=
10417836SJohn.Forte@Sun.COM 		    sizeof (msg)) {
10427836SJohn.Forte@Sun.COM 			mdb_warn("failed to read message pointer in kernel");
10437836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
10447836SJohn.Forte@Sun.COM 		}
10457836SJohn.Forte@Sun.COM 
10467836SJohn.Forte@Sun.COM 		if (msg.id_size) {
10477836SJohn.Forte@Sun.COM 
10487836SJohn.Forte@Sun.COM 			buf = mdb_alloc(msg.id_size + 1, UM_SLEEP);
10497836SJohn.Forte@Sun.COM 			tmppkt = mdb_alloc(msg.id_size + 1, UM_SLEEP);
10507836SJohn.Forte@Sun.COM 
10517836SJohn.Forte@Sun.COM 			if (mdb_vread(buf, msg.id_size,
10527836SJohn.Forte@Sun.COM 			    (uintptr_t)msg.id_buf) != msg.id_size) {
10537836SJohn.Forte@Sun.COM 				mdb_warn("failed to read buffer contents"
10547836SJohn.Forte@Sun.COM 				    " in kernel");
10557836SJohn.Forte@Sun.COM 				mdb_free(buf, msg.id_size + 1);
10567836SJohn.Forte@Sun.COM 				return (DCMD_ERR);
10577836SJohn.Forte@Sun.COM 			}
10587836SJohn.Forte@Sun.COM 
10597836SJohn.Forte@Sun.COM 			if (buf[0] == '\n') {
10607836SJohn.Forte@Sun.COM 				mdb_printf("There is a problem in"
10617836SJohn.Forte@Sun.COM 				    "the buffer\n");
10627836SJohn.Forte@Sun.COM 			}
10637836SJohn.Forte@Sun.COM 			/* funky packet processing stuff */
10647836SJohn.Forte@Sun.COM 			bcopy(buf, tmppkt, msg.id_size + 1);
10657836SJohn.Forte@Sun.COM 
10667836SJohn.Forte@Sun.COM 			tmpbuf = strchr(tmppkt, '=');
10677836SJohn.Forte@Sun.COM 			*tmpbuf = 0;
10687836SJohn.Forte@Sun.COM 			pktnum = (uint_t)mdb_strtoull(tmppkt);
10697836SJohn.Forte@Sun.COM 
10707836SJohn.Forte@Sun.COM 			if ((pktnum >= pktstart) && (pktnum <= pktend)) {
10717836SJohn.Forte@Sun.COM 				(void) mdb_snprintf(merge, sizeof (merge),
1072*8919SRenia.Miao@Sun.COM 				    "[%Y] %s", msg.id_time, buf);
10737836SJohn.Forte@Sun.COM 				mdb_printf("%s", merge);
10747836SJohn.Forte@Sun.COM 				if (printed != NULL)
10757836SJohn.Forte@Sun.COM 					(*printed) ++;
10767836SJohn.Forte@Sun.COM 			}
10777836SJohn.Forte@Sun.COM 			mdb_free(buf, msg.id_size + 1);
10787836SJohn.Forte@Sun.COM 			mdb_free(tmppkt, msg.id_size + 1);
10797836SJohn.Forte@Sun.COM 		}
10807836SJohn.Forte@Sun.COM 		addr = msg.id_next;
10817836SJohn.Forte@Sun.COM 	}
10827836SJohn.Forte@Sun.COM 
10837836SJohn.Forte@Sun.COM 	return (DCMD_OK);
10847836SJohn.Forte@Sun.COM }
10857836SJohn.Forte@Sun.COM 
10867836SJohn.Forte@Sun.COM int
fc_trace_dump(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)10877836SJohn.Forte@Sun.COM fc_trace_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
10887836SJohn.Forte@Sun.COM {
10897836SJohn.Forte@Sun.COM 	fc_trace_logq_t logq;
10907836SJohn.Forte@Sun.COM 	uint_t		pktnum = 0;
10917836SJohn.Forte@Sun.COM 	uint_t		printed = 0; /* have we printed anything? */
10927836SJohn.Forte@Sun.COM 
10937836SJohn.Forte@Sun.COM 	uintptr_t	pktstart = 0;
10947836SJohn.Forte@Sun.COM 	uintptr_t	pktend = UINT_MAX;
10957836SJohn.Forte@Sun.COM 	int		rval = DCMD_OK;
10967836SJohn.Forte@Sun.COM 
10977836SJohn.Forte@Sun.COM 	if (mdb_vread(&logq, sizeof (logq), addr) != sizeof (logq)) {
10987836SJohn.Forte@Sun.COM 		mdb_warn("Failed to read log queue in kernel");
10997836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
11007836SJohn.Forte@Sun.COM 	}
11017836SJohn.Forte@Sun.COM 
11027836SJohn.Forte@Sun.COM 	if (mdb_getopts(argc, argv,
11037836SJohn.Forte@Sun.COM 	    's', MDB_OPT_UINTPTR, &pktstart,
11047836SJohn.Forte@Sun.COM 	    'e', MDB_OPT_UINTPTR, &pktend) != argc) {
11057836SJohn.Forte@Sun.COM 		return (DCMD_USAGE);
11067836SJohn.Forte@Sun.COM 	}
11077836SJohn.Forte@Sun.COM 
11087836SJohn.Forte@Sun.COM 	if (pktstart > pktend) {
11097836SJohn.Forte@Sun.COM 		return (DCMD_USAGE);
11107836SJohn.Forte@Sun.COM 	}
11117836SJohn.Forte@Sun.COM 
11127836SJohn.Forte@Sun.COM 	if (logq.il_flags & FC_TRACE_LOGQ_V2 != 0) {
11137836SJohn.Forte@Sun.COM 		rval = fc_dump_logmsg((fc_trace_dmsg_t *)logq.il_msgh, pktstart,
11147836SJohn.Forte@Sun.COM 		    pktend, &printed);
11157836SJohn.Forte@Sun.COM 	} else {
11167836SJohn.Forte@Sun.COM 		rval = fc_dump_old_logmsg((fc_trace_dmsgv1_t *)logq.il_msgh,
11177836SJohn.Forte@Sun.COM 		    pktstart, pktend, &printed);
11187836SJohn.Forte@Sun.COM 	}
11197836SJohn.Forte@Sun.COM 
11207836SJohn.Forte@Sun.COM 	if (rval != DCMD_OK) {
11217836SJohn.Forte@Sun.COM 		return (rval);
11227836SJohn.Forte@Sun.COM 	}
11237836SJohn.Forte@Sun.COM 
11247836SJohn.Forte@Sun.COM 	if (printed == 0) {
11257836SJohn.Forte@Sun.COM 		mdb_printf("No packets in the buffer match the"
11267836SJohn.Forte@Sun.COM 		    " criteria given");
11277836SJohn.Forte@Sun.COM 	}
11287836SJohn.Forte@Sun.COM 
11297836SJohn.Forte@Sun.COM 	return (rval);
11307836SJohn.Forte@Sun.COM }
11317836SJohn.Forte@Sun.COM 
11327836SJohn.Forte@Sun.COM int
fp_trace_dump(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)11337836SJohn.Forte@Sun.COM fp_trace_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
11347836SJohn.Forte@Sun.COM {
11357836SJohn.Forte@Sun.COM 	if (mdb_readvar(&addr, "fp_logq") == -1) {
11367836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fp_logq");
11377836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
11387836SJohn.Forte@Sun.COM 	}
11397836SJohn.Forte@Sun.COM 
11407836SJohn.Forte@Sun.COM 	if (DCMD_HDRSPEC(flags)) {
11417836SJohn.Forte@Sun.COM 		mdb_printf("fp trace buffer contents\n");
11427836SJohn.Forte@Sun.COM 	}
11437836SJohn.Forte@Sun.COM 
11447836SJohn.Forte@Sun.COM 	return (fc_trace_dump(addr, flags, argc, argv));
11457836SJohn.Forte@Sun.COM }
11467836SJohn.Forte@Sun.COM 
11477836SJohn.Forte@Sun.COM 
11487836SJohn.Forte@Sun.COM int
fcp_trace_dump(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)11497836SJohn.Forte@Sun.COM fcp_trace_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
11507836SJohn.Forte@Sun.COM {
11517836SJohn.Forte@Sun.COM 	if (mdb_readvar(&addr, "fcp_logq") == -1) {
11527836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fcp_logq");
11537836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
11547836SJohn.Forte@Sun.COM 	}
11557836SJohn.Forte@Sun.COM 
11567836SJohn.Forte@Sun.COM 	if (DCMD_HDRSPEC(flags)) {
11577836SJohn.Forte@Sun.COM 		mdb_printf("fcp trace buffer contents\n");
11587836SJohn.Forte@Sun.COM 	}
11597836SJohn.Forte@Sun.COM 
11607836SJohn.Forte@Sun.COM 	return (fc_trace_dump(addr, flags, argc, argv));
11617836SJohn.Forte@Sun.COM }
11627836SJohn.Forte@Sun.COM 
11637836SJohn.Forte@Sun.COM /*
11647836SJohn.Forte@Sun.COM  * Leadville job_request walker/dcmd code
11657836SJohn.Forte@Sun.COM  */
11667836SJohn.Forte@Sun.COM 
11677836SJohn.Forte@Sun.COM /*
11687836SJohn.Forte@Sun.COM  * We need to be given the address of a local port structure in order to start
11697836SJohn.Forte@Sun.COM  * walking.  From that, we can read the job_request list.
11707836SJohn.Forte@Sun.COM  */
11717836SJohn.Forte@Sun.COM 
11727836SJohn.Forte@Sun.COM static int
job_request_walk_i(mdb_walk_state_t * wsp)11737836SJohn.Forte@Sun.COM job_request_walk_i(mdb_walk_state_t *wsp)
11747836SJohn.Forte@Sun.COM {
11757836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
11767836SJohn.Forte@Sun.COM 		mdb_warn("The address of a fc_local_port"
11777836SJohn.Forte@Sun.COM 		    " structure must be given\n");
11787836SJohn.Forte@Sun.COM 		return (WALK_ERR);
11797836SJohn.Forte@Sun.COM 	}
11807836SJohn.Forte@Sun.COM 
11817836SJohn.Forte@Sun.COM 	/*
11827836SJohn.Forte@Sun.COM 	 * Input should be a fc_local_port_t, so read it to get the job_request
11837836SJohn.Forte@Sun.COM 	 * lists's head
11847836SJohn.Forte@Sun.COM 	 */
11857836SJohn.Forte@Sun.COM 
11867836SJohn.Forte@Sun.COM 	if (mdb_vread(&port, sizeof (fc_local_port_t), wsp->walk_addr) !=
11877836SJohn.Forte@Sun.COM 	    sizeof (fc_local_port_t)) {
11887836SJohn.Forte@Sun.COM 		mdb_warn("Failed to read in the fc_local_port"
11897836SJohn.Forte@Sun.COM 		    " at 0x%p\n", wsp->walk_addr);
11907836SJohn.Forte@Sun.COM 		return (WALK_ERR);
11917836SJohn.Forte@Sun.COM 	}
11927836SJohn.Forte@Sun.COM 
11937836SJohn.Forte@Sun.COM 	wsp->walk_addr = (uintptr_t)(port.fp_job_head);
11947836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (struct job_request), UM_SLEEP);
11957836SJohn.Forte@Sun.COM 
11967836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
11977836SJohn.Forte@Sun.COM }
11987836SJohn.Forte@Sun.COM 
11997836SJohn.Forte@Sun.COM static int
job_request_walk_s(mdb_walk_state_t * wsp)12007836SJohn.Forte@Sun.COM job_request_walk_s(mdb_walk_state_t *wsp)
12017836SJohn.Forte@Sun.COM {
12027836SJohn.Forte@Sun.COM 	int status;
12037836SJohn.Forte@Sun.COM 
12047836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL)
12057836SJohn.Forte@Sun.COM 		return (WALK_DONE);
12067836SJohn.Forte@Sun.COM 
12077836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (struct job_request),
12087836SJohn.Forte@Sun.COM 	    wsp->walk_addr) == -1) {
12097836SJohn.Forte@Sun.COM 		mdb_warn("Failed to read in the job_request at 0x%p\n",
12107836SJohn.Forte@Sun.COM 		    wsp->walk_addr);
12117836SJohn.Forte@Sun.COM 		return (WALK_DONE);
12127836SJohn.Forte@Sun.COM 	}
12137836SJohn.Forte@Sun.COM 
12147836SJohn.Forte@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
12157836SJohn.Forte@Sun.COM 	    wsp->walk_cbdata);
12167836SJohn.Forte@Sun.COM 
12177836SJohn.Forte@Sun.COM 	wsp->walk_addr =
12187836SJohn.Forte@Sun.COM 	    (uintptr_t)(((struct job_request *)wsp->walk_data)->job_next);
12197836SJohn.Forte@Sun.COM 
12207836SJohn.Forte@Sun.COM 	return (status);
12217836SJohn.Forte@Sun.COM }
12227836SJohn.Forte@Sun.COM 
12237836SJohn.Forte@Sun.COM /*
12247836SJohn.Forte@Sun.COM  * The walker's fini function is invoked at the end of each walk.
12257836SJohn.Forte@Sun.COM  */
12267836SJohn.Forte@Sun.COM static void
job_request_walk_f(mdb_walk_state_t * wsp)12277836SJohn.Forte@Sun.COM job_request_walk_f(mdb_walk_state_t *wsp)
12287836SJohn.Forte@Sun.COM {
12297836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (struct job_request));
12307836SJohn.Forte@Sun.COM }
12317836SJohn.Forte@Sun.COM 
12327836SJohn.Forte@Sun.COM 
12337836SJohn.Forte@Sun.COM /*
12347836SJohn.Forte@Sun.COM  * Leadville fc_orphan walker/dcmd code
12357836SJohn.Forte@Sun.COM  */
12367836SJohn.Forte@Sun.COM 
12377836SJohn.Forte@Sun.COM /*
12387836SJohn.Forte@Sun.COM  * We need to be given the address of a port structure in order to start
12397836SJohn.Forte@Sun.COM  * walking.  From that, we can read the orphan list.
12407836SJohn.Forte@Sun.COM  */
12417836SJohn.Forte@Sun.COM 
12427836SJohn.Forte@Sun.COM static int
orphan_walk_i(mdb_walk_state_t * wsp)12437836SJohn.Forte@Sun.COM orphan_walk_i(mdb_walk_state_t *wsp)
12447836SJohn.Forte@Sun.COM {
12457836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
12467836SJohn.Forte@Sun.COM 		mdb_warn("The address of a fc_local_port"
12477836SJohn.Forte@Sun.COM 		    " structure must be given\n");
12487836SJohn.Forte@Sun.COM 		return (WALK_ERR);
12497836SJohn.Forte@Sun.COM 	}
12507836SJohn.Forte@Sun.COM 
12517836SJohn.Forte@Sun.COM 	/*
12527836SJohn.Forte@Sun.COM 	 * Input should be a fc_local_port_t, so read it to get the orphan
12537836SJohn.Forte@Sun.COM 	 * lists's head
12547836SJohn.Forte@Sun.COM 	 */
12557836SJohn.Forte@Sun.COM 
12567836SJohn.Forte@Sun.COM 	if (mdb_vread(&port, sizeof (fc_local_port_t), wsp->walk_addr) !=
12577836SJohn.Forte@Sun.COM 	    sizeof (fc_local_port_t)) {
12587836SJohn.Forte@Sun.COM 		mdb_warn("Failed to read in the fc_local_port"
12597836SJohn.Forte@Sun.COM 		    " at 0x%p\n", wsp->walk_addr);
12607836SJohn.Forte@Sun.COM 		return (WALK_ERR);
12617836SJohn.Forte@Sun.COM 	}
12627836SJohn.Forte@Sun.COM 
12637836SJohn.Forte@Sun.COM 	wsp->walk_addr = (uintptr_t)(port.fp_orphan_list);
12647836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (struct fc_orphan), UM_SLEEP);
12657836SJohn.Forte@Sun.COM 
12667836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
12677836SJohn.Forte@Sun.COM }
12687836SJohn.Forte@Sun.COM 
12697836SJohn.Forte@Sun.COM static int
orphan_walk_s(mdb_walk_state_t * wsp)12707836SJohn.Forte@Sun.COM orphan_walk_s(mdb_walk_state_t *wsp)
12717836SJohn.Forte@Sun.COM {
12727836SJohn.Forte@Sun.COM 	int status;
12737836SJohn.Forte@Sun.COM 
12747836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL)
12757836SJohn.Forte@Sun.COM 		return (WALK_DONE);
12767836SJohn.Forte@Sun.COM 
12777836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (struct fc_orphan),
12787836SJohn.Forte@Sun.COM 	    wsp->walk_addr) == -1) {
12797836SJohn.Forte@Sun.COM 		mdb_warn("Failed to read in the fc_orphan at 0x%p\n",
12807836SJohn.Forte@Sun.COM 		    wsp->walk_addr);
12817836SJohn.Forte@Sun.COM 		return (WALK_DONE);
12827836SJohn.Forte@Sun.COM 	}
12837836SJohn.Forte@Sun.COM 
12847836SJohn.Forte@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
12857836SJohn.Forte@Sun.COM 	    wsp->walk_cbdata);
12867836SJohn.Forte@Sun.COM 
12877836SJohn.Forte@Sun.COM 	wsp->walk_addr =
12887836SJohn.Forte@Sun.COM 	    (uintptr_t)(((struct fc_orphan *)wsp->walk_data)->orp_next);
12897836SJohn.Forte@Sun.COM 
12907836SJohn.Forte@Sun.COM 	return (status);
12917836SJohn.Forte@Sun.COM }
12927836SJohn.Forte@Sun.COM 
12937836SJohn.Forte@Sun.COM /*
12947836SJohn.Forte@Sun.COM  * The walker's fini function is invoked at the end of each walk.
12957836SJohn.Forte@Sun.COM  */
12967836SJohn.Forte@Sun.COM static void
orphan_walk_f(mdb_walk_state_t * wsp)12977836SJohn.Forte@Sun.COM orphan_walk_f(mdb_walk_state_t *wsp)
12987836SJohn.Forte@Sun.COM {
12997836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (struct fc_orphan));
13007836SJohn.Forte@Sun.COM }
13017836SJohn.Forte@Sun.COM 
13027836SJohn.Forte@Sun.COM 
13037836SJohn.Forte@Sun.COM /*
13047836SJohn.Forte@Sun.COM  * MDB module linkage information:
13057836SJohn.Forte@Sun.COM  *
13067836SJohn.Forte@Sun.COM  * We declare a list of structures describing our dcmds, a list of structures
13077836SJohn.Forte@Sun.COM  * describing our walkers, and a function named _mdb_init to return a pointer
13087836SJohn.Forte@Sun.COM  * to our module information.
13097836SJohn.Forte@Sun.COM  */
13107836SJohn.Forte@Sun.COM 
13117836SJohn.Forte@Sun.COM static const mdb_dcmd_t dcmds[] = {
13127836SJohn.Forte@Sun.COM 	{ "ports", "[-l]", "Leadville port list", ports },
13137836SJohn.Forte@Sun.COM 	{ "ulps", NULL, "Leadville ULP list", ulps },
13147836SJohn.Forte@Sun.COM 	{ "ulpmods", NULL, "Leadville ULP module list", ulpmods },
13157836SJohn.Forte@Sun.COM 	{ "fcport", NULL, "Display a Leadville fc_local_port structure",
13167836SJohn.Forte@Sun.COM 	    fcport },
13177836SJohn.Forte@Sun.COM 	{ "remote_port", NULL, "Display fc_remote_port structures",
13187836SJohn.Forte@Sun.COM 	    remote_port },
13197836SJohn.Forte@Sun.COM 	{ "fcptrace", "[-s m][-e n] (m < n)", "Dump the fcp trace buffer, "
13207836SJohn.Forte@Sun.COM 	    "optionally supplying starting and ending packet numbers.",
13217836SJohn.Forte@Sun.COM 	    fcp_trace_dump, NULL },
13227836SJohn.Forte@Sun.COM 	{ "fptrace", "[-s m][-e n] (m < n)", "Dump the fp trace buffer, "
13237836SJohn.Forte@Sun.COM 	    "optionally supplying starting and ending packet numbers.",
13247836SJohn.Forte@Sun.COM 	    fp_trace_dump, NULL },
13257836SJohn.Forte@Sun.COM 	{ NULL }
13267836SJohn.Forte@Sun.COM };
13277836SJohn.Forte@Sun.COM 
13287836SJohn.Forte@Sun.COM static const mdb_walker_t walkers[] = {
13297836SJohn.Forte@Sun.COM 	{ "ports", "walk list of Leadville port structures",
13307836SJohn.Forte@Sun.COM 	    port_walk_i, port_walk_s, port_walk_f },
13317836SJohn.Forte@Sun.COM 	{ "ulps", "walk list of Leadville ULP structures",
13327836SJohn.Forte@Sun.COM 	    ulp_walk_i, ulp_walk_s, ulp_walk_f },
13337836SJohn.Forte@Sun.COM 	{ "ulpmods", "walk list of Leadville ULP module structures",
13347836SJohn.Forte@Sun.COM 	    ulpmod_walk_i, ulpmod_walk_s, ulpmod_walk_f },
13357836SJohn.Forte@Sun.COM 	{ "pd_by_pwwn", "walk list of fc_remote_port structures hashed by PWWN",
13367836SJohn.Forte@Sun.COM 	    pd_by_pwwn_walk_i, pd_by_pwwn_walk_s, pd_by_pwwn_walk_f },
13377836SJohn.Forte@Sun.COM 	{ "pd_by_did", "walk list of fc_remote_port structures hashed by D_ID",
13387836SJohn.Forte@Sun.COM 	    pd_by_did_walk_i, pd_by_did_walk_s, pd_by_did_walk_f },
13397836SJohn.Forte@Sun.COM 	{ "job_request", "walk list of job_request structures for a local port",
13407836SJohn.Forte@Sun.COM 	    job_request_walk_i, job_request_walk_s, job_request_walk_f },
13417836SJohn.Forte@Sun.COM 	{ "orphan", "walk list of orphan structures for a local port",
13427836SJohn.Forte@Sun.COM 	    orphan_walk_i, orphan_walk_s, orphan_walk_f },
13437836SJohn.Forte@Sun.COM 	{ NULL }
13447836SJohn.Forte@Sun.COM };
13457836SJohn.Forte@Sun.COM 
13467836SJohn.Forte@Sun.COM static const mdb_modinfo_t modinfo = {
13477836SJohn.Forte@Sun.COM 	MDB_API_VERSION, dcmds, walkers
13487836SJohn.Forte@Sun.COM };
13497836SJohn.Forte@Sun.COM 
13507836SJohn.Forte@Sun.COM const mdb_modinfo_t *
_mdb_init(void)13517836SJohn.Forte@Sun.COM _mdb_init(void)
13527836SJohn.Forte@Sun.COM {
13537836SJohn.Forte@Sun.COM 	return (&modinfo);
13547836SJohn.Forte@Sun.COM }
1355