6895357 Add iscsit mdb walkers and dcmds for portals and services
authorPeter Gill <Peter.Gill@Sun.COM>
Fri, 09 Apr 2010 14:59:31 -0400
changeset 12114 97f31f629b06
parent 12113 87d80888f29c
child 12115 3655f38d3bea
6895357 Add iscsit mdb walkers and dcmds for portals and services 6894764 RFE: RefCnt enchancements for COMSTAR iscsit mdb walker
usr/src/cmd/mdb/common/modules/idm/idm.c
usr/src/cmd/mdb/intel/amd64/idm/Makefile
usr/src/cmd/mdb/intel/ia32/idm/Makefile
usr/src/cmd/mdb/sparc/v9/idm/Makefile
--- a/usr/src/cmd/mdb/common/modules/idm/idm.c	Fri Apr 09 11:20:11 2010 -0700
+++ b/usr/src/cmd/mdb/common/modules/idm/idm.c	Fri Apr 09 14:59:31 2010 -0400
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <mdb/mdb_modapi.h>
@@ -54,6 +53,7 @@
 #include <iscsi.h>
 #include <iscsit.h>
 #include <iscsit_isns.h>
+#include <sys/ib/clients/iser/iser.h>
 
 /*
  * We want to be able to print multiple levels of object hierarchy with a
@@ -66,9 +66,12 @@
  * The session dcmd should allow the printing of all associated tasks for the
  * sessions without printing all the associated connections.  To accomplish
  * this the following structure contains a bit for each object type.  Dcmds
- * should invoked the functions for child objects if any bits are set
+ * should invoke the functions for child objects if any bits are set
  * in iscsi_dcmd_ctrl_t but the functions for the child object should only
- * print data if their associated bit is set.
+ * print data if their associated bit is set. Each object type should print
+ * a header for its first occurrence or if it is being printed as a child
+ * object for the first occurrence under each parent. For the model to follow
+ * see how idc->idc_header is handled in iscsi_sess_impl.
  *
  * Each dcmd should provide an external interface with the standard MDB API
  * and an internal interface that accepts iscsi_dcmd_ctrl_t.  To display
@@ -82,17 +85,20 @@
 		uint32_t	idc_children;
 		struct {
 			uint32_t	idc_tgt:1,
+					idc_tpg:1,
 					idc_tpgt:1,
 					idc_portal:1,
 					idc_sess:1,
 					idc_conn:1,
+					idc_svc:1,
 					idc_print_ip:1,
 					idc_task:1,
 					idc_buffer:1,
 					idc_states:1,
 					idc_rc_audit:1,
 					idc_lun:1,
-					idc_hba:1;
+					idc_hba:1,
+					idc_cmd:1;
 		} child;
 	} u;
 	boolean_t		idc_ini;
@@ -113,8 +119,14 @@
 	uintptr_t		idc_assoc_session;
 } iscsi_dcmd_ctrl_t;
 
+typedef struct idm_hba_walk_info {
+	void	**array;
+	int	n_elements;
+	int	cur_element;
+	void	*data;
+} idm_hba_walk_info_t;
+
 static int iscsi_walk_all_sess(iscsi_dcmd_ctrl_t *idc);
-static int iscsi_walk_ini_sessions(uintptr_t array_addr);
 static int iscsi_walk_all_conn(iscsi_dcmd_ctrl_t *idc);
 static int iscsi_tgt_walk_cb(uintptr_t addr, const void *list_walker_data,
     void *idc_void);
@@ -130,6 +142,18 @@
     void *idc_void);
 static int iscsi_buffer_walk_cb(uintptr_t addr, const void *list_walker_data,
     void *idc_void);
+static int iscsi_svc_walk_cb(uintptr_t addr, const void *list_walker_data,
+    void *idc_void);
+static int iscsi_ini_hba_walk_cb(uintptr_t addr, const void *vhba,
+    void *idc_void);
+static int iscsi_ini_sess_walk_cb(uintptr_t addr, const void *vsess,
+    void *idc);
+static int iscsi_ini_conn_walk_cb(uintptr_t addr, const void *vconn,
+    void *idc_void);
+static int iscsi_ini_lun_walk_cb(uintptr_t addr, const void *vlun,
+    void *idc_void);
+static int iscsi_ini_cmd_walk_cb(uintptr_t addr, const void *vcmd,
+    void *idc);
 static int iscsi_tgt_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
 static int iscsi_tpgt_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
 static int iscsi_tpg_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
@@ -137,6 +161,7 @@
 static int iscsi_sess_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
 static int iscsi_conn_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
 static void iscsi_print_iscsit_conn_data(idm_conn_t *ict);
+static void iscsi_print_ini_conn_data(idm_conn_t *ict);
 static void iscsi_print_idm_conn_data(idm_conn_t *ict);
 static int iscsi_task_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
 static void iscsi_print_iscsit_task_data(idm_task_t *idt);
@@ -148,7 +173,22 @@
 static int iscsi_sm_audit_impl(uintptr_t addr);
 static int iscsi_isns(uintptr_t addr, uint_t flags, int argc,
     const mdb_arg_t *argv);
-
+static int iscsi_svc_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
+static int iscsi_ini_hba_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
+static int iscsi_print_ini_sess(uintptr_t addr, iscsi_sess_t *sess,
+    iscsi_dcmd_ctrl_t *idc);
+static int iscsi_print_ini_lun(uintptr_t addr, const iscsi_lun_t *lun,
+    iscsi_dcmd_ctrl_t *idc);
+static int iscsi_print_ini_cmd(uintptr_t addr, const iscsi_cmd_t *cmd,
+    iscsi_dcmd_ctrl_t *idc);
+static int iscsi_ini_sess_walk_init(mdb_walk_state_t *wsp);
+static int iscsi_ini_sess_step(mdb_walk_state_t *wsp);
+static int iscsi_ini_conn_walk_init(mdb_walk_state_t *wsp);
+static int iscsi_ini_conn_step(mdb_walk_state_t *wsp);
+static int iscsi_ini_lun_walk_init(mdb_walk_state_t *wsp);
+static int iscsi_ini_lun_step(mdb_walk_state_t *wsp);
+static int iscsi_ini_cmd_walk_init(mdb_walk_state_t *wsp);
+static int iscsi_ini_cmd_step(mdb_walk_state_t *wsp);
 static const char *iscsi_idm_conn_event(unsigned int event);
 static const char *iscsi_iscsit_tgt_event(unsigned int event);
 static const char *iscsi_iscsit_sess_event(unsigned int event);
@@ -258,10 +298,8 @@
 			return (DCMD_ERR);
 		}
 		return (DCMD_OK);
-	} else {
-		return (iscsi_tgt_impl(addr, &idc));
 	}
-	/*NOTREACHED*/
+	return (iscsi_tgt_impl(addr, &idc));
 }
 
 static int
@@ -270,14 +308,18 @@
 	iscsi_dcmd_ctrl_t	idc;
 	uintptr_t		iscsit_global_addr, avl_addr;
 	GElf_Sym		sym;
+	int			rc_audit = 0;
 
 	bzero(&idc, sizeof (idc));
 	if (mdb_getopts(argc, argv,
-	    'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
+	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
 	    NULL) != argc)
 		return (DCMD_USAGE);
 
-	idc.u.child.idc_portal = 1; /* Always print portals */
+	/* Always print tpgs and portals */
+	idc.u.child.idc_tpg = 1;
+	idc.u.child.idc_portal = 1;
+	idc.u.child.idc_rc_audit = rc_audit;
 	if (DCMD_HDRSPEC(flags))
 		idc.idc_header = 1;
 
@@ -298,14 +340,68 @@
 			return (DCMD_ERR);
 		}
 		return (DCMD_OK);
-	} else {
-		return (iscsi_tpg_impl(addr, &idc));
 	}
-	/*NOTREACHED*/
+	return (iscsi_tpg_impl(addr, &idc));
 }
 
 /*
- * ::iscsi_sess [-bctvIT]
+ * ::iscsi_tpgt [-pR]
+ *
+ * Print tpgt information.
+ * R	Print reference count audit data
+ * p	Print portal data
+ */
+static int
+iscsi_tpgt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	iscsi_dcmd_ctrl_t	idc;
+	uintptr_t		iscsit_global_addr, avl_addr, list_addr;
+	GElf_Sym		sym;
+	int			rc_audit = 0, portal = 0;
+
+	bzero(&idc, sizeof (idc));
+	if (mdb_getopts(argc, argv,
+	    'p', MDB_OPT_SETBITS, TRUE, &portal,
+	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
+	    NULL) != argc)
+		return (DCMD_USAGE);
+
+	idc.u.child.idc_tpgt = 1;
+	idc.u.child.idc_portal = portal;
+	idc.u.child.idc_rc_audit = rc_audit;
+	if (DCMD_HDRSPEC(flags))
+		idc.idc_header = 1;
+
+	/*
+	 * If no address was specified on the command line,
+	 * print out all tpgts
+	 */
+	if (!(flags & DCMD_ADDRSPEC)) {
+		if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
+			mdb_warn("failed to find symbol 'iscsit_global'");
+			return (DCMD_ERR);
+		}
+		iscsit_global_addr = (uintptr_t)sym.st_value;
+		avl_addr = iscsit_global_addr +
+		    offsetof(iscsit_global_t, global_target_list);
+		if (mdb_pwalk("avl", iscsi_tgt_walk_cb, &idc, avl_addr) == -1) {
+			mdb_warn("avl walk failed for global target tree");
+			return (DCMD_ERR);
+		}
+		list_addr = iscsit_global_addr +
+		    offsetof(iscsit_global_t, global_deleted_target_list);
+		if (mdb_pwalk("list", iscsi_tgt_walk_cb,
+		    &idc, list_addr) == -1) {
+			mdb_warn("list walk failed for deleted target list");
+			return (DCMD_ERR);
+		}
+		return (DCMD_OK);
+	}
+	return (iscsi_tpgt_impl(addr, &idc));
+}
+
+/*
+ * ::iscsi_sess [-ablmtvcSRIT]
  *
  * iscsi_sess - Print out information associated with an iSCSI session
  *
@@ -314,6 +410,8 @@
  * c	Print associated connection information
  * a	Print IP addresses with connection information
  * t	Print associated task information
+ * l	Print associated lun information (with -I)
+ * m	Print associated initiator command information (with -I)
  * b	Print associated buffer information
  * S	Print recent state events and transitions
  * R	Print reference count audit data
@@ -325,7 +423,8 @@
 {
 	iscsi_dcmd_ctrl_t	idc;
 	int			buffer = 0, task = 0, conn = 0, print_ip = 0;
-	int			states = 0, rc_audit = 0;
+	int			states = 0, rc_audit = 0, commands = 0;
+	int			luns = 0;
 
 	bzero(&idc, sizeof (idc));
 	if (mdb_getopts(argc, argv,
@@ -334,6 +433,8 @@
 	    'a', MDB_OPT_SETBITS, TRUE, &print_ip,
 	    'c', MDB_OPT_SETBITS, TRUE, &conn,
 	    't', MDB_OPT_SETBITS, TRUE, &task,
+	    'l', MDB_OPT_SETBITS, TRUE, &luns,
+	    'm', MDB_OPT_SETBITS, TRUE, &commands,
 	    'b', MDB_OPT_SETBITS, TRUE, &buffer,
 	    'S', MDB_OPT_SETBITS, TRUE, &states,
 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
@@ -345,6 +446,8 @@
 	idc.u.child.idc_print_ip = print_ip;
 	idc.u.child.idc_conn = conn;
 	idc.u.child.idc_task = task;
+	idc.u.child.idc_cmd = commands;
+	idc.u.child.idc_lun = luns;
 	idc.u.child.idc_buffer = buffer;
 	idc.u.child.idc_states = states;
 	idc.u.child.idc_rc_audit = rc_audit;
@@ -357,16 +460,14 @@
 	 */
 	if (!(flags & DCMD_ADDRSPEC)) {
 		return (iscsi_walk_all_sess(&idc));
-	} else {
-		return (iscsi_sess_impl(addr, &idc));
 	}
