changeset 12045:c8a185097d95

6933916 Should check if the NACA flag is set in uscsi path
author Nikko He <Li.He@Sun.COM>
date Wed, 31 Mar 2010 10:38:52 +0800
parents 3b818da59da0
children da752cc12a31
files usr/src/uts/common/io/scsi/impl/scsi_subr.c usr/src/uts/common/io/scsi/impl/scsi_transport.c usr/src/uts/common/sys/scsi/impl/commands.h
diffstat 3 files changed, 46 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/scsi/impl/scsi_subr.c	Tue Mar 30 17:10:14 2010 -0700
+++ b/usr/src/uts/common/io/scsi/impl/scsi_subr.c	Wed Mar 31 10:38:52 2010 +0800
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <sys/scsi/scsi.h>
@@ -34,6 +34,7 @@
  * Polling support routines
  */
 
+int		scsi_pkt_allow_naca = 0;
 extern uintptr_t scsi_callback_id;
 
 extern uchar_t scsi_cdb_size[];
@@ -2477,6 +2478,25 @@
 {
 
 	/*
+	 * Check if the NACA flag is set. If one initiator sets it
+	 * but does not clear it, other initiators would end up
+	 * waiting indefinitely for the first to clear NACA. If the
+	 * the system allows NACA to be set, then warn the user but
+	 * still pass the command down, otherwise, clear the flag.
+	 */
+	if (uscmd->uscsi_cdb[uscmd->uscsi_cdblen - 1] & CDB_FLAG_NACA) {
+		if (scsi_pkt_allow_naca) {
+			cmn_err(CE_WARN, "scsi_uscsi_pktinit: "
+			    "NACA flag is set");
+		} else {
+			uscmd->uscsi_cdb[uscmd->uscsi_cdblen - 1] &=
+			    ~CDB_FLAG_NACA;
+			cmn_err(CE_WARN, "scsi_uscsi_pktinit: "
+			    "NACA flag is cleared");
+		}
+	}
+
+	/*
 	 * See if path_instance was requested in uscsi_cmd.
 	 */
 	if ((uscmd->uscsi_flags & USCSI_PATH_INSTANCE) &&
--- a/usr/src/uts/common/io/scsi/impl/scsi_transport.c	Tue Mar 30 17:10:14 2010 -0700
+++ b/usr/src/uts/common/io/scsi/impl/scsi_transport.c	Wed Mar 31 10:38:52 2010 +0800
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -50,6 +50,12 @@
 
 extern int		do_polled_io;
 
+extern int		scsi_pkt_allow_naca;
+extern uchar_t		scsi_cdb_size[];
+#define	NACA_IS_SET(cdb)						\
+	(((cdb)[scsi_cdb_size[GETGROUP((union scsi_cdb *)(cdb))] - 1]	\
+	& CDB_FLAG_NACA) ? 1 : 0)
+
 /*
  * we used to set the callback_done value to NULL after the callback
  * but this interfered with esp/fas drivers that also set the callback
@@ -102,6 +108,16 @@
 	major_t			major;
 
 	/*
+	 * Add an assertion check for debugging as use of the NACA flag
+	 * can cause problems. If an initiator sets it but does not clear
+	 * it, other initiators would end up waiting indefinitely for the
+	 * first to clear ACA.
+	 */
+	if (!scsi_pkt_allow_naca) {
+		ASSERT(!NACA_IS_SET(pkt->pkt_cdbp));
+	}
+
+	/*
 	 * The DDI does not allow drivers to allocate their own scsi_pkt(9S),
 	 * a driver can't have *any* compiled in dependencies on the
 	 * "sizeof (struct scsi_pkt)". While this has been the case for years,
--- a/usr/src/uts/common/sys/scsi/impl/commands.h	Tue Mar 30 17:10:14 2010 -0700
+++ b/usr/src/uts/common/sys/scsi/impl/commands.h	Wed Mar 31 10:38:52 2010 +0800
@@ -18,16 +18,14 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef	_SYS_SCSI_IMPL_COMMANDS_H
 #define	_SYS_SCSI_IMPL_COMMANDS_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef	__cplusplus
 extern "C" {
 #endif
@@ -575,6 +573,10 @@
 #define	DLD_BFI_FORMAT		0x04	/* bytes-from-index format */
 #define	DLD_PS_FORMAT		0x05	/* physical sector format */
 
+/*
+ * Defines for value of CONTROL byte of cdb.
+ */
+#define	CDB_FLAG_NACA		0x04	/* naca flag */
 
 /*
  * Disk defect list - used by format command.