Commit 214e702d authored by Xiaofei Tan's avatar Xiaofei Tan Committed by Martin K. Petersen

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: default avatarXiaofei Tan <tanxiaofei@huawei.com>
Signed-off-by: default avatarJohn Garry <john.garry@huawei.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent d2fc401e
...@@ -536,8 +536,13 @@ static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags, ...@@ -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 device *dev = hisi_hba->dev;
struct hisi_sas_dq *dq = NULL; struct hisi_sas_dq *dq = NULL;
if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags))) if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags))) {
return -EINVAL; if (in_softirq())
return -EINVAL;
down(&hisi_hba->sem);
up(&hisi_hba->sem);
}
/* protect task_prep and start_delivery sequence */ /* protect task_prep and start_delivery sequence */
rc = hisi_sas_task_prep(task, &dq, is_tmf, tmf, &pass); 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) ...@@ -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); clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
up(&hisi_hba->sem); up(&hisi_hba->sem);
scsi_unblock_requests(shost); 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. */ /* Init and wait for PHYs to come up and all libsas event finished. */
hisi_hba->hw->phys_init(hisi_hba); hisi_hba->hw->phys_init(hisi_hba);
msleep(1000); msleep(1000);
hisi_sas_refresh_port_id(hisi_hba); hisi_sas_refresh_port_id(hisi_hba);
clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
up(&hisi_hba->sem); up(&hisi_hba->sem);
if (hisi_hba->reject_stp_links_msk) if (hisi_hba->reject_stp_links_msk)
hisi_sas_terminate_stp_reject(hisi_hba); hisi_sas_terminate_stp_reject(hisi_hba);
hisi_sas_reset_init_all_devices(hisi_hba); hisi_sas_reset_init_all_devices(hisi_hba);
scsi_unblock_requests(shost); scsi_unblock_requests(shost);
clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags);
state = hisi_hba->hw->get_phys_state(hisi_hba); state = hisi_hba->hw->get_phys_state(hisi_hba);
hisi_sas_rescan_topology(hisi_hba, old_state, state); hisi_sas_rescan_topology(hisi_hba, old_state, state);
dev_info(dev, "controller reset complete\n"); dev_info(dev, "controller reset complete\n");
out: return 0;
clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags);
return rc;
} }
static int hisi_sas_abort_task(struct sas_task *task) static int hisi_sas_abort_task(struct sas_task *task)
......
...@@ -2459,7 +2459,9 @@ static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -2459,7 +2459,9 @@ static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state)
return -ENODEV; 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); scsi_block_requests(shost);
set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
flush_workqueue(hisi_hba->wq); flush_workqueue(hisi_hba->wq);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment