aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorSumit.Saxena@lsi.com <Sumit.Saxena@lsi.com>2014-02-12 13:06:15 -0500
committerJames Bottomley <JBottomley@Parallels.com>2014-03-15 13:19:20 -0400
commitcfbe7554f6ebdf8034604d3cc90afd60cbb2195e (patch)
tree5b9be0fbd6830d22def10a2ee7cd46f5e9df6e6d /drivers/scsi
parente2c70425f05219b142b3a8a9489a622c736db39d (diff)
[SCSI] megaraid_sas: Don't wait forever for non-IOCTL DCMDs
Don't wait forever for firmware response for internal DCMDs sent from driver firmware. Such DCMDs will be posted to firmware with timeout. Timeout is also introduced for DCMD sent to abort the commands. DCMD sent via IOCTL path will still be always blocking to keep the IOCTL design intact. Signed-off-by: Sumit Saxena <sumit.saxena@lsi.com> Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c79
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c1
2 files changed, 55 insertions, 25 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index f21e48b2e956..3cf97a388e4a 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -898,6 +898,7 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
898 * megasas_issue_blocked_cmd - Synchronous wrapper around regular FW cmds 898 * megasas_issue_blocked_cmd - Synchronous wrapper around regular FW cmds
899 * @instance: Adapter soft state 899 * @instance: Adapter soft state
900 * @cmd: Command to be issued 900 * @cmd: Command to be issued
901 * @timeout: Timeout in seconds
901 * 902 *
902 * This function waits on an event for the command to be returned from ISR. 903 * This function waits on an event for the command to be returned from ISR.
903 * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs 904 * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
@@ -905,13 +906,20 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
905 */ 906 */
906static int 907static int
907megasas_issue_blocked_cmd(struct megasas_instance *instance, 908megasas_issue_blocked_cmd(struct megasas_instance *instance,
908 struct megasas_cmd *cmd) 909 struct megasas_cmd *cmd, int timeout)
909{ 910{
911 int ret = 0;
910 cmd->cmd_status = ENODATA; 912 cmd->cmd_status = ENODATA;
911 913
912 instance->instancet->issue_dcmd(instance, cmd); 914 instance->instancet->issue_dcmd(instance, cmd);
913 915 if (timeout) {
914 wait_event(instance->int_cmd_wait_q, cmd->cmd_status != ENODATA); 916 ret = wait_event_timeout(instance->int_cmd_wait_q,
917 cmd->cmd_status != ENODATA, timeout * HZ);
918 if (!ret)
919 return 1;
920 } else
921 wait_event(instance->int_cmd_wait_q,
922 cmd->cmd_status != ENODATA);
915 923
916 return 0; 924 return 0;
917} 925}
@@ -920,18 +928,20 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance,
920 * megasas_issue_blocked_abort_cmd - Aborts previously issued cmd 928 * megasas_issue_blocked_abort_cmd - Aborts previously issued cmd
921 * @instance: Adapter soft state 929 * @instance: Adapter soft state
922 * @cmd_to_abort: Previously issued cmd to be aborted 930 * @cmd_to_abort: Previously issued cmd to be aborted
931 * @timeout: Timeout in seconds
923 * 932 *
924 * MFI firmware can abort previously issued AEN command (automatic event 933 * MFI firmware can abort previously issued AEN comamnd (automatic event
925 * notification). The megasas_issue_blocked_abort_cmd() issues such abort 934 * notification). The megasas_issue_blocked_abort_cmd() issues such abort
926 * cmd and waits for return status. 935 * cmd and waits for return status.
927 * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs 936 * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
928 */ 937 */
929static int 938static int
930megasas_issue_blocked_abort_cmd(struct megasas_instance *instance, 939megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
931 struct megasas_cmd *cmd_to_abort) 940 struct megasas_cmd *cmd_to_abort, int timeout)
932{ 941{
933 struct megasas_cmd *cmd; 942 struct megasas_cmd *cmd;
934 struct megasas_abort_frame *abort_fr; 943 struct megasas_abort_frame *abort_fr;
944 int ret = 0;
935 945
936 cmd = megasas_get_cmd(instance); 946 cmd = megasas_get_cmd(instance);
937 947
@@ -957,10 +967,18 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
957 967
958 instance->instancet->issue_dcmd(instance, cmd); 968 instance->instancet->issue_dcmd(instance, cmd);
959 969
960 /* 970 if (timeout) {
961 * Wait for this cmd to complete 971 ret = wait_event_timeout(instance->abort_cmd_wait_q,
962 */ 972 cmd->cmd_status != ENODATA, timeout * HZ);
963 wait_event(instance->abort_cmd_wait_q, cmd->cmd_status != 0xFF); 973 if (!ret) {
974 dev_err(&instance->pdev->dev, "Command timedout"
975 "from %s\n", __func__);
976 return 1;
977 }
978 } else
979 wait_event(instance->abort_cmd_wait_q,
980 cmd->cmd_status != ENODATA);
981
964 cmd->sync_cmd = 0; 982 cmd->sync_cmd = 0;
965 983
966 megasas_return_cmd(instance, cmd); 984 megasas_return_cmd(instance, cmd);
@@ -3936,16 +3954,19 @@ megasas_get_seq_num(struct megasas_instance *instance,
3936 dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(el_info_h); 3954 dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(el_info_h);
3937 dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_evt_log_info)); 3955 dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_evt_log_info));
3938 3956
3939 megasas_issue_blocked_cmd(instance, cmd); 3957 if (megasas_issue_blocked_cmd(instance, cmd, 30))
3940 3958 dev_err(&instance->pdev->dev, "Command timedout"
3941 /* 3959 "from %s\n", __func__);
3942 * Copy the data back into callers buffer 3960 else {
3943 */ 3961 /*
3944 eli->newest_seq_num = le32_to_cpu(el_info->newest_seq_num); 3962 * Copy the data back into callers buffer
3945 eli->oldest_seq_num = le32_to_cpu(el_info->oldest_seq_num); 3963 */
3946 eli->clear_seq_num = le32_to_cpu(el_info->clear_seq_num); 3964 eli->newest_seq_num = le32_to_cpu(el_info->newest_seq_num);
3947 eli->shutdown_seq_num = le32_to_cpu(el_info->shutdown_seq_num); 3965 eli->oldest_seq_num = le32_to_cpu(el_info->oldest_seq_num);
3948 eli->boot_seq_num = le32_to_cpu(el_info->boot_seq_num); 3966 eli->clear_seq_num = le32_to_cpu(el_info->clear_seq_num);
3967 eli->shutdown_seq_num = le32_to_cpu(el_info->shutdown_seq_num);
3968 eli->boot_seq_num = le32_to_cpu(el_info->boot_seq_num);
3969 }
3949 3970
3950 pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info), 3971 pci_free_consistent(instance->pdev, sizeof(struct megasas_evt_log_info),
3951 el_info, el_info_h); 3972 el_info, el_info_h);
@@ -4021,7 +4042,7 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
4021 instance->aen_cmd->abort_aen = 1; 4042 instance->aen_cmd->abort_aen = 1;
4022 ret_val = megasas_issue_blocked_abort_cmd(instance, 4043 ret_val = megasas_issue_blocked_abort_cmd(instance,
4023 instance-> 4044 instance->
4024 aen_cmd); 4045 aen_cmd, 30);
4025 4046
4026 if (ret_val) { 4047 if (ret_val) {
4027 printk(KERN_DEBUG "megasas: Failed to abort " 4048 printk(KERN_DEBUG "megasas: Failed to abort "
@@ -4525,7 +4546,9 @@ static void megasas_flush_cache(struct megasas_instance *instance)
4525 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_CACHE_FLUSH); 4546 dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_CACHE_FLUSH);
4526 dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE; 4547 dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
4527 4548
4528 megasas_issue_blocked_cmd(instance, cmd); 4549 if (megasas_issue_blocked_cmd(instance, cmd, 30))
4550 dev_err(&instance->pdev->dev, "Command timedout"
4551 " from %s\n", __func__);
4529 4552
4530 megasas_return_cmd(instance, cmd); 4553 megasas_return_cmd(instance, cmd);
4531 4554
@@ -4552,10 +4575,11 @@ static void megasas_shutdown_controller(struct megasas_instance *instance,
4552 return; 4575 return;
4553 4576
4554 if (instance->aen_cmd) 4577 if (instance->aen_cmd)
4555 megasas_issue_blocked_abort_cmd(instance, instance->aen_cmd); 4578 megasas_issue_blocked_abort_cmd(instance,
4579 instance->aen_cmd, 30);
4556 if (instance->map_update_cmd) 4580 if (instance->map_update_cmd)
4557 megasas_issue_blocked_abort_cmd(instance, 4581 megasas_issue_blocked_abort_cmd(instance,
4558 instance->map_update_cmd); 4582 instance->map_update_cmd, 30);
4559 dcmd = &cmd->frame->dcmd; 4583 dcmd = &cmd->frame->dcmd;
4560 4584
4561 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); 4585 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
@@ -4569,7 +4593,9 @@ static void megasas_shutdown_controller(struct megasas_instance *instance,
4569 dcmd->data_xfer_len = 0; 4593 dcmd->data_xfer_len = 0;
4570 dcmd->opcode = cpu_to_le32(opcode); 4594 dcmd->opcode = cpu_to_le32(opcode);
4571 4595
4572 megasas_issue_blocked_cmd(instance, cmd); 4596 if (megasas_issue_blocked_cmd(instance, cmd, 30))
4597 dev_err(&instance->pdev->dev, "Command timedout"
4598 "from %s\n", __func__);
4573 4599
4574 megasas_return_cmd(instance, cmd); 4600 megasas_return_cmd(instance, cmd);
4575 4601
@@ -4796,6 +4822,9 @@ static void megasas_detach_one(struct pci_dev *pdev)
4796 instance->ev = NULL; 4822 instance->ev = NULL;
4797 } 4823 }
4798 4824
4825 /* cancel all wait events */
4826 wake_up_all(&instance->int_cmd_wait_q);
4827
4799 tasklet_kill(&instance->isr_tasklet); 4828 tasklet_kill(&instance->isr_tasklet);
4800 4829
4801 /* 4830 /*
@@ -5048,7 +5077,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
5048 * cmd to the SCSI mid-layer 5077 * cmd to the SCSI mid-layer
5049 */ 5078 */
5050 cmd->sync_cmd = 1; 5079 cmd->sync_cmd = 1;
5051 megasas_issue_blocked_cmd(instance, cmd); 5080 megasas_issue_blocked_cmd(instance, cmd, 0);
5052 cmd->sync_cmd = 0; 5081 cmd->sync_cmd = 0;
5053 5082
5054 /* 5083 /*
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 357c6c65970c..4544c27b6489 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -2472,6 +2472,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost)
2472 printk(KERN_WARNING "megaraid_sas: Reset failed, killing " 2472 printk(KERN_WARNING "megaraid_sas: Reset failed, killing "
2473 "adapter.\n"); 2473 "adapter.\n");
2474 megaraid_sas_kill_hba(instance); 2474 megaraid_sas_kill_hba(instance);
2475 instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
2475 retval = FAILED; 2476 retval = FAILED;
2476 } else { 2477 } else {
2477 clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); 2478 clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);