diff options
author | Xiaofei Tan <tanxiaofei@huawei.com> | 2018-07-18 22:14:28 +0800 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-07-19 21:57:39 -0400 |
commit | 4522204ab218a8c1f4d3901276deb0a61e7ac9c0 (patch) | |
tree | 893cbf13ee1cefb86ad3e4451a10e3162c792ceb /drivers/scsi/hisi_sas | |
parent | 25908cac84b2ea18d4609fc237d6135d0037041d (diff) | |
download | talos-op-linux-4522204ab218a8c1f4d3901276deb0a61e7ac9c0.tar.gz talos-op-linux-4522204ab218a8c1f4d3901276deb0a61e7ac9c0.zip |
scsi: hisi_sas: tidy host controller reset function a bit
This patch tidies host controller reset function by putting some code to
two new functions, and exports these two functions out, so that they could
be used by FLR feature to be realised.
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.h | 3 | ||||
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_main.c | 61 |
2 files changed, 42 insertions, 22 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 0ff911531295..6c7d2e201abe 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -320,6 +320,7 @@ struct hisi_hba { const struct hisi_sas_hw *hw; /* Low level hw interface */ unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)]; struct work_struct rst_work; + u32 phy_state; }; /* Generic HW DMA host memory structures */ @@ -480,4 +481,6 @@ extern bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy, enum hisi_sas_phy_event event); extern void hisi_sas_release_tasks(struct hisi_hba *hisi_hba); extern u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max); +extern void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba); +extern void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba); #endif diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index ed671af1f6e8..b0bcd142adc7 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1309,22 +1309,12 @@ static void hisi_sas_terminate_stp_reject(struct hisi_hba *hisi_hba) } } -static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) +void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba) { - struct device *dev = hisi_hba->dev; struct Scsi_Host *shost = hisi_hba->shost; - u32 old_state, state; - int rc; - - if (!hisi_hba->hw->soft_reset) - return -1; - - if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) - return -1; down(&hisi_hba->sem); - dev_info(dev, "controller resetting...\n"); - old_state = hisi_hba->hw->get_phys_state(hisi_hba); + hisi_hba->phy_state = hisi_hba->hw->get_phys_state(hisi_hba); scsi_block_requests(shost); hisi_hba->hw->wait_cmds_complete_timeout(hisi_hba, 100, 5000); @@ -1333,15 +1323,13 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) del_timer_sync(&hisi_hba->timer); set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); - rc = hisi_hba->hw->soft_reset(hisi_hba); - if (rc) { - dev_warn(dev, "controller reset failed (%d)\n", rc); - clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); - up(&hisi_hba->sem); - scsi_unblock_requests(shost); - clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); - return rc; - } +} +EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_prepare); + +void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba) +{ + struct Scsi_Host *shost = hisi_hba->shost; + u32 state; /* Init and wait for PHYs to come up and all libsas event finished. */ hisi_hba->hw->phys_init(hisi_hba); @@ -1357,7 +1345,36 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) 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); + hisi_sas_rescan_topology(hisi_hba, hisi_hba->phy_state, state); +} +EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_done); + +static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) +{ + struct device *dev = hisi_hba->dev; + struct Scsi_Host *shost = hisi_hba->shost; + int rc; + + if (!hisi_hba->hw->soft_reset) + return -1; + + if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) + return -1; + + dev_info(dev, "controller resetting...\n"); + hisi_sas_controller_reset_prepare(hisi_hba); + + rc = hisi_hba->hw->soft_reset(hisi_hba); + if (rc) { + dev_warn(dev, "controller reset failed (%d)\n", rc); + clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); + up(&hisi_hba->sem); + scsi_unblock_requests(shost); + clear_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags); + return rc; + } + + hisi_sas_controller_reset_done(hisi_hba); dev_info(dev, "controller reset complete\n"); return 0; |