diff options
Diffstat (limited to 'drivers/scsi/hisi_sas/hisi_sas_main.c')
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_main.c | 21 |
1 files changed, 12 insertions, 9 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) |