summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/hisi_sas
diff options
context:
space:
mode:
authorXiaofei Tan <tanxiaofei@huawei.com>2018-05-31 20:50:45 +0800
committerMartin K. Petersen <martin.petersen@oracle.com>2018-06-19 22:02:25 -0400
commit214e702d4b70b6ca7c8a57ff89e1990a76d12f82 (patch)
treea811e2443634ed12286e9c862da1a80a9482c4fa /drivers/scsi/hisi_sas
parentd2fc401e47529d9ffd2673a5395d56002e31ad98 (diff)
downloadlinux-214e702d4b70b6ca7c8a57ff89e1990a76d12f82.tar.bz2
scsi: hisi_sas: Adjust task reject period during host reset
After soft_reset() for host reset, we should not be allowed to send commands to the HW before the PHYs have come up and the port ids have been refreshed. Prior to this point, any commands cannot be successfully completed. This exclusion is achieved by grabbing the host reset semaphore. Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com> Signed-off-by: John Garry <john.garry@huawei.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/hisi_sas')
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_main.c21
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v3_hw.c4
2 files changed, 15 insertions, 10 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 823386ff940c..090d3e0b1a00 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -536,8 +536,13 @@ static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags,
struct device *dev = hisi_hba->dev;
struct hisi_sas_dq *dq = NULL;
- if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags)))
- return -EINVAL;
+ if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags))) {
+ if (in_softirq())
+ return -EINVAL;
+
+ down(&hisi_hba->sem);
+ up(&hisi_hba->sem);
+ }
/* protect task_prep and start_delivery sequence */
rc = hisi_sas_task_prep(task, &dq, is_tmf, tmf, &pass);
@@ -1383,30 +1388,28 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
up(&hisi_hba->sem);
scsi_unblock_requests(shost);
- goto out;
+ clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags);
+ return rc;
}
- clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
-
/* Init and wait for PHYs to come up and all libsas event finished. */
hisi_hba->hw->phys_init(hisi_hba);
msleep(1000);
hisi_sas_refresh_port_id(hisi_hba);
+ clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
up(&hisi_hba->sem);
if (hisi_hba->reject_stp_links_msk)
hisi_sas_terminate_stp_reject(hisi_hba);
hisi_sas_reset_init_all_devices(hisi_hba);
scsi_unblock_requests(shost);
+ clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags);
state = hisi_hba->hw->get_phys_state(hisi_hba);
hisi_sas_rescan_topology(hisi_hba, old_state, state);
dev_info(dev, "controller reset complete\n");
-out:
- clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags);
-
- return rc;
+ return 0;
}
static int hisi_sas_abort_task(struct sas_task *task)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index 0a126a8285c6..c40fdb8d5c2c 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -2459,7 +2459,9 @@ static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state)
return -ENODEV;
}
- set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags);
+ if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))
+ return -1;
+
scsi_block_requests(shost);
set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
flush_workqueue(hisi_hba->wq);