-	/*NOTREACHED*/
+	return (iscsi_sess_impl(addr, &idc));
 }
 
 
 
 /*
- * ::iscsi_conn [-btvIT]
+ * ::iscsi_conn [-abmtvSRIT]
  *
  * iscsi_conn - Print out information associated with an iSCSI connection
  *
@@ -375,6 +476,7 @@
  * a	Print IP addresses with connection information
  * t	Print associated task information
  * b	Print associated buffer information
+ * m	Print associated initiator commands (with -I)
  * S	Print recent state events and transitions
  * R	Print reference count audit data
  * v	Verbose output about the connection
@@ -385,7 +487,7 @@
 {
 	iscsi_dcmd_ctrl_t	idc;
 	int			buffer = 0, task = 0, print_ip = 0;
-	int			states = 0, rc_audit = 0;
+	int			states = 0, rc_audit = 0, commands = 0;
 
 	bzero(&idc, sizeof (idc));
 	if (mdb_getopts(argc, argv,
@@ -394,6 +496,7 @@
 	    'a', MDB_OPT_SETBITS, TRUE, &print_ip,
 	    't', MDB_OPT_SETBITS, TRUE, &task,
 	    'b', MDB_OPT_SETBITS, TRUE, &buffer,
+	    'm', MDB_OPT_SETBITS, TRUE, &commands,
 	    'S', MDB_OPT_SETBITS, TRUE, &states,
 	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
 	    'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
@@ -404,6 +507,7 @@
 	idc.u.child.idc_print_ip = print_ip;
 	idc.u.child.idc_task = task;
 	idc.u.child.idc_buffer = buffer;
+	idc.u.child.idc_cmd = commands;
 	idc.u.child.idc_states = states;
 	idc.u.child.idc_rc_audit = rc_audit;
 	if (DCMD_HDRSPEC(flags))
@@ -415,10 +519,188 @@
 	 */
 	if (!(flags & DCMD_ADDRSPEC)) {
 		return (iscsi_walk_all_conn(&idc));
+	}
+	return (iscsi_conn_impl(addr, &idc));
+}
+
+
+/*
+ * ::iscsi_svc [-vR]
+ *
+ * iscsi_svc - Print out information associated with an iSCSI svc
+ *
+ * R	Print reference count audit data
+ * v	Verbose output about the service
+ */
+static int
+iscsi_svc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	iscsi_dcmd_ctrl_t	idc;
+	GElf_Sym		sym;
+	uintptr_t		idm_addr;
+	uintptr_t		svc_list_addr;
+	int			rc_audit = 0;
+
+	bzero(&idc, sizeof (iscsi_dcmd_ctrl_t));
+
+	if (mdb_getopts(argc, argv,
+	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
+	    'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
+	    NULL) != argc)
+		return (DCMD_USAGE);
+
+	idc.u.child.idc_svc = 1;
+	idc.u.child.idc_rc_audit = rc_audit;
+	if (DCMD_HDRSPEC(flags)) {
+		idc.idc_header = 1;
+	}
+
+	if (!(flags & DCMD_ADDRSPEC)) {
+		if (mdb_lookup_by_name("idm", &sym) == -1) {
+			mdb_warn("failed to find symbol 'idm'");
+			return (DCMD_ERR);
+		}
+		idm_addr = (uintptr_t)sym.st_value;
+		svc_list_addr = idm_addr + offsetof(idm_global_t,
+		    idm_tgt_svc_list);
+
+		if (mdb_pwalk("list", iscsi_svc_walk_cb, &idc,
+		    svc_list_addr) == -1) {
+			mdb_warn("list walk failed for idm services");
+			return (DCMD_ERR);
+		}
+		return (DCMD_OK);
+	}
+	return (iscsi_svc_impl(addr, &idc));
+}
+
+/*
+ * ::iscsi_portal -R
+ *
+ * iscsi_portal - Print out information associated with an iSCSI portal
+ *
+ * R	Print reference count audit data
+ */
+static int
+iscsi_portal(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	iscsi_dcmd_ctrl_t	idc;
+	GElf_Sym		sym;
+	iscsit_global_t		iscsit_global;
+	uintptr_t		iscsit_global_addr;
+	uintptr_t		tpg_avl_addr;
+	int			rc_audit = 0;
+
+	bzero(&idc, sizeof (iscsi_dcmd_ctrl_t));
+
+	if (mdb_getopts(argc, argv,
+	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
+	    NULL) != argc)
+		return (DCMD_USAGE);
+
+	idc.u.child.idc_rc_audit = rc_audit;
+	idc.u.child.idc_portal = 1;
+	if (DCMD_HDRSPEC(flags)) {
+		idc.idc_header = 1;
+	}
+
+	if (!(flags & DCMD_ADDRSPEC)) {
+		if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
+			mdb_warn("failed to find symbol 'iscsit_global'");
+			return (DCMD_ERR);
+		}
+
+		iscsit_global_addr = (uintptr_t)sym.st_value;
+
+		/* get and print the global default tpg */
+		if (mdb_vread(&iscsit_global, sizeof (iscsit_global_t),
+		    iscsit_global_addr) != sizeof (iscsit_global_t)) {
+			mdb_warn("failed to read iscsit_global_t");
+			return (DCMD_ERR);
+		}
+		if (iscsi_tpg_impl((uintptr_t)iscsit_global.global_default_tpg,
+		    &idc) != DCMD_OK) {
+			return (DCMD_ERR);
+		}
+
+		/* Walk the tpgs for the rest of the portals */
+		tpg_avl_addr = iscsit_global_addr + offsetof(iscsit_global_t,
+		    global_tpg_list);
+		if (mdb_pwalk("avl", iscsi_tpg_walk_cb, &idc,
+		    tpg_avl_addr) == -1) {
+			mdb_warn("list walk failed for global tpg tree");
+			return (DCMD_ERR);
+		}
+		return (DCMD_OK);
+	}
+	return (iscsi_portal_impl(addr, &idc));
+}
+
+
+/*
+ * ::iscsi_cmd -S
+ *
+ * iscsi_cmd - Print out information associated with an iSCSI cmd
+ *
+ * S	Print state audit data
+ */
+static int
+iscsi_cmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	iscsi_dcmd_ctrl_t	idc;
+	iscsi_cmd_t		cmd;
+	int			states = 0;
+
+	bzero(&idc, sizeof (iscsi_dcmd_ctrl_t));
+
+	if (mdb_getopts(argc, argv,
+	    'S', MDB_OPT_SETBITS, TRUE, &states,
+	    NULL) != argc)
+		return (DCMD_USAGE);
+
+	idc.u.child.idc_states = states;
+	idc.u.child.idc_cmd = 1;
+	idc.idc_ini = 1;
+	if (DCMD_HDRSPEC(flags)) {
+		idc.idc_header = 1;
+	}
+
+	if (!(flags & DCMD_ADDRSPEC)) {
+		if (mdb_pwalk("iscsi_ini_hba", iscsi_ini_hba_walk_cb,
+		    &idc, NULL) == -1) {
+			mdb_warn("iscsi cmd hba list walk failed");
+			return (DCMD_ERR);
+		}
 	} else {
-		return (iscsi_conn_impl(addr, &idc));
+		if (mdb_vread(&cmd, sizeof (iscsi_cmd_t), addr) !=
+		    sizeof (iscsi_cmd_t)) {
+			return (DCMD_ERR);
+		}
+		return (iscsi_print_ini_cmd(addr, &cmd, &idc));
 	}
-	/*NOTREACHED*/
+	return (DCMD_OK);
+}
+
+
+static int
+iscsi_ini_hba_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc) {
+	iscsi_hba_t ih;
+
+	if (mdb_vread(&ih, sizeof (ih), addr) != sizeof (ih)) {
+		mdb_warn("Invalid HBA\n");
+		return (DCMD_ERR);
+	}
+
+	if (idc->u.child.idc_hba) {
+		mdb_printf("iscsi_hba %p sessions: \n", addr);
+	}
+
+	if (mdb_pwalk("iscsi_ini_sess", iscsi_ini_sess_walk_cb, idc,
+	    (uintptr_t)ih.hba_sess_list) == -1) {
+		mdb_warn("iscsi_sess_t walk failed");
+		return (DCMD_ERR);
+	}
+	return (DCMD_OK);
 }
 
 /*
@@ -462,10 +744,8 @@
 	 */
 	if (!(flags & DCMD_ADDRSPEC)) {
 		return (iscsi_walk_all_conn(&idc));
-	} else {
-		return (iscsi_task_impl(addr, &idc));
 	}
