diff options
author | Salyzyn, Mark <Mark_Salyzyn@adaptec.com> | 2008-01-08 15:01:07 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-23 12:29:18 -0500 |
commit | 95e852e1ef165560e85d3012127068c8f08b19a1 (patch) | |
tree | 42963d0880b10f34c888ad55890b679ad8a5ccc2 | |
parent | 9b161a4d3e83518323ce13822e55de70c630aa65 (diff) |
[SCSI] aacraid: add parameter to control FUA and SYNCHRONIZE_CACHE policy
aacraid.cache parameter, Disable Queue Flush commands:
bit 0 - Disable FUA in WRITE SCSI commands
bit 1 - Disable SYNCHRONIZE_CACHE SCSI command
bit 2 - Disable only if Battery not protecting adapter supplied Cache
e.g.: aacraid.cache=7 will disable the FUA and SYNCHRONIZE_CACHE
commands if the adapter has reported that it's cache is battery backed
up.
This parameter permits experimentation with tradeoffs between
performance and caching policy.
Signed-off-by: Mark Salyzyn <aacraid@adaptec.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r-- | drivers/scsi/aacraid/aachba.c | 36 | ||||
-rw-r--r-- | drivers/scsi/aacraid/aacraid.h | 2 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 4 |
3 files changed, 30 insertions, 12 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index cef764eba307..43d6aff460d2 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -144,6 +144,7 @@ static char *aac_get_status_string(u32 status); | |||
144 | */ | 144 | */ |
145 | 145 | ||
146 | static int nondasd = -1; | 146 | static int nondasd = -1; |
147 | static int aac_cache = 0; | ||
147 | static int dacmode = -1; | 148 | static int dacmode = -1; |
148 | 149 | ||
149 | int aac_commit = -1; | 150 | int aac_commit = -1; |
@@ -152,6 +153,8 @@ int aif_timeout = 120; | |||
152 | 153 | ||
153 | module_param(nondasd, int, S_IRUGO|S_IWUSR); | 154 | module_param(nondasd, int, S_IRUGO|S_IWUSR); |
154 | MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on"); | 155 | MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on"); |
156 | module_param_named(cache, aac_cache, int, S_IRUGO|S_IWUSR); | ||
157 | MODULE_PARM_DESC(cache, "Disable Queue Flush commands:\n\tbit 0 - Disable FUA in WRITE SCSI commands\n\tbit 1 - Disable SYNCHRONIZE_CACHE SCSI command\n\tbit 2 - Disable only if Battery not protecting Cache"); | ||
155 | module_param(dacmode, int, S_IRUGO|S_IWUSR); | 158 | module_param(dacmode, int, S_IRUGO|S_IWUSR); |
156 | MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on"); | 159 | MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on"); |
157 | module_param_named(commit, aac_commit, int, S_IRUGO|S_IWUSR); | 160 | module_param_named(commit, aac_commit, int, S_IRUGO|S_IWUSR); |
@@ -1013,7 +1016,8 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u | |||
1013 | writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); | 1016 | writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); |
1014 | writecmd->count = cpu_to_le32(count<<9); | 1017 | writecmd->count = cpu_to_le32(count<<9); |
1015 | writecmd->cid = cpu_to_le16(scmd_id(cmd)); | 1018 | writecmd->cid = cpu_to_le16(scmd_id(cmd)); |
1016 | writecmd->flags = fua ? | 1019 | writecmd->flags = (fua && ((aac_cache & 5) != 1) && |
1020 | (((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ? | ||
1017 | cpu_to_le16(IO_TYPE_WRITE|IO_SUREWRITE) : | 1021 | cpu_to_le16(IO_TYPE_WRITE|IO_SUREWRITE) : |
1018 | cpu_to_le16(IO_TYPE_WRITE); | 1022 | cpu_to_le16(IO_TYPE_WRITE); |
1019 | writecmd->bpTotal = 0; | 1023 | writecmd->bpTotal = 0; |
@@ -1325,11 +1329,11 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
1325 | } | 1329 | } |
1326 | } | 1330 | } |
1327 | 1331 | ||
1332 | dev->cache_protected = 0; | ||
1328 | dev->nondasd_support = 0; | 1333 | dev->nondasd_support = 0; |
1329 | dev->raid_scsi_mode = 0; | 1334 | dev->raid_scsi_mode = 0; |
1330 | if(dev->adapter_info.options & AAC_OPT_NONDASD){ | 1335 | if(dev->adapter_info.options & AAC_OPT_NONDASD) |
1331 | dev->nondasd_support = 1; | 1336 | dev->nondasd_support = 1; |
1332 | } | ||
1333 | 1337 | ||
1334 | /* | 1338 | /* |
1335 | * If the firmware supports ROMB RAID/SCSI mode and we are currently | 1339 | * If the firmware supports ROMB RAID/SCSI mode and we are currently |
@@ -1351,10 +1355,9 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
1351 | printk(KERN_INFO "%s%d: ROMB RAID/SCSI mode enabled\n", | 1355 | printk(KERN_INFO "%s%d: ROMB RAID/SCSI mode enabled\n", |
1352 | dev->name, dev->id); | 1356 | dev->name, dev->id); |
1353 | 1357 | ||
1354 | if(nondasd != -1) { | 1358 | if (nondasd != -1) |
1355 | dev->nondasd_support = (nondasd!=0); | 1359 | dev->nondasd_support = (nondasd!=0); |
1356 | } | 1360 | if(dev->nondasd_support != 0) { |
1357 | if(dev->nondasd_support != 0){ | ||
1358 | printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id); | 1361 | printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id); |
1359 | } | 1362 | } |
1360 | 1363 | ||
@@ -2106,7 +2109,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2106 | mode_buf[2] = 0; /* Device-specific param, | 2109 | mode_buf[2] = 0; /* Device-specific param, |
2107 | bit 8: 0/1 = write enabled/protected | 2110 | bit 8: 0/1 = write enabled/protected |
2108 | bit 4: 0/1 = FUA enabled */ | 2111 | bit 4: 0/1 = FUA enabled */ |
2109 | if (dev->raw_io_interface) | 2112 | if (dev->raw_io_interface && ((aac_cache & 5) != 1)) |
2110 | mode_buf[2] = 0x10; | 2113 | mode_buf[2] = 0x10; |
2111 | mode_buf[3] = 0; /* Block descriptor length */ | 2114 | mode_buf[3] = 0; /* Block descriptor length */ |
2112 | if (((scsicmd->cmnd[2] & 0x3f) == 8) || | 2115 | if (((scsicmd->cmnd[2] & 0x3f) == 8) || |
@@ -2114,7 +2117,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2114 | mode_buf[0] = 6; | 2117 | mode_buf[0] = 6; |
2115 | mode_buf[4] = 8; | 2118 | mode_buf[4] = 8; |
2116 | mode_buf[5] = 1; | 2119 | mode_buf[5] = 1; |
2117 | mode_buf[6] = 0x04; /* WCE */ | 2120 | mode_buf[6] = ((aac_cache & 6) == 2) |
2121 | ? 0 : 0x04; /* WCE */ | ||
2118 | mode_buf_length = 7; | 2122 | mode_buf_length = 7; |
2119 | if (mode_buf_length > scsicmd->cmnd[4]) | 2123 | if (mode_buf_length > scsicmd->cmnd[4]) |
2120 | mode_buf_length = scsicmd->cmnd[4]; | 2124 | mode_buf_length = scsicmd->cmnd[4]; |
@@ -2137,7 +2141,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2137 | mode_buf[3] = 0; /* Device-specific param, | 2141 | mode_buf[3] = 0; /* Device-specific param, |
2138 | bit 8: 0/1 = write enabled/protected | 2142 | bit 8: 0/1 = write enabled/protected |
2139 | bit 4: 0/1 = FUA enabled */ | 2143 | bit 4: 0/1 = FUA enabled */ |
2140 | if (dev->raw_io_interface) | 2144 | if (dev->raw_io_interface && ((aac_cache & 5) != 1)) |
2141 | mode_buf[3] = 0x10; | 2145 | mode_buf[3] = 0x10; |
2142 | mode_buf[4] = 0; /* reserved */ | 2146 | mode_buf[4] = 0; /* reserved */ |
2143 | mode_buf[5] = 0; /* reserved */ | 2147 | mode_buf[5] = 0; /* reserved */ |
@@ -2148,7 +2152,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2148 | mode_buf[1] = 9; | 2152 | mode_buf[1] = 9; |
2149 | mode_buf[8] = 8; | 2153 | mode_buf[8] = 8; |
2150 | mode_buf[9] = 1; | 2154 | mode_buf[9] = 1; |
2151 | mode_buf[10] = 0x04; /* WCE */ | 2155 | mode_buf[10] = ((aac_cache & 6) == 2) |
2156 | ? 0 : 0x04; /* WCE */ | ||
2152 | mode_buf_length = 11; | 2157 | mode_buf_length = 11; |
2153 | if (mode_buf_length > scsicmd->cmnd[8]) | 2158 | if (mode_buf_length > scsicmd->cmnd[8]) |
2154 | mode_buf_length = scsicmd->cmnd[8]; | 2159 | mode_buf_length = scsicmd->cmnd[8]; |
@@ -2224,9 +2229,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2224 | return aac_write(scsicmd); | 2229 | return aac_write(scsicmd); |
2225 | 2230 | ||
2226 | case SYNCHRONIZE_CACHE: | 2231 | case SYNCHRONIZE_CACHE: |
2232 | if (((aac_cache & 6) == 6) && dev->cache_protected) { | ||
2233 | scsicmd->result = DID_OK << 16 | | ||
2234 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | ||
2235 | scsicmd->scsi_done(scsicmd); | ||
2236 | return 0; | ||
2237 | } | ||
2227 | /* Issue FIB to tell Firmware to flush it's cache */ | 2238 | /* Issue FIB to tell Firmware to flush it's cache */ |
2228 | return aac_synchronize(scsicmd); | 2239 | if ((aac_cache & 6) != 2) |
2229 | 2240 | return aac_synchronize(scsicmd); | |
2241 | /* FALLTHRU */ | ||
2230 | default: | 2242 | default: |
2231 | /* | 2243 | /* |
2232 | * Unhandled commands | 2244 | * Unhandled commands |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 734623af9c45..7bb3d9fde713 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -1016,6 +1016,7 @@ struct aac_dev | |||
1016 | * lets break them out so we don't have to do an AND to check them | 1016 | * lets break them out so we don't have to do an AND to check them |
1017 | */ | 1017 | */ |
1018 | u8 nondasd_support; | 1018 | u8 nondasd_support; |
1019 | u8 cache_protected; | ||
1019 | u8 dac_support; | 1020 | u8 dac_support; |
1020 | u8 raid_scsi_mode; | 1021 | u8 raid_scsi_mode; |
1021 | u8 comm_interface; | 1022 | u8 comm_interface; |
@@ -1770,6 +1771,7 @@ extern struct aac_common aac_config; | |||
1770 | #define AifEnConfigChange 3 /* Adapter configuration change */ | 1771 | #define AifEnConfigChange 3 /* Adapter configuration change */ |
1771 | #define AifEnContainerChange 4 /* Container configuration change */ | 1772 | #define AifEnContainerChange 4 /* Container configuration change */ |
1772 | #define AifEnDeviceFailure 5 /* SCSI device failed */ | 1773 | #define AifEnDeviceFailure 5 /* SCSI device failed */ |
1774 | #define AifEnBatteryEvent 14 /* Change in Battery State */ | ||
1773 | #define AifEnAddContainer 15 /* A new array was created */ | 1775 | #define AifEnAddContainer 15 /* A new array was created */ |
1774 | #define AifEnDeleteContainer 16 /* A container was deleted */ | 1776 | #define AifEnDeleteContainer 16 /* A container was deleted */ |
1775 | #define AifEnExpEvent 23 /* Firmware Event Log */ | 1777 | #define AifEnExpEvent 23 /* Firmware Event Log */ |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 53d415e812ee..81cdac166d4b 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -849,6 +849,10 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) | |||
849 | 849 | ||
850 | case AifCmdEventNotify: | 850 | case AifCmdEventNotify: |
851 | switch (le32_to_cpu(((__le32 *)aifcmd->data)[0])) { | 851 | switch (le32_to_cpu(((__le32 *)aifcmd->data)[0])) { |
852 | case AifEnBatteryEvent: | ||
853 | dev->cache_protected = | ||
854 | (((__le32 *)aifcmd->data)[1] == cpu_to_le32(3)); | ||
855 | break; | ||
852 | /* | 856 | /* |
853 | * Add an Array. | 857 | * Add an Array. |
854 | */ | 858 | */ |