xref: /illumos-gate/usr/src/cmd/mdb/common/modules/idm/idm.c (revision 5f7d09c6)
1a6d42e7dSPeter Dunlap /*
2a6d42e7dSPeter Dunlap  * CDDL HEADER START
3a6d42e7dSPeter Dunlap  *
4a6d42e7dSPeter Dunlap  * The contents of this file are subject to the terms of the
5a6d42e7dSPeter Dunlap  * Common Development and Distribution License (the "License").
6a6d42e7dSPeter Dunlap  * You may not use this file except in compliance with the License.
7a6d42e7dSPeter Dunlap  *
8a6d42e7dSPeter Dunlap  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9a6d42e7dSPeter Dunlap  * or http://www.opensolaris.org/os/licensing.
10a6d42e7dSPeter Dunlap  * See the License for the specific language governing permissions
11a6d42e7dSPeter Dunlap  * and limitations under the License.
12a6d42e7dSPeter Dunlap  *
13a6d42e7dSPeter Dunlap  * When distributing Covered Code, include this CDDL HEADER in each
14a6d42e7dSPeter Dunlap  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15a6d42e7dSPeter Dunlap  * If applicable, add the following below this CDDL HEADER, with the
16a6d42e7dSPeter Dunlap  * fields enclosed by brackets "[]" replaced with your own identifying
17a6d42e7dSPeter Dunlap  * information: Portions Copyright [yyyy] [name of copyright owner]
18a6d42e7dSPeter Dunlap  *
19a6d42e7dSPeter Dunlap  * CDDL HEADER END
20a6d42e7dSPeter Dunlap  */
21a6d42e7dSPeter Dunlap /*
2230e7468fSPeter Dunlap  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23a6d42e7dSPeter Dunlap  * Use is subject to license terms.
24a6d42e7dSPeter Dunlap  */
25a6d42e7dSPeter Dunlap 
26a6d42e7dSPeter Dunlap #include <sys/mdb_modapi.h>
27a6d42e7dSPeter Dunlap #include <sys/cpuvar.h>
28a6d42e7dSPeter Dunlap #include <sys/conf.h>
29a6d42e7dSPeter Dunlap #include <sys/file.h>
30a6d42e7dSPeter Dunlap #include <sys/types.h>
31a6d42e7dSPeter Dunlap #include <sys/taskq.h>
32a6d42e7dSPeter Dunlap #include <sys/sysmacros.h>
33a6d42e7dSPeter Dunlap #include <sys/socket.h>		/* networking stuff */
34a6d42e7dSPeter Dunlap #include <sys/strsubr.h>	/* networking stuff */
35a6d42e7dSPeter Dunlap #include <sys/nvpair.h>
36a6d42e7dSPeter Dunlap #include <sys/sunldi.h>
37a6d42e7dSPeter Dunlap #include <sys/stmf.h>
38a6d42e7dSPeter Dunlap #include <sys/stmf_ioctl.h>
39a6d42e7dSPeter Dunlap #include <sys/portif.h>
40a6d42e7dSPeter Dunlap 
41a6d42e7dSPeter Dunlap #define	IDM_CONN_SM_STRINGS
42bf604c64SPeter Dunlap #define	IDM_TASK_SM_STRINGS
43a6d42e7dSPeter Dunlap #define	ISCSIT_TGT_SM_STRINGS
44a6d42e7dSPeter Dunlap #define	ISCSIT_SESS_SM_STRINGS
45a6d42e7dSPeter Dunlap #define	ISCSIT_LOGIN_SM_STRINGS
4630e7468fSPeter Dunlap #define	ISCSI_SESS_SM_STRINGS
4730e7468fSPeter Dunlap #define	ISCSI_CMD_SM_STRINGS
4830e7468fSPeter Dunlap #define	ISCSI_ICS_NAMES
4930e7468fSPeter Dunlap #define	ISCSI_LOGIN_STATE_NAMES
50*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States #define	IDM_CN_NOTIFY_STRINGS
51a6d42e7dSPeter Dunlap #include <sys/idm/idm.h>
52aff4bce5Syi zhang - Sun Microsystems - Beijing China #include <iscsi.h>
53a6d42e7dSPeter Dunlap #include <iscsit.h>
54a6d42e7dSPeter Dunlap #include <iscsit_isns.h>
55a6d42e7dSPeter Dunlap 
56a6d42e7dSPeter Dunlap /*
57a6d42e7dSPeter Dunlap  * We want to be able to print multiple levels of object hierarchy with a
58a6d42e7dSPeter Dunlap  * single dcmd information, and preferably also exclude intermediate
59a6d42e7dSPeter Dunlap  * levels if desired.  For example some of the target objects have the
60a6d42e7dSPeter Dunlap  * following relationship:
61a6d42e7dSPeter Dunlap  *
62a6d42e7dSPeter Dunlap  * target --> session --> connection --> task
63a6d42e7dSPeter Dunlap  *
64a6d42e7dSPeter Dunlap  * The session dcmd should allow the printing of all associated tasks for the
65a6d42e7dSPeter Dunlap  * sessions without printing all the associated connections.  To accomplish
66a6d42e7dSPeter Dunlap  * this the following structure contains a bit for each object type.  Dcmds
67a6d42e7dSPeter Dunlap  * should invoked the functions for child objects if any bits are set
68a6d42e7dSPeter Dunlap  * in iscsi_dcmd_ctrl_t but the functions for the child object should only
69a6d42e7dSPeter Dunlap  * print data if their associated bit is set.
70a6d42e7dSPeter Dunlap  *
71a6d42e7dSPeter Dunlap  * Each dcmd should provide an external interface with the standard MDB API
72a6d42e7dSPeter Dunlap  * and an internal interface that accepts iscsi_dcmd_ctrl_t.  To display
73a6d42e7dSPeter Dunlap  * child objects the dcmd calls the internal interface for the child object
74a6d42e7dSPeter Dunlap  * directly.  Dcmds invoked from the command line will, of course, call the
75a6d42e7dSPeter Dunlap  * external interface.  See iscsi_conn() and iscsi_conn_impl().
76a6d42e7dSPeter Dunlap  */
77a6d42e7dSPeter Dunlap 
78a6d42e7dSPeter Dunlap typedef struct {
79a6d42e7dSPeter Dunlap 	union	{
80a6d42e7dSPeter Dunlap 		uint32_t	idc_children;
81a6d42e7dSPeter Dunlap 		struct {
82a6d42e7dSPeter Dunlap 			uint32_t	idc_tgt:1,
83a6d42e7dSPeter Dunlap 					idc_tpgt:1,
84a6d42e7dSPeter Dunlap 					idc_portal:1,
85a6d42e7dSPeter Dunlap 					idc_sess:1,
86a6d42e7dSPeter Dunlap 					idc_conn:1,
87a6d42e7dSPeter Dunlap 					idc_print_ip:1,
88a6d42e7dSPeter Dunlap 					idc_task:1,
89a6d42e7dSPeter Dunlap 					idc_buffer:1,
90a6d42e7dSPeter Dunlap 					idc_states:1,
91a6d42e7dSPeter Dunlap 					idc_rc_audit:1,
92a6d42e7dSPeter Dunlap 					idc_lun:1,
93a6d42e7dSPeter Dunlap 					idc_hba:1;
94a6d42e7dSPeter Dunlap 		} child;
95a6d42e7dSPeter Dunlap 	} u;
96a6d42e7dSPeter Dunlap 	boolean_t		idc_ini;
97a6d42e7dSPeter Dunlap 	boolean_t		idc_tgt;
98a6d42e7dSPeter Dunlap 	boolean_t		idc_verbose;
99a6d42e7dSPeter Dunlap 	boolean_t		idc_header;
100a6d42e7dSPeter Dunlap 	/*
101a6d42e7dSPeter Dunlap 	 * Our connection dcmd code works off the global connection lists
102a6d42e7dSPeter Dunlap 	 * in IDM since we want to know about connections even when they
103a6d42e7dSPeter Dunlap 	 * have not progressed to the point that they have an associated
104a6d42e7dSPeter Dunlap 	 * session.  If we use "::iscsi_sess [-c]" then we only want to
105a6d42e7dSPeter Dunlap 	 * see connections associated with particular session.  To avoid
106a6d42e7dSPeter Dunlap 	 * writing a separate set of code to print session-specific connection
107a6d42e7dSPeter Dunlap 	 * the session code should set the sessions kernel address in the
108a6d42e7dSPeter Dunlap 	 * following field.  The connection code will then only print
109a6d42e7dSPeter Dunlap 	 * connections that match.
110a6d42e7dSPeter Dunlap 	 */
111a6d42e7dSPeter Dunlap 	uintptr_t		idc_assoc_session;
112a6d42e7dSPeter Dunlap } iscsi_dcmd_ctrl_t;
113a6d42e7dSPeter Dunlap 
114a6d42e7dSPeter Dunlap static int iscsi_walk_all_sess(iscsi_dcmd_ctrl_t *idc);
11530e7468fSPeter Dunlap static int iscsi_walk_ini_sessions(uintptr_t array_addr);
116a6d42e7dSPeter Dunlap static int iscsi_walk_all_conn(iscsi_dcmd_ctrl_t *idc);
117a6d42e7dSPeter Dunlap static int iscsi_tgt_walk_cb(uintptr_t addr, const void *list_walker_data,
118a6d42e7dSPeter Dunlap     void *idc_void);
119a6d42e7dSPeter Dunlap static int iscsi_tpgt_walk_cb(uintptr_t addr, const void *list_walker_data,
120a6d42e7dSPeter Dunlap     void *idc_void);
121a6d42e7dSPeter Dunlap static int iscsi_tpg_walk_cb(uintptr_t addr, const void *list_walker_data,
122a6d42e7dSPeter Dunlap     void *idc_void);
123a6d42e7dSPeter Dunlap static int iscsi_portal_walk_cb(uintptr_t addr, const void *list_walker_data,
124a6d42e7dSPeter Dunlap     void *idc_void);
125a6d42e7dSPeter Dunlap static int iscsi_sess_walk_cb(uintptr_t addr, const void *list_walker_data,
126a6d42e7dSPeter Dunlap     void *idc_void);
127a6d42e7dSPeter Dunlap static int iscsi_conn_walk_cb(uintptr_t addr, const void *list_walker_data,
128a6d42e7dSPeter Dunlap     void *idc_void);
129a6d42e7dSPeter Dunlap static int iscsi_buffer_walk_cb(uintptr_t addr, const void *list_walker_data,
130a6d42e7dSPeter Dunlap     void *idc_void);
131a6d42e7dSPeter Dunlap static int iscsi_tgt_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
132a6d42e7dSPeter Dunlap static int iscsi_tpgt_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
133a6d42e7dSPeter Dunlap static int iscsi_tpg_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
134a6d42e7dSPeter Dunlap static int iscsi_portal_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
135a6d42e7dSPeter Dunlap static int iscsi_sess_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
136a6d42e7dSPeter Dunlap static int iscsi_conn_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
137a6d42e7dSPeter Dunlap static void iscsi_print_iscsit_conn_data(idm_conn_t *ict);
138a6d42e7dSPeter Dunlap static void iscsi_print_idm_conn_data(idm_conn_t *ict);
139a6d42e7dSPeter Dunlap static int iscsi_task_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
140a6d42e7dSPeter Dunlap static void iscsi_print_iscsit_task_data(idm_task_t *idt);
141a6d42e7dSPeter Dunlap static int iscsi_buffer_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
142a6d42e7dSPeter Dunlap static idm_conn_type_t idm_conn_type(uintptr_t addr);
143a6d42e7dSPeter Dunlap static int iscsi_i_task_impl(idm_task_t *idt, uintptr_t addr,
144a6d42e7dSPeter Dunlap     iscsi_dcmd_ctrl_t *idc);
145a6d42e7dSPeter Dunlap static int iscsi_refcnt_impl(uintptr_t addr);
146a6d42e7dSPeter Dunlap static int iscsi_sm_audit_impl(uintptr_t addr);
147a6d42e7dSPeter Dunlap static int iscsi_isns(uintptr_t addr, uint_t flags, int argc,
148a6d42e7dSPeter Dunlap     const mdb_arg_t *argv);
149a6d42e7dSPeter Dunlap 
15030e7468fSPeter Dunlap static const char *iscsi_idm_conn_event(unsigned int event);
15130e7468fSPeter Dunlap static const char *iscsi_iscsit_tgt_event(unsigned int event);
15230e7468fSPeter Dunlap static const char *iscsi_iscsit_sess_event(unsigned int event);
15330e7468fSPeter Dunlap static const char *iscsi_iscsit_login_event(unsigned int event);
15430e7468fSPeter Dunlap static const char *iscsi_iscsi_cmd_event(unsigned int event);
15530e7468fSPeter Dunlap static const char *iscsi_iscsi_sess_event(unsigned int event);
15630e7468fSPeter Dunlap static const char *iscsi_idm_conn_state(unsigned int state);
15730e7468fSPeter Dunlap static const char *iscsi_idm_task_state(unsigned int state);
15830e7468fSPeter Dunlap static const char *iscsi_iscsit_tgt_state(unsigned int state);
15930e7468fSPeter Dunlap static const char *iscsi_iscsit_sess_state(unsigned int state);
16030e7468fSPeter Dunlap static const char *iscsi_iscsit_login_state(unsigned int state);
16130e7468fSPeter Dunlap static const char *iscsi_iscsi_cmd_state(unsigned int state);
16230e7468fSPeter Dunlap static const char *iscsi_iscsi_sess_state(unsigned int state);
16330e7468fSPeter Dunlap static const char *iscsi_iscsi_conn_state(unsigned int state);
164*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States static const char *iscsi_iscsi_conn_event(unsigned int event);
16530e7468fSPeter Dunlap static const char *iscsi_iscsi_login_state(unsigned int state);
166a6d42e7dSPeter Dunlap 
167a6d42e7dSPeter Dunlap static void iscsi_format_timestamp(char *ts_str, int strlen,
168a6d42e7dSPeter Dunlap     timespec_t *ts);
16930e7468fSPeter Dunlap static char *iscsi_inet_ntop(int af, const void *addr, char *buf, int addrlen);
170a6d42e7dSPeter Dunlap static void convert2ascii(char *, const in6_addr_t *);
171a6d42e7dSPeter Dunlap static int sa_to_str(struct sockaddr_storage *sa, char *addr);
172e42a0851Speter dunlap static int iscsi_isns_esi_cb(uintptr_t addr, const void *walker_data,
173e42a0851Speter dunlap     void *data);
174a6d42e7dSPeter Dunlap static int iscsi_isns_portal_cb(uintptr_t addr, const void *walker_data,
175a6d42e7dSPeter Dunlap     void *data);
176a6d42e7dSPeter Dunlap 
177a6d42e7dSPeter Dunlap #define	PORTAL_STR_LEN	(INET6_ADDRSTRLEN + 7)
178a6d42e7dSPeter Dunlap 
179a6d42e7dSPeter Dunlap /*
180a6d42e7dSPeter Dunlap  * ::iscsi_tgt [-scatgpbSRv]
181a6d42e7dSPeter Dunlap  *
182a6d42e7dSPeter Dunlap  * iscsi_tgt - Print out information associated with an iscsit target instance
183a6d42e7dSPeter Dunlap  *
184a6d42e7dSPeter Dunlap  * s	Print associated session information
185a6d42e7dSPeter Dunlap  * c	Print associated connection information
186a6d42e7dSPeter Dunlap  * a	Print IP addresses with connection information
187a6d42e7dSPeter Dunlap  * t	Print associated task information
188a6d42e7dSPeter Dunlap  * g	Print associated TPG information
189a6d42e7dSPeter Dunlap  * p	Print portals with TPG information
190a6d42e7dSPeter Dunlap  * b	Print associated buffer information
191a6d42e7dSPeter Dunlap  * S	Print recent state events and transitions
192a6d42e7dSPeter Dunlap  * R	Print reference count audit data
193a6d42e7dSPeter Dunlap  * v	Verbose output about the connection
194a6d42e7dSPeter Dunlap  */
195a6d42e7dSPeter Dunlap /*ARGSUSED*/
196a6d42e7dSPeter Dunlap static int
197a6d42e7dSPeter Dunlap iscsi_tgt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
198a6d42e7dSPeter Dunlap {
199a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	idc;
200a6d42e7dSPeter Dunlap 	int			buffer = 0, task = 0, print_ip = 0;
201a6d42e7dSPeter Dunlap 	int			tpgt = 0, conn = 0, sess = 0, portal = 0;
202a6d42e7dSPeter Dunlap 	int			states = 0, rc_audit = 0;
203a6d42e7dSPeter Dunlap 	uintptr_t		iscsit_global_addr, avl_addr, list_addr;
204a6d42e7dSPeter Dunlap 	GElf_Sym		sym;
205a6d42e7dSPeter Dunlap 
206a6d42e7dSPeter Dunlap 	bzero(&idc, sizeof (idc));
207a6d42e7dSPeter Dunlap 	if (mdb_getopts(argc, argv,
208a6d42e7dSPeter Dunlap 	    'a', MDB_OPT_SETBITS, TRUE, &print_ip,
209a6d42e7dSPeter Dunlap 	    'g', MDB_OPT_SETBITS, TRUE, &tpgt,
210a6d42e7dSPeter Dunlap 	    's', MDB_OPT_SETBITS, TRUE, &sess,
211a6d42e7dSPeter Dunlap 	    'c', MDB_OPT_SETBITS, TRUE, &conn,
212a6d42e7dSPeter Dunlap 	    't', MDB_OPT_SETBITS, TRUE, &task,
213a6d42e7dSPeter Dunlap 	    'b', MDB_OPT_SETBITS, TRUE, &buffer,
214a6d42e7dSPeter Dunlap 	    'p', MDB_OPT_SETBITS, TRUE, &portal,
215a6d42e7dSPeter Dunlap 	    'S', MDB_OPT_SETBITS, TRUE, &states,
216a6d42e7dSPeter Dunlap 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
217a6d42e7dSPeter Dunlap 	    'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
218a6d42e7dSPeter Dunlap 	    NULL) != argc)
219a6d42e7dSPeter Dunlap 		return (DCMD_USAGE);
220a6d42e7dSPeter Dunlap 
221a6d42e7dSPeter Dunlap 	idc.u.child.idc_tgt = 1;
222a6d42e7dSPeter Dunlap 	idc.u.child.idc_print_ip = print_ip;
223a6d42e7dSPeter Dunlap 	idc.u.child.idc_tpgt = tpgt;
224a6d42e7dSPeter Dunlap 	idc.u.child.idc_portal = portal;
225a6d42e7dSPeter Dunlap 	idc.u.child.idc_sess = sess;
226a6d42e7dSPeter Dunlap 	idc.u.child.idc_conn = conn;
227a6d42e7dSPeter Dunlap 	idc.u.child.idc_task = task;
228a6d42e7dSPeter Dunlap 	idc.u.child.idc_buffer = buffer;
229a6d42e7dSPeter Dunlap 	idc.u.child.idc_states = states;
230a6d42e7dSPeter Dunlap 	idc.u.child.idc_rc_audit = rc_audit;
231a6d42e7dSPeter Dunlap 
232a6d42e7dSPeter Dunlap 	if (DCMD_HDRSPEC(flags))
233a6d42e7dSPeter Dunlap 		idc.idc_header = 1;
234a6d42e7dSPeter Dunlap 
235a6d42e7dSPeter Dunlap 	/*
236a6d42e7dSPeter Dunlap 	 * If no address was specified on the command line, we
237a6d42e7dSPeter Dunlap 	 * print out all tgtions
238a6d42e7dSPeter Dunlap 	 */
239a6d42e7dSPeter Dunlap 	if (!(flags & DCMD_ADDRSPEC)) {
240a6d42e7dSPeter Dunlap 		if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
241a6d42e7dSPeter Dunlap 			mdb_warn("failed to find symbol 'iscsit_global'");
242a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
243a6d42e7dSPeter Dunlap 		}
244a6d42e7dSPeter Dunlap 		iscsit_global_addr = (uintptr_t)sym.st_value;
245a6d42e7dSPeter Dunlap 		avl_addr = iscsit_global_addr +
246a6d42e7dSPeter Dunlap 		    offsetof(iscsit_global_t, global_target_list);
247a6d42e7dSPeter Dunlap 		if (mdb_pwalk("avl", iscsi_tgt_walk_cb, &idc, avl_addr) == -1) {
248a6d42e7dSPeter Dunlap 			mdb_warn("avl walk failed for global target tree");
249a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
250a6d42e7dSPeter Dunlap 		}
251a6d42e7dSPeter Dunlap 		list_addr = iscsit_global_addr +
252a6d42e7dSPeter Dunlap 		    offsetof(iscsit_global_t, global_deleted_target_list);
253a6d42e7dSPeter Dunlap 		if (mdb_pwalk("list", iscsi_tgt_walk_cb,
254a6d42e7dSPeter Dunlap 		    &idc, list_addr) == -1) {
255a6d42e7dSPeter Dunlap 			mdb_warn("list walk failed for deleted target list");
256a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
257a6d42e7dSPeter Dunlap 		}
258a6d42e7dSPeter Dunlap 		return (DCMD_OK);
259a6d42e7dSPeter Dunlap 	} else {
260a6d42e7dSPeter Dunlap 		return (iscsi_tgt_impl(addr, &idc));
261a6d42e7dSPeter Dunlap 	}
262a6d42e7dSPeter Dunlap 	/*NOTREACHED*/
263a6d42e7dSPeter Dunlap }
264a6d42e7dSPeter Dunlap 
265a6d42e7dSPeter Dunlap static int
266a6d42e7dSPeter Dunlap iscsi_tpg(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
267a6d42e7dSPeter Dunlap {
268a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	idc;
269a6d42e7dSPeter Dunlap 	uintptr_t		iscsit_global_addr, avl_addr;
270a6d42e7dSPeter Dunlap 	GElf_Sym		sym;
271a6d42e7dSPeter Dunlap 
272a6d42e7dSPeter Dunlap 	bzero(&idc, sizeof (idc));
273a6d42e7dSPeter Dunlap 	if (mdb_getopts(argc, argv,
274a6d42e7dSPeter Dunlap 	    'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
275a6d42e7dSPeter Dunlap 	    NULL) != argc)
276a6d42e7dSPeter Dunlap 		return (DCMD_USAGE);
277a6d42e7dSPeter Dunlap 
278a6d42e7dSPeter Dunlap 	idc.u.child.idc_portal = 1; /* Always print portals */
279a6d42e7dSPeter Dunlap 	if (DCMD_HDRSPEC(flags))
280a6d42e7dSPeter Dunlap 		idc.idc_header = 1;
281a6d42e7dSPeter Dunlap 
282a6d42e7dSPeter Dunlap 	/*
283a6d42e7dSPeter Dunlap 	 * If no address was specified on the command line, we
284a6d42e7dSPeter Dunlap 	 * print out all tgtions
285a6d42e7dSPeter Dunlap 	 */
286a6d42e7dSPeter Dunlap 	if (!(flags & DCMD_ADDRSPEC)) {
287a6d42e7dSPeter Dunlap 		if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
288a6d42e7dSPeter Dunlap 			mdb_warn("failed to find symbol 'iscsit_global'");
289a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
290a6d42e7dSPeter Dunlap 		}
291a6d42e7dSPeter Dunlap 		iscsit_global_addr = (uintptr_t)sym.st_value;
292a6d42e7dSPeter Dunlap 		avl_addr = iscsit_global_addr +
293a6d42e7dSPeter Dunlap 		    offsetof(iscsit_global_t, global_tpg_list);
294a6d42e7dSPeter Dunlap 		if (mdb_pwalk("avl", iscsi_tpg_walk_cb, &idc, avl_addr) == -1) {
295a6d42e7dSPeter Dunlap 			mdb_warn("avl walk failed for global target tree");
296a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
297a6d42e7dSPeter Dunlap 		}
298a6d42e7dSPeter Dunlap 		return (DCMD_OK);
299a6d42e7dSPeter Dunlap 	} else {
300a6d42e7dSPeter Dunlap 		return (iscsi_tpg_impl(addr, &idc));
301a6d42e7dSPeter Dunlap 	}
302a6d42e7dSPeter Dunlap 	/*NOTREACHED*/
303a6d42e7dSPeter Dunlap }
304a6d42e7dSPeter Dunlap 
305a6d42e7dSPeter Dunlap /*
306a6d42e7dSPeter Dunlap  * ::iscsi_sess [-bctvIT]
307a6d42e7dSPeter Dunlap  *
308a6d42e7dSPeter Dunlap  * iscsi_sess - Print out information associated with an iSCSI session
309a6d42e7dSPeter Dunlap  *
310a6d42e7dSPeter Dunlap  * I	Print only initiator sessions
311a6d42e7dSPeter Dunlap  * T	Print only target sessions
312a6d42e7dSPeter Dunlap  * c	Print associated connection information
313a6d42e7dSPeter Dunlap  * a	Print IP addresses with connection information
314a6d42e7dSPeter Dunlap  * t	Print associated task information
315a6d42e7dSPeter Dunlap  * b	Print associated buffer information
316a6d42e7dSPeter Dunlap  * S	Print recent state events and transitions
317a6d42e7dSPeter Dunlap  * R	Print reference count audit data
318a6d42e7dSPeter Dunlap  * v	Verbose output about the connection
319a6d42e7dSPeter Dunlap  */
320a6d42e7dSPeter Dunlap /*ARGSUSED*/
321a6d42e7dSPeter Dunlap static int
322a6d42e7dSPeter Dunlap iscsi_sess(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
323a6d42e7dSPeter Dunlap {
324a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	idc;
325a6d42e7dSPeter Dunlap 	int			buffer = 0, task = 0, conn = 0, print_ip = 0;
326a6d42e7dSPeter Dunlap 	int			states = 0, rc_audit = 0;
327a6d42e7dSPeter Dunlap 
328a6d42e7dSPeter Dunlap 	bzero(&idc, sizeof (idc));
329a6d42e7dSPeter Dunlap 	if (mdb_getopts(argc, argv,
330a6d42e7dSPeter Dunlap 	    'I', MDB_OPT_SETBITS, TRUE, &idc.idc_ini,
331a6d42e7dSPeter Dunlap 	    'T', MDB_OPT_SETBITS, TRUE, &idc.idc_tgt,
332a6d42e7dSPeter Dunlap 	    'a', MDB_OPT_SETBITS, TRUE, &print_ip,
333a6d42e7dSPeter Dunlap 	    'c', MDB_OPT_SETBITS, TRUE, &conn,
334a6d42e7dSPeter Dunlap 	    't', MDB_OPT_SETBITS, TRUE, &task,
335a6d42e7dSPeter Dunlap 	    'b', MDB_OPT_SETBITS, TRUE, &buffer,
336a6d42e7dSPeter Dunlap 	    'S', MDB_OPT_SETBITS, TRUE, &states,
337a6d42e7dSPeter Dunlap 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
338a6d42e7dSPeter Dunlap 	    'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
339a6d42e7dSPeter Dunlap 	    NULL) != argc)
340a6d42e7dSPeter Dunlap 		return (DCMD_USAGE);
341a6d42e7dSPeter Dunlap 
342a6d42e7dSPeter Dunlap 	idc.u.child.idc_sess = 1;
343a6d42e7dSPeter Dunlap 	idc.u.child.idc_print_ip = print_ip;
344a6d42e7dSPeter Dunlap 	idc.u.child.idc_conn = conn;
345a6d42e7dSPeter Dunlap 	idc.u.child.idc_task = task;
346a6d42e7dSPeter Dunlap 	idc.u.child.idc_buffer = buffer;
347a6d42e7dSPeter Dunlap 	idc.u.child.idc_states = states;
348a6d42e7dSPeter Dunlap 	idc.u.child.idc_rc_audit = rc_audit;
349a6d42e7dSPeter Dunlap 	if (DCMD_HDRSPEC(flags))
350a6d42e7dSPeter Dunlap 		idc.idc_header = 1;
351a6d42e7dSPeter Dunlap 
352a6d42e7dSPeter Dunlap 	/*
353a6d42e7dSPeter Dunlap 	 * If no address was specified on the command line, we
354a6d42e7dSPeter Dunlap 	 * print out all sessions
355a6d42e7dSPeter Dunlap 	 */
356a6d42e7dSPeter Dunlap 	if (!(flags & DCMD_ADDRSPEC)) {
357a6d42e7dSPeter Dunlap 		return (iscsi_walk_all_sess(&idc));
358a6d42e7dSPeter Dunlap 	} else {
359a6d42e7dSPeter Dunlap 		return (iscsi_sess_impl(addr, &idc));
360a6d42e7dSPeter Dunlap 	}
361a6d42e7dSPeter Dunlap 	/*NOTREACHED*/
362a6d42e7dSPeter Dunlap }
363a6d42e7dSPeter Dunlap 
364a6d42e7dSPeter Dunlap 
365a6d42e7dSPeter Dunlap 
366a6d42e7dSPeter Dunlap /*
367a6d42e7dSPeter Dunlap  * ::iscsi_conn [-btvIT]
368a6d42e7dSPeter Dunlap  *
369a6d42e7dSPeter Dunlap  * iscsi_conn - Print out information associated with an iSCSI connection
370a6d42e7dSPeter Dunlap  *
371a6d42e7dSPeter Dunlap  * I	Print only initiator connections
372a6d42e7dSPeter Dunlap  * T	Print only target connections
373a6d42e7dSPeter Dunlap  * a	Print IP addresses with connection information
374a6d42e7dSPeter Dunlap  * t	Print associated task information
375a6d42e7dSPeter Dunlap  * b	Print associated buffer information
376a6d42e7dSPeter Dunlap  * S	Print recent state events and transitions
377a6d42e7dSPeter Dunlap  * R	Print reference count audit data
378a6d42e7dSPeter Dunlap  * v	Verbose output about the connection
379a6d42e7dSPeter Dunlap  */
380a6d42e7dSPeter Dunlap /*ARGSUSED*/
381a6d42e7dSPeter Dunlap static int
382a6d42e7dSPeter Dunlap iscsi_conn(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
383a6d42e7dSPeter Dunlap {
384a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	idc;
385a6d42e7dSPeter Dunlap 	int			buffer = 0, task = 0, print_ip = 0;
386a6d42e7dSPeter Dunlap 	int			states = 0, rc_audit = 0;
387a6d42e7dSPeter Dunlap 
388a6d42e7dSPeter Dunlap 	bzero(&idc, sizeof (idc));
389a6d42e7dSPeter Dunlap 	if (mdb_getopts(argc, argv,
390a6d42e7dSPeter Dunlap 	    'I', MDB_OPT_SETBITS, TRUE, &idc.idc_ini,
391a6d42e7dSPeter Dunlap 	    'T', MDB_OPT_SETBITS, TRUE, &idc.idc_tgt,
392a6d42e7dSPeter Dunlap 	    'a', MDB_OPT_SETBITS, TRUE, &print_ip,
393a6d42e7dSPeter Dunlap 	    't', MDB_OPT_SETBITS, TRUE, &task,
394a6d42e7dSPeter Dunlap 	    'b', MDB_OPT_SETBITS, TRUE, &buffer,
395a6d42e7dSPeter Dunlap 	    'S', MDB_OPT_SETBITS, TRUE, &states,
396a6d42e7dSPeter Dunlap 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
397a6d42e7dSPeter Dunlap 	    'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
398a6d42e7dSPeter Dunlap 	    NULL) != argc)
399a6d42e7dSPeter Dunlap 		return (DCMD_USAGE);
400a6d42e7dSPeter Dunlap 
401a6d42e7dSPeter Dunlap 	idc.u.child.idc_conn = 1;
402a6d42e7dSPeter Dunlap 	idc.u.child.idc_print_ip = print_ip;
403a6d42e7dSPeter Dunlap 	idc.u.child.idc_task = task;
404a6d42e7dSPeter Dunlap 	idc.u.child.idc_buffer = buffer;
405a6d42e7dSPeter Dunlap 	idc.u.child.idc_states = states;
406a6d42e7dSPeter Dunlap 	idc.u.child.idc_rc_audit = rc_audit;
407a6d42e7dSPeter Dunlap 	if (DCMD_HDRSPEC(flags))
408a6d42e7dSPeter Dunlap 		idc.idc_header = 1;
409a6d42e7dSPeter Dunlap 
410a6d42e7dSPeter Dunlap 	/*
411a6d42e7dSPeter Dunlap 	 * If no address was specified on the command line, we
412a6d42e7dSPeter Dunlap 	 * print out all connections
413a6d42e7dSPeter Dunlap 	 */
414a6d42e7dSPeter Dunlap 	if (!(flags & DCMD_ADDRSPEC)) {
415a6d42e7dSPeter Dunlap 		return (iscsi_walk_all_conn(&idc));
416a6d42e7dSPeter Dunlap 	} else {
417a6d42e7dSPeter Dunlap 		return (iscsi_conn_impl(addr, &idc));
418a6d42e7dSPeter Dunlap 	}
419a6d42e7dSPeter Dunlap 	/*NOTREACHED*/
420a6d42e7dSPeter Dunlap }
421a6d42e7dSPeter Dunlap 
422a6d42e7dSPeter Dunlap /*
423a6d42e7dSPeter Dunlap  * ::iscsi_task [-bv]
424a6d42e7dSPeter Dunlap  *
425a6d42e7dSPeter Dunlap  * iscsi_task - Print out information associated with an iSCSI task
426a6d42e7dSPeter Dunlap  *
427a6d42e7dSPeter Dunlap  * b	Print associated buffer information
428a6d42e7dSPeter Dunlap  * S	Print recent state events and transitions
429a6d42e7dSPeter Dunlap  * R	Print reference count audit data
430a6d42e7dSPeter Dunlap  * v	Verbose output about the connection
431a6d42e7dSPeter Dunlap  */
432a6d42e7dSPeter Dunlap /*ARGSUSED*/
433a6d42e7dSPeter Dunlap static int
434a6d42e7dSPeter Dunlap iscsi_task(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
435a6d42e7dSPeter Dunlap {
436a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	idc;
437a6d42e7dSPeter Dunlap 	int			buffer = 0;
438a6d42e7dSPeter Dunlap 	int			states = 0, rc_audit = 0;
439a6d42e7dSPeter Dunlap 
440a6d42e7dSPeter Dunlap 	bzero(&idc, sizeof (idc));
441a6d42e7dSPeter Dunlap 	if (mdb_getopts(argc, argv,
442a6d42e7dSPeter Dunlap 	    'b', MDB_OPT_SETBITS, TRUE, &buffer,
443a6d42e7dSPeter Dunlap 	    'S', MDB_OPT_SETBITS, TRUE, &states,
444a6d42e7dSPeter Dunlap 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
445a6d42e7dSPeter Dunlap 	    'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
446a6d42e7dSPeter Dunlap 	    NULL) != argc)
447a6d42e7dSPeter Dunlap 		return (DCMD_USAGE);
448a6d42e7dSPeter Dunlap 
449a6d42e7dSPeter Dunlap 	idc.u.child.idc_conn = 0;
450a6d42e7dSPeter Dunlap 	idc.u.child.idc_task = 1;
451a6d42e7dSPeter Dunlap 	idc.u.child.idc_buffer = buffer;
452a6d42e7dSPeter Dunlap 	idc.u.child.idc_states = states;
453a6d42e7dSPeter Dunlap 	idc.u.child.idc_rc_audit = rc_audit;
454a6d42e7dSPeter Dunlap 	if (DCMD_HDRSPEC(flags))
455a6d42e7dSPeter Dunlap 		idc.idc_header = 1;
456a6d42e7dSPeter Dunlap 
457a6d42e7dSPeter Dunlap 	/*
458a6d42e7dSPeter Dunlap 	 * If no address was specified on the command line, we
459a6d42e7dSPeter Dunlap 	 * print out all connections
460a6d42e7dSPeter Dunlap 	 */
461a6d42e7dSPeter Dunlap 	if (!(flags & DCMD_ADDRSPEC)) {
462a6d42e7dSPeter Dunlap 		return (iscsi_walk_all_conn(&idc));
463a6d42e7dSPeter Dunlap 	} else {
464a6d42e7dSPeter Dunlap 		return (iscsi_task_impl(addr, &idc));
465a6d42e7dSPeter Dunlap 	}
466a6d42e7dSPeter Dunlap 	/*NOTREACHED*/
467a6d42e7dSPeter Dunlap }
468a6d42e7dSPeter Dunlap 
469a6d42e7dSPeter Dunlap /*
470a6d42e7dSPeter Dunlap  * ::iscsi_refcnt
471a6d42e7dSPeter Dunlap  *
472a6d42e7dSPeter Dunlap  * iscsi_refcnt - Dump an idm_refcnt_t structure
473a6d42e7dSPeter Dunlap  *
474a6d42e7dSPeter Dunlap  */
475a6d42e7dSPeter Dunlap /*ARGSUSED*/
476a6d42e7dSPeter Dunlap static int
477a6d42e7dSPeter Dunlap iscsi_refcnt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
478a6d42e7dSPeter Dunlap {
479a6d42e7dSPeter Dunlap 	if (!(flags & DCMD_ADDRSPEC)) {
480a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
481a6d42e7dSPeter Dunlap 	} else {
482a6d42e7dSPeter Dunlap 		return (iscsi_refcnt_impl(addr));
483a6d42e7dSPeter Dunlap 	}
484a6d42e7dSPeter Dunlap 	/*NOTREACHED*/
485a6d42e7dSPeter Dunlap }
486a6d42e7dSPeter Dunlap 
487a6d42e7dSPeter Dunlap /*
488a6d42e7dSPeter Dunlap  * ::iscsi_states
489a6d42e7dSPeter Dunlap  *
490a6d42e7dSPeter Dunlap  * iscsi_states - Dump events and state transitions recoreded in an
491a6d42e7dSPeter Dunlap  * idm_sm_audit_t structure
492a6d42e7dSPeter Dunlap  *
493a6d42e7dSPeter Dunlap  */
494a6d42e7dSPeter Dunlap /*ARGSUSED*/
495a6d42e7dSPeter Dunlap static int
496a6d42e7dSPeter Dunlap iscsi_states(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
497a6d42e7dSPeter Dunlap {
498a6d42e7dSPeter Dunlap 	if (!(flags & DCMD_ADDRSPEC)) {
499a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
500a6d42e7dSPeter Dunlap 	} else {
501a6d42e7dSPeter Dunlap 		return (iscsi_sm_audit_impl(addr));
502a6d42e7dSPeter Dunlap 	}
503a6d42e7dSPeter Dunlap 	/*NOTREACHED*/
504a6d42e7dSPeter Dunlap }
505a6d42e7dSPeter Dunlap 
50630e7468fSPeter Dunlap /*
50730e7468fSPeter Dunlap  * Helper function to list all the initiator sessions
50830e7468fSPeter Dunlap  */
50930e7468fSPeter Dunlap static int
51030e7468fSPeter Dunlap iscsi_walk_ini_sessions(uintptr_t array_vaddr)
51130e7468fSPeter Dunlap {
51230e7468fSPeter Dunlap 	iscsi_hba_t ihp;
51330e7468fSPeter Dunlap 	int i;
51430e7468fSPeter Dunlap 	int array_size;
51530e7468fSPeter Dunlap 	struct i_ddi_soft_state *ss;
51630e7468fSPeter Dunlap 	iscsi_sess_t *isp;
51730e7468fSPeter Dunlap 
51830e7468fSPeter Dunlap 	ss = (struct i_ddi_soft_state *)mdb_alloc(sizeof (*ss),
51930e7468fSPeter Dunlap 	    UM_SLEEP|UM_GC);
52030e7468fSPeter Dunlap 	if (mdb_vread(ss, sizeof (*ss), array_vaddr) != sizeof (*ss)) {
52130e7468fSPeter Dunlap 		mdb_warn("Cannot read softstate struct (Invalid pointer?).\n");
52230e7468fSPeter Dunlap 		return (DCMD_ERR);
52330e7468fSPeter Dunlap 	}
52430e7468fSPeter Dunlap 	array_size = ss->n_items * (sizeof (void *));
52530e7468fSPeter Dunlap 	array_vaddr = (uintptr_t)ss->array;
52630e7468fSPeter Dunlap 	ss->array = mdb_alloc(array_size, UM_SLEEP|UM_GC);
52730e7468fSPeter Dunlap 	if (mdb_vread(ss->array, array_size, array_vaddr) != array_size) {
52830e7468fSPeter Dunlap 		mdb_warn("Corrupted softstate struct.\n");
52930e7468fSPeter Dunlap 		return (DCMD_ERR);
53030e7468fSPeter Dunlap 	}
53130e7468fSPeter Dunlap 	for (i = 0; i < ss->n_items; i++) {
53230e7468fSPeter Dunlap 		if (ss->array[i] == 0)
53330e7468fSPeter Dunlap 		continue;
53430e7468fSPeter Dunlap 
53530e7468fSPeter Dunlap 		if (mdb_vread(&ihp, sizeof (ihp), (uintptr_t)ss->array[i])
53630e7468fSPeter Dunlap 		    != sizeof (ihp)) {
53730e7468fSPeter Dunlap 			mdb_warn("Corrupted softstate struct.\n");
53830e7468fSPeter Dunlap 			return (DCMD_ERR);
53930e7468fSPeter Dunlap 		}
54030e7468fSPeter Dunlap 		mdb_printf("iscsi_hba %p sessions: \n", ihp);
54130e7468fSPeter Dunlap 		mdb_printf("%<u>%-19s %-4s  %-8s%</u>\n",
54230e7468fSPeter Dunlap 		    "Session", "Type", "State");
54330e7468fSPeter Dunlap 		for (isp = ihp.hba_sess_list; isp; ) {
54430e7468fSPeter Dunlap 			iscsi_sess_t sess;
54530e7468fSPeter Dunlap 			if ((mdb_vread(&sess, sizeof (iscsi_sess_t),
54630e7468fSPeter Dunlap 			    (uintptr_t)isp)) != sizeof (iscsi_sess_t)) {
54730e7468fSPeter Dunlap 				mdb_warn("Failed to read session\n");
54830e7468fSPeter Dunlap 				return (DCMD_ERR);
54930e7468fSPeter Dunlap 			}
55030e7468fSPeter Dunlap 			mdb_printf("%-19p %-4d %-8d\n", isp,
55130e7468fSPeter Dunlap 			    sess.sess_type,
55230e7468fSPeter Dunlap 			    sess.sess_state);
55330e7468fSPeter Dunlap 			isp = sess.sess_next;
55430e7468fSPeter Dunlap 		}
55530e7468fSPeter Dunlap 	}
55630e7468fSPeter Dunlap 	return (DCMD_OK);
55730e7468fSPeter Dunlap }
55830e7468fSPeter Dunlap 
559a6d42e7dSPeter Dunlap static int
560a6d42e7dSPeter Dunlap iscsi_walk_all_sess(iscsi_dcmd_ctrl_t *idc)
561a6d42e7dSPeter Dunlap {
562a6d42e7dSPeter Dunlap 	uintptr_t	iscsit_global_addr;
563a6d42e7dSPeter Dunlap 	uintptr_t	avl_addr;
564a6d42e7dSPeter Dunlap 	uintptr_t	list_addr;
565a6d42e7dSPeter Dunlap 	GElf_Sym	sym;
56630e7468fSPeter Dunlap 	uintptr_t adr;
56730e7468fSPeter Dunlap 	/* Initiator sessions */
56830e7468fSPeter Dunlap 	if (idc->idc_ini) {
56930e7468fSPeter Dunlap 		if (mdb_readvar(&adr, "iscsi_state") == -1) {
570a6d42e7dSPeter Dunlap 
57130e7468fSPeter Dunlap 			mdb_warn("state variable iscsi_state not found.\n");
57230e7468fSPeter Dunlap 			mdb_warn("Is the driver loaded ?\n");
57330e7468fSPeter Dunlap 			return (DCMD_ERR);
57430e7468fSPeter Dunlap 		}
57530e7468fSPeter Dunlap 		return (iscsi_walk_ini_sessions(adr));
57630e7468fSPeter Dunlap 	}
57730e7468fSPeter Dunlap 	/* Target sessions */
578a6d42e7dSPeter Dunlap 	/* Walk discovery sessions */
579a6d42e7dSPeter Dunlap 	if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
580a6d42e7dSPeter Dunlap 		mdb_warn("failed to find symbol 'iscsit_global'");
581a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
582a6d42e7dSPeter Dunlap 	}
583a6d42e7dSPeter Dunlap 	iscsit_global_addr = (uintptr_t)sym.st_value;
584a6d42e7dSPeter Dunlap 	avl_addr = iscsit_global_addr +
585a6d42e7dSPeter Dunlap 	    offsetof(iscsit_global_t, global_discovery_sessions);
586a6d42e7dSPeter Dunlap 	if (mdb_pwalk("avl", iscsi_sess_walk_cb, idc, avl_addr) == -1) {
587a6d42e7dSPeter Dunlap 		mdb_warn("avl walk failed for discovery sessions");
588a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
589a6d42e7dSPeter Dunlap 	}
590a6d42e7dSPeter Dunlap 
591a6d42e7dSPeter Dunlap 	/* Walk targets printing all session info */
592a6d42e7dSPeter Dunlap 	avl_addr = iscsit_global_addr +
593a6d42e7dSPeter Dunlap 	    offsetof(iscsit_global_t, global_target_list);
594a6d42e7dSPeter Dunlap 	if (mdb_pwalk("avl", iscsi_tgt_walk_cb, idc, avl_addr) == -1) {
595a6d42e7dSPeter Dunlap 		mdb_warn("avl walk failed for target/session tree");
596a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
597a6d42e7dSPeter Dunlap 	}
598a6d42e7dSPeter Dunlap 
599a6d42e7dSPeter Dunlap 	/* Walk deleting targets printing all session info */
600a6d42e7dSPeter Dunlap 	list_addr = iscsit_global_addr +
601a6d42e7dSPeter Dunlap 	    offsetof(iscsit_global_t, global_deleted_target_list);
602a6d42e7dSPeter Dunlap 	if (mdb_pwalk("list", iscsi_tgt_walk_cb, idc, list_addr) == -1) {
603a6d42e7dSPeter Dunlap 		mdb_warn("list walk failed for deleted target list");
604a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
605a6d42e7dSPeter Dunlap 	}
606a6d42e7dSPeter Dunlap 
607a6d42e7dSPeter Dunlap 	return (DCMD_OK);
608a6d42e7dSPeter Dunlap }
609a6d42e7dSPeter Dunlap 
610a6d42e7dSPeter Dunlap static int
611a6d42e7dSPeter Dunlap iscsi_walk_all_conn(iscsi_dcmd_ctrl_t *idc)
612a6d42e7dSPeter Dunlap {
613a6d42e7dSPeter Dunlap 	uintptr_t	idm_global_addr;
614a6d42e7dSPeter Dunlap 	uintptr_t	list_addr;
615a6d42e7dSPeter Dunlap 	GElf_Sym	sym;
616a6d42e7dSPeter Dunlap 
617a6d42e7dSPeter Dunlap 	/* Walk initiator connections */
618a6d42e7dSPeter Dunlap 	if (mdb_lookup_by_name("idm", &sym) == -1) {
619a6d42e7dSPeter Dunlap 		mdb_warn("failed to find symbol 'idm'");
620a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
621a6d42e7dSPeter Dunlap 	}
622a6d42e7dSPeter Dunlap 	idm_global_addr = (uintptr_t)sym.st_value;
623a6d42e7dSPeter Dunlap 	/* Walk connection list associated with the initiator */
624a6d42e7dSPeter Dunlap 	list_addr = idm_global_addr + offsetof(idm_global_t, idm_ini_conn_list);
625a6d42e7dSPeter Dunlap 	if (mdb_pwalk("list", iscsi_conn_walk_cb, idc, list_addr) == -1) {
626a6d42e7dSPeter Dunlap 		mdb_warn("list walk failed for initiator connections");
627a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
628a6d42e7dSPeter Dunlap 	}
629a6d42e7dSPeter Dunlap 
630a6d42e7dSPeter Dunlap 	/* Walk connection list associated with the target */
631a6d42e7dSPeter Dunlap 	list_addr = idm_global_addr + offsetof(idm_global_t, idm_tgt_conn_list);
632a6d42e7dSPeter Dunlap 	if (mdb_pwalk("list", iscsi_conn_walk_cb, idc, list_addr) == -1) {
633a6d42e7dSPeter Dunlap 		mdb_warn("list walk failed for target service instances");
634a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
635a6d42e7dSPeter Dunlap 	}
636a6d42e7dSPeter Dunlap 
637a6d42e7dSPeter Dunlap 	return (DCMD_OK);
638a6d42e7dSPeter Dunlap }
639a6d42e7dSPeter Dunlap 
640a6d42e7dSPeter Dunlap /*ARGSUSED*/
641a6d42e7dSPeter Dunlap static int
642a6d42e7dSPeter Dunlap iscsi_tpg_walk_cb(uintptr_t addr, const void *list_walker_data,
643a6d42e7dSPeter Dunlap     void *idc_void)
644a6d42e7dSPeter Dunlap {
645a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
646a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
647a6d42e7dSPeter Dunlap 	int			rc;
648a6d42e7dSPeter Dunlap 
649a6d42e7dSPeter Dunlap 	rc = iscsi_tpg_impl(addr, idc);
650a6d42e7dSPeter Dunlap 
651a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
652a6d42e7dSPeter Dunlap }
653a6d42e7dSPeter Dunlap 
654a6d42e7dSPeter Dunlap /*ARGSUSED*/
655a6d42e7dSPeter Dunlap static int
656a6d42e7dSPeter Dunlap iscsi_tgt_walk_cb(uintptr_t addr, const void *list_walker_data,
657a6d42e7dSPeter Dunlap     void *idc_void)
658a6d42e7dSPeter Dunlap {
659a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
660a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
661a6d42e7dSPeter Dunlap 	int			rc;
662a6d42e7dSPeter Dunlap 
663a6d42e7dSPeter Dunlap 	rc = iscsi_tgt_impl(addr, idc);
664a6d42e7dSPeter Dunlap 
665a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
666a6d42e7dSPeter Dunlap }
667a6d42e7dSPeter Dunlap 
668a6d42e7dSPeter Dunlap /*ARGSUSED*/
669a6d42e7dSPeter Dunlap static int
670a6d42e7dSPeter Dunlap iscsi_tpgt_walk_cb(uintptr_t addr, const void *list_walker_data,
671a6d42e7dSPeter Dunlap     void *idc_void)
672a6d42e7dSPeter Dunlap {
673a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
674a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
675a6d42e7dSPeter Dunlap 	int			rc;
676a6d42e7dSPeter Dunlap 
677a6d42e7dSPeter Dunlap 	rc = iscsi_tpgt_impl(addr, idc);
678a6d42e7dSPeter Dunlap 
679a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
680a6d42e7dSPeter Dunlap }
681a6d42e7dSPeter Dunlap 
682a6d42e7dSPeter Dunlap /*ARGSUSED*/
683a6d42e7dSPeter Dunlap static int
684a6d42e7dSPeter Dunlap iscsi_portal_walk_cb(uintptr_t addr, const void *list_walker_data,
685a6d42e7dSPeter Dunlap     void *idc_void)
686a6d42e7dSPeter Dunlap {
687a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
688a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
689a6d42e7dSPeter Dunlap 	int			rc;
690a6d42e7dSPeter Dunlap 
691a6d42e7dSPeter Dunlap 	rc = iscsi_portal_impl(addr, idc);
692a6d42e7dSPeter Dunlap 
693a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
694a6d42e7dSPeter Dunlap }
695a6d42e7dSPeter Dunlap 
696a6d42e7dSPeter Dunlap /*ARGSUSED*/
697a6d42e7dSPeter Dunlap static int
698a6d42e7dSPeter Dunlap iscsi_sess_walk_cb(uintptr_t addr, const void *list_walker_data,
699a6d42e7dSPeter Dunlap     void *idc_void)
700a6d42e7dSPeter Dunlap {
701a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
702a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
703a6d42e7dSPeter Dunlap 	int			rc;
704a6d42e7dSPeter Dunlap 
705a6d42e7dSPeter Dunlap 	rc = iscsi_sess_impl(addr, idc);
706a6d42e7dSPeter Dunlap 
707a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
708a6d42e7dSPeter Dunlap }
709a6d42e7dSPeter Dunlap 
710a6d42e7dSPeter Dunlap /*ARGSUSED*/
711a6d42e7dSPeter Dunlap static int
712a6d42e7dSPeter Dunlap iscsi_sess_conn_walk_cb(uintptr_t addr, const void *list_walker_data,
713a6d42e7dSPeter Dunlap     void *idc_void)
714a6d42e7dSPeter Dunlap {
715a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
716a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
717a6d42e7dSPeter Dunlap 	iscsit_conn_t		ict;
718a6d42e7dSPeter Dunlap 	int			rc;
719a6d42e7dSPeter Dunlap 
720a6d42e7dSPeter Dunlap 	/*
721a6d42e7dSPeter Dunlap 	 * This function is different from iscsi_conn_walk_cb because
722a6d42e7dSPeter Dunlap 	 * we get an iscsit_conn_t instead of an idm_conn_t
723a6d42e7dSPeter Dunlap 	 *
724a6d42e7dSPeter Dunlap 	 * Read iscsit_conn_t, use to get idm_conn_t pointer
725a6d42e7dSPeter Dunlap 	 */
726a6d42e7dSPeter Dunlap 	if (mdb_vread(&ict, sizeof (iscsit_conn_t), addr) !=
727a6d42e7dSPeter Dunlap 	    sizeof (iscsit_conn_t)) {
728a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
729a6d42e7dSPeter Dunlap 	}
730a6d42e7dSPeter Dunlap 	rc = iscsi_conn_impl((uintptr_t)ict.ict_ic, idc);
731a6d42e7dSPeter Dunlap 
732a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
733a6d42e7dSPeter Dunlap }
734a6d42e7dSPeter Dunlap 
735a6d42e7dSPeter Dunlap /*ARGSUSED*/
736a6d42e7dSPeter Dunlap static int
737a6d42e7dSPeter Dunlap iscsi_conn_walk_cb(uintptr_t addr, const void *list_walker_data,
738a6d42e7dSPeter Dunlap     void *idc_void)
739a6d42e7dSPeter Dunlap {
740a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
741a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
742a6d42e7dSPeter Dunlap 	int			rc;
743a6d42e7dSPeter Dunlap 
744a6d42e7dSPeter Dunlap 	rc = iscsi_conn_impl(addr, idc);
745a6d42e7dSPeter Dunlap 
746a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
747a6d42e7dSPeter Dunlap }
748a6d42e7dSPeter Dunlap 
749a6d42e7dSPeter Dunlap /*ARGSUSED*/
750a6d42e7dSPeter Dunlap static int
751a6d42e7dSPeter Dunlap iscsi_buffer_walk_cb(uintptr_t addr, const void *list_walker_data,
752a6d42e7dSPeter Dunlap     void *idc_void)
753a6d42e7dSPeter Dunlap {
754a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
755a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
756a6d42e7dSPeter Dunlap 	int			rc;
757a6d42e7dSPeter Dunlap 
758a6d42e7dSPeter Dunlap 	rc = iscsi_buffer_impl(addr, idc);
759a6d42e7dSPeter Dunlap 
760a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
761a6d42e7dSPeter Dunlap }
762a6d42e7dSPeter Dunlap 
763a6d42e7dSPeter Dunlap static int
764a6d42e7dSPeter Dunlap iscsi_tgt_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
765a6d42e7dSPeter Dunlap {
766a6d42e7dSPeter Dunlap 	iscsit_tgt_t	tgt;
767a6d42e7dSPeter Dunlap 	uintptr_t	avl_addr, rc_addr, states_addr;
768a6d42e7dSPeter Dunlap 	char		tgt_name[MAX_ISCSI_NODENAMELEN];
769a6d42e7dSPeter Dunlap 	int		verbose, states, rc_audit;
770a6d42e7dSPeter Dunlap 
771a6d42e7dSPeter Dunlap 	/*
772a6d42e7dSPeter Dunlap 	 * Read iscsit_tgt_t
773a6d42e7dSPeter Dunlap 	 */
774a6d42e7dSPeter Dunlap 	if (mdb_vread(&tgt, sizeof (iscsit_tgt_t), addr) !=
775a6d42e7dSPeter Dunlap 	    sizeof (iscsit_tgt_t)) {
776a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
777a6d42e7dSPeter Dunlap 	}
778a6d42e7dSPeter Dunlap 
779a6d42e7dSPeter Dunlap 	/*
780a6d42e7dSPeter Dunlap 	 * Read target name if available
781a6d42e7dSPeter Dunlap 	 */
782a6d42e7dSPeter Dunlap 	if ((tgt.target_name == NULL) ||
783a6d42e7dSPeter Dunlap 	    (mdb_readstr(tgt_name, sizeof (tgt_name),
784a6d42e7dSPeter Dunlap 	    (uintptr_t)tgt.target_name) == -1)) {
785a6d42e7dSPeter Dunlap 		strcpy(tgt_name, "N/A");
786a6d42e7dSPeter Dunlap 	}
787a6d42e7dSPeter Dunlap 
788a6d42e7dSPeter Dunlap 	/*
789a6d42e7dSPeter Dunlap 	 * Brief output
790a6d42e7dSPeter Dunlap 	 *
791a6d42e7dSPeter Dunlap 	 * iscsit_tgt_t pointer
792a6d42e7dSPeter Dunlap 	 * iscsit_tgt_t.target_stmf_state
793a6d42e7dSPeter Dunlap 	 * iscsit_tgt_t.target_sess_list.avl_numnodes (session count)
794a6d42e7dSPeter Dunlap 	 * iscsit_tgt_t.target_name;
795a6d42e7dSPeter Dunlap 	 */
796a6d42e7dSPeter Dunlap 
797a6d42e7dSPeter Dunlap 	verbose = idc->idc_verbose;
798a6d42e7dSPeter Dunlap 	states = idc->u.child.idc_states;
799a6d42e7dSPeter Dunlap 	rc_audit = idc->u.child.idc_rc_audit;
800a6d42e7dSPeter Dunlap 
801a6d42e7dSPeter Dunlap 	/* For now we will ignore the verbose flag */
802a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_tgt) {
803a6d42e7dSPeter Dunlap 		/* Print target data */
804a6d42e7dSPeter Dunlap 		if (idc->idc_header) {
805a6d42e7dSPeter Dunlap 			mdb_printf("%<u>%-19s %-4s  %-8s%</u>\n",
806a6d42e7dSPeter Dunlap 			    "iscsit_tgt_t", "Sess", "State");
807a6d42e7dSPeter Dunlap 		}
808a6d42e7dSPeter Dunlap 		mdb_printf("%-19p %-4d %-8d\n", addr,
809a6d42e7dSPeter Dunlap 		    tgt.target_sess_list.avl_numnodes,
810a6d42e7dSPeter Dunlap 		    tgt.target_state);
811a6d42e7dSPeter Dunlap 		mdb_printf("  %s\n", tgt_name);
812a6d42e7dSPeter Dunlap 	}
813a6d42e7dSPeter Dunlap 
814a6d42e7dSPeter Dunlap 	idc->idc_header = 0;
815a6d42e7dSPeter Dunlap 	idc->idc_verbose = 0;
816a6d42e7dSPeter Dunlap 
817a6d42e7dSPeter Dunlap 	/*
818a6d42e7dSPeter Dunlap 	 * Print states if requested
819a6d42e7dSPeter Dunlap 	 */
820a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_tgt && states) {
821a6d42e7dSPeter Dunlap 		states_addr = addr + offsetof(iscsit_tgt_t, target_state_audit);
822a6d42e7dSPeter Dunlap 
823a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(4);
824a6d42e7dSPeter Dunlap 		mdb_printf("State History:\n");
825a6d42e7dSPeter Dunlap 		if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
826a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
827a6d42e7dSPeter Dunlap 		idc->u.child.idc_states = 0;
828a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
829a6d42e7dSPeter Dunlap 	}
830a6d42e7dSPeter Dunlap 
831a6d42e7dSPeter Dunlap 	/*
832a6d42e7dSPeter Dunlap 	 * Print refcnt audit data if requested
833a6d42e7dSPeter Dunlap 	 */
834a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_tgt && rc_audit) {
835a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(4);
836a6d42e7dSPeter Dunlap 		mdb_printf("target_sess_refcnt:\n");
837a6d42e7dSPeter Dunlap 		rc_addr = addr +
838a6d42e7dSPeter Dunlap 		    offsetof(iscsit_tgt_t, target_sess_refcnt);
839a6d42e7dSPeter Dunlap 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
840a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
841a6d42e7dSPeter Dunlap 
842a6d42e7dSPeter Dunlap 		mdb_printf("target_refcnt:\n");
843a6d42e7dSPeter Dunlap 		rc_addr = addr +
844a6d42e7dSPeter Dunlap 		    offsetof(iscsit_tgt_t, target_refcnt);
845a6d42e7dSPeter Dunlap 
846a6d42e7dSPeter Dunlap 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
847a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
848a6d42e7dSPeter Dunlap 		idc->u.child.idc_rc_audit = 0;
849a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
850a6d42e7dSPeter Dunlap 	}
851a6d42e7dSPeter Dunlap 
852a6d42e7dSPeter Dunlap 	/* Any child objects to walk? */
853a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_tpgt || idc->u.child.idc_sess ||
854a6d42e7dSPeter Dunlap 	    idc->u.child.idc_conn || idc->u.child.idc_task ||
855a6d42e7dSPeter Dunlap 	    idc->u.child.idc_buffer) {
856a6d42e7dSPeter Dunlap 		/* Walk TPGT tree */
857a6d42e7dSPeter Dunlap 		idc->idc_header = 1;
858a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(4);
859a6d42e7dSPeter Dunlap 		avl_addr = addr +
860a6d42e7dSPeter Dunlap 		    offsetof(iscsit_tgt_t, target_tpgt_list);
861a6d42e7dSPeter Dunlap 		if (mdb_pwalk("avl", iscsi_tpgt_walk_cb, idc,
862a6d42e7dSPeter Dunlap 		    avl_addr) == -1) {
863a6d42e7dSPeter Dunlap 			mdb_warn("target tpgt list walk failed");
864a6d42e7dSPeter Dunlap 			(void) mdb_dec_indent(4);
865a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
866a6d42e7dSPeter Dunlap 		}
867a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
868a6d42e7dSPeter Dunlap 
869a6d42e7dSPeter Dunlap 		/* Walk sess tree */
870a6d42e7dSPeter Dunlap 		idc->idc_header = 1;
871a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(4);
872a6d42e7dSPeter Dunlap 		avl_addr = addr + offsetof(iscsit_tgt_t, target_sess_list);
873a6d42e7dSPeter Dunlap 		if (mdb_pwalk("avl", iscsi_sess_walk_cb, idc,
874a6d42e7dSPeter Dunlap 		    avl_addr) == -1) {
875a6d42e7dSPeter Dunlap 			mdb_warn("target sess list walk failed");
876a6d42e7dSPeter Dunlap 			(void) mdb_dec_indent(4);
877a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
878a6d42e7dSPeter Dunlap 		}
879a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
880a6d42e7dSPeter Dunlap 
881a6d42e7dSPeter Dunlap 		idc->idc_header = 0;
882a6d42e7dSPeter Dunlap 	}
883a6d42e7dSPeter Dunlap 
884a6d42e7dSPeter Dunlap 	idc->idc_verbose = verbose;
885a6d42e7dSPeter Dunlap 	idc->u.child.idc_states = states;
886a6d42e7dSPeter Dunlap 	idc->u.child.idc_rc_audit = rc_audit;
887a6d42e7dSPeter Dunlap 	return (DCMD_OK);
888a6d42e7dSPeter Dunlap }
889a6d42e7dSPeter Dunlap 
890a6d42e7dSPeter Dunlap static int
891a6d42e7dSPeter Dunlap iscsi_tpgt_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
892a6d42e7dSPeter Dunlap {
893a6d42e7dSPeter Dunlap 	iscsit_tpgt_t	tpgt;
894a6d42e7dSPeter Dunlap 	iscsit_tpg_t	tpg;
895a6d42e7dSPeter Dunlap 	uintptr_t	avl_addr, tpg_addr;
896a6d42e7dSPeter Dunlap 
897a6d42e7dSPeter Dunlap 	/*
898a6d42e7dSPeter Dunlap 	 * Read iscsit_tpgt_t
899a6d42e7dSPeter Dunlap 	 */
900a6d42e7dSPeter Dunlap 	if (mdb_vread(&tpgt, sizeof (iscsit_tpgt_t), addr) !=
901a6d42e7dSPeter Dunlap 	    sizeof (iscsit_tpgt_t)) {
902a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
903a6d42e7dSPeter Dunlap 	}
904a6d42e7dSPeter Dunlap 
905a6d42e7dSPeter Dunlap 	tpg_addr = (uintptr_t)tpgt.tpgt_tpg;
906a6d42e7dSPeter Dunlap 
907a6d42e7dSPeter Dunlap 	/*
908a6d42e7dSPeter Dunlap 	 * Read iscsit_tpg_t
909a6d42e7dSPeter Dunlap 	 */
910a6d42e7dSPeter Dunlap 	if (mdb_vread(&tpg, sizeof (iscsit_tpg_t), tpg_addr) !=
911a6d42e7dSPeter Dunlap 	    sizeof (iscsit_tpg_t)) {
912a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
913a6d42e7dSPeter Dunlap 	}
914a6d42e7dSPeter Dunlap 
915a6d42e7dSPeter Dunlap 	/*
916a6d42e7dSPeter Dunlap 	 * Brief output
917a6d42e7dSPeter Dunlap 	 *
918a6d42e7dSPeter Dunlap 	 * iscsit_tpgt_t pointer
919a6d42e7dSPeter Dunlap 	 * iscsit_tpg_t pointer
920a6d42e7dSPeter Dunlap 	 * iscsit_tpg_t.tpg_name
921a6d42e7dSPeter Dunlap 	 * iscsit_tpgt_t.tpgt_tag;
922a6d42e7dSPeter Dunlap 	 */
923a6d42e7dSPeter Dunlap 
924a6d42e7dSPeter Dunlap 	/* For now we will ignore the verbose flag */
925a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_tpgt) {
926a6d42e7dSPeter Dunlap 		/* Print target data */
927a6d42e7dSPeter Dunlap 		if (idc->idc_header) {
928a6d42e7dSPeter Dunlap 			mdb_printf("%<u>%-?s %-?s %-18s %-6s%</u>\n",
929a6d42e7dSPeter Dunlap 			    "iscsit_tpgt_t", "iscsit_tpg_t", "Name", "Tag");
930a6d42e7dSPeter Dunlap 		}
931a6d42e7dSPeter Dunlap 		mdb_printf("%?p %?p %-18s 0x%04x\n", addr, tpgt.tpgt_tpg,
932a6d42e7dSPeter Dunlap 		    tpg.tpg_name, tpgt.tpgt_tag);
933a6d42e7dSPeter Dunlap 	}
934a6d42e7dSPeter Dunlap 
935a6d42e7dSPeter Dunlap 	/*
936a6d42e7dSPeter Dunlap 	 * Assume for now that anyone interested in TPGT wants to see the
937a6d42e7dSPeter Dunlap 	 * portals as well.
938a6d42e7dSPeter Dunlap 	 */
939a6d42e7dSPeter Dunlap 	idc->idc_header = 1;
940a6d42e7dSPeter Dunlap 	(void) mdb_inc_indent(4);
941a6d42e7dSPeter Dunlap 	avl_addr = tpg_addr + offsetof(iscsit_tpg_t, tpg_portal_list);
942a6d42e7dSPeter Dunlap 	if (mdb_pwalk("avl", iscsi_portal_walk_cb, idc, avl_addr) == -1) {
943a6d42e7dSPeter Dunlap 		mdb_warn("portal list walk failed");
944a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
945a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
946a6d42e7dSPeter Dunlap 	}
947a6d42e7dSPeter Dunlap 	(void) mdb_dec_indent(4);
948a6d42e7dSPeter Dunlap 	idc->idc_header = 0;
949a6d42e7dSPeter Dunlap 
950a6d42e7dSPeter Dunlap 	return (DCMD_OK);
951a6d42e7dSPeter Dunlap }
952a6d42e7dSPeter Dunlap 
953a6d42e7dSPeter Dunlap static int
954a6d42e7dSPeter Dunlap iscsi_tpg_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
955a6d42e7dSPeter Dunlap {
956a6d42e7dSPeter Dunlap 	iscsit_tpg_t	tpg;
957a6d42e7dSPeter Dunlap 	uintptr_t	avl_addr;
958a6d42e7dSPeter Dunlap 
959a6d42e7dSPeter Dunlap 	/*
960a6d42e7dSPeter Dunlap 	 * Read iscsit_tpg_t
961a6d42e7dSPeter Dunlap 	 */
962a6d42e7dSPeter Dunlap 	if (mdb_vread(&tpg, sizeof (iscsit_tpg_t), addr) !=
963a6d42e7dSPeter Dunlap 	    sizeof (iscsit_tpg_t)) {
964a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
965a6d42e7dSPeter Dunlap 	}
966a6d42e7dSPeter Dunlap 
967a6d42e7dSPeter Dunlap 	/*
968a6d42e7dSPeter Dunlap 	 * Brief output
969a6d42e7dSPeter Dunlap 	 *
970a6d42e7dSPeter Dunlap 	 * iscsit_tpgt_t pointer
971a6d42e7dSPeter Dunlap 	 * iscsit_tpg_t pointer
972a6d42e7dSPeter Dunlap 	 * iscsit_tpg_t.tpg_name
973a6d42e7dSPeter Dunlap 	 * iscsit_tpgt_t.tpgt_tag;
974a6d42e7dSPeter Dunlap 	 */
975a6d42e7dSPeter Dunlap 
976a6d42e7dSPeter Dunlap 	/* For now we will ignore the verbose flag */
977a6d42e7dSPeter Dunlap 
978a6d42e7dSPeter Dunlap 	/* Print target data */
979a6d42e7dSPeter Dunlap 	if (idc->idc_header) {
980a6d42e7dSPeter Dunlap 		mdb_printf("%<u>%-?s %-18s%</u>\n",
981a6d42e7dSPeter Dunlap 		    "iscsit_tpg_t", "Name");
982a6d42e7dSPeter Dunlap 	}
983a6d42e7dSPeter Dunlap 	mdb_printf("%?p %-18s\n", addr, tpg.tpg_name);
984a6d42e7dSPeter Dunlap 
985a6d42e7dSPeter Dunlap 
986a6d42e7dSPeter Dunlap 	/*
987a6d42e7dSPeter Dunlap 	 * Assume for now that anyone interested in TPG wants to see the
988a6d42e7dSPeter Dunlap 	 * portals as well.
989a6d42e7dSPeter Dunlap 	 */
990a6d42e7dSPeter Dunlap 	idc->idc_header = 1;
991a6d42e7dSPeter Dunlap 	(void) mdb_inc_indent(4);
992a6d42e7dSPeter Dunlap 	avl_addr = addr + offsetof(iscsit_tpg_t, tpg_portal_list);
993a6d42e7dSPeter Dunlap 	if (mdb_pwalk("avl", iscsi_portal_walk_cb, idc, avl_addr) == -1) {
994a6d42e7dSPeter Dunlap 		mdb_warn("portal list walk failed");
995a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
996a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
997a6d42e7dSPeter Dunlap 	}
998a6d42e7dSPeter Dunlap 	(void) mdb_dec_indent(4);
999a6d42e7dSPeter Dunlap 	idc->idc_header = 0;
1000a6d42e7dSPeter Dunlap 
1001a6d42e7dSPeter Dunlap 	return (DCMD_OK);
1002a6d42e7dSPeter Dunlap }
1003a6d42e7dSPeter Dunlap 
1004a6d42e7dSPeter Dunlap static int
1005a6d42e7dSPeter Dunlap iscsi_portal_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
1006a6d42e7dSPeter Dunlap {
1007a6d42e7dSPeter Dunlap 	iscsit_portal_t	portal;
1008a6d42e7dSPeter Dunlap 	char		portal_addr[PORTAL_STR_LEN];
1009a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_portal) {
1010a6d42e7dSPeter Dunlap 		/*
1011a6d42e7dSPeter Dunlap 		 * Read iscsit_portal_t
1012a6d42e7dSPeter Dunlap 		 */
1013a6d42e7dSPeter Dunlap 		if (mdb_vread(&portal, sizeof (iscsit_portal_t), addr) !=
1014a6d42e7dSPeter Dunlap 		    sizeof (iscsit_portal_t)) {
1015a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1016a6d42e7dSPeter Dunlap 		}
1017a6d42e7dSPeter Dunlap 
1018a6d42e7dSPeter Dunlap 		/* Print portal data */
1019a6d42e7dSPeter Dunlap 		if (idc->idc_header) {
1020a6d42e7dSPeter Dunlap 			mdb_printf("%<u>%-?s %-?s %-30s%</u>\n",
1021a6d42e7dSPeter Dunlap 			    "iscsit_portal_t", "idm_svc_t", "IP:Port");
1022a6d42e7dSPeter Dunlap 		}
1023a6d42e7dSPeter Dunlap 		sa_to_str(&portal.portal_addr, portal_addr);
1024a6d42e7dSPeter Dunlap 		mdb_printf("%?p %?p %s\n", addr, portal.portal_svc,
1025a6d42e7dSPeter Dunlap 		    portal_addr);
1026a6d42e7dSPeter Dunlap 	}
1027a6d42e7dSPeter Dunlap 
1028a6d42e7dSPeter Dunlap 	return (DCMD_OK);
1029a6d42e7dSPeter Dunlap }
1030a6d42e7dSPeter Dunlap 
1031a6d42e7dSPeter Dunlap static int
1032a6d42e7dSPeter Dunlap iscsi_sess_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
1033a6d42e7dSPeter Dunlap {
1034a6d42e7dSPeter Dunlap 	iscsit_sess_t	ist;
1035a6d42e7dSPeter Dunlap 	uintptr_t	list_addr, states_addr, rc_addr;
1036a6d42e7dSPeter Dunlap 	char		ini_name[80];
1037a6d42e7dSPeter Dunlap 	char		tgt_name[80];
1038a6d42e7dSPeter Dunlap 	int		verbose, states, rc_audit;
1039a6d42e7dSPeter Dunlap 
1040a6d42e7dSPeter Dunlap 	/*
1041a6d42e7dSPeter Dunlap 	 * Read iscsit_sess_t
1042a6d42e7dSPeter Dunlap 	 */
1043a6d42e7dSPeter Dunlap 	if (mdb_vread(&ist, sizeof (iscsit_sess_t), addr) !=
1044a6d42e7dSPeter Dunlap 	    sizeof (iscsit_sess_t)) {
1045a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1046a6d42e7dSPeter Dunlap 	}
1047a6d42e7dSPeter Dunlap 
1048a6d42e7dSPeter Dunlap 	/*
1049a6d42e7dSPeter Dunlap 	 * Brief output
1050a6d42e7dSPeter Dunlap 	 *
1051a6d42e7dSPeter Dunlap 	 * iscsit_sess_t pointer
1052a6d42e7dSPeter Dunlap 	 * iscsit_sess_t.ist_state/iscsit_sess_t.ist_ffp_conn_count
1053a6d42e7dSPeter Dunlap 	 * iscsit_sess_t.ist_tsih
1054a6d42e7dSPeter Dunlap 	 * iscsit_sess_t.ist_initiator_name
1055a6d42e7dSPeter Dunlap 	 */
1056a6d42e7dSPeter Dunlap 
1057a6d42e7dSPeter Dunlap 	verbose = idc->idc_verbose;
1058a6d42e7dSPeter Dunlap 	states = idc->u.child.idc_states;
1059a6d42e7dSPeter Dunlap 	rc_audit = idc->u.child.idc_rc_audit;
1060a6d42e7dSPeter Dunlap 
1061a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_sess) {
1062a6d42e7dSPeter Dunlap 		if (verbose) {
1063a6d42e7dSPeter Dunlap 			/*
1064a6d42e7dSPeter Dunlap 			 * Read initiator name if available
1065a6d42e7dSPeter Dunlap 			 */
1066a6d42e7dSPeter Dunlap 			if ((ist.ist_initiator_name == NULL) ||
1067a6d42e7dSPeter Dunlap 			    (mdb_readstr(ini_name, sizeof (ini_name),
1068a6d42e7dSPeter Dunlap 			    (uintptr_t)ist.ist_initiator_name) == -1)) {
1069a6d42e7dSPeter Dunlap 				strcpy(ini_name, "N/A");
1070a6d42e7dSPeter Dunlap 			}
1071a6d42e7dSPeter Dunlap 
1072a6d42e7dSPeter Dunlap 			/*
1073a6d42e7dSPeter Dunlap 			 * Read target name if available
1074a6d42e7dSPeter Dunlap 			 */
1075a6d42e7dSPeter Dunlap 			if ((ist.ist_target_name == NULL) ||
1076a6d42e7dSPeter Dunlap 			    (mdb_readstr(tgt_name, sizeof (tgt_name),
1077a6d42e7dSPeter Dunlap 			    (uintptr_t)ist.ist_target_name) == -1)) {
1078a6d42e7dSPeter Dunlap 				strcpy(tgt_name, "N/A");
1079a6d42e7dSPeter Dunlap 			}
1080a6d42e7dSPeter Dunlap 
1081a6d42e7dSPeter Dunlap 			mdb_printf("Session %p\n", addr);
1082a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %d\n", "State",
1083a6d42e7dSPeter Dunlap 			    ist.ist_state);
1084a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %d\n", "Last State",
1085a6d42e7dSPeter Dunlap 			    ist.ist_last_state);
1086a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %d\n", "FFP Connections",
1087a6d42e7dSPeter Dunlap 			    ist.ist_ffp_conn_count);
1088a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %02x%02x%02x%02x%02x%02x\n", "ISID",
1089a6d42e7dSPeter Dunlap 			    ist.ist_isid[0], ist.ist_isid[1], ist.ist_isid[2],
1090a6d42e7dSPeter Dunlap 			    ist.ist_isid[3], ist.ist_isid[4], ist.ist_isid[5]);
1091a6d42e7dSPeter Dunlap 			mdb_printf("%16s: 0x%04x\n", "TSIH",
1092a6d42e7dSPeter Dunlap 			    ist.ist_tsih);
1093a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %s\n", "Initiator IQN",
1094a6d42e7dSPeter Dunlap 			    ini_name);
1095a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %s\n", "Target IQN",
1096a6d42e7dSPeter Dunlap 			    tgt_name);
1097a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %08x\n", "ExpCmdSN",
1098a6d42e7dSPeter Dunlap 			    ist.ist_expcmdsn);
1099a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %08x\n", "MaxCmdSN",
1100a6d42e7dSPeter Dunlap 			    ist.ist_maxcmdsn);
1101a6d42e7dSPeter Dunlap 		} else {
1102a6d42e7dSPeter Dunlap 			/* Print session data */
1103a6d42e7dSPeter Dunlap 			if (idc->idc_header) {
1104a6d42e7dSPeter Dunlap 				mdb_printf("%<u>%-?s %10s %-12s %-6s%</u>\n",
1105a6d42e7dSPeter Dunlap 				    "iscsit_sess_t", "State/Conn", "ISID",
1106a6d42e7dSPeter Dunlap 				    "TSIH");
1107a6d42e7dSPeter Dunlap 			}
1108a6d42e7dSPeter Dunlap 			mdb_printf("%?p  %4d/%-4d %02x%02x%02x%02x%02x%02x "
1109a6d42e7dSPeter Dunlap 			    "0x%04x\n", addr,
1110a6d42e7dSPeter Dunlap 			    ist.ist_state, ist.ist_ffp_conn_count,
1111a6d42e7dSPeter Dunlap 			    ist.ist_isid[0], ist.ist_isid[1], ist.ist_isid[2],
1112a6d42e7dSPeter Dunlap 			    ist.ist_isid[3], ist.ist_isid[4], ist.ist_isid[5],
1113a6d42e7dSPeter Dunlap 			    ist.ist_tsih);
1114a6d42e7dSPeter Dunlap 		}
1115a6d42e7dSPeter Dunlap 		idc->idc_header = 0;
1116a6d42e7dSPeter Dunlap 	}
1117a6d42e7dSPeter Dunlap 
1118a6d42e7dSPeter Dunlap 	idc->idc_verbose = 0;
1119a6d42e7dSPeter Dunlap 
1120a6d42e7dSPeter Dunlap 	/*
1121a6d42e7dSPeter Dunlap 	 * Print states if requested
1122a6d42e7dSPeter Dunlap 	 */
1123a6d42e7dSPeter Dunlap 	if (states) {
1124a6d42e7dSPeter Dunlap 		states_addr = addr + offsetof(iscsit_sess_t, ist_state_audit);
1125a6d42e7dSPeter Dunlap 
1126a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(4);
1127a6d42e7dSPeter Dunlap 		mdb_printf("State History:\n");
1128a6d42e7dSPeter Dunlap 		if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
1129a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1130a6d42e7dSPeter Dunlap 
1131a6d42e7dSPeter Dunlap 		/* Don't print state history for child objects */
1132a6d42e7dSPeter Dunlap 		idc->u.child.idc_states = 0;
1133a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
1134a6d42e7dSPeter Dunlap 	}
1135a6d42e7dSPeter Dunlap 
1136a6d42e7dSPeter Dunlap 	/*
1137a6d42e7dSPeter Dunlap 	 * Print refcnt audit data if requested
1138a6d42e7dSPeter Dunlap 	 */
1139a6d42e7dSPeter Dunlap 	if (rc_audit) {
1140a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(4);
1141a6d42e7dSPeter Dunlap 		mdb_printf("Reference History:\n");
1142a6d42e7dSPeter Dunlap 		rc_addr = addr +
1143a6d42e7dSPeter Dunlap 		    offsetof(iscsit_sess_t, ist_refcnt);
1144a6d42e7dSPeter Dunlap 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
1145a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1146a6d42e7dSPeter Dunlap 
1147a6d42e7dSPeter Dunlap 		/* Don't print audit data for child objects */
1148a6d42e7dSPeter Dunlap 		idc->u.child.idc_rc_audit = 0;
1149a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
1150a6d42e7dSPeter Dunlap 	}
1151a6d42e7dSPeter Dunlap 
1152a6d42e7dSPeter Dunlap 	/* Any child objects to walk? */
1153a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_conn || idc->u.child.idc_task ||
1154a6d42e7dSPeter Dunlap 	    idc->u.child.idc_buffer) {
1155a6d42e7dSPeter Dunlap 		/* Walk conn list */
1156a6d42e7dSPeter Dunlap 		idc->idc_header = 1;
1157a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(4);
1158a6d42e7dSPeter Dunlap 		list_addr = addr + offsetof(iscsit_sess_t, ist_conn_list);
1159a6d42e7dSPeter Dunlap 		if (mdb_pwalk("list", iscsi_sess_conn_walk_cb, idc,
1160a6d42e7dSPeter Dunlap 		    list_addr) == -1) {
1161a6d42e7dSPeter Dunlap 			mdb_warn("session conn list walk failed");
1162a6d42e7dSPeter Dunlap 			(void) mdb_dec_indent(4);
1163a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1164a6d42e7dSPeter Dunlap 		}
1165a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
1166a6d42e7dSPeter Dunlap 		idc->idc_header = 0;
1167a6d42e7dSPeter Dunlap 	}
1168a6d42e7dSPeter Dunlap 
1169a6d42e7dSPeter Dunlap 	idc->idc_verbose = verbose;
1170a6d42e7dSPeter Dunlap 	idc->u.child.idc_states = states;
1171a6d42e7dSPeter Dunlap 	idc->u.child.idc_rc_audit = rc_audit;
1172a6d42e7dSPeter Dunlap 
1173a6d42e7dSPeter Dunlap 	return (DCMD_OK);
1174a6d42e7dSPeter Dunlap }
1175a6d42e7dSPeter Dunlap 
1176a6d42e7dSPeter Dunlap static int
1177a6d42e7dSPeter Dunlap iscsi_conn_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
1178a6d42e7dSPeter Dunlap {
1179a6d42e7dSPeter Dunlap 	uintptr_t	idm_global_addr, states_addr, rc_addr;
1180a6d42e7dSPeter Dunlap 	uintptr_t	task_addr, task_ptr;
1181a6d42e7dSPeter Dunlap 	GElf_Sym	sym;
1182a6d42e7dSPeter Dunlap 	idm_task_t	idt;
1183a6d42e7dSPeter Dunlap 	idm_conn_t	ic;
1184a6d42e7dSPeter Dunlap 	char		*conn_type;
1185a6d42e7dSPeter Dunlap 	int		task_idx;
1186a6d42e7dSPeter Dunlap 	char		laddr[PORTAL_STR_LEN];
1187a6d42e7dSPeter Dunlap 	char		raddr[PORTAL_STR_LEN];
1188a6d42e7dSPeter Dunlap 	int		verbose, states, rc_audit;
1189a6d42e7dSPeter Dunlap 
1190a6d42e7dSPeter Dunlap 	/*
1191a6d42e7dSPeter Dunlap 	 * Get pointer to task table
1192a6d42e7dSPeter Dunlap 	 */
1193a6d42e7dSPeter Dunlap 
1194a6d42e7dSPeter Dunlap 	if (mdb_lookup_by_name("idm", &sym) == -1) {
1195a6d42e7dSPeter Dunlap 		mdb_warn("failed to find symbol 'idm'");
1196a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1197a6d42e7dSPeter Dunlap 	}
1198a6d42e7dSPeter Dunlap 
1199a6d42e7dSPeter Dunlap 	idm_global_addr = (uintptr_t)sym.st_value;
1200a6d42e7dSPeter Dunlap 
1201a6d42e7dSPeter Dunlap 	if (mdb_vread(&task_ptr, sizeof (uintptr_t),
1202a6d42e7dSPeter Dunlap 	    idm_global_addr + offsetof(idm_global_t, idm_taskid_table)) !=
1203a6d42e7dSPeter Dunlap 	    sizeof (uintptr_t)) {
1204a6d42e7dSPeter Dunlap 		mdb_warn("Failed to read address of task table");
1205a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1206a6d42e7dSPeter Dunlap 	}
1207a6d42e7dSPeter Dunlap 
1208a6d42e7dSPeter Dunlap 	/*
1209a6d42e7dSPeter Dunlap 	 * Read idm_conn_t
1210a6d42e7dSPeter Dunlap 	 */
1211a6d42e7dSPeter Dunlap 	if (mdb_vread(&ic, sizeof (idm_conn_t), addr) != sizeof (idm_conn_t)) {
1212a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1213a6d42e7dSPeter Dunlap 	}
1214a6d42e7dSPeter Dunlap 	conn_type = (ic.ic_conn_type == CONN_TYPE_INI) ? "Ini" :
1215a6d42e7dSPeter Dunlap 	    (ic.ic_conn_type == CONN_TYPE_TGT) ? "Tgt" : "Unk";
1216a6d42e7dSPeter Dunlap 
1217a6d42e7dSPeter Dunlap 	/*
1218a6d42e7dSPeter Dunlap 	 * Brief output
1219a6d42e7dSPeter Dunlap 	 *
1220a6d42e7dSPeter Dunlap 	 * idm_conn_t pointer
1221a6d42e7dSPeter Dunlap 	 * idm_conn_t.ic_conn_type
1222a6d42e7dSPeter Dunlap 	 * idm_conn_t.ic_statet+idm_conn_t.ic_ffp
1223a6d42e7dSPeter Dunlap 	 */
1224a6d42e7dSPeter Dunlap 
1225a6d42e7dSPeter Dunlap 	verbose = idc->idc_verbose;
1226a6d42e7dSPeter Dunlap 	states = idc->u.child.idc_states;
1227a6d42e7dSPeter Dunlap 	rc_audit = idc->u.child.idc_rc_audit;
1228a6d42e7dSPeter Dunlap 
1229a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_conn) {
1230a6d42e7dSPeter Dunlap 		if (idc->idc_verbose) {
1231a6d42e7dSPeter Dunlap 			mdb_printf("IDM Conn %p\n", addr);
1232a6d42e7dSPeter Dunlap 			if (ic.ic_conn_type == CONN_TYPE_TGT) {
1233a6d42e7dSPeter Dunlap 				iscsi_print_iscsit_conn_data(&ic);
1234a6d42e7dSPeter Dunlap 			} else {
1235a6d42e7dSPeter Dunlap 				iscsi_print_idm_conn_data(&ic);
1236a6d42e7dSPeter Dunlap 			}
1237a6d42e7dSPeter Dunlap 		} else {
1238a6d42e7dSPeter Dunlap 			/* Print connection data */
1239a6d42e7dSPeter Dunlap 			if (idc->idc_header) {
1240a6d42e7dSPeter Dunlap 				mdb_printf("%<u>%-?s %-6s %-10s %12s%</u>\n",
1241a6d42e7dSPeter Dunlap 				    "idm_conn_t", "Type", "Transport",
1242a6d42e7dSPeter Dunlap 				    "State/FFP");
1243a6d42e7dSPeter Dunlap 			}
1244a6d42e7dSPeter Dunlap 			mdb_printf("%?p %-6s %-10s %6d/%-6d\n", addr, conn_type,
1245a6d42e7dSPeter Dunlap 			    (ic.ic_transport_type ==
1246a6d42e7dSPeter Dunlap 			    IDM_TRANSPORT_TYPE_ISER) ? "ISER_IB" :
1247a6d42e7dSPeter Dunlap 			    (ic.ic_transport_type ==
1248a6d42e7dSPeter Dunlap 			    IDM_TRANSPORT_TYPE_SOCKETS) ? "SOCKETS" :
1249a6d42e7dSPeter Dunlap 			    "N/A",
1250a6d42e7dSPeter Dunlap 			    ic.ic_state, ic.ic_ffp);
1251a6d42e7dSPeter Dunlap 			if (idc->u.child.idc_print_ip) {
1252a6d42e7dSPeter Dunlap 				sa_to_str(&ic.ic_laddr, laddr);
1253a6d42e7dSPeter Dunlap 				sa_to_str(&ic.ic_raddr, raddr);
1254a6d42e7dSPeter Dunlap 				mdb_printf("  L%s  R%s\n",
1255a6d42e7dSPeter Dunlap 				    laddr, raddr);
1256a6d42e7dSPeter Dunlap 			}
1257a6d42e7dSPeter Dunlap 		}
1258a6d42e7dSPeter Dunlap 	}
1259a6d42e7dSPeter Dunlap 	idc->idc_header = 0;
1260a6d42e7dSPeter Dunlap 
1261a6d42e7dSPeter Dunlap 	idc->idc_verbose = 0;
1262a6d42e7dSPeter Dunlap 
1263a6d42e7dSPeter Dunlap 	/*
1264a6d42e7dSPeter Dunlap 	 * Print states if requested
1265a6d42e7dSPeter Dunlap 	 */
1266a6d42e7dSPeter Dunlap 	if (states) {
1267a6d42e7dSPeter Dunlap 		states_addr = addr + offsetof(idm_conn_t, ic_state_audit);
1268a6d42e7dSPeter Dunlap 
1269a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(4);
1270a6d42e7dSPeter Dunlap 		mdb_printf("State History:\n");
1271a6d42e7dSPeter Dunlap 		if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
1272a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1273a6d42e7dSPeter Dunlap 
1274a6d42e7dSPeter Dunlap 		/* Don't print state history for child objects */
1275a6d42e7dSPeter Dunlap 		idc->u.child.idc_states = 0;
1276a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
1277a6d42e7dSPeter Dunlap 	}
1278a6d42e7dSPeter Dunlap 
1279a6d42e7dSPeter Dunlap 	/*
1280a6d42e7dSPeter Dunlap 	 * Print refcnt audit data if requested
1281a6d42e7dSPeter Dunlap 	 */
1282a6d42e7dSPeter Dunlap 	if (rc_audit) {
1283a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(4);
1284a6d42e7dSPeter Dunlap 		mdb_printf("Reference History:\n");
1285a6d42e7dSPeter Dunlap 		rc_addr = addr + offsetof(idm_conn_t, ic_refcnt);
1286a6d42e7dSPeter Dunlap 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
1287a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1288a6d42e7dSPeter Dunlap 
1289a6d42e7dSPeter Dunlap 		/* Don't print audit data for child objects */
1290a6d42e7dSPeter Dunlap 		idc->u.child.idc_rc_audit = 0;
1291a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
1292a6d42e7dSPeter Dunlap 	}
1293a6d42e7dSPeter Dunlap 
1294a6d42e7dSPeter Dunlap 	task_idx = 0;
1295a6d42e7dSPeter Dunlap 
1296a6d42e7dSPeter Dunlap 	/* Any child objects to walk? */
1297a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_task || idc->u.child.idc_buffer) {
1298a6d42e7dSPeter Dunlap 		idc->idc_header = 1;
1299a6d42e7dSPeter Dunlap 		while (task_idx < IDM_TASKIDS_MAX) {
1300a6d42e7dSPeter Dunlap 
1301a6d42e7dSPeter Dunlap 			/*
1302a6d42e7dSPeter Dunlap 			 * Read the next idm_task_t
1303a6d42e7dSPeter Dunlap 			 */
1304a6d42e7dSPeter Dunlap 
1305a6d42e7dSPeter Dunlap 			if (mdb_vread(&task_addr, sizeof (uintptr_t),
1306a6d42e7dSPeter Dunlap 			    task_ptr) != sizeof (uintptr_t)) {
1307a6d42e7dSPeter Dunlap 				mdb_warn("Failed to read task pointer");
1308a6d42e7dSPeter Dunlap 				return (DCMD_ERR);
1309a6d42e7dSPeter Dunlap 			}
1310a6d42e7dSPeter Dunlap 
1311a6d42e7dSPeter Dunlap 			if (task_addr == NULL) {
1312a6d42e7dSPeter Dunlap 				task_ptr += sizeof (uintptr_t);
1313a6d42e7dSPeter Dunlap 				task_idx++;
1314a6d42e7dSPeter Dunlap 				continue;
1315a6d42e7dSPeter Dunlap 			}
1316a6d42e7dSPeter Dunlap 
1317a6d42e7dSPeter Dunlap 			if (mdb_vread(&idt, sizeof (idm_task_t), task_addr)
1318a6d42e7dSPeter Dunlap 			    != sizeof (idm_task_t)) {
1319a6d42e7dSPeter Dunlap 				mdb_warn("Failed to read task pointer");
1320a6d42e7dSPeter Dunlap 				return (DCMD_ERR);
1321a6d42e7dSPeter Dunlap 			}
1322a6d42e7dSPeter Dunlap 
1323a6d42e7dSPeter Dunlap 			if (((uintptr_t)idt.idt_ic == addr) &&
1324a6d42e7dSPeter Dunlap 			    (idt.idt_state != TASK_IDLE)) {
1325a6d42e7dSPeter Dunlap 				(void) mdb_inc_indent(4);
1326a6d42e7dSPeter Dunlap 				if (iscsi_i_task_impl(&idt, task_addr, idc)
1327a6d42e7dSPeter Dunlap 				    == -1) {
1328a6d42e7dSPeter Dunlap 					mdb_warn("Failed to walk connection "
1329a6d42e7dSPeter Dunlap 					    "task tree");
1330a6d42e7dSPeter Dunlap 					(void) mdb_dec_indent(4);
1331a6d42e7dSPeter Dunlap 					return (DCMD_ERR);
1332a6d42e7dSPeter Dunlap 				}
1333a6d42e7dSPeter Dunlap 				(void) mdb_dec_indent(4);
1334a6d42e7dSPeter Dunlap 			}
1335a6d42e7dSPeter Dunlap 
1336a6d42e7dSPeter Dunlap 			task_ptr += sizeof (uintptr_t);
1337a6d42e7dSPeter Dunlap 			task_idx++;
1338a6d42e7dSPeter Dunlap 		}
1339a6d42e7dSPeter Dunlap 		idc->idc_header = 0;
1340a6d42e7dSPeter Dunlap 	}
1341a6d42e7dSPeter Dunlap 
1342a6d42e7dSPeter Dunlap 	idc->idc_verbose = verbose;
1343a6d42e7dSPeter Dunlap 	idc->u.child.idc_states = states;
1344a6d42e7dSPeter Dunlap 	idc->u.child.idc_rc_audit = rc_audit;
1345a6d42e7dSPeter Dunlap 
1346a6d42e7dSPeter Dunlap 	return (DCMD_OK);
1347a6d42e7dSPeter Dunlap }
1348a6d42e7dSPeter Dunlap 
1349a6d42e7dSPeter Dunlap static void
1350a6d42e7dSPeter Dunlap iscsi_print_iscsit_conn_data(idm_conn_t *ic)
1351a6d42e7dSPeter Dunlap {
1352a6d42e7dSPeter Dunlap 	iscsit_conn_t	ict;
1353a6d42e7dSPeter Dunlap 	char		*csg;
1354a6d42e7dSPeter Dunlap 	char		*nsg;
1355a6d42e7dSPeter Dunlap 
1356a6d42e7dSPeter Dunlap 	iscsi_print_idm_conn_data(ic);
1357a6d42e7dSPeter Dunlap 
1358a6d42e7dSPeter Dunlap 	if (mdb_vread(&ict, sizeof (iscsit_conn_t),
1359a6d42e7dSPeter Dunlap 	    (uintptr_t)ic->ic_handle) != sizeof (iscsit_conn_t)) {
1360a6d42e7dSPeter Dunlap 		mdb_printf("**Failed to read conn private data\n");
1361a6d42e7dSPeter Dunlap 		return;
1362a6d42e7dSPeter Dunlap 	}
1363a6d42e7dSPeter Dunlap 
1364a6d42e7dSPeter Dunlap 	if (ict.ict_login_sm.icl_login_state != ILS_LOGIN_DONE) {
1365a6d42e7dSPeter Dunlap 		switch (ict.ict_login_sm.icl_login_csg) {
1366a6d42e7dSPeter Dunlap 		case ISCSI_SECURITY_NEGOTIATION_STAGE:
1367a6d42e7dSPeter Dunlap 			csg = "Security";
1368a6d42e7dSPeter Dunlap 			break;
1369a6d42e7dSPeter Dunlap 		case ISCSI_OP_PARMS_NEGOTIATION_STAGE:
1370a6d42e7dSPeter Dunlap 			csg = "Operational";
1371a6d42e7dSPeter Dunlap 			break;
1372a6d42e7dSPeter Dunlap 		case ISCSI_FULL_FEATURE_PHASE:
1373a6d42e7dSPeter Dunlap 			csg = "FFP";
1374a6d42e7dSPeter Dunlap 			break;
1375a6d42e7dSPeter Dunlap 		default:
1376a6d42e7dSPeter Dunlap 			csg = "Unknown";
1377a6d42e7dSPeter Dunlap 		}
1378a6d42e7dSPeter Dunlap 		switch (ict.ict_login_sm.icl_login_nsg) {
1379a6d42e7dSPeter Dunlap 		case ISCSI_SECURITY_NEGOTIATION_STAGE:
1380a6d42e7dSPeter Dunlap 			nsg = "Security";
1381a6d42e7dSPeter Dunlap 			break;
1382a6d42e7dSPeter Dunlap 		case ISCSI_OP_PARMS_NEGOTIATION_STAGE:
1383a6d42e7dSPeter Dunlap 			nsg = "Operational";
1384a6d42e7dSPeter Dunlap 			break;
1385a6d42e7dSPeter Dunlap 		case ISCSI_FULL_FEATURE_PHASE:
1386a6d42e7dSPeter Dunlap 			nsg = "FFP";
1387a6d42e7dSPeter Dunlap 			break;
1388a6d42e7dSPeter Dunlap 		default:
1389a6d42e7dSPeter Dunlap 			nsg = "Unknown";
1390a6d42e7dSPeter Dunlap 		}
1391a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %d\n", "Login State",
1392a6d42e7dSPeter Dunlap 		    ict.ict_login_sm.icl_login_state);
1393a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %d\n", "Login Last State",
1394a6d42e7dSPeter Dunlap 		    ict.ict_login_sm.icl_login_last_state);
1395a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %s\n", "CSG", csg);
1396a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %s\n", "NSG", nsg);
1397a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %d\n", "Transit",
1398a6d42e7dSPeter Dunlap 		    ict.ict_login_sm.icl_login_transit >> 7);
1399a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %p\n", "Request nvlist",
1400a6d42e7dSPeter Dunlap 		    ict.ict_login_sm.icl_request_nvlist);
1401a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %p\n", "Response nvlist",
1402a6d42e7dSPeter Dunlap 		    ict.ict_login_sm.icl_response_nvlist);
1403a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %p\n", "Negotiated nvlist",
1404a6d42e7dSPeter Dunlap 		    ict.ict_login_sm.icl_negotiated_values);
1405a6d42e7dSPeter Dunlap 		if (ict.ict_login_sm.icl_login_state == ILS_LOGIN_ERROR) {
1406a6d42e7dSPeter Dunlap 			mdb_printf("%20s: 0x%02x\n", "Error Class",
1407a6d42e7dSPeter Dunlap 			    ict.ict_login_sm.icl_login_resp_err_class);
1408a6d42e7dSPeter Dunlap 			mdb_printf("%20s: 0x%02x\n", "Error Detail",
1409a6d42e7dSPeter Dunlap 			    ict.ict_login_sm.icl_login_resp_err_detail);
1410a6d42e7dSPeter Dunlap 		}
1411a6d42e7dSPeter Dunlap 	}
1412a6d42e7dSPeter Dunlap 	mdb_printf("%20s: 0x%04x\n", "CID", ict.ict_cid);
1413a6d42e7dSPeter Dunlap 	mdb_printf("%20s: 0x%08x\n", "StatSN", ict.ict_statsn);
1414a6d42e7dSPeter Dunlap }
1415a6d42e7dSPeter Dunlap 
1416a6d42e7dSPeter Dunlap static void
1417a6d42e7dSPeter Dunlap iscsi_print_idm_conn_data(idm_conn_t *ic)
1418a6d42e7dSPeter Dunlap {
1419a6d42e7dSPeter Dunlap 	char		laddr[PORTAL_STR_LEN];
1420a6d42e7dSPeter Dunlap 	char		raddr[PORTAL_STR_LEN];
1421a6d42e7dSPeter Dunlap 
1422a6d42e7dSPeter Dunlap 	sa_to_str(&ic->ic_laddr, laddr);
1423a6d42e7dSPeter Dunlap 	sa_to_str(&ic->ic_raddr, raddr);
1424a6d42e7dSPeter Dunlap 
1425a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %s\n", "Conn Type",
1426a6d42e7dSPeter Dunlap 	    ((ic->ic_conn_type == CONN_TYPE_TGT) ? "Target" :
1427a6d42e7dSPeter Dunlap 	    ((ic->ic_conn_type == CONN_TYPE_INI) ? "Initiator" :
1428a6d42e7dSPeter Dunlap 	    "Unknown")));
1429a6d42e7dSPeter Dunlap 	if (ic->ic_conn_type == CONN_TYPE_TGT) {
1430a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %p\n", "Svc. Binding",
1431a6d42e7dSPeter Dunlap 		    ic->ic_svc_binding);
1432a6d42e7dSPeter Dunlap 	}
1433a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %s\n", "Transport",
1434a6d42e7dSPeter Dunlap 	    (ic->ic_transport_type == IDM_TRANSPORT_TYPE_ISER) ? "ISER_IB" :
1435a6d42e7dSPeter Dunlap 	    (ic->ic_transport_type == IDM_TRANSPORT_TYPE_SOCKETS) ? "SOCKETS" :
1436a6d42e7dSPeter Dunlap 	    "N/A");
1437a6d42e7dSPeter Dunlap 
1438a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %s\n", "Local IP", laddr);
1439a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %s\n", "Remote IP", raddr);
1440a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %d\n", "State",
1441a6d42e7dSPeter Dunlap 	    ic->ic_state);
1442a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %d\n", "Last State",
1443a6d42e7dSPeter Dunlap 	    ic->ic_last_state);
1444a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %d %s\n", "Refcount",
1445a6d42e7dSPeter Dunlap 	    ic->ic_refcnt.ir_refcnt,
1446a6d42e7dSPeter Dunlap 	    (ic->ic_refcnt.ir_waiting == REF_NOWAIT) ? "" :
1447a6d42e7dSPeter Dunlap 	    ((ic->ic_refcnt.ir_waiting == REF_WAIT_SYNC) ? "REF_WAIT_SYNC" :
1448a6d42e7dSPeter Dunlap 	    ((ic->ic_refcnt.ir_waiting == REF_WAIT_ASYNC) ? "REF_WAIT_ASYNC" :
1449a6d42e7dSPeter Dunlap 	    "UNKNOWN")));
1450a6d42e7dSPeter Dunlap }
1451a6d42e7dSPeter Dunlap 
1452a6d42e7dSPeter Dunlap static int
1453a6d42e7dSPeter Dunlap iscsi_i_task_impl(idm_task_t *idt, uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
1454a6d42e7dSPeter Dunlap {
1455a6d42e7dSPeter Dunlap 	uintptr_t	list_addr, rc_addr;
1456a6d42e7dSPeter Dunlap 	idm_conn_type_t	conn_type;
1457a6d42e7dSPeter Dunlap 	int		verbose, states, rc_audit;
1458a6d42e7dSPeter Dunlap 
1459a6d42e7dSPeter Dunlap 	conn_type = idm_conn_type((uintptr_t)idt->idt_ic);
1460a6d42e7dSPeter Dunlap 
1461a6d42e7dSPeter Dunlap 	verbose = idc->idc_verbose;
1462a6d42e7dSPeter Dunlap 	states = idc->u.child.idc_states;
1463a6d42e7dSPeter Dunlap 	rc_audit = idc->u.child.idc_rc_audit;
1464a6d42e7dSPeter Dunlap 
1465a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_task) {
1466a6d42e7dSPeter Dunlap 		if (verbose) {
1467a6d42e7dSPeter Dunlap 			mdb_printf("Task %p\n", addr);
1468a6d42e7dSPeter Dunlap 			(void) mdb_inc_indent(2);
1469a6d42e7dSPeter Dunlap 			if (conn_type == CONN_TYPE_TGT) {
1470a6d42e7dSPeter Dunlap 				iscsi_print_iscsit_task_data(idt);
1471a6d42e7dSPeter Dunlap 			}
1472a6d42e7dSPeter Dunlap 			(void) mdb_dec_indent(2);
1473a6d42e7dSPeter Dunlap 		} else {
1474a6d42e7dSPeter Dunlap 			/* Print task data */
1475a6d42e7dSPeter Dunlap 			if (idc->idc_header) {
1476a6d42e7dSPeter Dunlap 				mdb_printf(
1477bf604c64SPeter Dunlap 				    "%<u>%-?s %-16s %-4s %-8s %-8s%</u>\n",
1478bf604c64SPeter Dunlap 				    "Tasks:", "State", "Ref",
1479a6d42e7dSPeter Dunlap 				    (conn_type == CONN_TYPE_TGT ? "TTT" :
1480a6d42e7dSPeter Dunlap 				    (conn_type == CONN_TYPE_INI ? "ITT" :
1481a6d42e7dSPeter Dunlap 				    "TT")), "Handle");
1482a6d42e7dSPeter Dunlap 			}
1483bf604c64SPeter Dunlap 			mdb_printf("%?p %-16s %04x %08x %08x\n", addr,
1484bf604c64SPeter Dunlap 			    idm_ts_name[idt->idt_state],
1485bf604c64SPeter Dunlap 			    idt->idt_refcnt.ir_refcnt,
1486bf604c64SPeter Dunlap 			    idt->idt_tt, idt->idt_client_handle);
1487a6d42e7dSPeter Dunlap 		}
1488a6d42e7dSPeter Dunlap 	}
1489a6d42e7dSPeter Dunlap 	idc->idc_header = 0;
1490a6d42e7dSPeter Dunlap 	idc->idc_verbose = 0;
1491a6d42e7dSPeter Dunlap 
1492a6d42e7dSPeter Dunlap 	/*
1493a6d42e7dSPeter Dunlap 	 * Print states if requested
1494a6d42e7dSPeter Dunlap 	 */
1495a6d42e7dSPeter Dunlap #if 0
1496a6d42e7dSPeter Dunlap 	if (states) {
1497a6d42e7dSPeter Dunlap 		states_addr = addr + offsetof(idm_task_t, idt_state_audit);
1498a6d42e7dSPeter Dunlap 
1499a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(4);
1500a6d42e7dSPeter Dunlap 		mdb_printf("State History:\n");
1501a6d42e7dSPeter Dunlap 		if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
1502a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1503a6d42e7dSPeter Dunlap 
1504a6d42e7dSPeter Dunlap 		/* Don't print state history for child objects */
1505a6d42e7dSPeter Dunlap 		idc->u.child.idc_states = 0;
1506a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
1507a6d42e7dSPeter Dunlap 	}
1508a6d42e7dSPeter Dunlap #endif
1509a6d42e7dSPeter Dunlap 
1510a6d42e7dSPeter Dunlap 	/*
1511a6d42e7dSPeter Dunlap 	 * Print refcnt audit data if requested
1512a6d42e7dSPeter Dunlap 	 */
1513a6d42e7dSPeter Dunlap 	if (rc_audit) {
1514a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(4);
1515a6d42e7dSPeter Dunlap 		mdb_printf("Reference History:\n");
1516a6d42e7dSPeter Dunlap 		rc_addr = addr +
1517a6d42e7dSPeter Dunlap 		    offsetof(idm_task_t, idt_refcnt);
1518a6d42e7dSPeter Dunlap 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
1519a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1520a6d42e7dSPeter Dunlap 
1521a6d42e7dSPeter Dunlap 		/* Don't print audit data for child objects */
1522a6d42e7dSPeter Dunlap 		idc->u.child.idc_rc_audit = 0;
1523a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
1524a6d42e7dSPeter Dunlap 	}
1525a6d42e7dSPeter Dunlap 
1526a6d42e7dSPeter Dunlap 
1527a6d42e7dSPeter Dunlap 	/* Buffers are leaf objects */
1528a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_buffer) {
1529a6d42e7dSPeter Dunlap 		/* Walk in buffer list */
1530a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(2);
1531a6d42e7dSPeter Dunlap 		mdb_printf("In buffers:\n");
1532a6d42e7dSPeter Dunlap 		idc->idc_header = 1;
1533a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(2);
1534a6d42e7dSPeter Dunlap 		list_addr = addr + offsetof(idm_task_t, idt_inbufv);
1535a6d42e7dSPeter Dunlap 		if (mdb_pwalk("list", iscsi_buffer_walk_cb, idc, list_addr) ==
1536a6d42e7dSPeter Dunlap 		    -1) {
1537a6d42e7dSPeter Dunlap 			mdb_warn("list walk failed for task in buffers");
1538a6d42e7dSPeter Dunlap 			(void) mdb_dec_indent(4);
1539a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1540a6d42e7dSPeter Dunlap 		}
1541a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(2);
1542a6d42e7dSPeter Dunlap 		/* Walk out buffer list */
1543a6d42e7dSPeter Dunlap 		mdb_printf("Out buffers:\n");
1544a6d42e7dSPeter Dunlap 		idc->idc_header = 1;
1545a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(2);
1546a6d42e7dSPeter Dunlap 		list_addr = addr + offsetof(idm_task_t, idt_outbufv);
1547a6d42e7dSPeter Dunlap 		if (mdb_pwalk("list", iscsi_buffer_walk_cb, idc, list_addr) ==
1548a6d42e7dSPeter Dunlap 		    -1) {
1549a6d42e7dSPeter Dunlap 			mdb_warn("list walk failed for task out buffers\n");
1550a6d42e7dSPeter Dunlap 			(void) mdb_dec_indent(2);
1551a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1552a6d42e7dSPeter Dunlap 		}
1553a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
1554a6d42e7dSPeter Dunlap 	}
1555a6d42e7dSPeter Dunlap 
1556a6d42e7dSPeter Dunlap 	idc->idc_verbose = verbose;
1557a6d42e7dSPeter Dunlap 	idc->u.child.idc_states = states;
1558a6d42e7dSPeter Dunlap 	idc->u.child.idc_rc_audit = rc_audit;
1559a6d42e7dSPeter Dunlap 
1560a6d42e7dSPeter Dunlap 	return (DCMD_OK);
1561a6d42e7dSPeter Dunlap }
1562a6d42e7dSPeter Dunlap 
1563a6d42e7dSPeter Dunlap static int
1564a6d42e7dSPeter Dunlap iscsi_task_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
1565a6d42e7dSPeter Dunlap {
1566a6d42e7dSPeter Dunlap 	idm_task_t	idt;
1567a6d42e7dSPeter Dunlap 
1568a6d42e7dSPeter Dunlap 	/*
1569a6d42e7dSPeter Dunlap 	 * Read idm_conn_t
1570a6d42e7dSPeter Dunlap 	 */
1571a6d42e7dSPeter Dunlap 	if (mdb_vread(&idt, sizeof (idm_task_t), addr) != sizeof (idm_task_t)) {
1572a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1573a6d42e7dSPeter Dunlap 	}
1574a6d42e7dSPeter Dunlap 
1575a6d42e7dSPeter Dunlap 	return (iscsi_i_task_impl(&idt, addr, idc));
1576a6d42e7dSPeter Dunlap }
1577a6d42e7dSPeter Dunlap 
1578a6d42e7dSPeter Dunlap #define	ISCSI_CDB_INDENT	16
1579a6d42e7dSPeter Dunlap 
1580a6d42e7dSPeter Dunlap static void
1581a6d42e7dSPeter Dunlap iscsi_print_iscsit_task_data(idm_task_t *idt)
1582a6d42e7dSPeter Dunlap {
1583a6d42e7dSPeter Dunlap 	iscsit_task_t	itask;
1584a6d42e7dSPeter Dunlap 	boolean_t	good_scsi_task = B_TRUE;
1585a6d42e7dSPeter Dunlap 	scsi_task_t	scsi_task;
1586a6d42e7dSPeter Dunlap 
1587a6d42e7dSPeter Dunlap 	if (mdb_vread(&itask, sizeof (iscsit_task_t),
1588a6d42e7dSPeter Dunlap 	    (uintptr_t)idt->idt_private) != sizeof (iscsit_task_t)) {
1589a6d42e7dSPeter Dunlap 		mdb_printf("**Failed to read idt_private data\n");
1590a6d42e7dSPeter Dunlap 		return;
1591a6d42e7dSPeter Dunlap 	}
1592a6d42e7dSPeter Dunlap 
1593a6d42e7dSPeter Dunlap 	if (mdb_vread(&scsi_task, sizeof (scsi_task_t),
1594a6d42e7dSPeter Dunlap 	    (uintptr_t)itask.it_stmf_task) != sizeof (scsi_task_t)) {
1595a6d42e7dSPeter Dunlap 		good_scsi_task = B_FALSE;
1596a6d42e7dSPeter Dunlap 	}
1597a6d42e7dSPeter Dunlap 
1598bf604c64SPeter Dunlap 	mdb_printf("%20s: %s(%d)\n", "State",
1599bf604c64SPeter Dunlap 	    idt->idt_state > TASK_MAX_STATE ?
1600bf604c64SPeter Dunlap 	    "UNKNOWN" : idm_ts_name[idt->idt_state],
1601bf604c64SPeter Dunlap 	    idt->idt_state);
1602bf604c64SPeter Dunlap 	mdb_printf("%20s: %d/%d\n", "STMF abort/IDM aborted",
1603bf604c64SPeter Dunlap 	    itask.it_stmf_abort, itask.it_aborted);
1604a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %p/%p/%p%s\n",
1605a6d42e7dSPeter Dunlap 	    "iscsit/STMF/LU", idt->idt_private,
1606a6d42e7dSPeter Dunlap 	    itask.it_stmf_task, good_scsi_task ? scsi_task.task_lu_private : 0,
1607a6d42e7dSPeter Dunlap 	    good_scsi_task ? "" : "**");
1608a6d42e7dSPeter Dunlap 	if (good_scsi_task) {
1609a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %08x/%08x\n", "ITT/TTT",
1610a6d42e7dSPeter Dunlap 		    itask.it_itt, itask.it_ttt);
1611a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %08x\n", "CmdSN",
1612a6d42e7dSPeter Dunlap 		    itask.it_cmdsn);
1613a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %02x %02x %02x %02x %02x %02x %02x %02x\n",
1614a6d42e7dSPeter Dunlap 		    "LU number",
1615a6d42e7dSPeter Dunlap 		    scsi_task.task_lun_no[0], scsi_task.task_lun_no[1],
1616a6d42e7dSPeter Dunlap 		    scsi_task.task_lun_no[2], scsi_task.task_lun_no[3],
1617a6d42e7dSPeter Dunlap 		    scsi_task.task_lun_no[4], scsi_task.task_lun_no[5],
1618a6d42e7dSPeter Dunlap 		    scsi_task.task_lun_no[6], scsi_task.task_lun_no[7]);
1619bf604c64SPeter Dunlap 		mdb_printf("     CDB (%d bytes):\n",
1620a6d42e7dSPeter Dunlap 		    scsi_task.task_cdb_length);
1621a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(ISCSI_CDB_INDENT);
1622a6d42e7dSPeter Dunlap 		if (mdb_dumpptr((uintptr_t)scsi_task.task_cdb,
1623a6d42e7dSPeter Dunlap 		    scsi_task.task_cdb_length,
1624a6d42e7dSPeter Dunlap 		    MDB_DUMP_RELATIVE | MDB_DUMP_TRIM |
1625a6d42e7dSPeter Dunlap 		    MDB_DUMP_GROUP(1),
1626a6d42e7dSPeter Dunlap 		    (mdb_dumpptr_cb_t)mdb_vread, NULL)) {
1627a6d42e7dSPeter Dunlap 			mdb_printf("** Invalid CDB addr (%p)\n",
1628a6d42e7dSPeter Dunlap 			    scsi_task.task_cdb);
1629a6d42e7dSPeter Dunlap 		}
1630a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(ISCSI_CDB_INDENT);
1631a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %d/%d\n", "STMF cur/max bufs",
1632a6d42e7dSPeter Dunlap 		    scsi_task.task_cur_nbufs,
1633a6d42e7dSPeter Dunlap 		    scsi_task.task_max_nbufs);
1634a6d42e7dSPeter Dunlap 		mdb_printf("%20s: 0x%08x/0x%08x/0x%08x\n", "Bytes Exp/Cmd/Done",
1635a6d42e7dSPeter Dunlap 		    scsi_task.task_expected_xfer_length,
1636a6d42e7dSPeter Dunlap 		    scsi_task.task_cmd_xfer_length,
1637a6d42e7dSPeter Dunlap 		    scsi_task.task_nbytes_transferred);
1638a6d42e7dSPeter Dunlap 		mdb_printf("%20s: 0x%x/0x%x\n", "TX-ini start/done",
1639a6d42e7dSPeter Dunlap 		    idt->idt_tx_to_ini_start,
1640a6d42e7dSPeter Dunlap 		    idt->idt_tx_to_ini_done);
1641a6d42e7dSPeter Dunlap 		mdb_printf("%20s: 0x%x/0x%x\n", "RX-ini start/done",
1642a6d42e7dSPeter Dunlap 		    idt->idt_rx_from_ini_start,
1643a6d42e7dSPeter Dunlap 		    idt->idt_rx_from_ini_done);
1644a6d42e7dSPeter Dunlap 	}
1645a6d42e7dSPeter Dunlap }
1646a6d42e7dSPeter Dunlap 
1647a6d42e7dSPeter Dunlap static int
1648a6d42e7dSPeter Dunlap iscsi_buffer_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
1649a6d42e7dSPeter Dunlap {
1650a6d42e7dSPeter Dunlap 	idm_buf_t	idb;
1651a6d42e7dSPeter Dunlap 
1652a6d42e7dSPeter Dunlap 	/*
1653a6d42e7dSPeter Dunlap 	 * Read idm_buf_t
1654a6d42e7dSPeter Dunlap 	 */
1655a6d42e7dSPeter Dunlap 	if (mdb_vread(&idb, sizeof (idm_buf_t), addr) != sizeof (idm_buf_t)) {
1656a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1657a6d42e7dSPeter Dunlap 	}
1658a6d42e7dSPeter Dunlap 
1659a6d42e7dSPeter Dunlap 
1660a6d42e7dSPeter Dunlap 	if (idc->idc_header) {
1661a6d42e7dSPeter Dunlap 		mdb_printf("%<u>%-?s %?s/%-8s %8s %8s %8s%</u>\n",
1662a6d42e7dSPeter Dunlap 		    "idm_buf_t", "Mem Rgn", "Length",
1663a6d42e7dSPeter Dunlap 		    "Rel Off", "Xfer Len", "Exp. Off");
1664a6d42e7dSPeter Dunlap 	}
1665a6d42e7dSPeter Dunlap 	idc->idc_header = 0;
1666a6d42e7dSPeter Dunlap 
1667a6d42e7dSPeter Dunlap 	/* Print buffer data */
1668a6d42e7dSPeter Dunlap 	mdb_printf("%?p %?p/%08x %8x %8x %08x\n", addr,
1669a6d42e7dSPeter Dunlap 	    idb.idb_buf, idb.idb_buflen,
1670a6d42e7dSPeter Dunlap 	    idb.idb_bufoffset, idb.idb_xfer_len,
1671a6d42e7dSPeter Dunlap 	    idb.idb_exp_offset);
1672a6d42e7dSPeter Dunlap 
1673a6d42e7dSPeter Dunlap 
1674a6d42e7dSPeter Dunlap 	/* Buffers are leaf objects */
1675a6d42e7dSPeter Dunlap 
1676a6d42e7dSPeter Dunlap 	return (DCMD_OK);
1677a6d42e7dSPeter Dunlap }
1678a6d42e7dSPeter Dunlap 
1679a6d42e7dSPeter Dunlap static int
1680a6d42e7dSPeter Dunlap iscsi_refcnt_impl(uintptr_t addr)
1681a6d42e7dSPeter Dunlap {
1682a6d42e7dSPeter Dunlap 	idm_refcnt_t		refcnt;
1683a6d42e7dSPeter Dunlap 	refcnt_audit_buf_t	*anb;
1684a6d42e7dSPeter Dunlap 	int			ctr;
1685a6d42e7dSPeter Dunlap 
1686a6d42e7dSPeter Dunlap 	/*
1687a6d42e7dSPeter Dunlap 	 * Print refcnt info
1688a6d42e7dSPeter Dunlap 	 */
1689a6d42e7dSPeter Dunlap 	if (mdb_vread(&refcnt, sizeof (idm_refcnt_t), addr) !=
1690a6d42e7dSPeter Dunlap 	    sizeof (idm_refcnt_t)) {
1691a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1692a6d42e7dSPeter Dunlap 	}
1693a6d42e7dSPeter Dunlap 
1694a6d42e7dSPeter Dunlap 	anb = &refcnt.ir_audit_buf;
1695a6d42e7dSPeter Dunlap 
1696a6d42e7dSPeter Dunlap 	ctr = anb->anb_max_index + 1;
1697a6d42e7dSPeter Dunlap 	anb->anb_index--;
1698a6d42e7dSPeter Dunlap 	anb->anb_index &= anb->anb_max_index;
1699a6d42e7dSPeter Dunlap 
1700a6d42e7dSPeter Dunlap 	while (ctr) {
1701a6d42e7dSPeter Dunlap 		refcnt_audit_record_t	*anr;
1702a6d42e7dSPeter Dunlap 
1703a6d42e7dSPeter Dunlap 		anr = anb->anb_records + anb->anb_index;
1704a6d42e7dSPeter Dunlap 
1705a6d42e7dSPeter Dunlap 		if (anr->anr_depth) {
1706a6d42e7dSPeter Dunlap 			char c[MDB_SYM_NAMLEN];
1707a6d42e7dSPeter Dunlap 			GElf_Sym sym;
1708a6d42e7dSPeter Dunlap 			int i;
1709a6d42e7dSPeter Dunlap 
1710a6d42e7dSPeter Dunlap 			mdb_printf("\nRefCnt: %u\t", anr->anr_refcnt);
1711a6d42e7dSPeter Dunlap 
1712a6d42e7dSPeter Dunlap 			for (i = 0; i < anr->anr_depth; i++) {
1713a6d42e7dSPeter Dunlap 				if (mdb_lookup_by_addr(anr->anr_stack[i],
1714a6d42e7dSPeter Dunlap 				    MDB_SYM_FUZZY, c, sizeof (c),
1715a6d42e7dSPeter Dunlap 				    &sym) == -1) {
1716a6d42e7dSPeter Dunlap 					continue;
1717a6d42e7dSPeter Dunlap 				}
1718a6d42e7dSPeter Dunlap 				mdb_printf("%s+0x%1x", c,
1719a6d42e7dSPeter Dunlap 				    anr->anr_stack[i] -
1720a6d42e7dSPeter Dunlap 				    (uintptr_t)sym.st_value);
1721a6d42e7dSPeter Dunlap 				++i;
1722a6d42e7dSPeter Dunlap 				break;
1723a6d42e7dSPeter Dunlap 			}
1724a6d42e7dSPeter Dunlap 
1725a6d42e7dSPeter Dunlap 			while (i < anr->anr_depth) {
1726a6d42e7dSPeter Dunlap 				if (mdb_lookup_by_addr(anr->anr_stack[i],
1727a6d42e7dSPeter Dunlap 				    MDB_SYM_FUZZY, c, sizeof (c),
1728a6d42e7dSPeter Dunlap 				    &sym) == -1) {
1729a6d42e7dSPeter Dunlap 					++i;
1730a6d42e7dSPeter Dunlap 					continue;
1731a6d42e7dSPeter Dunlap 				}
1732a6d42e7dSPeter Dunlap 				mdb_printf("\n\t\t%s+0x%1x", c,
1733a6d42e7dSPeter Dunlap 				    anr->anr_stack[i] -
1734a6d42e7dSPeter Dunlap 				    (uintptr_t)sym.st_value);
1735a6d42e7dSPeter Dunlap 				++i;
1736a6d42e7dSPeter Dunlap 			}
1737a6d42e7dSPeter Dunlap 			mdb_printf("\n");
1738a6d42e7dSPeter Dunlap 		}
1739a6d42e7dSPeter Dunlap 		anb->anb_index--;
1740a6d42e7dSPeter Dunlap 		anb->anb_index &= anb->anb_max_index;
1741a6d42e7dSPeter Dunlap 		ctr--;
1742a6d42e7dSPeter Dunlap 	}
1743a6d42e7dSPeter Dunlap 
1744a6d42e7dSPeter Dunlap 	return (DCMD_OK);
1745a6d42e7dSPeter Dunlap }
1746a6d42e7dSPeter Dunlap 
1747a6d42e7dSPeter Dunlap static int
1748a6d42e7dSPeter Dunlap iscsi_sm_audit_impl(uintptr_t addr)
1749a6d42e7dSPeter Dunlap {
1750a6d42e7dSPeter Dunlap 	sm_audit_buf_t		audit_buf;
1751a6d42e7dSPeter Dunlap 	int			ctr;
1752a6d42e7dSPeter Dunlap 	const char		*event_name;
1753a6d42e7dSPeter Dunlap 	const char		*state_name;
1754a6d42e7dSPeter Dunlap 	const char		*new_state_name;
1755a6d42e7dSPeter Dunlap 	char			ts_string[40];
1756a6d42e7dSPeter Dunlap 	/*
1757a6d42e7dSPeter Dunlap 	 * Print refcnt info
1758a6d42e7dSPeter Dunlap 	 */
1759a6d42e7dSPeter Dunlap 	if (mdb_vread(&audit_buf, sizeof (sm_audit_buf_t), addr) !=
1760a6d42e7dSPeter Dunlap 	    sizeof (sm_audit_buf_t)) {
1761a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1762a6d42e7dSPeter Dunlap 	}
1763a6d42e7dSPeter Dunlap 
1764a6d42e7dSPeter Dunlap 	ctr = audit_buf.sab_max_index + 1;
1765a6d42e7dSPeter Dunlap 	audit_buf.sab_index++;
1766a6d42e7dSPeter Dunlap 	audit_buf.sab_index &= audit_buf.sab_max_index;
1767a6d42e7dSPeter Dunlap 
1768a6d42e7dSPeter Dunlap 	while (ctr) {
1769a6d42e7dSPeter Dunlap 		sm_audit_record_t	*sar;
1770a6d42e7dSPeter Dunlap 
1771a6d42e7dSPeter Dunlap 		sar = audit_buf.sab_records + audit_buf.sab_index;
1772a6d42e7dSPeter Dunlap 
1773a6d42e7dSPeter Dunlap 		iscsi_format_timestamp(ts_string, 40, &sar->sar_timestamp);
1774a6d42e7dSPeter Dunlap 
1775a6d42e7dSPeter Dunlap 		switch (sar->sar_type) {
1776a6d42e7dSPeter Dunlap 		case SAR_STATE_EVENT:
1777a6d42e7dSPeter Dunlap 			switch (sar->sar_sm_type) {
1778a6d42e7dSPeter Dunlap 			case SAS_IDM_CONN:
1779a6d42e7dSPeter Dunlap 				state_name =
1780a6d42e7dSPeter Dunlap 				    iscsi_idm_conn_state(sar->sar_state);
1781a6d42e7dSPeter Dunlap 				event_name =
1782a6d42e7dSPeter Dunlap 				    iscsi_idm_conn_event(sar->sar_event);
1783a6d42e7dSPeter Dunlap 				break;
1784a6d42e7dSPeter Dunlap 			case SAS_ISCSIT_TGT:
1785a6d42e7dSPeter Dunlap 				state_name =
1786a6d42e7dSPeter Dunlap 				    iscsi_iscsit_tgt_state(sar->sar_state);
1787a6d42e7dSPeter Dunlap 				event_name =
1788a6d42e7dSPeter Dunlap 				    iscsi_iscsit_tgt_event(sar->sar_event);
1789a6d42e7dSPeter Dunlap 				break;
1790a6d42e7dSPeter Dunlap 			case SAS_ISCSIT_SESS:
1791a6d42e7dSPeter Dunlap 				state_name =
1792a6d42e7dSPeter Dunlap 				    iscsi_iscsit_sess_state(sar->sar_state);
1793a6d42e7dSPeter Dunlap 				event_name =
1794a6d42e7dSPeter Dunlap 				    iscsi_iscsit_sess_event(sar->sar_event);
1795a6d42e7dSPeter Dunlap 				break;
1796a6d42e7dSPeter Dunlap 			case SAS_ISCSIT_LOGIN:
1797a6d42e7dSPeter Dunlap 				state_name =
1798a6d42e7dSPeter Dunlap 				    iscsi_iscsit_login_state(sar->sar_state);
1799a6d42e7dSPeter Dunlap 				event_name =
1800a6d42e7dSPeter Dunlap 				    iscsi_iscsit_login_event(sar->sar_event);
1801a6d42e7dSPeter Dunlap 				break;
180230e7468fSPeter Dunlap 			case SAS_ISCSI_CMD:
180330e7468fSPeter Dunlap 				state_name =
180430e7468fSPeter Dunlap 				    iscsi_iscsi_cmd_state(sar->sar_state);
180530e7468fSPeter Dunlap 				event_name=
180630e7468fSPeter Dunlap 				    iscsi_iscsi_cmd_event(sar->sar_event);
180730e7468fSPeter Dunlap 				break;
180830e7468fSPeter Dunlap 			case SAS_ISCSI_SESS:
180930e7468fSPeter Dunlap 				state_name =
181030e7468fSPeter Dunlap 				    iscsi_iscsi_sess_state(sar->sar_state);
181130e7468fSPeter Dunlap 				event_name=
181230e7468fSPeter Dunlap 				    iscsi_iscsi_sess_event(sar->sar_event);
181330e7468fSPeter Dunlap 				break;
1814*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 			case SAS_ISCSI_CONN:
1815*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 				state_name =
1816*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 				    iscsi_iscsi_conn_state(sar->sar_state);
1817*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 				event_name=
1818*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 				    iscsi_iscsi_conn_event(sar->sar_event);
1819*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 				break;
1820a6d42e7dSPeter Dunlap 			default:
1821a6d42e7dSPeter Dunlap 				state_name = event_name = "N/A";
1822a6d42e7dSPeter Dunlap 				break;
1823a6d42e7dSPeter Dunlap 			}
1824a6d42e7dSPeter Dunlap 			mdb_printf("%s|%s (%d)\n\t%9s %s (%d) %p\n",
1825a6d42e7dSPeter Dunlap 			    ts_string, state_name, sar->sar_state,
1826a6d42e7dSPeter Dunlap 			    "Event", event_name,
1827a6d42e7dSPeter Dunlap 			    sar->sar_event, sar->sar_event_info);
1828a6d42e7dSPeter Dunlap 
1829a6d42e7dSPeter Dunlap 			break;
1830a6d42e7dSPeter Dunlap 		case SAR_STATE_CHANGE:
1831a6d42e7dSPeter Dunlap 			switch (sar->sar_sm_type) {
1832a6d42e7dSPeter Dunlap 			case SAS_IDM_CONN:
1833a6d42e7dSPeter Dunlap 				state_name =
1834a6d42e7dSPeter Dunlap 				    iscsi_idm_conn_state(sar->sar_state);
1835a6d42e7dSPeter Dunlap 				new_state_name =
1836a6d42e7dSPeter Dunlap 				    iscsi_idm_conn_state(sar->sar_new_state);
1837a6d42e7dSPeter Dunlap 				break;
1838a6d42e7dSPeter Dunlap 			case SAS_IDM_TASK:
1839a6d42e7dSPeter Dunlap 				state_name =
1840a6d42e7dSPeter Dunlap 				    iscsi_idm_task_state(sar->sar_state);
1841a6d42e7dSPeter Dunlap 				new_state_name =
1842a6d42e7dSPeter Dunlap 				    iscsi_idm_task_state(sar->sar_new_state);
1843a6d42e7dSPeter Dunlap 				break;
1844a6d42e7dSPeter Dunlap 			case SAS_ISCSIT_TGT:
1845a6d42e7dSPeter Dunlap 				state_name =
1846a6d42e7dSPeter Dunlap 				    iscsi_iscsit_tgt_state(sar->sar_state);
1847a6d42e7dSPeter Dunlap 				new_state_name =
1848a6d42e7dSPeter Dunlap 				    iscsi_iscsit_tgt_state(sar->sar_new_state);
1849a6d42e7dSPeter Dunlap 				break;
1850a6d42e7dSPeter Dunlap 			case SAS_ISCSIT_SESS:
1851a6d42e7dSPeter Dunlap 				state_name =
1852a6d42e7dSPeter Dunlap 				    iscsi_iscsit_sess_state(sar->sar_state);
1853a6d42e7dSPeter Dunlap 				new_state_name =
1854a6d42e7dSPeter Dunlap 				    iscsi_iscsit_sess_state(sar->sar_new_state);
1855a6d42e7dSPeter Dunlap 				break;
1856a6d42e7dSPeter Dunlap 			case SAS_ISCSIT_LOGIN:
1857a6d42e7dSPeter Dunlap 				state_name =
1858a6d42e7dSPeter Dunlap 				    iscsi_iscsit_login_state(sar->sar_state);
1859a6d42e7dSPeter Dunlap 				new_state_name =
1860a6d42e7dSPeter Dunlap 				    iscsi_iscsit_login_state(
1861a6d42e7dSPeter Dunlap 				    sar->sar_new_state);
1862a6d42e7dSPeter Dunlap 				break;
186330e7468fSPeter Dunlap 			case SAS_ISCSI_CMD:
186430e7468fSPeter Dunlap 				state_name =
186530e7468fSPeter Dunlap 				    iscsi_iscsi_cmd_state(sar->sar_state);
186630e7468fSPeter Dunlap 				new_state_name=
186730e7468fSPeter Dunlap 				    iscsi_iscsi_cmd_state(sar->sar_new_state);
186830e7468fSPeter Dunlap 				break;
186930e7468fSPeter Dunlap 			case SAS_ISCSI_SESS:
187030e7468fSPeter Dunlap 				state_name =
187130e7468fSPeter Dunlap 				    iscsi_iscsi_sess_state(sar->sar_state);
187230e7468fSPeter Dunlap 				new_state_name=
187330e7468fSPeter Dunlap 				    iscsi_iscsi_sess_state(sar->sar_new_state);
187430e7468fSPeter Dunlap 				break;
187530e7468fSPeter Dunlap 			case SAS_ISCSI_CONN:
187630e7468fSPeter Dunlap 				state_name =
187730e7468fSPeter Dunlap 				    iscsi_iscsi_conn_state(sar->sar_state);
187830e7468fSPeter Dunlap 				new_state_name=
187930e7468fSPeter Dunlap 				    iscsi_iscsi_conn_state(sar->sar_new_state);
188030e7468fSPeter Dunlap 				break;
188130e7468fSPeter Dunlap 			case SAS_ISCSI_LOGIN:
188230e7468fSPeter Dunlap 				state_name =
188330e7468fSPeter Dunlap 				    iscsi_iscsi_login_state(sar->sar_state);
188430e7468fSPeter Dunlap 				new_state_name=
188530e7468fSPeter Dunlap 				    iscsi_iscsi_login_state(sar->sar_new_state);
188630e7468fSPeter Dunlap 				break;
1887a6d42e7dSPeter Dunlap 			default:
1888a6d42e7dSPeter Dunlap 				break;
1889a6d42e7dSPeter Dunlap 			}
1890a6d42e7dSPeter Dunlap 			mdb_printf("%s|%s (%d)\n\t%9s %s (%d)\n",
1891a6d42e7dSPeter Dunlap 			    ts_string, state_name, sar->sar_state,
1892a6d42e7dSPeter Dunlap 			    "New State", new_state_name, sar->sar_new_state);
1893a6d42e7dSPeter Dunlap 		default:
1894a6d42e7dSPeter Dunlap 			state_name = new_state_name = "N/A";
1895a6d42e7dSPeter Dunlap 			break;
1896a6d42e7dSPeter Dunlap 		}
1897a6d42e7dSPeter Dunlap 
1898a6d42e7dSPeter Dunlap 		audit_buf.sab_index++;
1899a6d42e7dSPeter Dunlap 		audit_buf.sab_index &= audit_buf.sab_max_index;
1900a6d42e7dSPeter Dunlap 		ctr--;
1901a6d42e7dSPeter Dunlap 	}
1902a6d42e7dSPeter Dunlap 
1903a6d42e7dSPeter Dunlap 	return (DCMD_OK);
1904a6d42e7dSPeter Dunlap }
1905a6d42e7dSPeter Dunlap 
1906a6d42e7dSPeter Dunlap static const char *
190730e7468fSPeter Dunlap iscsi_idm_conn_event(unsigned int event)
1908a6d42e7dSPeter Dunlap {
190930e7468fSPeter Dunlap 	return ((event < CE_MAX_EVENT) ? idm_ce_name[event] : "N/A");
1910a6d42e7dSPeter Dunlap }
1911a6d42e7dSPeter Dunlap 
1912a6d42e7dSPeter Dunlap static const char *
191330e7468fSPeter Dunlap iscsi_iscsit_tgt_event(unsigned int event)
1914a6d42e7dSPeter Dunlap {
191530e7468fSPeter Dunlap 	return ((event < TE_MAX_EVENT) ? iscsit_te_name[event] : "N/A");
1916a6d42e7dSPeter Dunlap }
1917a6d42e7dSPeter Dunlap 
1918a6d42e7dSPeter Dunlap static const char *
191930e7468fSPeter Dunlap iscsi_iscsit_sess_event(unsigned int event)
1920a6d42e7dSPeter Dunlap {
192130e7468fSPeter Dunlap 	return ((event < SE_MAX_EVENT) ? iscsit_se_name[event] : "N/A");
1922a6d42e7dSPeter Dunlap }
1923a6d42e7dSPeter Dunlap 
1924a6d42e7dSPeter Dunlap static const char *
192530e7468fSPeter Dunlap iscsi_iscsit_login_event(unsigned int event)
1926a6d42e7dSPeter Dunlap {
192730e7468fSPeter Dunlap 	return ((event < ILE_MAX_EVENT) ? iscsit_ile_name[event] : "N/A");
192830e7468fSPeter Dunlap }
1929a6d42e7dSPeter Dunlap 
193030e7468fSPeter Dunlap static const char *
193130e7468fSPeter Dunlap iscsi_iscsi_cmd_event(unsigned int event)
193230e7468fSPeter Dunlap {
193330e7468fSPeter Dunlap 	return ((event < ISCSI_CMD_EVENT_MAX) ?
193430e7468fSPeter Dunlap 	    iscsi_cmd_event_names[event] : "N/A");
1935a6d42e7dSPeter Dunlap }
1936a6d42e7dSPeter Dunlap 
1937a6d42e7dSPeter Dunlap static const char *
193830e7468fSPeter Dunlap iscsi_iscsi_sess_event(unsigned int event)
1939a6d42e7dSPeter Dunlap {
1940a6d42e7dSPeter Dunlap 
194130e7468fSPeter Dunlap 	return ((event < ISCSI_SESS_EVENT_MAX) ?
194230e7468fSPeter Dunlap 	    iscsi_sess_event_names[event] : "N/A");
194330e7468fSPeter Dunlap }
1944a6d42e7dSPeter Dunlap 
194530e7468fSPeter Dunlap static const char *
194630e7468fSPeter Dunlap iscsi_idm_conn_state(unsigned int state)
194730e7468fSPeter Dunlap {
194830e7468fSPeter Dunlap 	return ((state < CS_MAX_STATE) ? idm_cs_name[state] : "N/A");
1949a6d42e7dSPeter Dunlap }
1950a6d42e7dSPeter Dunlap 
1951*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States static const char *
1952*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States iscsi_iscsi_conn_event(unsigned int event)
1953*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States {
1954*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
1955*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	return ((event < CN_MAX) ? idm_cn_strings[event] : "N/A");
1956*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States }
1957*5f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
1958a6d42e7dSPeter Dunlap /*ARGSUSED*/
1959a6d42e7dSPeter Dunlap static const char *
196030e7468fSPeter Dunlap iscsi_idm_task_state(unsigned int state)
1961a6d42e7dSPeter Dunlap {
196230e7468fSPeter Dunlap 	return ("N/A");
1963a6d42e7dSPeter Dunlap }
1964a6d42e7dSPeter Dunlap 
1965a6d42e7dSPeter Dunlap static const char *
196630e7468fSPeter Dunlap iscsi_iscsit_tgt_state(unsigned int state)
1967a6d42e7dSPeter Dunlap {
196830e7468fSPeter Dunlap 	return ((state < TS_MAX_STATE) ? iscsit_ts_name[state] : "N/A");
1969a6d42e7dSPeter Dunlap }
1970a6d42e7dSPeter Dunlap 
1971a6d42e7dSPeter Dunlap static const char *
197230e7468fSPeter Dunlap iscsi_iscsit_sess_state(unsigned int state)
1973a6d42e7dSPeter Dunlap {
197430e7468fSPeter Dunlap 	return ((state < SS_MAX_STATE) ? iscsit_ss_name[state] : "N/A");
197530e7468fSPeter Dunlap }
1976a6d42e7dSPeter Dunlap 
197730e7468fSPeter Dunlap static const char *
197830e7468fSPeter Dunlap iscsi_iscsit_login_state(unsigned int state)
197930e7468fSPeter Dunlap {
198030e7468fSPeter Dunlap 	return ((state < ILS_MAX_STATE) ? iscsit_ils_name[state] : "N/A");
1981a6d42e7dSPeter Dunlap }
1982a6d42e7dSPeter Dunlap 
1983a6d42e7dSPeter Dunlap static const char *
198430e7468fSPeter Dunlap iscsi_iscsi_cmd_state(unsigned int state)
1985a6d42e7dSPeter Dunlap {
198630e7468fSPeter Dunlap 	return ((state < ISCSI_CMD_STATE_MAX) ?
198730e7468fSPeter Dunlap 	    iscsi_cmd_state_names[state] : "N/A");
198830e7468fSPeter Dunlap }
1989a6d42e7dSPeter Dunlap 
199030e7468fSPeter Dunlap static const char *
199130e7468fSPeter Dunlap iscsi_iscsi_sess_state(unsigned int state)
199230e7468fSPeter Dunlap {
199330e7468fSPeter Dunlap 	return ((state < ISCSI_SESS_STATE_MAX) ?
199430e7468fSPeter Dunlap 	    iscsi_sess_state_names[state] : "N/A");
199530e7468fSPeter Dunlap }
1996a6d42e7dSPeter Dunlap 
199730e7468fSPeter Dunlap static const char *
199830e7468fSPeter Dunlap iscsi_iscsi_conn_state(unsigned int state)
199930e7468fSPeter Dunlap {
200030e7468fSPeter Dunlap 	return ((state < ISCSI_CONN_STATE_MAX) ? iscsi_ics_name[state] : "N/A");
2001a6d42e7dSPeter Dunlap }
2002a6d42e7dSPeter Dunlap 
200330e7468fSPeter Dunlap static const char *
200430e7468fSPeter Dunlap iscsi_iscsi_login_state(unsigned int state)
200530e7468fSPeter Dunlap {
200630e7468fSPeter Dunlap 	return ((state < LOGIN_MAX) ? iscsi_login_state_names[state] : "N/A");
200730e7468fSPeter Dunlap }
2008a6d42e7dSPeter Dunlap 
2009a6d42e7dSPeter Dunlap 
2010a6d42e7dSPeter Dunlap /*
2011a6d42e7dSPeter Dunlap  * Retrieve connection type given a kernel address
2012a6d42e7dSPeter Dunlap  */
2013a6d42e7dSPeter Dunlap static idm_conn_type_t
2014a6d42e7dSPeter Dunlap idm_conn_type(uintptr_t addr)
2015a6d42e7dSPeter Dunlap {
2016a6d42e7dSPeter Dunlap 	idm_conn_type_t result = 0; /* Unknown */
2017a6d42e7dSPeter Dunlap 	uintptr_t idm_conn_type_addr;
2018a6d42e7dSPeter Dunlap 
2019a6d42e7dSPeter Dunlap 	idm_conn_type_addr = addr + offsetof(idm_conn_t, ic_conn_type);
2020a6d42e7dSPeter Dunlap 	(void) mdb_vread(&result, sizeof (result), idm_conn_type_addr);
2021a6d42e7dSPeter Dunlap 
2022a6d42e7dSPeter Dunlap 	return (result);
2023a6d42e7dSPeter Dunlap }
2024a6d42e7dSPeter Dunlap 
2025a6d42e7dSPeter Dunlap /*
2026a6d42e7dSPeter Dunlap  * Convert a sockaddr to the string representation, suitable for
2027a6d42e7dSPeter Dunlap  * storing in an nvlist or printing out in a list.
2028a6d42e7dSPeter Dunlap  */
2029a6d42e7dSPeter Dunlap static int
2030a6d42e7dSPeter Dunlap sa_to_str(struct sockaddr_storage *sa, char *buf)
2031a6d42e7dSPeter Dunlap {
2032a6d42e7dSPeter Dunlap 	char			pbuf[7];
2033a6d42e7dSPeter Dunlap 	const char		*bufp;
2034a6d42e7dSPeter Dunlap 	struct sockaddr_in	*sin;
2035a6d42e7dSPeter Dunlap 	struct sockaddr_in6	*sin6;
2036a6d42e7dSPeter Dunlap 	uint16_t		port;
2037a6d42e7dSPeter Dunlap 
2038a6d42e7dSPeter Dunlap 	if (!sa || !buf) {
2039a6d42e7dSPeter Dunlap 		return (EINVAL);
2040a6d42e7dSPeter Dunlap 	}
2041a6d42e7dSPeter Dunlap 
2042a6d42e7dSPeter Dunlap 	buf[0] = '\0';
2043a6d42e7dSPeter Dunlap 
2044a6d42e7dSPeter Dunlap 	if (sa->ss_family == AF_INET) {
2045a6d42e7dSPeter Dunlap 		sin = (struct sockaddr_in *)sa;
204630e7468fSPeter Dunlap 		bufp = iscsi_inet_ntop(AF_INET,
2047a6d42e7dSPeter Dunlap 		    (const void *)&(sin->sin_addr.s_addr),
2048a6d42e7dSPeter Dunlap 		    buf, PORTAL_STR_LEN);
2049a6d42e7dSPeter Dunlap 		if (bufp == NULL) {
2050a6d42e7dSPeter Dunlap 			return (-1);
2051a6d42e7dSPeter Dunlap 		}
2052a6d42e7dSPeter Dunlap 		mdb_nhconvert(&port, &sin->sin_port, sizeof (uint16_t));
2053a6d42e7dSPeter Dunlap 	} else if (sa->ss_family == AF_INET6) {
2054a6d42e7dSPeter Dunlap 		strlcat(buf, "[", sizeof (buf));
2055a6d42e7dSPeter Dunlap 		sin6 = (struct sockaddr_in6 *)sa;
205630e7468fSPeter Dunlap 		bufp = iscsi_inet_ntop(AF_INET6,
2057a6d42e7dSPeter Dunlap 		    (const void *)&sin6->sin6_addr.s6_addr,
2058a6d42e7dSPeter Dunlap 		    &buf[1], PORTAL_STR_LEN - 1);
2059a6d42e7dSPeter Dunlap 		if (bufp == NULL) {
2060a6d42e7dSPeter Dunlap 			return (-1);
2061a6d42e7dSPeter Dunlap 		}
2062a6d42e7dSPeter Dunlap 		strlcat(buf, "]", PORTAL_STR_LEN);
2063a6d42e7dSPeter Dunlap 		mdb_nhconvert(&port, &sin->sin_port, sizeof (uint16_t));
2064a6d42e7dSPeter Dunlap 	} else {
2065a6d42e7dSPeter Dunlap 		return (EINVAL);
2066a6d42e7dSPeter Dunlap 	}
2067a6d42e7dSPeter Dunlap 
2068a6d42e7dSPeter Dunlap 
2069a6d42e7dSPeter Dunlap 	mdb_snprintf(pbuf, sizeof (pbuf), ":%u", port);
2070a6d42e7dSPeter Dunlap 	strlcat(buf, pbuf, PORTAL_STR_LEN);
2071a6d42e7dSPeter Dunlap 
2072a6d42e7dSPeter Dunlap 	return (0);
2073a6d42e7dSPeter Dunlap }
2074a6d42e7dSPeter Dunlap 
2075a6d42e7dSPeter Dunlap 
2076a6d42e7dSPeter Dunlap static void
2077a6d42e7dSPeter Dunlap iscsi_format_timestamp(char *ts_str, int strlen, timespec_t *ts)
2078a6d42e7dSPeter Dunlap {
2079a6d42e7dSPeter Dunlap 	mdb_snprintf(ts_str, strlen, "%Y:%03d:%03d:%03d", ts->tv_sec,
2080a6d42e7dSPeter Dunlap 	    (ts->tv_nsec / 1000000) % 1000, (ts->tv_nsec / 1000) % 1000,
2081a6d42e7dSPeter Dunlap 	    ts->tv_nsec % 1000);
2082a6d42e7dSPeter Dunlap }
2083a6d42e7dSPeter Dunlap 
2084a6d42e7dSPeter Dunlap /*
2085a6d42e7dSPeter Dunlap  * Help information for the iscsi_isns dcmd
2086a6d42e7dSPeter Dunlap  */
2087a6d42e7dSPeter Dunlap static void
2088a6d42e7dSPeter Dunlap iscsi_isns_help(void)
2089a6d42e7dSPeter Dunlap {
2090a6d42e7dSPeter Dunlap 	mdb_printf("iscsi_isns:\n");
2091a6d42e7dSPeter Dunlap 	mdb_inc_indent(4);
2092a6d42e7dSPeter Dunlap 	mdb_printf("-e: Print ESI information\n");
2093a6d42e7dSPeter Dunlap 	mdb_printf("-p: Print portal information\n");
2094a6d42e7dSPeter Dunlap 	mdb_printf("-s: Print iSNS server information\n");
2095a6d42e7dSPeter Dunlap 	mdb_printf("-t: Print target information\n");
2096a6d42e7dSPeter Dunlap 	mdb_printf("-v: Add verbosity to the other options' output\n");
2097a6d42e7dSPeter Dunlap 	mdb_dec_indent(4);
2098a6d42e7dSPeter Dunlap }
2099a6d42e7dSPeter Dunlap 
2100a6d42e7dSPeter Dunlap /* ARGSUSED */
2101a6d42e7dSPeter Dunlap static int
2102a6d42e7dSPeter Dunlap iscsi_isns_esi_cb(uintptr_t addr, const void *walker_data, void *data)
2103a6d42e7dSPeter Dunlap {
2104a6d42e7dSPeter Dunlap 	isns_esi_tinfo_t tinfo;
2105a6d42e7dSPeter Dunlap 
2106a6d42e7dSPeter Dunlap 	if (mdb_vread(&tinfo, sizeof (isns_esi_tinfo_t), addr) !=
2107a6d42e7dSPeter Dunlap 	    sizeof (isns_esi_tinfo_t)) {
2108a6d42e7dSPeter Dunlap 		return (WALK_ERR);
2109a6d42e7dSPeter Dunlap 	}
2110a6d42e7dSPeter Dunlap 
2111a6d42e7dSPeter Dunlap 	mdb_printf("ESI thread/thr did : 0x%p / %d\n", tinfo.esi_thread,
2112a6d42e7dSPeter Dunlap 	    tinfo.esi_thread_did);
2113a6d42e7dSPeter Dunlap 	mdb_printf("ESI sonode         : 0x%p\n", tinfo.esi_so);
2114a6d42e7dSPeter Dunlap 	mdb_printf("ESI port           : %d\n", tinfo.esi_port);
2115a6d42e7dSPeter Dunlap 	mdb_printf("ESI thread running : %s\n",
2116a6d42e7dSPeter Dunlap 	    (tinfo.esi_thread_running) ? "Yes" : "No");
2117a6d42e7dSPeter Dunlap 
2118a6d42e7dSPeter Dunlap 	return (WALK_NEXT);
2119a6d42e7dSPeter Dunlap }
2120a6d42e7dSPeter Dunlap 
2121a6d42e7dSPeter Dunlap static int
2122a6d42e7dSPeter Dunlap iscsi_isns_esi(iscsi_dcmd_ctrl_t *idc)
2123a6d42e7dSPeter Dunlap {
2124e42a0851Speter dunlap 	GElf_Sym		sym;
2125e42a0851Speter dunlap 	uintptr_t		addr;
2126a6d42e7dSPeter Dunlap 
2127e42a0851Speter dunlap 	if (mdb_lookup_by_name("esi", &sym) == -1) {
2128a6d42e7dSPeter Dunlap 		mdb_warn("failed to find symbol 'esi_list'");
2129a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2130a6d42e7dSPeter Dunlap 	}
2131e42a0851Speter dunlap 	addr = (uintptr_t)sym.st_value;
2132a6d42e7dSPeter Dunlap 
2133a6d42e7dSPeter Dunlap 	idc->idc_header = 1;
2134e42a0851Speter dunlap 	(void) iscsi_isns_esi_cb(addr, NULL, idc);
2135a6d42e7dSPeter Dunlap 
2136a6d42e7dSPeter Dunlap 	return (0);
2137a6d42e7dSPeter Dunlap }
2138a6d42e7dSPeter Dunlap 
2139a6d42e7dSPeter Dunlap /* ARGSUSED */
2140a6d42e7dSPeter Dunlap static int
2141a6d42e7dSPeter Dunlap iscsi_isns_portal_cb(uintptr_t addr, const void *walker_data, void *data)
2142a6d42e7dSPeter Dunlap {
2143a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t *idc = (iscsi_dcmd_ctrl_t *)data;
2144bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	isns_portal_t portal;
2145a6d42e7dSPeter Dunlap 	char portal_addr[PORTAL_STR_LEN];
2146a6d42e7dSPeter Dunlap 	struct sockaddr_storage *ss;
2147e42a0851Speter dunlap 	char			ts_string[40];
2148a6d42e7dSPeter Dunlap 
2149bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (mdb_vread(&portal, sizeof (isns_portal_t), addr) !=
2150bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	    sizeof (isns_portal_t)) {
2151a6d42e7dSPeter Dunlap 		return (WALK_ERR);
2152a6d42e7dSPeter Dunlap 	}
2153a6d42e7dSPeter Dunlap 
2154a6d42e7dSPeter Dunlap 	ss = &portal.portal_addr;
2155a6d42e7dSPeter Dunlap 	sa_to_str(ss, portal_addr);
2156a6d42e7dSPeter Dunlap 	mdb_printf("Portal IP address ");
2157a6d42e7dSPeter Dunlap 
2158a6d42e7dSPeter Dunlap 	if (ss->ss_family == AF_INET) {
2159a6d42e7dSPeter Dunlap 		mdb_printf("(v4): %s", portal_addr);
2160a6d42e7dSPeter Dunlap 	} else {
2161a6d42e7dSPeter Dunlap 		mdb_printf("(v6): %s", portal_addr);
2162a6d42e7dSPeter Dunlap 	}
2163a6d42e7dSPeter Dunlap 
2164bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (portal.portal_default == B_TRUE) {
2165a6d42e7dSPeter Dunlap 		mdb_printf(" (Default portal)\n");
2166a6d42e7dSPeter Dunlap 	} else {
2167a6d42e7dSPeter Dunlap 		mdb_printf("\n");
2168a6d42e7dSPeter Dunlap 	}
2169bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (portal.portal_iscsit != NULL) {
2170bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_printf("(Part of TPG: 0x%x)\n", portal.portal_iscsit);
2171bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	}
2172bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2173bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	iscsi_format_timestamp(ts_string, 40, &portal.portal_esi_timestamp);
2174bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Portal ESI timestamp: 0x%p\n\n", ts_string);
2175a6d42e7dSPeter Dunlap 
2176a6d42e7dSPeter Dunlap 	if ((portal.portal_iscsit != NULL) && (idc->idc_verbose)) {
2177bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_inc_indent(4);
2178a6d42e7dSPeter Dunlap 		iscsi_portal_impl((uintptr_t)portal.portal_iscsit, idc);
2179bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_dec_indent(4);
2180a6d42e7dSPeter Dunlap 	}
2181a6d42e7dSPeter Dunlap 
2182a6d42e7dSPeter Dunlap 
2183a6d42e7dSPeter Dunlap 	return (WALK_NEXT);
2184a6d42e7dSPeter Dunlap }
2185a6d42e7dSPeter Dunlap 
2186a6d42e7dSPeter Dunlap static int
2187a6d42e7dSPeter Dunlap iscsi_isns_portals(iscsi_dcmd_ctrl_t *idc)
2188a6d42e7dSPeter Dunlap {
2189a6d42e7dSPeter Dunlap 	GElf_Sym sym;
2190a6d42e7dSPeter Dunlap 	uintptr_t portal_list;
2191a6d42e7dSPeter Dunlap 
2192bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("All Active Portals:\n");
2193bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2194bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (mdb_lookup_by_name("isns_all_portals", &sym) == -1) {
2195bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_warn("failed to find symbol 'isns_all_portals'");
2196bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		return (DCMD_ERR);
2197bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	}
2198bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2199bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	portal_list = (uintptr_t)sym.st_value;
2200bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	idc->idc_header = 1;
2201bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2202bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (mdb_pwalk("avl", iscsi_isns_portal_cb, idc, portal_list) == -1) {
2203bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_warn("avl walk failed for isns_all_portals");
2204bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		return (DCMD_ERR);
2205bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	}
2206bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("\nPortals from TPGs:\n");
2207bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2208bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (mdb_lookup_by_name("isns_tpg_portals", &sym) == -1) {
2209bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_warn("failed to find symbol 'isns_tpg_portals'");
2210a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2211a6d42e7dSPeter Dunlap 	}
2212a6d42e7dSPeter Dunlap 
2213a6d42e7dSPeter Dunlap 	portal_list = (uintptr_t)sym.st_value;
2214a6d42e7dSPeter Dunlap 	idc->idc_header = 1;
2215a6d42e7dSPeter Dunlap 
2216bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (mdb_pwalk("avl", iscsi_isns_portal_cb, idc, portal_list) == -1) {
2217bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_warn("avl walk failed for isns_tpg_portals");
2218a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2219a6d42e7dSPeter Dunlap 	}
2220a6d42e7dSPeter Dunlap 
2221bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2222a6d42e7dSPeter Dunlap 	return (0);
2223a6d42e7dSPeter Dunlap }
2224a6d42e7dSPeter Dunlap 
2225a6d42e7dSPeter Dunlap /* ARGSUSED */
2226a6d42e7dSPeter Dunlap static int
2227a6d42e7dSPeter Dunlap iscsi_isns_targets_cb(uintptr_t addr, const void *walker_data, void *data)
2228a6d42e7dSPeter Dunlap {
2229bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	iscsi_dcmd_ctrl_t	*idc = (iscsi_dcmd_ctrl_t *)data;
2230bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	isns_target_t		itarget;
2231bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	int			rc = 0;
2232a6d42e7dSPeter Dunlap 
2233a6d42e7dSPeter Dunlap 	if (mdb_vread(&itarget, sizeof (isns_target_t), addr) !=
2234a6d42e7dSPeter Dunlap 	    sizeof (isns_target_t)) {
2235a6d42e7dSPeter Dunlap 		return (WALK_ERR);
2236a6d42e7dSPeter Dunlap 	}
2237a6d42e7dSPeter Dunlap 
2238a6d42e7dSPeter Dunlap 	idc->idc_header = 1;
2239a6d42e7dSPeter Dunlap 
2240bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Target: %p\n", addr);
2241a6d42e7dSPeter Dunlap 	mdb_inc_indent(4);
2242a6d42e7dSPeter Dunlap 	mdb_printf("Registered: %s\n",
2243a6d42e7dSPeter Dunlap 	    (itarget.target_registered) ? "Yes" : "No");
2244bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Update needed: %s\n",
2245bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	    (itarget.target_update_needed) ? "Yes" : "No");
2246bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Target Info: %p\n", itarget.target_info);
2247a6d42e7dSPeter Dunlap 
2248a6d42e7dSPeter Dunlap 	rc = iscsi_tgt_impl((uintptr_t)itarget.target, idc);
2249a6d42e7dSPeter Dunlap 
2250a6d42e7dSPeter Dunlap 	mdb_dec_indent(4);
2251a6d42e7dSPeter Dunlap 
2252a6d42e7dSPeter Dunlap 	if (rc == DCMD_OK) {
2253a6d42e7dSPeter Dunlap 		return (WALK_NEXT);
2254a6d42e7dSPeter Dunlap 	}
2255a6d42e7dSPeter Dunlap 
2256a6d42e7dSPeter Dunlap 	return (WALK_ERR);
2257a6d42e7dSPeter Dunlap }
2258a6d42e7dSPeter Dunlap 
2259a6d42e7dSPeter Dunlap static int
2260a6d42e7dSPeter Dunlap iscsi_isns_targets(iscsi_dcmd_ctrl_t *idc)
2261a6d42e7dSPeter Dunlap {
2262a6d42e7dSPeter Dunlap 	GElf_Sym sym;
2263a6d42e7dSPeter Dunlap 	uintptr_t isns_target_list;
2264a6d42e7dSPeter Dunlap 
2265a6d42e7dSPeter Dunlap 	if (mdb_lookup_by_name("isns_target_list", &sym) == -1) {
2266a6d42e7dSPeter Dunlap 		mdb_warn("failed to find symbol 'isns_target_list'");
2267a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2268a6d42e7dSPeter Dunlap 	}
2269a6d42e7dSPeter Dunlap 
2270a6d42e7dSPeter Dunlap 	isns_target_list = (uintptr_t)sym.st_value;
2271a6d42e7dSPeter Dunlap 	idc->idc_header = 1;
2272a6d42e7dSPeter Dunlap 	idc->u.child.idc_tgt = 1;
2273a6d42e7dSPeter Dunlap 
2274a6d42e7dSPeter Dunlap 	if (mdb_pwalk("avl", iscsi_isns_targets_cb, idc,
2275a6d42e7dSPeter Dunlap 	    isns_target_list) == -1) {
2276a6d42e7dSPeter Dunlap 		mdb_warn("avl walk failed for isns_target_list");
2277a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2278a6d42e7dSPeter Dunlap 	}
2279a6d42e7dSPeter Dunlap 
2280a6d42e7dSPeter Dunlap 	return (0);
2281a6d42e7dSPeter Dunlap }
2282a6d42e7dSPeter Dunlap 
2283a6d42e7dSPeter Dunlap /* ARGSUSED */
2284a6d42e7dSPeter Dunlap static int
2285a6d42e7dSPeter Dunlap iscsi_isns_servers_cb(uintptr_t addr, const void *walker_data, void *data)
2286a6d42e7dSPeter Dunlap {
2287a6d42e7dSPeter Dunlap 	GElf_Sym		sym;
2288a6d42e7dSPeter Dunlap 	iscsit_isns_svr_t	server;
2289a6d42e7dSPeter Dunlap 	char			server_addr[PORTAL_STR_LEN];
2290a6d42e7dSPeter Dunlap 	struct sockaddr_storage *ss;
2291a6d42e7dSPeter Dunlap 	clock_t			lbolt;
2292bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	iscsi_dcmd_ctrl_t	*idc = (iscsi_dcmd_ctrl_t *)data;
2293bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	uintptr_t		avl_addr;
2294a6d42e7dSPeter Dunlap 
2295a6d42e7dSPeter Dunlap 	if (mdb_vread(&server, sizeof (iscsit_isns_svr_t), addr) !=
2296a6d42e7dSPeter Dunlap 	    sizeof (iscsit_isns_svr_t)) {
2297a6d42e7dSPeter Dunlap 		return (WALK_ERR);
2298a6d42e7dSPeter Dunlap 	}
2299a6d42e7dSPeter Dunlap 
2300a6d42e7dSPeter Dunlap 	if (mdb_lookup_by_name("lbolt", &sym) == -1) {
2301a6d42e7dSPeter Dunlap 		mdb_warn("failed to find symbol 'lbolt'");
2302a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2303a6d42e7dSPeter Dunlap 	}
2304a6d42e7dSPeter Dunlap 
2305a6d42e7dSPeter Dunlap 	if (mdb_vread(&lbolt, sizeof (clock_t), sym.st_value) !=
2306a6d42e7dSPeter Dunlap 	    sizeof (clock_t)) {
2307a6d42e7dSPeter Dunlap 		return (WALK_ERR);
2308a6d42e7dSPeter Dunlap 	}
2309a6d42e7dSPeter Dunlap 
2310a6d42e7dSPeter Dunlap 	mdb_printf("iSNS server %p:\n", addr);
2311a6d42e7dSPeter Dunlap 	mdb_inc_indent(4);
2312a6d42e7dSPeter Dunlap 	ss = &server.svr_sa;
2313a6d42e7dSPeter Dunlap 	sa_to_str(ss, server_addr);
2314a6d42e7dSPeter Dunlap 
2315a6d42e7dSPeter Dunlap 	mdb_printf("IP address ");
2316a6d42e7dSPeter Dunlap 	if (ss->ss_family == AF_INET) {
2317a6d42e7dSPeter Dunlap 		mdb_printf("(v4): %s\n", server_addr);
2318a6d42e7dSPeter Dunlap 	} else {
2319a6d42e7dSPeter Dunlap 		mdb_printf("(v6): %s\n", server_addr);
2320a6d42e7dSPeter Dunlap 	}
2321a6d42e7dSPeter Dunlap 
2322bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("ESI Interval: %d seconds\n",
2323bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	    server.svr_esi_interval);
2324bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Last message: %d seconds ago\n",
2325a6d42e7dSPeter Dunlap 	    ((lbolt - server.svr_last_msg) / 100));
2326a6d42e7dSPeter Dunlap 	mdb_printf("Client registered: %s\n",
2327a6d42e7dSPeter Dunlap 	    (server.svr_registered) ? "Yes" : "No");
2328bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Retry Count: %d\n",
2329bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	    server.svr_retry_count);
2330bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Targets Changes Pending: %s\n",
2331bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	    (server.svr_targets_changed) ? "Yes" : "No");
2332bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Delete Pending: %s\n",
2333bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	    (server.svr_delete_needed) ? "Yes" : "No");
2334bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Replace-All Needed: %s\n",
2335bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	    (server.svr_reset_needed) ? "Yes" : "No");
2336bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2337bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (idc->idc_verbose) {
2338bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		idc->idc_header = 1;
2339bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		idc->u.child.idc_tgt = 1;
2340bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2341bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_inc_indent(2);
2342bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		avl_addr = addr + offsetof(iscsit_isns_svr_t,
2343bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		    svr_target_list);
2344bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		if (mdb_pwalk("avl", iscsi_isns_targets_cb, idc,
2345bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		    avl_addr) == -1) {
2346bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 			mdb_warn("avl walk failed for svr_target_list");
2347bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 			return (WALK_ERR);
2348bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		}
2349bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_dec_indent(2);
2350bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	}
2351bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2352a6d42e7dSPeter Dunlap 	mdb_dec_indent(4);
2353a6d42e7dSPeter Dunlap 
2354bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	return (WALK_NEXT);
2355a6d42e7dSPeter Dunlap }
2356a6d42e7dSPeter Dunlap 
2357a6d42e7dSPeter Dunlap static int
2358a6d42e7dSPeter Dunlap iscsi_isns_servers(iscsi_dcmd_ctrl_t *idc)
2359a6d42e7dSPeter Dunlap {
2360a6d42e7dSPeter Dunlap 	uintptr_t	iscsit_global_addr;
2361a6d42e7dSPeter Dunlap 	uintptr_t	list_addr;
2362a6d42e7dSPeter Dunlap 	GElf_Sym	sym;
2363a6d42e7dSPeter Dunlap 
2364a6d42e7dSPeter Dunlap 	if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
2365a6d42e7dSPeter Dunlap 		mdb_warn("failed to find symbol 'iscsit_global'");
2366a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2367a6d42e7dSPeter Dunlap 	}
2368a6d42e7dSPeter Dunlap 
2369a6d42e7dSPeter Dunlap 	iscsit_global_addr = (uintptr_t)sym.st_value;
2370a6d42e7dSPeter Dunlap 	idc->idc_header = 1;
2371a6d42e7dSPeter Dunlap 	list_addr = iscsit_global_addr +
2372a6d42e7dSPeter Dunlap 	    offsetof(iscsit_global_t, global_isns_cfg.isns_svrs);
2373a6d42e7dSPeter Dunlap 
2374a6d42e7dSPeter Dunlap 	if (mdb_pwalk("list", iscsi_isns_servers_cb, idc, list_addr) == -1) {
2375a6d42e7dSPeter Dunlap 		mdb_warn("list walk failed for iSNS servers");
2376a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2377a6d42e7dSPeter Dunlap 	}
2378a6d42e7dSPeter Dunlap 
2379a6d42e7dSPeter Dunlap 	return (0);
2380a6d42e7dSPeter Dunlap }
2381a6d42e7dSPeter Dunlap 
2382a6d42e7dSPeter Dunlap /* ARGSUSED */
2383a6d42e7dSPeter Dunlap static int
2384a6d42e7dSPeter Dunlap iscsi_isns(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2385a6d42e7dSPeter Dunlap {
2386a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t idc;
2387a6d42e7dSPeter Dunlap 	int portals = 0, esi = 0, targets = 0, verbose = 0, servers = 0;
2388a6d42e7dSPeter Dunlap 
2389a6d42e7dSPeter Dunlap 	if (flags & DCMD_ADDRSPEC) {
2390a6d42e7dSPeter Dunlap 		mdb_warn("iscsi_isns is only a global dcmd.");
2391a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2392a6d42e7dSPeter Dunlap 	}
2393a6d42e7dSPeter Dunlap 
2394a6d42e7dSPeter Dunlap 	bzero(&idc, sizeof (idc));
2395a6d42e7dSPeter Dunlap 	if (mdb_getopts(argc, argv,
2396a6d42e7dSPeter Dunlap 	    'e', MDB_OPT_SETBITS, TRUE, &esi,
2397a6d42e7dSPeter Dunlap 	    'p', MDB_OPT_SETBITS, TRUE, &portals,
2398a6d42e7dSPeter Dunlap 	    's', MDB_OPT_SETBITS, TRUE, &servers,
2399a6d42e7dSPeter Dunlap 	    't', MDB_OPT_SETBITS, TRUE, &targets,
2400a6d42e7dSPeter Dunlap 	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
2401a6d42e7dSPeter Dunlap 	    NULL) != argc)
2402a6d42e7dSPeter Dunlap 		return (DCMD_USAGE);
2403a6d42e7dSPeter Dunlap 
2404a6d42e7dSPeter Dunlap 	if ((esi + portals + targets + servers) > 1) {
2405a6d42e7dSPeter Dunlap 		mdb_printf("Only one of e, p, s, and t must be provided");
2406a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2407a6d42e7dSPeter Dunlap 	}
2408a6d42e7dSPeter Dunlap 
2409a6d42e7dSPeter Dunlap 	if ((esi | portals | targets | servers) == 0) {
2410a6d42e7dSPeter Dunlap 		mdb_printf("Exactly one of e, p, s, or t must be provided");
2411a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2412a6d42e7dSPeter Dunlap 	}
2413a6d42e7dSPeter Dunlap 
2414a6d42e7dSPeter Dunlap 	idc.idc_verbose = verbose;
2415a6d42e7dSPeter Dunlap 
2416a6d42e7dSPeter Dunlap 	if (esi) {
2417a6d42e7dSPeter Dunlap 		return (iscsi_isns_esi(&idc));
2418a6d42e7dSPeter Dunlap 	}
2419a6d42e7dSPeter Dunlap 
2420a6d42e7dSPeter Dunlap 	if (portals) {
2421a6d42e7dSPeter Dunlap 		return (iscsi_isns_portals(&idc));
2422a6d42e7dSPeter Dunlap 	}
2423a6d42e7dSPeter Dunlap 
2424a6d42e7dSPeter Dunlap 	if (servers) {
2425a6d42e7dSPeter Dunlap 		return (iscsi_isns_servers(&idc));
2426a6d42e7dSPeter Dunlap 	}
2427a6d42e7dSPeter Dunlap 
2428a6d42e7dSPeter Dunlap 	return (iscsi_isns_targets(&idc));
2429a6d42e7dSPeter Dunlap }
2430a6d42e7dSPeter Dunlap 
2431a6d42e7dSPeter Dunlap /*
243230e7468fSPeter Dunlap  * iscsi_inet_ntop -- Convert an IPv4 or IPv6 address in binary form into
2433a6d42e7dSPeter Dunlap  * printable form, and return a pointer to that string. Caller should
2434a6d42e7dSPeter Dunlap  * provide a buffer of correct length to store string into.
2435a6d42e7dSPeter Dunlap  * Note: this routine is kernel version of inet_ntop. It has similar
243630e7468fSPeter Dunlap  * format as iscsi_inet_ntop() defined in rfc2553. But it does not do
2437a6d42e7dSPeter Dunlap  * error handling operations exactly as rfc2553 defines. This function
2438a6d42e7dSPeter Dunlap  * is used by kernel inet directory routines only for debugging.
243930e7468fSPeter Dunlap  * This iscsi_inet_ntop() function, does not return NULL if third argument
2440a6d42e7dSPeter Dunlap  * is NULL. The reason is simple that we don't want kernel to panic
2441a6d42e7dSPeter Dunlap  * as the output of this function is directly fed to ip<n>dbg macro.
2442a6d42e7dSPeter Dunlap  * Instead it uses a local buffer for destination address for
2443a6d42e7dSPeter Dunlap  * those calls which purposely pass NULL ptr for the destination
2444a6d42e7dSPeter Dunlap  * buffer. This function is thread-safe when the caller passes a non-
2445a6d42e7dSPeter Dunlap  * null buffer with the third argument.
2446a6d42e7dSPeter Dunlap  */
2447a6d42e7dSPeter Dunlap /* ARGSUSED */
2448a6d42e7dSPeter Dunlap 
2449a6d42e7dSPeter Dunlap #define	OK_16PTR(p)	(!((uintptr_t)(p) & 0x1))
2450a6d42e7dSPeter Dunlap #if defined(__x86)
2451a6d42e7dSPeter Dunlap #define	OK_32PTR(p)	OK_16PTR(p)
2452a6d42e7dSPeter Dunlap #else
2453a6d42e7dSPeter Dunlap #define	OK_32PTR(p)	(!((uintptr_t)(p) & 0x3))
2454a6d42e7dSPeter Dunlap #endif
2455a6d42e7dSPeter Dunlap 
2456a6d42e7dSPeter Dunlap char *
245730e7468fSPeter Dunlap iscsi_inet_ntop(int af, const void *addr, char *buf, int addrlen)
2458a6d42e7dSPeter Dunlap {
2459a6d42e7dSPeter Dunlap 	static char local_buf[PORTAL_STR_LEN];
2460a6d42e7dSPeter Dunlap 	static char *err_buf1 = "<badaddr>";
2461a6d42e7dSPeter Dunlap 	static char *err_buf2 = "<badfamily>";
2462a6d42e7dSPeter Dunlap 	in6_addr_t	*v6addr;
2463a6d42e7dSPeter Dunlap 	uchar_t		*v4addr;
2464a6d42e7dSPeter Dunlap 	char		*caddr;
2465a6d42e7dSPeter Dunlap 
2466a6d42e7dSPeter Dunlap 	/*
246730e7468fSPeter Dunlap 	 * We don't allow thread unsafe iscsi_inet_ntop calls, they
2468a6d42e7dSPeter Dunlap 	 * must pass a non-null buffer pointer. For DEBUG mode
2469a6d42e7dSPeter Dunlap 	 * we use the ASSERT() and for non-debug kernel it will
2470a6d42e7dSPeter Dunlap 	 * silently allow it for now. Someday we should remove
2471a6d42e7dSPeter Dunlap 	 * the static buffer from this function.
2472a6d42e7dSPeter Dunlap 	 */
2473a6d42e7dSPeter Dunlap 
2474a6d42e7dSPeter Dunlap 	ASSERT(buf != NULL);
2475a6d42e7dSPeter Dunlap 	if (buf == NULL)
2476a6d42e7dSPeter Dunlap 		buf = local_buf;
2477a6d42e7dSPeter Dunlap 	buf[0] = '\0';
2478a6d42e7dSPeter Dunlap 
2479a6d42e7dSPeter Dunlap 	/* Let user know politely not to send NULL or unaligned addr */
2480a6d42e7dSPeter Dunlap 	if (addr == NULL || !(OK_32PTR(addr))) {
2481a6d42e7dSPeter Dunlap 		return (err_buf1);
2482a6d42e7dSPeter Dunlap 	}
2483a6d42e7dSPeter Dunlap 
2484a6d42e7dSPeter Dunlap 
2485a6d42e7dSPeter Dunlap #define	UC(b)	(((int)b) & 0xff)
2486a6d42e7dSPeter Dunlap 	switch (af) {
2487a6d42e7dSPeter Dunlap 	case AF_INET:
2488a6d42e7dSPeter Dunlap 		ASSERT(addrlen >= INET_ADDRSTRLEN);
2489a6d42e7dSPeter Dunlap 		v4addr = (uchar_t *)addr;
2490a6d42e7dSPeter Dunlap 		(void) mdb_snprintf(buf, INET6_ADDRSTRLEN,
2491a6d42e7dSPeter Dunlap 		    "%03d.%03d.%03d.%03d",
2492a6d42e7dSPeter Dunlap 		    UC(v4addr[0]), UC(v4addr[1]), UC(v4addr[2]), UC(v4addr[3]));
2493a6d42e7dSPeter Dunlap 		return (buf);
2494a6d42e7dSPeter Dunlap 
2495a6d42e7dSPeter Dunlap 	case AF_INET6:
2496a6d42e7dSPeter Dunlap 		ASSERT(addrlen >= INET6_ADDRSTRLEN);
2497a6d42e7dSPeter Dunlap 		v6addr = (in6_addr_t *)addr;
2498a6d42e7dSPeter Dunlap 		if (IN6_IS_ADDR_V4MAPPED(v6addr)) {
2499a6d42e7dSPeter Dunlap 			caddr = (char *)addr;
2500a6d42e7dSPeter Dunlap 			(void) mdb_snprintf(buf, INET6_ADDRSTRLEN,
2501a6d42e7dSPeter Dunlap 			    "::ffff:%d.%d.%d.%d",
2502a6d42e7dSPeter Dunlap 			    UC(caddr[12]), UC(caddr[13]),
2503a6d42e7dSPeter Dunlap 			    UC(caddr[14]), UC(caddr[15]));
2504a6d42e7dSPeter Dunlap 		} else if (IN6_IS_ADDR_V4COMPAT(v6addr)) {
2505a6d42e7dSPeter Dunlap 			caddr = (char *)addr;
2506a6d42e7dSPeter Dunlap 			(void) mdb_snprintf(buf, INET6_ADDRSTRLEN,
2507a6d42e7dSPeter Dunlap 			    "::%d.%d.%d.%d",
2508a6d42e7dSPeter Dunlap 			    UC(caddr[12]), UC(caddr[13]), UC(caddr[14]),
2509a6d42e7dSPeter Dunlap 			    UC(caddr[15]));
2510a6d42e7dSPeter Dunlap 		} else if (IN6_IS_ADDR_UNSPECIFIED(v6addr)) {
2511a6d42e7dSPeter Dunlap 			(void) mdb_snprintf(buf, INET6_ADDRSTRLEN, "::");
2512a6d42e7dSPeter Dunlap 		} else {
2513a6d42e7dSPeter Dunlap 			convert2ascii(buf, v6addr);
2514a6d42e7dSPeter Dunlap 		}
2515a6d42e7dSPeter Dunlap 		return (buf);
2516a6d42e7dSPeter Dunlap 
2517a6d42e7dSPeter Dunlap 	default:
2518a6d42e7dSPeter Dunlap 		return (err_buf2);
2519a6d42e7dSPeter Dunlap 	}
2520a6d42e7dSPeter Dunlap #undef UC
2521a6d42e7dSPeter Dunlap }
2522a6d42e7dSPeter Dunlap 
2523a6d42e7dSPeter Dunlap /*
2524a6d42e7dSPeter Dunlap  *
2525a6d42e7dSPeter Dunlap  * v6 formats supported
2526a6d42e7dSPeter Dunlap  * General format xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
2527a6d42e7dSPeter Dunlap  * The short hand notation :: is used for COMPAT addr
2528a6d42e7dSPeter Dunlap  * Other forms : fe80::xxxx:xxxx:xxxx:xxxx
2529a6d42e7dSPeter Dunlap  */
2530a6d42e7dSPeter Dunlap static void
2531a6d42e7dSPeter Dunlap convert2ascii(char *buf, const in6_addr_t *addr)
2532a6d42e7dSPeter Dunlap {
2533a6d42e7dSPeter Dunlap 	int		hexdigits;
2534a6d42e7dSPeter Dunlap 	int		head_zero = 0;
2535a6d42e7dSPeter Dunlap 	int		tail_zero = 0;
2536a6d42e7dSPeter Dunlap 	/* tempbuf must be big enough to hold ffff:\0 */
2537a6d42e7dSPeter Dunlap 	char		tempbuf[6];
2538a6d42e7dSPeter Dunlap 	char		*ptr;
2539a6d42e7dSPeter Dunlap 	uint16_t	out_addr_component;
2540a6d42e7dSPeter Dunlap 	uint16_t	*addr_component;
2541a6d42e7dSPeter Dunlap 	size_t		len;
2542a6d42e7dSPeter Dunlap 	boolean_t	first = B_FALSE;
2543a6d42e7dSPeter Dunlap 	boolean_t	med_zero = B_FALSE;
2544a6d42e7dSPeter Dunlap 	boolean_t	end_zero = B_FALSE;
2545a6d42e7dSPeter Dunlap 
2546a6d42e7dSPeter Dunlap 	addr_component = (uint16_t *)addr;
2547a6d42e7dSPeter Dunlap 	ptr = buf;
2548a6d42e7dSPeter Dunlap 
2549a6d42e7dSPeter Dunlap 	/* First count if trailing zeroes higher in number */
2550a6d42e7dSPeter Dunlap 	for (hexdigits = 0; hexdigits < 8; hexdigits++) {
2551a6d42e7dSPeter Dunlap 		if (*addr_component == 0) {
2552a6d42e7dSPeter Dunlap 			if (hexdigits < 4)
2553a6d42e7dSPeter Dunlap 				head_zero++;
2554a6d42e7dSPeter Dunlap 			else
2555a6d42e7dSPeter Dunlap 				tail_zero++;
2556a6d42e7dSPeter Dunlap 		}
2557a6d42e7dSPeter Dunlap 		addr_component++;
2558a6d42e7dSPeter Dunlap 	}
2559a6d42e7dSPeter Dunlap 	addr_component = (uint16_t *)addr;
2560a6d42e7dSPeter Dunlap 	if (tail_zero > head_zero && (head_zero + tail_zero) != 7)
2561a6d42e7dSPeter Dunlap 		end_zero = B_TRUE;
2562a6d42e7dSPeter Dunlap 
2563a6d42e7dSPeter Dunlap 	for (hexdigits = 0; hexdigits < 8; hexdigits++) {
2564a6d42e7dSPeter Dunlap 
2565a6d42e7dSPeter Dunlap 		/* if entry is a 0 */
2566a6d42e7dSPeter Dunlap 
2567a6d42e7dSPeter Dunlap 		if (*addr_component == 0) {
2568a6d42e7dSPeter Dunlap 			if (!first && *(addr_component + 1) == 0) {
2569a6d42e7dSPeter Dunlap 				if (end_zero && (hexdigits < 4)) {
2570a6d42e7dSPeter Dunlap 					*ptr++ = '0';
2571a6d42e7dSPeter Dunlap 					*ptr++ = ':';
2572a6d42e7dSPeter Dunlap 				} else {
2573a6d42e7dSPeter Dunlap 					/*
2574a6d42e7dSPeter Dunlap 					 * address starts with 0s ..
2575a6d42e7dSPeter Dunlap 					 * stick in leading ':' of pair
2576a6d42e7dSPeter Dunlap 					 */
2577a6d42e7dSPeter Dunlap 					if (hexdigits == 0)
2578a6d42e7dSPeter Dunlap 						*ptr++ = ':';
2579a6d42e7dSPeter Dunlap 					/* add another */
2580a6d42e7dSPeter Dunlap 					*ptr++ = ':';
2581a6d42e7dSPeter Dunlap 					first = B_TRUE;
2582a6d42e7dSPeter Dunlap 					med_zero = B_TRUE;
2583a6d42e7dSPeter Dunlap 				}
2584a6d42e7dSPeter Dunlap 			} else if (first && med_zero) {
2585a6d42e7dSPeter Dunlap 				if (hexdigits == 7)
2586a6d42e7dSPeter Dunlap 					*ptr++ = ':';
2587a6d42e7dSPeter Dunlap 				addr_component++;
2588a6d42e7dSPeter Dunlap 				continue;
2589a6d42e7dSPeter Dunlap 			} else {
2590a6d42e7dSPeter Dunlap 				*ptr++ = '0';
2591a6d42e7dSPeter Dunlap 				*ptr++ = ':';
2592a6d42e7dSPeter Dunlap 			}
2593a6d42e7dSPeter Dunlap 			addr_component++;
2594a6d42e7dSPeter Dunlap 			continue;
2595a6d42e7dSPeter Dunlap 		}
2596a6d42e7dSPeter Dunlap 		if (med_zero)
2597a6d42e7dSPeter Dunlap 			med_zero = B_FALSE;
2598a6d42e7dSPeter Dunlap 
2599a6d42e7dSPeter Dunlap 		tempbuf[0] = '\0';
2600a6d42e7dSPeter Dunlap 		mdb_nhconvert(&out_addr_component, addr_component,
2601a6d42e7dSPeter Dunlap 		    sizeof (uint16_t));
2602a6d42e7dSPeter Dunlap 		(void) mdb_snprintf(tempbuf, 6, "%x:", out_addr_component);
2603a6d42e7dSPeter Dunlap 		len = strlen(tempbuf);
2604a6d42e7dSPeter Dunlap 		bcopy(tempbuf, ptr, len);
2605a6d42e7dSPeter Dunlap 		ptr = ptr + len;
2606a6d42e7dSPeter Dunlap 		addr_component++;
2607a6d42e7dSPeter Dunlap 	}
2608a6d42e7dSPeter Dunlap 	*--ptr = '\0';
2609a6d42e7dSPeter Dunlap }
2610a6d42e7dSPeter Dunlap 
2611a6d42e7dSPeter Dunlap 
2612a6d42e7dSPeter Dunlap /*
2613a6d42e7dSPeter Dunlap  * MDB module linkage information:
2614a6d42e7dSPeter Dunlap  *
2615a6d42e7dSPeter Dunlap  * We declare a list of structures describing our dcmds, a list of structures
2616a6d42e7dSPeter Dunlap  * describing our walkers and a function named _mdb_init to return a pointer
2617a6d42e7dSPeter Dunlap  * to our module information.
2618a6d42e7dSPeter Dunlap  */
2619a6d42e7dSPeter Dunlap static const mdb_dcmd_t dcmds[] = {
2620a6d42e7dSPeter Dunlap 	{   "iscsi_tgt", "[-agsctbSRv]",
2621a6d42e7dSPeter Dunlap 	    "iSCSI target information", iscsi_tgt },
2622a6d42e7dSPeter Dunlap 	{   "iscsi_tpg", "[-v]",
2623a6d42e7dSPeter Dunlap 	    "iSCSI target portal group information", iscsi_tpg },
2624a6d42e7dSPeter Dunlap 	{   "iscsi_sess", "[-abtvcSRIT]",
2625a6d42e7dSPeter Dunlap 	    "iSCSI session information", iscsi_sess },
2626a6d42e7dSPeter Dunlap 	{   "iscsi_conn", "[-abtvSRIT]",
2627a6d42e7dSPeter Dunlap 	    "iSCSI connection information", iscsi_conn },
2628a6d42e7dSPeter Dunlap 	{   "iscsi_task", "[-bSRv]",
2629a6d42e7dSPeter Dunlap 	    "iSCSI task information", iscsi_task },
2630a6d42e7dSPeter Dunlap 	{   "iscsi_refcnt", "",
2631a6d42e7dSPeter Dunlap 	    "Print audit informtion for idm_refcnt_t", iscsi_refcnt },
2632a6d42e7dSPeter Dunlap 	{   "iscsi_states", "",
2633a6d42e7dSPeter Dunlap 	    "Dump events and state transitions recorded in an\t"
2634a6d42e7dSPeter Dunlap 	    "\t\tidm_sm_audit_t structure", iscsi_states },
2635a6d42e7dSPeter Dunlap 	{   "iscsi_isns", "[-epstv]",
2636a6d42e7dSPeter Dunlap 	    "Print iscsit iSNS information", iscsi_isns, iscsi_isns_help },
2637a6d42e7dSPeter Dunlap 	{ NULL }
2638a6d42e7dSPeter Dunlap };
2639a6d42e7dSPeter Dunlap 
2640a6d42e7dSPeter Dunlap /*
2641a6d42e7dSPeter Dunlap  * No walkers for now.  Initiator might need some since it doesn't use list_t
2642a6d42e7dSPeter Dunlap  */
2643a6d42e7dSPeter Dunlap 
2644a6d42e7dSPeter Dunlap static const mdb_modinfo_t modinfo = {
2645a6d42e7dSPeter Dunlap 	MDB_API_VERSION, dcmds, NULL
2646a6d42e7dSPeter Dunlap };
2647a6d42e7dSPeter Dunlap 
2648a6d42e7dSPeter Dunlap const mdb_modinfo_t *
2649a6d42e7dSPeter Dunlap _mdb_init(void)
2650a6d42e7dSPeter Dunlap {
2651a6d42e7dSPeter Dunlap 	return (&modinfo);
2652a6d42e7dSPeter Dunlap }
2653