diff options
Diffstat (limited to 'drivers/scsi/megaraid/megaraid_sas.c')
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas.c | 35 |
1 files changed, 29 insertions, 6 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 | /* |