summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorzhongyan gu - Sun Microsystems - Beijing China <Zhongyan.Gu@Sun.COM>2009-11-06 11:27:47 +0800
committerzhongyan gu - Sun Microsystems - Beijing China <Zhongyan.Gu@Sun.COM>2009-11-06 11:27:47 +0800
commitb40e8a892f9b1015a0a51175e62b4e16280f6d98 (patch)
treeed01b5a2c406b8b0440ab4ecb75dc4f9b7299e4b /usr
parent3fb52c733c5435ce279a4641b57941b1befa5c9f (diff)
downloadillumos-gate-b40e8a892f9b1015a0a51175e62b4e16280f6d98.tar.gz
6862543 aac should support power management commands for logical disk
Diffstat (limited to 'usr')
-rw-r--r--usr/src/uts/common/io/aac/aac.c80
-rw-r--r--usr/src/uts/common/io/aac/aac.h4
-rw-r--r--usr/src/uts/common/io/aac/aac_regs.h31
3 files changed, 106 insertions, 9 deletions
diff --git a/usr/src/uts/common/io/aac/aac.c b/usr/src/uts/common/io/aac/aac.c
index e003c06215..d5c8990679 100644
--- a/usr/src/uts/common/io/aac/aac.c
+++ b/usr/src/uts/common/io/aac/aac.c
@@ -308,6 +308,7 @@ static void aac_cmd_fib_brw(struct aac_softstate *, struct aac_cmd *);
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_synccache_complete(struct aac_softstate *softs, struct aac_cmd *acp)
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 @@ aac_get_adapter_info(struct aac_softstate *softs,
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 @@ aac_common_attach(struct aac_softstate *softs)
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 @@ aac_setup_comm_space(struct aac_softstate *softs)
/* 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 @@ do_io:
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 @@ aac_cmd_fib_sync(struct aac_softstate *softs, struct aac_cmd *acp)
}
/*
+ * 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
diff --git a/usr/src/uts/common/io/aac/aac.h b/usr/src/uts/common/io/aac/aac.h
index 48e30a70bb..0fbe38d7c3 100644
--- a/usr/src/uts/common/io/aac/aac.h
+++ b/usr/src/uts/common/io/aac/aac.h
@@ -55,7 +55,7 @@ extern "C" {
#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 @@ struct aac_softstate {
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 */
diff --git a/usr/src/uts/common/io/aac/aac_regs.h b/usr/src/uts/common/io/aac/aac_regs.h
index c510b16fac..1d6d50a726 100644
--- a/usr/src/uts/common/io/aac/aac_regs.h
+++ b/usr/src/uts/common/io/aac/aac_regs.h
@@ -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 @@ extern "C" {
#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 @@ struct aac_supplement_adapter_info {
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 @@ typedef enum {
/* 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 @@ typedef enum {
/* 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 @@ struct aac_ctcfg_resp {
#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;