changeset 10976:03a10dbb75a3

6862543 aac should support power management commands for logical disk
author zhongyan gu - Sun Microsystems - Beijing China <Zhongyan.Gu@Sun.COM>
date Fri, 06 Nov 2009 11:27:47 +0800
parents 9dd13a7cd2e3
children de59debacdeb
files usr/src/uts/common/io/aac/aac.c usr/src/uts/common/io/aac/aac.h usr/src/uts/common/io/aac/aac_regs.h
diffstat 3 files changed, 106 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/aac/aac.c	Fri Nov 06 11:19:08 2009 +0800
+++ b/usr/src/uts/common/io/aac/aac.c	Fri Nov 06 11:27:47 2009 +0800
@@ -308,6 +308,7 @@
 static void aac_cmd_fib_sync(struct aac_softstate *, struct aac_cmd *);
 static void aac_cmd_fib_scsi32(struct aac_softstate *, struct aac_cmd *);
 static void aac_cmd_fib_scsi64(struct aac_softstate *, struct aac_cmd *);
+static void aac_cmd_fib_startstop(struct aac_softstate *, struct aac_cmd *);
 static void aac_start_waiting_io(struct aac_softstate *);
 static void aac_drain_comp_q(struct aac_softstate *);
 int aac_do_io(struct aac_softstate *, struct aac_cmd *);
@@ -2048,6 +2049,26 @@
 		aac_set_arq_data_hwerr(acp);
 }
 
+static void
+aac_startstop_complete(struct aac_softstate *softs, struct aac_cmd *acp)
+{
+	struct aac_slot *slotp = acp->slotp;
+	ddi_acc_handle_t acc = slotp->fib_acc_handle;
+	struct aac_Container_resp *resp;
+	uint32_t status;
+
+	ASSERT(!(acp->flags & AAC_CMD_SYNC));
+
+	acp->pkt->pkt_state |= STATE_GOT_STATUS;
+
+	resp = (struct aac_Container_resp *)&slotp->fibp->data[0];
+	status = ddi_get32(acc, &resp->Status);
+	if (status != 0) {
+		AACDB_PRINT(softs, CE_WARN, "Cannot start/stop a unit");
+		aac_set_arq_data_hwerr(acp);
+	}
+}
+
 /*
  * Access PCI space to see if the driver can support the card
  */
@@ -2451,7 +2472,15 @@
 		    MFG_PCBA_SERIAL_NUMBER_WIDTH);
 		AAC_REP_GET_FIELD8(acc, sinfr, sinfp, MfgWWNName[0],
 		    MFG_WWN_WIDTH);
-		AAC_REP_GET_FIELD32(acc, sinfr, sinfp, ReservedGrowth[0], 2);
+		AAC_GET_FIELD32(acc, sinfr, sinfp, SupportedOptions2);
+		AAC_GET_FIELD32(acc, sinfr, sinfp, ExpansionFlag);
+		if (sinfr->ExpansionFlag == 1) {
+			AAC_GET_FIELD32(acc, sinfr, sinfp, FeatureBits3);
+			AAC_GET_FIELD32(acc, sinfr, sinfp,
+			    SupportedPerformanceMode);
+			AAC_REP_GET_FIELD32(acc, sinfr, sinfp,
+			    ReservedGrowth[0], 80);
+		}
 	}
 	return (AACOK);
 }
