changeset 12750:f559965e4a2f

6817374 stmf_scsi_session:ss_rport_id is insufficient for some SCSI transports
author Nattuvetty Bhavyan <Nattuvetty.Bhavyan@Sun.COM>
date Thu, 01 Jul 2010 16:06:54 -0700
parents cd0d8608930c
children e426f0a40b0e
files usr/src/cmd/mdb/common/modules/stmf_sbd/stmf_sbd.c usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_impl.h usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_pgr.c usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c usr/src/uts/common/io/comstar/port/iscsit/iscsit_login.c usr/src/uts/common/io/comstar/port/iscsit/iscsit_sess.c usr/src/uts/common/io/comstar/port/pppt/alua_ic_if.c usr/src/uts/common/io/comstar/port/pppt/pppt.c usr/src/uts/common/io/comstar/port/pppt/pppt.h usr/src/uts/common/io/comstar/port/pppt/pppt_msg.c usr/src/uts/common/io/comstar/port/srpt/srpt_stp.c usr/src/uts/common/io/comstar/stmf/stmf.c usr/src/uts/common/io/comstar/stmf/stmf_impl.h usr/src/uts/common/sys/portif.h usr/src/uts/common/sys/pppt_ic_if.h usr/src/uts/common/sys/scsi/generic/persist.h usr/src/uts/common/sys/stmf.h usr/src/uts/common/sys/stmf_defines.h
diffstat 18 files changed, 947 insertions(+), 434 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/mdb/common/modules/stmf_sbd/stmf_sbd.c	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/cmd/mdb/common/modules/stmf_sbd/stmf_sbd.c	Thu Jul 01 16:06:54 2010 -0700
@@ -35,16 +35,18 @@
 #include <sbd_impl.h>
 #include <scsi/generic/persist.h>
 
-#define	STMF_SBD_FLAG_ARY_SZ	32
 #define	STMF_SBD_STR_MAX	2048
 #define	STMF_SBD_VERBOSE	0x00000001
 
+#define	ARRAY_SIZE(a)	(sizeof (a) / sizeof (*a))
+
 /* structure to pass arguments to mdb_walker callback function */
 typedef struct stmf_sbd_cb_s {
 	uint32_t flag;
 } stmf_sbd_cb_t;
 
