--- 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.