lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1512753410-50924-8-git-send-email-john.garry@huawei.com>
Date:   Sat, 9 Dec 2017 01:16:38 +0800
From:   John Garry <john.garry@...wei.com>
To:     <jejb@...ux.vnet.ibm.com>, <martin.petersen@...cle.com>
CC:     <linuxarm@...wei.com>, <linux-scsi@...r.kernel.org>,
        <linux-kernel@...r.kernel.org>,
        Xiaofei Tan <tanxiaofei@...wei.com>,
        "John Garry" <john.garry@...wei.com>
Subject: [PATCH 07/19] scsi: hisi_sas: add an mechanism to do reset work synchronously

From: Xiaofei Tan <tanxiaofei@...wei.com>

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: Xiaofei Tan <tanxiaofei@...wei.com>
Signed-off-by: John Garry <john.garry@...wei.com>
---
 drivers/scsi/hisi_sas/hisi_sas.h      | 26 ++++++++++++++++++++++++++
 drivers/scsi/hisi_sas/hisi_sas_main.c | 19 ++++++++++++++++++-
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index b2534ca..71bc8ea 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -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
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index e4b3092..fb162c0 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -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;
-- 
1.9.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