xref: /titanic_50/usr/src/cmd/mdb/common/modules/idm/idm.c (revision c89a15d415257cb029ed5e5efc36d64a60667972)
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 /*
225819f75eSPeter Gill  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23a6d42e7dSPeter Dunlap  */
24a6d42e7dSPeter Dunlap 
25d3d50737SRafael Vanoni #include <mdb/mdb_modapi.h>
26d3d50737SRafael Vanoni #include <mdb/mdb_ks.h>
27d3d50737SRafael Vanoni 
28a6d42e7dSPeter Dunlap #include <sys/cpuvar.h>
29a6d42e7dSPeter Dunlap #include <sys/conf.h>
30a6d42e7dSPeter Dunlap #include <sys/file.h>
31a6d42e7dSPeter Dunlap #include <sys/types.h>
32a6d42e7dSPeter Dunlap #include <sys/taskq.h>
33a6d42e7dSPeter Dunlap #include <sys/sysmacros.h>
34a6d42e7dSPeter Dunlap #include <sys/socket.h>		/* networking stuff */
35a6d42e7dSPeter Dunlap #include <sys/strsubr.h>	/* networking stuff */
36a6d42e7dSPeter Dunlap #include <sys/nvpair.h>
37a6d42e7dSPeter Dunlap #include <sys/sunldi.h>
38a6d42e7dSPeter Dunlap #include <sys/stmf.h>
39a6d42e7dSPeter Dunlap #include <sys/stmf_ioctl.h>
40a6d42e7dSPeter Dunlap #include <sys/portif.h>
41a6d42e7dSPeter Dunlap 
42a6d42e7dSPeter Dunlap #define	IDM_CONN_SM_STRINGS
43bf604c64SPeter Dunlap #define	IDM_TASK_SM_STRINGS
44a6d42e7dSPeter Dunlap #define	ISCSIT_TGT_SM_STRINGS
45a6d42e7dSPeter Dunlap #define	ISCSIT_SESS_SM_STRINGS
46a6d42e7dSPeter Dunlap #define	ISCSIT_LOGIN_SM_STRINGS
4730e7468fSPeter Dunlap #define	ISCSI_SESS_SM_STRINGS
4830e7468fSPeter Dunlap #define	ISCSI_CMD_SM_STRINGS
4930e7468fSPeter Dunlap #define	ISCSI_ICS_NAMES
5030e7468fSPeter Dunlap #define	ISCSI_LOGIN_STATE_NAMES
515f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States #define	IDM_CN_NOTIFY_STRINGS
52a6d42e7dSPeter Dunlap #include <sys/idm/idm.h>
53aff4bce5Syi zhang - Sun Microsystems - Beijing China #include <iscsi.h>
54a6d42e7dSPeter Dunlap #include <iscsit.h>
55a6d42e7dSPeter Dunlap #include <iscsit_isns.h>
565819f75eSPeter Gill #include <sys/ib/clients/iser/iser.h>
57a6d42e7dSPeter Dunlap 
58a6d42e7dSPeter Dunlap /*
59a6d42e7dSPeter Dunlap  * We want to be able to print multiple levels of object hierarchy with a
60a6d42e7dSPeter Dunlap  * single dcmd information, and preferably also exclude intermediate
61a6d42e7dSPeter Dunlap  * levels if desired.  For example some of the target objects have the
62a6d42e7dSPeter Dunlap  * following relationship:
63a6d42e7dSPeter Dunlap  *
64a6d42e7dSPeter Dunlap  * target --> session --> connection --> task
65a6d42e7dSPeter Dunlap  *
66a6d42e7dSPeter Dunlap  * The session dcmd should allow the printing of all associated tasks for the
67a6d42e7dSPeter Dunlap  * sessions without printing all the associated connections.  To accomplish
68a6d42e7dSPeter Dunlap  * this the following structure contains a bit for each object type.  Dcmds
695819f75eSPeter Gill  * should invoke the functions for child objects if any bits are set
70a6d42e7dSPeter Dunlap  * in iscsi_dcmd_ctrl_t but the functions for the child object should only
715819f75eSPeter Gill  * print data if their associated bit is set. Each object type should print
725819f75eSPeter Gill  * a header for its first occurrence or if it is being printed as a child
735819f75eSPeter Gill  * object for the first occurrence under each parent. For the model to follow
745819f75eSPeter Gill  * see how idc->idc_header is handled in iscsi_sess_impl.
75a6d42e7dSPeter Dunlap  *
76a6d42e7dSPeter Dunlap  * Each dcmd should provide an external interface with the standard MDB API
77a6d42e7dSPeter Dunlap  * and an internal interface that accepts iscsi_dcmd_ctrl_t.  To display
78a6d42e7dSPeter Dunlap  * child objects the dcmd calls the internal interface for the child object
79a6d42e7dSPeter Dunlap  * directly.  Dcmds invoked from the command line will, of course, call the
80a6d42e7dSPeter Dunlap  * external interface.  See iscsi_conn() and iscsi_conn_impl().
81a6d42e7dSPeter Dunlap  */
82a6d42e7dSPeter Dunlap 
83a6d42e7dSPeter Dunlap typedef struct {
84a6d42e7dSPeter Dunlap 	union	{
85a6d42e7dSPeter Dunlap 		uint32_t	idc_children;
86a6d42e7dSPeter Dunlap 		struct {
87a6d42e7dSPeter Dunlap 			uint32_t	idc_tgt:1,
885819f75eSPeter Gill 					idc_tpg:1,
89a6d42e7dSPeter Dunlap 					idc_tpgt:1,
90a6d42e7dSPeter Dunlap 					idc_portal:1,
91a6d42e7dSPeter Dunlap 					idc_sess:1,
92a6d42e7dSPeter Dunlap 					idc_conn:1,
935819f75eSPeter Gill 					idc_svc:1,
94a6d42e7dSPeter Dunlap 					idc_print_ip:1,
95a6d42e7dSPeter Dunlap 					idc_task:1,
96a6d42e7dSPeter Dunlap 					idc_buffer:1,
97a6d42e7dSPeter Dunlap 					idc_states:1,
98a6d42e7dSPeter Dunlap 					idc_rc_audit:1,
99a6d42e7dSPeter Dunlap 					idc_lun:1,
1005819f75eSPeter Gill 					idc_hba:1,
1015819f75eSPeter Gill 					idc_cmd:1;
102a6d42e7dSPeter Dunlap 		} child;
103a6d42e7dSPeter Dunlap 	} u;
104a6d42e7dSPeter Dunlap 	boolean_t		idc_ini;
105a6d42e7dSPeter Dunlap 	boolean_t		idc_tgt;
106a6d42e7dSPeter Dunlap 	boolean_t		idc_verbose;
107a6d42e7dSPeter Dunlap 	boolean_t		idc_header;
108a6d42e7dSPeter Dunlap 	/*
109a6d42e7dSPeter Dunlap 	 * Our connection dcmd code works off the global connection lists
110a6d42e7dSPeter Dunlap 	 * in IDM since we want to know about connections even when they
111a6d42e7dSPeter Dunlap 	 * have not progressed to the point that they have an associated
112a6d42e7dSPeter Dunlap 	 * session.  If we use "::iscsi_sess [-c]" then we only want to
113a6d42e7dSPeter Dunlap 	 * see connections associated with particular session.  To avoid
114a6d42e7dSPeter Dunlap 	 * writing a separate set of code to print session-specific connection
115a6d42e7dSPeter Dunlap 	 * the session code should set the sessions kernel address in the
116a6d42e7dSPeter Dunlap 	 * following field.  The connection code will then only print
117a6d42e7dSPeter Dunlap 	 * connections that match.
118a6d42e7dSPeter Dunlap 	 */
119a6d42e7dSPeter Dunlap 	uintptr_t		idc_assoc_session;
120a6d42e7dSPeter Dunlap } iscsi_dcmd_ctrl_t;
121a6d42e7dSPeter Dunlap 
1225819f75eSPeter Gill typedef struct idm_hba_walk_info {
1235819f75eSPeter Gill 	void	**array;
1245819f75eSPeter Gill 	int	n_elements;
1255819f75eSPeter Gill 	int	cur_element;
1265819f75eSPeter Gill 	void	*data;
1275819f75eSPeter Gill } idm_hba_walk_info_t;
1285819f75eSPeter Gill 
129a6d42e7dSPeter Dunlap static int iscsi_walk_all_sess(iscsi_dcmd_ctrl_t *idc);
130a6d42e7dSPeter Dunlap static int iscsi_walk_all_conn(iscsi_dcmd_ctrl_t *idc);
131a6d42e7dSPeter Dunlap static int iscsi_tgt_walk_cb(uintptr_t addr, const void *list_walker_data,
132a6d42e7dSPeter Dunlap     void *idc_void);
133a6d42e7dSPeter Dunlap static int iscsi_tpgt_walk_cb(uintptr_t addr, const void *list_walker_data,
134a6d42e7dSPeter Dunlap     void *idc_void);
135a6d42e7dSPeter Dunlap static int iscsi_tpg_walk_cb(uintptr_t addr, const void *list_walker_data,
136a6d42e7dSPeter Dunlap     void *idc_void);
137a6d42e7dSPeter Dunlap static int iscsi_portal_walk_cb(uintptr_t addr, const void *list_walker_data,
138a6d42e7dSPeter Dunlap     void *idc_void);
139a6d42e7dSPeter Dunlap static int iscsi_sess_walk_cb(uintptr_t addr, const void *list_walker_data,
140a6d42e7dSPeter Dunlap     void *idc_void);
141a6d42e7dSPeter Dunlap static int iscsi_conn_walk_cb(uintptr_t addr, const void *list_walker_data,
142a6d42e7dSPeter Dunlap     void *idc_void);
143a6d42e7dSPeter Dunlap static int iscsi_buffer_walk_cb(uintptr_t addr, const void *list_walker_data,
144a6d42e7dSPeter Dunlap     void *idc_void);
1455819f75eSPeter Gill static int iscsi_svc_walk_cb(uintptr_t addr, const void *list_walker_data,
1465819f75eSPeter Gill     void *idc_void);
1475819f75eSPeter Gill static int iscsi_ini_hba_walk_cb(uintptr_t addr, const void *vhba,
1485819f75eSPeter Gill     void *idc_void);
1495819f75eSPeter Gill static int iscsi_ini_sess_walk_cb(uintptr_t addr, const void *vsess,
1505819f75eSPeter Gill     void *idc);
1515819f75eSPeter Gill static int iscsi_ini_conn_walk_cb(uintptr_t addr, const void *vconn,
1525819f75eSPeter Gill     void *idc_void);
1535819f75eSPeter Gill static int iscsi_ini_lun_walk_cb(uintptr_t addr, const void *vlun,
1545819f75eSPeter Gill     void *idc_void);
1555819f75eSPeter Gill static int iscsi_ini_cmd_walk_cb(uintptr_t addr, const void *vcmd,
1565819f75eSPeter Gill     void *idc);
157a6d42e7dSPeter Dunlap static int iscsi_tgt_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
158a6d42e7dSPeter Dunlap static int iscsi_tpgt_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
159a6d42e7dSPeter Dunlap static int iscsi_tpg_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
160a6d42e7dSPeter Dunlap static int iscsi_portal_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
161a6d42e7dSPeter Dunlap static int iscsi_sess_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
162a6d42e7dSPeter Dunlap static int iscsi_conn_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
163a6d42e7dSPeter Dunlap static void iscsi_print_iscsit_conn_data(idm_conn_t *ict);
1645819f75eSPeter Gill static void iscsi_print_ini_conn_data(idm_conn_t *ict);
165a6d42e7dSPeter Dunlap static void iscsi_print_idm_conn_data(idm_conn_t *ict);
166a6d42e7dSPeter Dunlap static int iscsi_task_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
167a6d42e7dSPeter Dunlap static void iscsi_print_iscsit_task_data(idm_task_t *idt);
168a6d42e7dSPeter Dunlap static int iscsi_buffer_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
169a6d42e7dSPeter Dunlap static idm_conn_type_t idm_conn_type(uintptr_t addr);
170a6d42e7dSPeter Dunlap static int iscsi_i_task_impl(idm_task_t *idt, uintptr_t addr,
171a6d42e7dSPeter Dunlap     iscsi_dcmd_ctrl_t *idc);
172a6d42e7dSPeter Dunlap static int iscsi_refcnt_impl(uintptr_t addr);
173a6d42e7dSPeter Dunlap static int iscsi_sm_audit_impl(uintptr_t addr);
174a6d42e7dSPeter Dunlap static int iscsi_isns(uintptr_t addr, uint_t flags, int argc,
175a6d42e7dSPeter Dunlap     const mdb_arg_t *argv);
1765819f75eSPeter Gill static int iscsi_svc_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
1775819f75eSPeter Gill static int iscsi_ini_hba_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
1785819f75eSPeter Gill static int iscsi_print_ini_sess(uintptr_t addr, iscsi_sess_t *sess,
1795819f75eSPeter Gill     iscsi_dcmd_ctrl_t *idc);
1805819f75eSPeter Gill static int iscsi_print_ini_lun(uintptr_t addr, const iscsi_lun_t *lun,
1815819f75eSPeter Gill     iscsi_dcmd_ctrl_t *idc);
1825819f75eSPeter Gill static int iscsi_print_ini_cmd(uintptr_t addr, const iscsi_cmd_t *cmd,
1835819f75eSPeter Gill     iscsi_dcmd_ctrl_t *idc);
1845819f75eSPeter Gill static int iscsi_ini_sess_walk_init(mdb_walk_state_t *wsp);
1855819f75eSPeter Gill static int iscsi_ini_sess_step(mdb_walk_state_t *wsp);
1865819f75eSPeter Gill static int iscsi_ini_conn_walk_init(mdb_walk_state_t *wsp);
1875819f75eSPeter Gill static int iscsi_ini_conn_step(mdb_walk_state_t *wsp);
1885819f75eSPeter Gill static int iscsi_ini_lun_walk_init(mdb_walk_state_t *wsp);
1895819f75eSPeter Gill static int iscsi_ini_lun_step(mdb_walk_state_t *wsp);
1905819f75eSPeter Gill static int iscsi_ini_cmd_walk_init(mdb_walk_state_t *wsp);
1915819f75eSPeter Gill static int iscsi_ini_cmd_step(mdb_walk_state_t *wsp);
19230e7468fSPeter Dunlap static const char *iscsi_idm_conn_event(unsigned int event);
19330e7468fSPeter Dunlap static const char *iscsi_iscsit_tgt_event(unsigned int event);
19430e7468fSPeter Dunlap static const char *iscsi_iscsit_sess_event(unsigned int event);
19530e7468fSPeter Dunlap static const char *iscsi_iscsit_login_event(unsigned int event);
19630e7468fSPeter Dunlap static const char *iscsi_iscsi_cmd_event(unsigned int event);
19730e7468fSPeter Dunlap static const char *iscsi_iscsi_sess_event(unsigned int event);
19830e7468fSPeter Dunlap static const char *iscsi_idm_conn_state(unsigned int state);
19930e7468fSPeter Dunlap static const char *iscsi_idm_task_state(unsigned int state);
20030e7468fSPeter Dunlap static const char *iscsi_iscsit_tgt_state(unsigned int state);
20130e7468fSPeter Dunlap static const char *iscsi_iscsit_sess_state(unsigned int state);
20230e7468fSPeter Dunlap static const char *iscsi_iscsit_login_state(unsigned int state);
20330e7468fSPeter Dunlap static const char *iscsi_iscsi_cmd_state(unsigned int state);
20430e7468fSPeter Dunlap static const char *iscsi_iscsi_sess_state(unsigned int state);
20530e7468fSPeter Dunlap static const char *iscsi_iscsi_conn_state(unsigned int state);
2065f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States static const char *iscsi_iscsi_conn_event(unsigned int event);
20730e7468fSPeter Dunlap static const char *iscsi_iscsi_login_state(unsigned int state);
208a6d42e7dSPeter Dunlap 
209a6d42e7dSPeter Dunlap static void iscsi_format_timestamp(char *ts_str, int strlen,
210a6d42e7dSPeter Dunlap     timespec_t *ts);
21130e7468fSPeter Dunlap static char *iscsi_inet_ntop(int af, const void *addr, char *buf, int addrlen);
212a6d42e7dSPeter Dunlap static void convert2ascii(char *, const in6_addr_t *);
213a6d42e7dSPeter Dunlap static int sa_to_str(struct sockaddr_storage *sa, char *addr);
214e42a0851Speter dunlap static int iscsi_isns_esi_cb(uintptr_t addr, const void *walker_data,
215e42a0851Speter dunlap     void *data);
216a6d42e7dSPeter Dunlap static int iscsi_isns_portal_cb(uintptr_t addr, const void *walker_data,
217a6d42e7dSPeter Dunlap     void *data);
218a6d42e7dSPeter Dunlap 
219a6d42e7dSPeter Dunlap #define	PORTAL_STR_LEN	(INET6_ADDRSTRLEN + 7)
220a6d42e7dSPeter Dunlap 
221a6d42e7dSPeter Dunlap /*
222a6d42e7dSPeter Dunlap  * ::iscsi_tgt [-scatgpbSRv]
223a6d42e7dSPeter Dunlap  *
224a6d42e7dSPeter Dunlap  * iscsi_tgt - Print out information associated with an iscsit target instance
225a6d42e7dSPeter Dunlap  *
226a6d42e7dSPeter Dunlap  * s	Print associated session information
227a6d42e7dSPeter Dunlap  * c	Print associated connection information
228a6d42e7dSPeter Dunlap  * a	Print IP addresses with connection information
229a6d42e7dSPeter Dunlap  * t	Print associated task information
230a6d42e7dSPeter Dunlap  * g	Print associated TPG information
231a6d42e7dSPeter Dunlap  * p	Print portals with TPG information
232a6d42e7dSPeter Dunlap  * b	Print associated buffer information
233a6d42e7dSPeter Dunlap  * S	Print recent state events and transitions
234a6d42e7dSPeter Dunlap  * R	Print reference count audit data
235a6d42e7dSPeter Dunlap  * v	Verbose output about the connection
236a6d42e7dSPeter Dunlap  */
237a6d42e7dSPeter Dunlap /*ARGSUSED*/
238a6d42e7dSPeter Dunlap static int
iscsi_tgt(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)239a6d42e7dSPeter Dunlap iscsi_tgt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
240a6d42e7dSPeter Dunlap {
241a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	idc;
242a6d42e7dSPeter Dunlap 	int			buffer = 0, task = 0, print_ip = 0;
243a6d42e7dSPeter Dunlap 	int			tpgt = 0, conn = 0, sess = 0, portal = 0;
244a6d42e7dSPeter Dunlap 	int			states = 0, rc_audit = 0;
245a6d42e7dSPeter Dunlap 	uintptr_t		iscsit_global_addr, avl_addr, list_addr;
246a6d42e7dSPeter Dunlap 	GElf_Sym		sym;
247a6d42e7dSPeter Dunlap 
248a6d42e7dSPeter Dunlap 	bzero(&idc, sizeof (idc));
249a6d42e7dSPeter Dunlap 	if (mdb_getopts(argc, argv,
250a6d42e7dSPeter Dunlap 	    'a', MDB_OPT_SETBITS, TRUE, &print_ip,
251a6d42e7dSPeter Dunlap 	    'g', MDB_OPT_SETBITS, TRUE, &tpgt,
252a6d42e7dSPeter Dunlap 	    's', MDB_OPT_SETBITS, TRUE, &sess,
253a6d42e7dSPeter Dunlap 	    'c', MDB_OPT_SETBITS, TRUE, &conn,
254a6d42e7dSPeter Dunlap 	    't', MDB_OPT_SETBITS, TRUE, &task,
255a6d42e7dSPeter Dunlap 	    'b', MDB_OPT_SETBITS, TRUE, &buffer,
256a6d42e7dSPeter Dunlap 	    'p', MDB_OPT_SETBITS, TRUE, &portal,
257a6d42e7dSPeter Dunlap 	    'S', MDB_OPT_SETBITS, TRUE, &states,
258a6d42e7dSPeter Dunlap 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
259a6d42e7dSPeter Dunlap 	    'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
260a6d42e7dSPeter Dunlap 	    NULL) != argc)
261a6d42e7dSPeter Dunlap 		return (DCMD_USAGE);
262a6d42e7dSPeter Dunlap 
263a6d42e7dSPeter Dunlap 	idc.u.child.idc_tgt = 1;
264a6d42e7dSPeter Dunlap 	idc.u.child.idc_print_ip = print_ip;
265a6d42e7dSPeter Dunlap 	idc.u.child.idc_tpgt = tpgt;
266a6d42e7dSPeter Dunlap 	idc.u.child.idc_portal = portal;
267a6d42e7dSPeter Dunlap 	idc.u.child.idc_sess = sess;
268a6d42e7dSPeter Dunlap 	idc.u.child.idc_conn = conn;
269a6d42e7dSPeter Dunlap 	idc.u.child.idc_task = task;
270a6d42e7dSPeter Dunlap 	idc.u.child.idc_buffer = buffer;
271a6d42e7dSPeter Dunlap 	idc.u.child.idc_states = states;
272a6d42e7dSPeter Dunlap 	idc.u.child.idc_rc_audit = rc_audit;
273a6d42e7dSPeter Dunlap 
274a6d42e7dSPeter Dunlap 	if (DCMD_HDRSPEC(flags))
275a6d42e7dSPeter Dunlap 		idc.idc_header = 1;
276a6d42e7dSPeter Dunlap 
277a6d42e7dSPeter Dunlap 	/*
278a6d42e7dSPeter Dunlap 	 * If no address was specified on the command line, we
279a6d42e7dSPeter Dunlap 	 * print out all tgtions
280a6d42e7dSPeter Dunlap 	 */
281a6d42e7dSPeter Dunlap 	if (!(flags & DCMD_ADDRSPEC)) {
282a6d42e7dSPeter Dunlap 		if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
283a6d42e7dSPeter Dunlap 			mdb_warn("failed to find symbol 'iscsit_global'");
284a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
285a6d42e7dSPeter Dunlap 		}
286a6d42e7dSPeter Dunlap 		iscsit_global_addr = (uintptr_t)sym.st_value;
287a6d42e7dSPeter Dunlap 		avl_addr = iscsit_global_addr +
288a6d42e7dSPeter Dunlap 		    offsetof(iscsit_global_t, global_target_list);
289a6d42e7dSPeter Dunlap 		if (mdb_pwalk("avl", iscsi_tgt_walk_cb, &idc, avl_addr) == -1) {
290a6d42e7dSPeter Dunlap 			mdb_warn("avl walk failed for global target tree");
291a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
292a6d42e7dSPeter Dunlap 		}
293a6d42e7dSPeter Dunlap 		list_addr = iscsit_global_addr +
294a6d42e7dSPeter Dunlap 		    offsetof(iscsit_global_t, global_deleted_target_list);
295a6d42e7dSPeter Dunlap 		if (mdb_pwalk("list", iscsi_tgt_walk_cb,
296a6d42e7dSPeter Dunlap 		    &idc, list_addr) == -1) {
297a6d42e7dSPeter Dunlap 			mdb_warn("list walk failed for deleted target list");
298a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
299a6d42e7dSPeter Dunlap 		}
300a6d42e7dSPeter Dunlap 		return (DCMD_OK);
301a6d42e7dSPeter Dunlap 	}
3025819f75eSPeter Gill 	return (iscsi_tgt_impl(addr, &idc));
303a6d42e7dSPeter Dunlap }
304a6d42e7dSPeter Dunlap 
305a6d42e7dSPeter Dunlap static int
iscsi_tpg(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)306a6d42e7dSPeter Dunlap iscsi_tpg(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
307a6d42e7dSPeter Dunlap {
308a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	idc;
309a6d42e7dSPeter Dunlap 	uintptr_t		iscsit_global_addr, avl_addr;
310a6d42e7dSPeter Dunlap 	GElf_Sym		sym;
3115819f75eSPeter Gill 	int			rc_audit = 0;
312a6d42e7dSPeter Dunlap 
313a6d42e7dSPeter Dunlap 	bzero(&idc, sizeof (idc));
314a6d42e7dSPeter Dunlap 	if (mdb_getopts(argc, argv,
3155819f75eSPeter Gill 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
316a6d42e7dSPeter Dunlap 	    NULL) != argc)
317a6d42e7dSPeter Dunlap 		return (DCMD_USAGE);
318a6d42e7dSPeter Dunlap 
3195819f75eSPeter Gill 	/* Always print tpgs and portals */
3205819f75eSPeter Gill 	idc.u.child.idc_tpg = 1;
3215819f75eSPeter Gill 	idc.u.child.idc_portal = 1;
3225819f75eSPeter Gill 	idc.u.child.idc_rc_audit = rc_audit;
323a6d42e7dSPeter Dunlap 	if (DCMD_HDRSPEC(flags))
324a6d42e7dSPeter Dunlap 		idc.idc_header = 1;
325a6d42e7dSPeter Dunlap 
326a6d42e7dSPeter Dunlap 	/*
327a6d42e7dSPeter Dunlap 	 * If no address was specified on the command line, we
328a6d42e7dSPeter Dunlap 	 * print out all tgtions
329a6d42e7dSPeter Dunlap 	 */
330a6d42e7dSPeter Dunlap 	if (!(flags & DCMD_ADDRSPEC)) {
331a6d42e7dSPeter Dunlap 		if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
332a6d42e7dSPeter Dunlap 			mdb_warn("failed to find symbol 'iscsit_global'");
333a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
334a6d42e7dSPeter Dunlap 		}
335a6d42e7dSPeter Dunlap 		iscsit_global_addr = (uintptr_t)sym.st_value;
336a6d42e7dSPeter Dunlap 		avl_addr = iscsit_global_addr +
337a6d42e7dSPeter Dunlap 		    offsetof(iscsit_global_t, global_tpg_list);
338a6d42e7dSPeter Dunlap 		if (mdb_pwalk("avl", iscsi_tpg_walk_cb, &idc, avl_addr) == -1) {
339a6d42e7dSPeter Dunlap 			mdb_warn("avl walk failed for global target tree");
340a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
341a6d42e7dSPeter Dunlap 		}
342a6d42e7dSPeter Dunlap 		return (DCMD_OK);
343a6d42e7dSPeter Dunlap 	}
3445819f75eSPeter Gill 	return (iscsi_tpg_impl(addr, &idc));
345a6d42e7dSPeter Dunlap }
346a6d42e7dSPeter Dunlap 
347a6d42e7dSPeter Dunlap /*
3485819f75eSPeter Gill  * ::iscsi_tpgt [-pR]
3495819f75eSPeter Gill  *
3505819f75eSPeter Gill  * Print tpgt information.
3515819f75eSPeter Gill  * R	Print reference count audit data
3525819f75eSPeter Gill  * p	Print portal data
3535819f75eSPeter Gill  */
3545819f75eSPeter Gill static int
iscsi_tpgt(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)3555819f75eSPeter Gill iscsi_tpgt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3565819f75eSPeter Gill {
3575819f75eSPeter Gill 	iscsi_dcmd_ctrl_t	idc;
3585819f75eSPeter Gill 	uintptr_t		iscsit_global_addr, avl_addr, list_addr;
3595819f75eSPeter Gill 	GElf_Sym		sym;
3605819f75eSPeter Gill 	int			rc_audit = 0, portal = 0;
3615819f75eSPeter Gill 
3625819f75eSPeter Gill 	bzero(&idc, sizeof (idc));
3635819f75eSPeter Gill 	if (mdb_getopts(argc, argv,
3645819f75eSPeter Gill 	    'p', MDB_OPT_SETBITS, TRUE, &portal,
3655819f75eSPeter Gill 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
3665819f75eSPeter Gill 	    NULL) != argc)
3675819f75eSPeter Gill 		return (DCMD_USAGE);
3685819f75eSPeter Gill 
3695819f75eSPeter Gill 	idc.u.child.idc_tpgt = 1;
3705819f75eSPeter Gill 	idc.u.child.idc_portal = portal;
3715819f75eSPeter Gill 	idc.u.child.idc_rc_audit = rc_audit;
3725819f75eSPeter Gill 	if (DCMD_HDRSPEC(flags))
3735819f75eSPeter Gill 		idc.idc_header = 1;
3745819f75eSPeter Gill 
3755819f75eSPeter Gill 	/*
3765819f75eSPeter Gill 	 * If no address was specified on the command line,
3775819f75eSPeter Gill 	 * print out all tpgts
3785819f75eSPeter Gill 	 */
3795819f75eSPeter Gill 	if (!(flags & DCMD_ADDRSPEC)) {
3805819f75eSPeter Gill 		if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
3815819f75eSPeter Gill 			mdb_warn("failed to find symbol 'iscsit_global'");
3825819f75eSPeter Gill 			return (DCMD_ERR);
3835819f75eSPeter Gill 		}
3845819f75eSPeter Gill 		iscsit_global_addr = (uintptr_t)sym.st_value;
3855819f75eSPeter Gill 		avl_addr = iscsit_global_addr +
3865819f75eSPeter Gill 		    offsetof(iscsit_global_t, global_target_list);
3875819f75eSPeter Gill 		if (mdb_pwalk("avl", iscsi_tgt_walk_cb, &idc, avl_addr) == -1) {
3885819f75eSPeter Gill 			mdb_warn("avl walk failed for global target tree");
3895819f75eSPeter Gill 			return (DCMD_ERR);
3905819f75eSPeter Gill 		}
3915819f75eSPeter Gill 		list_addr = iscsit_global_addr +
3925819f75eSPeter Gill 		    offsetof(iscsit_global_t, global_deleted_target_list);
3935819f75eSPeter Gill 		if (mdb_pwalk("list", iscsi_tgt_walk_cb,
3945819f75eSPeter Gill 		    &idc, list_addr) == -1) {
3955819f75eSPeter Gill 			mdb_warn("list walk failed for deleted target list");
3965819f75eSPeter Gill 			return (DCMD_ERR);
3975819f75eSPeter Gill 		}
3985819f75eSPeter Gill 		return (DCMD_OK);
3995819f75eSPeter Gill 	}
4005819f75eSPeter Gill 	return (iscsi_tpgt_impl(addr, &idc));
4015819f75eSPeter Gill }
4025819f75eSPeter Gill 
4035819f75eSPeter Gill /*
4045819f75eSPeter Gill  * ::iscsi_sess [-ablmtvcSRIT]
405a6d42e7dSPeter Dunlap  *
406a6d42e7dSPeter Dunlap  * iscsi_sess - Print out information associated with an iSCSI session
407a6d42e7dSPeter Dunlap  *
408a6d42e7dSPeter Dunlap  * I	Print only initiator sessions
409a6d42e7dSPeter Dunlap  * T	Print only target sessions
410a6d42e7dSPeter Dunlap  * c	Print associated connection information
411a6d42e7dSPeter Dunlap  * a	Print IP addresses with connection information
412a6d42e7dSPeter Dunlap  * t	Print associated task information
4135819f75eSPeter Gill  * l	Print associated lun information (with -I)
4145819f75eSPeter Gill  * m	Print associated initiator command information (with -I)
415a6d42e7dSPeter Dunlap  * b	Print associated buffer information
416a6d42e7dSPeter Dunlap  * S	Print recent state events and transitions
417a6d42e7dSPeter Dunlap  * R	Print reference count audit data
418a6d42e7dSPeter Dunlap  * v	Verbose output about the connection
419a6d42e7dSPeter Dunlap  */
420a6d42e7dSPeter Dunlap /*ARGSUSED*/
421a6d42e7dSPeter Dunlap static int
iscsi_sess(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)422a6d42e7dSPeter Dunlap iscsi_sess(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
423a6d42e7dSPeter Dunlap {
424a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	idc;
425a6d42e7dSPeter Dunlap 	int			buffer = 0, task = 0, conn = 0, print_ip = 0;
4265819f75eSPeter Gill 	int			states = 0, rc_audit = 0, commands = 0;
4275819f75eSPeter Gill 	int			luns = 0;
428a6d42e7dSPeter Dunlap 
429a6d42e7dSPeter Dunlap 	bzero(&idc, sizeof (idc));
430a6d42e7dSPeter Dunlap 	if (mdb_getopts(argc, argv,
431a6d42e7dSPeter Dunlap 	    'I', MDB_OPT_SETBITS, TRUE, &idc.idc_ini,
432a6d42e7dSPeter Dunlap 	    'T', MDB_OPT_SETBITS, TRUE, &idc.idc_tgt,
433a6d42e7dSPeter Dunlap 	    'a', MDB_OPT_SETBITS, TRUE, &print_ip,
434a6d42e7dSPeter Dunlap 	    'c', MDB_OPT_SETBITS, TRUE, &conn,
435a6d42e7dSPeter Dunlap 	    't', MDB_OPT_SETBITS, TRUE, &task,
4365819f75eSPeter Gill 	    'l', MDB_OPT_SETBITS, TRUE, &luns,
4375819f75eSPeter Gill 	    'm', MDB_OPT_SETBITS, TRUE, &commands,
438a6d42e7dSPeter Dunlap 	    'b', MDB_OPT_SETBITS, TRUE, &buffer,
439a6d42e7dSPeter Dunlap 	    'S', MDB_OPT_SETBITS, TRUE, &states,
440a6d42e7dSPeter Dunlap 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
441a6d42e7dSPeter Dunlap 	    'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
442a6d42e7dSPeter Dunlap 	    NULL) != argc)
443a6d42e7dSPeter Dunlap 		return (DCMD_USAGE);
444a6d42e7dSPeter Dunlap 
445a6d42e7dSPeter Dunlap 	idc.u.child.idc_sess = 1;
446a6d42e7dSPeter Dunlap 	idc.u.child.idc_print_ip = print_ip;
447a6d42e7dSPeter Dunlap 	idc.u.child.idc_conn = conn;
448a6d42e7dSPeter Dunlap 	idc.u.child.idc_task = task;
4495819f75eSPeter Gill 	idc.u.child.idc_cmd = commands;
4505819f75eSPeter Gill 	idc.u.child.idc_lun = luns;
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 sessions
460a6d42e7dSPeter Dunlap 	 */
461a6d42e7dSPeter Dunlap 	if (!(flags & DCMD_ADDRSPEC)) {
462a6d42e7dSPeter Dunlap 		return (iscsi_walk_all_sess(&idc));
463a6d42e7dSPeter Dunlap 	}
4645819f75eSPeter Gill 	return (iscsi_sess_impl(addr, &idc));
465a6d42e7dSPeter Dunlap }
466a6d42e7dSPeter Dunlap 
467a6d42e7dSPeter Dunlap 
468a6d42e7dSPeter Dunlap 
469a6d42e7dSPeter Dunlap /*
4705819f75eSPeter Gill  * ::iscsi_conn [-abmtvSRIT]
471a6d42e7dSPeter Dunlap  *
472a6d42e7dSPeter Dunlap  * iscsi_conn - Print out information associated with an iSCSI connection
473a6d42e7dSPeter Dunlap  *
474a6d42e7dSPeter Dunlap  * I	Print only initiator connections
475a6d42e7dSPeter Dunlap  * T	Print only target connections
476a6d42e7dSPeter Dunlap  * a	Print IP addresses with connection information
477a6d42e7dSPeter Dunlap  * t	Print associated task information
478a6d42e7dSPeter Dunlap  * b	Print associated buffer information
4795819f75eSPeter Gill  * m	Print associated initiator commands (with -I)
480a6d42e7dSPeter Dunlap  * S	Print recent state events and transitions
481a6d42e7dSPeter Dunlap  * R	Print reference count audit data
482a6d42e7dSPeter Dunlap  * v	Verbose output about the connection
483a6d42e7dSPeter Dunlap  */
484a6d42e7dSPeter Dunlap /*ARGSUSED*/
485a6d42e7dSPeter Dunlap static int
iscsi_conn(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)486a6d42e7dSPeter Dunlap iscsi_conn(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
487a6d42e7dSPeter Dunlap {
488a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	idc;
489a6d42e7dSPeter Dunlap 	int			buffer = 0, task = 0, print_ip = 0;
4905819f75eSPeter Gill 	int			states = 0, rc_audit = 0, commands = 0;
491a6d42e7dSPeter Dunlap 
492a6d42e7dSPeter Dunlap 	bzero(&idc, sizeof (idc));
493a6d42e7dSPeter Dunlap 	if (mdb_getopts(argc, argv,
494a6d42e7dSPeter Dunlap 	    'I', MDB_OPT_SETBITS, TRUE, &idc.idc_ini,
495a6d42e7dSPeter Dunlap 	    'T', MDB_OPT_SETBITS, TRUE, &idc.idc_tgt,
496a6d42e7dSPeter Dunlap 	    'a', MDB_OPT_SETBITS, TRUE, &print_ip,
497a6d42e7dSPeter Dunlap 	    't', MDB_OPT_SETBITS, TRUE, &task,
498a6d42e7dSPeter Dunlap 	    'b', MDB_OPT_SETBITS, TRUE, &buffer,
4995819f75eSPeter Gill 	    'm', MDB_OPT_SETBITS, TRUE, &commands,
500a6d42e7dSPeter Dunlap 	    'S', MDB_OPT_SETBITS, TRUE, &states,
501a6d42e7dSPeter Dunlap 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
502a6d42e7dSPeter Dunlap 	    'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
503a6d42e7dSPeter Dunlap 	    NULL) != argc)
504a6d42e7dSPeter Dunlap 		return (DCMD_USAGE);
505a6d42e7dSPeter Dunlap 
506a6d42e7dSPeter Dunlap 	idc.u.child.idc_conn = 1;
507a6d42e7dSPeter Dunlap 	idc.u.child.idc_print_ip = print_ip;
508a6d42e7dSPeter Dunlap 	idc.u.child.idc_task = task;
509a6d42e7dSPeter Dunlap 	idc.u.child.idc_buffer = buffer;
5105819f75eSPeter Gill 	idc.u.child.idc_cmd = commands;
511a6d42e7dSPeter Dunlap 	idc.u.child.idc_states = states;
512a6d42e7dSPeter Dunlap 	idc.u.child.idc_rc_audit = rc_audit;
513a6d42e7dSPeter Dunlap 	if (DCMD_HDRSPEC(flags))
514a6d42e7dSPeter Dunlap 		idc.idc_header = 1;
515a6d42e7dSPeter Dunlap 
516a6d42e7dSPeter Dunlap 	/*
517a6d42e7dSPeter Dunlap 	 * If no address was specified on the command line, we
518a6d42e7dSPeter Dunlap 	 * print out all connections
519a6d42e7dSPeter Dunlap 	 */
520a6d42e7dSPeter Dunlap 	if (!(flags & DCMD_ADDRSPEC)) {
521a6d42e7dSPeter Dunlap 		return (iscsi_walk_all_conn(&idc));
5225819f75eSPeter Gill 	}
523a6d42e7dSPeter Dunlap 	return (iscsi_conn_impl(addr, &idc));
524a6d42e7dSPeter Dunlap }
5255819f75eSPeter Gill 
5265819f75eSPeter Gill 
5275819f75eSPeter Gill /*
5285819f75eSPeter Gill  * ::iscsi_svc [-vR]
5295819f75eSPeter Gill  *
5305819f75eSPeter Gill  * iscsi_svc - Print out information associated with an iSCSI svc
5315819f75eSPeter Gill  *
5325819f75eSPeter Gill  * R	Print reference count audit data
5335819f75eSPeter Gill  * v	Verbose output about the service
5345819f75eSPeter Gill  */
5355819f75eSPeter Gill static int
iscsi_svc(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)5365819f75eSPeter Gill iscsi_svc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
5375819f75eSPeter Gill {
5385819f75eSPeter Gill 	iscsi_dcmd_ctrl_t	idc;
5395819f75eSPeter Gill 	GElf_Sym		sym;
5405819f75eSPeter Gill 	uintptr_t		idm_addr;
5415819f75eSPeter Gill 	uintptr_t		svc_list_addr;
5425819f75eSPeter Gill 	int			rc_audit = 0;
5435819f75eSPeter Gill 
5445819f75eSPeter Gill 	bzero(&idc, sizeof (iscsi_dcmd_ctrl_t));
5455819f75eSPeter Gill 
5465819f75eSPeter Gill 	if (mdb_getopts(argc, argv,
5475819f75eSPeter Gill 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
5485819f75eSPeter Gill 	    'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
5495819f75eSPeter Gill 	    NULL) != argc)
5505819f75eSPeter Gill 		return (DCMD_USAGE);
5515819f75eSPeter Gill 
5525819f75eSPeter Gill 	idc.u.child.idc_svc = 1;
5535819f75eSPeter Gill 	idc.u.child.idc_rc_audit = rc_audit;
5545819f75eSPeter Gill 	if (DCMD_HDRSPEC(flags)) {
5555819f75eSPeter Gill 		idc.idc_header = 1;
5565819f75eSPeter Gill 	}
5575819f75eSPeter Gill 
5585819f75eSPeter Gill 	if (!(flags & DCMD_ADDRSPEC)) {
5595819f75eSPeter Gill 		if (mdb_lookup_by_name("idm", &sym) == -1) {
5605819f75eSPeter Gill 			mdb_warn("failed to find symbol 'idm'");
5615819f75eSPeter Gill 			return (DCMD_ERR);
5625819f75eSPeter Gill 		}
5635819f75eSPeter Gill 		idm_addr = (uintptr_t)sym.st_value;
5645819f75eSPeter Gill 		svc_list_addr = idm_addr + offsetof(idm_global_t,
5655819f75eSPeter Gill 		    idm_tgt_svc_list);
5665819f75eSPeter Gill 
5675819f75eSPeter Gill 		if (mdb_pwalk("list", iscsi_svc_walk_cb, &idc,
5685819f75eSPeter Gill 		    svc_list_addr) == -1) {
5695819f75eSPeter Gill 			mdb_warn("list walk failed for idm services");
5705819f75eSPeter Gill 			return (DCMD_ERR);
5715819f75eSPeter Gill 		}
5725819f75eSPeter Gill 		return (DCMD_OK);
5735819f75eSPeter Gill 	}
5745819f75eSPeter Gill 	return (iscsi_svc_impl(addr, &idc));
5755819f75eSPeter Gill }
5765819f75eSPeter Gill 
5775819f75eSPeter Gill /*
5785819f75eSPeter Gill  * ::iscsi_portal -R
5795819f75eSPeter Gill  *
5805819f75eSPeter Gill  * iscsi_portal - Print out information associated with an iSCSI portal
5815819f75eSPeter Gill  *
5825819f75eSPeter Gill  * R	Print reference count audit data
5835819f75eSPeter Gill  */
5845819f75eSPeter Gill static int
iscsi_portal(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)5855819f75eSPeter Gill iscsi_portal(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
5865819f75eSPeter Gill {
5875819f75eSPeter Gill 	iscsi_dcmd_ctrl_t	idc;
5885819f75eSPeter Gill 	GElf_Sym		sym;
5895819f75eSPeter Gill 	iscsit_global_t		iscsit_global;
5905819f75eSPeter Gill 	uintptr_t		iscsit_global_addr;
5915819f75eSPeter Gill 	uintptr_t		tpg_avl_addr;
5925819f75eSPeter Gill 	int			rc_audit = 0;
5935819f75eSPeter Gill 
5945819f75eSPeter Gill 	bzero(&idc, sizeof (iscsi_dcmd_ctrl_t));
5955819f75eSPeter Gill 
5965819f75eSPeter Gill 	if (mdb_getopts(argc, argv,
5975819f75eSPeter Gill 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
5985819f75eSPeter Gill 	    NULL) != argc)
5995819f75eSPeter Gill 		return (DCMD_USAGE);
6005819f75eSPeter Gill 
6015819f75eSPeter Gill 	idc.u.child.idc_rc_audit = rc_audit;
6025819f75eSPeter Gill 	idc.u.child.idc_portal = 1;
6035819f75eSPeter Gill 	if (DCMD_HDRSPEC(flags)) {
6045819f75eSPeter Gill 		idc.idc_header = 1;
6055819f75eSPeter Gill 	}
6065819f75eSPeter Gill 
6075819f75eSPeter Gill 	if (!(flags & DCMD_ADDRSPEC)) {
6085819f75eSPeter Gill 		if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
6095819f75eSPeter Gill 			mdb_warn("failed to find symbol 'iscsit_global'");
6105819f75eSPeter Gill 			return (DCMD_ERR);
6115819f75eSPeter Gill 		}
6125819f75eSPeter Gill 
6135819f75eSPeter Gill 		iscsit_global_addr = (uintptr_t)sym.st_value;
6145819f75eSPeter Gill 
6155819f75eSPeter Gill 		/* get and print the global default tpg */
6165819f75eSPeter Gill 		if (mdb_vread(&iscsit_global, sizeof (iscsit_global_t),
6175819f75eSPeter Gill 		    iscsit_global_addr) != sizeof (iscsit_global_t)) {
6185819f75eSPeter Gill 			mdb_warn("failed to read iscsit_global_t");
6195819f75eSPeter Gill 			return (DCMD_ERR);
6205819f75eSPeter Gill 		}
6215819f75eSPeter Gill 		if (iscsi_tpg_impl((uintptr_t)iscsit_global.global_default_tpg,
6225819f75eSPeter Gill 		    &idc) != DCMD_OK) {
6235819f75eSPeter Gill 			return (DCMD_ERR);
6245819f75eSPeter Gill 		}
6255819f75eSPeter Gill 
6265819f75eSPeter Gill 		/* Walk the tpgs for the rest of the portals */
6275819f75eSPeter Gill 		tpg_avl_addr = iscsit_global_addr + offsetof(iscsit_global_t,
6285819f75eSPeter Gill 		    global_tpg_list);
6295819f75eSPeter Gill 		if (mdb_pwalk("avl", iscsi_tpg_walk_cb, &idc,
6305819f75eSPeter Gill 		    tpg_avl_addr) == -1) {
6315819f75eSPeter Gill 			mdb_warn("list walk failed for global tpg tree");
6325819f75eSPeter Gill 			return (DCMD_ERR);
6335819f75eSPeter Gill 		}
6345819f75eSPeter Gill 		return (DCMD_OK);
6355819f75eSPeter Gill 	}
6365819f75eSPeter Gill 	return (iscsi_portal_impl(addr, &idc));
6375819f75eSPeter Gill }
6385819f75eSPeter Gill 
6395819f75eSPeter Gill 
6405819f75eSPeter Gill /*
6415819f75eSPeter Gill  * ::iscsi_cmd -S
6425819f75eSPeter Gill  *
6435819f75eSPeter Gill  * iscsi_cmd - Print out information associated with an iSCSI cmd
6445819f75eSPeter Gill  *
6455819f75eSPeter Gill  * S	Print state audit data
6465819f75eSPeter Gill  */
6475819f75eSPeter Gill static int
iscsi_cmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)6485819f75eSPeter Gill iscsi_cmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
6495819f75eSPeter Gill {
6505819f75eSPeter Gill 	iscsi_dcmd_ctrl_t	idc;
6515819f75eSPeter Gill 	iscsi_cmd_t		cmd;
6525819f75eSPeter Gill 	int			states = 0;
6535819f75eSPeter Gill 
6545819f75eSPeter Gill 	bzero(&idc, sizeof (iscsi_dcmd_ctrl_t));
6555819f75eSPeter Gill 
6565819f75eSPeter Gill 	if (mdb_getopts(argc, argv,
6575819f75eSPeter Gill 	    'S', MDB_OPT_SETBITS, TRUE, &states,
6585819f75eSPeter Gill 	    NULL) != argc)
6595819f75eSPeter Gill 		return (DCMD_USAGE);
6605819f75eSPeter Gill 
6615819f75eSPeter Gill 	idc.u.child.idc_states = states;
6625819f75eSPeter Gill 	idc.u.child.idc_cmd = 1;
6635819f75eSPeter Gill 	idc.idc_ini = 1;
6645819f75eSPeter Gill 	if (DCMD_HDRSPEC(flags)) {
6655819f75eSPeter Gill 		idc.idc_header = 1;
6665819f75eSPeter Gill 	}
6675819f75eSPeter Gill 
6685819f75eSPeter Gill 	if (!(flags & DCMD_ADDRSPEC)) {
6695819f75eSPeter Gill 		if (mdb_pwalk("iscsi_ini_hba", iscsi_ini_hba_walk_cb,
6705819f75eSPeter Gill 		    &idc, NULL) == -1) {
6715819f75eSPeter Gill 			mdb_warn("iscsi cmd hba list walk failed");
6725819f75eSPeter Gill 			return (DCMD_ERR);
6735819f75eSPeter Gill 		}
6745819f75eSPeter Gill 	} else {
6755819f75eSPeter Gill 		if (mdb_vread(&cmd, sizeof (iscsi_cmd_t), addr) !=
6765819f75eSPeter Gill 		    sizeof (iscsi_cmd_t)) {
6775819f75eSPeter Gill 			return (DCMD_ERR);
6785819f75eSPeter Gill 		}
6795819f75eSPeter Gill 		return (iscsi_print_ini_cmd(addr, &cmd, &idc));
6805819f75eSPeter Gill 	}
6815819f75eSPeter Gill 	return (DCMD_OK);
6825819f75eSPeter Gill }
6835819f75eSPeter Gill 
6845819f75eSPeter Gill 
6855819f75eSPeter Gill static int
iscsi_ini_hba_impl(uintptr_t addr,iscsi_dcmd_ctrl_t * idc)6865819f75eSPeter Gill iscsi_ini_hba_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc) {
6875819f75eSPeter Gill 	iscsi_hba_t ih;
6885819f75eSPeter Gill 
6895819f75eSPeter Gill 	if (mdb_vread(&ih, sizeof (ih), addr) != sizeof (ih)) {
6905819f75eSPeter Gill 		mdb_warn("Invalid HBA\n");
6915819f75eSPeter Gill 		return (DCMD_ERR);
6925819f75eSPeter Gill 	}
6935819f75eSPeter Gill 
6945819f75eSPeter Gill 	if (idc->u.child.idc_hba) {
6955819f75eSPeter Gill 		mdb_printf("iscsi_hba %p sessions: \n", addr);
6965819f75eSPeter Gill 	}
6975819f75eSPeter Gill 
6985819f75eSPeter Gill 	if (mdb_pwalk("iscsi_ini_sess", iscsi_ini_sess_walk_cb, idc,
6995819f75eSPeter Gill 	    (uintptr_t)ih.hba_sess_list) == -1) {
7005819f75eSPeter Gill 		mdb_warn("iscsi_sess_t walk failed");
7015819f75eSPeter Gill 		return (DCMD_ERR);
7025819f75eSPeter Gill 	}
7035819f75eSPeter Gill 	return (DCMD_OK);
704a6d42e7dSPeter Dunlap }
705a6d42e7dSPeter Dunlap 
706a6d42e7dSPeter Dunlap /*
707a6d42e7dSPeter Dunlap  * ::iscsi_task [-bv]
708a6d42e7dSPeter Dunlap  *
709a6d42e7dSPeter Dunlap  * iscsi_task - Print out information associated with an iSCSI task
710a6d42e7dSPeter Dunlap  *
711a6d42e7dSPeter Dunlap  * b	Print associated buffer information
712a6d42e7dSPeter Dunlap  * S	Print recent state events and transitions
713a6d42e7dSPeter Dunlap  * R	Print reference count audit data
714a6d42e7dSPeter Dunlap  * v	Verbose output about the connection
715a6d42e7dSPeter Dunlap  */
716a6d42e7dSPeter Dunlap /*ARGSUSED*/
717a6d42e7dSPeter Dunlap static int
iscsi_task(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)718a6d42e7dSPeter Dunlap iscsi_task(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
719a6d42e7dSPeter Dunlap {
720a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	idc;
721a6d42e7dSPeter Dunlap 	int			buffer = 0;
722a6d42e7dSPeter Dunlap 	int			states = 0, rc_audit = 0;
723a6d42e7dSPeter Dunlap 
724a6d42e7dSPeter Dunlap 	bzero(&idc, sizeof (idc));
725a6d42e7dSPeter Dunlap 	if (mdb_getopts(argc, argv,
726a6d42e7dSPeter Dunlap 	    'b', MDB_OPT_SETBITS, TRUE, &buffer,
727a6d42e7dSPeter Dunlap 	    'S', MDB_OPT_SETBITS, TRUE, &states,
728a6d42e7dSPeter Dunlap 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
729a6d42e7dSPeter Dunlap 	    'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
730a6d42e7dSPeter Dunlap 	    NULL) != argc)
731a6d42e7dSPeter Dunlap 		return (DCMD_USAGE);
732a6d42e7dSPeter Dunlap 
733a6d42e7dSPeter Dunlap 	idc.u.child.idc_conn = 0;
734a6d42e7dSPeter Dunlap 	idc.u.child.idc_task = 1;
735a6d42e7dSPeter Dunlap 	idc.u.child.idc_buffer = buffer;
736a6d42e7dSPeter Dunlap 	idc.u.child.idc_states = states;
737a6d42e7dSPeter Dunlap 	idc.u.child.idc_rc_audit = rc_audit;
738a6d42e7dSPeter Dunlap 	if (DCMD_HDRSPEC(flags))
739a6d42e7dSPeter Dunlap 		idc.idc_header = 1;
740a6d42e7dSPeter Dunlap 
741a6d42e7dSPeter Dunlap 	/*
742a6d42e7dSPeter Dunlap 	 * If no address was specified on the command line, we
743a6d42e7dSPeter Dunlap 	 * print out all connections
744a6d42e7dSPeter Dunlap 	 */
745a6d42e7dSPeter Dunlap 	if (!(flags & DCMD_ADDRSPEC)) {
746a6d42e7dSPeter Dunlap 		return (iscsi_walk_all_conn(&idc));
747a6d42e7dSPeter Dunlap 	}
7485819f75eSPeter Gill 	return (iscsi_task_impl(addr, &idc));
749a6d42e7dSPeter Dunlap }
750a6d42e7dSPeter Dunlap 
751a6d42e7dSPeter Dunlap /*
752a6d42e7dSPeter Dunlap  * ::iscsi_refcnt
753a6d42e7dSPeter Dunlap  *
754a6d42e7dSPeter Dunlap  * iscsi_refcnt - Dump an idm_refcnt_t structure
755a6d42e7dSPeter Dunlap  *
756a6d42e7dSPeter Dunlap  */
757a6d42e7dSPeter Dunlap /*ARGSUSED*/
758a6d42e7dSPeter Dunlap static int
iscsi_refcnt(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)759a6d42e7dSPeter Dunlap iscsi_refcnt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
760a6d42e7dSPeter Dunlap {
761a6d42e7dSPeter Dunlap 	if (!(flags & DCMD_ADDRSPEC)) {
762a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
763a6d42e7dSPeter Dunlap 	}
7645819f75eSPeter Gill 	return (iscsi_refcnt_impl(addr));
765a6d42e7dSPeter Dunlap }
766a6d42e7dSPeter Dunlap 
767a6d42e7dSPeter Dunlap /*
768a6d42e7dSPeter Dunlap  * ::iscsi_states
769a6d42e7dSPeter Dunlap  *
770a6d42e7dSPeter Dunlap  * iscsi_states - Dump events and state transitions recoreded in an
771a6d42e7dSPeter Dunlap  * idm_sm_audit_t structure
772a6d42e7dSPeter Dunlap  *
773a6d42e7dSPeter Dunlap  */
774a6d42e7dSPeter Dunlap /*ARGSUSED*/
775a6d42e7dSPeter Dunlap static int
iscsi_states(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)776a6d42e7dSPeter Dunlap iscsi_states(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
777a6d42e7dSPeter Dunlap {
778a6d42e7dSPeter Dunlap 	if (!(flags & DCMD_ADDRSPEC)) {
779a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
7805819f75eSPeter Gill 	}
781a6d42e7dSPeter Dunlap 	return (iscsi_sm_audit_impl(addr));
782a6d42e7dSPeter Dunlap }
783a6d42e7dSPeter Dunlap 
78430e7468fSPeter Dunlap 
785a6d42e7dSPeter Dunlap static int
iscsi_walk_all_sess(iscsi_dcmd_ctrl_t * idc)786a6d42e7dSPeter Dunlap iscsi_walk_all_sess(iscsi_dcmd_ctrl_t *idc)
787a6d42e7dSPeter Dunlap {
788a6d42e7dSPeter Dunlap 	uintptr_t	iscsit_global_addr;
789a6d42e7dSPeter Dunlap 	uintptr_t	avl_addr;
790a6d42e7dSPeter Dunlap 	uintptr_t	list_addr;
791a6d42e7dSPeter Dunlap 	GElf_Sym	sym;
7925819f75eSPeter Gill 
79330e7468fSPeter Dunlap 	/* Initiator sessions */
79430e7468fSPeter Dunlap 	if (idc->idc_ini) {
7955819f75eSPeter Gill 		/* Always print hba info on this path */
7965819f75eSPeter Gill 		idc->u.child.idc_hba = 1;
7975819f75eSPeter Gill 		if (mdb_pwalk("iscsi_ini_hba", iscsi_ini_hba_walk_cb,
7985819f75eSPeter Gill 		    idc, NULL) == -1) {
7995819f75eSPeter Gill 			mdb_warn("iscsi cmd hba list walk failed");
80030e7468fSPeter Dunlap 			return (DCMD_ERR);
80130e7468fSPeter Dunlap 		}
8025819f75eSPeter Gill 		return (DCMD_OK);
80330e7468fSPeter Dunlap 	}
8045819f75eSPeter Gill 
80530e7468fSPeter Dunlap 	/* Target sessions */
806a6d42e7dSPeter Dunlap 	/* Walk discovery sessions */
807a6d42e7dSPeter Dunlap 	if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
808a6d42e7dSPeter Dunlap 		mdb_warn("failed to find symbol 'iscsit_global'");
809a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
810a6d42e7dSPeter Dunlap 	}
811a6d42e7dSPeter Dunlap 	iscsit_global_addr = (uintptr_t)sym.st_value;
812a6d42e7dSPeter Dunlap 	avl_addr = iscsit_global_addr +
813a6d42e7dSPeter Dunlap 	    offsetof(iscsit_global_t, global_discovery_sessions);
814a6d42e7dSPeter Dunlap 	if (mdb_pwalk("avl", iscsi_sess_walk_cb, idc, avl_addr) == -1) {
815a6d42e7dSPeter Dunlap 		mdb_warn("avl walk failed for discovery sessions");
816a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
817a6d42e7dSPeter Dunlap 	}
818a6d42e7dSPeter Dunlap 
819a6d42e7dSPeter Dunlap 	/* Walk targets printing all session info */
820a6d42e7dSPeter Dunlap 	avl_addr = iscsit_global_addr +
821a6d42e7dSPeter Dunlap 	    offsetof(iscsit_global_t, global_target_list);
822a6d42e7dSPeter Dunlap 	if (mdb_pwalk("avl", iscsi_tgt_walk_cb, idc, avl_addr) == -1) {
823a6d42e7dSPeter Dunlap 		mdb_warn("avl walk failed for target/session tree");
824a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
825a6d42e7dSPeter Dunlap 	}
826a6d42e7dSPeter Dunlap 
827a6d42e7dSPeter Dunlap 	/* Walk deleting targets printing all session info */
828a6d42e7dSPeter Dunlap 	list_addr = iscsit_global_addr +
829a6d42e7dSPeter Dunlap 	    offsetof(iscsit_global_t, global_deleted_target_list);
830a6d42e7dSPeter Dunlap 	if (mdb_pwalk("list", iscsi_tgt_walk_cb, idc, list_addr) == -1) {
831a6d42e7dSPeter Dunlap 		mdb_warn("list walk failed for deleted target list");
832a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
833a6d42e7dSPeter Dunlap 	}
834a6d42e7dSPeter Dunlap 
835a6d42e7dSPeter Dunlap 	return (DCMD_OK);
836a6d42e7dSPeter Dunlap }
837a6d42e7dSPeter Dunlap 
838a6d42e7dSPeter Dunlap static int
iscsi_walk_all_conn(iscsi_dcmd_ctrl_t * idc)839a6d42e7dSPeter Dunlap iscsi_walk_all_conn(iscsi_dcmd_ctrl_t *idc)
840a6d42e7dSPeter Dunlap {
841a6d42e7dSPeter Dunlap 	uintptr_t	idm_global_addr;
842a6d42e7dSPeter Dunlap 	uintptr_t	list_addr;
843a6d42e7dSPeter Dunlap 	GElf_Sym	sym;
844a6d42e7dSPeter Dunlap 
845a6d42e7dSPeter Dunlap 	/* Walk initiator connections */
846a6d42e7dSPeter Dunlap 	if (mdb_lookup_by_name("idm", &sym) == -1) {
847a6d42e7dSPeter Dunlap 		mdb_warn("failed to find symbol 'idm'");
848a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
849a6d42e7dSPeter Dunlap 	}
850a6d42e7dSPeter Dunlap 	idm_global_addr = (uintptr_t)sym.st_value;
851a6d42e7dSPeter Dunlap 	/* Walk connection list associated with the initiator */
852a6d42e7dSPeter Dunlap 	list_addr = idm_global_addr + offsetof(idm_global_t, idm_ini_conn_list);
853a6d42e7dSPeter Dunlap 	if (mdb_pwalk("list", iscsi_conn_walk_cb, idc, list_addr) == -1) {
854a6d42e7dSPeter Dunlap 		mdb_warn("list walk failed for initiator connections");
855a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
856a6d42e7dSPeter Dunlap 	}
857a6d42e7dSPeter Dunlap 
858a6d42e7dSPeter Dunlap 	/* Walk connection list associated with the target */
859a6d42e7dSPeter Dunlap 	list_addr = idm_global_addr + offsetof(idm_global_t, idm_tgt_conn_list);
860a6d42e7dSPeter Dunlap 	if (mdb_pwalk("list", iscsi_conn_walk_cb, idc, list_addr) == -1) {
861a6d42e7dSPeter Dunlap 		mdb_warn("list walk failed for target service instances");
862a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
863a6d42e7dSPeter Dunlap 	}
864a6d42e7dSPeter Dunlap 
865a6d42e7dSPeter Dunlap 	return (DCMD_OK);
866a6d42e7dSPeter Dunlap }
867a6d42e7dSPeter Dunlap 
868a6d42e7dSPeter Dunlap /*ARGSUSED*/
869a6d42e7dSPeter Dunlap static int
iscsi_tpg_walk_cb(uintptr_t addr,const void * list_walker_data,void * idc_void)870a6d42e7dSPeter Dunlap iscsi_tpg_walk_cb(uintptr_t addr, const void *list_walker_data,
871a6d42e7dSPeter Dunlap     void *idc_void)
872a6d42e7dSPeter Dunlap {
873a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
874a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
875a6d42e7dSPeter Dunlap 	int			rc;
876a6d42e7dSPeter Dunlap 
877a6d42e7dSPeter Dunlap 	rc = iscsi_tpg_impl(addr, idc);
878a6d42e7dSPeter Dunlap 
879a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
880a6d42e7dSPeter Dunlap }
881a6d42e7dSPeter Dunlap 
882a6d42e7dSPeter Dunlap /*ARGSUSED*/
883a6d42e7dSPeter Dunlap static int
iscsi_tgt_walk_cb(uintptr_t addr,const void * list_walker_data,void * idc_void)884a6d42e7dSPeter Dunlap iscsi_tgt_walk_cb(uintptr_t addr, const void *list_walker_data,
885a6d42e7dSPeter Dunlap     void *idc_void)
886a6d42e7dSPeter Dunlap {
887a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
888a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
889a6d42e7dSPeter Dunlap 	int			rc;
890a6d42e7dSPeter Dunlap 
891a6d42e7dSPeter Dunlap 	rc = iscsi_tgt_impl(addr, idc);
892a6d42e7dSPeter Dunlap 
893a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
894a6d42e7dSPeter Dunlap }
895a6d42e7dSPeter Dunlap 
896a6d42e7dSPeter Dunlap /*ARGSUSED*/
897a6d42e7dSPeter Dunlap static int
iscsi_tpgt_walk_cb(uintptr_t addr,const void * list_walker_data,void * idc_void)898a6d42e7dSPeter Dunlap iscsi_tpgt_walk_cb(uintptr_t addr, const void *list_walker_data,
899a6d42e7dSPeter Dunlap     void *idc_void)
900a6d42e7dSPeter Dunlap {
901a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
902a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
903a6d42e7dSPeter Dunlap 	int			rc;
904a6d42e7dSPeter Dunlap 
905a6d42e7dSPeter Dunlap 	rc = iscsi_tpgt_impl(addr, idc);
906a6d42e7dSPeter Dunlap 
907a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
908a6d42e7dSPeter Dunlap }
909a6d42e7dSPeter Dunlap 
910a6d42e7dSPeter Dunlap /*ARGSUSED*/
911a6d42e7dSPeter Dunlap static int
iscsi_portal_walk_cb(uintptr_t addr,const void * list_walker_data,void * idc_void)912a6d42e7dSPeter Dunlap iscsi_portal_walk_cb(uintptr_t addr, const void *list_walker_data,
913a6d42e7dSPeter Dunlap     void *idc_void)
914a6d42e7dSPeter Dunlap {
915a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
916a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
917a6d42e7dSPeter Dunlap 	int			rc;
918a6d42e7dSPeter Dunlap 
919a6d42e7dSPeter Dunlap 	rc = iscsi_portal_impl(addr, idc);
920a6d42e7dSPeter Dunlap 
921a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
922a6d42e7dSPeter Dunlap }
923a6d42e7dSPeter Dunlap 
924a6d42e7dSPeter Dunlap /*ARGSUSED*/
925a6d42e7dSPeter Dunlap static int
iscsi_sess_walk_cb(uintptr_t addr,const void * list_walker_data,void * idc_void)926a6d42e7dSPeter Dunlap iscsi_sess_walk_cb(uintptr_t addr, const void *list_walker_data,
927a6d42e7dSPeter Dunlap     void *idc_void)
928a6d42e7dSPeter Dunlap {
929a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
930a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
931a6d42e7dSPeter Dunlap 	int			rc;
932a6d42e7dSPeter Dunlap 
933a6d42e7dSPeter Dunlap 	rc = iscsi_sess_impl(addr, idc);
934a6d42e7dSPeter Dunlap 
935a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
936a6d42e7dSPeter Dunlap }
937a6d42e7dSPeter Dunlap 
938a6d42e7dSPeter Dunlap /*ARGSUSED*/
939a6d42e7dSPeter Dunlap static int
iscsi_sess_conn_walk_cb(uintptr_t addr,const void * list_walker_data,void * idc_void)940a6d42e7dSPeter Dunlap iscsi_sess_conn_walk_cb(uintptr_t addr, const void *list_walker_data,
941a6d42e7dSPeter Dunlap     void *idc_void)
942a6d42e7dSPeter Dunlap {
943a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
944a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
945a6d42e7dSPeter Dunlap 	iscsit_conn_t		ict;
946a6d42e7dSPeter Dunlap 	int			rc;
947a6d42e7dSPeter Dunlap 
948a6d42e7dSPeter Dunlap 	/*
949a6d42e7dSPeter Dunlap 	 * This function is different from iscsi_conn_walk_cb because
950a6d42e7dSPeter Dunlap 	 * we get an iscsit_conn_t instead of an idm_conn_t
951a6d42e7dSPeter Dunlap 	 *
952a6d42e7dSPeter Dunlap 	 * Read iscsit_conn_t, use to get idm_conn_t pointer
953a6d42e7dSPeter Dunlap 	 */
954a6d42e7dSPeter Dunlap 	if (mdb_vread(&ict, sizeof (iscsit_conn_t), addr) !=
955a6d42e7dSPeter Dunlap 	    sizeof (iscsit_conn_t)) {
956a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
957a6d42e7dSPeter Dunlap 	}
958a6d42e7dSPeter Dunlap 	rc = iscsi_conn_impl((uintptr_t)ict.ict_ic, idc);
959a6d42e7dSPeter Dunlap 
960a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
961a6d42e7dSPeter Dunlap }
962a6d42e7dSPeter Dunlap 
963a6d42e7dSPeter Dunlap /*ARGSUSED*/
964a6d42e7dSPeter Dunlap static int
iscsi_conn_walk_cb(uintptr_t addr,const void * list_walker_data,void * idc_void)965a6d42e7dSPeter Dunlap iscsi_conn_walk_cb(uintptr_t addr, const void *list_walker_data,
966a6d42e7dSPeter Dunlap     void *idc_void)
967a6d42e7dSPeter Dunlap {
968a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
969a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
970a6d42e7dSPeter Dunlap 	int			rc;
971a6d42e7dSPeter Dunlap 
972a6d42e7dSPeter Dunlap 	rc = iscsi_conn_impl(addr, idc);
973a6d42e7dSPeter Dunlap 
974a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
975a6d42e7dSPeter Dunlap }
976a6d42e7dSPeter Dunlap 
977a6d42e7dSPeter Dunlap /*ARGSUSED*/
978a6d42e7dSPeter Dunlap static int
iscsi_buffer_walk_cb(uintptr_t addr,const void * list_walker_data,void * idc_void)979a6d42e7dSPeter Dunlap iscsi_buffer_walk_cb(uintptr_t addr, const void *list_walker_data,
980a6d42e7dSPeter Dunlap     void *idc_void)
981a6d42e7dSPeter Dunlap {
982a6d42e7dSPeter Dunlap 	/* We don't particularly care about the list walker data */
983a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = idc_void;
984a6d42e7dSPeter Dunlap 	int			rc;
985a6d42e7dSPeter Dunlap 
986a6d42e7dSPeter Dunlap 	rc = iscsi_buffer_impl(addr, idc);
987a6d42e7dSPeter Dunlap 
988a6d42e7dSPeter Dunlap 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
989a6d42e7dSPeter Dunlap }
990a6d42e7dSPeter Dunlap 
9915819f75eSPeter Gill /*ARGSUSED*/
9925819f75eSPeter Gill static int
iscsi_svc_walk_cb(uintptr_t addr,const void * list_walker_data,void * idc_void)9935819f75eSPeter Gill iscsi_svc_walk_cb(uintptr_t addr, const void *list_walker_data,
9945819f75eSPeter Gill     void *idc_void)
9955819f75eSPeter Gill {
9965819f75eSPeter Gill 	iscsi_dcmd_ctrl_t	*idc = idc_void;
9975819f75eSPeter Gill 	int			rc;
9985819f75eSPeter Gill 
9995819f75eSPeter Gill 	rc = iscsi_svc_impl(addr, idc);
10005819f75eSPeter Gill 
10015819f75eSPeter Gill 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
10025819f75eSPeter Gill }
10035819f75eSPeter Gill 
10045819f75eSPeter Gill /*ARGSUSED*/
10055819f75eSPeter Gill static int
iscsi_ini_hba_walk_cb(uintptr_t addr,const void * vhba,void * idc_void)10065819f75eSPeter Gill iscsi_ini_hba_walk_cb(uintptr_t addr, const void *vhba,
10075819f75eSPeter Gill     void *idc_void) {
10085819f75eSPeter Gill 
10095819f75eSPeter Gill 	iscsi_dcmd_ctrl_t	*idc = idc_void;
10105819f75eSPeter Gill 	int			rc;
10115819f75eSPeter Gill 
10125819f75eSPeter Gill 	rc = iscsi_ini_hba_impl(addr, idc);
10135819f75eSPeter Gill 
10145819f75eSPeter Gill 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
10155819f75eSPeter Gill }
10165819f75eSPeter Gill 
10175819f75eSPeter Gill static int
iscsi_ini_sess_walk_cb(uintptr_t addr,const void * vsess,void * idc_void)10185819f75eSPeter Gill iscsi_ini_sess_walk_cb(uintptr_t addr, const void *vsess, void *idc_void)
10195819f75eSPeter Gill {
10205819f75eSPeter Gill 	int rc;
10215819f75eSPeter Gill 
10225819f75eSPeter Gill 	if (vsess == NULL) {
10235819f75eSPeter Gill 		return (WALK_ERR);
10245819f75eSPeter Gill 	}
10255819f75eSPeter Gill 
10265819f75eSPeter Gill 	rc = iscsi_print_ini_sess(addr, (iscsi_sess_t *)vsess,
10275819f75eSPeter Gill 	    (iscsi_dcmd_ctrl_t *)idc_void);
10285819f75eSPeter Gill 
10295819f75eSPeter Gill 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
10305819f75eSPeter Gill }
10315819f75eSPeter Gill 
10325819f75eSPeter Gill /*ARGSUSED*/
10335819f75eSPeter Gill static int
iscsi_ini_conn_walk_cb(uintptr_t addr,const void * vconn,void * idc_void)10345819f75eSPeter Gill iscsi_ini_conn_walk_cb(uintptr_t addr, const void *vconn, void *idc_void)
10355819f75eSPeter Gill {
10365819f75eSPeter Gill 	const iscsi_conn_t	*ict = vconn;
10375819f75eSPeter Gill 	int			rc;
10385819f75eSPeter Gill 
10395819f75eSPeter Gill 	if (vconn == NULL) {
10405819f75eSPeter Gill 		return (WALK_ERR);
10415819f75eSPeter Gill 	}
10425819f75eSPeter Gill 
10435819f75eSPeter Gill 	/*
10445819f75eSPeter Gill 	 * Look up the idm_conn_t in the iscsi_conn_t and call the general
10455819f75eSPeter Gill 	 * connection handler.
10465819f75eSPeter Gill 	 */
10475819f75eSPeter Gill 	rc = iscsi_conn_impl((uintptr_t)ict->conn_ic,
10485819f75eSPeter Gill 	    (iscsi_dcmd_ctrl_t *)idc_void);
10495819f75eSPeter Gill 
10505819f75eSPeter Gill 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
10515819f75eSPeter Gill }
10525819f75eSPeter Gill 
10535819f75eSPeter Gill static int
iscsi_ini_lun_walk_cb(uintptr_t addr,const void * vlun,void * idc_void)10545819f75eSPeter Gill iscsi_ini_lun_walk_cb(uintptr_t addr, const void *vlun, void *idc_void)
10555819f75eSPeter Gill {
10565819f75eSPeter Gill 	int			rc;
10575819f75eSPeter Gill 
10585819f75eSPeter Gill 	if (vlun == NULL) {
10595819f75eSPeter Gill 		return (WALK_ERR);
10605819f75eSPeter Gill 	}
10615819f75eSPeter Gill 
10625819f75eSPeter Gill 	rc = iscsi_print_ini_lun(addr, (iscsi_lun_t *)vlun,
10635819f75eSPeter Gill 	    (iscsi_dcmd_ctrl_t *)idc_void);
10645819f75eSPeter Gill 
10655819f75eSPeter Gill 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
10665819f75eSPeter Gill }
10675819f75eSPeter Gill 
10685819f75eSPeter Gill 
1069a6d42e7dSPeter Dunlap static int
iscsi_tgt_impl(uintptr_t addr,iscsi_dcmd_ctrl_t * idc)1070a6d42e7dSPeter Dunlap iscsi_tgt_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
1071a6d42e7dSPeter Dunlap {
1072a6d42e7dSPeter Dunlap 	iscsit_tgt_t	tgt;
1073a6d42e7dSPeter Dunlap 	uintptr_t	avl_addr, rc_addr, states_addr;
1074a6d42e7dSPeter Dunlap 	char		tgt_name[MAX_ISCSI_NODENAMELEN];
1075a6d42e7dSPeter Dunlap 	int		verbose, states, rc_audit;
1076a6d42e7dSPeter Dunlap 
1077a6d42e7dSPeter Dunlap 	/*
1078a6d42e7dSPeter Dunlap 	 * Read iscsit_tgt_t
1079a6d42e7dSPeter Dunlap 	 */
1080a6d42e7dSPeter Dunlap 	if (mdb_vread(&tgt, sizeof (iscsit_tgt_t), addr) !=
1081a6d42e7dSPeter Dunlap 	    sizeof (iscsit_tgt_t)) {
1082a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1083a6d42e7dSPeter Dunlap 	}
1084a6d42e7dSPeter Dunlap 
1085a6d42e7dSPeter Dunlap 	/*
1086a6d42e7dSPeter Dunlap 	 * Read target name if available
1087a6d42e7dSPeter Dunlap 	 */
1088a6d42e7dSPeter Dunlap 	if ((tgt.target_name == NULL) ||
1089a6d42e7dSPeter Dunlap 	    (mdb_readstr(tgt_name, sizeof (tgt_name),
1090a6d42e7dSPeter Dunlap 	    (uintptr_t)tgt.target_name) == -1)) {
1091a6d42e7dSPeter Dunlap 		strcpy(tgt_name, "N/A");
1092a6d42e7dSPeter Dunlap 	}
1093a6d42e7dSPeter Dunlap 
1094a6d42e7dSPeter Dunlap 	/*
1095a6d42e7dSPeter Dunlap 	 * Brief output
1096a6d42e7dSPeter Dunlap 	 *
1097a6d42e7dSPeter Dunlap 	 * iscsit_tgt_t pointer
1098a6d42e7dSPeter Dunlap 	 * iscsit_tgt_t.target_stmf_state
1099a6d42e7dSPeter Dunlap 	 * iscsit_tgt_t.target_sess_list.avl_numnodes (session count)
1100a6d42e7dSPeter Dunlap 	 * iscsit_tgt_t.target_name;
1101a6d42e7dSPeter Dunlap 	 */
1102a6d42e7dSPeter Dunlap 
1103a6d42e7dSPeter Dunlap 	verbose = idc->idc_verbose;
1104a6d42e7dSPeter Dunlap 	states = idc->u.child.idc_states;
1105a6d42e7dSPeter Dunlap 	rc_audit = idc->u.child.idc_rc_audit;
1106a6d42e7dSPeter Dunlap 
1107a6d42e7dSPeter Dunlap 	/* For now we will ignore the verbose flag */
1108a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_tgt) {
1109a6d42e7dSPeter Dunlap 		/* Print target data */
1110a6d42e7dSPeter Dunlap 		if (idc->idc_header) {
1111a6d42e7dSPeter Dunlap 			mdb_printf("%<u>%-19s %-4s  %-8s%</u>\n",
1112a6d42e7dSPeter Dunlap 			    "iscsit_tgt_t", "Sess", "State");
1113a6d42e7dSPeter Dunlap 		}
1114a6d42e7dSPeter Dunlap 		mdb_printf("%-19p %-4d %-8d\n", addr,
1115a6d42e7dSPeter Dunlap 		    tgt.target_sess_list.avl_numnodes,
1116a6d42e7dSPeter Dunlap 		    tgt.target_state);
1117a6d42e7dSPeter Dunlap 		mdb_printf("  %s\n", tgt_name);
1118a6d42e7dSPeter Dunlap 
11195819f75eSPeter Gill 		/* Indent and disable verbose for any child structures */
11205819f75eSPeter Gill 		mdb_inc_indent(4);
1121a6d42e7dSPeter Dunlap 		idc->idc_verbose = 0;
11225819f75eSPeter Gill 	}
1123a6d42e7dSPeter Dunlap 
1124a6d42e7dSPeter Dunlap 	/*
1125a6d42e7dSPeter Dunlap 	 * Print states if requested
1126a6d42e7dSPeter Dunlap 	 */
1127a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_tgt && states) {
1128a6d42e7dSPeter Dunlap 		states_addr = addr + offsetof(iscsit_tgt_t, target_state_audit);
1129a6d42e7dSPeter Dunlap 
11305819f75eSPeter Gill 		mdb_printf("State History(target_state_audit):\n");
1131a6d42e7dSPeter Dunlap 		if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
1132a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1133a6d42e7dSPeter Dunlap 		idc->u.child.idc_states = 0;
1134a6d42e7dSPeter Dunlap 	}
1135a6d42e7dSPeter Dunlap 
1136a6d42e7dSPeter Dunlap 	/*
1137a6d42e7dSPeter Dunlap 	 * Print refcnt audit data if requested
1138a6d42e7dSPeter Dunlap 	 */
1139a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_tgt && rc_audit) {
11405819f75eSPeter Gill 		mdb_printf("Reference History(target_sess_refcnt):\n");
1141a6d42e7dSPeter Dunlap 		rc_addr = addr +
1142a6d42e7dSPeter Dunlap 		    offsetof(iscsit_tgt_t, target_sess_refcnt);
1143a6d42e7dSPeter Dunlap 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
1144a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1145a6d42e7dSPeter Dunlap 
11465819f75eSPeter Gill 		mdb_printf("Reference History(target_refcnt):\n");
1147a6d42e7dSPeter Dunlap 		rc_addr = addr +
1148a6d42e7dSPeter Dunlap 		    offsetof(iscsit_tgt_t, target_refcnt);
1149a6d42e7dSPeter Dunlap 
1150a6d42e7dSPeter Dunlap 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
1151a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1152a6d42e7dSPeter Dunlap 		idc->u.child.idc_rc_audit = 0;
1153a6d42e7dSPeter Dunlap 	}
1154a6d42e7dSPeter Dunlap 
1155a6d42e7dSPeter Dunlap 	/* Any child objects to walk? */
11565819f75eSPeter Gill 	if (idc->u.child.idc_tpgt || idc->u.child.idc_portal) {
11575819f75eSPeter Gill 
11585819f75eSPeter Gill 		if (idc->u.child.idc_tgt) {
1159a6d42e7dSPeter Dunlap 			idc->idc_header = 1;
11605819f75eSPeter Gill 		}
11615819f75eSPeter Gill 
11625819f75eSPeter Gill 		/* Walk TPGT tree */
1163a6d42e7dSPeter Dunlap 		avl_addr = addr +
1164a6d42e7dSPeter Dunlap 		    offsetof(iscsit_tgt_t, target_tpgt_list);
1165a6d42e7dSPeter Dunlap 		if (mdb_pwalk("avl", iscsi_tpgt_walk_cb, idc,
1166a6d42e7dSPeter Dunlap 		    avl_addr) == -1) {
1167a6d42e7dSPeter Dunlap 			mdb_warn("target tpgt list walk failed");
1168a6d42e7dSPeter Dunlap 			(void) mdb_dec_indent(4);
1169a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1170a6d42e7dSPeter Dunlap 		}
11715819f75eSPeter Gill 	}
11725819f75eSPeter Gill 
11735819f75eSPeter Gill 	if (idc->u.child.idc_sess || idc->u.child.idc_conn ||
11745819f75eSPeter Gill 	    idc->u.child.idc_task || idc->u.child.idc_buffer) {
11755819f75eSPeter Gill 
11765819f75eSPeter Gill 		if (idc->u.child.idc_tgt || idc->u.child.idc_tpgt ||
11775819f75eSPeter Gill 		    idc->u.child.idc_portal) {
11785819f75eSPeter Gill 			idc->idc_header = 1;
11795819f75eSPeter Gill 		}
1180a6d42e7dSPeter Dunlap 
1181a6d42e7dSPeter Dunlap 		/* Walk sess tree */
1182a6d42e7dSPeter Dunlap 		avl_addr = addr + offsetof(iscsit_tgt_t, target_sess_list);
1183a6d42e7dSPeter Dunlap 		if (mdb_pwalk("avl", iscsi_sess_walk_cb, idc,
1184a6d42e7dSPeter Dunlap 		    avl_addr) == -1) {
1185a6d42e7dSPeter Dunlap 			mdb_warn("target sess list walk failed");
1186a6d42e7dSPeter Dunlap 			(void) mdb_dec_indent(4);
1187a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1188a6d42e7dSPeter Dunlap 		}
11895819f75eSPeter Gill 	}
1190a6d42e7dSPeter Dunlap 
11915819f75eSPeter Gill 	/* If tgts were handled decrease indent and reset header */
11925819f75eSPeter Gill 	if (idc->u.child.idc_tgt) {
1193a6d42e7dSPeter Dunlap 		idc->idc_header = 0;
11945819f75eSPeter Gill 		mdb_dec_indent(4);
1195a6d42e7dSPeter Dunlap 	}
1196a6d42e7dSPeter Dunlap 
1197a6d42e7dSPeter Dunlap 	idc->idc_verbose = verbose;
1198a6d42e7dSPeter Dunlap 	idc->u.child.idc_states = states;
1199a6d42e7dSPeter Dunlap 	idc->u.child.idc_rc_audit = rc_audit;
1200a6d42e7dSPeter Dunlap 	return (DCMD_OK);
1201a6d42e7dSPeter Dunlap }
1202a6d42e7dSPeter Dunlap 
1203a6d42e7dSPeter Dunlap static int
iscsi_tpgt_impl(uintptr_t addr,iscsi_dcmd_ctrl_t * idc)1204a6d42e7dSPeter Dunlap iscsi_tpgt_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
1205a6d42e7dSPeter Dunlap {
1206a6d42e7dSPeter Dunlap 	iscsit_tpgt_t	tpgt;
1207a6d42e7dSPeter Dunlap 	iscsit_tpg_t	tpg;
12085819f75eSPeter Gill 	uintptr_t	avl_addr, tpg_addr, rc_addr;
12095819f75eSPeter Gill 	int		rc_audit;
1210a6d42e7dSPeter Dunlap 
1211a6d42e7dSPeter Dunlap 	/*
1212a6d42e7dSPeter Dunlap 	 * Read iscsit_tpgt_t
1213a6d42e7dSPeter Dunlap 	 */
1214a6d42e7dSPeter Dunlap 	if (mdb_vread(&tpgt, sizeof (iscsit_tpgt_t), addr) !=
1215a6d42e7dSPeter Dunlap 	    sizeof (iscsit_tpgt_t)) {
1216a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1217a6d42e7dSPeter Dunlap 	}
1218a6d42e7dSPeter Dunlap 
1219a6d42e7dSPeter Dunlap 	tpg_addr = (uintptr_t)tpgt.tpgt_tpg;
1220a6d42e7dSPeter Dunlap 
1221a6d42e7dSPeter Dunlap 	/*
1222a6d42e7dSPeter Dunlap 	 * Read iscsit_tpg_t
1223a6d42e7dSPeter Dunlap 	 */
1224a6d42e7dSPeter Dunlap 	if (mdb_vread(&tpg, sizeof (iscsit_tpg_t), tpg_addr) !=
1225a6d42e7dSPeter Dunlap 	    sizeof (iscsit_tpg_t)) {
1226a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1227a6d42e7dSPeter Dunlap 	}
1228a6d42e7dSPeter Dunlap 
12295819f75eSPeter Gill 	rc_audit = idc->u.child.idc_rc_audit;
12305819f75eSPeter Gill 
1231a6d42e7dSPeter Dunlap 	/*
1232a6d42e7dSPeter Dunlap 	 * Brief output
1233a6d42e7dSPeter Dunlap 	 *
1234a6d42e7dSPeter Dunlap 	 * iscsit_tpgt_t pointer
1235a6d42e7dSPeter Dunlap 	 * iscsit_tpg_t pointer
1236a6d42e7dSPeter Dunlap 	 * iscsit_tpg_t.tpg_name
1237a6d42e7dSPeter Dunlap 	 * iscsit_tpgt_t.tpgt_tag;
1238a6d42e7dSPeter Dunlap 	 */
1239a6d42e7dSPeter Dunlap 
1240a6d42e7dSPeter Dunlap 	/* For now we will ignore the verbose flag */
1241a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_tpgt) {
1242a6d42e7dSPeter Dunlap 		/* Print target data */
1243a6d42e7dSPeter Dunlap 		if (idc->idc_header) {
1244a6d42e7dSPeter Dunlap 			mdb_printf("%<u>%-?s %-?s %-18s %-6s%</u>\n",
1245a6d42e7dSPeter Dunlap 			    "iscsit_tpgt_t", "iscsit_tpg_t", "Name", "Tag");
1246a6d42e7dSPeter Dunlap 		}
1247a6d42e7dSPeter Dunlap 		mdb_printf("%?p %?p %-18s 0x%04x\n", addr, tpgt.tpgt_tpg,
1248a6d42e7dSPeter Dunlap 		    tpg.tpg_name, tpgt.tpgt_tag);
12495819f75eSPeter Gill 
12505819f75eSPeter Gill 		if (rc_audit) {
12515819f75eSPeter Gill 			(void) mdb_inc_indent(4);
12525819f75eSPeter Gill 
12535819f75eSPeter Gill 			mdb_printf("Reference History(tpgt_refcnt):\n");
12545819f75eSPeter Gill 			rc_addr = addr + offsetof(iscsit_tpgt_t, tpgt_refcnt);
12555819f75eSPeter Gill 			if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
12565819f75eSPeter Gill 				return (DCMD_ERR);
12575819f75eSPeter Gill 
12585819f75eSPeter Gill 			idc->u.child.idc_rc_audit = 0;
12595819f75eSPeter Gill 			(void) mdb_dec_indent(4);
12605819f75eSPeter Gill 		}
1261a6d42e7dSPeter Dunlap 	}
1262a6d42e7dSPeter Dunlap 
1263a6d42e7dSPeter Dunlap 	/*
1264a6d42e7dSPeter Dunlap 	 * Assume for now that anyone interested in TPGT wants to see the
12655819f75eSPeter Gill 	 * portals as well. Enable idc_header for the portals.
1266a6d42e7dSPeter Dunlap 	 */
1267a6d42e7dSPeter Dunlap 	idc->idc_header = 1;
1268a6d42e7dSPeter Dunlap 	(void) mdb_inc_indent(4);
1269a6d42e7dSPeter Dunlap 	avl_addr = tpg_addr + offsetof(iscsit_tpg_t, tpg_portal_list);
1270a6d42e7dSPeter Dunlap 	if (mdb_pwalk("avl", iscsi_portal_walk_cb, idc, avl_addr) == -1) {
1271a6d42e7dSPeter Dunlap 		mdb_warn("portal list walk failed");
1272a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
1273a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1274a6d42e7dSPeter Dunlap 	}
1275a6d42e7dSPeter Dunlap 	(void) mdb_dec_indent(4);
1276a6d42e7dSPeter Dunlap 	idc->idc_header = 0;
1277a6d42e7dSPeter Dunlap 
12785819f75eSPeter Gill 	idc->u.child.idc_rc_audit = rc_audit;
1279a6d42e7dSPeter Dunlap 	return (DCMD_OK);
1280a6d42e7dSPeter Dunlap }
1281a6d42e7dSPeter Dunlap 
1282a6d42e7dSPeter Dunlap static int
iscsi_tpg_impl(uintptr_t addr,iscsi_dcmd_ctrl_t * idc)1283a6d42e7dSPeter Dunlap iscsi_tpg_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
1284a6d42e7dSPeter Dunlap {
1285a6d42e7dSPeter Dunlap 	iscsit_tpg_t	tpg;
12865819f75eSPeter Gill 	uintptr_t	avl_addr, rc_addr;
12875819f75eSPeter Gill 	int		rc_audit = 0;
12885819f75eSPeter Gill 
12895819f75eSPeter Gill 	rc_audit = idc->u.child.idc_rc_audit;
1290a6d42e7dSPeter Dunlap 
1291a6d42e7dSPeter Dunlap 	/*
1292a6d42e7dSPeter Dunlap 	 * Read iscsit_tpg_t
1293a6d42e7dSPeter Dunlap 	 */
1294a6d42e7dSPeter Dunlap 	if (mdb_vread(&tpg, sizeof (iscsit_tpg_t), addr) !=
1295a6d42e7dSPeter Dunlap 	    sizeof (iscsit_tpg_t)) {
1296a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1297a6d42e7dSPeter Dunlap 	}
1298a6d42e7dSPeter Dunlap 
1299a6d42e7dSPeter Dunlap 	/*
1300a6d42e7dSPeter Dunlap 	 * Brief output
1301a6d42e7dSPeter Dunlap 	 *
1302a6d42e7dSPeter Dunlap 	 * iscsit_tpgt_t pointer
1303a6d42e7dSPeter Dunlap 	 * iscsit_tpg_t pointer
1304a6d42e7dSPeter Dunlap 	 * iscsit_tpg_t.tpg_name
1305a6d42e7dSPeter Dunlap 	 * iscsit_tpgt_t.tpgt_tag;
1306a6d42e7dSPeter Dunlap 	 */
1307a6d42e7dSPeter Dunlap 
13085819f75eSPeter Gill 	/* Print tpg data */
13095819f75eSPeter Gill 	if (idc->u.child.idc_tpg) {
1310a6d42e7dSPeter Dunlap 		if (idc->idc_header) {
1311a6d42e7dSPeter Dunlap 			mdb_printf("%<u>%-?s %-18s%</u>\n",
1312a6d42e7dSPeter Dunlap 			    "iscsit_tpg_t", "Name");
1313a6d42e7dSPeter Dunlap 		}
1314a6d42e7dSPeter Dunlap 		mdb_printf("%?p %-18s\n", addr, tpg.tpg_name);
1315a6d42e7dSPeter Dunlap 
1316a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(4);
13175819f75eSPeter Gill 
13185819f75eSPeter Gill 		if (rc_audit) {
13195819f75eSPeter Gill 			mdb_printf("Reference History(tpg_refcnt):\n");
13205819f75eSPeter Gill 			rc_addr = addr + offsetof(iscsit_tpg_t, tpg_refcnt);
13215819f75eSPeter Gill 			if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
1322a6d42e7dSPeter Dunlap 				return (DCMD_ERR);
1323a6d42e7dSPeter Dunlap 			}
13245819f75eSPeter Gill 			idc->u.child.idc_rc_audit = 0;
13255819f75eSPeter Gill 		}
13265819f75eSPeter Gill 	}
13275819f75eSPeter Gill 
13285819f75eSPeter Gill 	if (idc->u.child.idc_portal) {
13295819f75eSPeter Gill 		if (idc->u.child.idc_tpg) {
13305819f75eSPeter Gill 			idc->idc_header = 1;
13315819f75eSPeter Gill 		}
13325819f75eSPeter Gill 
13335819f75eSPeter Gill 		avl_addr = addr + offsetof(iscsit_tpg_t, tpg_portal_list);
13345819f75eSPeter Gill 		if (mdb_pwalk("avl", iscsi_portal_walk_cb, idc,
13355819f75eSPeter Gill 		    avl_addr) == -1) {
13365819f75eSPeter Gill 			mdb_warn("portal list walk failed");
13375819f75eSPeter Gill 			if (idc->u.child.idc_tpg) {
13385819f75eSPeter Gill 				(void) mdb_dec_indent(4);
13395819f75eSPeter Gill 			}
13405819f75eSPeter Gill 			return (DCMD_ERR);
13415819f75eSPeter Gill 		}
13425819f75eSPeter Gill 	}
13435819f75eSPeter Gill 
13445819f75eSPeter Gill 	if (idc->u.child.idc_tpg) {
1345a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
1346a6d42e7dSPeter Dunlap 		idc->idc_header = 0;
13475819f75eSPeter Gill 	}
1348a6d42e7dSPeter Dunlap 
13495819f75eSPeter Gill 	idc->u.child.idc_rc_audit = rc_audit;
1350a6d42e7dSPeter Dunlap 	return (DCMD_OK);
1351a6d42e7dSPeter Dunlap }
1352a6d42e7dSPeter Dunlap 
1353a6d42e7dSPeter Dunlap static int
iscsi_portal_impl(uintptr_t addr,iscsi_dcmd_ctrl_t * idc)1354a6d42e7dSPeter Dunlap iscsi_portal_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
1355a6d42e7dSPeter Dunlap {
1356a6d42e7dSPeter Dunlap 	iscsit_portal_t	portal;
1357a6d42e7dSPeter Dunlap 	char		portal_addr[PORTAL_STR_LEN];
13585819f75eSPeter Gill 	uintptr_t	rc_addr;
13595819f75eSPeter Gill 
1360a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_portal) {
1361a6d42e7dSPeter Dunlap 		/*
1362a6d42e7dSPeter Dunlap 		 * Read iscsit_portal_t
1363a6d42e7dSPeter Dunlap 		 */
1364a6d42e7dSPeter Dunlap 		if (mdb_vread(&portal, sizeof (iscsit_portal_t), addr) !=
1365a6d42e7dSPeter Dunlap 		    sizeof (iscsit_portal_t)) {
1366a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1367a6d42e7dSPeter Dunlap 		}
1368a6d42e7dSPeter Dunlap 
1369a6d42e7dSPeter Dunlap 		/* Print portal data */
1370a6d42e7dSPeter Dunlap 		if (idc->idc_header) {
1371a6d42e7dSPeter Dunlap 			mdb_printf("%<u>%-?s %-?s %-30s%</u>\n",
1372a6d42e7dSPeter Dunlap 			    "iscsit_portal_t", "idm_svc_t", "IP:Port");
13735819f75eSPeter Gill 			idc->idc_header = 0;
1374a6d42e7dSPeter Dunlap 		}
1375a6d42e7dSPeter Dunlap 		sa_to_str(&portal.portal_addr, portal_addr);
1376a6d42e7dSPeter Dunlap 		mdb_printf("%?p %?p %s\n", addr, portal.portal_svc,
13775819f75eSPeter Gill 		    portal.portal_default ? "(Default)" : portal_addr);
13785819f75eSPeter Gill 
13795819f75eSPeter Gill 		if (idc->u.child.idc_rc_audit) {
13805819f75eSPeter Gill 			(void) mdb_inc_indent(4);
13815819f75eSPeter Gill 			mdb_printf("Reference History(portal_refcnt):\n");
13825819f75eSPeter Gill 			rc_addr = addr + offsetof(iscsit_portal_t,
13835819f75eSPeter Gill 			    portal_refcnt);
13845819f75eSPeter Gill 			if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
13855819f75eSPeter Gill 				return (DCMD_ERR);
13865819f75eSPeter Gill 			}
13875819f75eSPeter Gill 			(void) mdb_dec_indent(4);
13885819f75eSPeter Gill 		}
1389a6d42e7dSPeter Dunlap 	}
1390a6d42e7dSPeter Dunlap 
1391a6d42e7dSPeter Dunlap 	return (DCMD_OK);
1392a6d42e7dSPeter Dunlap }
1393a6d42e7dSPeter Dunlap 
1394a6d42e7dSPeter Dunlap static int
iscsi_sess_impl(uintptr_t addr,iscsi_dcmd_ctrl_t * idc)1395a6d42e7dSPeter Dunlap iscsi_sess_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
1396a6d42e7dSPeter Dunlap {
1397a6d42e7dSPeter Dunlap 	iscsit_sess_t	ist;
13985819f75eSPeter Gill 	iscsi_sess_t	ini_sess;
1399a6d42e7dSPeter Dunlap 	uintptr_t	list_addr, states_addr, rc_addr;
1400a6d42e7dSPeter Dunlap 	char		ini_name[80];
1401a6d42e7dSPeter Dunlap 	char		tgt_name[80];
1402a6d42e7dSPeter Dunlap 	int		verbose, states, rc_audit;
1403a6d42e7dSPeter Dunlap 
14045819f75eSPeter Gill 	if (idc->idc_ini) {
14055819f75eSPeter Gill 		if ((mdb_vread(&ini_sess, sizeof (iscsi_sess_t),
14065819f75eSPeter Gill 		    (uintptr_t)addr)) != sizeof (iscsi_sess_t)) {
14075819f75eSPeter Gill 			mdb_warn("Failed to read initiator session\n");
14085819f75eSPeter Gill 			return (DCMD_ERR);
14095819f75eSPeter Gill 		}
14105819f75eSPeter Gill 		if (iscsi_print_ini_sess(addr, &ini_sess, idc) != DCMD_OK) {
14115819f75eSPeter Gill 			return (DCMD_ERR);
14125819f75eSPeter Gill 		}
14135819f75eSPeter Gill 		return (DCMD_OK);
14145819f75eSPeter Gill 	}
1415a6d42e7dSPeter Dunlap 	/*
1416a6d42e7dSPeter Dunlap 	 * Read iscsit_sess_t
1417a6d42e7dSPeter Dunlap 	 */
1418a6d42e7dSPeter Dunlap 	if (mdb_vread(&ist, sizeof (iscsit_sess_t), addr) !=
1419a6d42e7dSPeter Dunlap 	    sizeof (iscsit_sess_t)) {
1420a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1421a6d42e7dSPeter Dunlap 	}
1422a6d42e7dSPeter Dunlap 
1423a6d42e7dSPeter Dunlap 	/*
1424a6d42e7dSPeter Dunlap 	 * Brief output
1425a6d42e7dSPeter Dunlap 	 *
1426a6d42e7dSPeter Dunlap 	 * iscsit_sess_t pointer
1427a6d42e7dSPeter Dunlap 	 * iscsit_sess_t.ist_state/iscsit_sess_t.ist_ffp_conn_count
1428a6d42e7dSPeter Dunlap 	 * iscsit_sess_t.ist_tsih
1429a6d42e7dSPeter Dunlap 	 * iscsit_sess_t.ist_initiator_name
1430a6d42e7dSPeter Dunlap 	 */
1431a6d42e7dSPeter Dunlap 
1432a6d42e7dSPeter Dunlap 	verbose = idc->idc_verbose;
1433a6d42e7dSPeter Dunlap 	states = idc->u.child.idc_states;
1434a6d42e7dSPeter Dunlap 	rc_audit = idc->u.child.idc_rc_audit;
1435a6d42e7dSPeter Dunlap 
1436a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_sess) {
1437a6d42e7dSPeter Dunlap 		if (verbose) {
1438a6d42e7dSPeter Dunlap 			/*
1439a6d42e7dSPeter Dunlap 			 * Read initiator name if available
1440a6d42e7dSPeter Dunlap 			 */
1441a6d42e7dSPeter Dunlap 			if ((ist.ist_initiator_name == NULL) ||
1442a6d42e7dSPeter Dunlap 			    (mdb_readstr(ini_name, sizeof (ini_name),
1443a6d42e7dSPeter Dunlap 			    (uintptr_t)ist.ist_initiator_name) == -1)) {
1444a6d42e7dSPeter Dunlap 				strcpy(ini_name, "N/A");
1445a6d42e7dSPeter Dunlap 			}
1446a6d42e7dSPeter Dunlap 
1447a6d42e7dSPeter Dunlap 			/*
1448a6d42e7dSPeter Dunlap 			 * Read target name if available
1449a6d42e7dSPeter Dunlap 			 */
1450a6d42e7dSPeter Dunlap 			if ((ist.ist_target_name == NULL) ||
1451a6d42e7dSPeter Dunlap 			    (mdb_readstr(tgt_name, sizeof (tgt_name),
1452a6d42e7dSPeter Dunlap 			    (uintptr_t)ist.ist_target_name) == -1)) {
1453a6d42e7dSPeter Dunlap 				strcpy(tgt_name, "N/A");
1454a6d42e7dSPeter Dunlap 			}
1455a6d42e7dSPeter Dunlap 
1456a6d42e7dSPeter Dunlap 			mdb_printf("Session %p\n", addr);
1457a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %d\n", "State",
1458a6d42e7dSPeter Dunlap 			    ist.ist_state);
1459a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %d\n", "Last State",
1460a6d42e7dSPeter Dunlap 			    ist.ist_last_state);
1461a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %d\n", "FFP Connections",
1462a6d42e7dSPeter Dunlap 			    ist.ist_ffp_conn_count);
1463a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %02x%02x%02x%02x%02x%02x\n", "ISID",
1464a6d42e7dSPeter Dunlap 			    ist.ist_isid[0], ist.ist_isid[1], ist.ist_isid[2],
1465a6d42e7dSPeter Dunlap 			    ist.ist_isid[3], ist.ist_isid[4], ist.ist_isid[5]);
1466a6d42e7dSPeter Dunlap 			mdb_printf("%16s: 0x%04x\n", "TSIH",
1467a6d42e7dSPeter Dunlap 			    ist.ist_tsih);
1468a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %s\n", "Initiator IQN",
1469a6d42e7dSPeter Dunlap 			    ini_name);
1470a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %s\n", "Target IQN",
1471a6d42e7dSPeter Dunlap 			    tgt_name);
1472a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %08x\n", "ExpCmdSN",
1473a6d42e7dSPeter Dunlap 			    ist.ist_expcmdsn);
1474a6d42e7dSPeter Dunlap 			mdb_printf("%16s: %08x\n", "MaxCmdSN",
1475a6d42e7dSPeter Dunlap 			    ist.ist_maxcmdsn);
14765819f75eSPeter Gill 
14775819f75eSPeter Gill 			idc->idc_verbose = 0;
1478a6d42e7dSPeter Dunlap 		} else {
1479a6d42e7dSPeter Dunlap 			/* Print session data */
1480a6d42e7dSPeter Dunlap 			if (idc->idc_header) {
1481a6d42e7dSPeter Dunlap 				mdb_printf("%<u>%-?s %10s %-12s %-6s%</u>\n",
1482a6d42e7dSPeter Dunlap 				    "iscsit_sess_t", "State/Conn", "ISID",
1483a6d42e7dSPeter Dunlap 				    "TSIH");
1484a6d42e7dSPeter Dunlap 			}
1485a6d42e7dSPeter Dunlap 			mdb_printf("%?p  %4d/%-4d %02x%02x%02x%02x%02x%02x "
1486a6d42e7dSPeter Dunlap 			    "0x%04x\n", addr,
1487a6d42e7dSPeter Dunlap 			    ist.ist_state, ist.ist_ffp_conn_count,
1488a6d42e7dSPeter Dunlap 			    ist.ist_isid[0], ist.ist_isid[1], ist.ist_isid[2],
1489a6d42e7dSPeter Dunlap 			    ist.ist_isid[3], ist.ist_isid[4], ist.ist_isid[5],
1490a6d42e7dSPeter Dunlap 			    ist.ist_tsih);
1491a6d42e7dSPeter Dunlap 		}
1492a6d42e7dSPeter Dunlap 
14935819f75eSPeter Gill 		/*
14945819f75eSPeter Gill 		 * Indent for any child structures
14955819f75eSPeter Gill 		 */
14965819f75eSPeter Gill 		(void) mdb_inc_indent(4);
14975819f75eSPeter Gill 	}
1498a6d42e7dSPeter Dunlap 
1499a6d42e7dSPeter Dunlap 	/*
1500a6d42e7dSPeter Dunlap 	 * Print states if requested
1501a6d42e7dSPeter Dunlap 	 */
15025819f75eSPeter Gill 	if (idc->u.child.idc_sess && states) {
1503a6d42e7dSPeter Dunlap 		states_addr = addr + offsetof(iscsit_sess_t, ist_state_audit);
1504a6d42e7dSPeter Dunlap 
15055819f75eSPeter Gill 		mdb_printf("State History(ist_state_audit):\n");
1506a6d42e7dSPeter Dunlap 		if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
1507a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1508a6d42e7dSPeter Dunlap 
1509a6d42e7dSPeter Dunlap 		/* Don't print state history for child objects */
1510a6d42e7dSPeter Dunlap 		idc->u.child.idc_states = 0;
1511a6d42e7dSPeter Dunlap 	}
1512a6d42e7dSPeter Dunlap 
1513a6d42e7dSPeter Dunlap 	/*
1514a6d42e7dSPeter Dunlap 	 * Print refcnt audit data if requested
1515a6d42e7dSPeter Dunlap 	 */
15165819f75eSPeter Gill 	if (idc->u.child.idc_sess && rc_audit) {
15175819f75eSPeter Gill 		mdb_printf("Reference History(ist_refcnt):\n");
1518a6d42e7dSPeter Dunlap 		rc_addr = addr +
1519a6d42e7dSPeter Dunlap 		    offsetof(iscsit_sess_t, ist_refcnt);
1520a6d42e7dSPeter Dunlap 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
1521a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1522a6d42e7dSPeter Dunlap 
1523a6d42e7dSPeter Dunlap 		/* Don't print audit data for child objects */
1524a6d42e7dSPeter Dunlap 		idc->u.child.idc_rc_audit = 0;
1525a6d42e7dSPeter Dunlap 	}
1526a6d42e7dSPeter Dunlap 
1527a6d42e7dSPeter Dunlap 	/* Any child objects to walk? */
1528a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_conn || idc->u.child.idc_task ||
1529a6d42e7dSPeter Dunlap 	    idc->u.child.idc_buffer) {
15305819f75eSPeter Gill 		/*
15315819f75eSPeter Gill 		 * If a session has been printed enable headers for
15325819f75eSPeter Gill 		 * any child structs.
15335819f75eSPeter Gill 		 */
15345819f75eSPeter Gill 		if (idc->u.child.idc_sess) {
1535a6d42e7dSPeter Dunlap 			idc->idc_header = 1;
15365819f75eSPeter Gill 		}
15375819f75eSPeter Gill 
15385819f75eSPeter Gill 		/* Walk conn list */
1539a6d42e7dSPeter Dunlap 		list_addr = addr + offsetof(iscsit_sess_t, ist_conn_list);
1540a6d42e7dSPeter Dunlap 		if (mdb_pwalk("list", iscsi_sess_conn_walk_cb, idc,
1541a6d42e7dSPeter Dunlap 		    list_addr) == -1) {
1542a6d42e7dSPeter Dunlap 			mdb_warn("session conn list walk failed");
1543a6d42e7dSPeter Dunlap 			(void) mdb_dec_indent(4);
1544a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1545a6d42e7dSPeter Dunlap 		}
15465819f75eSPeter Gill 	}
15475819f75eSPeter Gill 
15485819f75eSPeter Gill 	/* If a session was handled decrease indent and reset header. */
15495819f75eSPeter Gill 	if (idc->u.child.idc_sess) {
1550a6d42e7dSPeter Dunlap 		idc->idc_header = 0;
15515819f75eSPeter Gill 		mdb_dec_indent(4);
1552a6d42e7dSPeter Dunlap 	}
1553a6d42e7dSPeter Dunlap 
1554a6d42e7dSPeter Dunlap 	idc->idc_verbose = verbose;
1555a6d42e7dSPeter Dunlap 	idc->u.child.idc_states = states;
1556a6d42e7dSPeter Dunlap 	idc->u.child.idc_rc_audit = rc_audit;
1557a6d42e7dSPeter Dunlap 
1558a6d42e7dSPeter Dunlap 	return (DCMD_OK);
1559a6d42e7dSPeter Dunlap }
1560a6d42e7dSPeter Dunlap 
1561a6d42e7dSPeter Dunlap static int
iscsi_print_ini_sess(uintptr_t addr,iscsi_sess_t * sess,iscsi_dcmd_ctrl_t * idc)15625819f75eSPeter Gill iscsi_print_ini_sess(uintptr_t addr, iscsi_sess_t *sess,
15635819f75eSPeter Gill     iscsi_dcmd_ctrl_t *idc)
15645819f75eSPeter Gill {
15655819f75eSPeter Gill 
15665819f75eSPeter Gill 	int verbose, states;
15675819f75eSPeter Gill 	uintptr_t states_addr;
15685819f75eSPeter Gill 
15695819f75eSPeter Gill 	verbose = idc->idc_verbose;
15705819f75eSPeter Gill 	states = idc->u.child.idc_states;
15715819f75eSPeter Gill 
15725819f75eSPeter Gill 
15735819f75eSPeter Gill 	if (idc->u.child.idc_sess) {
15745819f75eSPeter Gill 		if (!idc->idc_verbose) {
15755819f75eSPeter Gill 			if (idc->idc_header) {
15765819f75eSPeter Gill 				mdb_printf("%<u>%-?s %-4s  %-8s%</u>\n",
15775819f75eSPeter Gill 				    "iscsi_sess_t", "Type", "State");
15785819f75eSPeter Gill 			}
15795819f75eSPeter Gill 			mdb_printf("%-19p %-4d %-8d\n", addr,
15805819f75eSPeter Gill 			    sess->sess_type, sess->sess_state);
15815819f75eSPeter Gill 		} else {
15825819f75eSPeter Gill 			mdb_printf("Session %p\n", addr);
15835819f75eSPeter Gill 			mdb_printf("%22s: %d\n", "State",
15845819f75eSPeter Gill 			    sess->sess_state);
15855819f75eSPeter Gill 			mdb_printf("%22s: %d\n", "Last State",
15865819f75eSPeter Gill 			    sess->sess_prev_state);
15875819f75eSPeter Gill 			mdb_printf("%22s: %s\n", "Session Name",
15885819f75eSPeter Gill 			    sess->sess_name);
15895819f75eSPeter Gill 			mdb_printf("%22s: %s\n", "Alias",
15905819f75eSPeter Gill 			    sess->sess_alias);
15915819f75eSPeter Gill 			mdb_printf("%22s: %08x\n", "CmdSN",
15925819f75eSPeter Gill 			    sess->sess_cmdsn);
15935819f75eSPeter Gill 			mdb_printf("%22s: %08x\n", "ExpCmdSN",
15945819f75eSPeter Gill 			    sess->sess_expcmdsn);
15955819f75eSPeter Gill 			mdb_printf("%22s: %08x\n", "MaxCmdSN",
15965819f75eSPeter Gill 			    sess->sess_maxcmdsn);
15975819f75eSPeter Gill 			mdb_printf("%22s: %p\n", "Pending Queue Head",
15985819f75eSPeter Gill 			    sess->sess_queue_pending.head);
15995819f75eSPeter Gill 			mdb_printf("%22s: %p\n", "Completion Queue Head",
16005819f75eSPeter Gill 			    sess->sess_queue_completion.head);
16015819f75eSPeter Gill 			mdb_printf("%22s: %p\n", "Connnection List Head",
16025819f75eSPeter Gill 			    sess->sess_conn_list);
16035819f75eSPeter Gill 
16045819f75eSPeter Gill 			idc->idc_verbose = 0;
16055819f75eSPeter Gill 		}
16065819f75eSPeter Gill 
16075819f75eSPeter Gill 		/* Indent for any child structures */
16085819f75eSPeter Gill 		mdb_inc_indent(4);
16095819f75eSPeter Gill 
16105819f75eSPeter Gill 		if (idc->u.child.idc_states) {
16115819f75eSPeter Gill 			states_addr = (uintptr_t)addr +
16125819f75eSPeter Gill 			    offsetof(iscsi_sess_t, sess_state_audit);
16135819f75eSPeter Gill 
16145819f75eSPeter Gill 			mdb_printf("State History(sess_state_audit):\n");
16155819f75eSPeter Gill 			if (iscsi_sm_audit_impl(states_addr) != DCMD_OK) {
16165819f75eSPeter Gill 				(void) mdb_dec_indent(4);
16175819f75eSPeter Gill 				return (DCMD_ERR);
16185819f75eSPeter Gill 			}
16195819f75eSPeter Gill 			idc->u.child.idc_states = 0;
16205819f75eSPeter Gill 		}
16215819f75eSPeter Gill 	}
16225819f75eSPeter Gill 
16235819f75eSPeter Gill 	if (idc->u.child.idc_lun && sess->sess_lun_list) {
16245819f75eSPeter Gill 		if (idc->u.child.idc_sess) {
16255819f75eSPeter Gill 			idc->idc_header = 1;
16265819f75eSPeter Gill 		}
16275819f75eSPeter Gill 
16285819f75eSPeter Gill 		if (mdb_pwalk("iscsi_ini_lun", iscsi_ini_lun_walk_cb, idc,
16295819f75eSPeter Gill 		    (uintptr_t)sess->sess_lun_list) == -1) {
16305819f75eSPeter Gill 			mdb_warn("iscsi_ini_lun walk failed");
16315819f75eSPeter Gill 			(void) mdb_dec_indent(4);
16325819f75eSPeter Gill 			return (DCMD_ERR);
16335819f75eSPeter Gill 		}
16345819f75eSPeter Gill 	}
16355819f75eSPeter Gill 
16365819f75eSPeter Gill 
16375819f75eSPeter Gill 	/* If requested print the cmds in the session queue */
16385819f75eSPeter Gill 	if (idc->u.child.idc_cmd) {
16395819f75eSPeter Gill 
16405819f75eSPeter Gill 		/* If any other structs printed enable header */
16415819f75eSPeter Gill 		if (idc->u.child.idc_sess || idc->u.child.idc_lun) {
16425819f75eSPeter Gill 			idc->idc_header = 1;
16435819f75eSPeter Gill 		}
16445819f75eSPeter Gill 
16455819f75eSPeter Gill 		if (sess->sess_queue_pending.head) {
16465819f75eSPeter Gill 			if (mdb_pwalk("iscsi_ini_cmd", iscsi_ini_cmd_walk_cb,
16475819f75eSPeter Gill 			    idc, (uintptr_t)sess->sess_queue_pending.head)
16485819f75eSPeter Gill 			    == -1) {
16495819f75eSPeter Gill 				mdb_warn("list walk failed for iscsi cmds");
16505819f75eSPeter Gill 			}
16515819f75eSPeter Gill 		}
16525819f75eSPeter Gill 		if (sess->sess_queue_completion.head) {
16535819f75eSPeter Gill 			if (mdb_pwalk("iscsi_ini_cmd", iscsi_ini_cmd_walk_cb,
16545819f75eSPeter Gill 			    idc, (uintptr_t)sess->sess_queue_completion.head)
16555819f75eSPeter Gill 			    == -1) {
16565819f75eSPeter Gill 				mdb_warn("list walk failed for iscsi cmds");
16575819f75eSPeter Gill 			}
16585819f75eSPeter Gill 		}
16595819f75eSPeter Gill 	}
16605819f75eSPeter Gill 
16615819f75eSPeter Gill 	/* If connections or cmds requested walk the connections */
16625819f75eSPeter Gill 	if (idc->u.child.idc_conn || idc->u.child.idc_cmd) {
16635819f75eSPeter Gill 		/*
16645819f75eSPeter Gill 		 * If idc_conn is not set don't enable header or the
16655819f75eSPeter Gill 		 * commands may get extraneous headers.
16665819f75eSPeter Gill 		 */
16675819f75eSPeter Gill 		if (idc->u.child.idc_conn) {
16685819f75eSPeter Gill 			idc->idc_header = 1;
16695819f75eSPeter Gill 		}
16705819f75eSPeter Gill 		if (mdb_pwalk("iscsi_ini_conn", iscsi_ini_conn_walk_cb, idc,
16715819f75eSPeter Gill 		    (uintptr_t)sess->sess_conn_list) == -1) {
16725819f75eSPeter Gill 			mdb_warn("iscsi_ini_conn walk failed");
16735819f75eSPeter Gill 			return (DCMD_ERR);
16745819f75eSPeter Gill 		}
16755819f75eSPeter Gill 	}
16765819f75eSPeter Gill 
16775819f75eSPeter Gill 	/* If sessions were handled decrease indent and reset header */
16785819f75eSPeter Gill 	if (idc->u.child.idc_sess) {
16795819f75eSPeter Gill 		idc->idc_header = 0;
16805819f75eSPeter Gill 		mdb_dec_indent(4);
16815819f75eSPeter Gill 	}
16825819f75eSPeter Gill 
16835819f75eSPeter Gill 	idc->u.child.idc_states = states;
16845819f75eSPeter Gill 	idc->idc_verbose = verbose;
16855819f75eSPeter Gill 	return (DCMD_OK);
16865819f75eSPeter Gill }
16875819f75eSPeter Gill 
16885819f75eSPeter Gill 
16895819f75eSPeter Gill static int
iscsi_conn_impl(uintptr_t addr,iscsi_dcmd_ctrl_t * idc)1690a6d42e7dSPeter Dunlap iscsi_conn_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
1691a6d42e7dSPeter Dunlap {
1692a6d42e7dSPeter Dunlap 	uintptr_t	idm_global_addr, states_addr, rc_addr;
1693a6d42e7dSPeter Dunlap 	uintptr_t	task_addr, task_ptr;
1694a6d42e7dSPeter Dunlap 	GElf_Sym	sym;
1695a6d42e7dSPeter Dunlap 	idm_task_t	idt;
1696a6d42e7dSPeter Dunlap 	idm_conn_t	ic;
16975819f75eSPeter Gill 	iscsit_conn_t	ict;
16985819f75eSPeter Gill 	iscsi_conn_t	ini_conn;
1699a6d42e7dSPeter Dunlap 	char		*conn_type;
1700a6d42e7dSPeter Dunlap 	int		task_idx;
1701a6d42e7dSPeter Dunlap 	char		laddr[PORTAL_STR_LEN];
1702a6d42e7dSPeter Dunlap 	char		raddr[PORTAL_STR_LEN];
1703a6d42e7dSPeter Dunlap 	int		verbose, states, rc_audit;
1704a6d42e7dSPeter Dunlap 
1705a6d42e7dSPeter Dunlap 	/*
1706a6d42e7dSPeter Dunlap 	 * Get pointer to task table
1707a6d42e7dSPeter Dunlap 	 */
1708a6d42e7dSPeter Dunlap 
1709a6d42e7dSPeter Dunlap 	if (mdb_lookup_by_name("idm", &sym) == -1) {
1710a6d42e7dSPeter Dunlap 		mdb_warn("failed to find symbol 'idm'");
1711a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1712a6d42e7dSPeter Dunlap 	}
1713a6d42e7dSPeter Dunlap 
1714a6d42e7dSPeter Dunlap 	idm_global_addr = (uintptr_t)sym.st_value;
1715a6d42e7dSPeter Dunlap 
1716a6d42e7dSPeter Dunlap 	if (mdb_vread(&task_ptr, sizeof (uintptr_t),
1717a6d42e7dSPeter Dunlap 	    idm_global_addr + offsetof(idm_global_t, idm_taskid_table)) !=
1718a6d42e7dSPeter Dunlap 	    sizeof (uintptr_t)) {
1719a6d42e7dSPeter Dunlap 		mdb_warn("Failed to read address of task table");
1720a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1721a6d42e7dSPeter Dunlap 	}
1722a6d42e7dSPeter Dunlap 
1723a6d42e7dSPeter Dunlap 	/*
1724a6d42e7dSPeter Dunlap 	 * Read idm_conn_t
1725a6d42e7dSPeter Dunlap 	 */
1726a6d42e7dSPeter Dunlap 	if (mdb_vread(&ic, sizeof (idm_conn_t), addr) != sizeof (idm_conn_t)) {
1727a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
1728a6d42e7dSPeter Dunlap 	}
17295819f75eSPeter Gill 
17305819f75eSPeter Gill 	/*
17315819f75eSPeter Gill 	 * If filter bits are set to only print targets or only initiators
17325819f75eSPeter Gill 	 * skip entries of the other type.
17335819f75eSPeter Gill 	 */
17345819f75eSPeter Gill 	if (!(idc->idc_ini && idc->idc_tgt) &&
17355819f75eSPeter Gill 	    ((idc->idc_ini && (ic.ic_conn_type != CONN_TYPE_INI)) ||
17365819f75eSPeter Gill 	    (idc->idc_tgt && (ic.ic_conn_type != CONN_TYPE_TGT)))) {
17375819f75eSPeter Gill 		return (DCMD_OK);
17385819f75eSPeter Gill 	}
17395819f75eSPeter Gill 
17405819f75eSPeter Gill 
1741a6d42e7dSPeter Dunlap 	conn_type = (ic.ic_conn_type == CONN_TYPE_INI) ? "Ini" :
1742a6d42e7dSPeter Dunlap 	    (ic.ic_conn_type == CONN_TYPE_TGT) ? "Tgt" : "Unk";
1743a6d42e7dSPeter Dunlap 
1744a6d42e7dSPeter Dunlap 	/*
1745a6d42e7dSPeter Dunlap 	 * Brief output
1746a6d42e7dSPeter Dunlap 	 *
1747a6d42e7dSPeter Dunlap 	 * idm_conn_t pointer
1748a6d42e7dSPeter Dunlap 	 * idm_conn_t.ic_conn_type
1749a6d42e7dSPeter Dunlap 	 * idm_conn_t.ic_statet+idm_conn_t.ic_ffp
1750a6d42e7dSPeter Dunlap 	 */
1751a6d42e7dSPeter Dunlap 
1752a6d42e7dSPeter Dunlap 	verbose = idc->idc_verbose;
1753a6d42e7dSPeter Dunlap 	states = idc->u.child.idc_states;
1754a6d42e7dSPeter Dunlap 	rc_audit = idc->u.child.idc_rc_audit;
1755a6d42e7dSPeter Dunlap 
17565819f75eSPeter Gill 	/*
17575819f75eSPeter Gill 	 * If targets(-T) and/or initiators (-I) are specifically requested,
17585819f75eSPeter Gill 	 * fetch the iscsit_conn_t and/or iscsi_conn_t struct as a sanity
17595819f75eSPeter Gill 	 * check and for use below.
17605819f75eSPeter Gill 	 */
17615819f75eSPeter Gill 	if (idc->idc_tgt && IDM_CONN_ISTGT(&ic)) {
17625819f75eSPeter Gill 		if (mdb_vread(&ict, sizeof (iscsit_conn_t),
17635819f75eSPeter Gill 		    (uintptr_t)ic.ic_handle) !=
17645819f75eSPeter Gill 		    sizeof (iscsit_conn_t)) {
17655819f75eSPeter Gill 			mdb_printf("Failed to read target connection "
17665819f75eSPeter Gill 			    "handle data\n");
17675819f75eSPeter Gill 			return (DCMD_ERR);
17685819f75eSPeter Gill 		}
17695819f75eSPeter Gill 	}
17705819f75eSPeter Gill 
17715819f75eSPeter Gill 	if (idc->idc_ini && IDM_CONN_ISINI(&ic)) {
17725819f75eSPeter Gill 		if (mdb_vread(&ini_conn, sizeof (iscsi_conn_t),
17735819f75eSPeter Gill 		    (uintptr_t)ic.ic_handle) !=
17745819f75eSPeter Gill 		    sizeof (iscsi_conn_t)) {
17755819f75eSPeter Gill 			mdb_printf("Failed to read initiator "
17765819f75eSPeter Gill 			    "connection handle data\n");
17775819f75eSPeter Gill 			return (DCMD_ERR);
17785819f75eSPeter Gill 		}
17795819f75eSPeter Gill 	}
17805819f75eSPeter Gill 
1781a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_conn) {
1782a6d42e7dSPeter Dunlap 		if (idc->idc_verbose) {
1783a6d42e7dSPeter Dunlap 			mdb_printf("IDM Conn %p\n", addr);
1784a6d42e7dSPeter Dunlap 			if (ic.ic_conn_type == CONN_TYPE_TGT) {
1785a6d42e7dSPeter Dunlap 				iscsi_print_iscsit_conn_data(&ic);
1786a6d42e7dSPeter Dunlap 			} else {
17875819f75eSPeter Gill 				iscsi_print_ini_conn_data(&ic);
1788a6d42e7dSPeter Dunlap 			}
17895819f75eSPeter Gill 			idc->idc_verbose = 0;
1790a6d42e7dSPeter Dunlap 		} else {
1791a6d42e7dSPeter Dunlap 			/* Print connection data */
1792a6d42e7dSPeter Dunlap 			if (idc->idc_header) {
1793a6d42e7dSPeter Dunlap 				mdb_printf("%<u>%-?s %-6s %-10s %12s%</u>\n",
1794a6d42e7dSPeter Dunlap 				    "idm_conn_t", "Type", "Transport",
1795a6d42e7dSPeter Dunlap 				    "State/FFP");
1796a6d42e7dSPeter Dunlap 			}
1797a6d42e7dSPeter Dunlap 			mdb_printf("%?p %-6s %-10s %6d/%-6d\n", addr, conn_type,
1798a6d42e7dSPeter Dunlap 			    (ic.ic_transport_type ==
1799a6d42e7dSPeter Dunlap 			    IDM_TRANSPORT_TYPE_ISER) ? "ISER_IB" :
1800a6d42e7dSPeter Dunlap 			    (ic.ic_transport_type ==
1801a6d42e7dSPeter Dunlap 			    IDM_TRANSPORT_TYPE_SOCKETS) ? "SOCKETS" :
1802a6d42e7dSPeter Dunlap 			    "N/A",
1803a6d42e7dSPeter Dunlap 			    ic.ic_state, ic.ic_ffp);
1804a6d42e7dSPeter Dunlap 			if (idc->u.child.idc_print_ip) {
1805a6d42e7dSPeter Dunlap 				sa_to_str(&ic.ic_laddr, laddr);
1806a6d42e7dSPeter Dunlap 				sa_to_str(&ic.ic_raddr, raddr);
1807a6d42e7dSPeter Dunlap 				mdb_printf("  L%s  R%s\n",
1808a6d42e7dSPeter Dunlap 				    laddr, raddr);
1809a6d42e7dSPeter Dunlap 			}
1810a6d42e7dSPeter Dunlap 		}
1811a6d42e7dSPeter Dunlap 
18125819f75eSPeter Gill 		/* Indent for any child structs */
18135819f75eSPeter Gill 		mdb_inc_indent(4);
18145819f75eSPeter Gill 	}
1815a6d42e7dSPeter Dunlap 
1816a6d42e7dSPeter Dunlap 	/*
1817a6d42e7dSPeter Dunlap 	 * Print states if requested
1818a6d42e7dSPeter Dunlap 	 */
18195819f75eSPeter Gill 	if (idc->u.child.idc_conn && states) {
1820a6d42e7dSPeter Dunlap 		states_addr = addr + offsetof(idm_conn_t, ic_state_audit);
1821a6d42e7dSPeter Dunlap 
18225819f75eSPeter Gill 		mdb_printf("State History(ic_state_audit):\n");
1823a6d42e7dSPeter Dunlap 		if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
1824a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1825a6d42e7dSPeter Dunlap 
18265819f75eSPeter Gill 		/*
18275819f75eSPeter Gill 		 * If targets are specifically requested show the
18285819f75eSPeter Gill 		 * state audit for the target specific connection struct
18295819f75eSPeter Gill 		 */
18305819f75eSPeter Gill 		if (idc->idc_tgt && IDM_CONN_ISTGT(&ic)) {
18315819f75eSPeter Gill 			states_addr = (uintptr_t)ic.ic_handle +
18325819f75eSPeter Gill 			    offsetof(iscsit_conn_t, ict_login_sm) +
18335819f75eSPeter Gill 			    offsetof(iscsit_conn_login_t, icl_state_audit);
18345819f75eSPeter Gill 
18355819f75eSPeter Gill 			mdb_printf("State History(icl_state_audit):\n");
18365819f75eSPeter Gill 			if (iscsi_sm_audit_impl(states_addr) != DCMD_OK) {
18375819f75eSPeter Gill 				return (DCMD_ERR);
18385819f75eSPeter Gill 			}
1839a6d42e7dSPeter Dunlap 		}
1840a6d42e7dSPeter Dunlap 
1841a6d42e7dSPeter Dunlap 		/*
18425819f75eSPeter Gill 		 * If initiators are specifically requested show the
18435819f75eSPeter Gill 		 * state audit for the initiator specific connection struct
1844a6d42e7dSPeter Dunlap 		 */
18455819f75eSPeter Gill 		if (idc->idc_ini && IDM_CONN_ISINI(&ic)) {
18465819f75eSPeter Gill 			states_addr = (uintptr_t)ic.ic_handle +
18475819f75eSPeter Gill 			    offsetof(iscsi_conn_t, conn_state_audit);
18485819f75eSPeter Gill 
18495819f75eSPeter Gill 			mdb_printf("State History(iscsi_conn_t "
18505819f75eSPeter Gill 			    "conn_state_audit):\n");
18515819f75eSPeter Gill 			if (iscsi_sm_audit_impl(states_addr) != DCMD_OK) {
18525819f75eSPeter Gill 				return (DCMD_ERR);
18535819f75eSPeter Gill 			}
18545819f75eSPeter Gill 		}
18555819f75eSPeter Gill 
18565819f75eSPeter Gill 		/* Don't print state history for child objects */
18575819f75eSPeter Gill 		idc->u.child.idc_states = 0;
18585819f75eSPeter Gill 	}
18595819f75eSPeter Gill 
18605819f75eSPeter Gill 	/*
18615819f75eSPeter Gill 	 * Print refcnt audit data for the connection struct if requested.
18625819f75eSPeter Gill 	 */
18635819f75eSPeter Gill 	if (idc->u.child.idc_conn && rc_audit) {
18645819f75eSPeter Gill 		mdb_printf("Reference History(ic_refcnt):\n");
1865a6d42e7dSPeter Dunlap 		rc_addr = addr + offsetof(idm_conn_t, ic_refcnt);
1866a6d42e7dSPeter Dunlap 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
1867a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
1868a6d42e7dSPeter Dunlap 
18695819f75eSPeter Gill 		/*
18705819f75eSPeter Gill 		 * If targets are specifically requested show the
18715819f75eSPeter Gill 		 * Refcounts for the target specific connection struct
18725819f75eSPeter Gill 		 */
18735819f75eSPeter Gill 		if (idc->idc_tgt && IDM_CONN_ISTGT(&ic)) {
18745819f75eSPeter Gill 			mdb_printf("Reference History(ict_refcnt):\n");
18755819f75eSPeter Gill 			rc_addr = (uintptr_t)ic.ic_handle +
18765819f75eSPeter Gill 			    offsetof(iscsit_conn_t, ict_refcnt);
18775819f75eSPeter Gill 			if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
18785819f75eSPeter Gill 				return (DCMD_ERR);
18795819f75eSPeter Gill 			}
18805819f75eSPeter Gill 
18815819f75eSPeter Gill 			mdb_printf("Reference History(ict_dispatch_refcnt):\n");
18825819f75eSPeter Gill 			rc_addr = (uintptr_t)ic.ic_handle +
18835819f75eSPeter Gill 			    offsetof(iscsit_conn_t, ict_dispatch_refcnt);
18845819f75eSPeter Gill 			if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
18855819f75eSPeter Gill 				return (DCMD_ERR);
18865819f75eSPeter Gill 			}
18875819f75eSPeter Gill 		}
18885819f75eSPeter Gill 
1889a6d42e7dSPeter Dunlap 		/* Don't print audit data for child objects */
1890a6d42e7dSPeter Dunlap 		idc->u.child.idc_rc_audit = 0;
1891a6d42e7dSPeter Dunlap 	}
1892a6d42e7dSPeter Dunlap 
1893a6d42e7dSPeter Dunlap 	task_idx = 0;
1894a6d42e7dSPeter Dunlap 
1895a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_task || idc->u.child.idc_buffer) {
1896a6d42e7dSPeter Dunlap 
18975819f75eSPeter Gill 		if (idc->u.child.idc_conn) {
18985819f75eSPeter Gill 			idc->idc_header = 1;
18995819f75eSPeter Gill 		}
19005819f75eSPeter Gill 
19015819f75eSPeter Gill 		while (task_idx < IDM_TASKIDS_MAX) {
1902a6d42e7dSPeter Dunlap 			/*
1903a6d42e7dSPeter Dunlap 			 * Read the next idm_task_t
1904a6d42e7dSPeter Dunlap 			 */
1905a6d42e7dSPeter Dunlap 			if (mdb_vread(&task_addr, sizeof (uintptr_t),
1906a6d42e7dSPeter Dunlap 			    task_ptr) != sizeof (uintptr_t)) {
1907a6d42e7dSPeter Dunlap 				mdb_warn("Failed to read task pointer");
1908a6d42e7dSPeter Dunlap 				return (DCMD_ERR);
1909a6d42e7dSPeter Dunlap 			}
1910a6d42e7dSPeter Dunlap 
1911a6d42e7dSPeter Dunlap 			if (task_addr == NULL) {
1912a6d42e7dSPeter Dunlap 				task_ptr += sizeof (uintptr_t);
1913a6d42e7dSPeter Dunlap 				task_idx++;
1914a6d42e7dSPeter Dunlap 				continue;
1915a6d42e7dSPeter Dunlap 			}
1916a6d42e7dSPeter Dunlap 
1917a6d42e7dSPeter Dunlap 			if (mdb_vread(&idt, sizeof (idm_task_t), task_addr)
1918a6d42e7dSPeter Dunlap 			    != sizeof (idm_task_t)) {
1919a6d42e7dSPeter Dunlap 				mdb_warn("Failed to read task pointer");
1920a6d42e7dSPeter Dunlap 				return (DCMD_ERR);
1921a6d42e7dSPeter Dunlap 			}
1922a6d42e7dSPeter Dunlap 
1923a6d42e7dSPeter Dunlap 			if (((uintptr_t)idt.idt_ic == addr) &&
1924a6d42e7dSPeter Dunlap 			    (idt.idt_state != TASK_IDLE)) {
1925a6d42e7dSPeter Dunlap 				if (iscsi_i_task_impl(&idt, task_addr, idc)
1926a6d42e7dSPeter Dunlap 				    == -1) {
1927a6d42e7dSPeter Dunlap 					mdb_warn("Failed to walk connection "
1928a6d42e7dSPeter Dunlap 					    "task tree");
1929a6d42e7dSPeter Dunlap 					return (DCMD_ERR);
1930a6d42e7dSPeter Dunlap 				}
1931a6d42e7dSPeter Dunlap 			}
1932a6d42e7dSPeter Dunlap 
1933a6d42e7dSPeter Dunlap 			task_ptr += sizeof (uintptr_t);
1934a6d42e7dSPeter Dunlap 			task_idx++;
1935a6d42e7dSPeter Dunlap 		}
19365819f75eSPeter Gill 	}
19375819f75eSPeter Gill 
19385819f75eSPeter Gill 	if (idc->idc_ini && IDM_CONN_ISINI(&ic) && idc->u.child.idc_cmd) {
19395819f75eSPeter Gill 		if (idc->u.child.idc_conn || idc->u.child.idc_task) {
19405819f75eSPeter Gill 			idc->idc_header = 1;
19415819f75eSPeter Gill 		}
19425819f75eSPeter Gill 		if (ini_conn.conn_queue_active.head &&
19435819f75eSPeter Gill 		    (mdb_pwalk("iscsi_ini_cmd", iscsi_ini_cmd_walk_cb, idc,
19445819f75eSPeter Gill 		    (uintptr_t)ini_conn.conn_queue_active.head) == -1)) {
19455819f75eSPeter Gill 			mdb_warn("list walk failed for iscsi cmds");
19465819f75eSPeter Gill 		}
19475819f75eSPeter Gill 		if (ini_conn.conn_queue_idm_aborting.head &&
19485819f75eSPeter Gill 		    (mdb_pwalk("iscsi_ini_cmd", iscsi_ini_cmd_walk_cb, idc,
19495819f75eSPeter Gill 		    (uintptr_t)ini_conn.conn_queue_idm_aborting.head) == -1)) {
19505819f75eSPeter Gill 			mdb_warn("list walk failed for iscsi cmds");
19515819f75eSPeter Gill 		}
19525819f75eSPeter Gill 	}
19535819f75eSPeter Gill 
19545819f75eSPeter Gill 	/*
19555819f75eSPeter Gill 	 * If connection information was handled unset header and
19565819f75eSPeter Gill 	 * decrease indent
19575819f75eSPeter Gill 	 */
19585819f75eSPeter Gill 	if (idc->u.child.idc_conn) {
1959a6d42e7dSPeter Dunlap 		idc->idc_header = 0;
19605819f75eSPeter Gill 		mdb_dec_indent(4);
1961a6d42e7dSPeter Dunlap 	}
1962a6d42e7dSPeter Dunlap 
1963a6d42e7dSPeter Dunlap 	idc->idc_verbose = verbose;
1964a6d42e7dSPeter Dunlap 	idc->u.child.idc_states = states;
1965a6d42e7dSPeter Dunlap 	idc->u.child.idc_rc_audit = rc_audit;
1966a6d42e7dSPeter Dunlap 
1967a6d42e7dSPeter Dunlap 	return (DCMD_OK);
1968a6d42e7dSPeter Dunlap }
1969a6d42e7dSPeter Dunlap 
19705819f75eSPeter Gill static int
iscsi_svc_impl(uintptr_t addr,iscsi_dcmd_ctrl_t * idc)19715819f75eSPeter Gill iscsi_svc_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
19725819f75eSPeter Gill {
19735819f75eSPeter Gill 	idm_svc_t	svc;
19745819f75eSPeter Gill 	iser_svc_t	iser_svc;
19755819f75eSPeter Gill 	uintptr_t	rc_addr;
19765819f75eSPeter Gill 
19775819f75eSPeter Gill 	if (mdb_vread(&svc, sizeof (idm_svc_t), addr) !=
19785819f75eSPeter Gill 	    sizeof (idm_svc_t)) {
19795819f75eSPeter Gill 		return (DCMD_ERR);
19805819f75eSPeter Gill 	}
19815819f75eSPeter Gill 
19825819f75eSPeter Gill 	if (idc->u.child.idc_svc) {
19835819f75eSPeter Gill 		if (idc->idc_verbose) {
19845819f75eSPeter Gill 			mdb_printf("Service %p\n", addr);
19855819f75eSPeter Gill 			mdb_printf("%20s: %d\n", "Port",
19865819f75eSPeter Gill 			    svc.is_svc_req.sr_port);
19875819f75eSPeter Gill 			mdb_printf("%20s: %d\n", "Online",
19885819f75eSPeter Gill 			    svc.is_online);
19895819f75eSPeter Gill 			mdb_printf("%20s: %p\n", "Socket Service",
19905819f75eSPeter Gill 			    svc.is_so_svc);
19915819f75eSPeter Gill 			mdb_printf("%20s: %p\n", "iSER Service",
19925819f75eSPeter Gill 			    svc.is_iser_svc);
19935819f75eSPeter Gill 		} else {
19945819f75eSPeter Gill 			if (idc->idc_header) {
19955819f75eSPeter Gill 				mdb_printf("%<u>%-?s %-8s %-8s%</u>\n",
19965819f75eSPeter Gill 				    "idm_svc_t", "Port", "Online");
19975819f75eSPeter Gill 				idc->idc_header = 0;
19985819f75eSPeter Gill 			}
19995819f75eSPeter Gill 
20005819f75eSPeter Gill 			mdb_printf("%?p %-8d %-8d\n", addr,
20015819f75eSPeter Gill 			    svc.is_svc_req.sr_port, svc.is_online);
20025819f75eSPeter Gill 		}
20035819f75eSPeter Gill 
20045819f75eSPeter Gill 		if (idc->u.child.idc_rc_audit) {
20055819f75eSPeter Gill 			(void) mdb_inc_indent(4);
20065819f75eSPeter Gill 			mdb_printf("Reference History(is_refcnt):\n");
20075819f75eSPeter Gill 			rc_addr = addr + offsetof(idm_svc_t, is_refcnt);
20085819f75eSPeter Gill 			if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
20095819f75eSPeter Gill 				(void) mdb_dec_indent(4);
20105819f75eSPeter Gill 				return (DCMD_ERR);
20115819f75eSPeter Gill 			}
20125819f75eSPeter Gill 
20135819f75eSPeter Gill 			if (svc.is_iser_svc != NULL) {
20145819f75eSPeter Gill 				mdb_printf("Reference History"
20155819f75eSPeter Gill 				    "(iser_svc is_refcnt):\n");
20165819f75eSPeter Gill 
20175819f75eSPeter Gill 				/* Sanity check the iser svc struct */
20185819f75eSPeter Gill 				if (mdb_vread(&iser_svc, sizeof (iser_svc_t),
20195819f75eSPeter Gill 				    (uintptr_t)svc.is_iser_svc) !=
20205819f75eSPeter Gill 				    sizeof (iser_svc_t)) {
20215819f75eSPeter Gill 					return (DCMD_ERR);
20225819f75eSPeter Gill 				}
20235819f75eSPeter Gill 
20245819f75eSPeter Gill 				rc_addr = (uintptr_t)svc.is_iser_svc +
20255819f75eSPeter Gill 				    offsetof(iser_svc_t, is_refcnt);
20265819f75eSPeter Gill 
20275819f75eSPeter Gill 				if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
20285819f75eSPeter Gill 					return (DCMD_ERR);
20295819f75eSPeter Gill 				}
20305819f75eSPeter Gill 			}
20315819f75eSPeter Gill 			(void) mdb_dec_indent(4);
20325819f75eSPeter Gill 		}
20335819f75eSPeter Gill 	}
20345819f75eSPeter Gill 	return (DCMD_OK);
20355819f75eSPeter Gill }
20365819f75eSPeter Gill 
2037a6d42e7dSPeter Dunlap static void
iscsi_print_iscsit_conn_data(idm_conn_t * ic)2038a6d42e7dSPeter Dunlap iscsi_print_iscsit_conn_data(idm_conn_t *ic)
2039a6d42e7dSPeter Dunlap {
2040a6d42e7dSPeter Dunlap 	iscsit_conn_t	ict;
2041a6d42e7dSPeter Dunlap 	char		*csg;
2042a6d42e7dSPeter Dunlap 	char		*nsg;
2043a6d42e7dSPeter Dunlap 
2044a6d42e7dSPeter Dunlap 	iscsi_print_idm_conn_data(ic);
2045a6d42e7dSPeter Dunlap 
2046a6d42e7dSPeter Dunlap 	if (mdb_vread(&ict, sizeof (iscsit_conn_t),
2047a6d42e7dSPeter Dunlap 	    (uintptr_t)ic->ic_handle) != sizeof (iscsit_conn_t)) {
2048a6d42e7dSPeter Dunlap 		mdb_printf("**Failed to read conn private data\n");
2049a6d42e7dSPeter Dunlap 		return;
2050a6d42e7dSPeter Dunlap 	}
2051a6d42e7dSPeter Dunlap 
20525819f75eSPeter Gill 	mdb_printf("%20s: %p\n", "iSCSIT TGT Conn",
20535819f75eSPeter Gill 	    ic->ic_handle);
20545819f75eSPeter Gill 
2055a6d42e7dSPeter Dunlap 	if (ict.ict_login_sm.icl_login_state != ILS_LOGIN_DONE) {
2056a6d42e7dSPeter Dunlap 		switch (ict.ict_login_sm.icl_login_csg) {
2057a6d42e7dSPeter Dunlap 		case ISCSI_SECURITY_NEGOTIATION_STAGE:
2058a6d42e7dSPeter Dunlap 			csg = "Security";
2059a6d42e7dSPeter Dunlap 			break;
2060a6d42e7dSPeter Dunlap 		case ISCSI_OP_PARMS_NEGOTIATION_STAGE:
2061a6d42e7dSPeter Dunlap 			csg = "Operational";
2062a6d42e7dSPeter Dunlap 			break;
2063a6d42e7dSPeter Dunlap 		case ISCSI_FULL_FEATURE_PHASE:
2064a6d42e7dSPeter Dunlap 			csg = "FFP";
2065a6d42e7dSPeter Dunlap 			break;
2066a6d42e7dSPeter Dunlap 		default:
2067a6d42e7dSPeter Dunlap 			csg = "Unknown";
2068a6d42e7dSPeter Dunlap 		}
2069a6d42e7dSPeter Dunlap 		switch (ict.ict_login_sm.icl_login_nsg) {
2070a6d42e7dSPeter Dunlap 		case ISCSI_SECURITY_NEGOTIATION_STAGE:
2071a6d42e7dSPeter Dunlap 			nsg = "Security";
2072a6d42e7dSPeter Dunlap 			break;
2073a6d42e7dSPeter Dunlap 		case ISCSI_OP_PARMS_NEGOTIATION_STAGE:
2074a6d42e7dSPeter Dunlap 			nsg = "Operational";
2075a6d42e7dSPeter Dunlap 			break;
2076a6d42e7dSPeter Dunlap 		case ISCSI_FULL_FEATURE_PHASE:
2077a6d42e7dSPeter Dunlap 			nsg = "FFP";
2078a6d42e7dSPeter Dunlap 			break;
2079a6d42e7dSPeter Dunlap 		default:
2080a6d42e7dSPeter Dunlap 			nsg = "Unknown";
2081a6d42e7dSPeter Dunlap 		}
2082a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %d\n", "Login State",
2083a6d42e7dSPeter Dunlap 		    ict.ict_login_sm.icl_login_state);
2084a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %d\n", "Login Last State",
2085a6d42e7dSPeter Dunlap 		    ict.ict_login_sm.icl_login_last_state);
2086a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %s\n", "CSG", csg);
2087a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %s\n", "NSG", nsg);
2088a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %d\n", "Transit",
2089a6d42e7dSPeter Dunlap 		    ict.ict_login_sm.icl_login_transit >> 7);
2090a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %p\n", "Request nvlist",
2091a6d42e7dSPeter Dunlap 		    ict.ict_login_sm.icl_request_nvlist);
2092a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %p\n", "Response nvlist",
2093a6d42e7dSPeter Dunlap 		    ict.ict_login_sm.icl_response_nvlist);
2094a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %p\n", "Negotiated nvlist",
2095a6d42e7dSPeter Dunlap 		    ict.ict_login_sm.icl_negotiated_values);
2096a6d42e7dSPeter Dunlap 		if (ict.ict_login_sm.icl_login_state == ILS_LOGIN_ERROR) {
2097a6d42e7dSPeter Dunlap 			mdb_printf("%20s: 0x%02x\n", "Error Class",
2098a6d42e7dSPeter Dunlap 			    ict.ict_login_sm.icl_login_resp_err_class);
2099a6d42e7dSPeter Dunlap 			mdb_printf("%20s: 0x%02x\n", "Error Detail",
2100a6d42e7dSPeter Dunlap 			    ict.ict_login_sm.icl_login_resp_err_detail);
2101a6d42e7dSPeter Dunlap 		}
2102a6d42e7dSPeter Dunlap 	}
2103a6d42e7dSPeter Dunlap 	mdb_printf("%20s: 0x%04x\n", "CID", ict.ict_cid);
2104a6d42e7dSPeter Dunlap 	mdb_printf("%20s: 0x%08x\n", "StatSN", ict.ict_statsn);
2105a6d42e7dSPeter Dunlap }
2106a6d42e7dSPeter Dunlap 
2107a6d42e7dSPeter Dunlap static void
iscsi_print_ini_conn_data(idm_conn_t * ic)21085819f75eSPeter Gill iscsi_print_ini_conn_data(idm_conn_t *ic)
21095819f75eSPeter Gill {
21105819f75eSPeter Gill 	iscsi_conn_t	ini_conn;
21115819f75eSPeter Gill 
21125819f75eSPeter Gill 	iscsi_print_idm_conn_data(ic);
21135819f75eSPeter Gill 
21145819f75eSPeter Gill 	if (mdb_vread(&ini_conn, sizeof (iscsi_conn_t),
21155819f75eSPeter Gill 	    (uintptr_t)ic->ic_handle) != sizeof (iscsi_conn_t)) {
21165819f75eSPeter Gill 		mdb_printf("Failed to read conn private data\n");
21175819f75eSPeter Gill 		return;
21185819f75eSPeter Gill 	}
21195819f75eSPeter Gill 
21205819f75eSPeter Gill 	mdb_printf("%20s: %p\n", "iSCSI Ini Conn",
21215819f75eSPeter Gill 	    ic->ic_handle);
21225819f75eSPeter Gill 	mdb_printf("%20s: %p\n", "Parent Session",
21235819f75eSPeter Gill 	    ini_conn.conn_sess);
21245819f75eSPeter Gill 	mdb_printf("%20s: %d\n", "Conn State",
21255819f75eSPeter Gill 	    ini_conn.conn_state);
21265819f75eSPeter Gill 	mdb_printf("%20s: %d\n", "Last Conn State",
21275819f75eSPeter Gill 	    ini_conn.conn_prev_state);
21285819f75eSPeter Gill 
21295819f75eSPeter Gill 	mdb_printf("%20s: %d\n", "Login Stage",
21305819f75eSPeter Gill 	    ini_conn.conn_current_stage);
21315819f75eSPeter Gill 	mdb_printf("%20s: %d\n", "Next Login Stage",
21325819f75eSPeter Gill 	    ini_conn.conn_next_stage);
21335819f75eSPeter Gill 
21345819f75eSPeter Gill 	mdb_printf("%20s: 0x%08x\n", "Expected StatSN",
21355819f75eSPeter Gill 	    ini_conn.conn_expstatsn);
21365819f75eSPeter Gill 	mdb_printf("%20s: %p\n", "Active Queue Head",
21375819f75eSPeter Gill 	    ini_conn.conn_queue_active.head);
21385819f75eSPeter Gill 	mdb_printf("%20s: %d\n", "Abort Queue Head",
21395819f75eSPeter Gill 	    ini_conn.conn_queue_idm_aborting.head);
21405819f75eSPeter Gill }
21415819f75eSPeter Gill 
21425819f75eSPeter Gill static void
iscsi_print_idm_conn_data(idm_conn_t * ic)2143a6d42e7dSPeter Dunlap iscsi_print_idm_conn_data(idm_conn_t *ic)
2144a6d42e7dSPeter Dunlap {
2145a6d42e7dSPeter Dunlap 	char		laddr[PORTAL_STR_LEN];
2146a6d42e7dSPeter Dunlap 	char		raddr[PORTAL_STR_LEN];
2147a6d42e7dSPeter Dunlap 
2148a6d42e7dSPeter Dunlap 	sa_to_str(&ic->ic_laddr, laddr);
2149a6d42e7dSPeter Dunlap 	sa_to_str(&ic->ic_raddr, raddr);
2150a6d42e7dSPeter Dunlap 
2151a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %s\n", "Conn Type",
2152a6d42e7dSPeter Dunlap 	    ((ic->ic_conn_type == CONN_TYPE_TGT) ? "Target" :
2153a6d42e7dSPeter Dunlap 	    ((ic->ic_conn_type == CONN_TYPE_INI) ? "Initiator" :
2154a6d42e7dSPeter Dunlap 	    "Unknown")));
2155a6d42e7dSPeter Dunlap 	if (ic->ic_conn_type == CONN_TYPE_TGT) {
2156a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %p\n", "Svc. Binding",
2157a6d42e7dSPeter Dunlap 		    ic->ic_svc_binding);
2158a6d42e7dSPeter Dunlap 	}
2159a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %s\n", "Transport",
2160a6d42e7dSPeter Dunlap 	    (ic->ic_transport_type == IDM_TRANSPORT_TYPE_ISER) ? "ISER_IB" :
2161a6d42e7dSPeter Dunlap 	    (ic->ic_transport_type == IDM_TRANSPORT_TYPE_SOCKETS) ? "SOCKETS" :
2162a6d42e7dSPeter Dunlap 	    "N/A");
2163a6d42e7dSPeter Dunlap 
2164a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %s\n", "Local IP", laddr);
2165a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %s\n", "Remote IP", raddr);
2166a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %d\n", "State",
2167a6d42e7dSPeter Dunlap 	    ic->ic_state);
2168a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %d\n", "Last State",
2169a6d42e7dSPeter Dunlap 	    ic->ic_last_state);
2170a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %d %s\n", "Refcount",
2171a6d42e7dSPeter Dunlap 	    ic->ic_refcnt.ir_refcnt,
2172a6d42e7dSPeter Dunlap 	    (ic->ic_refcnt.ir_waiting == REF_NOWAIT) ? "" :
2173a6d42e7dSPeter Dunlap 	    ((ic->ic_refcnt.ir_waiting == REF_WAIT_SYNC) ? "REF_WAIT_SYNC" :
2174a6d42e7dSPeter Dunlap 	    ((ic->ic_refcnt.ir_waiting == REF_WAIT_ASYNC) ? "REF_WAIT_ASYNC" :
2175a6d42e7dSPeter Dunlap 	    "UNKNOWN")));
2176a6d42e7dSPeter Dunlap }
2177a6d42e7dSPeter Dunlap 
2178a6d42e7dSPeter Dunlap static int
iscsi_i_task_impl(idm_task_t * idt,uintptr_t addr,iscsi_dcmd_ctrl_t * idc)2179a6d42e7dSPeter Dunlap iscsi_i_task_impl(idm_task_t *idt, uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
2180a6d42e7dSPeter Dunlap {
2181a6d42e7dSPeter Dunlap 	uintptr_t	list_addr, rc_addr;
2182a6d42e7dSPeter Dunlap 	idm_conn_type_t	conn_type;
2183a6d42e7dSPeter Dunlap 	int		verbose, states, rc_audit;
2184a6d42e7dSPeter Dunlap 
2185a6d42e7dSPeter Dunlap 	conn_type = idm_conn_type((uintptr_t)idt->idt_ic);
2186a6d42e7dSPeter Dunlap 
2187a6d42e7dSPeter Dunlap 	verbose = idc->idc_verbose;
2188a6d42e7dSPeter Dunlap 	states = idc->u.child.idc_states;
2189a6d42e7dSPeter Dunlap 	rc_audit = idc->u.child.idc_rc_audit;
2190a6d42e7dSPeter Dunlap 
2191a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_task) {
2192a6d42e7dSPeter Dunlap 		if (verbose) {
2193a6d42e7dSPeter Dunlap 			mdb_printf("Task %p\n", addr);
2194a6d42e7dSPeter Dunlap 			(void) mdb_inc_indent(2);
2195a6d42e7dSPeter Dunlap 			if (conn_type == CONN_TYPE_TGT) {
2196a6d42e7dSPeter Dunlap 				iscsi_print_iscsit_task_data(idt);
2197a6d42e7dSPeter Dunlap 			}
2198a6d42e7dSPeter Dunlap 			(void) mdb_dec_indent(2);
2199a6d42e7dSPeter Dunlap 		} else {
2200a6d42e7dSPeter Dunlap 			/* Print task data */
2201a6d42e7dSPeter Dunlap 			if (idc->idc_header) {
2202a6d42e7dSPeter Dunlap 				mdb_printf(
2203bf604c64SPeter Dunlap 				    "%<u>%-?s %-16s %-4s %-8s %-8s%</u>\n",
2204bf604c64SPeter Dunlap 				    "Tasks:", "State", "Ref",
2205a6d42e7dSPeter Dunlap 				    (conn_type == CONN_TYPE_TGT ? "TTT" :
2206a6d42e7dSPeter Dunlap 				    (conn_type == CONN_TYPE_INI ? "ITT" :
2207a6d42e7dSPeter Dunlap 				    "TT")), "Handle");
2208a6d42e7dSPeter Dunlap 			}
2209bf604c64SPeter Dunlap 			mdb_printf("%?p %-16s %04x %08x %08x\n", addr,
2210bf604c64SPeter Dunlap 			    idm_ts_name[idt->idt_state],
2211bf604c64SPeter Dunlap 			    idt->idt_refcnt.ir_refcnt,
2212bf604c64SPeter Dunlap 			    idt->idt_tt, idt->idt_client_handle);
2213a6d42e7dSPeter Dunlap 		}
2214a6d42e7dSPeter Dunlap 	}
2215a6d42e7dSPeter Dunlap 	idc->idc_header = 0;
2216a6d42e7dSPeter Dunlap 	idc->idc_verbose = 0;
2217a6d42e7dSPeter Dunlap 
2218a6d42e7dSPeter Dunlap 	/*
2219a6d42e7dSPeter Dunlap 	 * Print states if requested
2220a6d42e7dSPeter Dunlap 	 */
2221a6d42e7dSPeter Dunlap #if 0
2222a6d42e7dSPeter Dunlap 	if (states) {
2223a6d42e7dSPeter Dunlap 		states_addr = addr + offsetof(idm_task_t, idt_state_audit);
2224a6d42e7dSPeter Dunlap 
2225a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(4);
22265819f75eSPeter Gill 		mdb_printf("State History(idt_state_audit):\n");
2227a6d42e7dSPeter Dunlap 		if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
2228a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
2229a6d42e7dSPeter Dunlap 
2230a6d42e7dSPeter Dunlap 		/* Don't print state history for child objects */
2231a6d42e7dSPeter Dunlap 		idc->u.child.idc_states = 0;
2232a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
2233a6d42e7dSPeter Dunlap 	}
2234a6d42e7dSPeter Dunlap #endif
2235a6d42e7dSPeter Dunlap 
2236a6d42e7dSPeter Dunlap 	/*
2237a6d42e7dSPeter Dunlap 	 * Print refcnt audit data if requested
2238a6d42e7dSPeter Dunlap 	 */
2239a6d42e7dSPeter Dunlap 	if (rc_audit) {
2240a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(4);
22415819f75eSPeter Gill 		mdb_printf("Reference History(idt_refcnt):\n");
2242a6d42e7dSPeter Dunlap 		rc_addr = addr +
2243a6d42e7dSPeter Dunlap 		    offsetof(idm_task_t, idt_refcnt);
2244a6d42e7dSPeter Dunlap 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
2245a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
2246a6d42e7dSPeter Dunlap 
2247a6d42e7dSPeter Dunlap 		/* Don't print audit data for child objects */
2248a6d42e7dSPeter Dunlap 		idc->u.child.idc_rc_audit = 0;
2249a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
2250a6d42e7dSPeter Dunlap 	}
2251a6d42e7dSPeter Dunlap 
2252a6d42e7dSPeter Dunlap 
22535819f75eSPeter Gill 	/*
22545819f75eSPeter Gill 	 * Buffers are leaf objects and always get headers so the
22555819f75eSPeter Gill 	 * user can discern between in and out buffers.
22565819f75eSPeter Gill 	 */
2257a6d42e7dSPeter Dunlap 	if (idc->u.child.idc_buffer) {
2258a6d42e7dSPeter Dunlap 		/* Walk in buffer list */
2259a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(2);
2260a6d42e7dSPeter Dunlap 		mdb_printf("In buffers:\n");
2261a6d42e7dSPeter Dunlap 		idc->idc_header = 1;
2262a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(2);
2263a6d42e7dSPeter Dunlap 		list_addr = addr + offsetof(idm_task_t, idt_inbufv);
2264a6d42e7dSPeter Dunlap 		if (mdb_pwalk("list", iscsi_buffer_walk_cb, idc, list_addr) ==
2265a6d42e7dSPeter Dunlap 		    -1) {
2266a6d42e7dSPeter Dunlap 			mdb_warn("list walk failed for task in buffers");
2267a6d42e7dSPeter Dunlap 			(void) mdb_dec_indent(4);
2268a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
2269a6d42e7dSPeter Dunlap 		}
2270a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(2);
2271a6d42e7dSPeter Dunlap 		/* Walk out buffer list */
2272a6d42e7dSPeter Dunlap 		mdb_printf("Out buffers:\n");
2273a6d42e7dSPeter Dunlap 		idc->idc_header = 1;
2274a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(2);
2275a6d42e7dSPeter Dunlap 		list_addr = addr + offsetof(idm_task_t, idt_outbufv);
2276a6d42e7dSPeter Dunlap 		if (mdb_pwalk("list", iscsi_buffer_walk_cb, idc, list_addr) ==
2277a6d42e7dSPeter Dunlap 		    -1) {
2278a6d42e7dSPeter Dunlap 			mdb_warn("list walk failed for task out buffers\n");
2279a6d42e7dSPeter Dunlap 			(void) mdb_dec_indent(2);
2280a6d42e7dSPeter Dunlap 			return (DCMD_ERR);
2281a6d42e7dSPeter Dunlap 		}
2282a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(4);
2283a6d42e7dSPeter Dunlap 	}
2284a6d42e7dSPeter Dunlap 
2285a6d42e7dSPeter Dunlap 	idc->idc_verbose = verbose;
2286a6d42e7dSPeter Dunlap 	idc->u.child.idc_states = states;
2287a6d42e7dSPeter Dunlap 	idc->u.child.idc_rc_audit = rc_audit;
2288a6d42e7dSPeter Dunlap 
2289a6d42e7dSPeter Dunlap 	return (DCMD_OK);
2290a6d42e7dSPeter Dunlap }
2291a6d42e7dSPeter Dunlap 
2292a6d42e7dSPeter Dunlap static int
iscsi_task_impl(uintptr_t addr,iscsi_dcmd_ctrl_t * idc)2293a6d42e7dSPeter Dunlap iscsi_task_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
2294a6d42e7dSPeter Dunlap {
2295a6d42e7dSPeter Dunlap 	idm_task_t	idt;
2296a6d42e7dSPeter Dunlap 
2297a6d42e7dSPeter Dunlap 	/*
2298a6d42e7dSPeter Dunlap 	 * Read idm_conn_t
2299a6d42e7dSPeter Dunlap 	 */
2300a6d42e7dSPeter Dunlap 	if (mdb_vread(&idt, sizeof (idm_task_t), addr) != sizeof (idm_task_t)) {
2301a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2302a6d42e7dSPeter Dunlap 	}
2303a6d42e7dSPeter Dunlap 
2304a6d42e7dSPeter Dunlap 	return (iscsi_i_task_impl(&idt, addr, idc));
2305a6d42e7dSPeter Dunlap }
2306a6d42e7dSPeter Dunlap 
2307a6d42e7dSPeter Dunlap #define	ISCSI_CDB_INDENT	16
2308a6d42e7dSPeter Dunlap 
2309a6d42e7dSPeter Dunlap static void
iscsi_print_iscsit_task_data(idm_task_t * idt)2310a6d42e7dSPeter Dunlap iscsi_print_iscsit_task_data(idm_task_t *idt)
2311a6d42e7dSPeter Dunlap {
2312a6d42e7dSPeter Dunlap 	iscsit_task_t	itask;
2313a6d42e7dSPeter Dunlap 	boolean_t	good_scsi_task = B_TRUE;
2314a6d42e7dSPeter Dunlap 	scsi_task_t	scsi_task;
2315a6d42e7dSPeter Dunlap 
2316a6d42e7dSPeter Dunlap 	if (mdb_vread(&itask, sizeof (iscsit_task_t),
2317a6d42e7dSPeter Dunlap 	    (uintptr_t)idt->idt_private) != sizeof (iscsit_task_t)) {
2318a6d42e7dSPeter Dunlap 		mdb_printf("**Failed to read idt_private data\n");
2319a6d42e7dSPeter Dunlap 		return;
2320a6d42e7dSPeter Dunlap 	}
2321a6d42e7dSPeter Dunlap 
2322a6d42e7dSPeter Dunlap 	if (mdb_vread(&scsi_task, sizeof (scsi_task_t),
2323a6d42e7dSPeter Dunlap 	    (uintptr_t)itask.it_stmf_task) != sizeof (scsi_task_t)) {
2324a6d42e7dSPeter Dunlap 		good_scsi_task = B_FALSE;
2325a6d42e7dSPeter Dunlap 	}
2326a6d42e7dSPeter Dunlap 
2327bf604c64SPeter Dunlap 	mdb_printf("%20s: %s(%d)\n", "State",
2328bf604c64SPeter Dunlap 	    idt->idt_state > TASK_MAX_STATE ?
2329bf604c64SPeter Dunlap 	    "UNKNOWN" : idm_ts_name[idt->idt_state],
2330bf604c64SPeter Dunlap 	    idt->idt_state);
2331bf604c64SPeter Dunlap 	mdb_printf("%20s: %d/%d\n", "STMF abort/IDM aborted",
2332bf604c64SPeter Dunlap 	    itask.it_stmf_abort, itask.it_aborted);
2333a6d42e7dSPeter Dunlap 	mdb_printf("%20s: %p/%p/%p%s\n",
2334a6d42e7dSPeter Dunlap 	    "iscsit/STMF/LU", idt->idt_private,
2335a6d42e7dSPeter Dunlap 	    itask.it_stmf_task, good_scsi_task ? scsi_task.task_lu_private : 0,
2336a6d42e7dSPeter Dunlap 	    good_scsi_task ? "" : "**");
2337a6d42e7dSPeter Dunlap 	if (good_scsi_task) {
2338a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %08x/%08x\n", "ITT/TTT",
2339a6d42e7dSPeter Dunlap 		    itask.it_itt, itask.it_ttt);
2340a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %08x\n", "CmdSN",
2341a6d42e7dSPeter Dunlap 		    itask.it_cmdsn);
2342a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %02x %02x %02x %02x %02x %02x %02x %02x\n",
2343a6d42e7dSPeter Dunlap 		    "LU number",
2344a6d42e7dSPeter Dunlap 		    scsi_task.task_lun_no[0], scsi_task.task_lun_no[1],
2345a6d42e7dSPeter Dunlap 		    scsi_task.task_lun_no[2], scsi_task.task_lun_no[3],
2346a6d42e7dSPeter Dunlap 		    scsi_task.task_lun_no[4], scsi_task.task_lun_no[5],
2347a6d42e7dSPeter Dunlap 		    scsi_task.task_lun_no[6], scsi_task.task_lun_no[7]);
2348a6d42e7dSPeter Dunlap 		mdb_printf("     CDB (%d bytes):\n",
2349a6d42e7dSPeter Dunlap 		    scsi_task.task_cdb_length);
2350a6d42e7dSPeter Dunlap 		(void) mdb_inc_indent(ISCSI_CDB_INDENT);
2351a6d42e7dSPeter Dunlap 		if (mdb_dumpptr((uintptr_t)scsi_task.task_cdb,
2352a6d42e7dSPeter Dunlap 		    scsi_task.task_cdb_length,
2353a6d42e7dSPeter Dunlap 		    MDB_DUMP_RELATIVE | MDB_DUMP_TRIM |
2354a6d42e7dSPeter Dunlap 		    MDB_DUMP_GROUP(1),
2355a6d42e7dSPeter Dunlap 		    (mdb_dumpptr_cb_t)mdb_vread, NULL)) {
2356a6d42e7dSPeter Dunlap 			mdb_printf("** Invalid CDB addr (%p)\n",
2357a6d42e7dSPeter Dunlap 			    scsi_task.task_cdb);
2358a6d42e7dSPeter Dunlap 		}
2359a6d42e7dSPeter Dunlap 		(void) mdb_dec_indent(ISCSI_CDB_INDENT);
2360a6d42e7dSPeter Dunlap 		mdb_printf("%20s: %d/%d\n", "STMF cur/max bufs",
2361a6d42e7dSPeter Dunlap 		    scsi_task.task_cur_nbufs,
2362a6d42e7dSPeter Dunlap 		    scsi_task.task_max_nbufs);
2363a6d42e7dSPeter Dunlap 		mdb_printf("%20s: 0x%08x/0x%08x/0x%08x\n", "Bytes Exp/Cmd/Done",
2364a6d42e7dSPeter Dunlap 		    scsi_task.task_expected_xfer_length,
2365a6d42e7dSPeter Dunlap 		    scsi_task.task_cmd_xfer_length,
2366a6d42e7dSPeter Dunlap 		    scsi_task.task_nbytes_transferred);
2367a6d42e7dSPeter Dunlap 		mdb_printf("%20s: 0x%x/0x%x\n", "TX-ini start/done",
2368a6d42e7dSPeter Dunlap 		    idt->idt_tx_to_ini_start,
2369a6d42e7dSPeter Dunlap 		    idt->idt_tx_to_ini_done);
2370a6d42e7dSPeter Dunlap 		mdb_printf("%20s: 0x%x/0x%x\n", "RX-ini start/done",
2371a6d42e7dSPeter Dunlap 		    idt->idt_rx_from_ini_start,
2372a6d42e7dSPeter Dunlap 		    idt->idt_rx_from_ini_done);
2373a6d42e7dSPeter Dunlap 	}
2374a6d42e7dSPeter Dunlap }
2375a6d42e7dSPeter Dunlap 
2376a6d42e7dSPeter Dunlap static int
iscsi_print_ini_lun(uintptr_t addr,const iscsi_lun_t * lun,iscsi_dcmd_ctrl_t * idc)23775819f75eSPeter Gill iscsi_print_ini_lun(uintptr_t addr, const iscsi_lun_t *lun,
23785819f75eSPeter Gill     iscsi_dcmd_ctrl_t *idc)
23795819f75eSPeter Gill {
23805819f75eSPeter Gill 
23815819f75eSPeter Gill 	if (idc->u.child.idc_lun) {
23825819f75eSPeter Gill 		if (idc->idc_header) {
23835819f75eSPeter Gill 			mdb_printf("%<u>%-?s %-5s %-10s%</u>\n",
23845819f75eSPeter Gill 			    "iscsi_lun_t", "State", "Lun Number");
23855819f75eSPeter Gill 			idc->idc_header = 0;
23865819f75eSPeter Gill 		}
23875819f75eSPeter Gill 		mdb_printf("%?p %-5d %-10d\n", addr,
23885819f75eSPeter Gill 		    lun->lun_state, lun->lun_num);
23895819f75eSPeter Gill 	}
23905819f75eSPeter Gill 	return (DCMD_OK);
23915819f75eSPeter Gill }
23925819f75eSPeter Gill 
23935819f75eSPeter Gill static int
iscsi_print_ini_cmd(uintptr_t addr,const iscsi_cmd_t * cmd,iscsi_dcmd_ctrl_t * idc)23945819f75eSPeter Gill iscsi_print_ini_cmd(uintptr_t addr, const iscsi_cmd_t *cmd,
23955819f75eSPeter Gill     iscsi_dcmd_ctrl_t *idc) {
23965819f75eSPeter Gill 
23975819f75eSPeter Gill 	uintptr_t states_addr;
23985819f75eSPeter Gill 
23995819f75eSPeter Gill 	if (idc->idc_header) {
24005819f75eSPeter Gill 		mdb_printf("%<u>%-?s %-?s %4s %6s/%-6s %-?s%</u>\n",
24015819f75eSPeter Gill 		    "iscsi_cmd_t", "idm_task_t", "Type",
24025819f75eSPeter Gill 		    "State", "Prev", "iscsi_lun_t");
24035819f75eSPeter Gill 		idc->idc_header = 0;
24045819f75eSPeter Gill 	}
24055819f75eSPeter Gill 
24065819f75eSPeter Gill 	mdb_printf("%?p %?p %4d %6d/%-6d %?p\n",
24075819f75eSPeter Gill 	    addr, cmd->cmd_itp, cmd->cmd_type, cmd->cmd_state,
24085819f75eSPeter Gill 	    cmd->cmd_prev_state, cmd->cmd_lun);
24095819f75eSPeter Gill 
24105819f75eSPeter Gill 	/*
24115819f75eSPeter Gill 	 * Print states if requested
24125819f75eSPeter Gill 	 */
24135819f75eSPeter Gill 	if (idc->u.child.idc_states) {
24145819f75eSPeter Gill 		states_addr = addr + offsetof(iscsi_cmd_t, cmd_state_audit);
24155819f75eSPeter Gill 
24165819f75eSPeter Gill 		(void) mdb_inc_indent(4);
24175819f75eSPeter Gill 		mdb_printf("State History(cmd_state_audit):\n");
24185819f75eSPeter Gill 		if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
24195819f75eSPeter Gill 			return (DCMD_ERR);
24205819f75eSPeter Gill 		idc->u.child.idc_states = 0;
24215819f75eSPeter Gill 		(void) mdb_dec_indent(4);
24225819f75eSPeter Gill 	}
24235819f75eSPeter Gill 	return (DCMD_OK);
24245819f75eSPeter Gill }
24255819f75eSPeter Gill 
24265819f75eSPeter Gill static int
iscsi_buffer_impl(uintptr_t addr,iscsi_dcmd_ctrl_t * idc)2427a6d42e7dSPeter Dunlap iscsi_buffer_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
2428a6d42e7dSPeter Dunlap {
2429a6d42e7dSPeter Dunlap 	idm_buf_t	idb;
2430a6d42e7dSPeter Dunlap 
2431a6d42e7dSPeter Dunlap 	/*
2432a6d42e7dSPeter Dunlap 	 * Read idm_buf_t
2433a6d42e7dSPeter Dunlap 	 */
2434a6d42e7dSPeter Dunlap 	if (mdb_vread(&idb, sizeof (idm_buf_t), addr) != sizeof (idm_buf_t)) {
2435a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2436a6d42e7dSPeter Dunlap 	}
2437a6d42e7dSPeter Dunlap 
2438a6d42e7dSPeter Dunlap 
2439a6d42e7dSPeter Dunlap 	if (idc->idc_header) {
2440a6d42e7dSPeter Dunlap 		mdb_printf("%<u>%-?s %?s/%-8s %8s %8s %8s%</u>\n",
2441a6d42e7dSPeter Dunlap 		    "idm_buf_t", "Mem Rgn", "Length",
2442a6d42e7dSPeter Dunlap 		    "Rel Off", "Xfer Len", "Exp. Off");
2443a6d42e7dSPeter Dunlap 		idc->idc_header = 0;
24445819f75eSPeter Gill 	}
2445a6d42e7dSPeter Dunlap 
2446a6d42e7dSPeter Dunlap 	/* Print buffer data */
2447a6d42e7dSPeter Dunlap 	mdb_printf("%?p %?p/%08x %8x %8x %08x\n", addr,
2448a6d42e7dSPeter Dunlap 	    idb.idb_buf, idb.idb_buflen,
2449a6d42e7dSPeter Dunlap 	    idb.idb_bufoffset, idb.idb_xfer_len,
2450a6d42e7dSPeter Dunlap 	    idb.idb_exp_offset);
2451a6d42e7dSPeter Dunlap 
2452a6d42e7dSPeter Dunlap 
2453a6d42e7dSPeter Dunlap 	/* Buffers are leaf objects */
2454a6d42e7dSPeter Dunlap 
2455a6d42e7dSPeter Dunlap 	return (DCMD_OK);
2456a6d42e7dSPeter Dunlap }
2457a6d42e7dSPeter Dunlap 
2458a6d42e7dSPeter Dunlap static int
iscsi_refcnt_impl(uintptr_t addr)2459a6d42e7dSPeter Dunlap iscsi_refcnt_impl(uintptr_t addr)
2460a6d42e7dSPeter Dunlap {
2461a6d42e7dSPeter Dunlap 	idm_refcnt_t		refcnt;
2462a6d42e7dSPeter Dunlap 	refcnt_audit_buf_t	*anb;
2463a6d42e7dSPeter Dunlap 	int			ctr;
2464a6d42e7dSPeter Dunlap 
2465a6d42e7dSPeter Dunlap 	/*
2466a6d42e7dSPeter Dunlap 	 * Print refcnt info
2467a6d42e7dSPeter Dunlap 	 */
2468a6d42e7dSPeter Dunlap 	if (mdb_vread(&refcnt, sizeof (idm_refcnt_t), addr) !=
2469a6d42e7dSPeter Dunlap 	    sizeof (idm_refcnt_t)) {
24705819f75eSPeter Gill 		mdb_warn("read refcnt failed");
2471a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2472a6d42e7dSPeter Dunlap 	}
2473a6d42e7dSPeter Dunlap 
2474a6d42e7dSPeter Dunlap 	anb = &refcnt.ir_audit_buf;
2475a6d42e7dSPeter Dunlap 
2476a6d42e7dSPeter Dunlap 	ctr = anb->anb_max_index + 1;
2477a6d42e7dSPeter Dunlap 	anb->anb_index--;
2478a6d42e7dSPeter Dunlap 	anb->anb_index &= anb->anb_max_index;
2479a6d42e7dSPeter Dunlap 
2480a6d42e7dSPeter Dunlap 	while (ctr) {
2481a6d42e7dSPeter Dunlap 		refcnt_audit_record_t	*anr;
2482a6d42e7dSPeter Dunlap 
2483a6d42e7dSPeter Dunlap 		anr = anb->anb_records + anb->anb_index;
2484a6d42e7dSPeter Dunlap 
2485a6d42e7dSPeter Dunlap 		if (anr->anr_depth) {
2486a6d42e7dSPeter Dunlap 			char c[MDB_SYM_NAMLEN];
2487a6d42e7dSPeter Dunlap 			GElf_Sym sym;
2488a6d42e7dSPeter Dunlap 			int i;
2489a6d42e7dSPeter Dunlap 
2490a6d42e7dSPeter Dunlap 			mdb_printf("\nRefCnt: %u\t", anr->anr_refcnt);
2491a6d42e7dSPeter Dunlap 
2492a6d42e7dSPeter Dunlap 			for (i = 0; i < anr->anr_depth; i++) {
2493a6d42e7dSPeter Dunlap 				if (mdb_lookup_by_addr(anr->anr_stack[i],
2494a6d42e7dSPeter Dunlap 				    MDB_SYM_FUZZY, c, sizeof (c),
2495a6d42e7dSPeter Dunlap 				    &sym) == -1) {
2496a6d42e7dSPeter Dunlap 					continue;
2497a6d42e7dSPeter Dunlap 				}
2498a6d42e7dSPeter Dunlap 				mdb_printf("%s+0x%1x", c,
2499a6d42e7dSPeter Dunlap 				    anr->anr_stack[i] -
2500a6d42e7dSPeter Dunlap 				    (uintptr_t)sym.st_value);
2501a6d42e7dSPeter Dunlap 				++i;
2502a6d42e7dSPeter Dunlap 				break;
2503a6d42e7dSPeter Dunlap 			}
2504a6d42e7dSPeter Dunlap 
2505a6d42e7dSPeter Dunlap 			while (i < anr->anr_depth) {
2506a6d42e7dSPeter Dunlap 				if (mdb_lookup_by_addr(anr->anr_stack[i],
2507a6d42e7dSPeter Dunlap 				    MDB_SYM_FUZZY, c, sizeof (c),
2508a6d42e7dSPeter Dunlap 				    &sym) == -1) {
2509a6d42e7dSPeter Dunlap 					++i;
2510a6d42e7dSPeter Dunlap 					continue;
2511a6d42e7dSPeter Dunlap 				}
2512a6d42e7dSPeter Dunlap 				mdb_printf("\n\t\t%s+0x%1x", c,
2513a6d42e7dSPeter Dunlap 				    anr->anr_stack[i] -
2514a6d42e7dSPeter Dunlap 				    (uintptr_t)sym.st_value);
2515a6d42e7dSPeter Dunlap 				++i;
2516a6d42e7dSPeter Dunlap 			}
2517a6d42e7dSPeter Dunlap 			mdb_printf("\n");
2518a6d42e7dSPeter Dunlap 		}
2519a6d42e7dSPeter Dunlap 		anb->anb_index--;
2520a6d42e7dSPeter Dunlap 		anb->anb_index &= anb->anb_max_index;
2521a6d42e7dSPeter Dunlap 		ctr--;
2522a6d42e7dSPeter Dunlap 	}
2523a6d42e7dSPeter Dunlap 
2524a6d42e7dSPeter Dunlap 	return (DCMD_OK);
2525a6d42e7dSPeter Dunlap }
2526a6d42e7dSPeter Dunlap 
2527a6d42e7dSPeter Dunlap static int
iscsi_sm_audit_impl(uintptr_t addr)2528a6d42e7dSPeter Dunlap iscsi_sm_audit_impl(uintptr_t addr)
2529a6d42e7dSPeter Dunlap {
2530a6d42e7dSPeter Dunlap 	sm_audit_buf_t		audit_buf;
2531a6d42e7dSPeter Dunlap 	int			ctr;
2532a6d42e7dSPeter Dunlap 	const char		*event_name;
2533a6d42e7dSPeter Dunlap 	const char		*state_name;
2534a6d42e7dSPeter Dunlap 	const char		*new_state_name;
2535a6d42e7dSPeter Dunlap 	char			ts_string[40];
2536a6d42e7dSPeter Dunlap 	/*
2537a6d42e7dSPeter Dunlap 	 * Print refcnt info
2538a6d42e7dSPeter Dunlap 	 */
2539a6d42e7dSPeter Dunlap 	if (mdb_vread(&audit_buf, sizeof (sm_audit_buf_t), addr) !=
2540a6d42e7dSPeter Dunlap 	    sizeof (sm_audit_buf_t)) {
25415819f75eSPeter Gill 		mdb_warn("failed to read audit buf");
2542a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2543a6d42e7dSPeter Dunlap 	}
2544a6d42e7dSPeter Dunlap 
2545a6d42e7dSPeter Dunlap 	ctr = audit_buf.sab_max_index + 1;
2546a6d42e7dSPeter Dunlap 	audit_buf.sab_index++;
2547a6d42e7dSPeter Dunlap 	audit_buf.sab_index &= audit_buf.sab_max_index;
2548a6d42e7dSPeter Dunlap 
2549a6d42e7dSPeter Dunlap 	while (ctr) {
2550a6d42e7dSPeter Dunlap 		sm_audit_record_t	*sar;
2551a6d42e7dSPeter Dunlap 
2552a6d42e7dSPeter Dunlap 		sar = audit_buf.sab_records + audit_buf.sab_index;
2553a6d42e7dSPeter Dunlap 
2554a6d42e7dSPeter Dunlap 		iscsi_format_timestamp(ts_string, 40, &sar->sar_timestamp);
2555a6d42e7dSPeter Dunlap 
2556a6d42e7dSPeter Dunlap 		switch (sar->sar_type) {
2557a6d42e7dSPeter Dunlap 		case SAR_STATE_EVENT:
2558a6d42e7dSPeter Dunlap 			switch (sar->sar_sm_type) {
2559a6d42e7dSPeter Dunlap 			case SAS_IDM_CONN:
2560a6d42e7dSPeter Dunlap 				state_name =
2561a6d42e7dSPeter Dunlap 				    iscsi_idm_conn_state(sar->sar_state);
2562a6d42e7dSPeter Dunlap 				event_name =
2563a6d42e7dSPeter Dunlap 				    iscsi_idm_conn_event(sar->sar_event);
2564a6d42e7dSPeter Dunlap 				break;
2565a6d42e7dSPeter Dunlap 			case SAS_ISCSIT_TGT:
2566a6d42e7dSPeter Dunlap 				state_name =
2567a6d42e7dSPeter Dunlap 				    iscsi_iscsit_tgt_state(sar->sar_state);
2568a6d42e7dSPeter Dunlap 				event_name =
2569a6d42e7dSPeter Dunlap 				    iscsi_iscsit_tgt_event(sar->sar_event);
2570a6d42e7dSPeter Dunlap 				break;
2571a6d42e7dSPeter Dunlap 			case SAS_ISCSIT_SESS:
2572a6d42e7dSPeter Dunlap 				state_name =
2573a6d42e7dSPeter Dunlap 				    iscsi_iscsit_sess_state(sar->sar_state);
2574a6d42e7dSPeter Dunlap 				event_name =
2575a6d42e7dSPeter Dunlap 				    iscsi_iscsit_sess_event(sar->sar_event);
2576a6d42e7dSPeter Dunlap 				break;
2577a6d42e7dSPeter Dunlap 			case SAS_ISCSIT_LOGIN:
2578a6d42e7dSPeter Dunlap 				state_name =
2579a6d42e7dSPeter Dunlap 				    iscsi_iscsit_login_state(sar->sar_state);
2580a6d42e7dSPeter Dunlap 				event_name =
2581a6d42e7dSPeter Dunlap 				    iscsi_iscsit_login_event(sar->sar_event);
2582a6d42e7dSPeter Dunlap 				break;
258330e7468fSPeter Dunlap 			case SAS_ISCSI_CMD:
258430e7468fSPeter Dunlap 				state_name =
258530e7468fSPeter Dunlap 				    iscsi_iscsi_cmd_state(sar->sar_state);
258630e7468fSPeter Dunlap 				event_name=
258730e7468fSPeter Dunlap 				    iscsi_iscsi_cmd_event(sar->sar_event);
258830e7468fSPeter Dunlap 				break;
258930e7468fSPeter Dunlap 			case SAS_ISCSI_SESS:
259030e7468fSPeter Dunlap 				state_name =
259130e7468fSPeter Dunlap 				    iscsi_iscsi_sess_state(sar->sar_state);
259230e7468fSPeter Dunlap 				event_name=
259330e7468fSPeter Dunlap 				    iscsi_iscsi_sess_event(sar->sar_event);
259430e7468fSPeter Dunlap 				break;
25955f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 			case SAS_ISCSI_CONN:
25965f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 				state_name =
25975f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 				    iscsi_iscsi_conn_state(sar->sar_state);
25985f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 				event_name=
25995f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 				    iscsi_iscsi_conn_event(sar->sar_event);
26005f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 				break;
2601a6d42e7dSPeter Dunlap 			default:
2602a6d42e7dSPeter Dunlap 				state_name = event_name = "N/A";
2603a6d42e7dSPeter Dunlap 				break;
2604a6d42e7dSPeter Dunlap 			}
2605a6d42e7dSPeter Dunlap 			mdb_printf("%s|%s (%d)\n\t%9s %s (%d) %p\n",
2606a6d42e7dSPeter Dunlap 			    ts_string, state_name, sar->sar_state,
2607a6d42e7dSPeter Dunlap 			    "Event", event_name,
2608a6d42e7dSPeter Dunlap 			    sar->sar_event, sar->sar_event_info);
2609a6d42e7dSPeter Dunlap 
2610a6d42e7dSPeter Dunlap 			break;
2611a6d42e7dSPeter Dunlap 		case SAR_STATE_CHANGE:
2612a6d42e7dSPeter Dunlap 			switch (sar->sar_sm_type) {
2613a6d42e7dSPeter Dunlap 			case SAS_IDM_CONN:
2614a6d42e7dSPeter Dunlap 				state_name =
2615a6d42e7dSPeter Dunlap 				    iscsi_idm_conn_state(sar->sar_state);
2616a6d42e7dSPeter Dunlap 				new_state_name =
2617a6d42e7dSPeter Dunlap 				    iscsi_idm_conn_state(sar->sar_new_state);
2618a6d42e7dSPeter Dunlap 				break;
2619a6d42e7dSPeter Dunlap 			case SAS_IDM_TASK:
2620a6d42e7dSPeter Dunlap 				state_name =
2621a6d42e7dSPeter Dunlap 				    iscsi_idm_task_state(sar->sar_state);
2622a6d42e7dSPeter Dunlap 				new_state_name =
2623a6d42e7dSPeter Dunlap 				    iscsi_idm_task_state(sar->sar_new_state);
2624a6d42e7dSPeter Dunlap 				break;
2625a6d42e7dSPeter Dunlap 			case SAS_ISCSIT_TGT:
2626a6d42e7dSPeter Dunlap 				state_name =
2627a6d42e7dSPeter Dunlap 				    iscsi_iscsit_tgt_state(sar->sar_state);
2628a6d42e7dSPeter Dunlap 				new_state_name =
2629a6d42e7dSPeter Dunlap 				    iscsi_iscsit_tgt_state(sar->sar_new_state);
2630a6d42e7dSPeter Dunlap 				break;
2631a6d42e7dSPeter Dunlap 			case SAS_ISCSIT_SESS:
2632a6d42e7dSPeter Dunlap 				state_name =
2633a6d42e7dSPeter Dunlap 				    iscsi_iscsit_sess_state(sar->sar_state);
2634a6d42e7dSPeter Dunlap 				new_state_name =
2635a6d42e7dSPeter Dunlap 				    iscsi_iscsit_sess_state(sar->sar_new_state);
2636a6d42e7dSPeter Dunlap 				break;
2637a6d42e7dSPeter Dunlap 			case SAS_ISCSIT_LOGIN:
2638a6d42e7dSPeter Dunlap 				state_name =
2639a6d42e7dSPeter Dunlap 				    iscsi_iscsit_login_state(sar->sar_state);
2640a6d42e7dSPeter Dunlap 				new_state_name =
2641a6d42e7dSPeter Dunlap 				    iscsi_iscsit_login_state(
2642a6d42e7dSPeter Dunlap 				    sar->sar_new_state);
2643a6d42e7dSPeter Dunlap 				break;
264430e7468fSPeter Dunlap 			case SAS_ISCSI_CMD:
264530e7468fSPeter Dunlap 				state_name =
264630e7468fSPeter Dunlap 				    iscsi_iscsi_cmd_state(sar->sar_state);
264730e7468fSPeter Dunlap 				new_state_name=
264830e7468fSPeter Dunlap 				    iscsi_iscsi_cmd_state(sar->sar_new_state);
264930e7468fSPeter Dunlap 				break;
265030e7468fSPeter Dunlap 			case SAS_ISCSI_SESS:
265130e7468fSPeter Dunlap 				state_name =
265230e7468fSPeter Dunlap 				    iscsi_iscsi_sess_state(sar->sar_state);
265330e7468fSPeter Dunlap 				new_state_name=
265430e7468fSPeter Dunlap 				    iscsi_iscsi_sess_state(sar->sar_new_state);
265530e7468fSPeter Dunlap 				break;
265630e7468fSPeter Dunlap 			case SAS_ISCSI_CONN:
265730e7468fSPeter Dunlap 				state_name =
265830e7468fSPeter Dunlap 				    iscsi_iscsi_conn_state(sar->sar_state);
265930e7468fSPeter Dunlap 				new_state_name=
266030e7468fSPeter Dunlap 				    iscsi_iscsi_conn_state(sar->sar_new_state);
266130e7468fSPeter Dunlap 				break;
266230e7468fSPeter Dunlap 			case SAS_ISCSI_LOGIN:
266330e7468fSPeter Dunlap 				state_name =
266430e7468fSPeter Dunlap 				    iscsi_iscsi_login_state(sar->sar_state);
266530e7468fSPeter Dunlap 				new_state_name=
266630e7468fSPeter Dunlap 				    iscsi_iscsi_login_state(sar->sar_new_state);
266730e7468fSPeter Dunlap 				break;
2668a6d42e7dSPeter Dunlap 			default:
2669a6d42e7dSPeter Dunlap 				break;
2670a6d42e7dSPeter Dunlap 			}
2671a6d42e7dSPeter Dunlap 			mdb_printf("%s|%s (%d)\n\t%9s %s (%d)\n",
2672a6d42e7dSPeter Dunlap 			    ts_string, state_name, sar->sar_state,
2673a6d42e7dSPeter Dunlap 			    "New State", new_state_name, sar->sar_new_state);
2674a6d42e7dSPeter Dunlap 		default:
2675a6d42e7dSPeter Dunlap 			state_name = new_state_name = "N/A";
2676a6d42e7dSPeter Dunlap 			break;
2677a6d42e7dSPeter Dunlap 		}
2678a6d42e7dSPeter Dunlap 
2679a6d42e7dSPeter Dunlap 		audit_buf.sab_index++;
2680a6d42e7dSPeter Dunlap 		audit_buf.sab_index &= audit_buf.sab_max_index;
2681a6d42e7dSPeter Dunlap 		ctr--;
2682a6d42e7dSPeter Dunlap 	}
2683a6d42e7dSPeter Dunlap 
2684a6d42e7dSPeter Dunlap 	return (DCMD_OK);
2685a6d42e7dSPeter Dunlap }
2686a6d42e7dSPeter Dunlap 
2687a6d42e7dSPeter Dunlap static const char *
iscsi_idm_conn_event(unsigned int event)268830e7468fSPeter Dunlap iscsi_idm_conn_event(unsigned int event)
2689a6d42e7dSPeter Dunlap {
269030e7468fSPeter Dunlap 	return ((event < CE_MAX_EVENT) ? idm_ce_name[event] : "N/A");
2691a6d42e7dSPeter Dunlap }
2692a6d42e7dSPeter Dunlap 
2693a6d42e7dSPeter Dunlap static const char *
iscsi_iscsit_tgt_event(unsigned int event)269430e7468fSPeter Dunlap iscsi_iscsit_tgt_event(unsigned int event)
2695a6d42e7dSPeter Dunlap {
269630e7468fSPeter Dunlap 	return ((event < TE_MAX_EVENT) ? iscsit_te_name[event] : "N/A");
2697a6d42e7dSPeter Dunlap }
2698a6d42e7dSPeter Dunlap 
2699a6d42e7dSPeter Dunlap static const char *
iscsi_iscsit_sess_event(unsigned int event)270030e7468fSPeter Dunlap iscsi_iscsit_sess_event(unsigned int event)
2701a6d42e7dSPeter Dunlap {
270230e7468fSPeter Dunlap 	return ((event < SE_MAX_EVENT) ? iscsit_se_name[event] : "N/A");
2703a6d42e7dSPeter Dunlap }
2704a6d42e7dSPeter Dunlap 
2705a6d42e7dSPeter Dunlap static const char *
iscsi_iscsit_login_event(unsigned int event)270630e7468fSPeter Dunlap iscsi_iscsit_login_event(unsigned int event)
2707a6d42e7dSPeter Dunlap {
270830e7468fSPeter Dunlap 	return ((event < ILE_MAX_EVENT) ? iscsit_ile_name[event] : "N/A");
2709a6d42e7dSPeter Dunlap }
2710a6d42e7dSPeter Dunlap 
2711a6d42e7dSPeter Dunlap static const char *
iscsi_iscsi_cmd_event(unsigned int event)271230e7468fSPeter Dunlap iscsi_iscsi_cmd_event(unsigned int event)
2713a6d42e7dSPeter Dunlap {
271430e7468fSPeter Dunlap 	return ((event < ISCSI_CMD_EVENT_MAX) ?
271530e7468fSPeter Dunlap 	    iscsi_cmd_event_names[event] : "N/A");
271630e7468fSPeter Dunlap }
2717a6d42e7dSPeter Dunlap 
271830e7468fSPeter Dunlap static const char *
iscsi_iscsi_sess_event(unsigned int event)271930e7468fSPeter Dunlap iscsi_iscsi_sess_event(unsigned int event)
272030e7468fSPeter Dunlap {
2721a6d42e7dSPeter Dunlap 
272230e7468fSPeter Dunlap 	return ((event < ISCSI_SESS_EVENT_MAX) ?
272330e7468fSPeter Dunlap 	    iscsi_sess_event_names[event] : "N/A");
272430e7468fSPeter Dunlap }
272530e7468fSPeter Dunlap 
272630e7468fSPeter Dunlap static const char *
iscsi_idm_conn_state(unsigned int state)272730e7468fSPeter Dunlap iscsi_idm_conn_state(unsigned int state)
272830e7468fSPeter Dunlap {
272930e7468fSPeter Dunlap 	return ((state < CS_MAX_STATE) ? idm_cs_name[state] : "N/A");
2730a6d42e7dSPeter Dunlap }
2731a6d42e7dSPeter Dunlap 
27325f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States static const char *
iscsi_iscsi_conn_event(unsigned int event)27335f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States iscsi_iscsi_conn_event(unsigned int event)
27345f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States {
27355f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
27365f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	return ((event < CN_MAX) ? idm_cn_strings[event] : "N/A");
27375f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States }
27385f7d09c6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2739a6d42e7dSPeter Dunlap /*ARGSUSED*/
2740a6d42e7dSPeter Dunlap static const char *
iscsi_idm_task_state(unsigned int state)274130e7468fSPeter Dunlap iscsi_idm_task_state(unsigned int state)
2742a6d42e7dSPeter Dunlap {
274330e7468fSPeter Dunlap 	return ("N/A");
2744a6d42e7dSPeter Dunlap }
2745a6d42e7dSPeter Dunlap 
2746a6d42e7dSPeter Dunlap static const char *
iscsi_iscsit_tgt_state(unsigned int state)274730e7468fSPeter Dunlap iscsi_iscsit_tgt_state(unsigned int state)
2748a6d42e7dSPeter Dunlap {
274930e7468fSPeter Dunlap 	return ((state < TS_MAX_STATE) ? iscsit_ts_name[state] : "N/A");
2750a6d42e7dSPeter Dunlap }
2751a6d42e7dSPeter Dunlap 
2752a6d42e7dSPeter Dunlap static const char *
iscsi_iscsit_sess_state(unsigned int state)275330e7468fSPeter Dunlap iscsi_iscsit_sess_state(unsigned int state)
2754a6d42e7dSPeter Dunlap {
275530e7468fSPeter Dunlap 	return ((state < SS_MAX_STATE) ? iscsit_ss_name[state] : "N/A");
2756a6d42e7dSPeter Dunlap }
2757a6d42e7dSPeter Dunlap 
2758a6d42e7dSPeter Dunlap static const char *
iscsi_iscsit_login_state(unsigned int state)275930e7468fSPeter Dunlap iscsi_iscsit_login_state(unsigned int state)
2760a6d42e7dSPeter Dunlap {
276130e7468fSPeter Dunlap 	return ((state < ILS_MAX_STATE) ? iscsit_ils_name[state] : "N/A");
2762a6d42e7dSPeter Dunlap }
2763a6d42e7dSPeter Dunlap 
276430e7468fSPeter Dunlap static const char *
iscsi_iscsi_cmd_state(unsigned int state)276530e7468fSPeter Dunlap iscsi_iscsi_cmd_state(unsigned int state)
276630e7468fSPeter Dunlap {
276730e7468fSPeter Dunlap 	return ((state < ISCSI_CMD_STATE_MAX) ?
276830e7468fSPeter Dunlap 	    iscsi_cmd_state_names[state] : "N/A");
276930e7468fSPeter Dunlap }
277030e7468fSPeter Dunlap 
277130e7468fSPeter Dunlap static const char *
iscsi_iscsi_sess_state(unsigned int state)277230e7468fSPeter Dunlap iscsi_iscsi_sess_state(unsigned int state)
277330e7468fSPeter Dunlap {
277430e7468fSPeter Dunlap 	return ((state < ISCSI_SESS_STATE_MAX) ?
277530e7468fSPeter Dunlap 	    iscsi_sess_state_names[state] : "N/A");
277630e7468fSPeter Dunlap }
277730e7468fSPeter Dunlap 
277830e7468fSPeter Dunlap static const char *
iscsi_iscsi_conn_state(unsigned int state)277930e7468fSPeter Dunlap iscsi_iscsi_conn_state(unsigned int state)
278030e7468fSPeter Dunlap {
278130e7468fSPeter Dunlap 	return ((state < ISCSI_CONN_STATE_MAX) ? iscsi_ics_name[state] : "N/A");
278230e7468fSPeter Dunlap }
278330e7468fSPeter Dunlap 
278430e7468fSPeter Dunlap static const char *
iscsi_iscsi_login_state(unsigned int state)278530e7468fSPeter Dunlap iscsi_iscsi_login_state(unsigned int state)
278630e7468fSPeter Dunlap {
278730e7468fSPeter Dunlap 	return ((state < LOGIN_MAX) ? iscsi_login_state_names[state] : "N/A");
278830e7468fSPeter Dunlap }
2789a6d42e7dSPeter Dunlap 
2790a6d42e7dSPeter Dunlap 
2791a6d42e7dSPeter Dunlap /*
2792a6d42e7dSPeter Dunlap  * Retrieve connection type given a kernel address
2793a6d42e7dSPeter Dunlap  */
2794a6d42e7dSPeter Dunlap static idm_conn_type_t
idm_conn_type(uintptr_t addr)2795a6d42e7dSPeter Dunlap idm_conn_type(uintptr_t addr)
2796a6d42e7dSPeter Dunlap {
2797a6d42e7dSPeter Dunlap 	idm_conn_type_t result = 0; /* Unknown */
2798a6d42e7dSPeter Dunlap 	uintptr_t idm_conn_type_addr;
2799a6d42e7dSPeter Dunlap 
2800a6d42e7dSPeter Dunlap 	idm_conn_type_addr = addr + offsetof(idm_conn_t, ic_conn_type);
2801a6d42e7dSPeter Dunlap 	(void) mdb_vread(&result, sizeof (result), idm_conn_type_addr);
2802a6d42e7dSPeter Dunlap 
2803a6d42e7dSPeter Dunlap 	return (result);
2804a6d42e7dSPeter Dunlap }
2805a6d42e7dSPeter Dunlap 
2806a6d42e7dSPeter Dunlap /*
2807a6d42e7dSPeter Dunlap  * Convert a sockaddr to the string representation, suitable for
2808a6d42e7dSPeter Dunlap  * storing in an nvlist or printing out in a list.
2809a6d42e7dSPeter Dunlap  */
2810a6d42e7dSPeter Dunlap static int
sa_to_str(struct sockaddr_storage * sa,char * buf)2811a6d42e7dSPeter Dunlap sa_to_str(struct sockaddr_storage *sa, char *buf)
2812a6d42e7dSPeter Dunlap {
2813a6d42e7dSPeter Dunlap 	char			pbuf[7];
2814a6d42e7dSPeter Dunlap 	const char		*bufp;
2815a6d42e7dSPeter Dunlap 	struct sockaddr_in	*sin;
2816a6d42e7dSPeter Dunlap 	struct sockaddr_in6	*sin6;
2817a6d42e7dSPeter Dunlap 	uint16_t		port;
2818a6d42e7dSPeter Dunlap 
2819a6d42e7dSPeter Dunlap 	if (!sa || !buf) {
2820a6d42e7dSPeter Dunlap 		return (EINVAL);
2821a6d42e7dSPeter Dunlap 	}
2822a6d42e7dSPeter Dunlap 
2823a6d42e7dSPeter Dunlap 	buf[0] = '\0';
2824a6d42e7dSPeter Dunlap 
2825a6d42e7dSPeter Dunlap 	if (sa->ss_family == AF_INET) {
2826a6d42e7dSPeter Dunlap 		sin = (struct sockaddr_in *)sa;
282730e7468fSPeter Dunlap 		bufp = iscsi_inet_ntop(AF_INET,
2828a6d42e7dSPeter Dunlap 		    (const void *)&(sin->sin_addr.s_addr),
2829a6d42e7dSPeter Dunlap 		    buf, PORTAL_STR_LEN);
2830a6d42e7dSPeter Dunlap 		if (bufp == NULL) {
2831a6d42e7dSPeter Dunlap 			return (-1);
2832a6d42e7dSPeter Dunlap 		}
2833a6d42e7dSPeter Dunlap 		mdb_nhconvert(&port, &sin->sin_port, sizeof (uint16_t));
2834a6d42e7dSPeter Dunlap 	} else if (sa->ss_family == AF_INET6) {
2835a6d42e7dSPeter Dunlap 		strlcat(buf, "[", sizeof (buf));
2836a6d42e7dSPeter Dunlap 		sin6 = (struct sockaddr_in6 *)sa;
283730e7468fSPeter Dunlap 		bufp = iscsi_inet_ntop(AF_INET6,
2838a6d42e7dSPeter Dunlap 		    (const void *)&sin6->sin6_addr.s6_addr,
2839a6d42e7dSPeter Dunlap 		    &buf[1], PORTAL_STR_LEN - 1);
2840a6d42e7dSPeter Dunlap 		if (bufp == NULL) {
2841a6d42e7dSPeter Dunlap 			return (-1);
2842a6d42e7dSPeter Dunlap 		}
2843a6d42e7dSPeter Dunlap 		strlcat(buf, "]", PORTAL_STR_LEN);
2844*c89a15d4SRichard Lowe 		mdb_nhconvert(&port, &sin6->sin6_port, sizeof (uint16_t));
2845a6d42e7dSPeter Dunlap 	} else {
2846a6d42e7dSPeter Dunlap 		return (EINVAL);
2847a6d42e7dSPeter Dunlap 	}
2848a6d42e7dSPeter Dunlap 
2849a6d42e7dSPeter Dunlap 
2850a6d42e7dSPeter Dunlap 	mdb_snprintf(pbuf, sizeof (pbuf), ":%u", port);
2851a6d42e7dSPeter Dunlap 	strlcat(buf, pbuf, PORTAL_STR_LEN);
2852a6d42e7dSPeter Dunlap 
2853a6d42e7dSPeter Dunlap 	return (0);
2854a6d42e7dSPeter Dunlap }
2855a6d42e7dSPeter Dunlap 
2856a6d42e7dSPeter Dunlap 
2857a6d42e7dSPeter Dunlap static void
iscsi_format_timestamp(char * ts_str,int strlen,timespec_t * ts)2858a6d42e7dSPeter Dunlap iscsi_format_timestamp(char *ts_str, int strlen, timespec_t *ts)
2859a6d42e7dSPeter Dunlap {
2860a6d42e7dSPeter Dunlap 	mdb_snprintf(ts_str, strlen, "%Y:%03d:%03d:%03d", ts->tv_sec,
2861a6d42e7dSPeter Dunlap 	    (ts->tv_nsec / 1000000) % 1000, (ts->tv_nsec / 1000) % 1000,
2862a6d42e7dSPeter Dunlap 	    ts->tv_nsec % 1000);
2863a6d42e7dSPeter Dunlap }
2864a6d42e7dSPeter Dunlap 
2865a6d42e7dSPeter Dunlap /*
2866a6d42e7dSPeter Dunlap  * Help information for the iscsi_isns dcmd
2867a6d42e7dSPeter Dunlap  */
2868a6d42e7dSPeter Dunlap static void
iscsi_isns_help(void)2869a6d42e7dSPeter Dunlap iscsi_isns_help(void)
2870a6d42e7dSPeter Dunlap {
2871a6d42e7dSPeter Dunlap 	mdb_printf("iscsi_isns:\n");
2872a6d42e7dSPeter Dunlap 	mdb_inc_indent(4);
2873a6d42e7dSPeter Dunlap 	mdb_printf("-e: Print ESI information\n");
2874a6d42e7dSPeter Dunlap 	mdb_printf("-p: Print portal information\n");
2875a6d42e7dSPeter Dunlap 	mdb_printf("-s: Print iSNS server information\n");
2876a6d42e7dSPeter Dunlap 	mdb_printf("-t: Print target information\n");
2877a6d42e7dSPeter Dunlap 	mdb_printf("-v: Add verbosity to the other options' output\n");
28785819f75eSPeter Gill 	mdb_printf("-R: Add Refcount information to '-t' output\n");
2879a6d42e7dSPeter Dunlap 	mdb_dec_indent(4);
2880a6d42e7dSPeter Dunlap }
2881a6d42e7dSPeter Dunlap 
2882a6d42e7dSPeter Dunlap /* ARGSUSED */
2883a6d42e7dSPeter Dunlap static int
iscsi_isns_esi_cb(uintptr_t addr,const void * walker_data,void * data)2884a6d42e7dSPeter Dunlap iscsi_isns_esi_cb(uintptr_t addr, const void *walker_data, void *data)
2885a6d42e7dSPeter Dunlap {
2886a6d42e7dSPeter Dunlap 	isns_esi_tinfo_t tinfo;
2887a6d42e7dSPeter Dunlap 
2888a6d42e7dSPeter Dunlap 	if (mdb_vread(&tinfo, sizeof (isns_esi_tinfo_t), addr) !=
2889a6d42e7dSPeter Dunlap 	    sizeof (isns_esi_tinfo_t)) {
2890a6d42e7dSPeter Dunlap 		return (WALK_ERR);
2891a6d42e7dSPeter Dunlap 	}
2892a6d42e7dSPeter Dunlap 
2893a6d42e7dSPeter Dunlap 	mdb_printf("ESI thread/thr did : 0x%p / %d\n", tinfo.esi_thread,
2894a6d42e7dSPeter Dunlap 	    tinfo.esi_thread_did);
2895a6d42e7dSPeter Dunlap 	mdb_printf("ESI sonode         : 0x%p\n", tinfo.esi_so);
2896a6d42e7dSPeter Dunlap 	mdb_printf("ESI port           : %d\n", tinfo.esi_port);
2897a6d42e7dSPeter Dunlap 	mdb_printf("ESI thread running : %s\n",
2898a6d42e7dSPeter Dunlap 	    (tinfo.esi_thread_running) ? "Yes" : "No");
2899a6d42e7dSPeter Dunlap 
2900a6d42e7dSPeter Dunlap 	return (WALK_NEXT);
2901a6d42e7dSPeter Dunlap }
2902a6d42e7dSPeter Dunlap 
2903a6d42e7dSPeter Dunlap static int
iscsi_isns_esi(iscsi_dcmd_ctrl_t * idc)2904a6d42e7dSPeter Dunlap iscsi_isns_esi(iscsi_dcmd_ctrl_t *idc)
2905a6d42e7dSPeter Dunlap {
2906a6d42e7dSPeter Dunlap 	GElf_Sym		sym;
2907e42a0851Speter dunlap 	uintptr_t		addr;
2908a6d42e7dSPeter Dunlap 
2909e42a0851Speter dunlap 	if (mdb_lookup_by_name("esi", &sym) == -1) {
2910a6d42e7dSPeter Dunlap 		mdb_warn("failed to find symbol 'esi_list'");
2911a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2912a6d42e7dSPeter Dunlap 	}
2913e42a0851Speter dunlap 	addr = (uintptr_t)sym.st_value;
2914a6d42e7dSPeter Dunlap 
2915a6d42e7dSPeter Dunlap 	idc->idc_header = 1;
2916e42a0851Speter dunlap 	(void) iscsi_isns_esi_cb(addr, NULL, idc);
2917a6d42e7dSPeter Dunlap 
2918a6d42e7dSPeter Dunlap 	return (0);
2919a6d42e7dSPeter Dunlap }
2920a6d42e7dSPeter Dunlap 
2921a6d42e7dSPeter Dunlap /* ARGSUSED */
2922a6d42e7dSPeter Dunlap static int
iscsi_isns_portal_cb(uintptr_t addr,const void * walker_data,void * data)2923a6d42e7dSPeter Dunlap iscsi_isns_portal_cb(uintptr_t addr, const void *walker_data, void *data)
2924a6d42e7dSPeter Dunlap {
2925a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t *idc = (iscsi_dcmd_ctrl_t *)data;
2926bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	isns_portal_t portal;
2927a6d42e7dSPeter Dunlap 	char portal_addr[PORTAL_STR_LEN];
2928a6d42e7dSPeter Dunlap 	struct sockaddr_storage *ss;
2929e42a0851Speter dunlap 	char			ts_string[40];
2930a6d42e7dSPeter Dunlap 
2931bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (mdb_vread(&portal, sizeof (isns_portal_t), addr) !=
2932bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	    sizeof (isns_portal_t)) {
2933a6d42e7dSPeter Dunlap 		return (WALK_ERR);
2934a6d42e7dSPeter Dunlap 	}
2935a6d42e7dSPeter Dunlap 
2936a6d42e7dSPeter Dunlap 	ss = &portal.portal_addr;
2937a6d42e7dSPeter Dunlap 	sa_to_str(ss, portal_addr);
2938a6d42e7dSPeter Dunlap 	mdb_printf("Portal IP address ");
2939a6d42e7dSPeter Dunlap 
2940a6d42e7dSPeter Dunlap 	if (ss->ss_family == AF_INET) {
2941a6d42e7dSPeter Dunlap 		mdb_printf("(v4): %s", portal_addr);
2942a6d42e7dSPeter Dunlap 	} else {
2943a6d42e7dSPeter Dunlap 		mdb_printf("(v6): %s", portal_addr);
2944a6d42e7dSPeter Dunlap 	}
2945a6d42e7dSPeter Dunlap 
2946bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (portal.portal_default == B_TRUE) {
2947a6d42e7dSPeter Dunlap 		mdb_printf(" (Default portal)\n");
2948a6d42e7dSPeter Dunlap 	} else {
2949a6d42e7dSPeter Dunlap 		mdb_printf("\n");
2950a6d42e7dSPeter Dunlap 	}
2951bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (portal.portal_iscsit != NULL) {
29525819f75eSPeter Gill 		mdb_printf("(Part of TPG: 0x%p)\n", portal.portal_iscsit);
2953a6d42e7dSPeter Dunlap 	}
2954a6d42e7dSPeter Dunlap 
2955e42a0851Speter dunlap 	iscsi_format_timestamp(ts_string, 40, &portal.portal_esi_timestamp);
29565819f75eSPeter Gill 	mdb_printf("Portal ESI timestamp: %s\n\n", ts_string);
2957a6d42e7dSPeter Dunlap 
2958bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if ((portal.portal_iscsit != NULL) && (idc->idc_verbose)) {
2959bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_inc_indent(4);
2960bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		iscsi_portal_impl((uintptr_t)portal.portal_iscsit, idc);
2961bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_dec_indent(4);
2962bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	}
2963bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2964bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2965a6d42e7dSPeter Dunlap 	return (WALK_NEXT);
2966a6d42e7dSPeter Dunlap }
2967a6d42e7dSPeter Dunlap 
2968a6d42e7dSPeter Dunlap static int
iscsi_isns_portals(iscsi_dcmd_ctrl_t * idc)2969a6d42e7dSPeter Dunlap iscsi_isns_portals(iscsi_dcmd_ctrl_t *idc)
2970a6d42e7dSPeter Dunlap {
2971a6d42e7dSPeter Dunlap 	GElf_Sym sym;
2972a6d42e7dSPeter Dunlap 	uintptr_t portal_list;
2973a6d42e7dSPeter Dunlap 
2974bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("All Active Portals:\n");
2975bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2976bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (mdb_lookup_by_name("isns_all_portals", &sym) == -1) {
2977bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_warn("failed to find symbol 'isns_all_portals'");
2978a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2979a6d42e7dSPeter Dunlap 	}
2980a6d42e7dSPeter Dunlap 
2981a6d42e7dSPeter Dunlap 	portal_list = (uintptr_t)sym.st_value;
2982a6d42e7dSPeter Dunlap 	idc->idc_header = 1;
2983a6d42e7dSPeter Dunlap 
2984bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (mdb_pwalk("avl", iscsi_isns_portal_cb, idc, portal_list) == -1) {
2985bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_warn("avl walk failed for isns_all_portals");
2986a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
2987a6d42e7dSPeter Dunlap 	}
2988bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("\nPortals from TPGs:\n");
2989bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2990bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (mdb_lookup_by_name("isns_tpg_portals", &sym) == -1) {
2991bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_warn("failed to find symbol 'isns_tpg_portals'");
2992bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		return (DCMD_ERR);
2993bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	}
2994bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2995bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	portal_list = (uintptr_t)sym.st_value;
2996bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	idc->idc_header = 1;
2997bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
2998bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (mdb_pwalk("avl", iscsi_isns_portal_cb, idc, portal_list) == -1) {
2999bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_warn("avl walk failed for isns_tpg_portals");
3000bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		return (DCMD_ERR);
3001bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	}
3002bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
3003a6d42e7dSPeter Dunlap 
3004a6d42e7dSPeter Dunlap 	return (0);
3005a6d42e7dSPeter Dunlap }
3006a6d42e7dSPeter Dunlap 
3007a6d42e7dSPeter Dunlap /* ARGSUSED */
3008a6d42e7dSPeter Dunlap static int
iscsi_isns_targets_cb(uintptr_t addr,const void * walker_data,void * data)3009a6d42e7dSPeter Dunlap iscsi_isns_targets_cb(uintptr_t addr, const void *walker_data, void *data)
3010a6d42e7dSPeter Dunlap {
3011a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t	*idc = (iscsi_dcmd_ctrl_t *)data;
3012a6d42e7dSPeter Dunlap 	isns_target_t		itarget;
3013a6d42e7dSPeter Dunlap 	int			rc = 0;
30145819f75eSPeter Gill 	int			rc_audit = 0;
30155819f75eSPeter Gill 	uintptr_t		rc_addr;
3016a6d42e7dSPeter Dunlap 
3017a6d42e7dSPeter Dunlap 	if (mdb_vread(&itarget, sizeof (isns_target_t), addr) !=
3018a6d42e7dSPeter Dunlap 	    sizeof (isns_target_t)) {
3019a6d42e7dSPeter Dunlap 		return (WALK_ERR);
3020a6d42e7dSPeter Dunlap 	}
3021a6d42e7dSPeter Dunlap 
3022a6d42e7dSPeter Dunlap 	idc->idc_header = 1;
30235819f75eSPeter Gill 	rc_audit = idc->u.child.idc_rc_audit;
3024a6d42e7dSPeter Dunlap 
3025bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Target: %p\n", addr);
3026a6d42e7dSPeter Dunlap 	mdb_inc_indent(4);
3027a6d42e7dSPeter Dunlap 	mdb_printf("Registered: %s\n",
3028a6d42e7dSPeter Dunlap 	    (itarget.target_registered) ? "Yes" : "No");
3029bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Update needed: %s\n",
3030bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	    (itarget.target_update_needed) ? "Yes" : "No");
3031bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Target Info: %p\n", itarget.target_info);
3032a6d42e7dSPeter Dunlap 
30335819f75eSPeter Gill 	/* Prevent target refcounts from showing through this path */
30345819f75eSPeter Gill 	idc->u.child.idc_rc_audit = 0;
3035a6d42e7dSPeter Dunlap 	rc = iscsi_tgt_impl((uintptr_t)itarget.target, idc);
3036a6d42e7dSPeter Dunlap 
30375819f75eSPeter Gill 	idc->u.child.idc_rc_audit = rc_audit;
30385819f75eSPeter Gill 	if (idc->u.child.idc_rc_audit) {
30395819f75eSPeter Gill 		rc_addr = (uintptr_t)itarget.target_info +
30405819f75eSPeter Gill 		    offsetof(isns_target_info_t, ti_refcnt);
30415819f75eSPeter Gill 
30425819f75eSPeter Gill 		mdb_printf("Reference History(isns_target_info ti_refcnt):\n");
30435819f75eSPeter Gill 		if (iscsi_refcnt_impl(rc_addr) != 0) {
30445819f75eSPeter Gill 			return (WALK_ERR);
30455819f75eSPeter Gill 		}
30465819f75eSPeter Gill 	}
30475819f75eSPeter Gill 
3048a6d42e7dSPeter Dunlap 	mdb_dec_indent(4);
3049a6d42e7dSPeter Dunlap 
3050a6d42e7dSPeter Dunlap 	if (rc == DCMD_OK) {
3051a6d42e7dSPeter Dunlap 		return (WALK_NEXT);
3052a6d42e7dSPeter Dunlap 	}
3053a6d42e7dSPeter Dunlap 
3054a6d42e7dSPeter Dunlap 	return (WALK_ERR);
3055a6d42e7dSPeter Dunlap }
3056a6d42e7dSPeter Dunlap 
3057a6d42e7dSPeter Dunlap static int
iscsi_isns_targets(iscsi_dcmd_ctrl_t * idc)3058a6d42e7dSPeter Dunlap iscsi_isns_targets(iscsi_dcmd_ctrl_t *idc)
3059a6d42e7dSPeter Dunlap {
3060a6d42e7dSPeter Dunlap 	GElf_Sym sym;
3061a6d42e7dSPeter Dunlap 	uintptr_t isns_target_list;
3062a6d42e7dSPeter Dunlap 
3063a6d42e7dSPeter Dunlap 	if (mdb_lookup_by_name("isns_target_list", &sym) == -1) {
3064a6d42e7dSPeter Dunlap 		mdb_warn("failed to find symbol 'isns_target_list'");
3065a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
3066a6d42e7dSPeter Dunlap 	}
3067a6d42e7dSPeter Dunlap 
3068a6d42e7dSPeter Dunlap 	isns_target_list = (uintptr_t)sym.st_value;
3069a6d42e7dSPeter Dunlap 	idc->idc_header = 1;
3070a6d42e7dSPeter Dunlap 	idc->u.child.idc_tgt = 1;
3071a6d42e7dSPeter Dunlap 
3072a6d42e7dSPeter Dunlap 	if (mdb_pwalk("avl", iscsi_isns_targets_cb, idc,
3073a6d42e7dSPeter Dunlap 	    isns_target_list) == -1) {
3074a6d42e7dSPeter Dunlap 		mdb_warn("avl walk failed for isns_target_list");
3075a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
3076a6d42e7dSPeter Dunlap 	}
3077a6d42e7dSPeter Dunlap 
3078a6d42e7dSPeter Dunlap 	return (0);
3079a6d42e7dSPeter Dunlap }
3080a6d42e7dSPeter Dunlap 
3081a6d42e7dSPeter Dunlap /* ARGSUSED */
3082a6d42e7dSPeter Dunlap static int
iscsi_isns_servers_cb(uintptr_t addr,const void * walker_data,void * data)3083a6d42e7dSPeter Dunlap iscsi_isns_servers_cb(uintptr_t addr, const void *walker_data, void *data)
3084a6d42e7dSPeter Dunlap {
3085a6d42e7dSPeter Dunlap 	iscsit_isns_svr_t	server;
3086a6d42e7dSPeter Dunlap 	char			server_addr[PORTAL_STR_LEN];
3087a6d42e7dSPeter Dunlap 	struct sockaddr_storage *ss;
3088a6d42e7dSPeter Dunlap 	clock_t			lbolt;
3089bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	iscsi_dcmd_ctrl_t	*idc = (iscsi_dcmd_ctrl_t *)data;
3090bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	uintptr_t		avl_addr;
3091a6d42e7dSPeter Dunlap 
3092a6d42e7dSPeter Dunlap 	if (mdb_vread(&server, sizeof (iscsit_isns_svr_t), addr) !=
3093a6d42e7dSPeter Dunlap 	    sizeof (iscsit_isns_svr_t)) {
3094a6d42e7dSPeter Dunlap 		return (WALK_ERR);
3095a6d42e7dSPeter Dunlap 	}
3096a6d42e7dSPeter Dunlap 
3097d3d50737SRafael Vanoni 	if ((lbolt = (clock_t)mdb_get_lbolt()) == -1)
3098a6d42e7dSPeter Dunlap 		return (WALK_ERR);
3099a6d42e7dSPeter Dunlap 
3100a6d42e7dSPeter Dunlap 	mdb_printf("iSNS server %p:\n", addr);
3101a6d42e7dSPeter Dunlap 	mdb_inc_indent(4);
3102a6d42e7dSPeter Dunlap 	ss = &server.svr_sa;
3103a6d42e7dSPeter Dunlap 	sa_to_str(ss, server_addr);
3104a6d42e7dSPeter Dunlap 
3105a6d42e7dSPeter Dunlap 	mdb_printf("IP address ");
3106a6d42e7dSPeter Dunlap 	if (ss->ss_family == AF_INET) {
3107a6d42e7dSPeter Dunlap 		mdb_printf("(v4): %s\n", server_addr);
3108a6d42e7dSPeter Dunlap 	} else {
3109a6d42e7dSPeter Dunlap 		mdb_printf("(v6): %s\n", server_addr);
3110a6d42e7dSPeter Dunlap 	}
3111a6d42e7dSPeter Dunlap 
3112bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("ESI Interval: %d seconds\n",
3113bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	    server.svr_esi_interval);
3114bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Last message: %d seconds ago\n",
3115a6d42e7dSPeter Dunlap 	    ((lbolt - server.svr_last_msg) / 100));
3116a6d42e7dSPeter Dunlap 	mdb_printf("Client registered: %s\n",
3117a6d42e7dSPeter Dunlap 	    (server.svr_registered) ? "Yes" : "No");
3118bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Retry Count: %d\n",
3119bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	    server.svr_retry_count);
3120bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Targets Changes Pending: %s\n",
3121bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	    (server.svr_targets_changed) ? "Yes" : "No");
3122bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Delete Pending: %s\n",
3123bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	    (server.svr_delete_needed) ? "Yes" : "No");
3124bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	mdb_printf("Replace-All Needed: %s\n",
3125bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	    (server.svr_reset_needed) ? "Yes" : "No");
3126bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
3127bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	if (idc->idc_verbose) {
3128bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		idc->idc_header = 1;
3129bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		idc->u.child.idc_tgt = 1;
3130bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
3131bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_inc_indent(2);
3132bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		avl_addr = addr + offsetof(iscsit_isns_svr_t,
3133bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		    svr_target_list);
3134bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		if (mdb_pwalk("avl", iscsi_isns_targets_cb, idc,
3135bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		    avl_addr) == -1) {
3136bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 			mdb_warn("avl walk failed for svr_target_list");
3137bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 			return (WALK_ERR);
3138bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		}
3139bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 		mdb_dec_indent(2);
3140bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	}
3141bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 
3142a6d42e7dSPeter Dunlap 	mdb_dec_indent(4);
3143a6d42e7dSPeter Dunlap 
3144bdbe8dc6SPeter Cudhea - Sun Microsystems - Burlington, MA United States 	return (WALK_NEXT);
3145a6d42e7dSPeter Dunlap }
3146a6d42e7dSPeter Dunlap 
3147a6d42e7dSPeter Dunlap static int
iscsi_isns_servers(iscsi_dcmd_ctrl_t * idc)3148a6d42e7dSPeter Dunlap iscsi_isns_servers(iscsi_dcmd_ctrl_t *idc)
3149a6d42e7dSPeter Dunlap {
3150a6d42e7dSPeter Dunlap 	uintptr_t	iscsit_global_addr;
3151a6d42e7dSPeter Dunlap 	uintptr_t	list_addr;
3152a6d42e7dSPeter Dunlap 	GElf_Sym	sym;
3153a6d42e7dSPeter Dunlap 
3154a6d42e7dSPeter Dunlap 	if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
3155a6d42e7dSPeter Dunlap 		mdb_warn("failed to find symbol 'iscsit_global'");
3156a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
3157a6d42e7dSPeter Dunlap 	}
3158a6d42e7dSPeter Dunlap 
3159a6d42e7dSPeter Dunlap 	iscsit_global_addr = (uintptr_t)sym.st_value;
3160a6d42e7dSPeter Dunlap 	idc->idc_header = 1;
3161a6d42e7dSPeter Dunlap 	list_addr = iscsit_global_addr +
3162a6d42e7dSPeter Dunlap 	    offsetof(iscsit_global_t, global_isns_cfg.isns_svrs);
3163a6d42e7dSPeter Dunlap 
3164a6d42e7dSPeter Dunlap 	if (mdb_pwalk("list", iscsi_isns_servers_cb, idc, list_addr) == -1) {
3165a6d42e7dSPeter Dunlap 		mdb_warn("list walk failed for iSNS servers");
3166a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
3167a6d42e7dSPeter Dunlap 	}
3168a6d42e7dSPeter Dunlap 
3169a6d42e7dSPeter Dunlap 	return (0);
3170a6d42e7dSPeter Dunlap }
3171a6d42e7dSPeter Dunlap 
3172a6d42e7dSPeter Dunlap /* ARGSUSED */
3173a6d42e7dSPeter Dunlap static int
iscsi_isns(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)3174a6d42e7dSPeter Dunlap iscsi_isns(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3175a6d42e7dSPeter Dunlap {
3176a6d42e7dSPeter Dunlap 	iscsi_dcmd_ctrl_t idc;
3177a6d42e7dSPeter Dunlap 	int portals = 0, esi = 0, targets = 0, verbose = 0, servers = 0;
31785819f75eSPeter Gill 	int rc_audit = 0;
3179a6d42e7dSPeter Dunlap 
3180a6d42e7dSPeter Dunlap 	if (flags & DCMD_ADDRSPEC) {
3181a6d42e7dSPeter Dunlap 		mdb_warn("iscsi_isns is only a global dcmd.");
3182a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
3183a6d42e7dSPeter Dunlap 	}
3184a6d42e7dSPeter Dunlap 
3185a6d42e7dSPeter Dunlap 	bzero(&idc, sizeof (idc));
3186a6d42e7dSPeter Dunlap 	if (mdb_getopts(argc, argv,
3187a6d42e7dSPeter Dunlap 	    'e', MDB_OPT_SETBITS, TRUE, &esi,
3188a6d42e7dSPeter Dunlap 	    'p', MDB_OPT_SETBITS, TRUE, &portals,
3189a6d42e7dSPeter Dunlap 	    's', MDB_OPT_SETBITS, TRUE, &servers,
3190a6d42e7dSPeter Dunlap 	    't', MDB_OPT_SETBITS, TRUE, &targets,
3191a6d42e7dSPeter Dunlap 	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
31925819f75eSPeter Gill 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
3193a6d42e7dSPeter Dunlap 	    NULL) != argc)
3194a6d42e7dSPeter Dunlap 		return (DCMD_USAGE);
3195a6d42e7dSPeter Dunlap 
3196a6d42e7dSPeter Dunlap 	if ((esi + portals + targets + servers) > 1) {
3197a6d42e7dSPeter Dunlap 		mdb_printf("Only one of e, p, s, and t must be provided");
3198a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
3199a6d42e7dSPeter Dunlap 	}
3200a6d42e7dSPeter Dunlap 
3201a6d42e7dSPeter Dunlap 	if ((esi | portals | targets | servers) == 0) {
3202a6d42e7dSPeter Dunlap 		mdb_printf("Exactly one of e, p, s, or t must be provided");
3203a6d42e7dSPeter Dunlap 		return (DCMD_ERR);
3204a6d42e7dSPeter Dunlap 	}
3205a6d42e7dSPeter Dunlap 
3206a6d42e7dSPeter Dunlap 	idc.idc_verbose = verbose;
32075819f75eSPeter Gill 	idc.u.child.idc_rc_audit = rc_audit;
3208a6d42e7dSPeter Dunlap 
3209a6d42e7dSPeter Dunlap 	if (esi) {
3210a6d42e7dSPeter Dunlap 		return (iscsi_isns_esi(&idc));
3211a6d42e7dSPeter Dunlap 	}
3212a6d42e7dSPeter Dunlap 
3213a6d42e7dSPeter Dunlap 	if (portals) {
3214a6d42e7dSPeter Dunlap 		return (iscsi_isns_portals(&idc));
3215a6d42e7dSPeter Dunlap 	}
3216a6d42e7dSPeter Dunlap 
3217a6d42e7dSPeter Dunlap 	if (servers) {
3218a6d42e7dSPeter Dunlap 		return (iscsi_isns_servers(&idc));
3219a6d42e7dSPeter Dunlap 	}
3220a6d42e7dSPeter Dunlap 
3221a6d42e7dSPeter Dunlap 	return (iscsi_isns_targets(&idc));
3222a6d42e7dSPeter Dunlap }
3223a6d42e7dSPeter Dunlap 
32245819f75eSPeter Gill static int
iscsi_ini_sess_walk_init(mdb_walk_state_t * wsp)32255819f75eSPeter Gill iscsi_ini_sess_walk_init(mdb_walk_state_t *wsp) {
32265819f75eSPeter Gill 
32275819f75eSPeter Gill 
32285819f75eSPeter Gill 	if (wsp->walk_addr == NULL) {
32295819f75eSPeter Gill 		mdb_warn("<iscsi_sess_t addr>::walk iscsi_ini_sess");
32305819f75eSPeter Gill 		return (WALK_ERR);
32315819f75eSPeter Gill 	}
32325819f75eSPeter Gill 
32335819f75eSPeter Gill 	wsp->walk_data = mdb_alloc(sizeof (iscsi_sess_t), UM_SLEEP|UM_GC);
32345819f75eSPeter Gill 	if (!wsp->walk_data) {
32355819f75eSPeter Gill 		mdb_warn("iscsi_ini_sess walk failed");
32365819f75eSPeter Gill 		return (WALK_ERR);
32375819f75eSPeter Gill 	}
32385819f75eSPeter Gill 
32395819f75eSPeter Gill 	return (WALK_NEXT);
32405819f75eSPeter Gill }
32415819f75eSPeter Gill 
32425819f75eSPeter Gill static int
iscsi_ini_sess_step(mdb_walk_state_t * wsp)32435819f75eSPeter Gill iscsi_ini_sess_step(mdb_walk_state_t *wsp) {
32445819f75eSPeter Gill 	int status;
32455819f75eSPeter Gill 
32465819f75eSPeter Gill 	if (wsp->walk_addr == NULL) {
32475819f75eSPeter Gill 		return (WALK_DONE);
32485819f75eSPeter Gill 	}
32495819f75eSPeter Gill 
32505819f75eSPeter Gill 	if (mdb_vread(wsp->walk_data, sizeof (iscsi_sess_t), wsp->walk_addr)
32515819f75eSPeter Gill 	    != sizeof (iscsi_sess_t)) {
32525819f75eSPeter Gill 		mdb_warn("failed to read iscsi_sess_t at %p", wsp->walk_addr);
32535819f75eSPeter Gill 		return (WALK_DONE);
32545819f75eSPeter Gill 	}
32555819f75eSPeter Gill 
32565819f75eSPeter Gill 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
32575819f75eSPeter Gill 	    wsp->walk_cbdata);
32585819f75eSPeter Gill 
32595819f75eSPeter Gill 	wsp->walk_addr =
32605819f75eSPeter Gill 	    (uintptr_t)(((iscsi_sess_t *)wsp->walk_data)->sess_next);
32615819f75eSPeter Gill 
32625819f75eSPeter Gill 	return (status);
32635819f75eSPeter Gill }
32645819f75eSPeter Gill 
32655819f75eSPeter Gill static int
iscsi_ini_conn_walk_init(mdb_walk_state_t * wsp)32665819f75eSPeter Gill iscsi_ini_conn_walk_init(mdb_walk_state_t *wsp) {
32675819f75eSPeter Gill 
32685819f75eSPeter Gill 	if (wsp->walk_addr == NULL) {
32695819f75eSPeter Gill 		mdb_warn("<iscsi_conn_t addr>::walk iscsi_ini_conn");
32705819f75eSPeter Gill 		return (WALK_DONE);
32715819f75eSPeter Gill 	}
32725819f75eSPeter Gill 
32735819f75eSPeter Gill 	wsp->walk_data = mdb_alloc(sizeof (iscsi_conn_t), UM_SLEEP|UM_GC);
32745819f75eSPeter Gill 	if (!wsp->walk_data) {
32755819f75eSPeter Gill 		mdb_warn("iscsi_ini_conn walk failed");
32765819f75eSPeter Gill 		return (WALK_ERR);
32775819f75eSPeter Gill 	}
32785819f75eSPeter Gill 
32795819f75eSPeter Gill 	return (WALK_NEXT);
32805819f75eSPeter Gill }
32815819f75eSPeter Gill 
32825819f75eSPeter Gill static int
iscsi_ini_conn_step(mdb_walk_state_t * wsp)32835819f75eSPeter Gill iscsi_ini_conn_step(mdb_walk_state_t *wsp) {
32845819f75eSPeter Gill 	int status;
32855819f75eSPeter Gill 
32865819f75eSPeter Gill 	if (wsp->walk_addr == NULL) {
32875819f75eSPeter Gill 		return (WALK_DONE);
32885819f75eSPeter Gill 	}
32895819f75eSPeter Gill 
32905819f75eSPeter Gill 	if (mdb_vread(wsp->walk_data, sizeof (iscsi_conn_t), wsp->walk_addr)
32915819f75eSPeter Gill 	    != sizeof (iscsi_conn_t)) {
32925819f75eSPeter Gill 		mdb_warn("failed to read iscsi_conn_t at %p", wsp->walk_addr);
32935819f75eSPeter Gill 		return (WALK_DONE);
32945819f75eSPeter Gill 	}
32955819f75eSPeter Gill 
32965819f75eSPeter Gill 
32975819f75eSPeter Gill 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
32985819f75eSPeter Gill 	    wsp->walk_cbdata);
32995819f75eSPeter Gill 
33005819f75eSPeter Gill 	wsp->walk_addr =
33015819f75eSPeter Gill 	    (uintptr_t)(((iscsi_conn_t *)wsp->walk_data)->conn_next);
33025819f75eSPeter Gill 
33035819f75eSPeter Gill 	return (status);
33045819f75eSPeter Gill }
33055819f75eSPeter Gill 
33065819f75eSPeter Gill static int
iscsi_ini_lun_walk_init(mdb_walk_state_t * wsp)33075819f75eSPeter Gill iscsi_ini_lun_walk_init(mdb_walk_state_t *wsp) {
33085819f75eSPeter Gill 
33095819f75eSPeter Gill 	if (wsp->walk_addr == NULL) {
33105819f75eSPeter Gill 		mdb_warn("<iscsi_lun_t addr>::walk iscsi_ini_lun");
33115819f75eSPeter Gill 		return (WALK_DONE);
33125819f75eSPeter Gill 	}
33135819f75eSPeter Gill 
33145819f75eSPeter Gill 	wsp->walk_data = mdb_alloc(sizeof (iscsi_lun_t), UM_SLEEP|UM_GC);
33155819f75eSPeter Gill 	if (!wsp->walk_data) {
33165819f75eSPeter Gill 		return (WALK_ERR);
33175819f75eSPeter Gill 	}
33185819f75eSPeter Gill 
33195819f75eSPeter Gill 	return (WALK_NEXT);
33205819f75eSPeter Gill }
33215819f75eSPeter Gill 
33225819f75eSPeter Gill static int
iscsi_ini_lun_step(mdb_walk_state_t * wsp)33235819f75eSPeter Gill iscsi_ini_lun_step(mdb_walk_state_t *wsp) {
33245819f75eSPeter Gill 	int status;
33255819f75eSPeter Gill 
33265819f75eSPeter Gill 	if (wsp->walk_addr == NULL) {
33275819f75eSPeter Gill 		return (WALK_DONE);
33285819f75eSPeter Gill 	}
33295819f75eSPeter Gill 
33305819f75eSPeter Gill 	if (mdb_vread(wsp->walk_data, sizeof (iscsi_lun_t), wsp->walk_addr)
33315819f75eSPeter Gill 	    != sizeof (iscsi_lun_t)) {
33325819f75eSPeter Gill 		mdb_warn("failed to read iscsi_lun_t at %p", wsp->walk_addr);
33335819f75eSPeter Gill 		return (WALK_DONE);
33345819f75eSPeter Gill 	}
33355819f75eSPeter Gill 
33365819f75eSPeter Gill 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
33375819f75eSPeter Gill 	    wsp->walk_cbdata);
33385819f75eSPeter Gill 
33395819f75eSPeter Gill 	wsp->walk_addr =
33405819f75eSPeter Gill 	    (uintptr_t)(((iscsi_lun_t *)wsp->walk_data)->lun_next);
33415819f75eSPeter Gill 
33425819f75eSPeter Gill 	return (status);
33435819f75eSPeter Gill }
33445819f75eSPeter Gill 
33455819f75eSPeter Gill static int
iscsi_ini_cmd_walk_init(mdb_walk_state_t * wsp)33465819f75eSPeter Gill iscsi_ini_cmd_walk_init(mdb_walk_state_t *wsp) {
33475819f75eSPeter Gill 
33485819f75eSPeter Gill 	if (wsp->walk_addr == NULL) {
33495819f75eSPeter Gill 		mdb_warn("<iscsi_cmd_t addr>::walk iscsi_ini_cmd");
33505819f75eSPeter Gill 		return (WALK_DONE);
33515819f75eSPeter Gill 	}
33525819f75eSPeter Gill 
33535819f75eSPeter Gill 	wsp->walk_data = mdb_alloc(sizeof (iscsi_cmd_t), UM_SLEEP|UM_GC);
33545819f75eSPeter Gill 	if (!wsp->walk_data) {
33555819f75eSPeter Gill 		return (WALK_ERR);
33565819f75eSPeter Gill 	}
33575819f75eSPeter Gill 
33585819f75eSPeter Gill 	return (WALK_NEXT);
33595819f75eSPeter Gill }
33605819f75eSPeter Gill 
33615819f75eSPeter Gill static int
iscsi_ini_cmd_step(mdb_walk_state_t * wsp)33625819f75eSPeter Gill iscsi_ini_cmd_step(mdb_walk_state_t *wsp) {
33635819f75eSPeter Gill 	int status;
33645819f75eSPeter Gill 
33655819f75eSPeter Gill 	if (wsp->walk_addr == NULL) {
33665819f75eSPeter Gill 		return (WALK_DONE);
33675819f75eSPeter Gill 	}
33685819f75eSPeter Gill 
33695819f75eSPeter Gill 	if (mdb_vread(wsp->walk_data, sizeof (iscsi_cmd_t), wsp->walk_addr)
33705819f75eSPeter Gill 	    != sizeof (iscsi_cmd_t)) {
33715819f75eSPeter Gill 		mdb_warn("failed to read iscsi_cmd_t at %p", wsp->walk_addr);
33725819f75eSPeter Gill 		return (WALK_DONE);
33735819f75eSPeter Gill 	}
33745819f75eSPeter Gill 
33755819f75eSPeter Gill 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
33765819f75eSPeter Gill 	    wsp->walk_cbdata);
33775819f75eSPeter Gill 
33785819f75eSPeter Gill 	wsp->walk_addr =
33795819f75eSPeter Gill 	    (uintptr_t)(((iscsi_cmd_t *)wsp->walk_data)->cmd_next);
33805819f75eSPeter Gill 
33815819f75eSPeter Gill 	return (status);
33825819f75eSPeter Gill }
33835819f75eSPeter Gill 
33845819f75eSPeter Gill static int
iscsi_ini_cmd_walk_cb(uintptr_t addr,const void * vcmd,void * vidc)33855819f75eSPeter Gill iscsi_ini_cmd_walk_cb(uintptr_t addr, const void *vcmd,
33865819f75eSPeter Gill     void *vidc) {
33875819f75eSPeter Gill 
33885819f75eSPeter Gill 	const iscsi_cmd_t	*cmd = vcmd;
33895819f75eSPeter Gill 	iscsi_dcmd_ctrl_t	*idc = vidc;
33905819f75eSPeter Gill 	int			rc;
33915819f75eSPeter Gill 
33925819f75eSPeter Gill 	if (cmd == NULL) {
33935819f75eSPeter Gill 		mdb_warn("list walk failed. Null cmd");
33945819f75eSPeter Gill 		return (WALK_ERR);
33955819f75eSPeter Gill 	}
33965819f75eSPeter Gill 
33975819f75eSPeter Gill 	rc = iscsi_print_ini_cmd(addr, cmd, idc);
33985819f75eSPeter Gill 
33995819f75eSPeter Gill 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
34005819f75eSPeter Gill }
34015819f75eSPeter Gill 
34025819f75eSPeter Gill static int
iscsi_ini_hba_walk_init(mdb_walk_state_t * wsp)34035819f75eSPeter Gill iscsi_ini_hba_walk_init(mdb_walk_state_t *wsp) {
34045819f75eSPeter Gill 	uintptr_t state_addr, array_addr;
34055819f75eSPeter Gill 	int array_size;
34065819f75eSPeter Gill 	struct i_ddi_soft_state *ss;
34075819f75eSPeter Gill 	idm_hba_walk_info_t *hwi;
34085819f75eSPeter Gill 
34095819f75eSPeter Gill 
34105819f75eSPeter Gill 	hwi = (idm_hba_walk_info_t *)mdb_zalloc(
34115819f75eSPeter Gill 		sizeof (idm_hba_walk_info_t), UM_SLEEP|UM_GC);
34125819f75eSPeter Gill 
34135819f75eSPeter Gill 	if (!hwi) {
34145819f75eSPeter Gill 		mdb_warn("unable to allocate storage for iscsi_ini_hba walk");
34155819f75eSPeter Gill 		return (WALK_ERR);
34165819f75eSPeter Gill 	}
34175819f75eSPeter Gill 
34185819f75eSPeter Gill 	if (wsp->walk_addr != NULL) {
34195819f75eSPeter Gill 		mdb_warn("iscsi_ini_hba only supports global walk");
34205819f75eSPeter Gill 		return (WALK_ERR);
34215819f75eSPeter Gill 	} else {
34225819f75eSPeter Gill 
34235819f75eSPeter Gill 		/*
34245819f75eSPeter Gill 		 * Read in the array and setup the walk struct.
34255819f75eSPeter Gill 		 */
34265819f75eSPeter Gill 		if (mdb_readvar(&state_addr, "iscsi_state") == -1) {
34275819f75eSPeter Gill 			mdb_warn("state variable iscsi_state not found.\n");
34285819f75eSPeter Gill 			mdb_warn("Is the driver loaded ?\n");
34295819f75eSPeter Gill 			return (WALK_ERR);
34305819f75eSPeter Gill 		}
34315819f75eSPeter Gill 
34325819f75eSPeter Gill 		ss = (struct i_ddi_soft_state *)mdb_alloc(sizeof (*ss),
34335819f75eSPeter Gill 		    UM_SLEEP|UM_GC);
34345819f75eSPeter Gill 		if (mdb_vread(ss, sizeof (*ss), state_addr) != sizeof (*ss)) {
34355819f75eSPeter Gill 			mdb_warn("Cannot read softstate struct "
34365819f75eSPeter Gill 			    "(Invalid pointer?).\n");
34375819f75eSPeter Gill 			return (WALK_ERR);
34385819f75eSPeter Gill 		}
34395819f75eSPeter Gill 
34405819f75eSPeter Gill 		/* Where to get the data */
34415819f75eSPeter Gill 		array_size = ss->n_items * (sizeof (void *));
34425819f75eSPeter Gill 		array_addr = (uintptr_t)ss->array;
34435819f75eSPeter Gill 
34445819f75eSPeter Gill 		/* Where to put the data */
34455819f75eSPeter Gill 		hwi->n_elements = ss->n_items;
34465819f75eSPeter Gill 		hwi->array = mdb_alloc(array_size, UM_SLEEP|UM_GC);
34475819f75eSPeter Gill 		if (!hwi->array) {
34485819f75eSPeter Gill 			mdb_warn("list walk failed");
34495819f75eSPeter Gill 			return (WALK_ERR);
34505819f75eSPeter Gill 		}
34515819f75eSPeter Gill 		if (mdb_vread(hwi->array, array_size, array_addr) !=
34525819f75eSPeter Gill 		    array_size) {
34535819f75eSPeter Gill 			mdb_warn("Corrupted softstate struct.\n");
34545819f75eSPeter Gill 			return (WALK_ERR);
34555819f75eSPeter Gill 		}
34565819f75eSPeter Gill 		hwi->cur_element = 0;
34575819f75eSPeter Gill 		wsp->walk_data =  hwi;
34585819f75eSPeter Gill 	}
34595819f75eSPeter Gill 
34605819f75eSPeter Gill 	return (WALK_NEXT);
34615819f75eSPeter Gill }
34625819f75eSPeter Gill 
34635819f75eSPeter Gill static int
iscsi_ini_hba_step(mdb_walk_state_t * wsp)34645819f75eSPeter Gill iscsi_ini_hba_step(mdb_walk_state_t *wsp) {
34655819f75eSPeter Gill 	int status;
34665819f75eSPeter Gill 	idm_hba_walk_info_t *hwi = (idm_hba_walk_info_t *)wsp->walk_data;
34675819f75eSPeter Gill 
34685819f75eSPeter Gill 	for (; hwi->cur_element < hwi->n_elements; hwi->cur_element++) {
34695819f75eSPeter Gill 		if (hwi->array[hwi->cur_element] != NULL) {
34705819f75eSPeter Gill 			break;
34715819f75eSPeter Gill 		}
34725819f75eSPeter Gill 	}
34735819f75eSPeter Gill 	if (hwi->cur_element >= hwi->n_elements) {
34745819f75eSPeter Gill 		return (WALK_DONE);
34755819f75eSPeter Gill 	}
34765819f75eSPeter Gill 
34775819f75eSPeter Gill 	hwi->data = (iscsi_hba_t *)mdb_alloc(sizeof (iscsi_hba_t),
34785819f75eSPeter Gill 	    UM_SLEEP|UM_GC);
34795819f75eSPeter Gill 	if (mdb_vread(hwi->data, sizeof (iscsi_hba_t),
34805819f75eSPeter Gill 	    (uintptr_t)hwi->array[hwi->cur_element]) != sizeof (iscsi_hba_t)) {
34815819f75eSPeter Gill 		mdb_warn("failed to read iscsi_sess_t at %p", wsp->walk_addr);
34825819f75eSPeter Gill 		return (WALK_DONE);
34835819f75eSPeter Gill 	}
34845819f75eSPeter Gill 
34855819f75eSPeter Gill 
34865819f75eSPeter Gill 	status = wsp->walk_callback((uintptr_t)hwi->array[hwi->cur_element],
34875819f75eSPeter Gill 	    hwi->data, wsp->walk_cbdata);
34885819f75eSPeter Gill 
34895819f75eSPeter Gill 	/* Increment cur_element for next iteration */
34905819f75eSPeter Gill 	hwi->cur_element++;
34915819f75eSPeter Gill 
34925819f75eSPeter Gill 	return (status);
34935819f75eSPeter Gill }
34945819f75eSPeter Gill 
3495a6d42e7dSPeter Dunlap /*
349630e7468fSPeter Dunlap  * iscsi_inet_ntop -- Convert an IPv4 or IPv6 address in binary form into
3497a6d42e7dSPeter Dunlap  * printable form, and return a pointer to that string. Caller should
3498a6d42e7dSPeter Dunlap  * provide a buffer of correct length to store string into.
3499a6d42e7dSPeter Dunlap  * Note: this routine is kernel version of inet_ntop. It has similar
350030e7468fSPeter Dunlap  * format as iscsi_inet_ntop() defined in rfc2553. But it does not do
3501a6d42e7dSPeter Dunlap  * error handling operations exactly as rfc2553 defines. This function
3502a6d42e7dSPeter Dunlap  * is used by kernel inet directory routines only for debugging.
350330e7468fSPeter Dunlap  * This iscsi_inet_ntop() function, does not return NULL if third argument
3504a6d42e7dSPeter Dunlap  * is NULL. The reason is simple that we don't want kernel to panic
3505a6d42e7dSPeter Dunlap  * as the output of this function is directly fed to ip<n>dbg macro.
3506a6d42e7dSPeter Dunlap  * Instead it uses a local buffer for destination address for
3507a6d42e7dSPeter Dunlap  * those calls which purposely pass NULL ptr for the destination
3508a6d42e7dSPeter Dunlap  * buffer. This function is thread-safe when the caller passes a non-
3509a6d42e7dSPeter Dunlap  * null buffer with the third argument.
3510a6d42e7dSPeter Dunlap  */
3511a6d42e7dSPeter Dunlap /* ARGSUSED */
3512a6d42e7dSPeter Dunlap 
3513a6d42e7dSPeter Dunlap #define	OK_16PTR(p)	(!((uintptr_t)(p) & 0x1))
3514a6d42e7dSPeter Dunlap #if defined(__x86)
3515a6d42e7dSPeter Dunlap #define	OK_32PTR(p)	OK_16PTR(p)
3516a6d42e7dSPeter Dunlap #else
3517a6d42e7dSPeter Dunlap #define	OK_32PTR(p)	(!((uintptr_t)(p) & 0x3))
3518a6d42e7dSPeter Dunlap #endif
3519a6d42e7dSPeter Dunlap 
3520a6d42e7dSPeter Dunlap char *
iscsi_inet_ntop(int af,const void * addr,char * buf,int addrlen)352130e7468fSPeter Dunlap iscsi_inet_ntop(int af, const void *addr, char *buf, int addrlen)
3522a6d42e7dSPeter Dunlap {
3523a6d42e7dSPeter Dunlap 	static char local_buf[PORTAL_STR_LEN];
3524a6d42e7dSPeter Dunlap 	static char *err_buf1 = "<badaddr>";
3525a6d42e7dSPeter Dunlap 	static char *err_buf2 = "<badfamily>";
3526a6d42e7dSPeter Dunlap 	in6_addr_t	*v6addr;
3527a6d42e7dSPeter Dunlap 	uchar_t		*v4addr;
3528a6d42e7dSPeter Dunlap 	char		*caddr;
3529a6d42e7dSPeter Dunlap 
3530a6d42e7dSPeter Dunlap 	/*
353130e7468fSPeter Dunlap 	 * We don't allow thread unsafe iscsi_inet_ntop calls, they
3532a6d42e7dSPeter Dunlap 	 * must pass a non-null buffer pointer. For DEBUG mode
3533a6d42e7dSPeter Dunlap 	 * we use the ASSERT() and for non-debug kernel it will
3534a6d42e7dSPeter Dunlap 	 * silently allow it for now. Someday we should remove
3535a6d42e7dSPeter Dunlap 	 * the static buffer from this function.
3536a6d42e7dSPeter Dunlap 	 */
3537a6d42e7dSPeter Dunlap 
3538a6d42e7dSPeter Dunlap 	ASSERT(buf != NULL);
3539a6d42e7dSPeter Dunlap 	if (buf == NULL)
3540a6d42e7dSPeter Dunlap 		buf = local_buf;
3541a6d42e7dSPeter Dunlap 	buf[0] = '\0';
3542a6d42e7dSPeter Dunlap 
3543a6d42e7dSPeter Dunlap 	/* Let user know politely not to send NULL or unaligned addr */
3544a6d42e7dSPeter Dunlap 	if (addr == NULL || !(OK_32PTR(addr))) {
3545a6d42e7dSPeter Dunlap 		return (err_buf1);
3546a6d42e7dSPeter Dunlap 	}
3547a6d42e7dSPeter Dunlap 
3548a6d42e7dSPeter Dunlap 
3549a6d42e7dSPeter Dunlap #define	UC(b)	(((int)b) & 0xff)
3550a6d42e7dSPeter Dunlap 	switch (af) {
3551a6d42e7dSPeter Dunlap 	case AF_INET:
3552a6d42e7dSPeter Dunlap 		ASSERT(addrlen >= INET_ADDRSTRLEN);
3553a6d42e7dSPeter Dunlap 		v4addr = (uchar_t *)addr;
3554a6d42e7dSPeter Dunlap 		(void) mdb_snprintf(buf, INET6_ADDRSTRLEN,
3555a6d42e7dSPeter Dunlap 		    "%03d.%03d.%03d.%03d",
3556a6d42e7dSPeter Dunlap 		    UC(v4addr[0]), UC(v4addr[1]), UC(v4addr[2]), UC(v4addr[3]));
3557a6d42e7dSPeter Dunlap 		return (buf);
3558a6d42e7dSPeter Dunlap 
3559a6d42e7dSPeter Dunlap 	case AF_INET6:
3560a6d42e7dSPeter Dunlap 		ASSERT(addrlen >= INET6_ADDRSTRLEN);
3561a6d42e7dSPeter Dunlap 		v6addr = (in6_addr_t *)addr;
3562a6d42e7dSPeter Dunlap 		if (IN6_IS_ADDR_V4MAPPED(v6addr)) {
3563a6d42e7dSPeter Dunlap 			caddr = (char *)addr;
3564a6d42e7dSPeter Dunlap 			(void) mdb_snprintf(buf, INET6_ADDRSTRLEN,
3565a6d42e7dSPeter Dunlap 			    "::ffff:%d.%d.%d.%d",
3566a6d42e7dSPeter Dunlap 			    UC(caddr[12]), UC(caddr[13]),
3567a6d42e7dSPeter Dunlap 			    UC(caddr[14]), UC(caddr[15]));
3568a6d42e7dSPeter Dunlap 		} else if (IN6_IS_ADDR_V4COMPAT(v6addr)) {
3569a6d42e7dSPeter Dunlap 			caddr = (char *)addr;
3570a6d42e7dSPeter Dunlap 			(void) mdb_snprintf(buf, INET6_ADDRSTRLEN,
3571a6d42e7dSPeter Dunlap 			    "::%d.%d.%d.%d",
3572a6d42e7dSPeter Dunlap 			    UC(caddr[12]), UC(caddr[13]), UC(caddr[14]),
3573a6d42e7dSPeter Dunlap 			    UC(caddr[15]));
3574a6d42e7dSPeter Dunlap 		} else if (IN6_IS_ADDR_UNSPECIFIED(v6addr)) {
3575a6d42e7dSPeter Dunlap 			(void) mdb_snprintf(buf, INET6_ADDRSTRLEN, "::");
3576a6d42e7dSPeter Dunlap 		} else {
3577a6d42e7dSPeter Dunlap 			convert2ascii(buf, v6addr);
3578a6d42e7dSPeter Dunlap 		}
3579a6d42e7dSPeter Dunlap 		return (buf);
3580a6d42e7dSPeter Dunlap 
3581a6d42e7dSPeter Dunlap 	default:
3582a6d42e7dSPeter Dunlap 		return (err_buf2);
3583a6d42e7dSPeter Dunlap 	}
3584a6d42e7dSPeter Dunlap #undef UC
3585a6d42e7dSPeter Dunlap }
3586a6d42e7dSPeter Dunlap 
3587a6d42e7dSPeter Dunlap /*
3588a6d42e7dSPeter Dunlap  *
3589a6d42e7dSPeter Dunlap  * v6 formats supported
3590a6d42e7dSPeter Dunlap  * General format xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
3591a6d42e7dSPeter Dunlap  * The short hand notation :: is used for COMPAT addr
3592a6d42e7dSPeter Dunlap  * Other forms : fe80::xxxx:xxxx:xxxx:xxxx
3593a6d42e7dSPeter Dunlap  */
3594a6d42e7dSPeter Dunlap static void
convert2ascii(char * buf,const in6_addr_t * addr)3595a6d42e7dSPeter Dunlap convert2ascii(char *buf, const in6_addr_t *addr)
3596a6d42e7dSPeter Dunlap {
3597a6d42e7dSPeter Dunlap 	int		hexdigits;
3598a6d42e7dSPeter Dunlap 	int		head_zero = 0;
3599a6d42e7dSPeter Dunlap 	int		tail_zero = 0;
3600a6d42e7dSPeter Dunlap 	/* tempbuf must be big enough to hold ffff:\0 */
3601a6d42e7dSPeter Dunlap 	char		tempbuf[6];
3602a6d42e7dSPeter Dunlap 	char		*ptr;
3603a6d42e7dSPeter Dunlap 	uint16_t	out_addr_component;
3604a6d42e7dSPeter Dunlap 	uint16_t	*addr_component;
3605a6d42e7dSPeter Dunlap 	size_t		len;
3606a6d42e7dSPeter Dunlap 	boolean_t	first = B_FALSE;
3607a6d42e7dSPeter Dunlap 	boolean_t	med_zero = B_FALSE;
3608a6d42e7dSPeter Dunlap 	boolean_t	end_zero = B_FALSE;
3609a6d42e7dSPeter Dunlap 
3610a6d42e7dSPeter Dunlap 	addr_component = (uint16_t *)addr;
3611a6d42e7dSPeter Dunlap 	ptr = buf;
3612a6d42e7dSPeter Dunlap 
3613a6d42e7dSPeter Dunlap 	/* First count if trailing zeroes higher in number */
3614a6d42e7dSPeter Dunlap 	for (hexdigits = 0; hexdigits < 8; hexdigits++) {
3615a6d42e7dSPeter Dunlap 		if (*addr_component == 0) {
3616a6d42e7dSPeter Dunlap 			if (hexdigits < 4)
3617a6d42e7dSPeter Dunlap 				head_zero++;
3618a6d42e7dSPeter Dunlap 			else
3619a6d42e7dSPeter Dunlap 				tail_zero++;
3620a6d42e7dSPeter Dunlap 		}
3621a6d42e7dSPeter Dunlap 		addr_component++;
3622a6d42e7dSPeter Dunlap 	}
3623a6d42e7dSPeter Dunlap 	addr_component = (uint16_t *)addr;
3624a6d42e7dSPeter Dunlap 	if (tail_zero > head_zero && (head_zero + tail_zero) != 7)
3625a6d42e7dSPeter Dunlap 		end_zero = B_TRUE;
3626a6d42e7dSPeter Dunlap 
3627a6d42e7dSPeter Dunlap 	for (hexdigits = 0; hexdigits < 8; hexdigits++) {
3628a6d42e7dSPeter Dunlap 
3629a6d42e7dSPeter Dunlap 		/* if entry is a 0 */
3630a6d42e7dSPeter Dunlap 
3631a6d42e7dSPeter Dunlap 		if (*addr_component == 0) {
3632a6d42e7dSPeter Dunlap 			if (!first && *(addr_component + 1) == 0) {
3633a6d42e7dSPeter Dunlap 				if (end_zero && (hexdigits < 4)) {
3634a6d42e7dSPeter Dunlap 					*ptr++ = '0';
3635a6d42e7dSPeter Dunlap 					*ptr++ = ':';
3636a6d42e7dSPeter Dunlap 				} else {
3637a6d42e7dSPeter Dunlap 					/*
3638a6d42e7dSPeter Dunlap 					 * address starts with 0s ..
3639a6d42e7dSPeter Dunlap 					 * stick in leading ':' of pair
3640a6d42e7dSPeter Dunlap 					 */
3641a6d42e7dSPeter Dunlap 					if (hexdigits == 0)
3642a6d42e7dSPeter Dunlap 						*ptr++ = ':';
3643a6d42e7dSPeter Dunlap 					/* add another */
3644a6d42e7dSPeter Dunlap 					*ptr++ = ':';
3645a6d42e7dSPeter Dunlap 					first = B_TRUE;
3646a6d42e7dSPeter Dunlap 					med_zero = B_TRUE;
3647a6d42e7dSPeter Dunlap 				}
3648a6d42e7dSPeter Dunlap 			} else if (first && med_zero) {
3649a6d42e7dSPeter Dunlap 				if (hexdigits == 7)
3650a6d42e7dSPeter Dunlap 					*ptr++ = ':';
3651a6d42e7dSPeter Dunlap 				addr_component++;
3652a6d42e7dSPeter Dunlap 				continue;
3653a6d42e7dSPeter Dunlap 			} else {
3654a6d42e7dSPeter Dunlap 				*ptr++ = '0';
3655a6d42e7dSPeter Dunlap 				*ptr++ = ':';
3656a6d42e7dSPeter Dunlap 			}
3657a6d42e7dSPeter Dunlap 			addr_component++;
3658a6d42e7dSPeter Dunlap 			continue;
3659a6d42e7dSPeter Dunlap 		}
3660a6d42e7dSPeter Dunlap 		if (med_zero)
3661a6d42e7dSPeter Dunlap 			med_zero = B_FALSE;
3662a6d42e7dSPeter Dunlap 
3663a6d42e7dSPeter Dunlap 		tempbuf[0] = '\0';
3664a6d42e7dSPeter Dunlap 		mdb_nhconvert(&out_addr_component, addr_component,
3665a6d42e7dSPeter Dunlap 		    sizeof (uint16_t));
3666a6d42e7dSPeter Dunlap 		(void) mdb_snprintf(tempbuf, 6, "%x:", out_addr_component);
3667a6d42e7dSPeter Dunlap 		len = strlen(tempbuf);
3668a6d42e7dSPeter Dunlap 		bcopy(tempbuf, ptr, len);
3669a6d42e7dSPeter Dunlap 		ptr = ptr + len;
3670a6d42e7dSPeter Dunlap 		addr_component++;
3671a6d42e7dSPeter Dunlap 	}
3672a6d42e7dSPeter Dunlap 	*--ptr = '\0';
3673a6d42e7dSPeter Dunlap }
3674a6d42e7dSPeter Dunlap 
3675a6d42e7dSPeter Dunlap /*
3676a6d42e7dSPeter Dunlap  * MDB module linkage information:
3677a6d42e7dSPeter Dunlap  *
3678a6d42e7dSPeter Dunlap  * We declare a list of structures describing our dcmds, a list of structures
3679a6d42e7dSPeter Dunlap  * describing our walkers and a function named _mdb_init to return a pointer
3680a6d42e7dSPeter Dunlap  * to our module information.
3681a6d42e7dSPeter Dunlap  */
3682a6d42e7dSPeter Dunlap static const mdb_dcmd_t dcmds[] = {
36835819f75eSPeter Gill 	{   "iscsi_tgt", "[-agscptbSRv]",
3684a6d42e7dSPeter Dunlap 	    "iSCSI target information", iscsi_tgt },
36855819f75eSPeter Gill 	{   "iscsi_tpgt", "[-R]",
36865819f75eSPeter Gill 	    "iSCSI target portal group tag information", iscsi_tpgt },
36875819f75eSPeter Gill 	{   "iscsi_tpg", "[-R]",
3688a6d42e7dSPeter Dunlap 	    "iSCSI target portal group information", iscsi_tpg },
36895819f75eSPeter Gill 	{   "iscsi_sess", "[-ablmtvcSRIT]",
3690a6d42e7dSPeter Dunlap 	    "iSCSI session information", iscsi_sess },
36915819f75eSPeter Gill 	{   "iscsi_conn", "[-abmtvSRIT]",
3692a6d42e7dSPeter Dunlap 	    "iSCSI connection information", iscsi_conn },
3693a6d42e7dSPeter Dunlap 	{   "iscsi_task", "[-bSRv]",
3694a6d42e7dSPeter Dunlap 	    "iSCSI task information", iscsi_task },
3695a6d42e7dSPeter Dunlap 	{   "iscsi_refcnt", "",
36965819f75eSPeter Gill 	    "print audit informtion for idm_refcnt_t", iscsi_refcnt },
3697a6d42e7dSPeter Dunlap 	{   "iscsi_states", "",
36985819f75eSPeter Gill 	    "dump events and state transitions recorded in an\t"
3699a6d42e7dSPeter Dunlap 	    "\t\tidm_sm_audit_t structure", iscsi_states },
37005819f75eSPeter Gill 	{   "iscsi_isns", "[-epstvR]",
37015819f75eSPeter Gill 	    "print iscsit iSNS information", iscsi_isns, iscsi_isns_help },
37025819f75eSPeter Gill 	{   "iscsi_svc", "[-vR]",
37035819f75eSPeter Gill 	    "iSCSI service information", iscsi_svc },
37045819f75eSPeter Gill 	{   "iscsi_portal", "[-R]",
37055819f75eSPeter Gill 	    "iSCSI portal information", iscsi_portal },
37065819f75eSPeter Gill 	{   "iscsi_cmd", "[-S]",
37075819f75eSPeter Gill 	    "iSCSI command information (initiator only)", iscsi_cmd },
3708a6d42e7dSPeter Dunlap 	{ NULL }
3709a6d42e7dSPeter Dunlap };
3710a6d42e7dSPeter Dunlap 
3711a6d42e7dSPeter Dunlap /*
37125819f75eSPeter Gill  * Basic walkers for the initiator linked lists
3713a6d42e7dSPeter Dunlap  */
37145819f75eSPeter Gill static const mdb_walker_t walkers[] = {
37155819f75eSPeter Gill 	{ "iscsi_ini_hba", "global walk of the initiator iscsi_hba_t "
37165819f75eSPeter Gill 	    "list", iscsi_ini_hba_walk_init, iscsi_ini_hba_step, NULL},
37175819f75eSPeter Gill 	{ "iscsi_ini_sess", "walk list of initiator iscsi_sess_t structures",
37185819f75eSPeter Gill 	    iscsi_ini_sess_walk_init, iscsi_ini_sess_step, NULL },
37195819f75eSPeter Gill 	{ "iscsi_ini_conn", "walk list of initiator iscsi_conn_t structures",
37205819f75eSPeter Gill 	    iscsi_ini_conn_walk_init, iscsi_ini_conn_step, NULL },
37215819f75eSPeter Gill 	{ "iscsi_ini_lun", "walk list of initiator iscsi_lun_t structures",
37225819f75eSPeter Gill 	    iscsi_ini_lun_walk_init, iscsi_ini_lun_step, NULL },
37235819f75eSPeter Gill 	{ "iscsi_ini_cmd", "walk list of initiator iscsi_cmd_t structures",
37245819f75eSPeter Gill 	    iscsi_ini_cmd_walk_init, iscsi_ini_cmd_step, NULL },
37255819f75eSPeter Gill 	{ NULL }
37265819f75eSPeter Gill };
3727a6d42e7dSPeter Dunlap 
3728a6d42e7dSPeter Dunlap static const mdb_modinfo_t modinfo = {
37295819f75eSPeter Gill 	MDB_API_VERSION, dcmds, walkers
3730a6d42e7dSPeter Dunlap };
3731a6d42e7dSPeter Dunlap 
3732a6d42e7dSPeter Dunlap const mdb_modinfo_t *
_mdb_init(void)3733a6d42e7dSPeter Dunlap _mdb_init(void)
3734a6d42e7dSPeter Dunlap {
3735a6d42e7dSPeter Dunlap 	return (&modinfo);
3736a6d42e7dSPeter Dunlap }
3737