xref: /titanic_50/usr/src/cmd/mdb/common/modules/fcp/fcp.c (revision fcf3ce441efd61da9bb2884968af01cb7c1452cc)
1*fcf3ce44SJohn Forte /*
2*fcf3ce44SJohn Forte  * CDDL HEADER START
3*fcf3ce44SJohn Forte  *
4*fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5*fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6*fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7*fcf3ce44SJohn Forte  *
8*fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10*fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11*fcf3ce44SJohn Forte  * and limitations under the License.
12*fcf3ce44SJohn Forte  *
13*fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14*fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16*fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17*fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18*fcf3ce44SJohn Forte  *
19*fcf3ce44SJohn Forte  * CDDL HEADER END
20*fcf3ce44SJohn Forte  */
21*fcf3ce44SJohn Forte /*
22*fcf3ce44SJohn Forte  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*fcf3ce44SJohn Forte  * Use is subject to license terms.
24*fcf3ce44SJohn Forte  *
25*fcf3ce44SJohn Forte  * FCP mdb module
26*fcf3ce44SJohn Forte  */
27*fcf3ce44SJohn Forte 
28*fcf3ce44SJohn Forte 
29*fcf3ce44SJohn Forte #include <sys/mdb_modapi.h>
30*fcf3ce44SJohn Forte #include <sys/mutex.h>
31*fcf3ce44SJohn Forte #include <sys/modctl.h>
32*fcf3ce44SJohn Forte #include <sys/scsi/scsi.h>
33*fcf3ce44SJohn Forte #include <sys/sunndi.h>
34*fcf3ce44SJohn Forte #include <sys/fibre-channel/fc.h>
35*fcf3ce44SJohn Forte #include <sys/fibre-channel/ulp/fcpvar.h>
36*fcf3ce44SJohn Forte 
37*fcf3ce44SJohn Forte static struct fcp_port	port;
38*fcf3ce44SJohn Forte static struct fcp_tgt	tgt;
39*fcf3ce44SJohn Forte static struct fcp_lun	lun;
40*fcf3ce44SJohn Forte static uint32_t	tgt_hash_index;
41*fcf3ce44SJohn Forte 
42*fcf3ce44SJohn Forte 
43*fcf3ce44SJohn Forte /*
44*fcf3ce44SJohn Forte  * Leadville fcp walker/dcmd code
45*fcf3ce44SJohn Forte  */
46*fcf3ce44SJohn Forte 
47*fcf3ce44SJohn Forte static int
fcp_walk_i(mdb_walk_state_t * wsp)48*fcf3ce44SJohn Forte fcp_walk_i(mdb_walk_state_t *wsp)
49*fcf3ce44SJohn Forte {
50*fcf3ce44SJohn Forte 	if (wsp->walk_addr == NULL &&
51*fcf3ce44SJohn Forte 	    mdb_readvar(&wsp->walk_addr, "fcp_port_head") == -1) {
52*fcf3ce44SJohn Forte 		mdb_warn("failed to read 'fcp_port_head'");
53*fcf3ce44SJohn Forte 		return (WALK_ERR);
54*fcf3ce44SJohn Forte 	}
55*fcf3ce44SJohn Forte 
56*fcf3ce44SJohn Forte 	wsp->walk_data = mdb_alloc(sizeof (struct fcp_port), UM_SLEEP);
57*fcf3ce44SJohn Forte 	return (WALK_NEXT);
58*fcf3ce44SJohn Forte }
59*fcf3ce44SJohn Forte 
60*fcf3ce44SJohn Forte static int
fcp_walk_s(mdb_walk_state_t * wsp)61*fcf3ce44SJohn Forte fcp_walk_s(mdb_walk_state_t *wsp)
62*fcf3ce44SJohn Forte {
63*fcf3ce44SJohn Forte 	int status;
64*fcf3ce44SJohn Forte 
65*fcf3ce44SJohn Forte 	if (wsp->walk_addr == NULL)
66*fcf3ce44SJohn Forte 		return (WALK_DONE);
67*fcf3ce44SJohn Forte 
68*fcf3ce44SJohn Forte 	if (mdb_vread(wsp->walk_data, sizeof (struct fcp_port),
69*fcf3ce44SJohn Forte 	    wsp->walk_addr) == -1) {
70*fcf3ce44SJohn Forte 		mdb_warn("failed to read fcp_port at %p", wsp->walk_addr);
71*fcf3ce44SJohn Forte 		return (WALK_DONE);
72*fcf3ce44SJohn Forte 	}
73*fcf3ce44SJohn Forte 
74*fcf3ce44SJohn Forte 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
75*fcf3ce44SJohn Forte 	    wsp->walk_cbdata);
76*fcf3ce44SJohn Forte 
77*fcf3ce44SJohn Forte 	wsp->walk_addr =
78*fcf3ce44SJohn Forte 	    (uintptr_t)(((struct fcp_port *)wsp->walk_data)->port_next);
79*fcf3ce44SJohn Forte 
80*fcf3ce44SJohn Forte 	return (status);
81*fcf3ce44SJohn Forte }
82*fcf3ce44SJohn Forte 
83*fcf3ce44SJohn Forte /*
84*fcf3ce44SJohn Forte  * The walker's fini function is invoked at the end of each walk.
85*fcf3ce44SJohn Forte  */
86*fcf3ce44SJohn Forte static void
fcp_walk_f(mdb_walk_state_t * wsp)87*fcf3ce44SJohn Forte fcp_walk_f(mdb_walk_state_t *wsp)
88*fcf3ce44SJohn Forte {
89*fcf3ce44SJohn Forte 	mdb_free(wsp->walk_data, sizeof (struct fcp_port));
90*fcf3ce44SJohn Forte }
91*fcf3ce44SJohn Forte 
92*fcf3ce44SJohn Forte 
93*fcf3ce44SJohn Forte static int
fcp(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)94*fcf3ce44SJohn Forte fcp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
95*fcf3ce44SJohn Forte {
96*fcf3ce44SJohn Forte 	struct fcp_port		pinfo;
97*fcf3ce44SJohn Forte 
98*fcf3ce44SJohn Forte 	if (argc != 0) {
99*fcf3ce44SJohn Forte 		return (DCMD_USAGE);
100*fcf3ce44SJohn Forte 	}
101*fcf3ce44SJohn Forte 
102*fcf3ce44SJohn Forte 	if (!(flags & DCMD_ADDRSPEC)) {
103*fcf3ce44SJohn Forte 		if (mdb_walk_dcmd("fcp", "fcp",
104*fcf3ce44SJohn Forte 		    argc, argv) == -1) {
105*fcf3ce44SJohn Forte 			mdb_warn("failed to walk 'fcp_port_head'");
106*fcf3ce44SJohn Forte 			return (DCMD_ERR);
107*fcf3ce44SJohn Forte 		}
108*fcf3ce44SJohn Forte 		return (DCMD_OK);
109*fcf3ce44SJohn Forte 	}
110*fcf3ce44SJohn Forte 
111*fcf3ce44SJohn Forte 	mdb_printf("FCP structure at %p\n", addr);
112*fcf3ce44SJohn Forte 
113*fcf3ce44SJohn Forte 	/*
114*fcf3ce44SJohn Forte 	 * For each port, we just need to read the fc_fca_port_t struct, read
115*fcf3ce44SJohn Forte 	 * the port_handle
116*fcf3ce44SJohn Forte 	 */
117*fcf3ce44SJohn Forte 	if (mdb_vread(&pinfo, sizeof (struct fcp_port), addr) !=
118*fcf3ce44SJohn Forte 	    sizeof (struct fcp_port)) {
119*fcf3ce44SJohn Forte 		mdb_warn("failed to read fcp_port at %p", addr);
120*fcf3ce44SJohn Forte 		return (DCMD_OK);
121*fcf3ce44SJohn Forte 	}
122*fcf3ce44SJohn Forte 
123*fcf3ce44SJohn Forte 	mdb_printf("  mutex             : 0x%-08x\n", pinfo.port_mutex);
124*fcf3ce44SJohn Forte 	mdb_printf("  ipkt_list         : 0x%p\n", pinfo.port_ipkt_list);
125*fcf3ce44SJohn Forte 	mdb_printf("  state             : 0x%-08x\n", pinfo.port_state);
126*fcf3ce44SJohn Forte 	mdb_printf("  phys_state        : 0x%-08x\n", pinfo.port_phys_state);
127*fcf3ce44SJohn Forte 	mdb_printf("  top               : %u\n", pinfo.port_topology);
128*fcf3ce44SJohn Forte 	mdb_printf("  sid               : 0x%-06x\n", pinfo.port_id);
129*fcf3ce44SJohn Forte 	mdb_printf("  reset_list        : 0x%p\n", pinfo.port_reset_list);
130*fcf3ce44SJohn Forte 	mdb_printf("  link_cnt          : %u\n", pinfo.port_link_cnt);
131*fcf3ce44SJohn Forte 	mdb_printf("  deadline          : %d\n", pinfo.port_deadline);
132*fcf3ce44SJohn Forte 	mdb_printf("  port wwn          : "
133*fcf3ce44SJohn Forte 	    "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
134*fcf3ce44SJohn Forte 	    pinfo.port_pwwn.raw_wwn[0], pinfo.port_pwwn.raw_wwn[1],
135*fcf3ce44SJohn Forte 	    pinfo.port_pwwn.raw_wwn[2], pinfo.port_pwwn.raw_wwn[3],
136*fcf3ce44SJohn Forte 	    pinfo.port_pwwn.raw_wwn[4], pinfo.port_pwwn.raw_wwn[5],
137*fcf3ce44SJohn Forte 	    pinfo.port_pwwn.raw_wwn[6], pinfo.port_pwwn.raw_wwn[7]);
138*fcf3ce44SJohn Forte 	mdb_printf("  node wwn          : "
139*fcf3ce44SJohn Forte 	    "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
140*fcf3ce44SJohn Forte 	    pinfo.port_nwwn.raw_wwn[0], pinfo.port_nwwn.raw_wwn[1],
141*fcf3ce44SJohn Forte 	    pinfo.port_nwwn.raw_wwn[2], pinfo.port_nwwn.raw_wwn[3],
142*fcf3ce44SJohn Forte 	    pinfo.port_nwwn.raw_wwn[4], pinfo.port_nwwn.raw_wwn[5],
143*fcf3ce44SJohn Forte 	    pinfo.port_nwwn.raw_wwn[6], pinfo.port_nwwn.raw_wwn[7]);
144*fcf3ce44SJohn Forte 	mdb_printf("  handle            : 0x%p\n", pinfo.port_fp_handle);
145*fcf3ce44SJohn Forte 	mdb_printf("  cmd_mutex         : 0x%-08x\n", pinfo.port_pkt_mutex);
146*fcf3ce44SJohn Forte 	mdb_printf("  ncmds             : %u\n", pinfo.port_npkts);
147*fcf3ce44SJohn Forte 	mdb_printf("  pkt_head          : 0x%p\n", pinfo.port_pkt_head);
148*fcf3ce44SJohn Forte 	mdb_printf("  pkt_tail          : 0x%p\n", pinfo.port_pkt_tail);
149*fcf3ce44SJohn Forte 	mdb_printf("  ipkt_cnt          : %d\n", pinfo.port_ipkt_cnt);
150*fcf3ce44SJohn Forte 	mdb_printf("  instance          : %u\n", pinfo.port_instance);
151*fcf3ce44SJohn Forte 	mdb_printf("  max_exch          : %u\n", pinfo.port_max_exch);
152*fcf3ce44SJohn Forte 	mdb_printf("  cmds_aborted      : 0x%-08x\n",
153*fcf3ce44SJohn Forte 	    pinfo.port_reset_action);
154*fcf3ce44SJohn Forte 	mdb_printf("  cmds_dma_flags    : 0x%-08x\n",
155*fcf3ce44SJohn Forte 	    pinfo.port_cmds_dma_flags);
156*fcf3ce44SJohn Forte 	mdb_printf("  fcp_dma           : 0x%-08x\n", pinfo.port_fcp_dma);
157*fcf3ce44SJohn Forte 	mdb_printf("  priv_pkt_len      : %u\n", pinfo.port_priv_pkt_len);
158*fcf3ce44SJohn Forte 	mdb_printf("  data_dma_attr     : 0x%-08x\n",
159*fcf3ce44SJohn Forte 	    pinfo.port_data_dma_attr);
160*fcf3ce44SJohn Forte 	mdb_printf("  cmd_dma_attr      : 0x%-08x\n",
161*fcf3ce44SJohn Forte 	    pinfo.port_cmd_dma_attr);
162*fcf3ce44SJohn Forte 	mdb_printf("  resp_dma_attr     : 0x%-08x\n",
163*fcf3ce44SJohn Forte 	    pinfo.port_resp_dma_attr);
164*fcf3ce44SJohn Forte 	mdb_printf("  dma_acc_attr      : 0x%-08x\n",
165*fcf3ce44SJohn Forte 	    pinfo.port_dma_acc_attr);
166*fcf3ce44SJohn Forte 	mdb_printf("  tran              : 0x%p\n", pinfo.port_tran);
167*fcf3ce44SJohn Forte 	mdb_printf("  dip               : 0x%p\n", pinfo.port_dip);
168*fcf3ce44SJohn Forte 	mdb_printf("  reset_notify_listf: 0x%p\n",
169*fcf3ce44SJohn Forte 	    pinfo.port_reset_notify_listf);
170*fcf3ce44SJohn Forte 	mdb_printf("  event_defs        : 0x%p\n", pinfo.port_ndi_event_defs);
171*fcf3ce44SJohn Forte 	mdb_printf("  event_hdl         : 0x%p\n", pinfo.port_ndi_event_hdl);
172*fcf3ce44SJohn Forte 	mdb_printf("  events            : 0x%p\n", pinfo.port_ndi_events);
173*fcf3ce44SJohn Forte 	mdb_printf("  tgt_hash_table    : 0x%p\n", pinfo.port_tgt_hash_table);
174*fcf3ce44SJohn Forte 	mdb_printf("  mpxio             : %d\n", pinfo.port_mpxio);
175*fcf3ce44SJohn Forte 
176*fcf3ce44SJohn Forte 	mdb_printf("\n");
177*fcf3ce44SJohn Forte 
178*fcf3ce44SJohn Forte 	return (DCMD_OK);
179*fcf3ce44SJohn Forte }
180*fcf3ce44SJohn Forte 
181*fcf3ce44SJohn Forte 
182*fcf3ce44SJohn Forte /*
183*fcf3ce44SJohn Forte  * Leadville cmds walker/dcmd code
184*fcf3ce44SJohn Forte  */
185*fcf3ce44SJohn Forte 
186*fcf3ce44SJohn Forte static int
cmds_walk_i(mdb_walk_state_t * wsp)187*fcf3ce44SJohn Forte cmds_walk_i(mdb_walk_state_t *wsp)
188*fcf3ce44SJohn Forte {
189*fcf3ce44SJohn Forte 	if (wsp->walk_addr == NULL) {
190*fcf3ce44SJohn Forte 		mdb_warn("Can not perform global walk");
191*fcf3ce44SJohn Forte 		return (WALK_ERR);
192*fcf3ce44SJohn Forte 	}
193*fcf3ce44SJohn Forte 
194*fcf3ce44SJohn Forte 	/*
195*fcf3ce44SJohn Forte 	 * Input should be a fcp_lun, so read it to get the fcp_pkt
196*fcf3ce44SJohn Forte 	 * lists's head
197*fcf3ce44SJohn Forte 	 */
198*fcf3ce44SJohn Forte 
199*fcf3ce44SJohn Forte 	if (mdb_vread(&lun, sizeof (struct fcp_lun), wsp->walk_addr) !=
200*fcf3ce44SJohn Forte 	    sizeof (struct fcp_lun)) {
201*fcf3ce44SJohn Forte 		mdb_warn("Unable to read in the fcp_lun structure address\n");
202*fcf3ce44SJohn Forte 		return (WALK_ERR);
203*fcf3ce44SJohn Forte 	}
204*fcf3ce44SJohn Forte 
205*fcf3ce44SJohn Forte 	wsp->walk_addr = (uintptr_t)(lun.lun_pkt_head);
206*fcf3ce44SJohn Forte 	wsp->walk_data = mdb_alloc(sizeof (struct fcp_pkt), UM_SLEEP);
207*fcf3ce44SJohn Forte 
208*fcf3ce44SJohn Forte 	return (WALK_NEXT);
209*fcf3ce44SJohn Forte }
210*fcf3ce44SJohn Forte 
211*fcf3ce44SJohn Forte static int
cmds_walk_s(mdb_walk_state_t * wsp)212*fcf3ce44SJohn Forte cmds_walk_s(mdb_walk_state_t *wsp)
213*fcf3ce44SJohn Forte {
214*fcf3ce44SJohn Forte 	int status;
215*fcf3ce44SJohn Forte 
216*fcf3ce44SJohn Forte 	if (wsp->walk_addr == NULL)
217*fcf3ce44SJohn Forte 		return (WALK_DONE);
218*fcf3ce44SJohn Forte 
219*fcf3ce44SJohn Forte 	if (mdb_vread(wsp->walk_data, sizeof (struct fcp_pkt),
220*fcf3ce44SJohn Forte 	    wsp->walk_addr) == -1) {
221*fcf3ce44SJohn Forte 		mdb_warn("failed to read fcp_pkt at %p", wsp->walk_addr);
222*fcf3ce44SJohn Forte 		return (WALK_DONE);
223*fcf3ce44SJohn Forte 	}
224*fcf3ce44SJohn Forte 
225*fcf3ce44SJohn Forte 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
226*fcf3ce44SJohn Forte 	    wsp->walk_cbdata);
227*fcf3ce44SJohn Forte 
228*fcf3ce44SJohn Forte 	wsp->walk_addr =
229*fcf3ce44SJohn Forte 	    (uintptr_t)(((struct fcp_pkt *)wsp->walk_data)->cmd_forw);
230*fcf3ce44SJohn Forte 
231*fcf3ce44SJohn Forte 	return (status);
232*fcf3ce44SJohn Forte }
233*fcf3ce44SJohn Forte 
234*fcf3ce44SJohn Forte /*
235*fcf3ce44SJohn Forte  * The walker's fini function is invoked at the end of each walk.
236*fcf3ce44SJohn Forte  */
237*fcf3ce44SJohn Forte static void
cmds_walk_f(mdb_walk_state_t * wsp)238*fcf3ce44SJohn Forte cmds_walk_f(mdb_walk_state_t *wsp)
239*fcf3ce44SJohn Forte {
240*fcf3ce44SJohn Forte 	mdb_free(wsp->walk_data, sizeof (struct fcp_pkt));
241*fcf3ce44SJohn Forte }
242*fcf3ce44SJohn Forte 
243*fcf3ce44SJohn Forte 
244*fcf3ce44SJohn Forte /*
245*fcf3ce44SJohn Forte  * Leadville luns walker/dcmd code
246*fcf3ce44SJohn Forte  */
247*fcf3ce44SJohn Forte 
248*fcf3ce44SJohn Forte static int
luns_walk_i(mdb_walk_state_t * wsp)249*fcf3ce44SJohn Forte luns_walk_i(mdb_walk_state_t *wsp)
250*fcf3ce44SJohn Forte {
251*fcf3ce44SJohn Forte 	if (wsp->walk_addr == NULL) {
252*fcf3ce44SJohn Forte 		mdb_warn("Can not perform global walk");
253*fcf3ce44SJohn Forte 		return (WALK_ERR);
254*fcf3ce44SJohn Forte 	}
255*fcf3ce44SJohn Forte 
256*fcf3ce44SJohn Forte 	/*
257*fcf3ce44SJohn Forte 	 * Input should be a fcp_tgt, so read it to get the fcp_lun
258*fcf3ce44SJohn Forte 	 * lists's head
259*fcf3ce44SJohn Forte 	 */
260*fcf3ce44SJohn Forte 
261*fcf3ce44SJohn Forte 	if (mdb_vread(&tgt, sizeof (struct fcp_tgt), wsp->walk_addr) !=
262*fcf3ce44SJohn Forte 	    sizeof (struct fcp_tgt)) {
263*fcf3ce44SJohn Forte 		mdb_warn("Unable to read in the fcp_tgt structure address\n");
264*fcf3ce44SJohn Forte 		return (WALK_ERR);
265*fcf3ce44SJohn Forte 	}
266*fcf3ce44SJohn Forte 
267*fcf3ce44SJohn Forte 	wsp->walk_addr = (uintptr_t)(tgt.tgt_lun);
268*fcf3ce44SJohn Forte 	wsp->walk_data = mdb_alloc(sizeof (struct fcp_lun), UM_SLEEP);
269*fcf3ce44SJohn Forte 
270*fcf3ce44SJohn Forte 	return (WALK_NEXT);
271*fcf3ce44SJohn Forte }
272*fcf3ce44SJohn Forte 
273*fcf3ce44SJohn Forte static int
luns_walk_s(mdb_walk_state_t * wsp)274*fcf3ce44SJohn Forte luns_walk_s(mdb_walk_state_t *wsp)
275*fcf3ce44SJohn Forte {
276*fcf3ce44SJohn Forte 	int status;
277*fcf3ce44SJohn Forte 
278*fcf3ce44SJohn Forte 	if (wsp->walk_addr == NULL)
279*fcf3ce44SJohn Forte 		return (WALK_DONE);
280*fcf3ce44SJohn Forte 
281*fcf3ce44SJohn Forte 	if (mdb_vread(wsp->walk_data, sizeof (struct fcp_lun),
282*fcf3ce44SJohn Forte 	    wsp->walk_addr) == -1) {
283*fcf3ce44SJohn Forte 		mdb_warn("failed to read fcp_pkt at %p", wsp->walk_addr);
284*fcf3ce44SJohn Forte 		return (WALK_DONE);
285*fcf3ce44SJohn Forte 	}
286*fcf3ce44SJohn Forte 
287*fcf3ce44SJohn Forte 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
288*fcf3ce44SJohn Forte 	    wsp->walk_cbdata);
289*fcf3ce44SJohn Forte 
290*fcf3ce44SJohn Forte 	wsp->walk_addr =
291*fcf3ce44SJohn Forte 	    (uintptr_t)(((struct fcp_lun *)wsp->walk_data)->lun_next);
292*fcf3ce44SJohn Forte 
293*fcf3ce44SJohn Forte 	return (status);
294*fcf3ce44SJohn Forte }
295*fcf3ce44SJohn Forte 
296*fcf3ce44SJohn Forte /*
297*fcf3ce44SJohn Forte  * The walker's fini function is invoked at the end of each walk.
298*fcf3ce44SJohn Forte  */
299*fcf3ce44SJohn Forte static void
luns_walk_f(mdb_walk_state_t * wsp)300*fcf3ce44SJohn Forte luns_walk_f(mdb_walk_state_t *wsp)
301*fcf3ce44SJohn Forte {
302*fcf3ce44SJohn Forte 	mdb_free(wsp->walk_data, sizeof (struct fcp_lun));
303*fcf3ce44SJohn Forte }
304*fcf3ce44SJohn Forte 
305*fcf3ce44SJohn Forte 
306*fcf3ce44SJohn Forte /*
307*fcf3ce44SJohn Forte  * Leadville targets walker/dcmd code
308*fcf3ce44SJohn Forte  */
309*fcf3ce44SJohn Forte 
310*fcf3ce44SJohn Forte static int
targets_walk_i(mdb_walk_state_t * wsp)311*fcf3ce44SJohn Forte targets_walk_i(mdb_walk_state_t *wsp)
312*fcf3ce44SJohn Forte {
313*fcf3ce44SJohn Forte 	if (wsp->walk_addr == NULL) {
314*fcf3ce44SJohn Forte 		mdb_warn("Can not perform global walk\n");
315*fcf3ce44SJohn Forte 		return (WALK_ERR);
316*fcf3ce44SJohn Forte 	}
317*fcf3ce44SJohn Forte 
318*fcf3ce44SJohn Forte 	/*
319*fcf3ce44SJohn Forte 	 * Input should be a fcp_port, so read it to get the port_tgt
320*fcf3ce44SJohn Forte 	 * table's head
321*fcf3ce44SJohn Forte 	 */
322*fcf3ce44SJohn Forte 
323*fcf3ce44SJohn Forte 	if (mdb_vread(&port, sizeof (struct fcp_port), wsp->walk_addr) !=
324*fcf3ce44SJohn Forte 	    sizeof (struct fcp_port)) {
325*fcf3ce44SJohn Forte 		mdb_warn("Unable to read in the port structure address\n");
326*fcf3ce44SJohn Forte 		return (WALK_ERR);
327*fcf3ce44SJohn Forte 	}
328*fcf3ce44SJohn Forte 
329*fcf3ce44SJohn Forte 	tgt_hash_index = 0;
330*fcf3ce44SJohn Forte 
331*fcf3ce44SJohn Forte 	while ((port.port_tgt_hash_table[tgt_hash_index] == NULL) &&
332*fcf3ce44SJohn Forte 	    (tgt_hash_index < FCP_NUM_HASH)) {
333*fcf3ce44SJohn Forte 		tgt_hash_index++;
334*fcf3ce44SJohn Forte 	}
335*fcf3ce44SJohn Forte 
336*fcf3ce44SJohn Forte 	wsp->walk_addr = (uintptr_t)(port.port_tgt_hash_table[tgt_hash_index]);
337*fcf3ce44SJohn Forte 
338*fcf3ce44SJohn Forte 	wsp->walk_data = mdb_alloc(sizeof (struct fcp_tgt), UM_SLEEP);
339*fcf3ce44SJohn Forte 
340*fcf3ce44SJohn Forte 	return (WALK_NEXT);
341*fcf3ce44SJohn Forte }
342*fcf3ce44SJohn Forte 
343*fcf3ce44SJohn Forte static int
targets_walk_s(mdb_walk_state_t * wsp)344*fcf3ce44SJohn Forte targets_walk_s(mdb_walk_state_t *wsp)
345*fcf3ce44SJohn Forte {
346*fcf3ce44SJohn Forte 	int status;
347*fcf3ce44SJohn Forte 
348*fcf3ce44SJohn Forte 	if ((wsp->walk_addr == NULL) &&
349*fcf3ce44SJohn Forte 	    (tgt_hash_index >= (FCP_NUM_HASH - 1))) {
350*fcf3ce44SJohn Forte 		return (WALK_DONE);
351*fcf3ce44SJohn Forte 	}
352*fcf3ce44SJohn Forte 
353*fcf3ce44SJohn Forte 	if (mdb_vread(wsp->walk_data, sizeof (struct fcp_tgt),
354*fcf3ce44SJohn Forte 	    wsp->walk_addr) == -1) {
355*fcf3ce44SJohn Forte 		mdb_warn("failed to read fcp_tgt at %p", wsp->walk_addr);
356*fcf3ce44SJohn Forte 		return (WALK_DONE);
357*fcf3ce44SJohn Forte 	}
358*fcf3ce44SJohn Forte 
359*fcf3ce44SJohn Forte 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
360*fcf3ce44SJohn Forte 	    wsp->walk_cbdata);
361*fcf3ce44SJohn Forte 
362*fcf3ce44SJohn Forte 	wsp->walk_addr =
363*fcf3ce44SJohn Forte 	    (uintptr_t)(((struct fcp_tgt *)wsp->walk_data)->tgt_next);
364*fcf3ce44SJohn Forte 
365*fcf3ce44SJohn Forte 	if (wsp->walk_addr == NULL) {
366*fcf3ce44SJohn Forte 		/*
367*fcf3ce44SJohn Forte 		 * locate the next hash list
368*fcf3ce44SJohn Forte 		 */
369*fcf3ce44SJohn Forte 
370*fcf3ce44SJohn Forte 		tgt_hash_index++;
371*fcf3ce44SJohn Forte 
372*fcf3ce44SJohn Forte 		while ((port.port_tgt_hash_table[tgt_hash_index] == NULL) &&
373*fcf3ce44SJohn Forte 		    (tgt_hash_index < FCP_NUM_HASH)) {
374*fcf3ce44SJohn Forte 			tgt_hash_index++;
375*fcf3ce44SJohn Forte 		}
376*fcf3ce44SJohn Forte 
377*fcf3ce44SJohn Forte 		if (tgt_hash_index == FCP_NUM_HASH) {
378*fcf3ce44SJohn Forte 			/* You're done */
379*fcf3ce44SJohn Forte 			return (status);
380*fcf3ce44SJohn Forte 		}
381*fcf3ce44SJohn Forte 
382*fcf3ce44SJohn Forte 		wsp->walk_addr =
383*fcf3ce44SJohn Forte 		    (uintptr_t)(port.port_tgt_hash_table[tgt_hash_index]);
384*fcf3ce44SJohn Forte 	}
385*fcf3ce44SJohn Forte 
386*fcf3ce44SJohn Forte 	return (status);
387*fcf3ce44SJohn Forte }
388*fcf3ce44SJohn Forte 
389*fcf3ce44SJohn Forte /*
390*fcf3ce44SJohn Forte  * The walker's fini function is invoked at the end of each walk.
391*fcf3ce44SJohn Forte  */
392*fcf3ce44SJohn Forte static void
targets_walk_f(mdb_walk_state_t * wsp)393*fcf3ce44SJohn Forte targets_walk_f(mdb_walk_state_t *wsp)
394*fcf3ce44SJohn Forte {
395*fcf3ce44SJohn Forte 	mdb_free(wsp->walk_data, sizeof (struct fcp_tgt));
396*fcf3ce44SJohn Forte }
397*fcf3ce44SJohn Forte 
398*fcf3ce44SJohn Forte 
399*fcf3ce44SJohn Forte /*
400*fcf3ce44SJohn Forte  * Leadville fcp_ipkt walker/dcmd code
401*fcf3ce44SJohn Forte  */
402*fcf3ce44SJohn Forte 
403*fcf3ce44SJohn Forte static int
ipkt_walk_i(mdb_walk_state_t * wsp)404*fcf3ce44SJohn Forte ipkt_walk_i(mdb_walk_state_t *wsp)
405*fcf3ce44SJohn Forte {
406*fcf3ce44SJohn Forte 	if (wsp->walk_addr == NULL) {
407*fcf3ce44SJohn Forte 		mdb_warn("The address of a fcp_port"
408*fcf3ce44SJohn Forte 		    " structure must be given\n");
409*fcf3ce44SJohn Forte 		return (WALK_ERR);
410*fcf3ce44SJohn Forte 	}
411*fcf3ce44SJohn Forte 
412*fcf3ce44SJohn Forte 	/*
413*fcf3ce44SJohn Forte 	 * Input should be a fcp_port, so read it to get the ipkt
414*fcf3ce44SJohn Forte 	 * list's head
415*fcf3ce44SJohn Forte 	 */
416*fcf3ce44SJohn Forte 
417*fcf3ce44SJohn Forte 	if (mdb_vread(&port, sizeof (struct fcp_port), wsp->walk_addr) !=
418*fcf3ce44SJohn Forte 	    sizeof (struct fcp_port)) {
419*fcf3ce44SJohn Forte 		mdb_warn("Failed to read in the fcp_port"
420*fcf3ce44SJohn Forte 		    " at 0x%p\n", wsp->walk_addr);
421*fcf3ce44SJohn Forte 		return (WALK_ERR);
422*fcf3ce44SJohn Forte 	}
423*fcf3ce44SJohn Forte 
424*fcf3ce44SJohn Forte 	wsp->walk_addr = (uintptr_t)(port.port_ipkt_list);
425*fcf3ce44SJohn Forte 	wsp->walk_data = mdb_alloc(sizeof (struct fcp_ipkt), UM_SLEEP);
426*fcf3ce44SJohn Forte 
427*fcf3ce44SJohn Forte 	return (WALK_NEXT);
428*fcf3ce44SJohn Forte }
429*fcf3ce44SJohn Forte 
430*fcf3ce44SJohn Forte static int
ipkt_walk_s(mdb_walk_state_t * wsp)431*fcf3ce44SJohn Forte ipkt_walk_s(mdb_walk_state_t *wsp)
432*fcf3ce44SJohn Forte {
433*fcf3ce44SJohn Forte 	int status;
434*fcf3ce44SJohn Forte 
435*fcf3ce44SJohn Forte 	if (wsp->walk_addr == NULL)
436*fcf3ce44SJohn Forte 		return (WALK_DONE);
437*fcf3ce44SJohn Forte 
438*fcf3ce44SJohn Forte 	if (mdb_vread(wsp->walk_data, sizeof (struct fcp_ipkt),
439*fcf3ce44SJohn Forte 	    wsp->walk_addr) == -1) {
440*fcf3ce44SJohn Forte 		mdb_warn("Failed to read in the fcp_ipkt"
441*fcf3ce44SJohn Forte 		    " at 0x%p\n", wsp->walk_addr);
442*fcf3ce44SJohn Forte 		return (WALK_DONE);
443*fcf3ce44SJohn Forte 	}
444*fcf3ce44SJohn Forte 
445*fcf3ce44SJohn Forte 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
446*fcf3ce44SJohn Forte 	    wsp->walk_cbdata);
447*fcf3ce44SJohn Forte 
448*fcf3ce44SJohn Forte 	wsp->walk_addr =
449*fcf3ce44SJohn Forte 	    (uintptr_t)(((struct fcp_ipkt *)wsp->walk_data)->ipkt_next);
450*fcf3ce44SJohn Forte 
451*fcf3ce44SJohn Forte 	return (status);
452*fcf3ce44SJohn Forte }
453*fcf3ce44SJohn Forte 
454*fcf3ce44SJohn Forte /*
455*fcf3ce44SJohn Forte  * The walker's fini function is invoked at the end of each walk.
456*fcf3ce44SJohn Forte  */
457*fcf3ce44SJohn Forte static void
ipkt_walk_f(mdb_walk_state_t * wsp)458*fcf3ce44SJohn Forte ipkt_walk_f(mdb_walk_state_t *wsp)
459*fcf3ce44SJohn Forte {
460*fcf3ce44SJohn Forte 	mdb_free(wsp->walk_data, sizeof (struct fcp_ipkt));
461*fcf3ce44SJohn Forte }
462*fcf3ce44SJohn Forte 
463*fcf3ce44SJohn Forte /*
464*fcf3ce44SJohn Forte  * Leadville fcp_pkt walker/dcmd code
465*fcf3ce44SJohn Forte  */
466*fcf3ce44SJohn Forte 
467*fcf3ce44SJohn Forte static int
pkt_walk_i(mdb_walk_state_t * wsp)468*fcf3ce44SJohn Forte pkt_walk_i(mdb_walk_state_t *wsp)
469*fcf3ce44SJohn Forte {
470*fcf3ce44SJohn Forte 	if (wsp->walk_addr == NULL) {
471*fcf3ce44SJohn Forte 		mdb_warn("The address of a fcp_port"
472*fcf3ce44SJohn Forte 		    " structure must be given\n");
473*fcf3ce44SJohn Forte 		return (WALK_ERR);
474*fcf3ce44SJohn Forte 	}
475*fcf3ce44SJohn Forte 
476*fcf3ce44SJohn Forte 	/*
477*fcf3ce44SJohn Forte 	 * Input should be an fcp_port, so read it to get the pkt
478*fcf3ce44SJohn Forte 	 * list's head
479*fcf3ce44SJohn Forte 	 */
480*fcf3ce44SJohn Forte 
481*fcf3ce44SJohn Forte 	if (mdb_vread(&port, sizeof (struct fcp_port), wsp->walk_addr) !=
482*fcf3ce44SJohn Forte 	    sizeof (struct fcp_port)) {
483*fcf3ce44SJohn Forte 		mdb_warn("Failed to read in the fcp_port"
484*fcf3ce44SJohn Forte 		    " at 0x%p\n", wsp->walk_addr);
485*fcf3ce44SJohn Forte 		return (WALK_ERR);
486*fcf3ce44SJohn Forte 	}
487*fcf3ce44SJohn Forte 
488*fcf3ce44SJohn Forte 	wsp->walk_addr = (uintptr_t)(port.port_pkt_head);
489*fcf3ce44SJohn Forte 	wsp->walk_data = mdb_alloc(sizeof (struct fcp_pkt), UM_SLEEP);
490*fcf3ce44SJohn Forte 
491*fcf3ce44SJohn Forte 	return (WALK_NEXT);
492*fcf3ce44SJohn Forte }
493*fcf3ce44SJohn Forte 
494*fcf3ce44SJohn Forte static int
pkt_walk_s(mdb_walk_state_t * wsp)495*fcf3ce44SJohn Forte pkt_walk_s(mdb_walk_state_t *wsp)
496*fcf3ce44SJohn Forte {
497*fcf3ce44SJohn Forte 	int status;
498*fcf3ce44SJohn Forte 
499*fcf3ce44SJohn Forte 	if (wsp->walk_addr == NULL)
500*fcf3ce44SJohn Forte 		return (WALK_DONE);
501*fcf3ce44SJohn Forte 
502*fcf3ce44SJohn Forte 	if (mdb_vread(wsp->walk_data, sizeof (struct fcp_pkt),
503*fcf3ce44SJohn Forte 	    wsp->walk_addr) == -1) {
504*fcf3ce44SJohn Forte 		mdb_warn("Failed to read in the fcp_pkt"
505*fcf3ce44SJohn Forte 		    " at 0x%p\n", wsp->walk_addr);
506*fcf3ce44SJohn Forte 		return (WALK_DONE);
507*fcf3ce44SJohn Forte 	}
508*fcf3ce44SJohn Forte 
509*fcf3ce44SJohn Forte 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
510*fcf3ce44SJohn Forte 	    wsp->walk_cbdata);
511*fcf3ce44SJohn Forte 
512*fcf3ce44SJohn Forte 	wsp->walk_addr =
513*fcf3ce44SJohn Forte 	    (uintptr_t)(((struct fcp_pkt *)wsp->walk_data)->cmd_next);
514*fcf3ce44SJohn Forte 
515*fcf3ce44SJohn Forte 	return (status);
516*fcf3ce44SJohn Forte }
517*fcf3ce44SJohn Forte 
518*fcf3ce44SJohn Forte /*
519*fcf3ce44SJohn Forte  * The walker's fini function is invoked at the end of each walk.
520*fcf3ce44SJohn Forte  */
521*fcf3ce44SJohn Forte static void
pkt_walk_f(mdb_walk_state_t * wsp)522*fcf3ce44SJohn Forte pkt_walk_f(mdb_walk_state_t *wsp)
523*fcf3ce44SJohn Forte {
524*fcf3ce44SJohn Forte 	mdb_free(wsp->walk_data, sizeof (struct fcp_pkt));
525*fcf3ce44SJohn Forte }
526*fcf3ce44SJohn Forte 
527*fcf3ce44SJohn Forte /*
528*fcf3ce44SJohn Forte  * MDB module linkage information:
529*fcf3ce44SJohn Forte  *
530*fcf3ce44SJohn Forte  * We declare a list of structures describing our dcmds, a list of structures
531*fcf3ce44SJohn Forte  * describing our walkers, and a function named _mdb_init to return a pointer
532*fcf3ce44SJohn Forte  * to our module information.
533*fcf3ce44SJohn Forte  */
534*fcf3ce44SJohn Forte 
535*fcf3ce44SJohn Forte static const mdb_dcmd_t dcmds[] = {
536*fcf3ce44SJohn Forte 	{ "fcp", NULL, "Leadville fcp instances", fcp },
537*fcf3ce44SJohn Forte 	{ NULL }
538*fcf3ce44SJohn Forte };
539*fcf3ce44SJohn Forte 
540*fcf3ce44SJohn Forte static const mdb_walker_t walkers[] = {
541*fcf3ce44SJohn Forte 	{ "fcp", "Walk list of Leadville fcp instances",
542*fcf3ce44SJohn Forte 		fcp_walk_i, fcp_walk_s, fcp_walk_f },
543*fcf3ce44SJohn Forte 	{ "cmds", "Walk list of SCSI commands in fcp's per-lun queue",
544*fcf3ce44SJohn Forte 		cmds_walk_i, cmds_walk_s, cmds_walk_f },
545*fcf3ce44SJohn Forte 	{ "luns", "Walk list of LUNs in an fcp target",
546*fcf3ce44SJohn Forte 		luns_walk_i, luns_walk_s, luns_walk_f },
547*fcf3ce44SJohn Forte 	{ "targets", "Walk list of fcp targets attached to the local port",
548*fcf3ce44SJohn Forte 		targets_walk_i, targets_walk_s, targets_walk_f },
549*fcf3ce44SJohn Forte 	{ "fcp_ipkt", "Walk list of internal packets queued on a local port",
550*fcf3ce44SJohn Forte 		ipkt_walk_i, ipkt_walk_s, ipkt_walk_f},
551*fcf3ce44SJohn Forte 	{ "fcp_pkt", "Walk list of packets queued on a local port",
552*fcf3ce44SJohn Forte 		pkt_walk_i, pkt_walk_s, pkt_walk_f},
553*fcf3ce44SJohn Forte 	{ NULL }
554*fcf3ce44SJohn Forte };
555*fcf3ce44SJohn Forte 
556*fcf3ce44SJohn Forte static const mdb_modinfo_t modinfo = {
557*fcf3ce44SJohn Forte 	MDB_API_VERSION, dcmds, walkers
558*fcf3ce44SJohn Forte };
559*fcf3ce44SJohn Forte 
560*fcf3ce44SJohn Forte const mdb_modinfo_t *
_mdb_init(void)561*fcf3ce44SJohn Forte _mdb_init(void)
562*fcf3ce44SJohn Forte {
563*fcf3ce44SJohn Forte 	return (&modinfo);
564*fcf3ce44SJohn Forte }
565