# HG changeset patch # User zhongyan gu - Sun Microsystems - Beijing China # Date 1257478067 -28800 # Node ID 03a10dbb75a385a6e08847716b56598fd9b2de73 # Parent 9dd13a7cd2e34f7bd78b59dcd8f65b172314b215 6862543 aac should support power management commands for logical disk diff -r 9dd13a7cd2e3 -r 03a10dbb75a3 usr/src/uts/common/io/aac/aac.c --- 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 diff -r 9dd13a7cd2e3 -r 03a10dbb75a3 usr/src/uts/common/io/aac/aac.h --- 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 */ diff -r 9dd13a7cd2e3 -r 03a10dbb75a3 usr/src/uts/common/io/aac/aac_regs.h --- 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;