-	/*NOTREACHED*/
+	return (iscsi_task_impl(addr, &idc));
 }
 
 /*
@@ -480,10 +760,8 @@
 {
 	if (!(flags & DCMD_ADDRSPEC)) {
 		return (DCMD_ERR);
-	} else {
-		return (iscsi_refcnt_impl(addr));
 	}
-	/*NOTREACHED*/
+	return (iscsi_refcnt_impl(addr));
 }
 
 /*
@@ -499,64 +777,10 @@
 {
 	if (!(flags & DCMD_ADDRSPEC)) {
 		return (DCMD_ERR);
-	} else {
-		return (iscsi_sm_audit_impl(addr));
 	}
-	/*NOTREACHED*/
+	return (iscsi_sm_audit_impl(addr));
 }
 
-/*
- * Helper function to list all the initiator sessions
- */
-static int
-iscsi_walk_ini_sessions(uintptr_t array_vaddr)
-{
-	iscsi_hba_t ihp;
-	int i;
-	int array_size;
-	struct i_ddi_soft_state *ss;
-	iscsi_sess_t *isp;
-
-	ss = (struct i_ddi_soft_state *)mdb_alloc(sizeof (*ss),
-	    UM_SLEEP|UM_GC);
-	if (mdb_vread(ss, sizeof (*ss), array_vaddr) != sizeof (*ss)) {
-		mdb_warn("Cannot read softstate struct (Invalid pointer?).\n");
-		return (DCMD_ERR);
-	}
-	array_size = ss->n_items * (sizeof (void *));
-	array_vaddr = (uintptr_t)ss->array;
-	ss->array = mdb_alloc(array_size, UM_SLEEP|UM_GC);
-	if (mdb_vread(ss->array, array_size, array_vaddr) != array_size) {
-		mdb_warn("Corrupted softstate struct.\n");
-		return (DCMD_ERR);
-	}
-	for (i = 0; i < ss->n_items; i++) {
-		if (ss->array[i] == 0)
-		continue;
-
-		if (mdb_vread(&ihp, sizeof (ihp), (uintptr_t)ss->array[i])
-		    != sizeof (ihp)) {
-			mdb_warn("Corrupted softstate struct.\n");
-			return (DCMD_ERR);
-		}
-		mdb_printf("iscsi_hba %p sessions: \n", ihp);
-		mdb_printf("%<u>%-19s %-4s  %-8s%</u>\n",
-		    "Session", "Type", "State");
-		for (isp = ihp.hba_sess_list; isp; ) {
-			iscsi_sess_t sess;
-			if ((mdb_vread(&sess, sizeof (iscsi_sess_t),
-			    (uintptr_t)isp)) != sizeof (iscsi_sess_t)) {
-				mdb_warn("Failed to read session\n");
-				return (DCMD_ERR);
-			}
-			mdb_printf("%-19p %-4d %-8d\n", isp,
-			    sess.sess_type,
-			    sess.sess_state);
-			isp = sess.sess_next;
-		}
-	}
-	return (DCMD_OK);
-}
 
 static int
 iscsi_walk_all_sess(iscsi_dcmd_ctrl_t *idc)
@@ -565,17 +789,19 @@
 	uintptr_t	avl_addr;
 	uintptr_t	list_addr;
 	GElf_Sym	sym;
-	uintptr_t adr;
+
 	/* Initiator sessions */
 	if (idc->idc_ini) {
-		if (mdb_readvar(&adr, "iscsi_state") == -1) {
-
-			mdb_warn("state variable iscsi_state not found.\n");
-			mdb_warn("Is the driver loaded ?\n");
+		/* Always print hba info on this path */
+		idc->u.child.idc_hba = 1;
+		if (mdb_pwalk("iscsi_ini_hba", iscsi_ini_hba_walk_cb,
+		    idc, NULL) == -1) {
+			mdb_warn("iscsi cmd hba list walk failed");
 			return (DCMD_ERR);
 		}
-		return (iscsi_walk_ini_sessions(adr));
+		return (DCMD_OK);
 	}
+
 	/* Target sessions */
 	/* Walk discovery sessions */
 	if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
@@ -762,6 +988,84 @@
 	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
 }
 
+/*ARGSUSED*/
+static int
+iscsi_svc_walk_cb(uintptr_t addr, const void *list_walker_data,
+    void *idc_void)
+{
+	iscsi_dcmd_ctrl_t	*idc = idc_void;
+	int			rc;
+
+	rc = iscsi_svc_impl(addr, idc);
+
+	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
+}
+
+/*ARGSUSED*/
+static int
+iscsi_ini_hba_walk_cb(uintptr_t addr, const void *vhba,
+    void *idc_void) {
+
+	iscsi_dcmd_ctrl_t	*idc = idc_void;
+	int			rc;
+
+	rc = iscsi_ini_hba_impl(addr, idc);
+
+	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
+}
+
+static int
+iscsi_ini_sess_walk_cb(uintptr_t addr, const void *vsess, void *idc_void)
+{
+	int rc;
+
+	if (vsess == NULL) {
+		return (WALK_ERR);
+	}
+
+	rc = iscsi_print_ini_sess(addr, (iscsi_sess_t *)vsess,
+	    (iscsi_dcmd_ctrl_t *)idc_void);
+
+	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
+}
+
+/*ARGSUSED*/
+static int
+iscsi_ini_conn_walk_cb(uintptr_t addr, const void *vconn, void *idc_void)
+{
+	const iscsi_conn_t	*ict = vconn;
+	int			rc;
+
+	if (vconn == NULL) {
+		return (WALK_ERR);
+	}
+
+	/*
+	 * Look up the idm_conn_t in the iscsi_conn_t and call the general
+	 * connection handler.
+	 */
+	rc = iscsi_conn_impl((uintptr_t)ict->conn_ic,
+	    (iscsi_dcmd_ctrl_t *)idc_void);
+
+	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
+}
+
+static int
+iscsi_ini_lun_walk_cb(uintptr_t addr, const void *vlun, void *idc_void)
+{
+	int			rc;
+
+	if (vlun == NULL) {
+		return (WALK_ERR);
+	}
+
+	rc = iscsi_print_ini_lun(addr, (iscsi_lun_t *)vlun,
+	    (iscsi_dcmd_ctrl_t *)idc_void);
+
+	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
+}
+
+
 static int
 iscsi_tgt_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
 {
@@ -811,53 +1115,51 @@
 		    tgt.target_sess_list.avl_numnodes,
 		    tgt.target_state);
 		mdb_printf("  %s\n", tgt_name);
+
+		/* Indent and disable verbose for any child structures */
+		mdb_inc_indent(4);
+		idc->idc_verbose = 0;
 	}
 
-	idc->idc_header = 0;
-	idc->idc_verbose = 0;
-
 	/*
 	 * Print states if requested
 	 */
 	if (idc->u.child.idc_tgt && states) {
 		states_addr = addr + offsetof(iscsit_tgt_t, target_state_audit);
 
-		(void) mdb_inc_indent(4);
-		mdb_printf("State History:\n");
+		mdb_printf("State History(target_state_audit):\n");
 		if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
 			return (DCMD_ERR);
 		idc->u.child.idc_states = 0;
-		(void) mdb_dec_indent(4);
 	}
 
 	/*
 	 * Print refcnt audit data if requested
 	 */
 	if (idc->u.child.idc_tgt && rc_audit) {
-		(void) mdb_inc_indent(4);
-		mdb_printf("target_sess_refcnt:\n");
+		mdb_printf("Reference History(target_sess_refcnt):\n");
 		rc_addr = addr +
 		    offsetof(iscsit_tgt_t, target_sess_refcnt);
 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
 			return (DCMD_ERR);
 
-		mdb_printf("target_refcnt:\n");
+		mdb_printf("Reference History(target_refcnt):\n");
 		rc_addr = addr +
 		    offsetof(iscsit_tgt_t, target_refcnt);
 
 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
 			return (DCMD_ERR);
 		idc->u.child.idc_rc_audit = 0;
-		(void) mdb_dec_indent(4);
 	}
 
 	/* Any child objects to walk? */
