xref: /onnv-gate/usr/src/cmd/mdb/common/modules/fctl/fctl.c (revision 7836:4e95154b5b7a)
1*7836SJohn.Forte@Sun.COM /*
2*7836SJohn.Forte@Sun.COM  * CDDL HEADER START
3*7836SJohn.Forte@Sun.COM  *
4*7836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
5*7836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
6*7836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
7*7836SJohn.Forte@Sun.COM  *
8*7836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*7836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
11*7836SJohn.Forte@Sun.COM  * and limitations under the License.
12*7836SJohn.Forte@Sun.COM  *
13*7836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*7836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*7836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*7836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7836SJohn.Forte@Sun.COM  *
19*7836SJohn.Forte@Sun.COM  * CDDL HEADER END
20*7836SJohn.Forte@Sun.COM  */
21*7836SJohn.Forte@Sun.COM /*
22*7836SJohn.Forte@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*7836SJohn.Forte@Sun.COM  * Use is subject to license terms.
24*7836SJohn.Forte@Sun.COM  */
25*7836SJohn.Forte@Sun.COM 
26*7836SJohn.Forte@Sun.COM 
27*7836SJohn.Forte@Sun.COM #include <sys/mdb_modapi.h>
28*7836SJohn.Forte@Sun.COM #include <sys/mutex.h>
29*7836SJohn.Forte@Sun.COM #include <sys/modctl.h>
30*7836SJohn.Forte@Sun.COM #include <time.h>
31*7836SJohn.Forte@Sun.COM #include <sys/fibre-channel/fc.h>
32*7836SJohn.Forte@Sun.COM #include <sys/fibre-channel/impl/fctl_private.h>
33*7836SJohn.Forte@Sun.COM #include <sys/fibre-channel/impl/fc_ulpif.h>
34*7836SJohn.Forte@Sun.COM #include <sys/fibre-channel/impl/fc_portif.h>
35*7836SJohn.Forte@Sun.COM #include <sys/fibre-channel/impl/fc_fcaif.h>
36*7836SJohn.Forte@Sun.COM 
37*7836SJohn.Forte@Sun.COM 
38*7836SJohn.Forte@Sun.COM /*
39*7836SJohn.Forte@Sun.COM  * If we #include <string.h> then other definitions fail. This is
40*7836SJohn.Forte@Sun.COM  * the easiest way of getting access to the function
41*7836SJohn.Forte@Sun.COM  */
42*7836SJohn.Forte@Sun.COM extern char *strtok(char *string, const char *sepset);
43*7836SJohn.Forte@Sun.COM 
44*7836SJohn.Forte@Sun.COM /* we need 26 bytes for the cftime() call */
45*7836SJohn.Forte@Sun.COM #define	TIMESTAMPSIZE	26 * sizeof (char)
46*7836SJohn.Forte@Sun.COM 
47*7836SJohn.Forte@Sun.COM /* for backward compatibility */
48*7836SJohn.Forte@Sun.COM typedef struct fc_trace_dmsgv1 {
49*7836SJohn.Forte@Sun.COM 	int			id_size;
50*7836SJohn.Forte@Sun.COM 	int			id_flag;
51*7836SJohn.Forte@Sun.COM 	time_t			id_time;
52*7836SJohn.Forte@Sun.COM 	caddr_t			id_buf;
53*7836SJohn.Forte@Sun.COM 	struct fc_trace_dmsgv1	*id_next;
54*7836SJohn.Forte@Sun.COM } fc_trace_dmsgv1_t;
55*7836SJohn.Forte@Sun.COM 
56*7836SJohn.Forte@Sun.COM static struct pwwn_hash *fp_pwwn_table;
57*7836SJohn.Forte@Sun.COM static struct d_id_hash *fp_did_table;
58*7836SJohn.Forte@Sun.COM static uint32_t pd_hash_index;
59*7836SJohn.Forte@Sun.COM struct fc_local_port port;
60*7836SJohn.Forte@Sun.COM 
61*7836SJohn.Forte@Sun.COM /*
62*7836SJohn.Forte@Sun.COM  * Leadville port walker/dcmd code
63*7836SJohn.Forte@Sun.COM  */
64*7836SJohn.Forte@Sun.COM 
65*7836SJohn.Forte@Sun.COM /*
66*7836SJohn.Forte@Sun.COM  * Initialize the fc_fca_port_t walker by either using the given starting
67*7836SJohn.Forte@Sun.COM  * address, or reading the value of the kernel's fctl_fca_portlist pointer.
68*7836SJohn.Forte@Sun.COM  * We also allocate a fc_fca_port_t for storage, and save this using the
69*7836SJohn.Forte@Sun.COM  * walk_data pointer.
70*7836SJohn.Forte@Sun.COM  */
71*7836SJohn.Forte@Sun.COM static int
72*7836SJohn.Forte@Sun.COM port_walk_i(mdb_walk_state_t *wsp)
73*7836SJohn.Forte@Sun.COM {
74*7836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL &&
75*7836SJohn.Forte@Sun.COM 	    mdb_readvar(&wsp->walk_addr, "fctl_fca_portlist") == -1) {
76*7836SJohn.Forte@Sun.COM 		mdb_warn("failed to read 'fctl_fca_portlist'");
77*7836SJohn.Forte@Sun.COM 		return (WALK_ERR);
78*7836SJohn.Forte@Sun.COM 	}
79*7836SJohn.Forte@Sun.COM 
80*7836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (fc_fca_port_t), UM_SLEEP);
81*7836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
82*7836SJohn.Forte@Sun.COM }
83*7836SJohn.Forte@Sun.COM 
84*7836SJohn.Forte@Sun.COM /*
85*7836SJohn.Forte@Sun.COM  * At each step, read a fc_fca_port_t into our private storage, and then invoke
86*7836SJohn.Forte@Sun.COM  * the callback function.  We terminate when we reach a NULL p_next pointer.
87*7836SJohn.Forte@Sun.COM  */
88*7836SJohn.Forte@Sun.COM static int
89*7836SJohn.Forte@Sun.COM port_walk_s(mdb_walk_state_t *wsp)
90*7836SJohn.Forte@Sun.COM {
91*7836SJohn.Forte@Sun.COM 	int status;
92*7836SJohn.Forte@Sun.COM 
93*7836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL)
94*7836SJohn.Forte@Sun.COM 		return (WALK_DONE);
95*7836SJohn.Forte@Sun.COM 
96*7836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (fc_fca_port_t), wsp->walk_addr)
97*7836SJohn.Forte@Sun.COM 	    == -1) {
98*7836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fc_fca_port_t at %p", wsp->walk_addr);
99*7836SJohn.Forte@Sun.COM 		return (WALK_DONE);
100*7836SJohn.Forte@Sun.COM 	}
101*7836SJohn.Forte@Sun.COM 
102*7836SJohn.Forte@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
103*7836SJohn.Forte@Sun.COM 	    wsp->walk_cbdata);
104*7836SJohn.Forte@Sun.COM 
105*7836SJohn.Forte@Sun.COM 	wsp->walk_addr =
106*7836SJohn.Forte@Sun.COM 	    (uintptr_t)(((fc_fca_port_t *)wsp->walk_data)->port_next);
107*7836SJohn.Forte@Sun.COM 
108*7836SJohn.Forte@Sun.COM 	return (status);
109*7836SJohn.Forte@Sun.COM }
110*7836SJohn.Forte@Sun.COM 
111*7836SJohn.Forte@Sun.COM /*
112*7836SJohn.Forte@Sun.COM  * The walker's fini function is invoked at the end of each walk.  Since we
113*7836SJohn.Forte@Sun.COM  * dynamically allocated a fc_fca_port_t in port_walk_i, we must free it now.
114*7836SJohn.Forte@Sun.COM  */
115*7836SJohn.Forte@Sun.COM static void
116*7836SJohn.Forte@Sun.COM port_walk_f(mdb_walk_state_t *wsp)
117*7836SJohn.Forte@Sun.COM {
118*7836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (fc_fca_port_t));
119*7836SJohn.Forte@Sun.COM }
120*7836SJohn.Forte@Sun.COM 
121*7836SJohn.Forte@Sun.COM 
122*7836SJohn.Forte@Sun.COM static int
123*7836SJohn.Forte@Sun.COM ports(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
124*7836SJohn.Forte@Sun.COM {
125*7836SJohn.Forte@Sun.COM 	fc_fca_port_t	portlist;
126*7836SJohn.Forte@Sun.COM 	fc_local_port_t port;
127*7836SJohn.Forte@Sun.COM 	int		longlist = FALSE;
128*7836SJohn.Forte@Sun.COM 
129*7836SJohn.Forte@Sun.COM 	if (argc > 1) {
130*7836SJohn.Forte@Sun.COM 		return (DCMD_USAGE);
131*7836SJohn.Forte@Sun.COM 	}
132*7836SJohn.Forte@Sun.COM 
133*7836SJohn.Forte@Sun.COM 	if (mdb_getopts(argc, argv,
134*7836SJohn.Forte@Sun.COM 	    'l', MDB_OPT_SETBITS, TRUE, &longlist) != argc) {
135*7836SJohn.Forte@Sun.COM 		return (DCMD_USAGE);
136*7836SJohn.Forte@Sun.COM 	}
137*7836SJohn.Forte@Sun.COM 
138*7836SJohn.Forte@Sun.COM 
139*7836SJohn.Forte@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
140*7836SJohn.Forte@Sun.COM 		if (longlist == 0) {
141*7836SJohn.Forte@Sun.COM 			if (mdb_walk_dcmd("ports", "ports",
142*7836SJohn.Forte@Sun.COM 			    argc, argv) == -1) {
143*7836SJohn.Forte@Sun.COM 				mdb_warn("failed to walk 'fctl_fca_portlist'");
144*7836SJohn.Forte@Sun.COM 				return (DCMD_ERR);
145*7836SJohn.Forte@Sun.COM 			}
146*7836SJohn.Forte@Sun.COM 		} else {
147*7836SJohn.Forte@Sun.COM 			if (mdb_walk_dcmd("ports", "fcport",
148*7836SJohn.Forte@Sun.COM 			    argc, argv) == -1) {
149*7836SJohn.Forte@Sun.COM 				mdb_warn("failed to walk 'fctl_fca_portlist'");
150*7836SJohn.Forte@Sun.COM 				return (DCMD_ERR);
151*7836SJohn.Forte@Sun.COM 			}
152*7836SJohn.Forte@Sun.COM 		}
153*7836SJohn.Forte@Sun.COM 
154*7836SJohn.Forte@Sun.COM 		return (DCMD_OK);
155*7836SJohn.Forte@Sun.COM 	}
156*7836SJohn.Forte@Sun.COM 
157*7836SJohn.Forte@Sun.COM 	/*
158*7836SJohn.Forte@Sun.COM 	 * If this is the first invocation of the command, print a nice
159*7836SJohn.Forte@Sun.COM 	 * header line for the output that will follow.
160*7836SJohn.Forte@Sun.COM 	 */
161*7836SJohn.Forte@Sun.COM 	if (DCMD_HDRSPEC(flags))
162*7836SJohn.Forte@Sun.COM 		mdb_printf("%16s %-2s %4s %-4s%16s %16s %16s\n",
163*7836SJohn.Forte@Sun.COM 		    "Port", "I#", "State", "Soft", "FCA Handle",
164*7836SJohn.Forte@Sun.COM 		    "Port DIP", "FCA Port DIP");
165*7836SJohn.Forte@Sun.COM 
166*7836SJohn.Forte@Sun.COM 	/*
167*7836SJohn.Forte@Sun.COM 	 * For each port, we just need to read the fc_fca_port_t struct, read
168*7836SJohn.Forte@Sun.COM 	 * the port_handle
169*7836SJohn.Forte@Sun.COM 	 */
170*7836SJohn.Forte@Sun.COM 	if (mdb_vread(&portlist, sizeof (fc_fca_port_t), addr) ==
171*7836SJohn.Forte@Sun.COM 	    sizeof (fc_fca_port_t)) {
172*7836SJohn.Forte@Sun.COM 		/*
173*7836SJohn.Forte@Sun.COM 		 * Now read that port in
174*7836SJohn.Forte@Sun.COM 		 */
175*7836SJohn.Forte@Sun.COM 
176*7836SJohn.Forte@Sun.COM 		if (mdb_vread(&port, sizeof (fc_local_port_t), (uintptr_t)
177*7836SJohn.Forte@Sun.COM 		    portlist.port_handle) == sizeof (fc_local_port_t)) {
178*7836SJohn.Forte@Sun.COM 			mdb_printf("%16p %2d %4x %4x %16p %16p %16p\n",
179*7836SJohn.Forte@Sun.COM 			    portlist.port_handle, port.fp_instance,
180*7836SJohn.Forte@Sun.COM 			    port.fp_state, port.fp_soft_state,
181*7836SJohn.Forte@Sun.COM 			    port.fp_fca_handle, port.fp_port_dip,
182*7836SJohn.Forte@Sun.COM 			    port.fp_fca_dip);
183*7836SJohn.Forte@Sun.COM 		} else
184*7836SJohn.Forte@Sun.COM 			mdb_warn("failed to read port at %p",
185*7836SJohn.Forte@Sun.COM 			    portlist.port_handle);
186*7836SJohn.Forte@Sun.COM 
187*7836SJohn.Forte@Sun.COM 	} else
188*7836SJohn.Forte@Sun.COM 		mdb_warn("failed to read port info at %p", addr);
189*7836SJohn.Forte@Sun.COM 
190*7836SJohn.Forte@Sun.COM 	return (DCMD_OK);
191*7836SJohn.Forte@Sun.COM }
192*7836SJohn.Forte@Sun.COM 
193*7836SJohn.Forte@Sun.COM 
194*7836SJohn.Forte@Sun.COM /*
195*7836SJohn.Forte@Sun.COM  * Leadville ULP walker/dcmd code
196*7836SJohn.Forte@Sun.COM  */
197*7836SJohn.Forte@Sun.COM 
198*7836SJohn.Forte@Sun.COM static int
199*7836SJohn.Forte@Sun.COM ulp_walk_i(mdb_walk_state_t *wsp)
200*7836SJohn.Forte@Sun.COM {
201*7836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL &&
202*7836SJohn.Forte@Sun.COM 	    mdb_readvar(&wsp->walk_addr, "fctl_ulp_list") == -1) {
203*7836SJohn.Forte@Sun.COM 		mdb_warn("failed to read 'fctl_ulp_list'");
204*7836SJohn.Forte@Sun.COM 		return (WALK_ERR);
205*7836SJohn.Forte@Sun.COM 	}
206*7836SJohn.Forte@Sun.COM 
207*7836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (fc_ulp_list_t), UM_SLEEP);
208*7836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
209*7836SJohn.Forte@Sun.COM }
210*7836SJohn.Forte@Sun.COM 
211*7836SJohn.Forte@Sun.COM 
212*7836SJohn.Forte@Sun.COM 
213*7836SJohn.Forte@Sun.COM static int
214*7836SJohn.Forte@Sun.COM ulp_walk_s(mdb_walk_state_t *wsp)
215*7836SJohn.Forte@Sun.COM {
216*7836SJohn.Forte@Sun.COM 	int status;
217*7836SJohn.Forte@Sun.COM 
218*7836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL)
219*7836SJohn.Forte@Sun.COM 		return (WALK_DONE);
220*7836SJohn.Forte@Sun.COM 
221*7836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (fc_ulp_list_t), wsp->walk_addr)
222*7836SJohn.Forte@Sun.COM 	    == -1) {
223*7836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fctl_ulp_list %p", wsp->walk_addr);
224*7836SJohn.Forte@Sun.COM 		return (WALK_DONE);
225*7836SJohn.Forte@Sun.COM 	}
226*7836SJohn.Forte@Sun.COM 
227*7836SJohn.Forte@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
228*7836SJohn.Forte@Sun.COM 	    wsp->walk_cbdata);
229*7836SJohn.Forte@Sun.COM 
230*7836SJohn.Forte@Sun.COM 	wsp->walk_addr =
231*7836SJohn.Forte@Sun.COM 	    (uintptr_t)(((fc_ulp_list_t *)wsp->walk_data)->ulp_next);
232*7836SJohn.Forte@Sun.COM 
233*7836SJohn.Forte@Sun.COM 	return (status);
234*7836SJohn.Forte@Sun.COM }
235*7836SJohn.Forte@Sun.COM 
236*7836SJohn.Forte@Sun.COM 
237*7836SJohn.Forte@Sun.COM static void
238*7836SJohn.Forte@Sun.COM ulp_walk_f(mdb_walk_state_t *wsp)
239*7836SJohn.Forte@Sun.COM {
240*7836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (fc_ulp_list_t));
241*7836SJohn.Forte@Sun.COM }
242*7836SJohn.Forte@Sun.COM 
243*7836SJohn.Forte@Sun.COM 
244*7836SJohn.Forte@Sun.COM static int
245*7836SJohn.Forte@Sun.COM ulps(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
246*7836SJohn.Forte@Sun.COM {
247*7836SJohn.Forte@Sun.COM 	fc_ulp_list_t 		ulplist;
248*7836SJohn.Forte@Sun.COM 	fc_ulp_modinfo_t	ulp;
249*7836SJohn.Forte@Sun.COM 	char			ulp_name[30];
250*7836SJohn.Forte@Sun.COM 
251*7836SJohn.Forte@Sun.COM 	if (argc != 0) {
252*7836SJohn.Forte@Sun.COM 		return (DCMD_USAGE);
253*7836SJohn.Forte@Sun.COM 	}
254*7836SJohn.Forte@Sun.COM 
255*7836SJohn.Forte@Sun.COM 	/*
256*7836SJohn.Forte@Sun.COM 	 * If no fc_ulp_list_t address was specified on the command line, we can
257*7836SJohn.Forte@Sun.COM 	 * print out all processes by invoking the walker, using this
258*7836SJohn.Forte@Sun.COM 	 * dcmd itself as the callback.
259*7836SJohn.Forte@Sun.COM 	 */
260*7836SJohn.Forte@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
261*7836SJohn.Forte@Sun.COM 		if (mdb_walk_dcmd("ulps", "ulps", argc, argv) == -1) {
262*7836SJohn.Forte@Sun.COM 			mdb_warn("failed to walk 'fc_ulp_list_t'");
263*7836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
264*7836SJohn.Forte@Sun.COM 		}
265*7836SJohn.Forte@Sun.COM 		return (DCMD_OK);
266*7836SJohn.Forte@Sun.COM 	}
267*7836SJohn.Forte@Sun.COM 
268*7836SJohn.Forte@Sun.COM 	/*
269*7836SJohn.Forte@Sun.COM 	 * If this is the first invocation of the command, print a nice
270*7836SJohn.Forte@Sun.COM 	 * header line for the output that will follow.
271*7836SJohn.Forte@Sun.COM 	 */
272*7836SJohn.Forte@Sun.COM 	if (DCMD_HDRSPEC(flags))
273*7836SJohn.Forte@Sun.COM 		mdb_printf("%30s %4s %8s\n", "ULP Name", "Type", "Revision");
274*7836SJohn.Forte@Sun.COM 
275*7836SJohn.Forte@Sun.COM 	/*
276*7836SJohn.Forte@Sun.COM 	 * For each port, we just need to read the fc_fca_port_t struct, read
277*7836SJohn.Forte@Sun.COM 	 * the port_handle
278*7836SJohn.Forte@Sun.COM 	 */
279*7836SJohn.Forte@Sun.COM 	if (mdb_vread(&ulplist, sizeof (fc_ulp_list_t), addr) ==
280*7836SJohn.Forte@Sun.COM 	    sizeof (fc_ulp_list_t)) {
281*7836SJohn.Forte@Sun.COM 		/*
282*7836SJohn.Forte@Sun.COM 		 * Now read that port in
283*7836SJohn.Forte@Sun.COM 		 */
284*7836SJohn.Forte@Sun.COM 
285*7836SJohn.Forte@Sun.COM 		if (mdb_vread(&ulp, sizeof (fc_ulp_modinfo_t),
286*7836SJohn.Forte@Sun.COM 		    (uintptr_t)ulplist.ulp_info) == sizeof (fc_ulp_modinfo_t)) {
287*7836SJohn.Forte@Sun.COM 			if (mdb_vread(&ulp_name, 30,
288*7836SJohn.Forte@Sun.COM 			    (uintptr_t)ulp.ulp_name) > 0) {
289*7836SJohn.Forte@Sun.COM 				mdb_printf("%30s %4x %8x\n",
290*7836SJohn.Forte@Sun.COM 				    ulp_name, ulp.ulp_type, ulp.ulp_rev);
291*7836SJohn.Forte@Sun.COM 			}
292*7836SJohn.Forte@Sun.COM 		} else
293*7836SJohn.Forte@Sun.COM 			mdb_warn("failed to read ulp at %p",
294*7836SJohn.Forte@Sun.COM 			    ulplist.ulp_info);
295*7836SJohn.Forte@Sun.COM 
296*7836SJohn.Forte@Sun.COM 	} else
297*7836SJohn.Forte@Sun.COM 		mdb_warn("failed to read ulplist at %p", addr);
298*7836SJohn.Forte@Sun.COM 
299*7836SJohn.Forte@Sun.COM 	return (DCMD_OK);
300*7836SJohn.Forte@Sun.COM }
301*7836SJohn.Forte@Sun.COM 
302*7836SJohn.Forte@Sun.COM 
303*7836SJohn.Forte@Sun.COM 
304*7836SJohn.Forte@Sun.COM /*
305*7836SJohn.Forte@Sun.COM  * Leadville ULP module walker/dcmd code
306*7836SJohn.Forte@Sun.COM  */
307*7836SJohn.Forte@Sun.COM 
308*7836SJohn.Forte@Sun.COM static int
309*7836SJohn.Forte@Sun.COM ulpmod_walk_i(mdb_walk_state_t *wsp)
310*7836SJohn.Forte@Sun.COM {
311*7836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL &&
312*7836SJohn.Forte@Sun.COM 	    mdb_readvar(&wsp->walk_addr, "fctl_ulp_modules") == -1) {
313*7836SJohn.Forte@Sun.COM 		mdb_warn("failed to read 'fctl_ulp_modules'");
314*7836SJohn.Forte@Sun.COM 		return (WALK_ERR);
315*7836SJohn.Forte@Sun.COM 	}
316*7836SJohn.Forte@Sun.COM 
317*7836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (fc_ulp_module_t), UM_SLEEP);
318*7836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
319*7836SJohn.Forte@Sun.COM }
320*7836SJohn.Forte@Sun.COM 
321*7836SJohn.Forte@Sun.COM 
322*7836SJohn.Forte@Sun.COM 
323*7836SJohn.Forte@Sun.COM static int
324*7836SJohn.Forte@Sun.COM ulpmod_walk_s(mdb_walk_state_t *wsp)
325*7836SJohn.Forte@Sun.COM {
326*7836SJohn.Forte@Sun.COM 	int status;
327*7836SJohn.Forte@Sun.COM 
328*7836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL)
329*7836SJohn.Forte@Sun.COM 		return (WALK_DONE);
330*7836SJohn.Forte@Sun.COM 
331*7836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (fc_ulp_module_t), wsp->walk_addr)
332*7836SJohn.Forte@Sun.COM 	    == -1) {
333*7836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fctl_ulp_modules %p", wsp->walk_addr);
334*7836SJohn.Forte@Sun.COM 		return (WALK_DONE);
335*7836SJohn.Forte@Sun.COM 	}
336*7836SJohn.Forte@Sun.COM 
337*7836SJohn.Forte@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
338*7836SJohn.Forte@Sun.COM 	    wsp->walk_cbdata);
339*7836SJohn.Forte@Sun.COM 
340*7836SJohn.Forte@Sun.COM 	wsp->walk_addr =
341*7836SJohn.Forte@Sun.COM 	    (uintptr_t)(((fc_ulp_module_t *)wsp->walk_data)->mod_next);
342*7836SJohn.Forte@Sun.COM 
343*7836SJohn.Forte@Sun.COM 	return (status);
344*7836SJohn.Forte@Sun.COM }
345*7836SJohn.Forte@Sun.COM 
346*7836SJohn.Forte@Sun.COM 
347*7836SJohn.Forte@Sun.COM static void
348*7836SJohn.Forte@Sun.COM ulpmod_walk_f(mdb_walk_state_t *wsp)
349*7836SJohn.Forte@Sun.COM {
350*7836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (fc_ulp_module_t));
351*7836SJohn.Forte@Sun.COM }
352*7836SJohn.Forte@Sun.COM 
353*7836SJohn.Forte@Sun.COM 
354*7836SJohn.Forte@Sun.COM static int
355*7836SJohn.Forte@Sun.COM ulpmods(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
356*7836SJohn.Forte@Sun.COM {
357*7836SJohn.Forte@Sun.COM 	fc_ulp_module_t 	modlist;
358*7836SJohn.Forte@Sun.COM 	fc_ulp_modinfo_t	modinfo;
359*7836SJohn.Forte@Sun.COM 	fc_ulp_ports_t		ulp_port;
360*7836SJohn.Forte@Sun.COM 
361*7836SJohn.Forte@Sun.COM 	if (argc != 0) {
362*7836SJohn.Forte@Sun.COM 		return (DCMD_USAGE);
363*7836SJohn.Forte@Sun.COM 	}
364*7836SJohn.Forte@Sun.COM 
365*7836SJohn.Forte@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
366*7836SJohn.Forte@Sun.COM 		if (mdb_walk_dcmd("ulpmods", "ulpmods", argc, argv)
367*7836SJohn.Forte@Sun.COM 		    == -1) {
368*7836SJohn.Forte@Sun.COM 			mdb_warn("failed to walk 'fc_ulp_module_t'");
369*7836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
370*7836SJohn.Forte@Sun.COM 		}
371*7836SJohn.Forte@Sun.COM 		return (DCMD_OK);
372*7836SJohn.Forte@Sun.COM 	}
373*7836SJohn.Forte@Sun.COM 
374*7836SJohn.Forte@Sun.COM 	/*
375*7836SJohn.Forte@Sun.COM 	 * If this is the first invocation of the command, print a nice
376*7836SJohn.Forte@Sun.COM 	 * header line for the output that will follow.
377*7836SJohn.Forte@Sun.COM 	 */
378*7836SJohn.Forte@Sun.COM 	if (DCMD_HDRSPEC(flags))
379*7836SJohn.Forte@Sun.COM 		mdb_printf("%4s %16s %8s %8s\n",
380*7836SJohn.Forte@Sun.COM 		    "Type", "Port Handle", "dstate", "statec");
381*7836SJohn.Forte@Sun.COM 
382*7836SJohn.Forte@Sun.COM 	/*
383*7836SJohn.Forte@Sun.COM 	 * For each port, we just need to read the fc_fca_port_t struct, read
384*7836SJohn.Forte@Sun.COM 	 * the port_handle
385*7836SJohn.Forte@Sun.COM 	 */
386*7836SJohn.Forte@Sun.COM 	if (mdb_vread(&modlist, sizeof (fc_ulp_module_t), addr) ==
387*7836SJohn.Forte@Sun.COM 	    sizeof (fc_ulp_module_t)) {
388*7836SJohn.Forte@Sun.COM 		/*
389*7836SJohn.Forte@Sun.COM 		 * Now read that module info in
390*7836SJohn.Forte@Sun.COM 		 */
391*7836SJohn.Forte@Sun.COM 
392*7836SJohn.Forte@Sun.COM 		if (mdb_vread(&modinfo, sizeof (fc_ulp_modinfo_t),
393*7836SJohn.Forte@Sun.COM 		    (uintptr_t)modlist.mod_info) == sizeof (fc_ulp_modinfo_t)) {
394*7836SJohn.Forte@Sun.COM 			/* Now read all the ports for this module */
395*7836SJohn.Forte@Sun.COM 			if (mdb_vread(&ulp_port, sizeof (fc_ulp_ports_t),
396*7836SJohn.Forte@Sun.COM 			    (uintptr_t)modlist.mod_ports) ==
397*7836SJohn.Forte@Sun.COM 			    sizeof (fc_ulp_ports_t)) {
398*7836SJohn.Forte@Sun.COM 				while (ulp_port.port_handle != NULL) {
399*7836SJohn.Forte@Sun.COM 					mdb_printf("%4x %16p %8x %8x\n",
400*7836SJohn.Forte@Sun.COM 					    modinfo.ulp_type,
401*7836SJohn.Forte@Sun.COM 					    ulp_port.port_handle,
402*7836SJohn.Forte@Sun.COM 					    ulp_port.port_dstate,
403*7836SJohn.Forte@Sun.COM 					    ulp_port.port_statec);
404*7836SJohn.Forte@Sun.COM 
405*7836SJohn.Forte@Sun.COM 					if (ulp_port.port_next == NULL)
406*7836SJohn.Forte@Sun.COM 						break;
407*7836SJohn.Forte@Sun.COM 
408*7836SJohn.Forte@Sun.COM 					mdb_vread(&ulp_port,
409*7836SJohn.Forte@Sun.COM 					    sizeof (fc_ulp_ports_t),
410*7836SJohn.Forte@Sun.COM 					    (uintptr_t)ulp_port.port_next);
411*7836SJohn.Forte@Sun.COM 				}
412*7836SJohn.Forte@Sun.COM 			}
413*7836SJohn.Forte@Sun.COM 		} else
414*7836SJohn.Forte@Sun.COM 			mdb_warn("failed to read modinfo at %p",
415*7836SJohn.Forte@Sun.COM 			    modlist.mod_info);
416*7836SJohn.Forte@Sun.COM 
417*7836SJohn.Forte@Sun.COM 	} else
418*7836SJohn.Forte@Sun.COM 		mdb_warn("failed to read modlist at %p", addr);
419*7836SJohn.Forte@Sun.COM 
420*7836SJohn.Forte@Sun.COM 	return (DCMD_OK);
421*7836SJohn.Forte@Sun.COM }
422*7836SJohn.Forte@Sun.COM 
423*7836SJohn.Forte@Sun.COM 
424*7836SJohn.Forte@Sun.COM /*
425*7836SJohn.Forte@Sun.COM  * Display an fc_local_port_t struct
426*7836SJohn.Forte@Sun.COM  */
427*7836SJohn.Forte@Sun.COM static int
428*7836SJohn.Forte@Sun.COM fcport(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
429*7836SJohn.Forte@Sun.COM {
430*7836SJohn.Forte@Sun.COM 	fc_fca_port_t	portlist;
431*7836SJohn.Forte@Sun.COM 	fc_local_port_t	port;
432*7836SJohn.Forte@Sun.COM 	int		idx;
433*7836SJohn.Forte@Sun.COM 	int		first = 1;
434*7836SJohn.Forte@Sun.COM 	int		walking_fc_fca_portlist = 0;
435*7836SJohn.Forte@Sun.COM 
436*7836SJohn.Forte@Sun.COM 	if (argc != 0) {
437*7836SJohn.Forte@Sun.COM 		int result;
438*7836SJohn.Forte@Sun.COM 
439*7836SJohn.Forte@Sun.COM 		if (argc != 1)
440*7836SJohn.Forte@Sun.COM 			return (DCMD_USAGE);
441*7836SJohn.Forte@Sun.COM 
442*7836SJohn.Forte@Sun.COM 		if (argv->a_type != MDB_TYPE_STRING)
443*7836SJohn.Forte@Sun.COM 			return (DCMD_USAGE);
444*7836SJohn.Forte@Sun.COM 
445*7836SJohn.Forte@Sun.COM 		walking_fc_fca_portlist = 1;
446*7836SJohn.Forte@Sun.COM 	}
447*7836SJohn.Forte@Sun.COM 
448*7836SJohn.Forte@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
449*7836SJohn.Forte@Sun.COM 		mdb_printf("Sorry, you must provide an address\n");
450*7836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
451*7836SJohn.Forte@Sun.COM 	}
452*7836SJohn.Forte@Sun.COM 
453*7836SJohn.Forte@Sun.COM 	if (walking_fc_fca_portlist) {
454*7836SJohn.Forte@Sun.COM 		/*
455*7836SJohn.Forte@Sun.COM 		 * Must read the fc_fca_portlist to get the fc_local_port addr
456*7836SJohn.Forte@Sun.COM 		 */
457*7836SJohn.Forte@Sun.COM 		if (mdb_vread(&portlist, sizeof (fc_fca_port_t), addr) ==
458*7836SJohn.Forte@Sun.COM 		    sizeof (fc_fca_port_t)) {
459*7836SJohn.Forte@Sun.COM 			addr = (uintptr_t)portlist.port_handle;
460*7836SJohn.Forte@Sun.COM 		}
461*7836SJohn.Forte@Sun.COM 	}
462*7836SJohn.Forte@Sun.COM 
463*7836SJohn.Forte@Sun.COM 	mdb_printf("Reading fc_local_port_t at %p:\n", addr);
464*7836SJohn.Forte@Sun.COM 
465*7836SJohn.Forte@Sun.COM 	/*
466*7836SJohn.Forte@Sun.COM 	 * For each port, we just need to read the fc_local_port_t struct
467*7836SJohn.Forte@Sun.COM 	 */
468*7836SJohn.Forte@Sun.COM 
469*7836SJohn.Forte@Sun.COM 	if (mdb_vread(&port, sizeof (fc_local_port_t),
470*7836SJohn.Forte@Sun.COM 	    addr) == sizeof (fc_local_port_t)) {
471*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_mutex          : 0x%p\n", port.fp_mutex);
472*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_state          : 0x%-8x\n", port.fp_state);
473*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_port_id        : 0x%-06x\n",
474*7836SJohn.Forte@Sun.COM 		    port.fp_port_id.port_id);
475*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_fca_handle     : 0x%p\n", port.fp_fca_handle);
476*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_fca_tran       : 0x%p\n", port.fp_fca_tran);
477*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_job_head       : 0x%p\n", port.fp_job_head);
478*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_job_tail       : 0x%p\n", port.fp_job_tail);
479*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_wait_head      : 0x%p\n", port.fp_wait_head);
480*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_wait_tail      : 0x%p\n", port.fp_wait_tail);
481*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_topology       : %u\n", port.fp_topology);
482*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_task           : %d\n", port.fp_task);
483*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_last_task      : %d\n", port.fp_last_task);
484*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_soft_state     : 0x%-4x\n",
485*7836SJohn.Forte@Sun.COM 		    port.fp_soft_state);
486*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_flag           : 0x%-2x\n", port.fp_flag);
487*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_statec_busy    : 0x%-8x\n",
488*7836SJohn.Forte@Sun.COM 		    port.fp_statec_busy);
489*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_port_num       : %d\n", port.fp_port_num);
490*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_instance       : %d\n", port.fp_instance);
491*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_ulp_attach     : %d\n", port.fp_ulp_attach);
492*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_dev_count      : %d\n", port.fp_dev_count);
493*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_total_devices  : %d\n", port.fp_total_devices);
494*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_bind_state     : 0x%-8x\n",
495*7836SJohn.Forte@Sun.COM 		    port.fp_bind_state);
496*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_options        : 0x%-8x\n", port.fp_options);
497*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_port_type      : 0x%-2x\n",
498*7836SJohn.Forte@Sun.COM 		    port.fp_port_type.port_type);
499*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_ub_count       : %d\n", port.fp_ub_count);
500*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_active_ubs     : %d\n", port.fp_active_ubs);
501*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_port_dip       : 0x%p\n", port.fp_port_dip);
502*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_fca_dip        : 0x%p\n", port.fp_fca_dip);
503*7836SJohn.Forte@Sun.COM 
504*7836SJohn.Forte@Sun.COM 		for (idx = 0; idx < 16; idx++) {
505*7836SJohn.Forte@Sun.COM 			if (port.fp_ip_addr[idx] != 0)
506*7836SJohn.Forte@Sun.COM 				break;
507*7836SJohn.Forte@Sun.COM 		}
508*7836SJohn.Forte@Sun.COM 
509*7836SJohn.Forte@Sun.COM 		if (idx != 16) {
510*7836SJohn.Forte@Sun.COM 			mdb_printf("  fp_ip_addr        : %-2x:%-2x:%-2x:%-2x:"
511*7836SJohn.Forte@Sun.COM 			    "%-2x:%-2x:%-2x:%-2x:%-2x:%-2x:%-2x:%-2x:%-2x:%-2x"
512*7836SJohn.Forte@Sun.COM 			    ":%-2x:%-2x\n",
513*7836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[0], port.fp_ip_addr[1],
514*7836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[2], port.fp_ip_addr[3],
515*7836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[4], port.fp_ip_addr[5],
516*7836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[6], port.fp_ip_addr[7],
517*7836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[8], port.fp_ip_addr[9],
518*7836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[10], port.fp_ip_addr[11],
519*7836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[12], port.fp_ip_addr[13],
520*7836SJohn.Forte@Sun.COM 			    port.fp_ip_addr[14], port.fp_ip_addr[15]);
521*7836SJohn.Forte@Sun.COM 		} else {
522*7836SJohn.Forte@Sun.COM 			mdb_printf("  fp_ip_addr        : N/A\n");
523*7836SJohn.Forte@Sun.COM 		}
524*7836SJohn.Forte@Sun.COM 
525*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_fc4_types      : ");
526*7836SJohn.Forte@Sun.COM 
527*7836SJohn.Forte@Sun.COM 		for (idx = 0; idx < 8; idx++) {
528*7836SJohn.Forte@Sun.COM 			if (port.fp_fc4_types[idx] != 0) {
529*7836SJohn.Forte@Sun.COM 				if (first) {
530*7836SJohn.Forte@Sun.COM 					mdb_printf("%d",
531*7836SJohn.Forte@Sun.COM 					    port.fp_fc4_types[idx]);
532*7836SJohn.Forte@Sun.COM 					first = 0;
533*7836SJohn.Forte@Sun.COM 				} else {
534*7836SJohn.Forte@Sun.COM 					mdb_printf(", %d",
535*7836SJohn.Forte@Sun.COM 					    port.fp_fc4_types[idx]);
536*7836SJohn.Forte@Sun.COM 				}
537*7836SJohn.Forte@Sun.COM 			}
538*7836SJohn.Forte@Sun.COM 		}
539*7836SJohn.Forte@Sun.COM 
540*7836SJohn.Forte@Sun.COM 		if (first) {
541*7836SJohn.Forte@Sun.COM 			mdb_printf("None\n");
542*7836SJohn.Forte@Sun.COM 		} else {
543*7836SJohn.Forte@Sun.COM 			mdb_printf("\n");
544*7836SJohn.Forte@Sun.COM 		}
545*7836SJohn.Forte@Sun.COM 
546*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_pm_level       : %d\n", port.fp_pm_level);
547*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_pm_busy        : %d\n", port.fp_pm_busy);
548*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_pm_busy_nocomp : 0x%-8x\n",
549*7836SJohn.Forte@Sun.COM 		    port.fp_pm_busy_nocomp);
550*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_hard_addr      : 0x%-6x\n",
551*7836SJohn.Forte@Sun.COM 		    port.fp_hard_addr.hard_addr);
552*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_sym_port_name  : \"%s\"\n",
553*7836SJohn.Forte@Sun.COM 		    port.fp_sym_port_name);
554*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_sym_node_name  : \"%s\"\n",
555*7836SJohn.Forte@Sun.COM 		    port.fp_sym_node_name);
556*7836SJohn.Forte@Sun.COM 		mdb_printf("  fp_rscn_count     : %d\n", port.fp_rscn_count);
557*7836SJohn.Forte@Sun.COM 	} else {
558*7836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fc_local_port_t at 0x%p", addr);
559*7836SJohn.Forte@Sun.COM 	}
560*7836SJohn.Forte@Sun.COM 
561*7836SJohn.Forte@Sun.COM 	mdb_printf("\n");
562*7836SJohn.Forte@Sun.COM 
563*7836SJohn.Forte@Sun.COM 	return (DCMD_OK);
564*7836SJohn.Forte@Sun.COM }
565*7836SJohn.Forte@Sun.COM 
566*7836SJohn.Forte@Sun.COM 
567*7836SJohn.Forte@Sun.COM /*
568*7836SJohn.Forte@Sun.COM  * Leadville remote_port walker/dcmd code
569*7836SJohn.Forte@Sun.COM  */
570*7836SJohn.Forte@Sun.COM 
571*7836SJohn.Forte@Sun.COM /*
572*7836SJohn.Forte@Sun.COM  * We need to be given the address of a port structure in order to start
573*7836SJohn.Forte@Sun.COM  * walking.  From that, we can read the pwwn table.
574*7836SJohn.Forte@Sun.COM  */
575*7836SJohn.Forte@Sun.COM static int
576*7836SJohn.Forte@Sun.COM pd_by_pwwn_walk_i(mdb_walk_state_t *wsp)
577*7836SJohn.Forte@Sun.COM {
578*7836SJohn.Forte@Sun.COM 	fc_local_port_t port;
579*7836SJohn.Forte@Sun.COM 
580*7836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
581*7836SJohn.Forte@Sun.COM 		mdb_warn("pd_by_pwwn walk doesn't support global walks\n");
582*7836SJohn.Forte@Sun.COM 		return (WALK_ERR);
583*7836SJohn.Forte@Sun.COM 	}
584*7836SJohn.Forte@Sun.COM 
585*7836SJohn.Forte@Sun.COM 	/*
586*7836SJohn.Forte@Sun.COM 	 * Allocate space for the pwwn_hash table
587*7836SJohn.Forte@Sun.COM 	 */
588*7836SJohn.Forte@Sun.COM 
589*7836SJohn.Forte@Sun.COM 	fp_pwwn_table = mdb_alloc(sizeof (struct pwwn_hash) *
590*7836SJohn.Forte@Sun.COM 	    PWWN_HASH_TABLE_SIZE, UM_SLEEP);
591*7836SJohn.Forte@Sun.COM 
592*7836SJohn.Forte@Sun.COM 	/*
593*7836SJohn.Forte@Sun.COM 	 * Input should be an fc_local_port_t, so read it to get the pwwn
594*7836SJohn.Forte@Sun.COM 	 * table's head
595*7836SJohn.Forte@Sun.COM 	 */
596*7836SJohn.Forte@Sun.COM 
597*7836SJohn.Forte@Sun.COM 	if (mdb_vread(&port, sizeof (fc_local_port_t), wsp->walk_addr) !=
598*7836SJohn.Forte@Sun.COM 	    sizeof (fc_local_port_t)) {
599*7836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in the port structure address\n");
600*7836SJohn.Forte@Sun.COM 		return (WALK_ERR);
601*7836SJohn.Forte@Sun.COM 	}
602*7836SJohn.Forte@Sun.COM 
603*7836SJohn.Forte@Sun.COM 	if (mdb_vread(fp_pwwn_table, sizeof (struct pwwn_hash) *
604*7836SJohn.Forte@Sun.COM 	    PWWN_HASH_TABLE_SIZE, (uintptr_t)port.fp_pwwn_table) == -1) {
605*7836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in the pwwn hash table\n");
606*7836SJohn.Forte@Sun.COM 		return (WALK_ERR);
607*7836SJohn.Forte@Sun.COM 	}
608*7836SJohn.Forte@Sun.COM 
609*7836SJohn.Forte@Sun.COM 	pd_hash_index = 0;
610*7836SJohn.Forte@Sun.COM 
611*7836SJohn.Forte@Sun.COM 	while ((fp_pwwn_table[pd_hash_index].pwwn_head == NULL) &&
612*7836SJohn.Forte@Sun.COM 	    (pd_hash_index < PWWN_HASH_TABLE_SIZE)) {
613*7836SJohn.Forte@Sun.COM 		pd_hash_index++;
614*7836SJohn.Forte@Sun.COM 	}
615*7836SJohn.Forte@Sun.COM 
616*7836SJohn.Forte@Sun.COM 	wsp->walk_addr = (uintptr_t)fp_pwwn_table[pd_hash_index].pwwn_head;
617*7836SJohn.Forte@Sun.COM 
618*7836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (fc_remote_port_t), UM_SLEEP);
619*7836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
620*7836SJohn.Forte@Sun.COM }
621*7836SJohn.Forte@Sun.COM 
622*7836SJohn.Forte@Sun.COM /*
623*7836SJohn.Forte@Sun.COM  * At each step, read a fc_remote_port_t into our private storage, and then
624*7836SJohn.Forte@Sun.COM  * invoke the callback function.  We terminate when we reach a NULL p_next
625*7836SJohn.Forte@Sun.COM  * pointer.
626*7836SJohn.Forte@Sun.COM  */
627*7836SJohn.Forte@Sun.COM static int
628*7836SJohn.Forte@Sun.COM pd_by_pwwn_walk_s(mdb_walk_state_t *wsp)
629*7836SJohn.Forte@Sun.COM {
630*7836SJohn.Forte@Sun.COM 	int status;
631*7836SJohn.Forte@Sun.COM 
632*7836SJohn.Forte@Sun.COM 	if ((wsp->walk_addr == NULL) &&
633*7836SJohn.Forte@Sun.COM 	    (pd_hash_index >= (PWWN_HASH_TABLE_SIZE - 1))) {
634*7836SJohn.Forte@Sun.COM 		return (WALK_DONE);
635*7836SJohn.Forte@Sun.COM 	}
636*7836SJohn.Forte@Sun.COM 
637*7836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (fc_remote_port_t), wsp->walk_addr)
638*7836SJohn.Forte@Sun.COM 	    == -1) {
639*7836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fc_remote_port at %p", wsp->walk_addr);
640*7836SJohn.Forte@Sun.COM 		return (WALK_DONE);
641*7836SJohn.Forte@Sun.COM 	}
642*7836SJohn.Forte@Sun.COM 
643*7836SJohn.Forte@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
644*7836SJohn.Forte@Sun.COM 	    wsp->walk_cbdata);
645*7836SJohn.Forte@Sun.COM 
646*7836SJohn.Forte@Sun.COM 	wsp->walk_addr =
647*7836SJohn.Forte@Sun.COM 	    (uintptr_t)(((fc_remote_port_t *)wsp->walk_data)->pd_wwn_hnext);
648*7836SJohn.Forte@Sun.COM 
649*7836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
650*7836SJohn.Forte@Sun.COM 		/*
651*7836SJohn.Forte@Sun.COM 		 * Try the next hash list, if there is one.
652*7836SJohn.Forte@Sun.COM 		 */
653*7836SJohn.Forte@Sun.COM 
654*7836SJohn.Forte@Sun.COM 		pd_hash_index++;
655*7836SJohn.Forte@Sun.COM 
656*7836SJohn.Forte@Sun.COM 		while ((fp_pwwn_table[pd_hash_index].pwwn_head == NULL) &&
657*7836SJohn.Forte@Sun.COM 		    (pd_hash_index < PWWN_HASH_TABLE_SIZE)) {
658*7836SJohn.Forte@Sun.COM 			pd_hash_index++;
659*7836SJohn.Forte@Sun.COM 		}
660*7836SJohn.Forte@Sun.COM 
661*7836SJohn.Forte@Sun.COM 		if (pd_hash_index == PWWN_HASH_TABLE_SIZE) {
662*7836SJohn.Forte@Sun.COM 			/* We're done */
663*7836SJohn.Forte@Sun.COM 			return (status);
664*7836SJohn.Forte@Sun.COM 		}
665*7836SJohn.Forte@Sun.COM 
666*7836SJohn.Forte@Sun.COM 		wsp->walk_addr =
667*7836SJohn.Forte@Sun.COM 		    (uintptr_t)fp_pwwn_table[pd_hash_index].pwwn_head;
668*7836SJohn.Forte@Sun.COM 	}
669*7836SJohn.Forte@Sun.COM 
670*7836SJohn.Forte@Sun.COM 	return (status);
671*7836SJohn.Forte@Sun.COM }
672*7836SJohn.Forte@Sun.COM 
673*7836SJohn.Forte@Sun.COM /*
674*7836SJohn.Forte@Sun.COM  * The walker's fini function is invoked at the end of each walk.
675*7836SJohn.Forte@Sun.COM  */
676*7836SJohn.Forte@Sun.COM static void
677*7836SJohn.Forte@Sun.COM pd_by_pwwn_walk_f(mdb_walk_state_t *wsp)
678*7836SJohn.Forte@Sun.COM {
679*7836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (fc_remote_port_t));
680*7836SJohn.Forte@Sun.COM 	mdb_free(fp_pwwn_table, sizeof (struct pwwn_hash) *
681*7836SJohn.Forte@Sun.COM 	    PWWN_HASH_TABLE_SIZE);
682*7836SJohn.Forte@Sun.COM 	fp_pwwn_table = NULL;
683*7836SJohn.Forte@Sun.COM }
684*7836SJohn.Forte@Sun.COM 
685*7836SJohn.Forte@Sun.COM /*
686*7836SJohn.Forte@Sun.COM  * This is the same walker as pd_by_pwwn, but we walk the D_ID hash table
687*7836SJohn.Forte@Sun.COM  */
688*7836SJohn.Forte@Sun.COM 
689*7836SJohn.Forte@Sun.COM static int
690*7836SJohn.Forte@Sun.COM pd_by_did_walk_i(mdb_walk_state_t *wsp)
691*7836SJohn.Forte@Sun.COM {
692*7836SJohn.Forte@Sun.COM 	fc_local_port_t port;
693*7836SJohn.Forte@Sun.COM 
694*7836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
695*7836SJohn.Forte@Sun.COM 		mdb_warn("pd_by_did walk doesn't support global walks\n");
696*7836SJohn.Forte@Sun.COM 		return (WALK_ERR);
697*7836SJohn.Forte@Sun.COM 	}
698*7836SJohn.Forte@Sun.COM 
699*7836SJohn.Forte@Sun.COM 	/*
700*7836SJohn.Forte@Sun.COM 	 * Allocate space for the did_hash table
701*7836SJohn.Forte@Sun.COM 	 */
702*7836SJohn.Forte@Sun.COM 
703*7836SJohn.Forte@Sun.COM 	fp_did_table = mdb_alloc(sizeof (struct d_id_hash) *
704*7836SJohn.Forte@Sun.COM 	    D_ID_HASH_TABLE_SIZE, UM_SLEEP);
705*7836SJohn.Forte@Sun.COM 
706*7836SJohn.Forte@Sun.COM 	/*
707*7836SJohn.Forte@Sun.COM 	 * Input should be an fc_local_port_t, so read it to get the d_id
708*7836SJohn.Forte@Sun.COM 	 * table's head
709*7836SJohn.Forte@Sun.COM 	 */
710*7836SJohn.Forte@Sun.COM 
711*7836SJohn.Forte@Sun.COM 	if (mdb_vread(&port, sizeof (fc_local_port_t), wsp->walk_addr) !=
712*7836SJohn.Forte@Sun.COM 	    sizeof (fc_local_port_t)) {
713*7836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in the port structure address\n");
714*7836SJohn.Forte@Sun.COM 		return (WALK_ERR);
715*7836SJohn.Forte@Sun.COM 	}
716*7836SJohn.Forte@Sun.COM 
717*7836SJohn.Forte@Sun.COM 	if (mdb_vread(fp_did_table, sizeof (struct d_id_hash) *
718*7836SJohn.Forte@Sun.COM 	    D_ID_HASH_TABLE_SIZE, (uintptr_t)port.fp_did_table) == -1) {
719*7836SJohn.Forte@Sun.COM 		mdb_warn("Unable to read in the D_ID hash table\n");
720*7836SJohn.Forte@Sun.COM 		return (WALK_ERR);
721*7836SJohn.Forte@Sun.COM 	}
722*7836SJohn.Forte@Sun.COM 	pd_hash_index = 0;
723*7836SJohn.Forte@Sun.COM 
724*7836SJohn.Forte@Sun.COM 	while ((fp_did_table[pd_hash_index].d_id_head == NULL) &&
725*7836SJohn.Forte@Sun.COM 	    (pd_hash_index < D_ID_HASH_TABLE_SIZE)) {
726*7836SJohn.Forte@Sun.COM 		pd_hash_index++;
727*7836SJohn.Forte@Sun.COM 	}
728*7836SJohn.Forte@Sun.COM 
729*7836SJohn.Forte@Sun.COM 	wsp->walk_addr = (uintptr_t)fp_did_table[pd_hash_index].d_id_head;
730*7836SJohn.Forte@Sun.COM 
731*7836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (fc_remote_port_t), UM_SLEEP);
732*7836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
733*7836SJohn.Forte@Sun.COM }
734*7836SJohn.Forte@Sun.COM 
735*7836SJohn.Forte@Sun.COM /*
736*7836SJohn.Forte@Sun.COM  * At each step, read a fc_remote_port_t into our private storage, and then
737*7836SJohn.Forte@Sun.COM  * invoke the callback function.  We terminate when we reach a NULL p_next
738*7836SJohn.Forte@Sun.COM  * pointer.
739*7836SJohn.Forte@Sun.COM  */
740*7836SJohn.Forte@Sun.COM static int
741*7836SJohn.Forte@Sun.COM pd_by_did_walk_s(mdb_walk_state_t *wsp)
742*7836SJohn.Forte@Sun.COM {
743*7836SJohn.Forte@Sun.COM 	int status;
744*7836SJohn.Forte@Sun.COM 
745*7836SJohn.Forte@Sun.COM 	if ((wsp->walk_addr == NULL) &&
746*7836SJohn.Forte@Sun.COM 	    (pd_hash_index >= (D_ID_HASH_TABLE_SIZE - 1))) {
747*7836SJohn.Forte@Sun.COM 		return (WALK_DONE);
748*7836SJohn.Forte@Sun.COM 	}
749*7836SJohn.Forte@Sun.COM 
750*7836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (fc_remote_port_t), wsp->walk_addr)
751*7836SJohn.Forte@Sun.COM 	    == -1) {
752*7836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fc_remote_port at %p", wsp->walk_addr);
753*7836SJohn.Forte@Sun.COM 		return (WALK_DONE);
754*7836SJohn.Forte@Sun.COM 	}
755*7836SJohn.Forte@Sun.COM 
756*7836SJohn.Forte@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
757*7836SJohn.Forte@Sun.COM 	    wsp->walk_cbdata);
758*7836SJohn.Forte@Sun.COM 
759*7836SJohn.Forte@Sun.COM 	wsp->walk_addr =
760*7836SJohn.Forte@Sun.COM 	    (uintptr_t)(((fc_remote_port_t *)wsp->walk_data)->pd_did_hnext);
761*7836SJohn.Forte@Sun.COM 
762*7836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
763*7836SJohn.Forte@Sun.COM 		/*
764*7836SJohn.Forte@Sun.COM 		 * Try the next hash list, if there is one.
765*7836SJohn.Forte@Sun.COM 		 */
766*7836SJohn.Forte@Sun.COM 
767*7836SJohn.Forte@Sun.COM 		pd_hash_index++;
768*7836SJohn.Forte@Sun.COM 
769*7836SJohn.Forte@Sun.COM 		while ((fp_did_table[pd_hash_index].d_id_head == NULL) &&
770*7836SJohn.Forte@Sun.COM 		    (pd_hash_index < D_ID_HASH_TABLE_SIZE)) {
771*7836SJohn.Forte@Sun.COM 			pd_hash_index++;
772*7836SJohn.Forte@Sun.COM 		}
773*7836SJohn.Forte@Sun.COM 
774*7836SJohn.Forte@Sun.COM 		if (pd_hash_index == D_ID_HASH_TABLE_SIZE) {
775*7836SJohn.Forte@Sun.COM 			/* We're done */
776*7836SJohn.Forte@Sun.COM 			return (status);
777*7836SJohn.Forte@Sun.COM 		}
778*7836SJohn.Forte@Sun.COM 
779*7836SJohn.Forte@Sun.COM 		wsp->walk_addr =
780*7836SJohn.Forte@Sun.COM 		    (uintptr_t)fp_did_table[pd_hash_index].d_id_head;
781*7836SJohn.Forte@Sun.COM 	}
782*7836SJohn.Forte@Sun.COM 
783*7836SJohn.Forte@Sun.COM 	return (status);
784*7836SJohn.Forte@Sun.COM }
785*7836SJohn.Forte@Sun.COM 
786*7836SJohn.Forte@Sun.COM /*
787*7836SJohn.Forte@Sun.COM  * The walker's fini function is invoked at the end of each walk.
788*7836SJohn.Forte@Sun.COM  */
789*7836SJohn.Forte@Sun.COM static void
790*7836SJohn.Forte@Sun.COM pd_by_did_walk_f(mdb_walk_state_t *wsp)
791*7836SJohn.Forte@Sun.COM {
792*7836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (fc_remote_port_t));
793*7836SJohn.Forte@Sun.COM 	mdb_free(fp_did_table, sizeof (struct d_id_hash) *
794*7836SJohn.Forte@Sun.COM 	    D_ID_HASH_TABLE_SIZE);
795*7836SJohn.Forte@Sun.COM 	fp_did_table = NULL;
796*7836SJohn.Forte@Sun.COM }
797*7836SJohn.Forte@Sun.COM 
798*7836SJohn.Forte@Sun.COM 
799*7836SJohn.Forte@Sun.COM /*
800*7836SJohn.Forte@Sun.COM  * Display a remote_port structure
801*7836SJohn.Forte@Sun.COM  */
802*7836SJohn.Forte@Sun.COM static int
803*7836SJohn.Forte@Sun.COM remote_port(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
804*7836SJohn.Forte@Sun.COM {
805*7836SJohn.Forte@Sun.COM 	fc_remote_port_t	pd;
806*7836SJohn.Forte@Sun.COM 	int			idx;
807*7836SJohn.Forte@Sun.COM 	int			first = 1;
808*7836SJohn.Forte@Sun.COM 
809*7836SJohn.Forte@Sun.COM 	if (argc > 0) {
810*7836SJohn.Forte@Sun.COM 		return (DCMD_USAGE);
811*7836SJohn.Forte@Sun.COM 	}
812*7836SJohn.Forte@Sun.COM 
813*7836SJohn.Forte@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
814*7836SJohn.Forte@Sun.COM 		mdb_printf("Sorry, you must provide an address\n");
815*7836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
816*7836SJohn.Forte@Sun.COM 	}
817*7836SJohn.Forte@Sun.COM 
818*7836SJohn.Forte@Sun.COM 	if (mdb_vread(&pd, sizeof (fc_remote_port_t), addr) !=
819*7836SJohn.Forte@Sun.COM 	    sizeof (fc_remote_port_t)) {
820*7836SJohn.Forte@Sun.COM 		mdb_warn("Error reading pd at 0x%x\n", addr);
821*7836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
822*7836SJohn.Forte@Sun.COM 	}
823*7836SJohn.Forte@Sun.COM 
824*7836SJohn.Forte@Sun.COM 	mdb_printf("Reading remote_port at 0x%p\n", addr);
825*7836SJohn.Forte@Sun.COM 	mdb_printf("  mutex          : 0x%p\n", pd.pd_mutex);
826*7836SJohn.Forte@Sun.COM 	mdb_printf("  port_id        : 0x%-8x\n", pd.pd_port_id);
827*7836SJohn.Forte@Sun.COM 	mdb_printf("  port_name      : 0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
828*7836SJohn.Forte@Sun.COM 	    pd.pd_port_name.raw_wwn[0], pd.pd_port_name.raw_wwn[1],
829*7836SJohn.Forte@Sun.COM 	    pd.pd_port_name.raw_wwn[2], pd.pd_port_name.raw_wwn[3],
830*7836SJohn.Forte@Sun.COM 	    pd.pd_port_name.raw_wwn[4], pd.pd_port_name.raw_wwn[5],
831*7836SJohn.Forte@Sun.COM 	    pd.pd_port_name.raw_wwn[6], pd.pd_port_name.raw_wwn[7]);
832*7836SJohn.Forte@Sun.COM 	mdb_printf("  login_count    : %d\n", pd.pd_login_count);
833*7836SJohn.Forte@Sun.COM 	mdb_printf("  state          : 0x%x ", pd.pd_state);
834*7836SJohn.Forte@Sun.COM 
835*7836SJohn.Forte@Sun.COM 	switch (pd.pd_state) {
836*7836SJohn.Forte@Sun.COM 	case PORT_DEVICE_INVALID:
837*7836SJohn.Forte@Sun.COM 		mdb_printf("(invalid)\n");
838*7836SJohn.Forte@Sun.COM 		break;
839*7836SJohn.Forte@Sun.COM 	case PORT_DEVICE_VALID:
840*7836SJohn.Forte@Sun.COM 		mdb_printf("(valid)\n");
841*7836SJohn.Forte@Sun.COM 		break;
842*7836SJohn.Forte@Sun.COM 	case PORT_DEVICE_LOGGED_IN:
843*7836SJohn.Forte@Sun.COM 		mdb_printf("(logged in)\n");
844*7836SJohn.Forte@Sun.COM 		break;
845*7836SJohn.Forte@Sun.COM 	default:
846*7836SJohn.Forte@Sun.COM 		mdb_printf("(Unknown state)\n");
847*7836SJohn.Forte@Sun.COM 	}
848*7836SJohn.Forte@Sun.COM 
849*7836SJohn.Forte@Sun.COM 	mdb_printf("  remote node    : 0x%p\n", pd.pd_remote_nodep);
850*7836SJohn.Forte@Sun.COM 	mdb_printf("  hard_addr      : 0x%x\n", pd.pd_hard_addr);
851*7836SJohn.Forte@Sun.COM 	mdb_printf("  local port     : 0x%p\n", pd.pd_port);
852*7836SJohn.Forte@Sun.COM 	mdb_printf("  type           : %d ", pd.pd_type);
853*7836SJohn.Forte@Sun.COM 
854*7836SJohn.Forte@Sun.COM 	switch (pd.pd_type) {
855*7836SJohn.Forte@Sun.COM 	case PORT_DEVICE_NOCHANGE:
856*7836SJohn.Forte@Sun.COM 		mdb_printf("(No change)\n");
857*7836SJohn.Forte@Sun.COM 		break;
858*7836SJohn.Forte@Sun.COM 	case PORT_DEVICE_NEW:
859*7836SJohn.Forte@Sun.COM 		mdb_printf("(New)\n");
860*7836SJohn.Forte@Sun.COM 		break;
861*7836SJohn.Forte@Sun.COM 	case PORT_DEVICE_OLD:
862*7836SJohn.Forte@Sun.COM 		mdb_printf("(Old)\n");
863*7836SJohn.Forte@Sun.COM 		break;
864*7836SJohn.Forte@Sun.COM 	case PORT_DEVICE_CHANGED:
865*7836SJohn.Forte@Sun.COM 		mdb_printf("(Changed)\n");
866*7836SJohn.Forte@Sun.COM 		break;
867*7836SJohn.Forte@Sun.COM 	case PORT_DEVICE_DELETE:
868*7836SJohn.Forte@Sun.COM 		mdb_printf("(Delete)\n");
869*7836SJohn.Forte@Sun.COM 		break;
870*7836SJohn.Forte@Sun.COM 	case PORT_DEVICE_USER_LOGIN:
871*7836SJohn.Forte@Sun.COM 		mdb_printf("(User login)\n");
872*7836SJohn.Forte@Sun.COM 		break;
873*7836SJohn.Forte@Sun.COM 	case PORT_DEVICE_USER_LOGOUT:
874*7836SJohn.Forte@Sun.COM 		mdb_printf("(User logout)\n");
875*7836SJohn.Forte@Sun.COM 		break;
876*7836SJohn.Forte@Sun.COM 	case PORT_DEVICE_USER_CREATE:
877*7836SJohn.Forte@Sun.COM 		mdb_printf("(User create)\n");
878*7836SJohn.Forte@Sun.COM 		break;
879*7836SJohn.Forte@Sun.COM 	case PORT_DEVICE_USER_DELETE:
880*7836SJohn.Forte@Sun.COM 		mdb_printf("(User delete)\n");
881*7836SJohn.Forte@Sun.COM 		break;
882*7836SJohn.Forte@Sun.COM 	default:
883*7836SJohn.Forte@Sun.COM 		mdb_printf("(Unknown type)\n");
884*7836SJohn.Forte@Sun.COM 	}
885*7836SJohn.Forte@Sun.COM 
886*7836SJohn.Forte@Sun.COM 	mdb_printf("  flags          : 0x%x ", pd.pd_flags);
887*7836SJohn.Forte@Sun.COM 
888*7836SJohn.Forte@Sun.COM 	switch (pd.pd_flags) {
889*7836SJohn.Forte@Sun.COM 	case PD_IDLE:
890*7836SJohn.Forte@Sun.COM 		mdb_printf("(Idle)\n");
891*7836SJohn.Forte@Sun.COM 		break;
892*7836SJohn.Forte@Sun.COM 	case PD_ELS_IN_PROGRESS:
893*7836SJohn.Forte@Sun.COM 		mdb_printf("(ELS in progress)\n");
894*7836SJohn.Forte@Sun.COM 		break;
895*7836SJohn.Forte@Sun.COM 	case PD_ELS_MARK:
896*7836SJohn.Forte@Sun.COM 		mdb_printf("(Mark)\n");
897*7836SJohn.Forte@Sun.COM 		break;
898*7836SJohn.Forte@Sun.COM 	default:
899*7836SJohn.Forte@Sun.COM 		mdb_printf("(Unknown flag value)\n");
900*7836SJohn.Forte@Sun.COM 	}
901*7836SJohn.Forte@Sun.COM 
902*7836SJohn.Forte@Sun.COM 	mdb_printf("  login_class    : 0x%x\n", pd.pd_login_class);
903*7836SJohn.Forte@Sun.COM 	mdb_printf("  recipient      : %d\n", pd.pd_recepient);
904*7836SJohn.Forte@Sun.COM 	mdb_printf("  ref_count      : %d\n", pd.pd_ref_count);
905*7836SJohn.Forte@Sun.COM 	mdb_printf("  aux_flags      : 0x%x ", pd.pd_aux_flags);
906*7836SJohn.Forte@Sun.COM 
907*7836SJohn.Forte@Sun.COM 	first = 1;
908*7836SJohn.Forte@Sun.COM 	if (pd.pd_aux_flags & PD_IN_DID_QUEUE) {
909*7836SJohn.Forte@Sun.COM 		mdb_printf("(IN_DID_QUEUE");
910*7836SJohn.Forte@Sun.COM 		first = 0;
911*7836SJohn.Forte@Sun.COM 	}
912*7836SJohn.Forte@Sun.COM 
913*7836SJohn.Forte@Sun.COM 	if (pd.pd_aux_flags & PD_DISABLE_RELOGIN) {
914*7836SJohn.Forte@Sun.COM 		if (first) {
915*7836SJohn.Forte@Sun.COM 			mdb_printf("(DISABLE_RELOGIN");
916*7836SJohn.Forte@Sun.COM 		} else {
917*7836SJohn.Forte@Sun.COM 			mdb_printf(", DISABLE_RELOGIN");
918*7836SJohn.Forte@Sun.COM 		}
919*7836SJohn.Forte@Sun.COM 		first = 0;
920*7836SJohn.Forte@Sun.COM 	}
921*7836SJohn.Forte@Sun.COM 
922*7836SJohn.Forte@Sun.COM 	if (pd.pd_aux_flags & PD_NEEDS_REMOVAL) {
923*7836SJohn.Forte@Sun.COM 		if (first) {
924*7836SJohn.Forte@Sun.COM 			mdb_printf("(NEEDS_REMOVAL");
925*7836SJohn.Forte@Sun.COM 		} else {
926*7836SJohn.Forte@Sun.COM 			mdb_printf(", NEEDS_REMOVAL");
927*7836SJohn.Forte@Sun.COM 		}
928*7836SJohn.Forte@Sun.COM 		first = 0;
929*7836SJohn.Forte@Sun.COM 	}
930*7836SJohn.Forte@Sun.COM 
931*7836SJohn.Forte@Sun.COM 	if (pd.pd_aux_flags & PD_LOGGED_OUT) {
932*7836SJohn.Forte@Sun.COM 		if (first) {
933*7836SJohn.Forte@Sun.COM 			mdb_printf("(LOGGED_OUT");
934*7836SJohn.Forte@Sun.COM 		} else {
935*7836SJohn.Forte@Sun.COM 			mdb_printf(", LOGGED_OUT");
936*7836SJohn.Forte@Sun.COM 		}
937*7836SJohn.Forte@Sun.COM 		first = 0;
938*7836SJohn.Forte@Sun.COM 	}
939*7836SJohn.Forte@Sun.COM 
940*7836SJohn.Forte@Sun.COM 	if (pd.pd_aux_flags & PD_GIVEN_TO_ULPS) {
941*7836SJohn.Forte@Sun.COM 		if (first) {
942*7836SJohn.Forte@Sun.COM 			mdb_printf("(GIVEN_TO_ULPS");
943*7836SJohn.Forte@Sun.COM 		} else {
944*7836SJohn.Forte@Sun.COM 			mdb_printf(", GIVEN_TO_ULPS");
945*7836SJohn.Forte@Sun.COM 		}
946*7836SJohn.Forte@Sun.COM 		first = 0;
947*7836SJohn.Forte@Sun.COM 	}
948*7836SJohn.Forte@Sun.COM 
949*7836SJohn.Forte@Sun.COM 	if (first == 0) {
950*7836SJohn.Forte@Sun.COM 		mdb_printf(")\n");
951*7836SJohn.Forte@Sun.COM 	} else {
952*7836SJohn.Forte@Sun.COM 		mdb_printf("\n");
953*7836SJohn.Forte@Sun.COM 	}
954*7836SJohn.Forte@Sun.COM 
955*7836SJohn.Forte@Sun.COM 	mdb_printf("  sig            : %p\n", pd.pd_logo_tc.sig);
956*7836SJohn.Forte@Sun.COM 	mdb_printf("  active         : %d\n", pd.pd_logo_tc.active);
957*7836SJohn.Forte@Sun.COM 	mdb_printf("  counter        : %d\n", pd.pd_logo_tc.counter);
958*7836SJohn.Forte@Sun.COM 	mdb_printf("  max_value      : %d\n", pd.pd_logo_tc.max_value);
959*7836SJohn.Forte@Sun.COM 	mdb_printf("  timer          : %d\n", pd.pd_logo_tc.timer);
960*7836SJohn.Forte@Sun.COM 	mdb_printf("\n");
961*7836SJohn.Forte@Sun.COM 
962*7836SJohn.Forte@Sun.COM 	return (DCMD_OK);
963*7836SJohn.Forte@Sun.COM }
964*7836SJohn.Forte@Sun.COM 
965*7836SJohn.Forte@Sun.COM int
966*7836SJohn.Forte@Sun.COM fc_dump_logmsg(fc_trace_dmsg_t *addr, uint_t pktstart, uint_t pktend,
967*7836SJohn.Forte@Sun.COM     uint_t *printed)
968*7836SJohn.Forte@Sun.COM {
969*7836SJohn.Forte@Sun.COM 	fc_trace_dmsg_t	msg;
970*7836SJohn.Forte@Sun.COM 	caddr_t		buf;
971*7836SJohn.Forte@Sun.COM 	char		merge[1024];
972*7836SJohn.Forte@Sun.COM 	caddr_t		tmppkt;
973*7836SJohn.Forte@Sun.COM 	char		*tmpbuf; /* for tokenising the buffer */
974*7836SJohn.Forte@Sun.COM 	uint_t		pktnum = 0;
975*7836SJohn.Forte@Sun.COM 
976*7836SJohn.Forte@Sun.COM 	while (addr != NULL) {
977*7836SJohn.Forte@Sun.COM 		if (mdb_vread(&msg, sizeof (msg), (uintptr_t)addr) !=
978*7836SJohn.Forte@Sun.COM 		    sizeof (msg)) {
979*7836SJohn.Forte@Sun.COM 			mdb_warn("failed to read message pointer in kernel");
980*7836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
981*7836SJohn.Forte@Sun.COM 		}
982*7836SJohn.Forte@Sun.COM 
983*7836SJohn.Forte@Sun.COM 		if (msg.id_size) {
984*7836SJohn.Forte@Sun.COM 
985*7836SJohn.Forte@Sun.COM 			buf = mdb_alloc(msg.id_size + 1, UM_SLEEP);
986*7836SJohn.Forte@Sun.COM 			tmppkt = mdb_alloc(msg.id_size + 1, UM_SLEEP);
987*7836SJohn.Forte@Sun.COM 
988*7836SJohn.Forte@Sun.COM 			if (mdb_vread(buf, msg.id_size,
989*7836SJohn.Forte@Sun.COM 			    (uintptr_t)msg.id_buf) != msg.id_size) {
990*7836SJohn.Forte@Sun.COM 				mdb_warn("failed to read buffer contents"
991*7836SJohn.Forte@Sun.COM 				    " in kernel");
992*7836SJohn.Forte@Sun.COM 				mdb_free(buf, msg.id_size + 1);
993*7836SJohn.Forte@Sun.COM 				return (DCMD_ERR);
994*7836SJohn.Forte@Sun.COM 			}
995*7836SJohn.Forte@Sun.COM 
996*7836SJohn.Forte@Sun.COM 			if (buf[0] == '\n') {
997*7836SJohn.Forte@Sun.COM 				mdb_printf("There is a problem in"
998*7836SJohn.Forte@Sun.COM 				    "the buffer\n");
999*7836SJohn.Forte@Sun.COM 			}
1000*7836SJohn.Forte@Sun.COM 			/* funky packet processing stuff */
1001*7836SJohn.Forte@Sun.COM 			bcopy(buf, tmppkt, msg.id_size + 1);
1002*7836SJohn.Forte@Sun.COM 
1003*7836SJohn.Forte@Sun.COM 			/* find the equals sign, and put a null there */
1004*7836SJohn.Forte@Sun.COM 			tmpbuf = strchr(tmppkt, '=');
1005*7836SJohn.Forte@Sun.COM 			*tmpbuf = 0;
1006*7836SJohn.Forte@Sun.COM 			pktnum = (uint_t)mdb_strtoull(tmppkt);
1007*7836SJohn.Forte@Sun.COM 
1008*7836SJohn.Forte@Sun.COM 			if ((pktnum >= pktstart) && (pktnum <= pktend)) {
1009*7836SJohn.Forte@Sun.COM 				(void) mdb_snprintf(merge, sizeof (merge),
1010*7836SJohn.Forte@Sun.COM 				    "[%09d:%03d:%03d:%03d] %s",
1011*7836SJohn.Forte@Sun.COM 				    (int)msg.id_time.tv_sec,
1012*7836SJohn.Forte@Sun.COM 				    (int)msg.id_time.tv_nsec/1000000,
1013*7836SJohn.Forte@Sun.COM 				    (int)(msg.id_time.tv_nsec/1000)%1000,
1014*7836SJohn.Forte@Sun.COM 				    (int)msg.id_time.tv_nsec%1000,
1015*7836SJohn.Forte@Sun.COM 				    buf);
1016*7836SJohn.Forte@Sun.COM 				mdb_printf("%s", merge);
1017*7836SJohn.Forte@Sun.COM 				if (printed != NULL)
1018*7836SJohn.Forte@Sun.COM 					(*printed) ++;
1019*7836SJohn.Forte@Sun.COM 			}
1020*7836SJohn.Forte@Sun.COM 			mdb_free(buf, msg.id_size + 1);
1021*7836SJohn.Forte@Sun.COM 			mdb_free(tmppkt, msg.id_size + 1);
1022*7836SJohn.Forte@Sun.COM 		}
1023*7836SJohn.Forte@Sun.COM 		addr = msg.id_next;
1024*7836SJohn.Forte@Sun.COM 	}
1025*7836SJohn.Forte@Sun.COM 
1026*7836SJohn.Forte@Sun.COM 	return (DCMD_OK);
1027*7836SJohn.Forte@Sun.COM }
1028*7836SJohn.Forte@Sun.COM 
1029*7836SJohn.Forte@Sun.COM int
1030*7836SJohn.Forte@Sun.COM fc_dump_old_logmsg(fc_trace_dmsgv1_t *addr, uint_t pktstart, uint_t pktend,
1031*7836SJohn.Forte@Sun.COM     uint_t *printed)
1032*7836SJohn.Forte@Sun.COM {
1033*7836SJohn.Forte@Sun.COM 	fc_trace_dmsgv1_t	msg;
1034*7836SJohn.Forte@Sun.COM 	caddr_t			buf;
1035*7836SJohn.Forte@Sun.COM 	char			merge[1024];
1036*7836SJohn.Forte@Sun.COM 	caddr_t			tmppkt;
1037*7836SJohn.Forte@Sun.COM 	char			*tmpbuf; /* for tokenising the buffer */
1038*7836SJohn.Forte@Sun.COM 	uint_t			pktnum = 0;
1039*7836SJohn.Forte@Sun.COM 
1040*7836SJohn.Forte@Sun.COM 	while (addr != NULL) {
1041*7836SJohn.Forte@Sun.COM 		if (mdb_vread(&msg, sizeof (msg), (uintptr_t)addr) !=
1042*7836SJohn.Forte@Sun.COM 		    sizeof (msg)) {
1043*7836SJohn.Forte@Sun.COM 			mdb_warn("failed to read message pointer in kernel");
1044*7836SJohn.Forte@Sun.COM 			return (DCMD_ERR);
1045*7836SJohn.Forte@Sun.COM 		}
1046*7836SJohn.Forte@Sun.COM 
1047*7836SJohn.Forte@Sun.COM 		if (msg.id_size) {
1048*7836SJohn.Forte@Sun.COM 
1049*7836SJohn.Forte@Sun.COM 			buf = mdb_alloc(msg.id_size + 1, UM_SLEEP);
1050*7836SJohn.Forte@Sun.COM 			tmppkt = mdb_alloc(msg.id_size + 1, UM_SLEEP);
1051*7836SJohn.Forte@Sun.COM 
1052*7836SJohn.Forte@Sun.COM 			if (mdb_vread(buf, msg.id_size,
1053*7836SJohn.Forte@Sun.COM 			    (uintptr_t)msg.id_buf) != msg.id_size) {
1054*7836SJohn.Forte@Sun.COM 				mdb_warn("failed to read buffer contents"
1055*7836SJohn.Forte@Sun.COM 				    " in kernel");
1056*7836SJohn.Forte@Sun.COM 				mdb_free(buf, msg.id_size + 1);
1057*7836SJohn.Forte@Sun.COM 				return (DCMD_ERR);
1058*7836SJohn.Forte@Sun.COM 			}
1059*7836SJohn.Forte@Sun.COM 
1060*7836SJohn.Forte@Sun.COM 			if (buf[0] == '\n') {
1061*7836SJohn.Forte@Sun.COM 				mdb_printf("There is a problem in"
1062*7836SJohn.Forte@Sun.COM 				    "the buffer\n");
1063*7836SJohn.Forte@Sun.COM 			}
1064*7836SJohn.Forte@Sun.COM 			/* funky packet processing stuff */
1065*7836SJohn.Forte@Sun.COM 			bcopy(buf, tmppkt, msg.id_size + 1);
1066*7836SJohn.Forte@Sun.COM 
1067*7836SJohn.Forte@Sun.COM 			tmpbuf = strchr(tmppkt, '=');
1068*7836SJohn.Forte@Sun.COM 			*tmpbuf = 0;
1069*7836SJohn.Forte@Sun.COM 			pktnum = (uint_t)mdb_strtoull(tmppkt);
1070*7836SJohn.Forte@Sun.COM 
1071*7836SJohn.Forte@Sun.COM 			if ((pktnum >= pktstart) && (pktnum <= pktend)) {
1072*7836SJohn.Forte@Sun.COM 				(void) mdb_snprintf(merge, sizeof (merge),
1073*7836SJohn.Forte@Sun.COM 				    "[%d] %s",
1074*7836SJohn.Forte@Sun.COM 				    msg.id_time,
1075*7836SJohn.Forte@Sun.COM 				    buf);
1076*7836SJohn.Forte@Sun.COM 				mdb_printf("%s", merge);
1077*7836SJohn.Forte@Sun.COM 				if (printed != NULL)
1078*7836SJohn.Forte@Sun.COM 					(*printed) ++;
1079*7836SJohn.Forte@Sun.COM 			}
1080*7836SJohn.Forte@Sun.COM 			mdb_free(buf, msg.id_size + 1);
1081*7836SJohn.Forte@Sun.COM 			mdb_free(tmppkt, msg.id_size + 1);
1082*7836SJohn.Forte@Sun.COM 		}
1083*7836SJohn.Forte@Sun.COM 		addr = msg.id_next;
1084*7836SJohn.Forte@Sun.COM 	}
1085*7836SJohn.Forte@Sun.COM 
1086*7836SJohn.Forte@Sun.COM 	return (DCMD_OK);
1087*7836SJohn.Forte@Sun.COM }
1088*7836SJohn.Forte@Sun.COM 
1089*7836SJohn.Forte@Sun.COM int
1090*7836SJohn.Forte@Sun.COM fc_trace_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1091*7836SJohn.Forte@Sun.COM {
1092*7836SJohn.Forte@Sun.COM 	fc_trace_logq_t logq;
1093*7836SJohn.Forte@Sun.COM 	uint_t		pktnum = 0;
1094*7836SJohn.Forte@Sun.COM 	uint_t		printed = 0; /* have we printed anything? */
1095*7836SJohn.Forte@Sun.COM 
1096*7836SJohn.Forte@Sun.COM 	uintptr_t	pktstart = 0;
1097*7836SJohn.Forte@Sun.COM 	uintptr_t	pktend = UINT_MAX;
1098*7836SJohn.Forte@Sun.COM 	int		rval = DCMD_OK;
1099*7836SJohn.Forte@Sun.COM 
1100*7836SJohn.Forte@Sun.COM 	if (mdb_vread(&logq, sizeof (logq), addr) != sizeof (logq)) {
1101*7836SJohn.Forte@Sun.COM 		mdb_warn("Failed to read log queue in kernel");
1102*7836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
1103*7836SJohn.Forte@Sun.COM 	}
1104*7836SJohn.Forte@Sun.COM 
1105*7836SJohn.Forte@Sun.COM 	if (mdb_getopts(argc, argv,
1106*7836SJohn.Forte@Sun.COM 	    's', MDB_OPT_UINTPTR, &pktstart,
1107*7836SJohn.Forte@Sun.COM 	    'e', MDB_OPT_UINTPTR, &pktend) != argc) {
1108*7836SJohn.Forte@Sun.COM 		return (DCMD_USAGE);
1109*7836SJohn.Forte@Sun.COM 	}
1110*7836SJohn.Forte@Sun.COM 
1111*7836SJohn.Forte@Sun.COM 	if (pktstart > pktend) {
1112*7836SJohn.Forte@Sun.COM 		return (DCMD_USAGE);
1113*7836SJohn.Forte@Sun.COM 	}
1114*7836SJohn.Forte@Sun.COM 
1115*7836SJohn.Forte@Sun.COM 	if (logq.il_flags & FC_TRACE_LOGQ_V2 != 0) {
1116*7836SJohn.Forte@Sun.COM 		rval = fc_dump_logmsg((fc_trace_dmsg_t *)logq.il_msgh, pktstart,
1117*7836SJohn.Forte@Sun.COM 		    pktend, &printed);
1118*7836SJohn.Forte@Sun.COM 	} else {
1119*7836SJohn.Forte@Sun.COM 		rval = fc_dump_old_logmsg((fc_trace_dmsgv1_t *)logq.il_msgh,
1120*7836SJohn.Forte@Sun.COM 		    pktstart, pktend, &printed);
1121*7836SJohn.Forte@Sun.COM 	}
1122*7836SJohn.Forte@Sun.COM 
1123*7836SJohn.Forte@Sun.COM 	if (rval != DCMD_OK) {
1124*7836SJohn.Forte@Sun.COM 		return (rval);
1125*7836SJohn.Forte@Sun.COM 	}
1126*7836SJohn.Forte@Sun.COM 
1127*7836SJohn.Forte@Sun.COM 	if (printed == 0) {
1128*7836SJohn.Forte@Sun.COM 		mdb_printf("No packets in the buffer match the"
1129*7836SJohn.Forte@Sun.COM 		    " criteria given");
1130*7836SJohn.Forte@Sun.COM 	}
1131*7836SJohn.Forte@Sun.COM 
1132*7836SJohn.Forte@Sun.COM 	return (rval);
1133*7836SJohn.Forte@Sun.COM }
1134*7836SJohn.Forte@Sun.COM 
1135*7836SJohn.Forte@Sun.COM int
1136*7836SJohn.Forte@Sun.COM fp_trace_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1137*7836SJohn.Forte@Sun.COM {
1138*7836SJohn.Forte@Sun.COM 	if (mdb_readvar(&addr, "fp_logq") == -1) {
1139*7836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fp_logq");
1140*7836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
1141*7836SJohn.Forte@Sun.COM 	}
1142*7836SJohn.Forte@Sun.COM 
1143*7836SJohn.Forte@Sun.COM 	if (DCMD_HDRSPEC(flags)) {
1144*7836SJohn.Forte@Sun.COM 		mdb_printf("fp trace buffer contents\n");
1145*7836SJohn.Forte@Sun.COM 	}
1146*7836SJohn.Forte@Sun.COM 
1147*7836SJohn.Forte@Sun.COM 	return (fc_trace_dump(addr, flags, argc, argv));
1148*7836SJohn.Forte@Sun.COM }
1149*7836SJohn.Forte@Sun.COM 
1150*7836SJohn.Forte@Sun.COM 
1151*7836SJohn.Forte@Sun.COM int
1152*7836SJohn.Forte@Sun.COM fcp_trace_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1153*7836SJohn.Forte@Sun.COM {
1154*7836SJohn.Forte@Sun.COM 	if (mdb_readvar(&addr, "fcp_logq") == -1) {
1155*7836SJohn.Forte@Sun.COM 		mdb_warn("failed to read fcp_logq");
1156*7836SJohn.Forte@Sun.COM 		return (DCMD_ERR);
1157*7836SJohn.Forte@Sun.COM 	}
1158*7836SJohn.Forte@Sun.COM 
1159*7836SJohn.Forte@Sun.COM 	if (DCMD_HDRSPEC(flags)) {
1160*7836SJohn.Forte@Sun.COM 		mdb_printf("fcp trace buffer contents\n");
1161*7836SJohn.Forte@Sun.COM 	}
1162*7836SJohn.Forte@Sun.COM 
1163*7836SJohn.Forte@Sun.COM 	return (fc_trace_dump(addr, flags, argc, argv));
1164*7836SJohn.Forte@Sun.COM }
1165*7836SJohn.Forte@Sun.COM 
1166*7836SJohn.Forte@Sun.COM /*
1167*7836SJohn.Forte@Sun.COM  * Leadville job_request walker/dcmd code
1168*7836SJohn.Forte@Sun.COM  */
1169*7836SJohn.Forte@Sun.COM 
1170*7836SJohn.Forte@Sun.COM /*
1171*7836SJohn.Forte@Sun.COM  * We need to be given the address of a local port structure in order to start
1172*7836SJohn.Forte@Sun.COM  * walking.  From that, we can read the job_request list.
1173*7836SJohn.Forte@Sun.COM  */
1174*7836SJohn.Forte@Sun.COM 
1175*7836SJohn.Forte@Sun.COM static int
1176*7836SJohn.Forte@Sun.COM job_request_walk_i(mdb_walk_state_t *wsp)
1177*7836SJohn.Forte@Sun.COM {
1178*7836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
1179*7836SJohn.Forte@Sun.COM 		mdb_warn("The address of a fc_local_port"
1180*7836SJohn.Forte@Sun.COM 		    " structure must be given\n");
1181*7836SJohn.Forte@Sun.COM 		return (WALK_ERR);
1182*7836SJohn.Forte@Sun.COM 	}
1183*7836SJohn.Forte@Sun.COM 
1184*7836SJohn.Forte@Sun.COM 	/*
1185*7836SJohn.Forte@Sun.COM 	 * Input should be a fc_local_port_t, so read it to get the job_request
1186*7836SJohn.Forte@Sun.COM 	 * lists's head
1187*7836SJohn.Forte@Sun.COM 	 */
1188*7836SJohn.Forte@Sun.COM 
1189*7836SJohn.Forte@Sun.COM 	if (mdb_vread(&port, sizeof (fc_local_port_t), wsp->walk_addr) !=
1190*7836SJohn.Forte@Sun.COM 	    sizeof (fc_local_port_t)) {
1191*7836SJohn.Forte@Sun.COM 		mdb_warn("Failed to read in the fc_local_port"
1192*7836SJohn.Forte@Sun.COM 		    " at 0x%p\n", wsp->walk_addr);
1193*7836SJohn.Forte@Sun.COM 		return (WALK_ERR);
1194*7836SJohn.Forte@Sun.COM 	}
1195*7836SJohn.Forte@Sun.COM 
1196*7836SJohn.Forte@Sun.COM 	wsp->walk_addr = (uintptr_t)(port.fp_job_head);
1197*7836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (struct job_request), UM_SLEEP);
1198*7836SJohn.Forte@Sun.COM 
1199*7836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
1200*7836SJohn.Forte@Sun.COM }
1201*7836SJohn.Forte@Sun.COM 
1202*7836SJohn.Forte@Sun.COM static int
1203*7836SJohn.Forte@Sun.COM job_request_walk_s(mdb_walk_state_t *wsp)
1204*7836SJohn.Forte@Sun.COM {
1205*7836SJohn.Forte@Sun.COM 	int status;
1206*7836SJohn.Forte@Sun.COM 
1207*7836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL)
1208*7836SJohn.Forte@Sun.COM 		return (WALK_DONE);
1209*7836SJohn.Forte@Sun.COM 
1210*7836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (struct job_request),
1211*7836SJohn.Forte@Sun.COM 	    wsp->walk_addr) == -1) {
1212*7836SJohn.Forte@Sun.COM 		mdb_warn("Failed to read in the job_request at 0x%p\n",
1213*7836SJohn.Forte@Sun.COM 		    wsp->walk_addr);
1214*7836SJohn.Forte@Sun.COM 		return (WALK_DONE);
1215*7836SJohn.Forte@Sun.COM 	}
1216*7836SJohn.Forte@Sun.COM 
1217*7836SJohn.Forte@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
1218*7836SJohn.Forte@Sun.COM 	    wsp->walk_cbdata);
1219*7836SJohn.Forte@Sun.COM 
1220*7836SJohn.Forte@Sun.COM 	wsp->walk_addr =
1221*7836SJohn.Forte@Sun.COM 	    (uintptr_t)(((struct job_request *)wsp->walk_data)->job_next);
1222*7836SJohn.Forte@Sun.COM 
1223*7836SJohn.Forte@Sun.COM 	return (status);
1224*7836SJohn.Forte@Sun.COM }
1225*7836SJohn.Forte@Sun.COM 
1226*7836SJohn.Forte@Sun.COM /*
1227*7836SJohn.Forte@Sun.COM  * The walker's fini function is invoked at the end of each walk.
1228*7836SJohn.Forte@Sun.COM  */
1229*7836SJohn.Forte@Sun.COM static void
1230*7836SJohn.Forte@Sun.COM job_request_walk_f(mdb_walk_state_t *wsp)
1231*7836SJohn.Forte@Sun.COM {
1232*7836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (struct job_request));
1233*7836SJohn.Forte@Sun.COM }
1234*7836SJohn.Forte@Sun.COM 
1235*7836SJohn.Forte@Sun.COM 
1236*7836SJohn.Forte@Sun.COM /*
1237*7836SJohn.Forte@Sun.COM  * Leadville fc_orphan walker/dcmd code
1238*7836SJohn.Forte@Sun.COM  */
1239*7836SJohn.Forte@Sun.COM 
1240*7836SJohn.Forte@Sun.COM /*
1241*7836SJohn.Forte@Sun.COM  * We need to be given the address of a port structure in order to start
1242*7836SJohn.Forte@Sun.COM  * walking.  From that, we can read the orphan list.
1243*7836SJohn.Forte@Sun.COM  */
1244*7836SJohn.Forte@Sun.COM 
1245*7836SJohn.Forte@Sun.COM static int
1246*7836SJohn.Forte@Sun.COM orphan_walk_i(mdb_walk_state_t *wsp)
1247*7836SJohn.Forte@Sun.COM {
1248*7836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL) {
1249*7836SJohn.Forte@Sun.COM 		mdb_warn("The address of a fc_local_port"
1250*7836SJohn.Forte@Sun.COM 		    " structure must be given\n");
1251*7836SJohn.Forte@Sun.COM 		return (WALK_ERR);
1252*7836SJohn.Forte@Sun.COM 	}
1253*7836SJohn.Forte@Sun.COM 
1254*7836SJohn.Forte@Sun.COM 	/*
1255*7836SJohn.Forte@Sun.COM 	 * Input should be a fc_local_port_t, so read it to get the orphan
1256*7836SJohn.Forte@Sun.COM 	 * lists's head
1257*7836SJohn.Forte@Sun.COM 	 */
1258*7836SJohn.Forte@Sun.COM 
1259*7836SJohn.Forte@Sun.COM 	if (mdb_vread(&port, sizeof (fc_local_port_t), wsp->walk_addr) !=
1260*7836SJohn.Forte@Sun.COM 	    sizeof (fc_local_port_t)) {
1261*7836SJohn.Forte@Sun.COM 		mdb_warn("Failed to read in the fc_local_port"
1262*7836SJohn.Forte@Sun.COM 		    " at 0x%p\n", wsp->walk_addr);
1263*7836SJohn.Forte@Sun.COM 		return (WALK_ERR);
1264*7836SJohn.Forte@Sun.COM 	}
1265*7836SJohn.Forte@Sun.COM 
1266*7836SJohn.Forte@Sun.COM 	wsp->walk_addr = (uintptr_t)(port.fp_orphan_list);
1267*7836SJohn.Forte@Sun.COM 	wsp->walk_data = mdb_alloc(sizeof (struct fc_orphan), UM_SLEEP);
1268*7836SJohn.Forte@Sun.COM 
1269*7836SJohn.Forte@Sun.COM 	return (WALK_NEXT);
1270*7836SJohn.Forte@Sun.COM }
1271*7836SJohn.Forte@Sun.COM 
1272*7836SJohn.Forte@Sun.COM static int
1273*7836SJohn.Forte@Sun.COM orphan_walk_s(mdb_walk_state_t *wsp)
1274*7836SJohn.Forte@Sun.COM {
1275*7836SJohn.Forte@Sun.COM 	int status;
1276*7836SJohn.Forte@Sun.COM 
1277*7836SJohn.Forte@Sun.COM 	if (wsp->walk_addr == NULL)
1278*7836SJohn.Forte@Sun.COM 		return (WALK_DONE);
1279*7836SJohn.Forte@Sun.COM 
1280*7836SJohn.Forte@Sun.COM 	if (mdb_vread(wsp->walk_data, sizeof (struct fc_orphan),
1281*7836SJohn.Forte@Sun.COM 	    wsp->walk_addr) == -1) {
1282*7836SJohn.Forte@Sun.COM 		mdb_warn("Failed to read in the fc_orphan at 0x%p\n",
1283*7836SJohn.Forte@Sun.COM 		    wsp->walk_addr);
1284*7836SJohn.Forte@Sun.COM 		return (WALK_DONE);
1285*7836SJohn.Forte@Sun.COM 	}
1286*7836SJohn.Forte@Sun.COM 
1287*7836SJohn.Forte@Sun.COM 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
1288*7836SJohn.Forte@Sun.COM 	    wsp->walk_cbdata);
1289*7836SJohn.Forte@Sun.COM 
1290*7836SJohn.Forte@Sun.COM 	wsp->walk_addr =
1291*7836SJohn.Forte@Sun.COM 	    (uintptr_t)(((struct fc_orphan *)wsp->walk_data)->orp_next);
1292*7836SJohn.Forte@Sun.COM 
1293*7836SJohn.Forte@Sun.COM 	return (status);
1294*7836SJohn.Forte@Sun.COM }
1295*7836SJohn.Forte@Sun.COM 
1296*7836SJohn.Forte@Sun.COM /*
1297*7836SJohn.Forte@Sun.COM  * The walker's fini function is invoked at the end of each walk.
1298*7836SJohn.Forte@Sun.COM  */
1299*7836SJohn.Forte@Sun.COM static void
1300*7836SJohn.Forte@Sun.COM orphan_walk_f(mdb_walk_state_t *wsp)
1301*7836SJohn.Forte@Sun.COM {
1302*7836SJohn.Forte@Sun.COM 	mdb_free(wsp->walk_data, sizeof (struct fc_orphan));
1303*7836SJohn.Forte@Sun.COM }
1304*7836SJohn.Forte@Sun.COM 
1305*7836SJohn.Forte@Sun.COM 
1306*7836SJohn.Forte@Sun.COM /*
1307*7836SJohn.Forte@Sun.COM  * MDB module linkage information:
1308*7836SJohn.Forte@Sun.COM  *
1309*7836SJohn.Forte@Sun.COM  * We declare a list of structures describing our dcmds, a list of structures
1310*7836SJohn.Forte@Sun.COM  * describing our walkers, and a function named _mdb_init to return a pointer
1311*7836SJohn.Forte@Sun.COM  * to our module information.
1312*7836SJohn.Forte@Sun.COM  */
1313*7836SJohn.Forte@Sun.COM 
1314*7836SJohn.Forte@Sun.COM static const mdb_dcmd_t dcmds[] = {
1315*7836SJohn.Forte@Sun.COM 	{ "ports", "[-l]", "Leadville port list", ports },
1316*7836SJohn.Forte@Sun.COM 	{ "ulps", NULL, "Leadville ULP list", ulps },
1317*7836SJohn.Forte@Sun.COM 	{ "ulpmods", NULL, "Leadville ULP module list", ulpmods },
1318*7836SJohn.Forte@Sun.COM 	{ "fcport", NULL, "Display a Leadville fc_local_port structure",
1319*7836SJohn.Forte@Sun.COM 	    fcport },
1320*7836SJohn.Forte@Sun.COM 	{ "remote_port", NULL, "Display fc_remote_port structures",
1321*7836SJohn.Forte@Sun.COM 	    remote_port },
1322*7836SJohn.Forte@Sun.COM 	{ "fcptrace", "[-s m][-e n] (m < n)", "Dump the fcp trace buffer, "
1323*7836SJohn.Forte@Sun.COM 	    "optionally supplying starting and ending packet numbers.",
1324*7836SJohn.Forte@Sun.COM 	    fcp_trace_dump, NULL },
1325*7836SJohn.Forte@Sun.COM 	{ "fptrace", "[-s m][-e n] (m < n)", "Dump the fp trace buffer, "
1326*7836SJohn.Forte@Sun.COM 	    "optionally supplying starting and ending packet numbers.",
1327*7836SJohn.Forte@Sun.COM 	    fp_trace_dump, NULL },
1328*7836SJohn.Forte@Sun.COM 	{ NULL }
1329*7836SJohn.Forte@Sun.COM };
1330*7836SJohn.Forte@Sun.COM 
1331*7836SJohn.Forte@Sun.COM static const mdb_walker_t walkers[] = {
1332*7836SJohn.Forte@Sun.COM 	{ "ports", "walk list of Leadville port structures",
1333*7836SJohn.Forte@Sun.COM 	    port_walk_i, port_walk_s, port_walk_f },
1334*7836SJohn.Forte@Sun.COM 	{ "ulps", "walk list of Leadville ULP structures",
1335*7836SJohn.Forte@Sun.COM 	    ulp_walk_i, ulp_walk_s, ulp_walk_f },
1336*7836SJohn.Forte@Sun.COM 	{ "ulpmods", "walk list of Leadville ULP module structures",
1337*7836SJohn.Forte@Sun.COM 	    ulpmod_walk_i, ulpmod_walk_s, ulpmod_walk_f },
1338*7836SJohn.Forte@Sun.COM 	{ "pd_by_pwwn", "walk list of fc_remote_port structures hashed by PWWN",
1339*7836SJohn.Forte@Sun.COM 	    pd_by_pwwn_walk_i, pd_by_pwwn_walk_s, pd_by_pwwn_walk_f },
1340*7836SJohn.Forte@Sun.COM 	{ "pd_by_did", "walk list of fc_remote_port structures hashed by D_ID",
1341*7836SJohn.Forte@Sun.COM 	    pd_by_did_walk_i, pd_by_did_walk_s, pd_by_did_walk_f },
1342*7836SJohn.Forte@Sun.COM 	{ "job_request", "walk list of job_request structures for a local port",
1343*7836SJohn.Forte@Sun.COM 	    job_request_walk_i, job_request_walk_s, job_request_walk_f },
1344*7836SJohn.Forte@Sun.COM 	{ "orphan", "walk list of orphan structures for a local port",
1345*7836SJohn.Forte@Sun.COM 	    orphan_walk_i, orphan_walk_s, orphan_walk_f },
1346*7836SJohn.Forte@Sun.COM 	{ NULL }
1347*7836SJohn.Forte@Sun.COM };
1348*7836SJohn.Forte@Sun.COM 
1349*7836SJohn.Forte@Sun.COM static const mdb_modinfo_t modinfo = {
1350*7836SJohn.Forte@Sun.COM 	MDB_API_VERSION, dcmds, walkers
1351*7836SJohn.Forte@Sun.COM };
1352*7836SJohn.Forte@Sun.COM 
1353*7836SJohn.Forte@Sun.COM const mdb_modinfo_t *
1354*7836SJohn.Forte@Sun.COM _mdb_init(void)
1355*7836SJohn.Forte@Sun.COM {
1356*7836SJohn.Forte@Sun.COM 	return (&modinfo);
1357*7836SJohn.Forte@Sun.COM }
1358