-char stmf_protocol_str [9][STMF_SBD_FLAG_ARY_SZ] = {
+
+static const char *stmf_protocol_str[] = {
 	"FIBRE_CHANNEL",	/* PROTOCOL_FIBRE_CHANNEL	0 */
 	"PARALLEL_SCSI",	/* PROTOCOL_PARALLEL_SCSI	1 */
 	"SSA",			/* PROTOCOL_SSA			2 */
@@ -53,21 +55,29 @@
 	"iSCSI",		/* PROTOCOL_iSCSI		5 */
 	"SAS",			/* PROTOCOL_SAS			6 */
 	"ADT",			/* PROTOCOL_ADT			7 */
-	"ATAPI",		/* PROTOCOL_ATAPI		8 */
+	"ATAPI"			/* PROTOCOL_ATAPI		8 */
 };
 
+
 /*
  * Support functions.
  */
 
+static uint64_t
+nhconvert_8bytes(const void *src) {
+	uint64_t dest;
+	mdb_nhconvert(&dest, src, 8);
+	return (dest);
+}
+
 /*
  *        Variable 'bits' is a collection of flags for which a corresponding
  *        description string is available at flag_ary.
- *        So flag_ary should be an ary of strings with total_bits + 1 strings.
+ *        So flag_ary should be an ary of strings with total_bits strings.
  */
 static void
-stmf_sbd_print_bit_flags(char flag_ary[][STMF_SBD_FLAG_ARY_SZ],
-					int total_bits, uint32_t bits) {
+stmf_sbd_print_bit_flags(const char *flag_ary[],
+				int total_bits, uint32_t bits) {
 	uint32_t curbit = 0x01;
 	int i, delim = 0;
 
@@ -85,26 +95,28 @@
 static void
 stmf_sbd_print_pgr_info(sbd_pgr_t *pgr)
 {
-	char pgr_flag_str [5][STMF_SBD_FLAG_ARY_SZ] = {
+	static const char *pgr_flag_str[] = {
 		"SBD_PGR_APTPL",			/* 0x01 */
 		"SBD_PGR_RSVD_ONE",			/* 0x02 */
 		"SBD_PGR_RSVD_ALL_REGISTRANTS",		/* 0x04 */
 		"SBD_PGR_ALL_KEYS_HAS_IT"		/* 0x08 */
 	};
-	char pgr_type_desc[9][48] = {"ILLEGAL",
-	    "Write Exclusive",				/* 0x1 */
-	    "ILLEGAL",
-	    "Exclusive Access",				/* 0x3 */
-	    "Write Exclusive, Registrants Only",	/* 0x5 */
-	    "Exclusive Access, Registrants Only",	/* 0x6 */
-	    "Write Exclusive, All Registrants",		/* 0x7 */
-	    "Exclusive Access, All Registrants"		/* 0x8 */
+
+	static const char *pgr_type_desc[] = {
+		"ILLEGAL",				/* 0x0 */
+		"Write Exclusive",			/* 0x1 */
+		"ILLEGAL",				/* 0x2 */
+		"Exclusive Access",			/* 0x3 */
+		"ILLEGAL",				/* 0x4 */
+		"Write Exclusive, Registrants Only",	/* 0x5 */
+		"Exclusive Access, Registrants Only",	/* 0x6 */
+		"Write Exclusive, All Registrants",	/* 0x7 */
+		"Exclusive Access, All Registrants"	/* 0x8 */
 	};
-	char *type_str = pgr_type_desc[0];
-
 
 	mdb_printf("PGR flags: ");
-	stmf_sbd_print_bit_flags(pgr_flag_str, 4, pgr->pgr_flags);
+	stmf_sbd_print_bit_flags(pgr_flag_str, ARRAY_SIZE(pgr_flag_str),
+	    pgr->pgr_flags);
 	if (pgr->pgr_rsvholder || pgr->pgr_flags &
 	    SBD_PGR_RSVD_ALL_REGISTRANTS) {
 		mdb_printf("Reservation Details \n");
@@ -113,10 +125,11 @@
 			mdb_printf("%p\n", pgr->pgr_rsvholder);
 		else
 			mdb_printf("All Registrants\n");
-		if (pgr->pgr_rsv_type < 8)
-			type_str = pgr_type_desc[pgr->pgr_rsv_type];
+
 		mdb_printf("\t            type  : %d => %s\n",
-		    pgr->pgr_rsv_type, type_str);
+		    pgr->pgr_rsv_type,
+		    (pgr->pgr_rsv_type < ARRAY_SIZE(pgr_type_desc)) ?
+		    pgr_type_desc[pgr->pgr_rsv_type] : "ILLEGAL");
 		mdb_printf("\t            scope : %d\n", pgr->pgr_rsv_scope);
 	} else {
 		mdb_printf("No reservations.\n");
@@ -124,10 +137,16 @@
 }
 
 void
-print_scsi_devid_desc(uintptr_t addr, uint16_t len, char *s)
+print_scsi_devid_desc(uintptr_t addr, uint16_t len, char *spacer)
 {
 	scsi_devid_desc_t   *id;
 
+	if (len < sizeof (*id)) {
+		mdb_warn("%sError: Devid Size = %d < sizeof(scsi_devid_desc_t)"
+		    "\n", spacer, len);
+		return;
+	}
+
 	id = mdb_zalloc(len, UM_SLEEP);
 	if (mdb_vread(id, len, addr) == -1) {
 		mdb_warn("failed to read scsi_devid_desc at %p\n", addr);
@@ -135,22 +154,85 @@
 		return;
 	}
 
-	mdb_printf("%sTotal length:\t%d\n", s, len);
-	mdb_printf("%sProtocol:\t%d => %-16s\n", s, id->protocol_id,
-	    (id->protocol_id < 8) ? stmf_protocol_str[id->protocol_id] : "");
-	mdb_printf("%sCode Set:\t%d\n", s, id->code_set);
-	mdb_printf("%sIdent Length:\t%d\n", s, id->ident_length);
+	mdb_printf("%sTotal length:\t%d\n", spacer, len);
+	mdb_printf("%sProtocol:\t%d => %-16s\n", spacer, id->protocol_id,
+	    (id->protocol_id < ARRAY_SIZE(stmf_protocol_str)) ?
+	    stmf_protocol_str[id->protocol_id] : "");
+	mdb_printf("%sCode Set:\t%d\n", spacer, id->code_set);
+	mdb_printf("%sIdent Length:\t%d\n", spacer, id->ident_length);
 
-	if (len > id->ident_length + 3) {
+	if (len < sizeof (*id) + id->ident_length - 1) {
+		mdb_printf("%s(Can not recognize ident data)\n", spacer);
+	} else {
 		id->ident[id->ident_length] = '\0';
-		mdb_printf("%sIdent:\t%s\n", s, id->ident);
-	} else {
-		mdb_printf("%s(Can not recognize ident data)\n", s);
+		mdb_printf("%sIdent:\t\t%s\n", spacer, id->ident);
 	}
 	mdb_free(id, len);
 	mdb_printf("\n");
 }
 
+/*
+ * Decipher and print transport id  which is pointed by addr variable.
+ */
+static int
+print_transport_id(uintptr_t addr, uint16_t tpd_len, char *spacer)
+{
+	scsi_transport_id_t *tpd;
+
+	if (tpd_len < sizeof (*tpd)) {
+		mdb_warn("%sError: Transport ID Size = %d < "
+		    "sizeof (scsi_transport_id_t)\n", spacer, tpd_len);
+		return (DCMD_ERR);
+	}
+
+	tpd = mdb_zalloc(tpd_len, UM_SLEEP);
+	if (mdb_vread(tpd, tpd_len, addr) == -1) {
+		mdb_warn("failed to read scsi_transport_id at %p\n", addr);
+		mdb_free(tpd, tpd_len);
+		return (DCMD_ERR);
+	}
+
+	mdb_printf("%sTotal length:\t%d\n", spacer, tpd_len);
+	mdb_printf("%sProtocol:\t%d => %16s\n", spacer, tpd->protocol_id,
+	    (tpd->protocol_id < ARRAY_SIZE(stmf_protocol_str)) ?
+	    stmf_protocol_str[tpd->protocol_id] : "");
+	mdb_printf("%sFormat Code:\t0x%x\n", spacer, tpd->format_code);
+
+	switch (tpd->protocol_id) {
+	case PROTOCOL_FIBRE_CHANNEL:
+		{
+		uint8_t *p = ((scsi_fc_transport_id_t *)tpd)->port_name;
+		mdb_printf("%sFC Port Name:\t%016llX\n", spacer,
+		    nhconvert_8bytes(p));
+		}
+		break;
+	case PROTOCOL_PARALLEL_SCSI:
+	case PROTOCOL_SSA:
+	case PROTOCOL_IEEE_1394:
+		break;
+	case PROTOCOL_SRP:
+		{
+		uint8_t *p = ((scsi_srp_transport_id_t *)tpd)->srp_name;
+		/* Print 8 byte initiator extention and guid in order */
+		mdb_printf("%sSRP Name:\t%016llX:%016llX\n", spacer,
+		    nhconvert_8bytes(&p[8]), nhconvert_8bytes(&p[0]));
+		}
+		break;
+	case PROTOCOL_iSCSI:
+		mdb_printf("%sISCSI Name:\t%s\n", spacer,
+		    ((iscsi_transport_id_t *)tpd)->iscsi_name);
+		break;
+	case PROTOCOL_SAS:
+	case PROTOCOL_ADT:
+	case PROTOCOL_ATAPI:
+	default:
+		break;
+	}
+
+	mdb_free(tpd, tpd_len);
+	return (DCMD_OK);
+}
+
 void
 stmf_sbd_pgr_key_dcmd_help(void)
 {
@@ -214,7 +296,12 @@
 	if (cb_st->flag & STMF_SBD_VERBOSE) {
 		char str[STMF_SBD_STR_MAX];
 
-		mdb_printf("sbd_lu - %p\n", addr);
+		mdb_printf("\nsbd_lu - %p\n", addr);
+
+		/* sl_device_id contains 4 bytes hdr + 16 bytes(GUID) */
+		mdb_printf("\tsl_deviceid:      %-?p  GUID => %016llX%016llX\n",
+		    slu->sl_device_id, nhconvert_8bytes(&slu->sl_device_id[4]),
+		    nhconvert_8bytes(&slu->sl_device_id[12]));
 		mdb_printf("\tsl_name:          %-?p  %s\n", slu->sl_name,
 		    stmf_sbd_getstr((uintptr_t)slu->sl_name, str));
 		mdb_printf("\tsl_alias:         %-?p  %s\n", slu->sl_alias,
@@ -230,7 +317,6 @@
 		mdb_printf("\tsl_zfs_meta:      %-?p\n", slu->sl_zfs_meta);
 		mdb_printf("\tsl_it_list:       %-?p\n", slu->sl_it_list);
 		mdb_printf("\tsl_pgr:           %-?p\n", slu->sl_pgr);
-		mdb_printf("\n");
 	} else {
 		mdb_printf("%p\n", addr);
 	}
@@ -268,24 +354,25 @@
 stmf_sbd_pgr_key_cb(uintptr_t addr, const sbd_pgr_key_t *key,
 					stmf_sbd_cb_t *cb_st)
 {
-	char key_flag_str [5][STMF_SBD_FLAG_ARY_SZ] = {
+	static const char *key_flag_str [] = {
 		"SBD_PGR_KEY_ALL_TG_PT",   /* 0x01 */
-		"SBD_PGR_KEY_TPT_ID_FLAG", /* 0x02 */
+		"SBD_PGR_KEY_TPT_ID_FLAG"  /* 0x02 */
 	};
 
 	if (cb_st->flag & STMF_SBD_VERBOSE) {
 		mdb_printf("sbd_pgr_key - %p\n", addr);
-		mdb_printf("\tRegistered key:      0x%llx\n", key->pgr_key);
+		mdb_printf("\tRegistered key:      0x%016llx\n", key->pgr_key);
 		mdb_printf("\tKey Flags:           ");
-		stmf_sbd_print_bit_flags(key_flag_str, 2, key->pgr_key_flags);
+		stmf_sbd_print_bit_flags(key_flag_str, ARRAY_SIZE(key_flag_str),
+		    key->pgr_key_flags);
 		mdb_printf("\tpgr_key_it:          %?-p\n", key->pgr_key_it);
 		mdb_printf("\tLocal Device ID:     %?-p\n",
 		    key->pgr_key_lpt_id);
 		print_scsi_devid_desc((uintptr_t)key->pgr_key_lpt_id,
 		    key->pgr_key_lpt_len, "		");
-		mdb_printf("\tRemote scsi devid desc: %?-p\n",
+		mdb_printf("\tRemote Transport ID: %?-p\n",
 		    key->pgr_key_rpt_id);
-		print_scsi_devid_desc((uintptr_t)key->pgr_key_rpt_id,
+		print_transport_id((uintptr_t)key->pgr_key_rpt_id,
 		    key->pgr_key_rpt_len, "		");
 	} else {
 		mdb_printf("%p\n", addr);
@@ -323,20 +410,20 @@
 static int
 stmf_sbd_it_cb(uintptr_t addr, const sbd_it_data_t *it, stmf_sbd_cb_t *cb_st)
 {
-	char it_flag_str [5][STMF_SBD_FLAG_ARY_SZ] = {
+	static const char *it_flag_str [] = {
 		"SBD_IT_HAS_SCSI2_RESERVATION",		/* 0x0001 */
 		"SBD_IT_PGR_REGISTERED",		/* 0x0002 */
 		"SBD_IT_PGR_EXCLUSIVE_RSV_HOLDER",	/* 0x0004 */
-		"SBD_IT_PGR_CHECK_FLAG",		/* 0x0008 */
+		"SBD_IT_PGR_CHECK_FLAG"			/* 0x0008 */
 	};
 
 	if (cb_st->flag & STMF_SBD_VERBOSE) {
 		mdb_printf("SBD IT DATA - %p\n", addr);
 		mdb_printf("\tSession ID: 0x%0-lx\n", it->sbd_it_session_id);
 		mdb_printf("\tIT Flags:   ");
-		stmf_sbd_print_bit_flags(it_flag_str, 4, it->sbd_it_flags);
+		stmf_sbd_print_bit_flags(it_flag_str, ARRAY_SIZE(it_flag_str),
+		    it->sbd_it_flags);
 		mdb_printf("\tPGR Key:    %-p\n", it->pgr_key_ptr);
-		mdb_printf("\n");
 	} else {
 		mdb_printf("%p\n", addr);
 	}
@@ -451,6 +538,26 @@
 	return (DCMD_OK);
 }
 
+/*ARGSUSED*/
+static int
+stmf_remote_port(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+	stmf_remote_port_t rpt;
+	int	ret = DCMD_OK;
+
+	if (!(flags & DCMD_ADDRSPEC))
+		return (DCMD_USAGE);
+
+	if (mdb_vread(&rpt, sizeof (stmf_remote_port_t), addr) == -1) {
+		mdb_warn("failed to read stmf_remote_port_t at %p\n", addr);
+		return (DCMD_ERR);
+	}
+
+	ret = print_transport_id((uintptr_t)rpt.rport_tptid,
+	    rpt.rport_tptid_sz, "		");
+	return (ret);
+}
+
 static int
 stmf_sbd_it(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 {
@@ -467,7 +574,7 @@
 
 	if (verbose) {
 		cb_st.flag |= STMF_SBD_VERBOSE;
-		mdb_printf("LU:- %p\n", addr);
+		mdb_printf("\nLU:- %p\n", addr);
 	}
 
 	/* If address of pgr_key is given, just print that key and return */
@@ -479,7 +586,7 @@
 	/* Just a sanity check, not necessarily needed */
 	if (slu.sl_it_list == NULL) {
 		if (verbose)
-			mdb_warn("sbd_it_list is empty%p\n", addr);
+			mdb_printf("sbd_it_list is empty\n", addr);
 		return (DCMD_OK);
 	}
 
@@ -502,6 +609,8 @@
 	    stmf_sbd_it, NULL },
 	{ "stmf_sbd_pgr_key", ":[-kov]", "Print the list of pgr keys",
 	    stmf_sbd_pgr_key, stmf_sbd_pgr_key_dcmd_help },
+	{ "stmf_remote_port", ":", "decipher info in a stmf_remote_port",
+	    stmf_remote_port, NULL },
 	{ NULL }
 };
 
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_impl.h	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_impl.h	Thu Jul 01 16:06:54 2010 -0700
@@ -110,14 +110,15 @@
  * PGR key flags
  */
 #define	SBD_PGR_KEY_ALL_TG_PT		0x01
+#define	SBD_PGR_KEY_TPT_ID_FLAG		0x02
 
 typedef struct sbd_pgr_key_info {
 	uint64_t	pgr_key;
 	uint16_t	pgr_key_lpt_len;
 	uint16_t	pgr_key_rpt_len;
 	uint8_t		pgr_key_flags;
-	uint8_t		pgr_key_it[1];	/* devid_desc of initiator will be */
-					/* followed by devid_desc of target */
+	uint8_t		pgr_key_it[1];	/* order:- initiator info followed by */
+					/* scsi_devid_desc of local port */
 } sbd_pgr_key_info_t;
 
 typedef struct sbd_pgr_info {
@@ -143,7 +144,7 @@
 	uint16_t		pgr_key_rpt_len;
 	uint8_t			pgr_key_flags;
 	struct scsi_devid_desc	*pgr_key_lpt_id;
-	struct scsi_devid_desc	*pgr_key_rpt_id;
+	struct scsi_transport_id *pgr_key_rpt_id;
 	struct sbd_it_data	*pgr_key_it;
 	struct sbd_pgr_key	*pgr_key_next;
 	struct sbd_pgr_key	*pgr_key_prev;
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_pgr.c	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_pgr.c	Thu Jul 01 16:06:54 2010 -0700
@@ -46,11 +46,7 @@
 void sbd_handle_pgr_out_cmd(scsi_task_t *, stmf_data_buf_t *);
 void sbd_handle_pgr_out_data(scsi_task_t *, stmf_data_buf_t *);
 void sbd_pgr_keylist_dealloc(sbd_lu_t *);
-uint32_t sbd_get_tptid_length_for_devid(scsi_devid_desc_t *);
-uint32_t sbd_devid_desc_to_tptid(scsi_devid_desc_t *, scsi_transport_id_t *);
-scsi_devid_desc_t *sbd_tptid_to_devid_desc(scsi_transport_id_t *, uint32_t *);
 char *sbd_get_devid_string(sbd_lu_t *);
-void sbd_base16_str_to_binary(char *c, int, uint8_t *);
 
 sbd_status_t sbd_pgr_meta_init(sbd_lu_t *);
 sbd_status_t sbd_pgr_meta_load(sbd_lu_t *);
@@ -62,9 +58,9 @@
 static uint32_t sbd_pgr_remove_keys(sbd_lu_t *, sbd_it_data_t *,
 	sbd_pgr_key_t *, uint64_t, boolean_t);
 static boolean_t sbd_pgr_key_compare(sbd_pgr_key_t *, scsi_devid_desc_t *,
-	scsi_devid_desc_t *rpt);
+	stmf_remote_port_t *);
 static sbd_pgr_key_t *sbd_pgr_key_alloc(scsi_devid_desc_t *,
-	scsi_devid_desc_t *, int8_t, int8_t);
+	scsi_transport_id_t *, int16_t, int16_t);
 
 static void sbd_pgr_set_pgr_check_flag(sbd_lu_t *, boolean_t);
 static void sbd_pgr_set_ua_conditions(sbd_lu_t *, sbd_it_data_t *, uint8_t);
@@ -80,7 +76,7 @@
 static void sbd_pgr_out_register_and_move(scsi_task_t *, stmf_data_buf_t *);
 
 static sbd_pgr_key_t *sbd_pgr_do_register(sbd_lu_t *, sbd_it_data_t *,
-	scsi_devid_desc_t *, scsi_devid_desc_t *, uint8_t, uint64_t);
+	scsi_devid_desc_t *, stmf_remote_port_t *, uint8_t, uint64_t);
 static void sbd_pgr_do_unregister(sbd_lu_t *, sbd_it_data_t *, sbd_pgr_key_t *);
 static void sbd_pgr_do_release(sbd_lu_t *, sbd_it_data_t *, uint8_t);
 static void sbd_pgr_do_reserve(sbd_pgr_t *, sbd_pgr_key_t *, sbd_it_data_t *it,
@@ -259,7 +255,7 @@
 				((type) == PGR_TYPE_WR_EX_AR)	|| \
 				((type) == PGR_TYPE_EX_AC_AR))
 
-#define	ALIGNED_TO_WORD_BOUNDARY(i)	(((i) + 7) & ~7)
+#define	ALIGNED_TO_8BYTE_BOUNDARY(i)	(((i) + 7) & ~7)
 
 static void
 sbd_swap_pgr_info(sbd_pgr_info_t *spi)
@@ -307,7 +303,7 @@
 	sbd_pgr_key_t		*key, *last_key = NULL;
 	sbd_pgr_key_info_t	*spi_key;
 	sbd_status_t		ret = SBD_SUCCESS;
-	scsi_devid_desc_t	*lpt, *rpt;
+	scsi_devid_desc_t	*lpt;
 	uint8_t			*ptr, *keyoffset,  *endoffset;
 	uint32_t		i, sz;
 
@@ -321,6 +317,7 @@
 		}
 		return (ret);
 	}
+
 	if (spi->pgr_data_order != SMS_DATA_ORDER) {
 		sbd_swap_pgr_info(spi);
 	}
@@ -332,6 +329,7 @@
 	} else {
 		PGR_CLEAR_RSV_FLAG(pgr->pgr_flags);
 	}
+
 	PGR_CLEAR_FLAG(slu->sl_pgr->pgr_flags, SBD_PGR_ALL_KEYS_HAS_IT);
 
 	endoffset	= (uint8_t *)spi;
@@ -345,7 +343,7 @@
 		}
 
 		/* Calculate the size and next offset */
-		sz = ALIGNED_TO_WORD_BOUNDARY(sizeof (sbd_pgr_key_info_t) - 1 +
+		sz = ALIGNED_TO_8BYTE_BOUNDARY(sizeof (sbd_pgr_key_info_t) - 1 +
 		    spi_key->pgr_key_lpt_len + spi_key->pgr_key_rpt_len);
 		keyoffset += sz;
 
@@ -353,20 +351,46 @@
 		if (spi_key->pgr_key_rpt_len == 0 || endoffset < keyoffset ||
 		    (spi_key->pgr_key_lpt_len == 0 &&
 		    !(spi_key->pgr_key_flags & SBD_PGR_KEY_ALL_TG_PT))) {
-			char *lun_name = sbd_get_devid_string(slu);
-			sbd_pgr_keylist_dealloc(slu);
-			kmem_free(spi, spi->pgr_sms_header.sms_size);
-			cmn_err(CE_WARN, "sbd_pgr_meta_load: Failed to load "
-			    "PGR meta data for lun %s.", lun_name);
-			kmem_free(lun_name, strlen(lun_name) + 1);
-			return (SBD_META_CORRUPTED);
+			ret = SBD_META_CORRUPTED;
+			goto sbd_pgr_meta_load_failed;
 		}
 
 		lpt = (scsi_devid_desc_t *)spi_key->pgr_key_it;
 		ptr = (uint8_t *)spi_key->pgr_key_it + spi_key->pgr_key_lpt_len;
-		rpt = (scsi_devid_desc_t *)ptr;
-		key = sbd_pgr_key_alloc(lpt, rpt, spi_key->pgr_key_lpt_len,
-		    spi_key->pgr_key_rpt_len);
+
+		if (spi_key->pgr_key_flags & SBD_PGR_KEY_TPT_ID_FLAG) {
+			uint16_t tpd_len = 0;
+
+			if (!stmf_scsilib_tptid_validate(
+			    (scsi_transport_id_t *)ptr,
+			    spi_key->pgr_key_rpt_len, &tpd_len)) {
+				ret = SBD_META_CORRUPTED;
+				goto sbd_pgr_meta_load_failed;
+			}
+			if (tpd_len != spi_key->pgr_key_rpt_len) {
+				ret = SBD_META_CORRUPTED;
+				goto sbd_pgr_meta_load_failed;
+			}
+			key = sbd_pgr_key_alloc(lpt, (scsi_transport_id_t *)ptr,
+			    spi_key->pgr_key_lpt_len, spi_key->pgr_key_rpt_len);
+		} else {
+			stmf_remote_port_t	*rpt = NULL;
+
+			/*
+			 * This block is executed only if the metadata was
+			 * stored before the implementation of Transport ID
+			 * support.
+			 */
+			rpt = stmf_scsilib_devid_to_remote_port(
+			    (scsi_devid_desc_t *)ptr);
+			if (rpt == NULL) {
+				ret = SBD_META_CORRUPTED;
+				goto sbd_pgr_meta_load_failed;
+			}
+			key = sbd_pgr_key_alloc(lpt, rpt->rport_tptid,
+			    spi_key->pgr_key_lpt_len, rpt->rport_tptid_sz);
+			stmf_remote_port_free(rpt);
+		}
 
 		key->pgr_key		= spi_key->pgr_key;
 		key->pgr_key_flags	= spi_key->pgr_key_flags;
@@ -387,6 +411,17 @@
 
 	kmem_free(spi, spi->pgr_sms_header.sms_size);
 	return (ret);
+
+sbd_pgr_meta_load_failed:
+	{
+	char *lun_name = sbd_get_devid_string(slu);
+	sbd_pgr_keylist_dealloc(slu);
+	kmem_free(spi, spi->pgr_sms_header.sms_size);
+	cmn_err(CE_WARN, "sbd_pgr_meta_load: Failed to load PGR meta data "
+	    "for lun %s.", lun_name);
+	kmem_free(lun_name, strlen(lun_name) + 1);
+	return (ret);
+	}
 }
 
 sbd_status_t
@@ -404,7 +439,7 @@
 	if (pgr->pgr_flags & SBD_PGR_APTPL) {
 		key = pgr->pgr_keylist;
 		while (key != NULL) {
-			sz = ALIGNED_TO_WORD_BOUNDARY(sz +
+			sz = ALIGNED_TO_8BYTE_BOUNDARY(sz +
 			    sizeof (sbd_pgr_key_info_t) - 1 +
 			    key->pgr_key_lpt_len + key->pgr_key_rpt_len);
 			key = key->pgr_key_next;
@@ -430,6 +465,7 @@
 		while (key != NULL) {
 			spi_key = (sbd_pgr_key_info_t *)((uint8_t *)spi + sz);
 			spi_key->pgr_key = key->pgr_key;
+			spi_key->pgr_key_flags = key->pgr_key_flags;
 			spi_key->pgr_key_lpt_len = key->pgr_key_lpt_len;
 			spi_key->pgr_key_rpt_len = key->pgr_key_rpt_len;
 			ptr = spi_key->pgr_key_it;
@@ -442,7 +478,7 @@
 				spi->pgr_rsvholder_indx = spi->pgr_numkeys;
 			}
 
-			sz = ALIGNED_TO_WORD_BOUNDARY(sz +
+			sz = ALIGNED_TO_8BYTE_BOUNDARY(sz +
 			    sizeof (sbd_pgr_key_info_t) - 1 +
 			    key->pgr_key_lpt_len + key->pgr_key_rpt_len);
 			key = key->pgr_key_next;
@@ -476,25 +512,24 @@
 }
 
 static sbd_pgr_key_t *
-sbd_pgr_key_alloc(scsi_devid_desc_t *lptid, scsi_devid_desc_t *rptid,
-					int8_t lpt_len, int8_t rpt_len)
+sbd_pgr_key_alloc(scsi_devid_desc_t *lptid, scsi_transport_id_t *rptid,
+					int16_t lpt_len, int16_t rpt_len)
 {
 	sbd_pgr_key_t *key;
 
 	key = (sbd_pgr_key_t *)kmem_zalloc(sizeof (sbd_pgr_key_t), KM_SLEEP);
 
-	if (lpt_len >= sizeof (scsi_devid_desc_t)) {
-		ASSERT(lptid);
+	if (lptid && lpt_len >= sizeof (scsi_devid_desc_t)) {
 		key->pgr_key_lpt_len = lpt_len;
 		key->pgr_key_lpt_id  = (scsi_devid_desc_t *)kmem_zalloc(
 		    lpt_len, KM_SLEEP);
 		bcopy(lptid, key->pgr_key_lpt_id, lpt_len);
 	}
 
-	if (rpt_len >= sizeof (scsi_devid_desc_t)) {
-		ASSERT(rptid);
+	if (rptid && rpt_len >= sizeof (scsi_transport_id_t)) {
+		key->pgr_key_flags |= SBD_PGR_KEY_TPT_ID_FLAG;
 		key->pgr_key_rpt_len = rpt_len;
-		key->pgr_key_rpt_id  = (scsi_devid_desc_t *)kmem_zalloc(
+		key->pgr_key_rpt_id  = (scsi_transport_id_t *)kmem_zalloc(
 		    rpt_len, KM_SLEEP);
 		bcopy(rptid, key->pgr_key_rpt_id, rpt_len);
 	}
@@ -673,15 +708,12 @@
 
 static boolean_t
 sbd_pgr_key_compare(sbd_pgr_key_t *key, scsi_devid_desc_t *lpt,
-					scsi_devid_desc_t *rpt)
+					stmf_remote_port_t *rpt)
 {
 	scsi_devid_desc_t *id;
 
-	id = key->pgr_key_rpt_id;
-	if ((rpt->ident_length != id->ident_length) ||
-	    (memcmp(id->ident, rpt->ident, id->ident_length) != 0)) {
+	if (!stmf_scsilib_tptid_compare(rpt->rport_tptid, key->pgr_key_rpt_id))
 			return (B_FALSE);
-	}
 
 	/*
 	 * You can skip target port name comparison if ALL_TG_PT flag
@@ -691,7 +723,7 @@
 		id = key->pgr_key_lpt_id;
 		if ((lpt->ident_length != id->ident_length) ||
 		    (memcmp(id->ident, lpt->ident, id->ident_length) != 0)) {
-				return (B_FALSE);
+			return (B_FALSE);
 		}
 	}
 	return (B_TRUE);
@@ -700,7 +732,7 @@
 
 sbd_pgr_key_t *
 sbd_pgr_key_registered(sbd_pgr_t *pgr, scsi_devid_desc_t *lpt,
-					scsi_devid_desc_t *rpt)
+					stmf_remote_port_t *rpt)
 {
 	sbd_pgr_key_t *key;
 
@@ -719,11 +751,13 @@
 	stmf_scsi_session_t	*ses = task->task_session;
 	sbd_pgr_t		*pgr = slu->sl_pgr;
 	sbd_pgr_key_t		*key;
-	scsi_devid_desc_t	*lpt, *rpt, *id;
+	scsi_devid_desc_t	*lpt, *id;
+	stmf_remote_port_t	*rpt;
 
 	if (pgr->pgr_flags & SBD_PGR_ALL_KEYS_HAS_IT)
 		return;
-	rpt = ses->ss_rport_id;
+
+	rpt = ses->ss_rport;
 	lpt = ses->ss_lport->lport_id;
 
 	rw_enter(&pgr->pgr_lock, RW_WRITER);
@@ -929,7 +963,8 @@
 	sbd_pgr_key_t		*key;
 	scsi_prout_plist_t	*plist;
 	uint64_t		rsv_key;
-	uint8_t			*buf, buflen;
+	uint32_t		buflen;
+	uint8_t			*buf;
 
 	ASSERT(task->task_cdb[0] == SCMD_PERSISTENT_RESERVE_OUT);
 
@@ -1125,6 +1160,11 @@
 	    cdb_len, 8);
 }
 
+/* Minimum required size, SPC3 rev23 Table 110 */
+#define	PGR_IN_READ_FULL_STATUS_MINBUFSZ	8
+/* Full Satus Descriptor Fromat size, SPC3 rev23 Table 111 */
+#define	PGR_IN_READ_FULL_STATUS_DESCFMTSZ	24
+
 static void
 sbd_pgr_in_read_full_status(scsi_task_t *task,
 				stmf_data_buf_t *initial_dbuf)
@@ -1134,23 +1174,25 @@
 	sbd_pgr_key_t	*key;
 	scsi_prin_status_t 	*sts;
 	scsi_prin_full_status_t	*buf;
-	uint32_t 		i, buf_size, cdb_len, tptid_len;
+	uint32_t 		i, buf_size, cdb_len;
 	uint8_t			*offset;
 
 	ASSERT(task->task_cdb[0] == SCMD_PERSISTENT_RESERVE_IN);
 	ASSERT(pgr != NULL);
 
+	/* 4 byte allocation length for CDB, SPC3 rev23, Table 101 */
 	cdb_len = READ_SCSI16(&task->task_cdb[7], uint16_t);
 
-	buf_size = 8; /* PRgeneration and additional length fields */
+	/* PRgeneration and additional length fields */
+	buf_size = PGR_IN_READ_FULL_STATUS_MINBUFSZ;
 	for (key = pgr->pgr_keylist; key != NULL; key = key->pgr_key_next) {
-		tptid_len = sbd_get_tptid_length_for_devid(key->pgr_key_rpt_id);
-		buf_size  = buf_size + 24 + tptid_len;
+		buf_size  = buf_size + PGR_IN_READ_FULL_STATUS_DESCFMTSZ +
+		    key->pgr_key_rpt_len;
 	}
 
 	buf = kmem_zalloc(buf_size, KM_SLEEP);
 	SCSI_WRITE32(buf->PRgeneration, pgr->pgr_PRgeneration);
-	SCSI_WRITE32(buf->add_len, buf_size - 8);
+	SCSI_WRITE32(buf->add_len, buf_size - PGR_IN_READ_FULL_STATUS_MINBUFSZ);
 
 	offset	= (uint8_t *)&buf->full_desc[0];
 	key	= pgr->pgr_keylist;
@@ -1171,10 +1213,11 @@
 			SCSI_WRITE16(sts->rel_tgt_port_id,
 			    stmf_scsilib_get_lport_rtid(key->pgr_key_lpt_id));
 		}
-		tptid_len = sbd_devid_desc_to_tptid(key->pgr_key_rpt_id,
-		    &sts->trans_id);
-		SCSI_WRITE32(sts->add_len, tptid_len);
-		offset = offset + tptid_len + 24;
+		SCSI_WRITE32(sts->add_len, key->pgr_key_rpt_len);
+		offset += PGR_IN_READ_FULL_STATUS_DESCFMTSZ;
+		(void) memcpy(offset, key->pgr_key_rpt_id,
+		    key->pgr_key_rpt_len);
+		offset += key->pgr_key_rpt_len;
 		key = key->pgr_key_next;
 		++i;
 	}
@@ -1194,8 +1237,11 @@
 	sbd_it_data_t		*it	= task->task_lu_itl_handle;
 	sbd_pgr_key_t		*key	= it->pgr_key_ptr;
 	scsi_cdb_prout_t	*pr_out	= (scsi_cdb_prout_t *)task->task_cdb;
+	scsi_devid_desc_t	*lpt	= ses->ss_lport->lport_id;
 	scsi_prout_plist_t	*plist;
-	uint8_t			*buf, buflen;
+	stmf_remote_port_t	rport;
+	uint8_t			*buf, keyflag;
+	uint32_t		buflen;
 	uint64_t		rsv_key, svc_key;
 
 	buf = dbuf->db_sglist[0].seg_addr;
@@ -1248,11 +1294,18 @@
 		return;
 	}
 
+	keyflag = SBD_PGR_KEY_TPT_ID_FLAG;
+	if (plist->all_tg_pt) {
+		keyflag |= SBD_PGR_KEY_ALL_TG_PT;
+		lpt = NULL;
+	}
+
 	if (plist->spec_i_pt) {
-		uint8_t *tpd, *tpdmax;
-		uint32_t tpdlen, max_tpdnum, tpdnum, i, adnlen = 0;
-		scsi_devid_desc_t **newdevids;
-		scsi_devid_desc_t *rpt, *lpt = ses->ss_lport->lport_id;
+		uint32_t max_tpdnum, tpdnum, i, adn_len = 0;
+		uint16_t tpd_sz = 0;
+		uint8_t *adn_dat;
+		scsi_transport_id_t *tpd;
+		stmf_remote_port_t *rpt_ary;
 
 		if (pr_out->action == PR_OUT_REGISTER_AND_IGNORE_EXISTING_KEY) {
 			stmf_scsilib_send_status(task, STATUS_CHECK,
@@ -1260,70 +1313,76 @@
 			return;
 		}
 
-		if (plist->all_tg_pt)
-			lpt = NULL;
-
-		/* Validate the given length */
-		if (buflen >= sizeof (scsi_prout_plist_t) - 1 + 4)
-			adnlen = READ_SCSI32(plist->apd, uint32_t);
-		if (adnlen < sizeof (scsi_transport_id_t) + 4 ||
-		    buflen < sizeof (scsi_prout_plist_t) - 1 + adnlen) {
+		/* Length validation SPC3 rev23 Section 6.12.3 and Table 115 */
+		if (buflen >= sizeof (scsi_prout_plist_t) - 1 +
+		    sizeof (uint32_t))
+			adn_len = READ_SCSI32(plist->apd, uint32_t);
+		/* SPC3 rev23, adn_len should be multiple of 4 */
+		if (adn_len % 4 != 0 ||
+		    adn_len < sizeof (scsi_transport_id_t) +
+		    sizeof (uint32_t) ||
+		    buflen < sizeof (scsi_prout_plist_t) - 1 + adn_len) {
 			stmf_scsilib_send_status(task, STATUS_CHECK,
 			    STMF_SAA_PARAM_LIST_LENGTH_ERROR);
 			return;
 		}
-		tpdmax = plist->apd + adnlen + 4;
-		tpdlen = adnlen;
-		max_tpdnum = tpdlen / sizeof (scsi_transport_id_t);
-		newdevids  = kmem_zalloc(sizeof (scsi_devid_desc_t *) *
-		    max_tpdnum, KM_SLEEP);
+
 		tpdnum = 0;
+		adn_dat = plist->apd + sizeof (uint32_t);
+		max_tpdnum = adn_len / sizeof (scsi_transport_id_t);
+		rpt_ary = (stmf_remote_port_t *)kmem_zalloc(
+		    sizeof (stmf_remote_port_t) * max_tpdnum, KM_SLEEP);
+
 		/* Check the validity of given TransportIDs */
-		while (tpdlen != 0) {
-			tpd = tpdmax - tpdlen;
-			rpt = sbd_tptid_to_devid_desc((scsi_transport_id_t *)
-			    tpd, &tpdlen);
-			if (rpt == NULL)
+		while (adn_len != 0) {
+			if (!stmf_scsilib_tptid_validate(
+			    (scsi_transport_id_t *)adn_dat, adn_len, &tpd_sz))
 				break;
+			/* SPC3 rev23, tpd_sz should be multiple of 4 */
+			if (tpd_sz == 0 || tpd_sz % 4 != 0)
+				break;
+			tpd = (scsi_transport_id_t *)adn_dat;
+
 			/* make sure that there is no duplicates */
 			for (i = 0; i < tpdnum; i++) {
-				if (rpt->ident_length ==
-				    newdevids[i]->ident_length &&
-				    (memcmp(rpt->ident, newdevids[i]->ident,
-				    rpt->ident_length) == 0)) {
+				if (stmf_scsilib_tptid_compare(
+				    rpt_ary[i].rport_tptid, tpd))
 					break;
-				}
 			}
-			newdevids[tpdnum] = rpt;
-			tpdnum++;
-			if (i < tpdnum - 1)
+			if (i < tpdnum)
 				break;
+
+			rpt_ary[tpdnum].rport_tptid = tpd;
+			rpt_ary[tpdnum].rport_tptid_sz = tpd_sz;
+
 			/* Check if the given IT nexus is already registered */
-			if (sbd_pgr_key_registered(pgr, lpt, rpt))
+			if (sbd_pgr_key_registered(pgr, lpt, &rpt_ary[tpdnum]))
 				break;
+
+			adn_len -= tpd_sz;
+			adn_dat += tpd_sz;
+			tpdnum++;
 		}
 
-		for (i = 0; i < tpdnum; i++) {
-			rpt = newdevids[i];
-			if (tpdlen == 0) {
-				(void) sbd_pgr_do_register(slu, NULL,
-				    ses->ss_lport->lport_id, rpt,
-				    plist->all_tg_pt, svc_key);
-			}
-			kmem_free(rpt, sizeof (scsi_devid_desc_t) - 1 +
-			    rpt->ident_length);
-		}
-		kmem_free(newdevids,
-		    sizeof (scsi_devid_desc_t *) * max_tpdnum);
-		if (tpdlen != 0) {
+		if (adn_len != 0) {
+			kmem_free(rpt_ary,
+			    sizeof (stmf_remote_port_t) * max_tpdnum);
 			stmf_scsilib_send_status(task, STATUS_CHECK,
 			    STMF_SAA_INVALID_FIELD_IN_CDB);
 			return;
 		}
+
+		for (i = 0; i < tpdnum; i++) {
+			(void) sbd_pgr_do_register(slu, NULL, lpt, &rpt_ary[i],
+			    keyflag, svc_key);
+		}
+		kmem_free(rpt_ary, sizeof (stmf_remote_port_t) * max_tpdnum);
 	}
 
-	(void) sbd_pgr_do_register(slu, it, ses->ss_lport->lport_id,
-	    ses->ss_rport_id, plist->all_tg_pt, svc_key);
+	rport.rport_tptid = ses->ss_rport->rport_tptid;
+	rport.rport_tptid_sz = ses->ss_rport->rport_tptid_sz;
+
+	(void) sbd_pgr_do_register(slu, it, lpt, &rport, keyflag, svc_key);
 
 sbd_pgr_reg_done:
 
@@ -1346,20 +1405,21 @@
 
 static sbd_pgr_key_t *
 sbd_pgr_do_register(sbd_lu_t *slu, sbd_it_data_t *it, scsi_devid_desc_t *lpt,
-		scsi_devid_desc_t *rpt,	uint8_t all_tg_pt, uint64_t svc_key)
+		stmf_remote_port_t *rpt, uint8_t keyflag, uint64_t svc_key)
 {
 	sbd_pgr_t		*pgr = slu->sl_pgr;
 	sbd_pgr_key_t		*key;
-	uint16_t		lpt_len, rpt_len;
+	uint16_t		lpt_len = 0;
 
-	lpt_len	= sizeof (scsi_devid_desc_t) - 1 + lpt->ident_length;
-	rpt_len	= sizeof (scsi_devid_desc_t) - 1 + rpt->ident_length;
+	if (lpt)
+		lpt_len	= sizeof (scsi_devid_desc_t) + lpt->ident_length;
 
-	key = sbd_pgr_key_alloc(lpt, rpt, lpt_len, rpt_len);
+	key = sbd_pgr_key_alloc(lpt, rpt->rport_tptid,
+	    lpt_len, rpt->rport_tptid_sz);
 	key->pgr_key = svc_key;
+	key->pgr_key_flags |= keyflag;
 
-	if (all_tg_pt) {
-		key->pgr_key_flags |= SBD_PGR_KEY_ALL_TG_PT;
+	if (key->pgr_key_flags & SBD_PGR_KEY_ALL_TG_PT) {
 		/* set PGR_CHECK flag for all unregistered IT nexus */
 		sbd_pgr_set_pgr_check_flag(slu, B_FALSE);
 	} else {
@@ -1370,6 +1430,8 @@
 		mutex_enter(&slu->sl_lock);
 		it->pgr_key_ptr = key;
 		mutex_exit(&slu->sl_lock);
+	} else {
+		sbd_pgr_set_pgr_check_flag(slu, B_FALSE);
 	}
 
 	key->pgr_key_next = pgr->pgr_keylist;
@@ -1461,7 +1523,7 @@
 				kmem_free(lpt, lpt_len);
 			}
 			lpt = ses->ss_lport->lport_id;
-			lpt_len = sizeof (scsi_devid_desc_t) - 1 +
+			lpt_len = sizeof (scsi_devid_desc_t) +
 			    lpt->ident_length;
 			key->pgr_key_lpt_len = lpt_len;
 			key->pgr_key_lpt_id = (scsi_devid_desc_t *)
@@ -1679,11 +1741,13 @@
 	sbd_it_data_t		*it	= task->task_lu_itl_handle;
 	sbd_pgr_t		*pgr	= slu->sl_pgr;
 	sbd_pgr_key_t		*key	= it->pgr_key_ptr;
-	scsi_devid_desc_t	*lpt, *rpt;
+	scsi_devid_desc_t	*lpt;
+	stmf_remote_port_t	rport;
 	sbd_pgr_key_t		*newkey;
 	scsi_prout_reg_move_plist_t *plist;
 	uint8_t			*buf, lpt_len;
-	uint32_t		tpd_len;
+	uint16_t		tpd_len;
+	uint32_t		adn_len;
 	uint64_t		svc_key;
 
 	/*
@@ -1712,24 +1776,26 @@
 		return;
 	}
 
-	tpd_len = READ_SCSI32(plist->tptid_len, uint32_t);
-	rpt = sbd_tptid_to_devid_desc((scsi_transport_id_t *)plist->tptid,
-	    &tpd_len);
-	if (rpt == NULL) {
-		stmf_scsilib_send_status(task, STATUS_CHECK,
-		    STMF_SAA_INVALID_FIELD_IN_PARAM_LIST);
-		return;
-	} else if (rpt->ident_length == key->pgr_key_rpt_id->ident_length &&
-	    (memcmp(rpt->ident, key->pgr_key_rpt_id->ident, rpt->ident_length)
-	    == 0)) {
-		kmem_free(rpt, sizeof (rpt) - 1 + rpt->ident_length);
-		kmem_free(lpt, sizeof (lpt) - 1 + lpt->ident_length);
+	adn_len = READ_SCSI32(plist->tptid_len, uint32_t);
+	if (!stmf_scsilib_tptid_validate(
+	    (scsi_transport_id_t *)plist->tptid, adn_len, &tpd_len)) {
+		kmem_free(lpt, sizeof (scsi_devid_desc_t) + lpt->ident_length);
 		stmf_scsilib_send_status(task, STATUS_CHECK,
 		    STMF_SAA_INVALID_FIELD_IN_PARAM_LIST);
 		return;
 	}
 
-	newkey = sbd_pgr_key_registered(pgr, lpt, rpt);
+	rport.rport_tptid = (scsi_transport_id_t *)plist->tptid;
+	rport.rport_tptid_sz = tpd_len;
+
+	if (sbd_pgr_key_compare(key, lpt, &rport)) {
+		kmem_free(lpt, sizeof (scsi_devid_desc_t) + lpt->ident_length);
+		stmf_scsilib_send_status(task, STATUS_CHECK,
+		    STMF_SAA_INVALID_FIELD_IN_PARAM_LIST);
+		return;
+	}
+
+	newkey = sbd_pgr_key_registered(pgr, lpt, &rport);
 	if (newkey) {
 		/* Set the pgr_key, irrespective of what it currently holds */
 		newkey->pgr_key = svc_key;
@@ -1741,19 +1807,21 @@
 				kmem_free(newkey->pgr_key_lpt_id,
 				    newkey->pgr_key_lpt_len);
 			}
-			lpt_len = sizeof (scsi_devid_desc_t) - 1 +
+			lpt_len = sizeof (scsi_devid_desc_t) +
 			    lpt->ident_length;
 			newkey->pgr_key_lpt_len = lpt_len;
 			newkey->pgr_key_lpt_id = (scsi_devid_desc_t *)
 			    kmem_zalloc(lpt_len, KM_SLEEP);
 			bcopy(lpt, newkey->pgr_key_lpt_id, lpt_len);
 		}
+		/* No IT nexus information, hence set PGR_CHEK flag */
+		sbd_pgr_set_pgr_check_flag(slu, B_TRUE);
 	} else  {
-		newkey = sbd_pgr_do_register(slu, NULL, lpt, rpt, 0, svc_key);
+		newkey = sbd_pgr_do_register(slu, NULL, lpt, &rport,
+		    SBD_PGR_KEY_TPT_ID_FLAG, svc_key);
 	}
 
-	kmem_free(rpt, sizeof (scsi_devid_desc_t) - 1 + rpt->ident_length);
-	kmem_free(lpt, sizeof (scsi_devid_desc_t) - 1 + lpt->ident_length);
+	kmem_free(lpt, sizeof (scsi_devid_desc_t) + lpt->ident_length);
 
 	/* Now reserve the key corresponding to the specified IT nexus */
 	pgr->pgr_rsvholder = newkey;
@@ -1762,8 +1830,6 @@
 		sbd_pgr_do_unregister(slu, it, key);
 	}
 
-	/* Since we do not have IT nexus information, set PGR_CHEK flag */
-	sbd_pgr_set_pgr_check_flag(slu, B_TRUE);
 
 	/* Write to disk if currenty aptpl is set or given task is setting it */
 	if (pgr->pgr_flags & SBD_PGR_APTPL || plist->aptpl) {
@@ -1807,155 +1873,6 @@
 
 }
 
-scsi_devid_desc_t *
-sbd_tptid_to_devid_desc(scsi_transport_id_t *tptid, uint32_t *tptid_len)
-{
-
-	scsi_devid_desc_t *devid = NULL;
-	uint16_t ident_len,  sz;
-
-	struct scsi_fc_transport_id	*fcid;
-	struct iscsi_transport_id	*iscsiid;
-	struct scsi_srp_transport_id	*srpid;
-	char	eui_str[20+1];
-
-	switch (tptid->protocol_id) {
-
-	case PROTOCOL_FIBRE_CHANNEL:
-
-		if (*tptid_len < 24 || tptid->format_code != 0) {
-			return (NULL);
-		}
-		*tptid_len -= 24;
-		ident_len = 20; /* wwn.XXXXXXXXXXXXXXXX */
-		fcid	= (scsi_fc_transport_id_t *)tptid;
-		sz	= sizeof (scsi_devid_desc_t) - 1 + ident_len;
-		devid	= (scsi_devid_desc_t *)kmem_zalloc(sz, KM_SLEEP);
-		stmf_wwn_to_devid_desc(devid, fcid->port_name,
-		    PROTOCOL_FIBRE_CHANNEL);
-		return (devid);
-
-	case PROTOCOL_iSCSI:
-
-		if (tptid->format_code != 0 && tptid->format_code != 1) {
-			return (NULL);
-		}
-		iscsiid 	= (iscsi_transport_id_t *)tptid;
-		ident_len 	= READ_SCSI16(iscsiid->add_len, uint16_t);
-		if (*tptid_len < sizeof (iscsi_transport_id_t) + ident_len) {
-			return (NULL);
-		}
-		*tptid_len -= (sizeof (iscsi_transport_id_t) + ident_len);
-		sz	= sizeof (scsi_devid_desc_t) - 1 + ident_len;
-		devid	= (scsi_devid_desc_t *)kmem_zalloc(sz, KM_SLEEP);
-		(void) memcpy(devid->ident, iscsiid->iscsi_name, ident_len);
-		/* LINTED E_ASSIGN_NARROW_CONV */
-		devid->ident_length	= ident_len;
-		devid->protocol_id	= tptid->protocol_id;
-		devid->code_set		= CODE_SET_ASCII;
-		return (devid);
-
-	case PROTOCOL_SRP:
-		if (*tptid_len < 24 || tptid->format_code != 0) {
-			return (NULL);
-		}
-		*tptid_len -= 24;
-		srpid	= (scsi_srp_transport_id_t *)tptid;
-		ident_len = sizeof (eui_str) - 1; /* eui.XXXXXXXXXXXXXXXX */
-		sz	= sizeof (scsi_devid_desc_t) - 1 + ident_len;
-		devid	= (scsi_devid_desc_t *)kmem_zalloc(sz, KM_SLEEP);
-		/* ASSUME: initiator-extension of srp_name is zero */
-		(void) snprintf(eui_str, sizeof (eui_str), "eui.%016llX",
-		    (u_longlong_t)BE_IN64(srpid->srp_name));
-		bcopy(eui_str, devid->ident, ident_len);
-		/* LINTED E_ASSIGN_NARROW_CONV */
-		devid->ident_length	= ident_len;
-		devid->protocol_id	= tptid->protocol_id;
-		devid->code_set		= CODE_SET_ASCII;
-		return (devid);
-
-	default:
-		cmn_err(CE_NOTE, "sbd_tptid_to_devid_desc: received unknown"
-		    "protocol id 0x%x", tptid->protocol_id);
-		return (NULL);
-	}
-}
-
-/*
- * Changes devid_desc to corresponding TransportID format
- * Returns : Total length used by TransportID
- * Note    :- No buffer length checking
- */
-uint32_t
-sbd_devid_desc_to_tptid(scsi_devid_desc_t *devid, scsi_transport_id_t *tptid)
-{
-	struct scsi_fc_transport_id	*fcid;
-	struct iscsi_transport_id	*iscsiid;
-	struct scsi_srp_transport_id	*srpid;
-	uint32_t ident_len,  sz = 0;
-
-	switch (devid->protocol_id) {
-	case PROTOCOL_FIBRE_CHANNEL:
-		fcid = (scsi_fc_transport_id_t *)tptid;
-		tptid->format_code = 0;
-		tptid->protocol_id = devid->protocol_id;
-		/* convert from "wwn.XXXXXXXXXXXXXXXX" to 8-byte binary */
-		ASSERT(strncmp("wwn.", (char *)devid->ident, 4) == 0);
-		sbd_base16_str_to_binary((char *)devid->ident + 4, 16,
-		    fcid->port_name);
-		sz = 24;
-		break;
-
-	case PROTOCOL_iSCSI:
-		iscsiid = (iscsi_transport_id_t *)tptid;
-		ident_len = devid->ident_length;
-		tptid->format_code = 0;
-		tptid->protocol_id = devid->protocol_id;
-		SCSI_WRITE16(iscsiid->add_len, ident_len);
-		(void) memcpy(iscsiid->iscsi_name, devid->ident, ident_len);
-		sz = ALIGNED_TO_WORD_BOUNDARY(4 + ident_len);
-		break;
-
-	case PROTOCOL_SRP:
-		srpid = (scsi_srp_transport_id_t *)tptid;
-		tptid->format_code = 0;
-		tptid->protocol_id = devid->protocol_id;
-		/* convert from "eui.XXXXXXXXXXXXXXXX" to 8-byte binary */
-		ASSERT(strncmp("eui.", (char *)devid->ident, 4) == 0);
-		sbd_base16_str_to_binary((char *)devid->ident+4, 16,
-		    srpid->srp_name);
-		/* ASSUME: initiator-extension part of srp_name is zero */
-		sz = 24;
-		break;
-
-	default :
-		cmn_err(CE_NOTE, "sbd_devid_desc_to_tptid: received unknown"
-		    " protocol id 0x%x", devid->protocol_id);
-		break;
-	}
-
-	return (sz);
-}
-
-uint32_t
-sbd_get_tptid_length_for_devid(scsi_devid_desc_t *devid)
-{
-	uint32_t sz = 0;
-	switch (devid->protocol_id) {
-	case PROTOCOL_SRP:
-	case PROTOCOL_FIBRE_CHANNEL:
-		sz = 24;
-		break;
-	case PROTOCOL_iSCSI:
-		sz = 4 + devid->ident_length;
-		break;
-	}
-	sz = ALIGNED_TO_WORD_BOUNDARY(sz);
-	sz = (sz > 0 && sz < 24) ? 24 : sz;
-
-	return (sz);
-}
-
 char *
 sbd_get_devid_string(sbd_lu_t *sl)
 {
@@ -1970,23 +1887,3 @@
 	    sl->sl_device_id[19]);
 	return (str);
 }
-
-/* Convert from Hex value in ASCII format to the equivalent bytes */
-void
-sbd_base16_str_to_binary(char *c, int len, uint8_t *dp)
-{
-	int		ii;
-
-	ASSERT((len & 1) == 0);
-
-	for (ii = 0; ii < len / 2; ii++) {
-		char nibble1, nibble2;
-		char enc_char = *c++;
-		nibble1 = sbd_ctoi(enc_char);
-
-		enc_char = *c++;
-		nibble2 = sbd_ctoi(enc_char);
-
-		dp[ii] = (nibble1 << 4) | nibble2;
-	}
-}
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c	Thu Jul 01 16:06:54 2010 -0700
@@ -2612,10 +2612,10 @@
 			it->sbd_it_ua_conditions = SBD_UA_POR;
 		}
 	} else if (it->sbd_it_flags & SBD_IT_PGR_CHECK_FLAG) {
-		sbd_pgr_initialize_it(task, it);
 		mutex_enter(&sl->sl_lock);
 		it->sbd_it_flags &= ~SBD_IT_PGR_CHECK_FLAG;
 		mutex_exit(&sl->sl_lock);
+		sbd_pgr_initialize_it(task, it);
 	}
 
 	if (task->task_mgmt_function) {
--- a/usr/src/uts/common/io/comstar/port/iscsit/iscsit_login.c	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/io/comstar/port/iscsit/iscsit_login.c	Thu Jul 01 16:06:54 2010 -0700
@@ -29,6 +29,7 @@
 #include <sys/ddi.h>
 #include <sys/sunddi.h>
 #include <sys/modctl.h>
+#include <sys/scsi/generic/persist.h>
 
 #include <sys/socket.h>
 #include <sys/strsubr.h>
@@ -1725,6 +1726,8 @@
 {
 	iscsit_sess_t		*ist = ict->ict_sess;
 	stmf_scsi_session_t	*ss;
+	iscsi_transport_id_t	*iscsi_tptid;
+	uint16_t		ident_len, adn_len, tptid_sz;
 
 	/*
 	 * Hold target mutex until we have finished registering with STMF
@@ -1746,15 +1749,27 @@
 		return (IDM_STATUS_FAIL);
 	}
 
+	ident_len = strlen(ist->ist_initiator_name) + 1;
 	ss->ss_rport_id = kmem_zalloc(sizeof (scsi_devid_desc_t) +
-	    strlen(ist->ist_initiator_name) + 1, KM_SLEEP);
+	    ident_len, KM_SLEEP);
 	(void) strcpy((char *)ss->ss_rport_id->ident, ist->ist_initiator_name);
-	ss->ss_rport_id->ident_length = strlen(ist->ist_initiator_name);
+	ss->ss_rport_id->ident_length = ident_len - 1;
 	ss->ss_rport_id->protocol_id = PROTOCOL_iSCSI;
 	ss->ss_rport_id->piv = 1;
 	ss->ss_rport_id->code_set = CODE_SET_ASCII;
 	ss->ss_rport_id->association = ID_IS_TARGET_PORT;
 
+	/* adn_len should be 4 byte aligned, SPC3 rev 23, section 7.54.6 */
+	adn_len = (ident_len + 3) & ~ 3;
+	tptid_sz = sizeof (iscsi_transport_id_t) - 1 + adn_len;
+	ss->ss_rport = stmf_remote_port_alloc(tptid_sz);
+	ss->ss_rport->rport_tptid->protocol_id = PROTOCOL_iSCSI;
+	ss->ss_rport->rport_tptid->format_code = 0;
+	iscsi_tptid = (iscsi_transport_id_t *)ss->ss_rport->rport_tptid;
+	SCSI_WRITE16(&iscsi_tptid->add_len, adn_len);
+	(void) strlcpy((char *)iscsi_tptid->iscsi_name,
+	    ist->ist_initiator_name, ident_len);
+
 	ss->ss_lport = ist->ist_lport;
 
 	if (stmf_register_scsi_session(ict->ict_sess->ist_lport, ss) !=
@@ -1763,6 +1778,7 @@
 		kmem_free(ss->ss_rport_id,
 		    sizeof (scsi_devid_desc_t) +
 		    strlen(ist->ist_initiator_name) + 1);
+		stmf_remote_port_free(ss->ss_rport);
 		stmf_free(ss);
 		SET_LOGIN_ERROR(ict, ISCSI_STATUS_CLASS_TARGET_ERR,
 		    ISCSI_LOGIN_STATUS_TARGET_ERROR);
--- a/usr/src/uts/common/io/comstar/port/iscsit/iscsit_sess.c	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/io/comstar/port/iscsit/iscsit_sess.c	Thu Jul 01 16:06:54 2010 -0700
@@ -30,6 +30,7 @@
 #include <sys/sunddi.h>
 #include <sys/modctl.h>
 #include <sys/sysmacros.h>
+#include <sys/scsi/generic/persist.h>
 
 #include <sys/socket.h>
 #include <sys/strsubr.h>
@@ -208,6 +209,7 @@
 iscsit_sess_unref(void *ist_void)
 {
 	iscsit_sess_t *ist = ist_void;
+	stmf_scsi_session_t *iss;
 
 	/*
 	 * State machine has run to completion, destroy session
@@ -220,13 +222,13 @@
 	 */
 	mutex_enter(&ist->ist_mutex);
 	ASSERT(ist->ist_conn_count == 0);
-	if (ist->ist_stmf_sess != NULL) {
-		stmf_deregister_scsi_session(ist->ist_lport,
-		    ist->ist_stmf_sess);
-		kmem_free(ist->ist_stmf_sess->ss_rport_id,
-		    sizeof (scsi_devid_desc_t) +
+	iss = ist->ist_stmf_sess;
+	if (iss != NULL) {
+		stmf_deregister_scsi_session(ist->ist_lport, iss);
+		kmem_free(iss->ss_rport_id, sizeof (scsi_devid_desc_t) +
 		    strlen(ist->ist_initiator_name) + 1);
-		stmf_free(ist->ist_stmf_sess);
+		stmf_remote_port_free(iss->ss_rport);
+		stmf_free(iss);
 	}
 	mutex_exit(&ist->ist_mutex);
 
--- a/usr/src/uts/common/io/comstar/port/pppt/alua_ic_if.c	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/io/comstar/port/pppt/alua_ic_if.c	Thu Jul 01 16:06:54 2010 -0700
@@ -32,6 +32,7 @@
 #include <sys/ddi.h>
 #include <sys/sunddi.h>
 #include <sys/scsi/scsi.h>
+#include <sys/scsi/generic/persist.h>
 #include <sys/byteorder.h>
 #include <sys/nvpair.h>
 #include <sys/door.h>
@@ -99,6 +100,14 @@
 		_NOTE(CONSTCOND)					\
 	} while (0)
 
+#define	NVLIST_ADD_RPORT(structure, field)				\
+	do {								\
+		rc = stmf_ic_remote_port_marshal(nvl, #field,		\
+		    structure->field);					\
+		if (rc) goto done;					\
+		_NOTE(CONSTCOND)					\
+	} while (0)
+
 #define	NVLIST_ADD_FIELD_UINT8(structure, field)			\
 	NVLIST_ADD_FIELD(structure, field, uint8)
 
@@ -260,6 +269,8 @@
 static int stmf_ic_echo_request_reply_msg_marshal(nvlist_t *nvl, void *msg);
 static int stmf_ic_scsi_devid_desc_marshal(nvlist_t *parent_nvl,
 	char *sdid_name, scsi_devid_desc_t *sdid);
+static int stmf_ic_remote_port_marshal(nvlist_t *parent_nvl,
+	char *rport_name, stmf_remote_port_t *rport);
 
 /*
  * Unmarshaling routines.
@@ -283,6 +294,9 @@
 static uint8_t *stmf_ic_uint8_array_unmarshal(nvlist_t *nvl, char *field_name,
 	uint64_t len, uint8_t *buf);
 static char *stmf_ic_string_unmarshal(nvlist_t *nvl, char *field_name);
+static stmf_remote_port_t *stmf_ic_lookup_remote_port_and_unmarshal(
+	nvlist_t *nvl, char *field_name);
+static stmf_remote_port_t *stmf_ic_remote_port_unmarshal(nvlist_t *nvl);
 
 /*
  * Transmit and recieve routines.
@@ -297,6 +311,7 @@
 static size_t sizeof_scsi_devid_desc(int ident_length);
 static char *stmf_ic_strdup(char *str);
 static scsi_devid_desc_t *scsi_devid_desc_dup(scsi_devid_desc_t *did);
+static stmf_remote_port_t *remote_port_dup(stmf_remote_port_t *rport);
 static void scsi_devid_desc_free(scsi_devid_desc_t *did);
 static inline void stmf_ic_nvlookup_warn(const char *func, char *field);
 
@@ -628,6 +643,7 @@
 	stmf_ic_scsi_cmd_msg_t *icsc = NULL;
 	scsi_devid_desc_t *ini_devid = task->task_session->ss_rport_id;
 	scsi_devid_desc_t *tgt_devid = task->task_lport->lport_id;
+	stmf_remote_port_t *rport = task->task_session->ss_rport;
 
 	icm = stmf_ic_alloc_msg_header(STMF_ICM_SCSI_CMD, msgid);
 	icsc = (stmf_ic_scsi_cmd_msg_t *)kmem_zalloc(sizeof (*icsc), KM_SLEEP);
@@ -636,6 +652,7 @@
 	icsc->icsc_task_msgid = task_msgid;
 	icsc->icsc_ini_devid = scsi_devid_desc_dup(ini_devid);
 	icsc->icsc_tgt_devid = scsi_devid_desc_dup(tgt_devid);
+	icsc->icsc_rport = remote_port_dup(rport);
 	icsc->icsc_session_id = task->task_session->ss_session_id;
 
 	if (!task->task_mgmt_function && task->task_lu->lu_id) {
@@ -827,6 +844,7 @@
 	icscd->icscd_session_id = session->ss_session_id;
 	icscd->icscd_ini_devid = scsi_devid_desc_dup(ini_devid);
 	icscd->icscd_tgt_devid = scsi_devid_desc_dup(tgt_devid);
+	icscd->icscd_rport = remote_port_dup(session->ss_rport);
 
 	return (icm);
 }
@@ -1000,6 +1018,7 @@
 {
 	scsi_devid_desc_free(m->icsc_ini_devid);
 	scsi_devid_desc_free(m->icsc_tgt_devid);
+	stmf_remote_port_free(m->icsc_rport);
 	if (cmethod == STMF_CONSTRUCTOR) {
 		kmem_free(m->icsc_task_cdb, m->icsc_task_cdb_length);
 	}
@@ -1059,6 +1078,7 @@
 {
 	scsi_devid_desc_free(m->icscd_ini_devid);
 	scsi_devid_desc_free(m->icscd_tgt_devid);
+	stmf_remote_port_free(m->icscd_rport);
 
 	kmem_free(m, sizeof (*m));
 }
@@ -1230,6 +1250,7 @@
 	NVLIST_ADD_FIELD(uint64, m, icsc_task_msgid);
 	NVLIST_ADD_DEVID(m, icsc_ini_devid);
 	NVLIST_ADD_DEVID(m, icsc_tgt_devid);
+	NVLIST_ADD_RPORT(m, icsc_rport);
 	NVLIST_ADD_ARRAY(uint8, m, icsc_lun_id);
 	NVLIST_ADD_FIELD(uint64, m, icsc_session_id);
 	NVLIST_ADD_ARRAY_LEN(uint8, m, icsc_task_lun_no, 8);
@@ -1343,6 +1364,7 @@
 
 	NVLIST_ADD_DEVID(m, icscd_ini_devid);
 	NVLIST_ADD_DEVID(m, icscd_tgt_devid);
+	NVLIST_ADD_RPORT(m, icscd_rport);
 	NVLIST_ADD_FIELD(uint64, m, icscd_session_id);
 
 done:
@@ -1392,7 +1414,35 @@
 		goto done;
 
 	rc = nvlist_add_nvlist(parent_nvl, sdid_name, nvl);
+done:
+	if (nvl) {
+		nvlist_free(nvl);
+	}
+	return (rc);
+}
 
+/*
+ * Allocate a new nvlist representing the stmf_remote_port and add it
+ * to the nvlist.
+ */
+static int
+stmf_ic_remote_port_marshal(nvlist_t *parent_nvl, char *rport_name,
+	stmf_remote_port_t *rport) {
+
+	int rc = 0;
+	nvlist_t *nvl = NULL;
+
+	rc = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP);
+	if (rc)
+		goto done;
+
+	NVLIST_ADD_FIELD(uint16, rport, rport_tptid_sz);
+	rc = nvlist_add_uint8_array(nvl, "rport_tptid",
+	    (uint8_t *)rport->rport_tptid, rport->rport_tptid_sz);
+	if (rc)
+		goto done;
+
+	rc = nvlist_add_nvlist(parent_nvl, rport_name, nvl);
 done:
 	if (nvl) {
 		nvlist_free(nvl);
@@ -1666,6 +1716,14 @@
 		goto done;
 	}
 
+	m->icsc_rport = stmf_ic_lookup_remote_port_and_unmarshal(
+	    nvl, "icsc_rport");
+	if (m->icsc_rport == NULL) {
+		stmf_ic_nvlookup_warn(__func__, "icsc_rport");
+		rc = ENOMEM;
+		goto done;
+	}
+
 	/* icsc_lun_id */
 	if (!stmf_ic_uint8_array_unmarshal(nvl, "icsc_lun_id",
 	    sizeof (m->icsc_lun_id), m->icsc_lun_id)) {
@@ -1879,6 +1937,14 @@
 		goto done;
 	}
 
+	m->icscd_rport = stmf_ic_lookup_remote_port_and_unmarshal(
+	    nvl, "icscd_rport");
+	if (m->icscd_rport == NULL) {
+		stmf_ic_nvlookup_warn(__func__, "icscd_rport");
+		rc = ENOMEM;
+		goto done;
+	}
+
 done:
 	if (!rc)
 		return (m);
@@ -2009,6 +2075,37 @@
 	return (NULL);
 }
 
+static stmf_remote_port_t *
+stmf_ic_lookup_remote_port_and_unmarshal(nvlist_t *nvl, char *field_name)
+{
+	nvlist_t *nvl_rport = NULL;
+
+	if (nvlist_lookup_nvlist(nvl, field_name, &nvl_rport) != 0)
+		return (NULL);
+
+	return (stmf_ic_remote_port_unmarshal(nvl_rport));
+}
+
+static stmf_remote_port_t *
+stmf_ic_remote_port_unmarshal(nvlist_t *nvl)
+{
+	stmf_remote_port_t *rport = NULL;
+	uint16_t rport_tptid_sz = 0;
+	int rc = 0;
+
+	rc = nvlist_lookup_uint16(nvl, "rport_tptid_sz", &rport_tptid_sz);
+	if (rc || rport_tptid_sz < sizeof (scsi_transport_id_t))
+		return (NULL);
+
+	rport = stmf_remote_port_alloc(rport_tptid_sz);
+	if (!stmf_ic_uint8_array_unmarshal(nvl, "rport_tptid", rport_tptid_sz,
+	    (uint8_t *)rport->rport_tptid)) {
+		stmf_remote_port_free(rport);
+		rport = NULL;
+	}
+	return (rport);
+}
+
 /*
  * Unmarshal a uint8_t array.
  *
@@ -2151,6 +2248,21 @@
 }
 
 /*
+ * Duplicate the stmf_remote_port_t.
+ */
+static stmf_remote_port_t *
+remote_port_dup(stmf_remote_port_t *rport)
+{
+	stmf_remote_port_t *dup = NULL;
+	if (rport) {
+		dup = stmf_remote_port_alloc(rport->rport_tptid_sz);
+		bcopy(rport->rport_tptid, dup->rport_tptid,
+		    rport->rport_tptid_sz);
+	}
+	return (dup);
+}
+
+/*
  * Helper functions, returns NULL if no memory.
  */
 static char *
--- a/usr/src/uts/common/io/comstar/port/pppt/pppt.c	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/io/comstar/port/pppt/pppt.c	Thu Jul 01 16:06:54 2010 -0700
@@ -848,13 +848,11 @@
 
 pppt_sess_t *
 pppt_sess_lookup_locked(uint64_t session_id,
-    scsi_devid_desc_t *lport_devid,
-    scsi_devid_desc_t *rport_devid)
+    scsi_devid_desc_t *lport_devid, stmf_remote_port_t *rport)
 {
 	pppt_tgt_t				*tgt;
 	pppt_sess_t				*ps;
 	int					lport_cmp;
-	int					rport_cmp;
 
 	ASSERT(mutex_owned(&pppt_global.global_lock));
 
@@ -874,8 +872,8 @@
 	/* Validate local/remote port names */
 	if ((lport_devid->ident_length !=
 	    tgt->target_stmf_lport->lport_id->ident_length) ||
-	    (rport_devid->ident_length !=
-	    ps->ps_stmf_sess->ss_rport_id->ident_length)) {
+	    (rport->rport_tptid_sz !=
+	    ps->ps_stmf_sess->ss_rport->rport_tptid_sz)) {
 		mutex_exit(&tgt->target_mutex);
 		PPPT_INC_STAT(es_sess_lookup_ident_mismatch);
 		return (NULL);
@@ -883,10 +881,9 @@
 		lport_cmp = bcmp(lport_devid->ident,
 		    tgt->target_stmf_lport->lport_id->ident,
 		    lport_devid->ident_length);
-		rport_cmp = bcmp(rport_devid->ident,
-		    ps->ps_stmf_sess->ss_rport_id->ident,
-		    rport_devid->ident_length);
-		if (lport_cmp || rport_cmp) {
+		if (lport_cmp != 0 ||
+		    (stmf_scsilib_tptid_compare(rport->rport_tptid,
+		    ps->ps_stmf_sess->ss_rport->rport_tptid) != B_TRUE)) {
 			mutex_exit(&tgt->target_mutex);
 			PPPT_INC_STAT(es_sess_lookup_ident_mismatch);
 			return (NULL);
@@ -929,8 +926,8 @@
 /* New session */
 pppt_sess_t *
 pppt_sess_lookup_create(scsi_devid_desc_t *lport_devid,
-    scsi_devid_desc_t *rport_devid, uint64_t session_id,
-    stmf_status_t *statusp)
+    scsi_devid_desc_t *rport_devid, stmf_remote_port_t *rport,
+    uint64_t session_id, stmf_status_t *statusp)
 {
 	pppt_tgt_t		*tgt;
 	pppt_sess_t		*ps;
@@ -944,7 +941,7 @@
 	/*
 	 * Look for existing session for this ID
 	 */
-	ps = pppt_sess_lookup_locked(session_id, lport_devid, rport_devid);
+	ps = pppt_sess_lookup_locked(session_id, lport_devid, rport);
 
 	if (ps != NULL) {
 		PPPT_GLOBAL_UNLOCK();
@@ -974,7 +971,7 @@
 	bzero(&tmp_ps, sizeof (tmp_ps));
 	bzero(&tmp_ss, sizeof (tmp_ss));
 	tmp_ps.ps_stmf_sess = &tmp_ss;
-	tmp_ss.ss_rport_id = rport_devid;
+	tmp_ss.ss_rport = rport;
 
 	/*
 	 * Look for an existing session on this IT nexus
@@ -1035,13 +1032,17 @@
 
 	ss->ss_lport = tgt->target_stmf_lport;
 
+	ss->ss_rport = stmf_remote_port_alloc(rport->rport_tptid_sz);
+	bcopy(rport->rport_tptid, ss->ss_rport->rport_tptid,
+	    rport->rport_tptid_sz);
+
 	if (stmf_register_scsi_session(tgt->target_stmf_lport, ss) !=
 	    STMF_SUCCESS) {
 		mutex_exit(&tgt->target_mutex);
 		PPPT_GLOBAL_UNLOCK();
 		kmem_free(ss->ss_rport_id,
-		    sizeof (scsi_devid_desc_t) +
-		    rport_devid->ident_length + 1);
+		    sizeof (scsi_devid_desc_t) + rport_devid->ident_length + 1);
+		stmf_remote_port_free(ss->ss_rport);
 		stmf_free(ss);
 		kmem_free(ps, sizeof (*ps));
 		*statusp = STMF_TARGET_FAILURE;
@@ -1093,8 +1094,8 @@
 	mutex_enter(&ps->ps_mutex);
 	stmf_deregister_scsi_session(ss->ss_lport, ss);
 	kmem_free(ss->ss_rport_id,
-	    sizeof (scsi_devid_desc_t) +
-	    ss->ss_rport_id->ident_length + 1);
+	    sizeof (scsi_devid_desc_t) + ss->ss_rport_id->ident_length + 1);
+	stmf_remote_port_free(ss->ss_rport);
 	avl_destroy(&ps->ps_task_list);
 	mutex_exit(&ps->ps_mutex);
 	cv_destroy(&ps->ps_cv);
@@ -1133,28 +1134,19 @@
 	const	pppt_sess_t	*psess2 = void_sess2;
 	int			result;
 
-	/* Sort by code set then ident */
-	if (psess1->ps_stmf_sess->ss_rport_id->code_set <
-	    psess2->ps_stmf_sess->ss_rport_id->code_set) {
+	/* Compare by tptid size */
+	if (psess1->ps_stmf_sess->ss_rport->rport_tptid_sz <
+	    psess2->ps_stmf_sess->ss_rport->rport_tptid_sz) {
 		return (-1);
-	} else if (psess1->ps_stmf_sess->ss_rport_id->code_set >
-	    psess2->ps_stmf_sess->ss_rport_id->code_set) {
+	} else if (psess1->ps_stmf_sess->ss_rport->rport_tptid_sz >
+	    psess2->ps_stmf_sess->ss_rport->rport_tptid_sz) {
 		return (1);
 	}
 
-	/* Next by ident length */
-	if (psess1->ps_stmf_sess->ss_rport_id->ident_length <
-	    psess2->ps_stmf_sess->ss_rport_id->ident_length) {
-		return (-1);
-	} else if (psess1->ps_stmf_sess->ss_rport_id->ident_length >
-	    psess2->ps_stmf_sess->ss_rport_id->ident_length) {
-		return (1);
-	}
-
-	/* Code set and ident length both match, now compare idents */
-	result = memcmp(psess1->ps_stmf_sess->ss_rport_id->ident,
-	    psess2->ps_stmf_sess->ss_rport_id->ident,
-	    psess1->ps_stmf_sess->ss_rport_id->ident_length);
+	/* Now compare tptid */
+	result = memcmp(psess1->ps_stmf_sess->ss_rport->rport_tptid,
+	    psess2->ps_stmf_sess->ss_rport->rport_tptid,
+	    psess1->ps_stmf_sess->ss_rport->rport_tptid_sz);
 
 	if (result < 0) {
 		return (-1);
--- a/usr/src/uts/common/io/comstar/port/pppt/pppt.h	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/io/comstar/port/pppt/pppt.h	Thu Jul 01 16:06:54 2010 -0700
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 #ifndef _PPPT_H
 #define	_PPPT_H
@@ -248,13 +247,13 @@
 
 pppt_sess_t *pppt_sess_lookup_locked(uint64_t session_id,
     scsi_devid_desc_t *lport_devid,
-    scsi_devid_desc_t *rport_devid);
+    stmf_remote_port_t *rport);
 
 pppt_sess_t *pppt_sess_lookup_by_id_locked(uint64_t session_id);
 
 pppt_sess_t *pppt_sess_lookup_create(scsi_devid_desc_t *lport_devid,
-    scsi_devid_desc_t *rport_devid, uint64_t session_id,
-    stmf_status_t *statusp);
+    scsi_devid_desc_t *rport_devid, stmf_remote_port_t *rport,
+    uint64_t session_id, stmf_status_t *statusp);
 
 void pppt_sess_rele(pppt_sess_t *sks);
 
--- a/usr/src/uts/common/io/comstar/port/pppt/pppt_msg.c	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/io/comstar/port/pppt/pppt_msg.c	Thu Jul 01 16:06:54 2010 -0700
@@ -117,7 +117,6 @@
 
 	reg_port = msg->icm_msg;
 
-
 	PPPT_GLOBAL_LOCK();
 	if (pppt_global.global_svc_state != PSS_ENABLED) {
 		stmf_status = STMF_FAILURE;
@@ -215,7 +214,7 @@
 	 * Look for existing session for this ID
 	 */
 	ps = pppt_sess_lookup_locked(sess_destroy->icscd_session_id,
-	    sess_destroy->icscd_tgt_devid, sess_destroy->icscd_ini_devid);
+	    sess_destroy->icscd_tgt_devid, sess_destroy->icscd_rport);
 
 	if (ps == NULL) {
 		PPPT_GLOBAL_UNLOCK();
@@ -278,7 +277,8 @@
 	 * IT nexus
 	 */
 	pppt_sess = pppt_sess_lookup_create(scmd->icsc_tgt_devid,
-	    scmd->icsc_ini_devid, scmd->icsc_session_id, &stmf_status);
+	    scmd->icsc_ini_devid, scmd->icsc_rport,
+	    scmd->icsc_session_id, &stmf_status);
 	if (pppt_sess == NULL) {
 		pppt_task_free(ptask);
 		pppt_msg_tx_status(msg, stmf_status);
--- a/usr/src/uts/common/io/comstar/port/srpt/srpt_stp.c	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/io/comstar/port/srpt/srpt_stp.c	Thu Jul 01 16:06:54 2010 -0700
@@ -45,6 +45,7 @@
 #include <sys/stmf_ioctl.h>
 #include <sys/portif.h>
 
+#include <sys/scsi/generic/persist.h>
 #include <sys/ib/mgt/ibdma/ibdma.h>
 
 #include "srp.h"
@@ -1249,6 +1250,7 @@
 	srpt_session_t		*ss;
 	stmf_scsi_session_t	*stmf_ss;
 	uint64_t		i_guid;
+	scsi_srp_transport_id_t *srptpd;
 
 	ASSERT(tgt != NULL);
 	SRPT_DPRINTF_L3("stp_alloc_session, invoked");
@@ -1268,12 +1270,19 @@
 	ss = stmf_ss->ss_port_private;
 	ASSERT(ss != NULL);
 
-
 	rw_init(&ss->ss_rwlock, NULL, RW_DRIVER, NULL);
 	list_create(&ss->ss_task_list, sizeof (srpt_iu_t),
 	    offsetof(srpt_iu_t, iu_ss_task_node));
 
 	stmf_ss->ss_rport_id = srpt_stp_alloc_scsi_devid_desc(i_guid);
+	/* Setup remote port transport id */
+	stmf_ss->ss_rport = stmf_remote_port_alloc(
+	    sizeof (scsi_srp_transport_id_t));
+	stmf_ss->ss_rport->rport_tptid->protocol_id = PROTOCOL_SRP;
+	stmf_ss->ss_rport->rport_tptid->format_code = 0;
+	srptpd = (scsi_srp_transport_id_t *)stmf_ss->ss_rport->rport_tptid;
+	bcopy(i_id, srptpd->srp_name, SRP_PORT_ID_LEN);
+
 	stmf_ss->ss_lport    = tgt->tp_lport;
 
 	ss->ss_ss	= stmf_ss;
@@ -1295,7 +1304,6 @@
 	    BE_IN64(&ss->ss_i_id[8]));
 	ALIAS_STR(ss->ss_t_alias, BE_IN64(&ss->ss_t_id[0]),
 	    BE_IN64(&ss->ss_t_id[8]));
-
 	stmf_ss->ss_rport_alias = ss->ss_i_alias;
 
 	status = stmf_register_scsi_session(tgt->tp_lport, stmf_ss);
@@ -1304,6 +1312,8 @@
 		    " err(0x%llx)", (u_longlong_t)status);
 		list_destroy(&ss->ss_task_list);
 		rw_destroy(&ss->ss_rwlock);
+		srpt_stp_free_scsi_devid_desc(stmf_ss->ss_rport_id);
+		stmf_remote_port_free(stmf_ss->ss_rport);
 		stmf_free(stmf_ss);
 		mutex_exit(&tgt->tp_sess_list_lock);
 		return (NULL);
@@ -1340,7 +1350,7 @@
 
 	stmf_deregister_scsi_session(tgt->tp_lport, stmf_ss);
 	srpt_stp_free_scsi_devid_desc(stmf_ss->ss_rport_id);
-
+	stmf_remote_port_free(stmf_ss->ss_rport);
 	list_remove(&tgt->tp_sess_list, session);
 	cv_signal(&tgt->tp_sess_complete);
 	mutex_exit(&tgt->tp_sess_list_lock);
--- a/usr/src/uts/common/io/comstar/stmf/stmf.c	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/io/comstar/stmf/stmf.c	Thu Jul 01 16:06:54 2010 -0700
@@ -28,6 +28,7 @@
 #include <sys/sunddi.h>
 #include <sys/modctl.h>
 #include <sys/scsi/scsi.h>
+#include <sys/scsi/generic/persist.h>
 #include <sys/scsi/impl/scsi_reset_notify.h>
 #include <sys/disp.h>
 #include <sys/byteorder.h>
@@ -59,6 +60,7 @@
 /* start messages at 1 */
 static uint64_t stmf_proxy_msg_id = 1;
 #define	MSG_ID_TM_BIT	0x8000000000000000
+#define	ALIGNED_TO_8BYTE_BOUNDARY(i)	(((i) + 7) & ~7)
 
 static int stmf_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
 static int stmf_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
@@ -78,6 +80,8 @@
 static void stmf_task_audit(stmf_i_scsi_task_t *itask,
     task_audit_event_t te, uint32_t cmd_or_iof, stmf_data_buf_t *dbuf);
 
+static boolean_t stmf_base16_str_to_binary(char *c, int dplen, uint8_t *dp);
+static char stmf_ctoi(char c);
 stmf_xfer_data_t *stmf_prepare_tpgs_data(uint8_t ilu_alua);
 void stmf_svc_init();
 stmf_status_t stmf_svc_fini();
@@ -3550,6 +3554,26 @@
 
 	iss->iss_flags |= ISS_BEING_CREATED;
 
+	if (ss->ss_rport == NULL) {
+		iss->iss_flags |= ISS_NULL_TPTID;
+		ss->ss_rport = stmf_scsilib_devid_to_remote_port(
+		    ss->ss_rport_id);
+		if (ss->ss_rport == NULL) {
+			iss->iss_flags &= ~(ISS_NULL_TPTID | ISS_BEING_CREATED);
+			stmf_trace(lport->lport_alias, "Device id to "
+			    "remote port conversion failed");
+			return (STMF_FAILURE);
+		}
+	} else {
+		if (!stmf_scsilib_tptid_validate(ss->ss_rport->rport_tptid,
+		    ss->ss_rport->rport_tptid_sz, NULL)) {
+			iss->iss_flags &= ~ISS_BEING_CREATED;
+			stmf_trace(lport->lport_alias, "Remote port "
+			    "transport id validation failed");
+			return (STMF_FAILURE);
+		}
+	}
+
 	/* sessions use the ilport_lock. No separate lock is required */
 	iss->iss_lockp = &ilport->ilport_lock;
 
@@ -3638,6 +3662,10 @@
 	(void) stmf_session_destroy_lun_map(ilport, iss);
 	rw_exit(&ilport->ilport_lock);
 	mutex_exit(&stmf_state.stmf_lock);
+
+	if (iss->iss_flags & ISS_NULL_TPTID) {
+		stmf_remote_port_free(ss->ss_rport);
+	}
 }
 
 stmf_i_scsi_session_t *
@@ -5999,7 +6027,7 @@
 	    ilport = ilport->ilport_next) {
 		if (ilport->ilport_rtpid == rtpid) {
 			scsi_devid_desc_t *id = ilport->ilport_lport->lport_id;
-			uint32_t id_sz = sizeof (scsi_devid_desc_t) - 1 +
+			uint32_t id_sz = sizeof (scsi_devid_desc_t) +
 			    id->ident_length;
 			devid = (scsi_devid_desc_t *)kmem_zalloc(id_sz,
 			    KM_NOSLEEP);
@@ -8083,3 +8111,309 @@
 	}
 	(void) stmf_ctl(ctl_cmd, ctl_private, &change_info);
 }
+
+static char
+stmf_ctoi(char c)
+{
+	if ((c >= '0') && (c <= '9'))
+		c -= '0';
+	else if ((c >= 'A') && (c <= 'F'))
+		c = c - 'A' + 10;
+	else if ((c >= 'a') && (c <= 'f'))
+		c = c - 'a' + 10;
+	else
+		c = -1;
+	return (c);
+}
+
+/* Convert from Hex value in ASCII format to the equivalent bytes */
+static boolean_t
+stmf_base16_str_to_binary(char *c, int dplen, uint8_t *dp)
+{
+	int		ii;
+
+	for (ii = 0; ii < dplen; ii++) {
+		char nibble1, nibble2;
+		char enc_char = *c++;
+		nibble1 = stmf_ctoi(enc_char);
+
+		enc_char = *c++;
+		nibble2 = stmf_ctoi(enc_char);
+		if (nibble1 == -1 || nibble2 == -1)
+			return (B_FALSE);
+
+		dp[ii] = (nibble1 << 4) | nibble2;
+	}
+	return (B_TRUE);
+}
+
+boolean_t
+stmf_scsilib_tptid_validate(scsi_transport_id_t *tptid, uint32_t total_sz,
+				uint16_t *tptid_sz)
+{
+	uint16_t tpd_len = SCSI_TPTID_SIZE;
+
+	if (tptid_sz)
+		*tptid_sz = 0;
+	if (total_sz < sizeof (scsi_transport_id_t))
+		return (B_FALSE);
+
+	switch (tptid->protocol_id) {
+
+	case PROTOCOL_FIBRE_CHANNEL:
+		/* FC Transport ID validation checks. SPC3 rev23, Table 284 */
+		if (total_sz < tpd_len || tptid->format_code != 0)
+			return (B_FALSE);
+		break;
+
+	case PROTOCOL_iSCSI:
+		{
+		iscsi_transport_id_t	*iscsiid;
+		uint16_t		adn_len, name_len;
+
+		/* Check for valid format code, SPC3 rev 23 Table 288 */
+		if ((total_sz < tpd_len) ||
+		    (tptid->format_code != 0 && tptid->format_code != 1))
+			return (B_FALSE);
+
+		iscsiid = (iscsi_transport_id_t *)tptid;
+		adn_len = READ_SCSI16(iscsiid->add_len, uint16_t);
+		tpd_len = sizeof (iscsi_transport_id_t) + adn_len - 1;
+
+		/*
+		 * iSCSI Transport ID validation checks.
+		 * As per SPC3 rev 23 Section 7.5.4.6 and Table 289 & Table 290
+		 */
+		if (adn_len < 20 || (adn_len % 4 != 0))
+			return (B_FALSE);
+
+		name_len = strnlen(iscsiid->iscsi_name, adn_len);
+		if (name_len == 0 || name_len >= adn_len)
+			return (B_FALSE);
+
+		/* If the format_code is 1 check for ISID seperator */
+		if ((tptid->format_code == 1) && (strstr(iscsiid->iscsi_name,
+		    SCSI_TPTID_ISCSI_ISID_SEPERATOR) == NULL))
+			return (B_FALSE);
+
+		}
+		break;
+
+	case PROTOCOL_SRP:
+		/* SRP Transport ID validation checks. SPC3 rev23, Table 287 */
+		if (total_sz < tpd_len || tptid->format_code != 0)
+			return (B_FALSE);
+		break;
+
+	case PROTOCOL_PARALLEL_SCSI:
+	case PROTOCOL_SSA:
+	case PROTOCOL_IEEE_1394:
+	case PROTOCOL_SAS:
+	case PROTOCOL_ADT:
+	case PROTOCOL_ATAPI:
+	default:
+		{
+		stmf_dflt_scsi_tptid_t *dflttpd;
+
+		tpd_len = sizeof (stmf_dflt_scsi_tptid_t);
+		if (total_sz < tpd_len)
+			return (B_FALSE);
+		dflttpd = (stmf_dflt_scsi_tptid_t *)tptid;
+		tpd_len = tpd_len + SCSI_READ16(&dflttpd->ident_len) - 1;
+		if (total_sz < tpd_len)
+			return (B_FALSE);
+		}
+		break;
+	}
+	if (tptid_sz)
+		*tptid_sz = tpd_len;
+	return (B_TRUE);
+}
+
+boolean_t
+stmf_scsilib_tptid_compare(scsi_transport_id_t *tpd1,
+				scsi_transport_id_t *tpd2)
+{
+	if ((tpd1->protocol_id != tpd2->protocol_id) ||
+	    (tpd1->format_code != tpd2->format_code))
+		return (B_FALSE);
+
+	switch (tpd1->protocol_id) {
+
+	case PROTOCOL_iSCSI:
+		{
+		iscsi_transport_id_t *iscsitpd1, *iscsitpd2;
+		uint16_t len;
+
+		iscsitpd1 = (iscsi_transport_id_t *)tpd1;
+		iscsitpd2 = (iscsi_transport_id_t *)tpd2;
+		len = SCSI_READ16(&iscsitpd1->add_len);
+		if ((memcmp(iscsitpd1->add_len, iscsitpd2->add_len, 2) != 0) ||
+		    (memcmp(iscsitpd1->iscsi_name, iscsitpd2->iscsi_name, len)
+		    != 0))
+			return (B_FALSE);
+		}
+		break;
+
+	case PROTOCOL_SRP:
+		{
+		scsi_srp_transport_id_t *srptpd1, *srptpd2;
+
+		srptpd1 = (scsi_srp_transport_id_t *)tpd1;
+		srptpd2 = (scsi_srp_transport_id_t *)tpd2;
+		if (memcmp(srptpd1->srp_name, srptpd2->srp_name,
+		    sizeof (srptpd1->srp_name)) != 0)
+			return (B_FALSE);
+		}
+		break;
+
+	case PROTOCOL_FIBRE_CHANNEL:
+		{
+		scsi_fc_transport_id_t *fctpd1, *fctpd2;
+
+		fctpd1 = (scsi_fc_transport_id_t *)tpd1;
+		fctpd2 = (scsi_fc_transport_id_t *)tpd2;
+		if (memcmp(fctpd1->port_name, fctpd2->port_name,
+		    sizeof (fctpd1->port_name)) != 0)
+			return (B_FALSE);
+		}
+		break;
+
+	case PROTOCOL_PARALLEL_SCSI:
+	case PROTOCOL_SSA:
+	case PROTOCOL_IEEE_1394:
+	case PROTOCOL_SAS:
+	case PROTOCOL_ADT:
+	case PROTOCOL_ATAPI:
+	default:
+		{
+		stmf_dflt_scsi_tptid_t *dflt1, *dflt2;
+		uint16_t len;
+
+		dflt1 = (stmf_dflt_scsi_tptid_t *)tpd1;
+		dflt2 = (stmf_dflt_scsi_tptid_t *)tpd2;
+		len = SCSI_READ16(&dflt1->ident_len);
+		if ((memcmp(dflt1->ident_len, dflt2->ident_len, 2) != 0) ||
+		    (memcmp(dflt1->ident, dflt2->ident, len) != 0))
+			return (B_FALSE);
+		}
+		break;
+	}
+	return (B_TRUE);
+}
+
+/*
+ * Changes devid_desc to corresponding TransportID format
+ * Returns :- pointer to stmf_remote_port_t
+ * Note    :- Allocates continous memory for stmf_remote_port_t and TransportID,
+ *            This memory need to be freed when this remote_port is no longer
+ *            used.
+ */
+stmf_remote_port_t *
+stmf_scsilib_devid_to_remote_port(scsi_devid_desc_t *devid)
+{
+	struct scsi_fc_transport_id	*fc_tpd;
+	struct iscsi_transport_id	*iscsi_tpd;
+	struct scsi_srp_transport_id	*srp_tpd;
+	struct stmf_dflt_scsi_tptid	*dflt_tpd;
+	uint16_t ident_len,  sz = 0;
+	stmf_remote_port_t *rpt = NULL;
+
+	ident_len = devid->ident_length;
+	ASSERT(ident_len);
+	switch (devid->protocol_id) {
+	case PROTOCOL_FIBRE_CHANNEL:
+		sz = sizeof (scsi_fc_transport_id_t);
+		rpt = stmf_remote_port_alloc(sz);
+		rpt->rport_tptid->format_code = 0;
+		rpt->rport_tptid->protocol_id = devid->protocol_id;
+		fc_tpd = (scsi_fc_transport_id_t *)rpt->rport_tptid;
+		/*
+		 * convert from "wwn.xxxxxxxxxxxxxxxx" to 8-byte binary
+		 * skip first 4 byte for "wwn."
+		 */
+		ASSERT(strncmp("wwn.", (char *)devid->ident, 4) == 0);
+		if ((ident_len < SCSI_TPTID_FC_PORT_NAME_SIZE * 2 + 4) ||
+		    !stmf_base16_str_to_binary((char *)devid->ident + 4,
+		    SCSI_TPTID_FC_PORT_NAME_SIZE, fc_tpd->port_name))
+			goto devid_to_remote_port_fail;
+		break;
+
+	case PROTOCOL_iSCSI:
+		sz = ALIGNED_TO_8BYTE_BOUNDARY(sizeof (iscsi_transport_id_t) +
+		    ident_len - 1);
+		rpt = stmf_remote_port_alloc(sz);
+		rpt->rport_tptid->format_code = 0;
+		rpt->rport_tptid->protocol_id = devid->protocol_id;
+		iscsi_tpd = (iscsi_transport_id_t *)rpt->rport_tptid;
+		SCSI_WRITE16(iscsi_tpd->add_len, ident_len);
+		(void) memcpy(iscsi_tpd->iscsi_name, devid->ident, ident_len);
+		break;
+
+	case PROTOCOL_SRP:
+		sz = sizeof (scsi_srp_transport_id_t);
+		rpt = stmf_remote_port_alloc(sz);
+		rpt->rport_tptid->format_code = 0;
+		rpt->rport_tptid->protocol_id = devid->protocol_id;
+		srp_tpd = (scsi_srp_transport_id_t *)rpt->rport_tptid;
+		/*
+		 * convert from "eui.xxxxxxxxxxxxxxx" to 8-byte binary
+		 * skip first 4 byte for "eui."
+		 * Assume 8-byte initiator-extension part of srp_name is NOT
+		 * stored in devid and hence will be set as zero
+		 */
+		ASSERT(strncmp("eui.", (char *)devid->ident, 4) == 0);
+		if ((ident_len < (SCSI_TPTID_SRP_PORT_NAME_LEN - 8) * 2 + 4) ||
+		    !stmf_base16_str_to_binary((char *)devid->ident+4,
+		    SCSI_TPTID_SRP_PORT_NAME_LEN, srp_tpd->srp_name))
+			goto devid_to_remote_port_fail;
+		break;
+
+	case PROTOCOL_PARALLEL_SCSI:
+	case PROTOCOL_SSA:
+	case PROTOCOL_IEEE_1394:
+	case PROTOCOL_SAS:
+	case PROTOCOL_ADT:
+	case PROTOCOL_ATAPI:
+	default :
+		ident_len = devid->ident_length;
+		sz = ALIGNED_TO_8BYTE_BOUNDARY(sizeof (stmf_dflt_scsi_tptid_t) +
+		    ident_len - 1);
+		rpt = stmf_remote_port_alloc(sz);
+		rpt->rport_tptid->format_code = 0;
+		rpt->rport_tptid->protocol_id = devid->protocol_id;
+		dflt_tpd = (stmf_dflt_scsi_tptid_t *)rpt->rport_tptid;
+		SCSI_WRITE16(dflt_tpd->ident_len, ident_len);
+		(void) memcpy(dflt_tpd->ident, devid->ident, ident_len);
+		break;
+	}
+	return (rpt);
+
+devid_to_remote_port_fail:
+	stmf_remote_port_free(rpt);
+	return (NULL);
+
+}
+
+stmf_remote_port_t *
+stmf_remote_port_alloc(uint16_t tptid_sz) {
+	stmf_remote_port_t *rpt;
+	rpt = (stmf_remote_port_t *)kmem_zalloc(
+	    sizeof (stmf_remote_port_t) + tptid_sz, KM_SLEEP);
+	rpt->rport_tptid_sz = tptid_sz;
+	rpt->rport_tptid = (scsi_transport_id_t *)(rpt + 1);
+	return (rpt);
+}
+
+void
+stmf_remote_port_free(stmf_remote_port_t *rpt)
+{
+	/*
+	 * Note: stmf_scsilib_devid_to_remote_port() function allocates
+	 *	remote port structures for all transports in the same way, So
+	 *	it is safe to deallocate it in a protocol independent manner.
+	 *	If any of the allocation method changes, corresponding changes
+	 *	need to be made here too.
+	 */
+	kmem_free(rpt, sizeof (stmf_remote_port_t) + rpt->rport_tptid_sz);
+}
--- a/usr/src/uts/common/io/comstar/stmf/stmf_impl.h	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/io/comstar/stmf/stmf_impl.h	Thu Jul 01 16:06:54 2010 -0700
@@ -212,6 +212,7 @@
 #define	ISS_BEING_CREATED			0x0004
 #define	ISS_GOT_INITIAL_LUNS			0x0008
 #define	ISS_EVENT_ACTIVE			0x0010
+#define	ISS_NULL_TPTID				0x0020
 
 #define	ITASK_MAX_NCMDS			14
 #define	ITASK_DEFAULT_POLL_TIMEOUT	0
--- a/usr/src/uts/common/sys/portif.h	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/sys/portif.h	Thu Jul 01 16:06:54 2010 -0700
@@ -82,6 +82,27 @@
 		uint32_t flags);
 } stmf_local_port_t;
 
+typedef struct stmf_remote_port {
+	struct scsi_transport_id	*rport_tptid;
+	uint16_t			rport_tptid_sz;
+} stmf_remote_port_t;
+
+typedef struct stmf_dflt_scsi_tptid {
+#if defined(_BIT_FIELDS_LTOH)
+	uint8_t			protocol_id : 4,
+				resbits : 2,
+				format_code : 2;
+#elif defined(_BIT_FIELDS_HTOL)
+	uint8_t			format_code : 2,
+				resbits : 2,
+				protocol_id : 4;
+#else
+#error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
+#endif	/* _BIT_FIELDS_LTOH */
+	uint8_t			rsvbyte1;
+	uint8_t			ident_len[2];
+	char			ident[1];
+} stmf_dflt_scsi_tptid_t;
 /*
  * abort cmd
  */
@@ -108,6 +129,7 @@
 	char			*ss_rport_alias;
 	struct stmf_local_port	*ss_lport;
 	uint64_t		ss_session_id;
+	struct stmf_remote_port	*ss_rport;
 } stmf_scsi_session_t;
 
 stmf_status_t stmf_register_port_provider(stmf_port_provider_t *pp);
--- a/usr/src/uts/common/sys/pppt_ic_if.h	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/sys/pppt_ic_if.h	Thu Jul 01 16:06:54 2010 -0700
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 #ifndef _SYS_PPPT_IC_IF_H
 #define	_SYS_PPPT_IC_IF_H
@@ -120,6 +119,7 @@
 	stmf_ic_msgid_t		icsc_task_msgid;
 	scsi_devid_desc_t	*icsc_ini_devid;
 	scsi_devid_desc_t	*icsc_tgt_devid;
+	stmf_remote_port_t	*icsc_rport;
 	uint8_t 		icsc_lun_id[16];
 	/*
 	 * fields from scsi_task_t
@@ -197,6 +197,7 @@
 	uint64_t		icscd_session_id;
 	scsi_devid_desc_t	*icscd_ini_devid;
 	scsi_devid_desc_t	*icscd_tgt_devid;
+	stmf_remote_port_t	*icscd_rport;
 } stmf_ic_session_create_destroy_msg_t;
 
 /*
--- a/usr/src/uts/common/sys/scsi/generic/persist.h	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/sys/scsi/generic/persist.h	Thu Jul 01 16:06:54 2010 -0700
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef	_SYS_SCSI_GENERIC_PERSIST_H
@@ -66,6 +65,35 @@
 #define	PGR_TYPE_EX_AC_AR	0x8	/* Exclusive Access, All Registrants */
 
 /*
+ * SPC-3 revision 23, Section 6.12.2, Table 113
+ * Persistent Reservations
+ * Persistent Reserve Out service action codes
+ */
+#define	PR_OUT_REGISTER		0x0	/* Register/unregister a reservation */
+					/* key with the device server */
+#define	PR_OUT_RESERVE		0x1	/* Create a persistent reservation */
+					/* having a specified SCOPE & TYPE */
+#define	PR_OUT_RELEASE		0x2	/* Release the selected persistent */
+					/* reservation */
+#define	PR_OUT_CLEAR		0x3	/* Clears all reservation keys and */
+					/* all persistent reservations */
+#define	PR_OUT_PREEMPT		0x4	/* Preempts persistent reservations */
+					/* and/or removes reservations */
+#define	PR_OUT_PREEMPT_ABORT	0x5	/* Preempts persistent reservations */
+					/* and/or removes reservations, and */
+					/* aborts all tasks for all preempted */
+					/* I_T nexuses */
+#define	PR_OUT_REGISTER_AND_IGNORE_EXISTING_KEY	0x06
+					/* Register a reservation key with */
+					/* the device server, or unregister a */
+					/* reservation key */
+#define	PR_OUT_REGISTER_MOVE	0x7	/* Register a reservation key for */
+					/* another I_T nexus with the device */
+					/* server and move a persistent */
+					/* reservation to the I_T nexus */
+
+
+/*
  * Information obtained from:
  *	SPC-3, Revision 23
  *	Section 6.11.5 PERSISTENCE RESERVE IN
@@ -76,6 +104,17 @@
 #define	iSCSI_PROTOCOL_ID	0x5	/* Table 262 - iSCSI Protocol ID  */
 #define	WW_UID_DEVICE_NAME	0x0	/* Table 288 - iSCSI Transport IDs */
 
+/*
+ * Definitions related SCSI Transport ID
+ * SPC3 rev 23, Tables 284-287
+ */
+#define	SCSI_TPTID_SIZE			24
+#define	SCSI_TPTID_FC_PORT_NAME_SIZE	8
+#define	SCSI_TPTID_SPI_ADDRESS_LEN	2
+#define	SCSI_TPTID_SPI_REL_TGTPTID_LEN	2
+#define	SCSI_TPTID_SBP_PORT_NAME_LEN	8
+#define	SCSI_TPTID_SRP_PORT_NAME_LEN	16
+#define	SCSI_TPTID_ISCSI_ISID_SEPERATOR	",i,0x"
 
 #if defined(_BIT_FIELDS_LTOH)
 /*
@@ -473,37 +512,6 @@
 #else
 #error	One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
 #endif	/* _BIT_FIELDS_LTOH */
-
-
-/*
- * SPC-3 revision 23, Section 6.12.2, Table 113
- * Persistent Reservations
- * Persistent Reserve Out service action codes
- */
-#define	PR_OUT_REGISTER		0x0	/* Register/unregister a reservation */
-					/* key with the device server */
-#define	PR_OUT_RESERVE		0x1	/* Create a persistent reservation */
-					/* having a specified SCOPE & TYPE */
-#define	PR_OUT_RELEASE		0x2	/* Release the selected persistent */
-					/* reservation */
-#define	PR_OUT_CLEAR		0x3	/* Clears all reservation keys and */
-					/* all persistent reservations */
-#define	PR_OUT_PREEMPT		0x4	/* Preempts persistent reservations */
-					/* and/or removes reservations */
-#define	PR_OUT_PREEMPT_ABORT	0x5	/* Preempts persistent reservations */
-					/* and/or removes reservations, and */
-					/* aborts all tasks for all preempted */
-					/* I_T nexuses */
-#define	PR_OUT_REGISTER_AND_IGNORE_EXISTING_KEY	0x06
-					/* Register a reservation key with */
-					/* the device server, or unregister a */
-					/* reservation key */
-#define	PR_OUT_REGISTER_MOVE	0x7	/* Register a reservation key for */
-					/* another I_T nexus with the device */
-					/* server and move a persistent */
-					/* reservation to the I_T nexus */
-
-
 #ifdef	__cplusplus
 }
 #endif
--- a/usr/src/uts/common/sys/stmf.h	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/sys/stmf.h	Thu Jul 01 16:06:54 2010 -0700
@@ -409,6 +409,14 @@
 void stmf_scsilib_handle_report_tpgs(scsi_task_t *task, stmf_data_buf_t *dbuf);
 void stmf_scsilib_handle_task_mgmt(scsi_task_t *task);
 
+struct stmf_remote_port *stmf_scsilib_devid_to_remote_port(
+    struct scsi_devid_desc *);
+boolean_t stmf_scsilib_tptid_validate(struct scsi_transport_id *,
+    uint32_t, uint16_t *);
+boolean_t stmf_scsilib_tptid_compare(struct scsi_transport_id *,
+    struct scsi_transport_id *);
+struct stmf_remote_port *stmf_remote_port_alloc(uint16_t);
+void stmf_remote_port_free(struct stmf_remote_port *);
 #ifdef	__cplusplus
 }
 #endif
--- a/usr/src/uts/common/sys/stmf_defines.h	Thu Jul 01 15:58:16 2010 -0700
+++ b/usr/src/uts/common/sys/stmf_defines.h	Thu Jul 01 16:06:54 2010 -0700
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 #ifndef	_STMF_DEFINES_H
 #define	_STMF_DEFINES_H
@@ -136,9 +135,11 @@
 struct stmf_lu;
 struct stmf_port_provider;
 struct stmf_local_port;
+struct stmf_remote_port;
 struct stmf_scsi_session;
 struct scsi_task;
 struct scsi_devid_desc;
+struct scsi_transport_id;
 struct stmf_data_buf;
 struct stmf_lun_map;
 struct scsi_devid_desc;