@@ -2699,6 +2728,9 @@
 		if (aac_get_adapter_info(softs, NULL, &sinf) != AACOK) {
 			cmn_err(CE_CONT, "?Query adapter information failed");
 		} else {
+			softs->feature_bits = sinf.FeatureBits;
+			softs->support_opt2 = sinf.SupportedOptions2;
+
 			char *p, *p0, *p1;
 
 			/*
@@ -3448,11 +3480,17 @@
 
 	/* Setup new/old comm. specific data */
 	if (softs->flags & AAC_FLAGS_RAW_IO) {
+		uint32_t init_flags = 0;
+
+		if (softs->flags & AAC_FLAGS_NEW_COMM)
+			init_flags |= AAC_INIT_FLAGS_NEW_COMM_SUPPORTED;
+		/* AAC_SUPPORTED_POWER_MANAGEMENT */
+		init_flags |= AAC_INIT_FLAGS_DRIVER_SUPPORTS_PM;
+		init_flags |= AAC_INIT_FLAGS_DRIVER_USES_UTC_TIME;
+
 		ddi_put32(acc, &initp->InitStructRevision,
 		    AAC_INIT_STRUCT_REVISION_4);
-		ddi_put32(acc, &initp->InitFlags,
-		    (softs->flags & AAC_FLAGS_NEW_COMM) ?
-		    AAC_INIT_FLAGS_NEW_COMM_SUPPORTED : 0);
+		ddi_put32(acc, &initp->InitFlags, init_flags);
 		/* Setup the preferred settings */
 		ddi_put32(acc, &initp->MaxIoCommands, softs->aac_max_fibs);
 		ddi_put32(acc, &initp->MaxIoSize,
@@ -4640,10 +4678,17 @@
 		break;
 	}
 
+	case SCMD_START_STOP:
+		if (softs->support_opt2 & AAC_SUPPORTED_POWER_MANAGEMENT) {
+			acp->aac_cmd_fib = aac_cmd_fib_startstop;
+			acp->ac_comp = aac_startstop_complete;
+			rval = aac_do_io(softs, acp);
+			break;
+		}
+	/* FALLTHRU */
 	case SCMD_TEST_UNIT_READY:
 	case SCMD_REQUEST_SENSE:
 	case SCMD_FORMAT:
-	case SCMD_START_STOP:
 		aac_free_dmamap(acp);
 		if (bp && bp->b_un.b_addr && bp->b_bcount) {
 			if (acp->flags & AAC_CMD_BUF_READ) {
@@ -5484,6 +5529,31 @@
 }
 
 /*
+ * Start/Stop unit (Power Management)
+ */
+static void
+aac_cmd_fib_startstop(struct aac_softstate *softs, struct aac_cmd *acp)
+{
+	struct aac_slot *slotp = acp->slotp;
+	ddi_acc_handle_t acc = slotp->fib_acc_handle;
+	struct aac_Container *cmd =
+	    (struct aac_Container *)&slotp->fibp->data[0];
+	union scsi_cdb *cdbp = (void *)acp->pkt->pkt_cdbp;
+
+	acp->fib_size = AAC_FIB_SIZEOF(struct aac_Container);
+
+	aac_cmd_fib_header(softs, slotp, ContainerCommand, acp->fib_size);
+	bzero(cmd, sizeof (*cmd) - CT_PACKET_SIZE);
+	ddi_put32(acc, &cmd->Command, VM_ContainerConfig);
+	ddi_put32(acc, &cmd->CTCommand.command, CT_PM_DRIVER_SUPPORT);
+	ddi_put32(acc, &cmd->CTCommand.param[0], cdbp->cdb_opaque[4] & 1 ? \
+	    AAC_PM_DRIVERSUP_START_UNIT : AAC_PM_DRIVERSUP_STOP_UNIT);
+	ddi_put32(acc, &cmd->CTCommand.param[1],
+	    ((struct aac_container *)acp->dvp)->cid);
+	ddi_put32(acc, &cmd->CTCommand.param[2], cdbp->cdb_opaque[1] & 1);
+}
+
+/*
  * Init FIB for pass-through SCMD
  */
 static void
--- a/usr/src/uts/common/io/aac/aac.h	Fri Nov 06 11:19:08 2009 +0800
+++ b/usr/src/uts/common/io/aac/aac.h	Fri Nov 06 11:27:47 2009 +0800
@@ -55,7 +55,7 @@
 
 #define	AAC_DRIVER_MAJOR_VERSION	2
 #define	AAC_DRIVER_MINOR_VERSION	2
-#define	AAC_DRIVER_BUGFIX_LEVEL		6
+#define	AAC_DRIVER_BUGFIX_LEVEL		7
 #define	AAC_DRIVER_TYPE			AAC_TYPE_RELEASE
 
 #define	STR(s)				# s
@@ -276,6 +276,8 @@
 	char vendor_name[AAC_VENDOR_LEN + 1];
 	char product_name[AAC_PRODUCT_LEN + 1];
 	uint32_t support_opt;	/* firmware features */
+	uint32_t support_opt2;
+	uint32_t feature_bits;
 	uint32_t atu_size;	/* actual size of PCI mem space */
 	uint32_t map_size;	/* mapped PCI mem space size */
 	uint32_t map_size_min;	/* minimum size of PCI mem that must be */
--- a/usr/src/uts/common/io/aac/aac_regs.h	Fri Nov 06 11:19:08 2009 +0800
+++ b/usr/src/uts/common/io/aac/aac_regs.h	Fri Nov 06 11:27:47 2009 +0800
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -139,6 +139,14 @@
 #define	AAC_SUPPORTED_64BIT_ARRAYSIZE		0x40000
 #define	AAC_SUPPORTED_HEAT_SENSOR		0x80000
 
+/*
+ * More options from supplement info - SupportedOptions2
+ */
+#define	AAC_SUPPORTED_MU_RESET			0x01
+#define	AAC_SUPPORTED_IGNORE_RESET		0x02
+#define	AAC_SUPPORTED_POWER_MANAGEMENT		0x04
+#define	AAC_SUPPORTED_ARCIO_PHYDEV		0x08
+
 #pragma	pack(1)
 
 /*
@@ -331,8 +339,12 @@
 	uint8_t		MfgPcbaSerialNo[MFG_PCBA_SERIAL_NUMBER_WIDTH];
 	/* WWN from the MFG sector */
 	uint8_t		MfgWWNName[MFG_WWN_WIDTH];
-	/* Growth Area for future expansion ((7*4) - 12 - 8)/4 = 2 words */
-	uint32_t	ReservedGrowth[2];
+	uint32_t	SupportedOptions2;	/* more supported features */
+	uint32_t	ExpansionFlag;	/* 1 - following fields are valid */
+	uint32_t	FeatureBits3;
+	uint32_t	SupportedPerformanceMode;
+	/* Growth Area for future expansion */
+	uint32_t	ReservedGrowth[80];
 };
 
 /* Container creation data */
@@ -674,6 +686,8 @@
 	/* 210 added to support firmware cache sync operations */
 	CT_GET_CACHE_SYNC_INFO,
 	CT_SET_CACHE_SYNC_MODE,		/* 211 */
+	CT_PM_DRIVER_SUPPORT,		/* 212 */
+	CT_PM_CONFIGURATION,		/* 213 */
 
 	CT_LAST_COMMAND			/* last command */
 } AAC_CTCommand;
@@ -681,6 +695,13 @@
 /* General return status */
 #define	CT_OK				218
 
+/* CT_PM_DRIVER_SUPPORT parameter */
+typedef enum {
+	AAC_PM_DRIVERSUP_GET_STATUS = 1,
+	AAC_PM_DRIVERSUP_START_UNIT,
+	AAC_PM_DRIVERSUP_STOP_UNIT
+} AAC_CT_PM_DRIVER_SUPPORT_SUB_COM;
+
 struct aac_fsa_ctm {
 	uint32_t	command;
 	uint32_t	param[CT_FIB_PARAMS];
@@ -993,7 +1014,11 @@
 #define	AAC_INIT_STRUCT_REVISION		3
 #define	AAC_INIT_STRUCT_REVISION_4		4
 #define	AAC_INIT_STRUCT_MINIPORT_REVISION	1
+
 #define	AAC_INIT_FLAGS_NEW_COMM_SUPPORTED	1
+#define	AAC_INIT_FLAGS_DRIVER_USES_UTC_TIME	0x10
+#define	AAC_INIT_FLAGS_DRIVER_SUPPORTS_PM	0x20
+
 #define	AAC_PAGE_SIZE				4096
 struct aac_adapter_init {
 	uint32_t	InitStructRevision;