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