From c73a4d53dfbd548504334171623695c98baffb83 Mon Sep 17 00:00:00 2001
From: Saurav Kashyap <skashyap@marvell.com>
Date: Fri, 20 Oct 2023 14:12:35 +0530
Subject: [PATCH 2/2] qedf: Wait for stag work during unload.
Signed-off-by: Saurav Kashyap <skashyap@marvell.com>
Patch-mainline: not yet, waiting for upstream submission by Marvell
References: bsc#1214852
Acked-by: Martin Wilck <mwilck@suse.com>
---
drivers/scsi/qedf/qedf.h | 1 +
drivers/scsi/qedf/qedf_main.c | 24 +++++++++++++++++++++++-
2 files changed, 24 insertions(+), 1 deletion(-)
--- a/drivers/scsi/qedf/qedf.h
+++ b/drivers/scsi/qedf/qedf.h
@@ -354,6 +354,7 @@ struct qedf_ctx {
#define QEDF_IN_RECOVERY 5
#define QEDF_DBG_STOP_IO 6
#define QEDF_PROBING 8
+#define QEDF_STAG_IN_PROGRESS 9
unsigned long flags; /* Miscellaneous state flags */
int fipvlan_retries;
u8 num_queues;
--- a/drivers/scsi/qedf/qedf_main.c
+++ b/drivers/scsi/qedf/qedf_main.c
@@ -318,11 +318,17 @@ static struct fc_seq *qedf_elsct_send(st
*/
if (resp == fc_lport_flogi_resp) {
qedf->flogi_cnt++;
+ qedf->flogi_pending++;
+
+ if (test_bit(QEDF_UNLOADING, &qedf->flags)) {
+ QEDF_ERR(&qedf->dbg_ctx, "Driver unloading\n");
+ qedf->flogi_pending = 0;
+ }
+
if (qedf->flogi_pending >= QEDF_FLOGI_RETRY_CNT) {
schedule_delayed_work(&qedf->stag_work, 2);
return NULL;
}
- qedf->flogi_pending++;
return fc_elsct_send(lport, did, fp, op, qedf_flogi_resp,
arg, timeout);
}
@@ -912,6 +918,7 @@ void qedf_ctx_soft_reset(struct fc_lport
struct qed_link_output if_link;
if (lport->vport) {
+ clear_bit(QEDF_STAG_IN_PROGRESS, &qedf->flags);
printk_ratelimited("Cannot issue host reset on NPIV port.\n");
return;
}
@@ -935,6 +942,7 @@ void qedf_ctx_soft_reset(struct fc_lport
qed_ops->common->get_link(qedf->cdev, &if_link);
/* Bail if the physical link is not up */
if (!if_link.link_up) {
+ clear_bit(QEDF_STAG_IN_PROGRESS, &qedf->flags);
QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
"Physical link is not up.\n");
return;
@@ -949,6 +957,7 @@ void qedf_ctx_soft_reset(struct fc_lport
"Queue link up work.\n");
queue_delayed_work(qedf->link_update_wq, &qedf->link_update,
0);
+ clear_bit(QEDF_STAG_IN_PROGRESS, &qedf->flags);
}
/* Reset the host by gracefully logging out and then logging back in */
@@ -3722,6 +3731,7 @@ static void __qedf_remove(struct pci_dev
{
struct qedf_ctx *qedf;
int rc;
+ int cnt = 0;
if (!pdev) {
QEDF_ERR(NULL, "pdev is NULL.\n");
@@ -3739,6 +3749,17 @@ static void __qedf_remove(struct pci_dev
return;
}
+stag_in_prog:
+ if (test_bit(QEDF_STAG_IN_PROGRESS, &qedf->flags)) {
+ QEDF_ERR(&qedf->dbg_ctx, "Stag in progress, cnt=%d.\n", cnt);
+ cnt++;
+
+ if (cnt < 5) {
+ msleep(500);
+ goto stag_in_prog;
+ }
+ }
+
if (mode != QEDF_MODE_RECOVERY)
set_bit(QEDF_UNLOADING, &qedf->flags);
@@ -4003,6 +4024,7 @@ void qedf_stag_change_work(struct work_s
return;
}
+ set_bit(QEDF_STAG_IN_PROGRESS, &qedf->flags);
printk_ratelimited("[%s]:[%s:%d]:%d: Performing software context reset.",
dev_name(&qedf->pdev->dev), __func__, __LINE__,