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