6783286 STMS: Host loses access to data on >1TB volumes when there's an external failover on asymm arrays
authorwl202157@icefox
Wed, 08 Apr 2009 09:29:20 +0800
changeset 9304 ff96a286a5d4
parent 9303 587ef5ac9176
child 9305 7d93ad6ed659
6783286 STMS: Host loses access to data on >1TB volumes when there's an external failover on asymm arrays
usr/src/uts/common/io/scsi/adapters/scsi_vhci/fops/asym_sun.c
usr/src/uts/common/io/scsi/adapters/scsi_vhci/fops/sym.c
usr/src/uts/common/io/scsi/adapters/scsi_vhci/fops/tape.c
usr/src/uts/common/io/scsi/adapters/scsi_vhci/fops/tpgs.c
usr/src/uts/common/io/scsi/adapters/scsi_vhci/scsi_vhci.c
usr/src/uts/common/io/scsi/adapters/scsi_vhci/scsi_vhci_tpgs.c
usr/src/uts/common/sys/scsi/adapters/scsi_vhci.h
--- a/usr/src/uts/common/io/scsi/adapters/scsi_vhci/fops/asym_sun.c	Tue Apr 07 13:03:48 2009 -0600
+++ b/usr/src/uts/common/io/scsi/adapters/scsi_vhci/fops/asym_sun.c	Wed Apr 08 09:29:20 2009 +0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -225,7 +225,7 @@
 	struct scsi_address	*ap;
 	int			err, retry_cnt, retry_cmd_cnt;
 	int			mode, ownership, retval, xlf;
-	struct scsi_extended_sense	*sns;
+	uint8_t			*sns, skey, asc, ascq;
 
 	ap = &sd->sd_address;
 
