From 84b58ff94669a3356be7aa38ff10104918d90ad1 Mon Sep 17 00:00:00 2001 From: Xiaofei Tan Date: Thu, 31 May 2018 20:50:45 +0800 Subject: [PATCH] scsi: hisi_sas: Adjust task reject period during host reset BugLink: https://bugs.launchpad.net/bugs/1777696 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 Signed-off-by: John Garry Signed-off-by: Martin K. Petersen (cherry picked from commit b36d9c963f7eee2b949b900b477f3d7f6f0d7b76 scsi) Signed-off-by: dann frazier Acked-by: Khalid Elmously Acked-by: Kleber Sacilotto de Souza Signed-off-by: Kleber Sacilotto de Souza Signed-off-by: Khalid Elmously --- drivers/scsi/hisi_sas/hisi_sas_main.c | 21 ++++++++++++--------- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 +++- 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 06eff5d28cf2..b5e3ac47aad5 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -535,8 +535,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); @@ -1357,30 +1362,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 78e239f7774f..7ef7b97b894d 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2478,7 +2478,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); -- 2.39.5