-	if (idc->u.child.idc_tpgt || idc->u.child.idc_sess ||
-	    idc->u.child.idc_conn || idc->u.child.idc_task ||
-	    idc->u.child.idc_buffer) {
+	if (idc->u.child.idc_tpgt || idc->u.child.idc_portal) {
+
+		if (idc->u.child.idc_tgt) {
+			idc->idc_header = 1;
+		}
+
 		/* Walk TPGT tree */
-		idc->idc_header = 1;
-		(void) mdb_inc_indent(4);
 		avl_addr = addr +
 		    offsetof(iscsit_tgt_t, target_tpgt_list);
 		if (mdb_pwalk("avl", iscsi_tpgt_walk_cb, idc,
@@ -866,11 +1168,17 @@
 			(void) mdb_dec_indent(4);
 			return (DCMD_ERR);
 		}
-		(void) mdb_dec_indent(4);
+	}
+
+	if (idc->u.child.idc_sess || idc->u.child.idc_conn ||
+	    idc->u.child.idc_task || idc->u.child.idc_buffer) {
+
+		if (idc->u.child.idc_tgt || idc->u.child.idc_tpgt ||
+		    idc->u.child.idc_portal) {
+			idc->idc_header = 1;
+		}
 
 		/* Walk sess tree */
-		idc->idc_header = 1;
-		(void) mdb_inc_indent(4);
 		avl_addr = addr + offsetof(iscsit_tgt_t, target_sess_list);
 		if (mdb_pwalk("avl", iscsi_sess_walk_cb, idc,
 		    avl_addr) == -1) {
@@ -878,9 +1186,12 @@
 			(void) mdb_dec_indent(4);
 			return (DCMD_ERR);
 		}
-		(void) mdb_dec_indent(4);
-
+	}
+
+	/* If tgts were handled decrease indent and reset header */
+	if (idc->u.child.idc_tgt) {
 		idc->idc_header = 0;
+		mdb_dec_indent(4);
 	}
 
 	idc->idc_verbose = verbose;
@@ -894,7 +1205,8 @@
 {
 	iscsit_tpgt_t	tpgt;
 	iscsit_tpg_t	tpg;
-	uintptr_t	avl_addr, tpg_addr;
+	uintptr_t	avl_addr, tpg_addr, rc_addr;
+	int		rc_audit;
 
 	/*
 	 * Read iscsit_tpgt_t
@@ -914,6 +1226,8 @@
 		return (DCMD_ERR);
 	}
 
+	rc_audit = idc->u.child.idc_rc_audit;
+
 	/*
 	 * Brief output
 	 *
@@ -932,11 +1246,23 @@
 		}
 		mdb_printf("%?p %?p %-18s 0x%04x\n", addr, tpgt.tpgt_tpg,
 		    tpg.tpg_name, tpgt.tpgt_tag);
+
+		if (rc_audit) {
+			(void) mdb_inc_indent(4);
+
+			mdb_printf("Reference History(tpgt_refcnt):\n");
+			rc_addr = addr + offsetof(iscsit_tpgt_t, tpgt_refcnt);
+			if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
+				return (DCMD_ERR);
+
+			idc->u.child.idc_rc_audit = 0;
+			(void) mdb_dec_indent(4);
+		}
 	}
 
 	/*
 	 * Assume for now that anyone interested in TPGT wants to see the
-	 * portals as well.
+	 * portals as well. Enable idc_header for the portals.
 	 */
 	idc->idc_header = 1;
 	(void) mdb_inc_indent(4);
@@ -949,6 +1275,7 @@
 	(void) mdb_dec_indent(4);
 	idc->idc_header = 0;
 
+	idc->u.child.idc_rc_audit = rc_audit;
 	return (DCMD_OK);
 }
 
@@ -956,7 +1283,10 @@
 iscsi_tpg_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
 {
 	iscsit_tpg_t	tpg;
-	uintptr_t	avl_addr;
+	uintptr_t	avl_addr, rc_addr;
+	int		rc_audit = 0;
+
+	rc_audit = idc->u.child.idc_rc_audit;
 
 	/*
 	 * Read iscsit_tpg_t
@@ -975,31 +1305,48 @@
 	 * iscsit_tpgt_t.tpgt_tag;
 	 */
 
-	/* For now we will ignore the verbose flag */
-
-	/* Print target data */
-	if (idc->idc_header) {
-		mdb_printf("%<u>%-?s %-18s%</u>\n",
-		    "iscsit_tpg_t", "Name");
+	/* Print tpg data */
+	if (idc->u.child.idc_tpg) {
+		if (idc->idc_header) {
+			mdb_printf("%<u>%-?s %-18s%</u>\n",
+			    "iscsit_tpg_t", "Name");
+		}
+		mdb_printf("%?p %-18s\n", addr, tpg.tpg_name);
+
+		(void) mdb_inc_indent(4);
+
+		if (rc_audit) {
+			mdb_printf("Reference History(tpg_refcnt):\n");
+			rc_addr = addr + offsetof(iscsit_tpg_t, tpg_refcnt);
+			if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
+				return (DCMD_ERR);
+			}
+			idc->u.child.idc_rc_audit = 0;
+		}
 	}
-	mdb_printf("%?p %-18s\n", addr, tpg.tpg_name);
-
-
-	/*
-	 * Assume for now that anyone interested in TPG wants to see the
-	 * portals as well.
-	 */
-	idc->idc_header = 1;
-	(void) mdb_inc_indent(4);
-	avl_addr = addr + offsetof(iscsit_tpg_t, tpg_portal_list);
-	if (mdb_pwalk("avl", iscsi_portal_walk_cb, idc, avl_addr) == -1) {
-		mdb_warn("portal list walk failed");
+
+	if (idc->u.child.idc_portal) {
+		if (idc->u.child.idc_tpg) {
+			idc->idc_header = 1;
+		}
+
+		avl_addr = addr + offsetof(iscsit_tpg_t, tpg_portal_list);
+		if (mdb_pwalk("avl", iscsi_portal_walk_cb, idc,
+		    avl_addr) == -1) {
+			mdb_warn("portal list walk failed");
+			if (idc->u.child.idc_tpg) {
+				(void) mdb_dec_indent(4);
+			}
+			return (DCMD_ERR);
+		}
+	}
+
+	if (idc->u.child.idc_tpg) {
 		(void) mdb_dec_indent(4);
-		return (DCMD_ERR);
+		idc->idc_header = 0;
 	}
-	(void) mdb_dec_indent(4);
-	idc->idc_header = 0;
-
+
+	idc->u.child.idc_rc_audit = rc_audit;
 	return (DCMD_OK);
 }
 
@@ -1008,6 +1355,8 @@
 {
 	iscsit_portal_t	portal;
 	char		portal_addr[PORTAL_STR_LEN];
+	uintptr_t	rc_addr;
+
 	if (idc->u.child.idc_portal) {
 		/*
 		 * Read iscsit_portal_t
@@ -1021,10 +1370,22 @@
 		if (idc->idc_header) {
 			mdb_printf("%<u>%-?s %-?s %-30s%</u>\n",
 			    "iscsit_portal_t", "idm_svc_t", "IP:Port");
+			idc->idc_header = 0;
 		}
 		sa_to_str(&portal.portal_addr, portal_addr);
 		mdb_printf("%?p %?p %s\n", addr, portal.portal_svc,
-		    portal_addr);
+		    portal.portal_default ? "(Default)" : portal_addr);
+
+		if (idc->u.child.idc_rc_audit) {
+			(void) mdb_inc_indent(4);
+			mdb_printf("Reference History(portal_refcnt):\n");
+			rc_addr = addr + offsetof(iscsit_portal_t,
+			    portal_refcnt);
+			if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
+				return (DCMD_ERR);
+			}
+			(void) mdb_dec_indent(4);
+		}
 	}
 
 	return (DCMD_OK);
@@ -1034,11 +1395,23 @@
 iscsi_sess_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
 {
 	iscsit_sess_t	ist;
+	iscsi_sess_t	ini_sess;
 	uintptr_t	list_addr, states_addr, rc_addr;
 	char		ini_name[80];
 	char		tgt_name[80];
 	int		verbose, states, rc_audit;
 
+	if (idc->idc_ini) {
+		if ((mdb_vread(&ini_sess, sizeof (iscsi_sess_t),
+		    (uintptr_t)addr)) != sizeof (iscsi_sess_t)) {
+			mdb_warn("Failed to read initiator session\n");
+			return (DCMD_ERR);
+		}
+		if (iscsi_print_ini_sess(addr, &ini_sess, idc) != DCMD_OK) {
+			return (DCMD_ERR);
+		}
+		return (DCMD_OK);
+	}
 	/*
 	 * Read iscsit_sess_t
 	 */
@@ -1100,6 +1473,8 @@
 			    ist.ist_expcmdsn);
 			mdb_printf("%16s: %08x\n", "MaxCmdSN",
 			    ist.ist_maxcmdsn);
+
+			idc->idc_verbose = 0;
 		} else {
 			/* Print session data */
 			if (idc->idc_header) {
@@ -1114,33 +1489,32 @@
 			    ist.ist_isid[3], ist.ist_isid[4], ist.ist_isid[5],
 			    ist.ist_tsih);
 		}
-		idc->idc_header = 0;
+
+		/*
+		 * Indent for any child structures
+		 */
+		(void) mdb_inc_indent(4);
 	}
 
-	idc->idc_verbose = 0;
-
 	/*
 	 * Print states if requested
 	 */
-	if (states) {
+	if (idc->u.child.idc_sess && states) {
 		states_addr = addr + offsetof(iscsit_sess_t, ist_state_audit);
 
-		(void) mdb_inc_indent(4);
-		mdb_printf("State History:\n");
+		mdb_printf("State History(ist_state_audit):\n");
 		if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
 			return (DCMD_ERR);
 
 		/* Don't print state history for child objects */
 		idc->u.child.idc_states = 0;
-		(void) mdb_dec_indent(4);
 	}
 
 	/*
 	 * Print refcnt audit data if requested
 	 */
-	if (rc_audit) {
-		(void) mdb_inc_indent(4);
-		mdb_printf("Reference History:\n");
+	if (idc->u.child.idc_sess && rc_audit) {
+		mdb_printf("Reference History(ist_refcnt):\n");
 		rc_addr = addr +
 		    offsetof(iscsit_sess_t, ist_refcnt);
 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
@@ -1148,15 +1522,20 @@
 
 		/* Don't print audit data for child objects */
 		idc->u.child.idc_rc_audit = 0;
-		(void) mdb_dec_indent(4);
 	}
 
 	/* Any child objects to walk? */
 	if (idc->u.child.idc_conn || idc->u.child.idc_task ||
 	    idc->u.child.idc_buffer) {
+		/*
+		 * If a session has been printed enable headers for
+		 * any child structs.
+		 */
+		if (idc->u.child.idc_sess) {
+			idc->idc_header = 1;
+		}
+
 		/* Walk conn list */
-		idc->idc_header = 1;
-		(void) mdb_inc_indent(4);
 		list_addr = addr + offsetof(iscsit_sess_t, ist_conn_list);
 		if (mdb_pwalk("list", iscsi_sess_conn_walk_cb, idc,
 		    list_addr) == -1) {
@@ -1164,8 +1543,12 @@
 			(void) mdb_dec_indent(4);
 			return (DCMD_ERR);
 		}
-		(void) mdb_dec_indent(4);
+	}
+
+	/* If a session was handled decrease indent and reset header. */
+	if (idc->u.child.idc_sess) {
 		idc->idc_header = 0;
+		mdb_dec_indent(4);
 	}
 
 	idc->idc_verbose = verbose;
@@ -1176,6 +1559,134 @@
 }
 
 static int
+iscsi_print_ini_sess(uintptr_t addr, iscsi_sess_t *sess,
+    iscsi_dcmd_ctrl_t *idc)
+{
+
+	int verbose, states;
+	uintptr_t states_addr;
+
+	verbose = idc->idc_verbose;
+	states = idc->u.child.idc_states;
+
+
+	if (idc->u.child.idc_sess) {
+		if (!idc->idc_verbose) {
+			if (idc->idc_header) {
+				mdb_printf("%<u>%-?s %-4s  %-8s%</u>\n",
+				    "iscsi_sess_t", "Type", "State");
+			}
+			mdb_printf("%-19p %-4d %-8d\n", addr,
+			    sess->sess_type, sess->sess_state);
+		} else {
+			mdb_printf("Session %p\n", addr);
+			mdb_printf("%22s: %d\n", "State",
+			    sess->sess_state);
+			mdb_printf("%22s: %d\n", "Last State",
+			    sess->sess_prev_state);
+			mdb_printf("%22s: %s\n", "Session Name",
+			    sess->sess_name);
+			mdb_printf("%22s: %s\n", "Alias",
+			    sess->sess_alias);
+			mdb_printf("%22s: %08x\n", "CmdSN",
+			    sess->sess_cmdsn);
+			mdb_printf("%22s: %08x\n", "ExpCmdSN",
+			    sess->sess_expcmdsn);
+			mdb_printf("%22s: %08x\n", "MaxCmdSN",
+			    sess->sess_maxcmdsn);
+			mdb_printf("%22s: %p\n", "Pending Queue Head",
+			    sess->sess_queue_pending.head);
+			mdb_printf("%22s: %p\n", "Completion Queue Head",
+			    sess->sess_queue_completion.head);
+			mdb_printf("%22s: %p\n", "Connnection List Head",
+			    sess->sess_conn_list);
+
+			idc->idc_verbose = 0;
+		}
+
+		/* Indent for any child structures */
+		mdb_inc_indent(4);
+
+		if (idc->u.child.idc_states) {
+			states_addr = (uintptr_t)addr +
+			    offsetof(iscsi_sess_t, sess_state_audit);
+
+			mdb_printf("State History(sess_state_audit):\n");
+			if (iscsi_sm_audit_impl(states_addr) != DCMD_OK) {
+				(void) mdb_dec_indent(4);
+				return (DCMD_ERR);
+			}
+			idc->u.child.idc_states = 0;
+		}
+	}
+
+	if (idc->u.child.idc_lun && sess->sess_lun_list) {
+		if (idc->u.child.idc_sess) {
+			idc->idc_header = 1;
+		}
+
+		if (mdb_pwalk("iscsi_ini_lun", iscsi_ini_lun_walk_cb, idc,
+		    (uintptr_t)sess->sess_lun_list) == -1) {
+			mdb_warn("iscsi_ini_lun walk failed");
+			(void) mdb_dec_indent(4);
+			return (DCMD_ERR);
+		}
+	}
+
+
+	/* If requested print the cmds in the session queue */
+	if (idc->u.child.idc_cmd) {
+
+		/* If any other structs printed enable header */
+		if (idc->u.child.idc_sess || idc->u.child.idc_lun) {
+			idc->idc_header = 1;
+		}
+
+		if (sess->sess_queue_pending.head) {
+			if (mdb_pwalk("iscsi_ini_cmd", iscsi_ini_cmd_walk_cb,
+			    idc, (uintptr_t)sess->sess_queue_pending.head)
+			    == -1) {
+				mdb_warn("list walk failed for iscsi cmds");
+			}
+		}
+		if (sess->sess_queue_completion.head) {
+			if (mdb_pwalk("iscsi_ini_cmd", iscsi_ini_cmd_walk_cb,
+			    idc, (uintptr_t)sess->sess_queue_completion.head)
+			    == -1) {
+				mdb_warn("list walk failed for iscsi cmds");
+			}
+		}
+	}
+
+	/* If connections or cmds requested walk the connections */
+	if (idc->u.child.idc_conn || idc->u.child.idc_cmd) {
+		/*
+		 * If idc_conn is not set don't enable header or the
+		 * commands may get extraneous headers.
+		 */
+		if (idc->u.child.idc_conn) {
+			idc->idc_header = 1;
+		}
+		if (mdb_pwalk("iscsi_ini_conn", iscsi_ini_conn_walk_cb, idc,
+		    (uintptr_t)sess->sess_conn_list) == -1) {
+			mdb_warn("iscsi_ini_conn walk failed");
+			return (DCMD_ERR);
+		}
+	}
+
+	/* If sessions were handled decrease indent and reset header */
+	if (idc->u.child.idc_sess) {
+		idc->idc_header = 0;
+		mdb_dec_indent(4);
+	}
+
+	idc->u.child.idc_states = states;
+	idc->idc_verbose = verbose;
+	return (DCMD_OK);
+}
+
+
+static int
 iscsi_conn_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
 {
 	uintptr_t	idm_global_addr, states_addr, rc_addr;
@@ -1183,6 +1694,8 @@
 	GElf_Sym	sym;
 	idm_task_t	idt;
 	idm_conn_t	ic;
+	iscsit_conn_t	ict;
+	iscsi_conn_t	ini_conn;
 	char		*conn_type;
 	int		task_idx;
 	char		laddr[PORTAL_STR_LEN];
@@ -1213,6 +1726,18 @@
 	if (mdb_vread(&ic, sizeof (idm_conn_t), addr) != sizeof (idm_conn_t)) {
 		return (DCMD_ERR);
 	}
+
+	/*
+	 * If filter bits are set to only print targets or only initiators
+	 * skip entries of the other type.
+	 */
+	if (!(idc->idc_ini && idc->idc_tgt) &&
+	    ((idc->idc_ini && (ic.ic_conn_type != CONN_TYPE_INI)) ||
+	    (idc->idc_tgt && (ic.ic_conn_type != CONN_TYPE_TGT)))) {
+		return (DCMD_OK);
+	}
+
+
 	conn_type = (ic.ic_conn_type == CONN_TYPE_INI) ? "Ini" :
 	    (ic.ic_conn_type == CONN_TYPE_TGT) ? "Tgt" : "Unk";
 
@@ -1228,14 +1753,40 @@
 	states = idc->u.child.idc_states;
 	rc_audit = idc->u.child.idc_rc_audit;
 
+	/*
+	 * If targets(-T) and/or initiators (-I) are specifically requested,
+	 * fetch the iscsit_conn_t and/or iscsi_conn_t struct as a sanity
+	 * check and for use below.
+	 */
+	if (idc->idc_tgt && IDM_CONN_ISTGT(&ic)) {
+		if (mdb_vread(&ict, sizeof (iscsit_conn_t),
+		    (uintptr_t)ic.ic_handle) !=
+		    sizeof (iscsit_conn_t)) {
+			mdb_printf("Failed to read target connection "
+			    "handle data\n");
+			return (DCMD_ERR);
+		}
+	}
+
+	if (idc->idc_ini && IDM_CONN_ISINI(&ic)) {
+		if (mdb_vread(&ini_conn, sizeof (iscsi_conn_t),
+		    (uintptr_t)ic.ic_handle) !=
+		    sizeof (iscsi_conn_t)) {
+			mdb_printf("Failed to read initiator "
+			    "connection handle data\n");
+			return (DCMD_ERR);
+		}
+	}
+
 	if (idc->u.child.idc_conn) {
 		if (idc->idc_verbose) {
 			mdb_printf("IDM Conn %p\n", addr);
 			if (ic.ic_conn_type == CONN_TYPE_TGT) {
 				iscsi_print_iscsit_conn_data(&ic);
 			} else {
-				iscsi_print_idm_conn_data(&ic);
+				iscsi_print_ini_conn_data(&ic);
 			}
+			idc->idc_verbose = 0;
 		} else {
 			/* Print connection data */
 			if (idc->idc_header) {
@@ -1257,53 +1808,100 @@
 				    laddr, raddr);
 			}
 		}
+
+		/* Indent for any child structs */
+		mdb_inc_indent(4);
 	}
-	idc->idc_header = 0;
-
-	idc->idc_verbose = 0;
 
 	/*
 	 * Print states if requested
 	 */
-	if (states) {
+	if (idc->u.child.idc_conn && states) {
 		states_addr = addr + offsetof(idm_conn_t, ic_state_audit);
 
-		(void) mdb_inc_indent(4);
-		mdb_printf("State History:\n");
+		mdb_printf("State History(ic_state_audit):\n");
 		if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
 			return (DCMD_ERR);
 
+		/*
+		 * If targets are specifically requested show the
+		 * state audit for the target specific connection struct
+		 */
+		if (idc->idc_tgt && IDM_CONN_ISTGT(&ic)) {
+			states_addr = (uintptr_t)ic.ic_handle +
+			    offsetof(iscsit_conn_t, ict_login_sm) +
+			    offsetof(iscsit_conn_login_t, icl_state_audit);
+
+			mdb_printf("State History(icl_state_audit):\n");
+			if (iscsi_sm_audit_impl(states_addr) != DCMD_OK) {
+				return (DCMD_ERR);
+			}
+		}
+
+		/*
+		 * If initiators are specifically requested show the
+		 * state audit for the initiator specific connection struct
+		 */
+		if (idc->idc_ini && IDM_CONN_ISINI(&ic)) {
+			states_addr = (uintptr_t)ic.ic_handle +
+			    offsetof(iscsi_conn_t, conn_state_audit);
+
+			mdb_printf("State History(iscsi_conn_t "
+			    "conn_state_audit):\n");
+			if (iscsi_sm_audit_impl(states_addr) != DCMD_OK) {
+				return (DCMD_ERR);
+			}
+		}
+
 		/* Don't print state history for child objects */
 		idc->u.child.idc_states = 0;
-		(void) mdb_dec_indent(4);
 	}
 
 	/*
-	 * Print refcnt audit data if requested
+	 * Print refcnt audit data for the connection struct if requested.
 	 */
-	if (rc_audit) {
-		(void) mdb_inc_indent(4);
-		mdb_printf("Reference History:\n");
+	if (idc->u.child.idc_conn && rc_audit) {
+		mdb_printf("Reference History(ic_refcnt):\n");
 		rc_addr = addr + offsetof(idm_conn_t, ic_refcnt);
 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
 			return (DCMD_ERR);
 
+		/*
+		 * If targets are specifically requested show the
+		 * Refcounts for the target specific connection struct
+		 */
+		if (idc->idc_tgt && IDM_CONN_ISTGT(&ic)) {
+			mdb_printf("Reference History(ict_refcnt):\n");
+			rc_addr = (uintptr_t)ic.ic_handle +
+			    offsetof(iscsit_conn_t, ict_refcnt);
+			if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
+				return (DCMD_ERR);
+			}
+
+			mdb_printf("Reference History(ict_dispatch_refcnt):\n");
+			rc_addr = (uintptr_t)ic.ic_handle +
+			    offsetof(iscsit_conn_t, ict_dispatch_refcnt);
+			if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
+				return (DCMD_ERR);
+			}
+		}
+
 		/* Don't print audit data for child objects */
 		idc->u.child.idc_rc_audit = 0;
-		(void) mdb_dec_indent(4);
 	}
 
 	task_idx = 0;
 
-	/* Any child objects to walk? */
 	if (idc->u.child.idc_task || idc->u.child.idc_buffer) {
-		idc->idc_header = 1;
+
+		if (idc->u.child.idc_conn) {
+			idc->idc_header = 1;
+		}
+
 		while (task_idx < IDM_TASKIDS_MAX) {
-
 			/*
 			 * Read the next idm_task_t
 			 */
-
 			if (mdb_vread(&task_addr, sizeof (uintptr_t),
 			    task_ptr) != sizeof (uintptr_t)) {
 				mdb_warn("Failed to read task pointer");
@@ -1324,21 +1922,42 @@
 
 			if (((uintptr_t)idt.idt_ic == addr) &&
 			    (idt.idt_state != TASK_IDLE)) {
-				(void) mdb_inc_indent(4);
 				if (iscsi_i_task_impl(&idt, task_addr, idc)
 				    == -1) {
 					mdb_warn("Failed to walk connection "
 					    "task tree");
-					(void) mdb_dec_indent(4);
 					return (DCMD_ERR);
 				}
-				(void) mdb_dec_indent(4);
 			}
 
 			task_ptr += sizeof (uintptr_t);
 			task_idx++;
 		}
+	}
+
+	if (idc->idc_ini && IDM_CONN_ISINI(&ic) && idc->u.child.idc_cmd) {
+		if (idc->u.child.idc_conn || idc->u.child.idc_task) {
+			idc->idc_header = 1;
+		}
+		if (ini_conn.conn_queue_active.head &&
+		    (mdb_pwalk("iscsi_ini_cmd", iscsi_ini_cmd_walk_cb, idc,
+		    (uintptr_t)ini_conn.conn_queue_active.head) == -1)) {
+			mdb_warn("list walk failed for iscsi cmds");
+		}
+		if (ini_conn.conn_queue_idm_aborting.head &&
+		    (mdb_pwalk("iscsi_ini_cmd", iscsi_ini_cmd_walk_cb, idc,
+		    (uintptr_t)ini_conn.conn_queue_idm_aborting.head) == -1)) {
+			mdb_warn("list walk failed for iscsi cmds");
+		}
+	}
+
+	/*
+	 * If connection information was handled unset header and
+	 * decrease indent
+	 */
+	if (idc->u.child.idc_conn) {
 		idc->idc_header = 0;
+		mdb_dec_indent(4);
 	}
 
 	idc->idc_verbose = verbose;
@@ -1348,6 +1967,73 @@
 	return (DCMD_OK);
 }
 
+static int
+iscsi_svc_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
+{
+	idm_svc_t	svc;
+	iser_svc_t	iser_svc;
+	uintptr_t	rc_addr;
+
+	if (mdb_vread(&svc, sizeof (idm_svc_t), addr) !=
+	    sizeof (idm_svc_t)) {
+		return (DCMD_ERR);
+	}
+
+	if (idc->u.child.idc_svc) {
+		if (idc->idc_verbose) {
+			mdb_printf("Service %p\n", addr);
+			mdb_printf("%20s: %d\n", "Port",
+			    svc.is_svc_req.sr_port);
+			mdb_printf("%20s: %d\n", "Online",
+			    svc.is_online);
+			mdb_printf("%20s: %p\n", "Socket Service",
+			    svc.is_so_svc);
+			mdb_printf("%20s: %p\n", "iSER Service",
+			    svc.is_iser_svc);
+		} else {
+			if (idc->idc_header) {
+				mdb_printf("%<u>%-?s %-8s %-8s%</u>\n",
+				    "idm_svc_t", "Port", "Online");
+				idc->idc_header = 0;
+			}
+
+			mdb_printf("%?p %-8d %-8d\n", addr,
+			    svc.is_svc_req.sr_port, svc.is_online);
+		}
+
+		if (idc->u.child.idc_rc_audit) {
+			(void) mdb_inc_indent(4);
+			mdb_printf("Reference History(is_refcnt):\n");
+			rc_addr = addr + offsetof(idm_svc_t, is_refcnt);
+			if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
+				(void) mdb_dec_indent(4);
+				return (DCMD_ERR);
+			}
+
+			if (svc.is_iser_svc != NULL) {
+				mdb_printf("Reference History"
+				    "(iser_svc is_refcnt):\n");
+
+				/* Sanity check the iser svc struct */
+				if (mdb_vread(&iser_svc, sizeof (iser_svc_t),
+				    (uintptr_t)svc.is_iser_svc) !=
+				    sizeof (iser_svc_t)) {
+					return (DCMD_ERR);
+				}
+
+				rc_addr = (uintptr_t)svc.is_iser_svc +
+				    offsetof(iser_svc_t, is_refcnt);
+
+				if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
+					return (DCMD_ERR);
+				}
+			}
+			(void) mdb_dec_indent(4);
+		}
+	}
+	return (DCMD_OK);
+}
+
 static void
 iscsi_print_iscsit_conn_data(idm_conn_t *ic)
 {
@@ -1363,6 +2049,9 @@
 		return;
 	}
 
+	mdb_printf("%20s: %p\n", "iSCSIT TGT Conn",
+	    ic->ic_handle);
+
 	if (ict.ict_login_sm.icl_login_state != ILS_LOGIN_DONE) {
 		switch (ict.ict_login_sm.icl_login_csg) {
 		case ISCSI_SECURITY_NEGOTIATION_STAGE:
@@ -1416,6 +2105,41 @@
 }
 
 static void
+iscsi_print_ini_conn_data(idm_conn_t *ic)
+{
+	iscsi_conn_t	ini_conn;
+
+	iscsi_print_idm_conn_data(ic);
+
+	if (mdb_vread(&ini_conn, sizeof (iscsi_conn_t),
+	    (uintptr_t)ic->ic_handle) != sizeof (iscsi_conn_t)) {
+		mdb_printf("Failed to read conn private data\n");
+		return;
+	}
+
+	mdb_printf("%20s: %p\n", "iSCSI Ini Conn",
+	    ic->ic_handle);
+	mdb_printf("%20s: %p\n", "Parent Session",
+	    ini_conn.conn_sess);
+	mdb_printf("%20s: %d\n", "Conn State",
+	    ini_conn.conn_state);
+	mdb_printf("%20s: %d\n", "Last Conn State",
+	    ini_conn.conn_prev_state);
+
+	mdb_printf("%20s: %d\n", "Login Stage",
+	    ini_conn.conn_current_stage);
+	mdb_printf("%20s: %d\n", "Next Login Stage",
+	    ini_conn.conn_next_stage);
+
+	mdb_printf("%20s: 0x%08x\n", "Expected StatSN",
+	    ini_conn.conn_expstatsn);
+	mdb_printf("%20s: %p\n", "Active Queue Head",
+	    ini_conn.conn_queue_active.head);
+	mdb_printf("%20s: %d\n", "Abort Queue Head",
+	    ini_conn.conn_queue_idm_aborting.head);
+}
+
+static void
 iscsi_print_idm_conn_data(idm_conn_t *ic)
 {
 	char		laddr[PORTAL_STR_LEN];
@@ -1499,7 +2223,7 @@
 		states_addr = addr + offsetof(idm_task_t, idt_state_audit);
 
 		(void) mdb_inc_indent(4);
-		mdb_printf("State History:\n");
+		mdb_printf("State History(idt_state_audit):\n");
 		if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
 			return (DCMD_ERR);
 
@@ -1514,7 +2238,7 @@
 	 */
 	if (rc_audit) {
 		(void) mdb_inc_indent(4);
-		mdb_printf("Reference History:\n");
+		mdb_printf("Reference History(idt_refcnt):\n");
 		rc_addr = addr +
 		    offsetof(idm_task_t, idt_refcnt);
 		if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
@@ -1526,7 +2250,10 @@
 	}
 
 
-	/* Buffers are leaf objects */
+	/*
+	 * Buffers are leaf objects and always get headers so the
+	 * user can discern between in and out buffers.
+	 */
 	if (idc->u.child.idc_buffer) {
 		/* Walk in buffer list */
 		(void) mdb_inc_indent(2);
@@ -1647,6 +2374,56 @@
 }
 
 static int
+iscsi_print_ini_lun(uintptr_t addr, const iscsi_lun_t *lun,
+    iscsi_dcmd_ctrl_t *idc)
+{
+
+	if (idc->u.child.idc_lun) {
+		if (idc->idc_header) {
+			mdb_printf("%<u>%-?s %-5s %-10s%</u>\n",
+			    "iscsi_lun_t", "State", "Lun Number");
+			idc->idc_header = 0;
+		}
+		mdb_printf("%?p %-5d %-10d\n", addr,
+		    lun->lun_state, lun->lun_num);
+	}
+	return (DCMD_OK);
+}
+
+static int
+iscsi_print_ini_cmd(uintptr_t addr, const iscsi_cmd_t *cmd,
+    iscsi_dcmd_ctrl_t *idc) {
+
+	uintptr_t states_addr;
+
+	if (idc->idc_header) {
+		mdb_printf("%<u>%-?s %-?s %4s %6s/%-6s %-?s%</u>\n",
+		    "iscsi_cmd_t", "idm_task_t", "Type",
+		    "State", "Prev", "iscsi_lun_t");
+		idc->idc_header = 0;
+	}
+
+	mdb_printf("%?p %?p %4d %6d/%-6d %?p\n",
+	    addr, cmd->cmd_itp, cmd->cmd_type, cmd->cmd_state,
+	    cmd->cmd_prev_state, cmd->cmd_lun);
+
+	/*
+	 * Print states if requested
+	 */
+	if (idc->u.child.idc_states) {
+		states_addr = addr + offsetof(iscsi_cmd_t, cmd_state_audit);
+
+		(void) mdb_inc_indent(4);
+		mdb_printf("State History(cmd_state_audit):\n");
+		if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
+			return (DCMD_ERR);
+		idc->u.child.idc_states = 0;
+		(void) mdb_dec_indent(4);
+	}
+	return (DCMD_OK);
+}
+
+static int
 iscsi_buffer_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
 {
 	idm_buf_t	idb;
@@ -1663,8 +2440,8 @@
 		mdb_printf("%<u>%-?s %?s/%-8s %8s %8s %8s%</u>\n",
 		    "idm_buf_t", "Mem Rgn", "Length",
 		    "Rel Off", "Xfer Len", "Exp. Off");
+		idc->idc_header = 0;
 	}
-	idc->idc_header = 0;
 
 	/* Print buffer data */
 	mdb_printf("%?p %?p/%08x %8x %8x %08x\n", addr,
@@ -1690,6 +2467,7 @@
 	 */
 	if (mdb_vread(&refcnt, sizeof (idm_refcnt_t), addr) !=
 	    sizeof (idm_refcnt_t)) {
+		mdb_warn("read refcnt failed");
 		return (DCMD_ERR);
 	}
 
@@ -1760,6 +2538,7 @@
 	 */
 	if (mdb_vread(&audit_buf, sizeof (sm_audit_buf_t), addr) !=
 	    sizeof (sm_audit_buf_t)) {
+		mdb_warn("failed to read audit buf");
 		return (DCMD_ERR);
 	}
 
@@ -2096,6 +2875,7 @@
 	mdb_printf("-s: Print iSNS server information\n");
 	mdb_printf("-t: Print target information\n");
 	mdb_printf("-v: Add verbosity to the other options' output\n");
+	mdb_printf("-R: Add Refcount information to '-t' output\n");
 	mdb_dec_indent(4);
 }
 
@@ -2169,11 +2949,11 @@
 		mdb_printf("\n");
 	}
 	if (portal.portal_iscsit != NULL) {
-		mdb_printf("(Part of TPG: 0x%x)\n", portal.portal_iscsit);
+		mdb_printf("(Part of TPG: 0x%p)\n", portal.portal_iscsit);
 	}
 
 	iscsi_format_timestamp(ts_string, 40, &portal.portal_esi_timestamp);
-	mdb_printf("Portal ESI timestamp: 0x%p\n\n", ts_string);
+	mdb_printf("Portal ESI timestamp: %s\n\n", ts_string);
 
 	if ((portal.portal_iscsit != NULL) && (idc->idc_verbose)) {
 		mdb_inc_indent(4);
@@ -2231,6 +3011,8 @@
 	iscsi_dcmd_ctrl_t	*idc = (iscsi_dcmd_ctrl_t *)data;
 	isns_target_t		itarget;
 	int			rc = 0;
+	int			rc_audit = 0;
+	uintptr_t		rc_addr;
 
 	if (mdb_vread(&itarget, sizeof (isns_target_t), addr) !=
 	    sizeof (isns_target_t)) {
@@ -2238,6 +3020,7 @@
 	}
 
 	idc->idc_header = 1;
+	rc_audit = idc->u.child.idc_rc_audit;
 
 	mdb_printf("Target: %p\n", addr);
 	mdb_inc_indent(4);
@@ -2247,8 +3030,21 @@
 	    (itarget.target_update_needed) ? "Yes" : "No");
 	mdb_printf("Target Info: %p\n", itarget.target_info);
 
+	/* Prevent target refcounts from showing through this path */
+	idc->u.child.idc_rc_audit = 0;
 	rc = iscsi_tgt_impl((uintptr_t)itarget.target, idc);
 
+	idc->u.child.idc_rc_audit = rc_audit;
+	if (idc->u.child.idc_rc_audit) {
+		rc_addr = (uintptr_t)itarget.target_info +
+		    offsetof(isns_target_info_t, ti_refcnt);
+
+		mdb_printf("Reference History(isns_target_info ti_refcnt):\n");
+		if (iscsi_refcnt_impl(rc_addr) != 0) {
+			return (WALK_ERR);
+		}
+	}
+
 	mdb_dec_indent(4);
 
 	if (rc == DCMD_OK) {
@@ -2379,6 +3175,7 @@
 {
 	iscsi_dcmd_ctrl_t idc;
 	int portals = 0, esi = 0, targets = 0, verbose = 0, servers = 0;
+	int rc_audit = 0;
 
 	if (flags & DCMD_ADDRSPEC) {
 		mdb_warn("iscsi_isns is only a global dcmd.");
@@ -2392,6 +3189,7 @@
 	    's', MDB_OPT_SETBITS, TRUE, &servers,
 	    't', MDB_OPT_SETBITS, TRUE, &targets,
 	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
+	    'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
 	    NULL) != argc)
 		return (DCMD_USAGE);
 
@@ -2406,6 +3204,7 @@
 	}
 
 	idc.idc_verbose = verbose;
+	idc.u.child.idc_rc_audit = rc_audit;
 
 	if (esi) {
 		return (iscsi_isns_esi(&idc));
@@ -2422,6 +3221,277 @@
 	return (iscsi_isns_targets(&idc));
 }
 
+static int
+iscsi_ini_sess_walk_init(mdb_walk_state_t *wsp) {
+
+
+	if (wsp->walk_addr == NULL) {
+		mdb_warn("<iscsi_sess_t addr>::walk iscsi_ini_sess");
+		return (WALK_ERR);
+	}
+
+	wsp->walk_data = mdb_alloc(sizeof (iscsi_sess_t), UM_SLEEP|UM_GC);
+	if (!wsp->walk_data) {
+		mdb_warn("iscsi_ini_sess walk failed");
+		return (WALK_ERR);
+	}
+
+	return (WALK_NEXT);
+}
+
+static int
+iscsi_ini_sess_step(mdb_walk_state_t *wsp) {
+	int status;
+
+	if (wsp->walk_addr == NULL) {
+		return (WALK_DONE);
+	}
+
+	if (mdb_vread(wsp->walk_data, sizeof (iscsi_sess_t), wsp->walk_addr)
+	    != sizeof (iscsi_sess_t)) {
+		mdb_warn("failed to read iscsi_sess_t at %p", wsp->walk_addr);
+		return (WALK_DONE);
+	}
+
+	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
+	    wsp->walk_cbdata);
+
+	wsp->walk_addr =
+	    (uintptr_t)(((iscsi_sess_t *)wsp->walk_data)->sess_next);
+
+	return (status);
+}
+
+static int
+iscsi_ini_conn_walk_init(mdb_walk_state_t *wsp) {
+
+	if (wsp->walk_addr == NULL) {
+		mdb_warn("<iscsi_conn_t addr>::walk iscsi_ini_conn");
+		return (WALK_DONE);
+	}
+
+	wsp->walk_data = mdb_alloc(sizeof (iscsi_conn_t), UM_SLEEP|UM_GC);
+	if (!wsp->walk_data) {
+		mdb_warn("iscsi_ini_conn walk failed");
+		return (WALK_ERR);
+	}
+
+	return (WALK_NEXT);
+}
+
+static int
+iscsi_ini_conn_step(mdb_walk_state_t *wsp) {
+	int status;
+
+	if (wsp->walk_addr == NULL) {
+		return (WALK_DONE);
+	}
+
+	if (mdb_vread(wsp->walk_data, sizeof (iscsi_conn_t), wsp->walk_addr)
+	    != sizeof (iscsi_conn_t)) {
+		mdb_warn("failed to read iscsi_conn_t at %p", wsp->walk_addr);
+		return (WALK_DONE);
+	}
+
+
+	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
+	    wsp->walk_cbdata);
+
+	wsp->walk_addr =
+	    (uintptr_t)(((iscsi_conn_t *)wsp->walk_data)->conn_next);
+
+	return (status);
+}
+
+static int
+iscsi_ini_lun_walk_init(mdb_walk_state_t *wsp) {
+
+	if (wsp->walk_addr == NULL) {
+		mdb_warn("<iscsi_lun_t addr>::walk iscsi_ini_lun");
+		return (WALK_DONE);
+	}
+
+	wsp->walk_data = mdb_alloc(sizeof (iscsi_lun_t), UM_SLEEP|UM_GC);
+	if (!wsp->walk_data) {
+		return (WALK_ERR);
+	}
+
+	return (WALK_NEXT);
+}
+
+static int
+iscsi_ini_lun_step(mdb_walk_state_t *wsp) {
+	int status;
+
+	if (wsp->walk_addr == NULL) {
+		return (WALK_DONE);
+	}
+
+	if (mdb_vread(wsp->walk_data, sizeof (iscsi_lun_t), wsp->walk_addr)
+	    != sizeof (iscsi_lun_t)) {
+		mdb_warn("failed to read iscsi_lun_t at %p", wsp->walk_addr);
+		return (WALK_DONE);
+	}
+
+	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
+	    wsp->walk_cbdata);
+
+	wsp->walk_addr =
+	    (uintptr_t)(((iscsi_lun_t *)wsp->walk_data)->lun_next);
+
+	return (status);
+}
+
+static int
+iscsi_ini_cmd_walk_init(mdb_walk_state_t *wsp) {
+
+	if (wsp->walk_addr == NULL) {
+		mdb_warn("<iscsi_cmd_t addr>::walk iscsi_ini_cmd");
+		return (WALK_DONE);
+	}
+
+	wsp->walk_data = mdb_alloc(sizeof (iscsi_cmd_t), UM_SLEEP|UM_GC);
+	if (!wsp->walk_data) {
+		return (WALK_ERR);
+	}
+
+	return (WALK_NEXT);
+}
+
+static int
+iscsi_ini_cmd_step(mdb_walk_state_t *wsp) {
+	int status;
+
+	if (wsp->walk_addr == NULL) {
+		return (WALK_DONE);
+	}
+
+	if (mdb_vread(wsp->walk_data, sizeof (iscsi_cmd_t), wsp->walk_addr)
+	    != sizeof (iscsi_cmd_t)) {
+		mdb_warn("failed to read iscsi_cmd_t at %p", wsp->walk_addr);
+		return (WALK_DONE);
+	}
+
+	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
+	    wsp->walk_cbdata);
+
+	wsp->walk_addr =
+	    (uintptr_t)(((iscsi_cmd_t *)wsp->walk_data)->cmd_next);
+
+	return (status);
+}
+
+static int
+iscsi_ini_cmd_walk_cb(uintptr_t addr, const void *vcmd,
+    void *vidc) {
+
+	const iscsi_cmd_t	*cmd = vcmd;
+	iscsi_dcmd_ctrl_t	*idc = vidc;
+	int			rc;
+
+	if (cmd == NULL) {
+		mdb_warn("list walk failed. Null cmd");
+		return (WALK_ERR);
+	}
+
+	rc = iscsi_print_ini_cmd(addr, cmd, idc);
+
+	return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
+}
+
+static int
+iscsi_ini_hba_walk_init(mdb_walk_state_t *wsp) {
+	uintptr_t state_addr, array_addr;
+	int array_size;
+	struct i_ddi_soft_state *ss;
+	idm_hba_walk_info_t *hwi;
+
+
+	hwi = (idm_hba_walk_info_t *)mdb_zalloc(
+		sizeof (idm_hba_walk_info_t), UM_SLEEP|UM_GC);
+
+	if (!hwi) {
+		mdb_warn("unable to allocate storage for iscsi_ini_hba walk");
+		return (WALK_ERR);
+	}
+
+	if (wsp->walk_addr != NULL) {
+		mdb_warn("iscsi_ini_hba only supports global walk");
+		return (WALK_ERR);
+	} else {
+
+		/*
+		 * Read in the array and setup the walk struct.
+		 */
+		if (mdb_readvar(&state_addr, "iscsi_state") == -1) {
+			mdb_warn("state variable iscsi_state not found.\n");
+			mdb_warn("Is the driver loaded ?\n");
+			return (WALK_ERR);
+		}
+
+		ss = (struct i_ddi_soft_state *)mdb_alloc(sizeof (*ss),
+		    UM_SLEEP|UM_GC);
+		if (mdb_vread(ss, sizeof (*ss), state_addr) != sizeof (*ss)) {
+			mdb_warn("Cannot read softstate struct "
+			    "(Invalid pointer?).\n");
+			return (WALK_ERR);
+		}
+
+		/* Where to get the data */
+		array_size = ss->n_items * (sizeof (void *));
+		array_addr = (uintptr_t)ss->array;
+
+		/* Where to put the data */
+		hwi->n_elements = ss->n_items;
+		hwi->array = mdb_alloc(array_size, UM_SLEEP|UM_GC);
+		if (!hwi->array) {
+			mdb_warn("list walk failed");
+			return (WALK_ERR);
+		}
+		if (mdb_vread(hwi->array, array_size, array_addr) !=
+		    array_size) {
+			mdb_warn("Corrupted softstate struct.\n");
+			return (WALK_ERR);
+		}
+		hwi->cur_element = 0;
+		wsp->walk_data =  hwi;
+	}
+
+	return (WALK_NEXT);
+}
+
+static int
+iscsi_ini_hba_step(mdb_walk_state_t *wsp) {
+	int status;
+	idm_hba_walk_info_t *hwi = (idm_hba_walk_info_t *)wsp->walk_data;
+
+	for (; hwi->cur_element < hwi->n_elements; hwi->cur_element++) {
+		if (hwi->array[hwi->cur_element] != NULL) {
+			break;
+		}
+	}
+	if (hwi->cur_element >= hwi->n_elements) {
+		return (WALK_DONE);
+	}
+
+	hwi->data = (iscsi_hba_t *)mdb_alloc(sizeof (iscsi_hba_t),
+	    UM_SLEEP|UM_GC);
+	if (mdb_vread(hwi->data, sizeof (iscsi_hba_t),
+	    (uintptr_t)hwi->array[hwi->cur_element]) != sizeof (iscsi_hba_t)) {
+		mdb_warn("failed to read iscsi_sess_t at %p", wsp->walk_addr);
+		return (WALK_DONE);
+	}
+
+
+	status = wsp->walk_callback((uintptr_t)hwi->array[hwi->cur_element],
+	    hwi->data, wsp->walk_cbdata);
+
+	/* Increment cur_element for next iteration */
+	hwi->cur_element++;
+
+	return (status);
+}
+
 /*
  * iscsi_inet_ntop -- Convert an IPv4 or IPv6 address in binary form into
  * printable form, and return a pointer to that string. Caller should
@@ -2602,7 +3672,6 @@
 	*--ptr = '\0';
 }
 
-
 /*
  * MDB module linkage information:
  *
@@ -2611,32 +3680,53 @@
  * to our module information.
  */
 static const mdb_dcmd_t dcmds[] = {
-	{   "iscsi_tgt", "[-agsctbSRv]",
+	{   "iscsi_tgt", "[-agscptbSRv]",
 	    "iSCSI target information", iscsi_tgt },
-	{   "iscsi_tpg", "[-v]",
+	{   "iscsi_tpgt", "[-R]",
+	    "iSCSI target portal group tag information", iscsi_tpgt },
+	{   "iscsi_tpg", "[-R]",
 	    "iSCSI target portal group information", iscsi_tpg },
-	{   "iscsi_sess", "[-abtvcSRIT]",
+	{   "iscsi_sess", "[-ablmtvcSRIT]",
 	    "iSCSI session information", iscsi_sess },
-	{   "iscsi_conn", "[-abtvSRIT]",
+	{   "iscsi_conn", "[-abmtvSRIT]",
 	    "iSCSI connection information", iscsi_conn },
 	{   "iscsi_task", "[-bSRv]",
 	    "iSCSI task information", iscsi_task },
 	{   "iscsi_refcnt", "",
-	    "Print audit informtion for idm_refcnt_t", iscsi_refcnt },
+	    "print audit informtion for idm_refcnt_t", iscsi_refcnt },
 	{   "iscsi_states", "",
-	    "Dump events and state transitions recorded in an\t"
+	    "dump events and state transitions recorded in an\t"
 	    "\t\tidm_sm_audit_t structure", iscsi_states },
-	{   "iscsi_isns", "[-epstv]",
-	    "Print iscsit iSNS information", iscsi_isns, iscsi_isns_help },
+	{   "iscsi_isns", "[-epstvR]",
+	    "print iscsit iSNS information", iscsi_isns, iscsi_isns_help },
+	{   "iscsi_svc", "[-vR]",
+	    "iSCSI service information", iscsi_svc },
+	{   "iscsi_portal", "[-R]",
+	    "iSCSI portal information", iscsi_portal },
+	{   "iscsi_cmd", "[-S]",
+	    "iSCSI command information (initiator only)", iscsi_cmd },
 	{ NULL }
 };
 
 /*
- * No walkers for now.  Initiator might need some since it doesn't use list_t
+ * Basic walkers for the initiator linked lists
  */
+static const mdb_walker_t walkers[] = {
+	{ "iscsi_ini_hba", "global walk of the initiator iscsi_hba_t "
+	    "list", iscsi_ini_hba_walk_init, iscsi_ini_hba_step, NULL},
+	{ "iscsi_ini_sess", "walk list of initiator iscsi_sess_t structures",
+	    iscsi_ini_sess_walk_init, iscsi_ini_sess_step, NULL },
+	{ "iscsi_ini_conn", "walk list of initiator iscsi_conn_t structures",
+	    iscsi_ini_conn_walk_init, iscsi_ini_conn_step, NULL },
+	{ "iscsi_ini_lun", "walk list of initiator iscsi_lun_t structures",
+	    iscsi_ini_lun_walk_init, iscsi_ini_lun_step, NULL },
+	{ "iscsi_ini_cmd", "walk list of initiator iscsi_cmd_t structures",
+	    iscsi_ini_cmd_walk_init, iscsi_ini_cmd_step, NULL },
+	{ NULL }
+};
 
 static const mdb_modinfo_t modinfo = {
-	MDB_API_VERSION, dcmds, NULL
+	MDB_API_VERSION, dcmds, walkers
 };
 
 const mdb_modinfo_t *
--- a/usr/src/cmd/mdb/intel/amd64/idm/Makefile	Fri Apr 09 11:20:11 2010 -0700
+++ b/usr/src/cmd/mdb/intel/amd64/idm/Makefile	Fri Apr 09 14:59:31 2010 -0400
@@ -19,8 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 MODULE = idm.so
@@ -30,6 +29,7 @@
 
 ISCSITBASE = ../../../../../uts/common/io/comstar/port/iscsit
 ISCSIBASE = ../../../../../uts/common/io/scsi/adapters/iscsi
+ISERBASE = ../../../../../uts/common
 
 include ../../../../Makefile.cmd
 include ../../../../Makefile.cmd.64
@@ -38,3 +38,4 @@
 
 CPPFLAGS += -I$(ISCSITBASE)
 CPPFLAGS += -I$(ISCSIBASE)
+CPPFLAGS += -I$(ISERBASE)
--- a/usr/src/cmd/mdb/intel/ia32/idm/Makefile	Fri Apr 09 11:20:11 2010 -0700
+++ b/usr/src/cmd/mdb/intel/ia32/idm/Makefile	Fri Apr 09 14:59:31 2010 -0400
@@ -19,8 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 MODULE = idm.so
@@ -30,6 +29,7 @@
 
 ISCSITBASE = ../../../../../uts/common/io/comstar/port/iscsit
 ISCSIBASE = ../../../../../uts/common/io/scsi/adapters/iscsi
+ISERBASE = ../../../../../uts/common
 
 include ../../../../Makefile.cmd
 include ../../Makefile.ia32
@@ -37,3 +37,4 @@
 
 CPPFLAGS += -I$(ISCSITBASE)
 CPPFLAGS += -I$(ISCSIBASE)
+CPPFLAGS += -I$(ISERBASE)
--- a/usr/src/cmd/mdb/sparc/v9/idm/Makefile	Fri Apr 09 11:20:11 2010 -0700
+++ b/usr/src/cmd/mdb/sparc/v9/idm/Makefile	Fri Apr 09 14:59:31 2010 -0400
@@ -19,8 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 MODULE = idm.so
@@ -30,6 +29,7 @@
 
 ISCSITBASE = ../../../../../uts/common/io/comstar/port/iscsit
 ISCSIBASE = ../../../../../uts/common/io/scsi/adapters/iscsi
+ISERBASE = ../../../../../uts/common
 
 include ../../../../Makefile.cmd
 include ../../../../Makefile.cmd.64
@@ -38,3 +38,4 @@
 
 CPPFLAGS += -I$(ISCSITBASE)
 CPPFLAGS += -I$(ISCSIBASE)
+CPPFLAGS += -I$(ISERBASE)