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

scsi: hisi_sas: add an mechanism to do reset work synchronously

Sometimes it is required to know when the controller reset has completed and
also if it has completed successfully.  For such places, we call
hisi_sas_controller_reset() directly before. That may lead to multiple calls
to this function.

This patch create a per-reset structure which contains a completion structure
and status flag to know when the reset completes and also the status. It is
also in hisi_hba.wq to do reset work.

As all host reset works are done in hisi_hba.wq, we don't worry multiple calls
to hisi_sas_controller_reset().
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 f8e45ec2
......@@ -99,6 +99,31 @@ struct hisi_sas_hw_error {
const struct hisi_sas_hw_error *sub;
};
struct hisi_sas_rst {
struct hisi_hba *hisi_hba;
struct completion *completion;
struct work_struct work;
bool done;
};
#define HISI_SAS_RST_WORK_INIT(r, c) \
{ .hisi_hba = hisi_hba, \
.completion = &c, \
.work = __WORK_INITIALIZER(r.work, \
hisi_sas_sync_rst_work_handler), \
.done = false, \
}
#define HISI_SAS_DECLARE_RST_WORK_ON_STACK(r) \
DECLARE_COMPLETION_ONSTACK(c); \
DECLARE_WORK(w, hisi_sas_sync_rst_work_handler); \
struct hisi_sas_rst r = HISI_SAS_RST_WORK_INIT(r, c)
enum hisi_sas_bit_err_type {
HISI_SAS_ERR_SINGLE_BIT_ECC = 0x0,
HISI_SAS_ERR_MULTI_BIT_ECC = 0x1,
};
struct hisi_sas_phy {
struct hisi_hba *hisi_hba;
struct hisi_sas_port *port;
......@@ -426,5 +451,6 @@ extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba,
struct hisi_sas_slot *slot);
extern void hisi_sas_init_mem(struct hisi_hba *hisi_hba);
extern void hisi_sas_rst_work_handler(struct work_struct *work);
extern void hisi_sas_sync_rst_work_handler(struct work_struct *work);
extern void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba);
#endif
......@@ -1299,8 +1299,14 @@ static int hisi_sas_lu_reset(struct domain_device *device, u8 *lun)
static int hisi_sas_clear_nexus_ha(struct sas_ha_struct *sas_ha)
{
struct hisi_hba *hisi_hba = sas_ha->lldd_ha;
HISI_SAS_DECLARE_RST_WORK_ON_STACK(r);
return hisi_sas_controller_reset(hisi_hba);
queue_work(hisi_hba->wq, &r.work);
wait_for_completion(r.completion);
if (r.done)
return TMF_RESP_FUNC_COMPLETE;
return TMF_RESP_FUNC_FAILED;
}
static int hisi_sas_query_task(struct sas_task *task)
......@@ -1820,6 +1826,17 @@ void hisi_sas_rst_work_handler(struct work_struct *work)
}
EXPORT_SYMBOL_GPL(hisi_sas_rst_work_handler);
void hisi_sas_sync_rst_work_handler(struct work_struct *work)
{
struct hisi_sas_rst *rst =
container_of(work, struct hisi_sas_rst, work);
if (!hisi_sas_controller_reset(rst->hisi_hba))
rst->done = true;
complete(rst->completion);
}
EXPORT_SYMBOL_GPL(hisi_sas_sync_rst_work_handler);
int hisi_sas_get_fw_info(struct hisi_hba *hisi_hba)
{
struct device *dev = hisi_hba->dev;
......
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