@@ -315,18 +315,20 @@
 			 */
 			retry_cmd_cnt = 0;
 			if (pkt->pkt_state & STATE_ARQ_DONE) {
-				sns = &(((struct scsi_arq_status *)(uintptr_t)
+				sns = (uint8_t *)
+				    &(((struct scsi_arq_status *)(uintptr_t)
 				    (pkt->pkt_scbp))->sts_sensedata);
-				if (sns->es_key == KEY_UNIT_ATTENTION) {
+				skey = scsi_sense_key(sns);
+				asc = scsi_sense_asc(sns);
+				ascq = scsi_sense_ascq(sns);
+				if (skey == KEY_UNIT_ATTENTION) {
 					/*
 					 * swallow unit attention
 					 */
 					goto retry;
-				} else if ((sns->es_key == KEY_NOT_READY) &&
-				    (sns->es_add_code ==
-				    T3_SCSI_ASC_FO_IN_PROGRESS) &&
-				    (sns->es_qual_code ==
-				    T3_SCSI_ASCQ_PATH_INACT2ACT)) {
+				} else if ((skey == KEY_NOT_READY) &&
+				    (asc == T3_SCSI_ASC_FO_IN_PROGRESS) &&
+				    (ascq == T3_SCSI_ASCQ_PATH_INACT2ACT)) {
 					if (retry_cnt++ >=
 					    PURPLE_FO_MAX_RETRIES) {
 						cmn_err(CE_WARN, "!T3 failover"
@@ -345,8 +347,7 @@
 				}
 				cmn_err(CE_NOTE, "!T3 failover failed;"
 				    " sense key:%x, ASC: %x, "
-				    "ASCQ:%x", sns->es_key,
-				    sns->es_add_code, sns->es_qual_code);
+				    "ASCQ:%x", skey, asc, ascq);
 				scsi_destroy_pkt(pkt);
 				scsi_free_consistent_buf(bp);
 				return (1);
@@ -507,18 +508,23 @@
 
 /* ARGSUSED */
 static int
-purple_analyze_sense(struct scsi_device *sd, struct scsi_extended_sense
-*sense, void *ctpriv)
+purple_analyze_sense(struct scsi_device *sd, uint8_t *sense,
+void *ctpriv)
 {
-	if (sense->es_key == KEY_NOT_READY) {
-		if (sense->es_add_code == T3_SCSI_ASC_FO_IN_PROGRESS) {
-			if (sense->es_qual_code == T3_SCSI_ASCQ_PATH_INACT2ACT)
+	uint8_t skey, asc, ascq;
+
+	skey = scsi_sense_key(sense);
+	asc = scsi_sense_asc(sense);
+	ascq = scsi_sense_ascq(sense);
+
+	if (skey == KEY_NOT_READY) {
+		if (asc == T3_SCSI_ASC_FO_IN_PROGRESS) {
+			if (ascq == T3_SCSI_ASCQ_PATH_INACT2ACT)
 				return (SCSI_SENSE_INACT2ACT);
-			else if (sense->es_qual_code ==
-			    T3_SCSI_ASCQ_PATH_ACT2INACT)
+			else if (ascq == T3_SCSI_ASCQ_PATH_ACT2INACT)
 				return (SCSI_SENSE_ACT2INACT);
-		} else if ((sense->es_add_code == T3_SCSI_ASC_PATH_INACTIVE) &&
-		    (sense->es_qual_code == T3_SCSI_ASCQ_PATH_INACTIVE)) {
+		} else if ((asc == T3_SCSI_ASC_PATH_INACTIVE) &&
+		    (ascq == T3_SCSI_ASCQ_PATH_INACTIVE)) {
 			return (SCSI_SENSE_INACTIVE);
 		}
 	}
@@ -529,8 +535,7 @@
 	 * return SCSI_SENSE_UNKNOWN.
 	 */
 	VHCI_DEBUG(6, (CE_NOTE, NULL, "!T3 analyze sense UNKNOWN:"
-	    " sense key:%x, ASC: %x, ASCQ:%x\n", sense->es_key,
-	    sense->es_add_code, sense->es_qual_code));
+	    " sense key:%x, ASC: %x, ASCQ:%x\n", skey, asc, ascq));
 	return (SCSI_SENSE_UNKNOWN);
 }
 
--- a/usr/src/uts/common/io/scsi/adapters/scsi_vhci/fops/sym.c	Tue Apr 07 13:03:48 2009 -0600
+++ b/usr/src/uts/common/io/scsi/adapters/scsi_vhci/fops/sym.c	Wed Apr 08 09:29:20 2009 +0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -157,7 +157,7 @@
 /* ARGSUSED */
 static int
 symmetric_analyze_sense(struct scsi_device *sd,
-struct scsi_extended_sense *sense, void *ctpriv)
+uint8_t *sense, void *ctpriv)
 {
 	return (SCSI_SENSE_NOFAILOVER);
 }
--- a/usr/src/uts/common/io/scsi/adapters/scsi_vhci/fops/tape.c	Tue Apr 07 13:03:48 2009 -0600
+++ b/usr/src/uts/common/io/scsi/adapters/scsi_vhci/fops/tape.c	Wed Apr 08 09:29:20 2009 +0800
@@ -180,17 +180,23 @@
 
 /* ARGSUSED */
 static int
-tape_analyze_sense(struct scsi_device *sd, struct scsi_extended_sense *sense,
+tape_analyze_sense(struct scsi_device *sd, uint8_t *sense,
     void *ctpriv)
 {
-	if (sense->es_key == KEY_ABORTED_COMMAND &&
-	    sense->es_add_code == 0x4b &&
-	    sense->es_qual_code == 0x83) {
+	uint8_t skey, asc, ascq;
+
+	skey = scsi_sense_key(sense);
+	asc = scsi_sense_asc(sense);
+	ascq = scsi_sense_ascq(sense);
+
+	if (skey == KEY_ABORTED_COMMAND &&
+	    asc == 0x4b &&
+	    ascq == 0x83) {
 		return (SCSI_SENSE_INACTIVE);
 	}
-	if (sense->es_key == KEY_NOT_READY &&
-	    sense->es_add_code == 0x4 &&
-	    sense->es_qual_code == 0x1) {
+	if (skey == KEY_NOT_READY &&
+	    asc == 0x4 &&
+	    ascq == 0x1) {
 		return (SCSI_SENSE_NOT_READY);
 	}
 	return (SCSI_SENSE_NOFAILOVER);
--- a/usr/src/uts/common/io/scsi/adapters/scsi_vhci/fops/tpgs.c	Tue Apr 07 13:03:48 2009 -0600
+++ b/usr/src/uts/common/io/scsi/adapters/scsi_vhci/fops/tpgs.c	Wed Apr 08 09:29:20 2009 +0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -137,7 +137,7 @@
 std_process_cmplt_pkt(struct scsi_device *sd, struct scsi_pkt *pkt,
     int *retry_cnt)
 {
-	struct scsi_extended_sense	*sns;
+	uint8_t *sns, skey, asc, ascq;
 
 	/*
 	 * Re-initialize retry_cmd_cnt. Allow transport and
@@ -149,20 +149,24 @@
 	 * while waiting for the fo to complete.
 	 */
 	if (pkt->pkt_state & STATE_ARQ_DONE) {
-		sns = &(((struct scsi_arq_status *)(uintptr_t)
+		sns = (uint8_t *)
+		    &(((struct scsi_arq_status *)(uintptr_t)
 		    (pkt->pkt_scbp))->sts_sensedata);
-		if (sns->es_key == KEY_UNIT_ATTENTION) {
+		skey = scsi_sense_key(sns);
+		asc = scsi_sense_asc(sns);
+		ascq = scsi_sense_ascq(sns);
+		if (skey == KEY_UNIT_ATTENTION) {
 			/*
 			 * tpgs access state changed
 			 */
-			if (sns->es_add_code == STD_SCSI_ASC_STATE_CHG &&
-			    sns->es_qual_code == STD_SCSI_ASCQ_STATE_CHG_SUCC) {
+			if (asc == STD_SCSI_ASC_STATE_CHG &&
+			    ascq == STD_SCSI_ASCQ_STATE_CHG_SUCC) {
 				/* XXX: update path info? */
 				cmn_err(CE_WARN, "!Device failover"
 				    " state change");
 			}
 			return (1);
-		} else if (sns->es_key == KEY_NOT_READY) {
+		} else if (skey == KEY_NOT_READY) {
 			if ((*retry_cnt)++ >=
 			    STD_FO_MAX_RETRIES) {
 				cmn_err(CE_WARN, "!Device failover"
@@ -178,8 +182,7 @@
 		}
 		cmn_err(CE_NOTE, "!Failover failed;"
 		    " sense key:%x, ASC: %x, "
-		    "ASCQ:%x", sns->es_key,
-		    sns->es_add_code, sns->es_qual_code);
+		    "ASCQ:%x", skey, asc, ascq);
 		return (0);
 	}
 	switch (SCBP_C(pkt)) {
@@ -413,41 +416,43 @@
  */
 /* ARGSUSED */
 static int
-std_analyze_sense(struct scsi_device *sd, struct scsi_extended_sense *sense,
+std_analyze_sense(struct scsi_device *sd, uint8_t *sense,
     void *ctpriv)
 {
 	int rval = SCSI_SENSE_UNKNOWN;
 
-	if ((sense->es_key == KEY_UNIT_ATTENTION) &&
-	    (sense->es_add_code == STD_SCSI_ASC_STATE_CHG) &&
-	    (sense->es_qual_code == STD_SCSI_ASCQ_STATE_CHG_SUCC)) {
+	uint8_t skey, asc, ascq;
+
+	skey = scsi_sense_key(sense);
+	asc = scsi_sense_asc(sense);
+	ascq = scsi_sense_ascq(sense);
+
+	if ((skey == KEY_UNIT_ATTENTION) &&
+	    (asc == STD_SCSI_ASC_STATE_CHG) &&
+	    (ascq == STD_SCSI_ASCQ_STATE_CHG_SUCC)) {
 		rval = SCSI_SENSE_STATE_CHANGED;
 		VHCI_DEBUG(4, (CE_NOTE, NULL, "!std_analyze_sense:"
 		    " sense_key:%x, add_code: %x, qual_code:%x"
-		    " sense:%x\n", sense->es_key, sense->es_add_code,
-		    sense->es_qual_code, rval));
-	} else if ((sense->es_key == KEY_NOT_READY) &&
-	    (sense->es_add_code == STD_LOGICAL_UNIT_NOT_ACCESSIBLE) &&
-	    (sense->es_qual_code == STD_TGT_PORT_UNAVAILABLE)) {
+		    " sense:%x\n", skey, asc, ascq, rval));
+	} else if ((skey == KEY_NOT_READY) &&
+	    (asc == STD_LOGICAL_UNIT_NOT_ACCESSIBLE) &&
+	    (ascq == STD_TGT_PORT_UNAVAILABLE)) {
 		rval = SCSI_SENSE_INACTIVE;
 		VHCI_DEBUG(4, (CE_NOTE, NULL, "!std_analyze_sense:"
 		    " sense_key:%x, add_code: %x, qual_code:%x"
-		    " sense:%x\n", sense->es_key, sense->es_add_code,
-		    sense->es_qual_code, rval));
-	} else if ((sense->es_key == KEY_ILLEGAL_REQUEST) &&
-	    (sense->es_add_code == STD_SCSI_ASC_INVAL_PARAM_LIST)) {
+		    " sense:%x\n", skey, asc, ascq, rval));
+	} else if ((skey == KEY_ILLEGAL_REQUEST) &&
+	    (asc == STD_SCSI_ASC_INVAL_PARAM_LIST)) {
 		rval = SCSI_SENSE_NOFAILOVER;
 		VHCI_DEBUG(1, (CE_NOTE, NULL, "!std_analyze_sense:"
 		    " sense_key:%x, add_code: %x, qual_code:%x"
-		    " sense:%x\n", sense->es_key, sense->es_add_code,
-		    sense->es_qual_code, rval));
-	} else if ((sense->es_key == KEY_ILLEGAL_REQUEST) &&
-	    (sense->es_add_code == STD_SCSI_ASC_INVAL_CMD_OPCODE)) {
+		    " sense:%x\n", skey, asc, ascq, rval));
+	} else if ((skey == KEY_ILLEGAL_REQUEST) &&
+	    (asc == STD_SCSI_ASC_INVAL_CMD_OPCODE)) {
 		rval = SCSI_SENSE_NOFAILOVER;
 		VHCI_DEBUG(1, (CE_NOTE, NULL, "!std_analyze_sense:"
 		    " sense_key:%x, add_code: %x, qual_code:%x"
-		    " sense:%x\n", sense->es_key, sense->es_add_code,
-		    sense->es_qual_code, rval));
+		    " sense:%x\n", skey, asc, ascq, rval));
 	} else {
 		/*
 		 * At this point sense data may be for power-on-reset
@@ -455,8 +460,7 @@
 		 * For all these cases, return SCSI_SENSE_UNKNOWN.
 		 */
 		VHCI_DEBUG(1, (CE_NOTE, NULL, "!Analyze sense UNKNOWN:"
-		    " sense key:%x, ASC:%x, ASCQ:%x\n", sense->es_key,
-		    sense->es_add_code, sense->es_qual_code));
+		    " sense key:%x, ASC:%x, ASCQ:%x\n", skey, asc, ascq));
 	}
 
 	return (rval);
--- a/usr/src/uts/common/io/scsi/adapters/scsi_vhci/scsi_vhci.c	Tue Apr 07 13:03:48 2009 -0600
+++ b/usr/src/uts/common/io/scsi/adapters/scsi_vhci/scsi_vhci.c	Wed Apr 08 09:29:20 2009 +0800
@@ -2469,7 +2469,7 @@
 	struct buf			*bp;
 	scsi_vhci_lun_t			*vlun = svp->svp_svl;
 	int				rval, retry, nr_retry, ua_retry;
-	struct scsi_extended_sense	*sns;
+	uint8_t				*sns, skey;
 
 	bp = getrbuf(KM_SLEEP);
 	bp->b_flags = B_WRITE;
@@ -2504,10 +2504,12 @@
 		if ((new_pkt->pkt_reason == CMD_CMPLT) &&
 		    (SCBP_C(new_pkt) == STATUS_CHECK) &&
 		    (new_pkt->pkt_state & STATE_ARQ_DONE)) {
-			sns = &(((struct scsi_arq_status *)(uintptr_t)
+			sns = (uint8_t *)
+			    &(((struct scsi_arq_status *)(uintptr_t)
 			    (new_pkt->pkt_scbp))->sts_sensedata);
-			if ((sns->es_key == KEY_UNIT_ATTENTION) ||
-			    (sns->es_key == KEY_NOT_READY)) {
+			skey = scsi_sense_key(sns);
+			if ((skey == KEY_UNIT_ATTENTION) ||
+			    (skey == KEY_NOT_READY)) {
 				int max_retry;
 				struct scsi_failover_ops *fops;
 				fops = vlun->svl_fops;
@@ -2552,7 +2554,7 @@
 				    new_pkt->pkt_cdbp[0],
 				    new_pkt->pkt_cdbp[1],
 				    new_pkt->pkt_cdbp[2]));
-			} else if (sns->es_key == KEY_ILLEGAL_REQUEST)
+			} else if (skey == KEY_ILLEGAL_REQUEST)
 				rval = VHCI_PGR_ILLEGALOP;
 		}
 	} else {
@@ -3047,7 +3049,7 @@
 	scsi_vhci_lun_t		*vlun;
 	int			rval, held;
 	struct scsi_failover_ops	*fops;
-	struct scsi_extended_sense	*sns;
+	uint8_t			*sns, skey, asc, ascq;
 	mdi_pathinfo_t		*lpath;
 	static char		*timeout_err = "Command Timeout";
 	static char		*parity_err = "Parity Error";
@@ -3111,14 +3113,17 @@
 		switch (*(pkt->pkt_scbp)) {
 		case STATUS_CHECK:
 			if (pkt->pkt_state & STATE_ARQ_DONE) {
-				sns = &(((struct scsi_arq_status *)(uintptr_t)
+				sns = (uint8_t *)
+				    &(((struct scsi_arq_status *)(uintptr_t)
 				    (pkt->pkt_scbp))->sts_sensedata);
+				skey = scsi_sense_key(sns);
+				asc = scsi_sense_asc(sns);
+				ascq = scsi_sense_ascq(sns);
 				fops = vlun->svl_fops;
 				ASSERT(fops != NULL);
 				VHCI_DEBUG(4, (CE_NOTE, NULL, "vhci_intr: "
 				    "Received sns key %x  esc %x  escq %x\n",
-				    sns->es_key, sns->es_add_code,
-				    sns->es_qual_code));
+				    skey, asc, ascq));
 
 				if (vlun->svl_waiting_for_activepath == 1) {
 					/*
@@ -3134,7 +3139,7 @@
 					    vpkt->vpkt_tgt_init_scblen);
 					break;
 				}
-				if (sns->es_add_code == VHCI_SCSI_PERR) {
+				if (asc == VHCI_SCSI_PERR) {
 					/*
 					 * parity error
 					 */
@@ -3530,7 +3535,7 @@
 vhci_efo_watch_cb(caddr_t arg, struct scsi_watch_result *resultp)
 {
 	struct scsi_status		*statusp = resultp->statusp;
-	struct scsi_extended_sense	*sensep = resultp->sensep;
+	uint8_t				*sensep = (uint8_t *)resultp->sensep;
 	struct scsi_pkt			*pkt = resultp->pkt;
 	scsi_vhci_swarg_t		*swarg;
 	scsi_vhci_priv_t		*svp;
@@ -6840,11 +6845,15 @@
 			}
 			if (check_condition &&
 			    (pkt->pkt_state & STATE_ARQ_DONE)) {
-				struct scsi_extended_sense *sns =
+				uint8_t *sns, skey, asc, ascq;
+				sns = (uint8_t *)
 				    &(((struct scsi_arq_status *)(uintptr_t)
 				    (pkt->pkt_scbp))->sts_sensedata);
-				if (sns->es_key == KEY_UNIT_ATTENTION &&
-				    sns->es_add_code == 0x29) {
+				skey = scsi_sense_key(sns);
+				asc = scsi_sense_asc(sns);
+				ascq = scsi_sense_ascq(sns);
+				if (skey == KEY_UNIT_ATTENTION &&
+				    asc == 0x29) {
 					/* Already failed over */
 					VHCI_DEBUG(1, (CE_NOTE, NULL,
 					    "!vhci_failover(7)(%s): "
@@ -6859,9 +6868,8 @@
 					VHCI_DEBUG(1, (CE_NOTE, NULL,
 					    "!vhci_failover(%s): path 0x%p "
 					    "unhandled chkcond %x %x %x\n",
-					    guid, (void *)npip, sns->es_key,
-					    sns->es_add_code,
-					    sns->es_qual_code));
+					    guid, (void *)npip, skey,
+					    asc, ascq));
 				}
 			}
 			scsi_destroy_pkt(pkt);
@@ -7218,7 +7226,7 @@
 {
 	int	err = 0;
 	int	retry_cnt = 0;
-	struct scsi_extended_sense	*sns;
+	uint8_t	*sns, skey;
 
 #ifdef DEBUG
 	if (vhci_debug > 5) {
@@ -7246,12 +7254,14 @@
 			if ((pkt->pkt_reason == CMD_CMPLT) &&
 			    (SCBP_C(pkt) == STATUS_CHECK) &&
 			    (pkt->pkt_state & STATE_ARQ_DONE)) {
-				sns = &(((struct scsi_arq_status *)(uintptr_t)
+				sns = (uint8_t *)
+				    &(((struct scsi_arq_status *)(uintptr_t)
 				    (pkt->pkt_scbp))->sts_sensedata);
+				skey = scsi_sense_key(sns);
 				VHCI_DEBUG(1, (CE_WARN, NULL,
 				    "!v_s_do_s_c:retry "
 				    "packet 0x%p  sense data %s", (void *)pkt,
-				    scsi_sname(sns->es_key)));
+				    scsi_sname(skey)));
 			}
 			goto retry;
 		}
@@ -7272,14 +7282,15 @@
 					break;
 				case STATUS_CHECK:
 					if (pkt->pkt_state & STATE_ARQ_DONE) {
-						sns = &(((
+						sns = (uint8_t *)&(((
 						    struct scsi_arq_status *)
 						    (uintptr_t)
 						    (pkt->pkt_scbp))->
 						    sts_sensedata);
-						if ((sns->es_key ==
+						skey = scsi_sense_key(sns);
+						if ((skey ==
 						    KEY_UNIT_ATTENTION) ||
-						    (sns->es_key ==
+						    (skey ==
 						    KEY_NOT_READY)) {
 							/*
 							 * clear unit attn.
@@ -7293,7 +7304,7 @@
 							    "data %s",
 							    (void *)pkt,
 							    scsi_sname
-							    (sns->es_key)));
+							    (skey)));
 							goto retry;
 						}
 						VHCI_DEBUG(4, (CE_WARN, NULL,
--- a/usr/src/uts/common/io/scsi/adapters/scsi_vhci/scsi_vhci_tpgs.c	Tue Apr 07 13:03:48 2009 -0600
+++ b/usr/src/uts/common/io/scsi/adapters/scsi_vhci/scsi_vhci_tpgs.c	Wed Apr 08 09:29:20 2009 +0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -55,7 +55,7 @@
 	struct buf			*bp;
 	int				len, rval, ss = SCSI_SENSE_UNKNOWN;
 	char				*bufp;
-	struct scsi_extended_sense	*sns;
+	uint8_t				*sns, skey, asc, ascq;
 
 	len = 8;
 
@@ -124,34 +124,35 @@
 	} else if ((pkt->pkt_reason == CMD_CMPLT) &&
 	    (SCBP_C(pkt) == STATUS_CHECK) &&
 	    (pkt->pkt_state & STATE_ARQ_DONE)) {
-		sns = &(((struct scsi_arq_status *)(uintptr_t)
+		sns = (uint8_t *)
+		    &(((struct scsi_arq_status *)(uintptr_t)
 		    (pkt->pkt_scbp))->sts_sensedata);
+		skey = scsi_sense_key(sns);
+		asc = scsi_sense_asc(sns);
+		ascq = scsi_sense_ascq(sns);
 
-		if ((sns->es_key == KEY_UNIT_ATTENTION) &&
-		    (sns->es_add_code == STD_SCSI_ASC_STATE_CHG) &&
-		    (sns->es_qual_code == STD_SCSI_ASCQ_STATE_CHG_SUCC)) {
+		if ((skey == KEY_UNIT_ATTENTION) &&
+		    (asc == STD_SCSI_ASC_STATE_CHG) &&
+		    (ascq == STD_SCSI_ASCQ_STATE_CHG_SUCC)) {
 			ss = SCSI_SENSE_STATE_CHANGED;
 			VHCI_DEBUG(4, (CE_NOTE, NULL,
 			    "!vhci_tpgs_set_target_groups:"
 			    " sense:%x, add_code: %x, qual_code:%x"
-			    " sense:%x\n", sns->es_key, sns->es_add_code,
-			    sns->es_qual_code, ss));
-		} else if ((sns->es_key == KEY_ILLEGAL_REQUEST) &&
-		    (sns->es_add_code == STD_SCSI_ASC_INVAL_PARAM_LIST)) {
+			    " sense:%x\n", skey, asc, ascq, ss));
+		} else if ((skey == KEY_ILLEGAL_REQUEST) &&
+		    (asc == STD_SCSI_ASC_INVAL_PARAM_LIST)) {
 			ss = SCSI_SENSE_NOFAILOVER;
 			VHCI_DEBUG(1, (CE_NOTE, NULL,
 			    "!vhci_tpgs_set_target_groups:"
 			    " sense:%x, add_code: %x, qual_code:%x"
-			    " sense:%x\n", sns->es_key, sns->es_add_code,
-			    sns->es_qual_code, ss));
-		} else if ((sns->es_key == KEY_ILLEGAL_REQUEST) &&
-		    (sns->es_add_code == STD_SCSI_ASC_INVAL_CMD_OPCODE)) {
+			    " sense:%x\n", skey, asc, ascq, ss));
+		} else if ((skey == KEY_ILLEGAL_REQUEST) &&
+		    (asc == STD_SCSI_ASC_INVAL_CMD_OPCODE)) {
 			ss = SCSI_SENSE_NOFAILOVER;
 			VHCI_DEBUG(1, (CE_NOTE, NULL,
 			    "!vhci_tpgs_set_target_groups:"
 			    " sense_key:%x, add_code: %x, qual_code:%x"
-			    " sense:%x\n", sns->es_key, sns->es_add_code,
-			    sns->es_qual_code, rval));
+			    " sense:%x\n", skey, asc, ascq, rval));
 		} else {
 			/*
 			 * At this point sns data may be for power-on-reset
@@ -162,7 +163,7 @@
 			VHCI_DEBUG(1, (CE_NOTE, NULL,
 			    "!vhci_tpgs_set_target_groups: "
 			    " sense UNKNOWN: sense key:%x, ASC:%x, ASCQ:%x\n",
-			    sns->es_key, sns->es_add_code, sns->es_qual_code));
+			    skey, asc, ascq));
 		}
 
 		if (ss == SCSI_SENSE_STATE_CHANGED) {
--- a/usr/src/uts/common/sys/scsi/adapters/scsi_vhci.h	Tue Apr 07 13:03:48 2009 -0600
+++ b/usr/src/uts/common/sys/scsi/adapters/scsi_vhci.h	Wed Apr 08 09:29:20 2009 +0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -600,9 +600,9 @@
 	 * failovers
 	 */
 	int	(*sfo_analyze_sense)(
-			struct scsi_device		*sd,
-			struct scsi_extended_sense	*sense,
-			void				*ctpriv);
+			struct scsi_device	*sd,
+			uint8_t			*sense,
+			void			*ctpriv);
 
 	/*
 	 * return the next pathclass in order of preference
@@ -663,7 +663,7 @@
 				struct scsi_device *, void *);		\
 	static int	local_name##_analyze_sense(			\
 				struct scsi_device *,			\
-				struct scsi_extended_sense *, void *);	\
+				uint8_t *, void *);			\
 	static int	local_name##_pathclass_next(			\
 				char *, char **, void *);		\
 	struct scsi_failover_ops ops_name##_failover_ops = {		\