aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid
diff options
context:
space:
mode:
authorSumant Patro <sumantp@lsil.com>2006-10-03 15:28:49 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-10-04 13:45:19 -0400
commite3bbff9f3cf91c84c76cfdd5e80041ad1b487192 (patch)
tree62875328d2ffd90bffc9999c81aa356218d7da12 /drivers/scsi/megaraid
parent65935ff95cfda67c7b2bf228d6f7083a46f832a1 (diff)
[SCSI] megaraid_sas: FW transition and q size changes
This patch has the following enhancements : a. handles new transition states of FW to support controller hotplug. b. It reduces by 1 the maximum cmds that the driver may send to FW. c. Sends "Stop Processing" cmd to FW before returning failure from reset routine d. Adds print in megasas_transition routine e. Sends "RESET" flag to FW to do a soft reset of controller to move from Operational to Ready state. f. Sending correct pointer (cmd->sense) to pci_pool_free Signed-off-by: Sumant Patro <Sumant.Patro@lsil.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/megaraid')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c35
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h11
2 files changed, 38 insertions, 8 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 4cab5b534b25..38733b6009a4 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -832,6 +832,12 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
832 } 832 }
833 833
834 if (atomic_read(&instance->fw_outstanding)) { 834 if (atomic_read(&instance->fw_outstanding)) {
835 /*
836 * Send signal to FW to stop processing any pending cmds.
837 * The controller will be taken offline by the OS now.
838 */
839 writel(MFI_STOP_ADP,
840 &instance->reg_set->inbound_doorbell);
835 instance->hw_crit_error = 1; 841 instance->hw_crit_error = 1;
836 return FAILED; 842 return FAILED;
837 } 843 }
@@ -1229,10 +1235,12 @@ megasas_transition_to_ready(struct megasas_instance* instance)
1229 1235
1230 fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK; 1236 fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
1231 1237
1238 if (fw_state != MFI_STATE_READY)
1239 printk(KERN_INFO "megasas: Waiting for FW to come to ready"
1240 " state\n");
1241
1232 while (fw_state != MFI_STATE_READY) { 1242 while (fw_state != MFI_STATE_READY) {
1233 1243
1234 printk(KERN_INFO "megasas: Waiting for FW to come to ready"
1235 " state\n");
1236 switch (fw_state) { 1244 switch (fw_state) {
1237 1245
1238 case MFI_STATE_FAULT: 1246 case MFI_STATE_FAULT:
@@ -1244,19 +1252,27 @@ megasas_transition_to_ready(struct megasas_instance* instance)
1244 /* 1252 /*
1245 * Set the CLR bit in inbound doorbell 1253 * Set the CLR bit in inbound doorbell
1246 */ 1254 */
1247 writel(MFI_INIT_CLEAR_HANDSHAKE, 1255 writel(MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
1248 &instance->reg_set->inbound_doorbell); 1256 &instance->reg_set->inbound_doorbell);
1249 1257
1250 max_wait = 2; 1258 max_wait = 2;
1251 cur_state = MFI_STATE_WAIT_HANDSHAKE; 1259 cur_state = MFI_STATE_WAIT_HANDSHAKE;
1252 break; 1260 break;
1253 1261
1262 case MFI_STATE_BOOT_MESSAGE_PENDING:
1263 writel(MFI_INIT_HOTPLUG,
1264 &instance->reg_set->inbound_doorbell);
1265
1266 max_wait = 10;
1267 cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
1268 break;
1269
1254 case MFI_STATE_OPERATIONAL: 1270 case MFI_STATE_OPERATIONAL:
1255 /* 1271 /*
1256 * Bring it to READY state; assuming max wait 2 secs 1272 * Bring it to READY state; assuming max wait 10 secs
1257 */ 1273 */
1258 megasas_disable_intr(instance); 1274 megasas_disable_intr(instance);
1259 writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell); 1275 writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell);
1260 1276
1261 max_wait = 10; 1277 max_wait = 10;
1262 cur_state = MFI_STATE_OPERATIONAL; 1278 cur_state = MFI_STATE_OPERATIONAL;
@@ -1323,6 +1339,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
1323 return -ENODEV; 1339 return -ENODEV;
1324 } 1340 }
1325 }; 1341 };
1342 printk(KERN_INFO "megasas: FW now in Ready state\n");
1326 1343
1327 return 0; 1344 return 0;
1328} 1345}
@@ -1352,7 +1369,7 @@ static void megasas_teardown_frame_pool(struct megasas_instance *instance)
1352 cmd->frame_phys_addr); 1369 cmd->frame_phys_addr);
1353 1370
1354 if (cmd->sense) 1371 if (cmd->sense)
1355 pci_pool_free(instance->sense_dma_pool, cmd->frame, 1372 pci_pool_free(instance->sense_dma_pool, cmd->sense,
1356 cmd->sense_phys_addr); 1373 cmd->sense_phys_addr);
1357 } 1374 }
1358 1375
@@ -1690,6 +1707,12 @@ static int megasas_init_mfi(struct megasas_instance *instance)
1690 * Get various operational parameters from status register 1707 * Get various operational parameters from status register
1691 */ 1708 */
1692 instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF; 1709 instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
1710 /*
1711 * Reduce the max supported cmds by 1. This is to ensure that the
1712 * reply_q_sz (1 more than the max cmd that driver may send)
1713 * does not exceed max cmds that the FW can support
1714 */
1715 instance->max_fw_cmds = instance->max_fw_cmds-1;
1693 instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >> 1716 instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >>
1694 0x10; 1717 0x10;
1695 /* 1718 /*
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 3531a14222a7..930c06d0a4f7 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -50,6 +50,7 @@
50#define MFI_STATE_WAIT_HANDSHAKE 0x60000000 50#define MFI_STATE_WAIT_HANDSHAKE 0x60000000
51#define MFI_STATE_FW_INIT_2 0x70000000 51#define MFI_STATE_FW_INIT_2 0x70000000
52#define MFI_STATE_DEVICE_SCAN 0x80000000 52#define MFI_STATE_DEVICE_SCAN 0x80000000
53#define MFI_STATE_BOOT_MESSAGE_PENDING 0x90000000
53#define MFI_STATE_FLUSH_CACHE 0xA0000000 54#define MFI_STATE_FLUSH_CACHE 0xA0000000
54#define MFI_STATE_READY 0xB0000000 55#define MFI_STATE_READY 0xB0000000
55#define MFI_STATE_OPERATIONAL 0xC0000000 56#define MFI_STATE_OPERATIONAL 0xC0000000
@@ -64,12 +65,18 @@
64 * READY : Move from OPERATIONAL to READY state; discard queue info 65 * READY : Move from OPERATIONAL to READY state; discard queue info
65 * MFIMODE : Discard (possible) low MFA posted in 64-bit mode (??) 66 * MFIMODE : Discard (possible) low MFA posted in 64-bit mode (??)
66 * CLR_HANDSHAKE: FW is waiting for HANDSHAKE from BIOS or Driver 67 * CLR_HANDSHAKE: FW is waiting for HANDSHAKE from BIOS or Driver
68 * HOTPLUG : Resume from Hotplug
69 * MFI_STOP_ADP : Send signal to FW to stop processing
67 */ 70 */
68#define MFI_INIT_ABORT 0x00000000 71#define MFI_INIT_ABORT 0x00000001
69#define MFI_INIT_READY 0x00000002 72#define MFI_INIT_READY 0x00000002
70#define MFI_INIT_MFIMODE 0x00000004 73#define MFI_INIT_MFIMODE 0x00000004
71#define MFI_INIT_CLEAR_HANDSHAKE 0x00000008 74#define MFI_INIT_CLEAR_HANDSHAKE 0x00000008
72#define MFI_RESET_FLAGS MFI_INIT_READY|MFI_INIT_MFIMODE 75#define MFI_INIT_HOTPLUG 0x00000010
76#define MFI_STOP_ADP 0x00000020
77#define MFI_RESET_FLAGS MFI_INIT_READY| \
78 MFI_INIT_MFIMODE| \
79 MFI_INIT_ABORT
73 80
74/** 81/**
75 * MFI frame flags 82 * MFI frame flags