summaryrefslogtreecommitdiff
path: root/drivers/scsi/qedi
diff options
context:
space:
mode:
authorManish Rangankar <mrangankar@marvell.com>2020-09-24 00:03:38 -0700
committerMartin K. Petersen <martin.petersen@oracle.com>2020-10-02 21:24:15 -0400
commit7dc71ac8eb0bcaa76d69a3214d62a80b21c73f50 (patch)
tree0ef49df937c1dafc9f7a8c6f0be59262593fcf09 /drivers/scsi/qedi
parent61741d8699e1fc764a309ebd20211bb1cb193110 (diff)
scsi: qedi: Add schedule_hw_err_handler callback for fan failure
On fan failure event from MFW, bring down active connections and unload the firmware context. Link: https://lore.kernel.org/r/20200924070338.8270-1-mrangankar@marvell.com Signed-off-by: Manish Rangankar <mrangankar@marvell.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/qedi')
-rw-r--r--drivers/scsi/qedi/qedi.h1
-rw-r--r--drivers/scsi/qedi/qedi_main.c20
2 files changed, 21 insertions, 0 deletions
diff --git a/drivers/scsi/qedi/qedi.h b/drivers/scsi/qedi/qedi.h
index 7e59d50f2fab..c342defc3f52 100644
--- a/drivers/scsi/qedi/qedi.h
+++ b/drivers/scsi/qedi/qedi.h
@@ -339,6 +339,7 @@ struct qedi_ctx {
struct workqueue_struct *dpc_wq;
struct delayed_work recovery_work;
+ struct delayed_work board_disable_work;
spinlock_t task_idx_lock; /* To protect gbl context */
s32 last_tidx_alloc;
diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c
index 642790b2d9be..61fab01d2d52 100644
--- a/drivers/scsi/qedi/qedi_main.c
+++ b/drivers/scsi/qedi/qedi_main.c
@@ -1132,6 +1132,9 @@ void qedi_schedule_hw_err_handler(void *dev,
err_type, qedi->qedi_err_flags);
switch (err_type) {
+ case QED_HW_ERR_FAN_FAIL:
+ schedule_delayed_work(&qedi->board_disable_work, 0);
+ break;
case QED_HW_ERR_MFW_RESP_FAIL:
case QED_HW_ERR_HW_ATTN:
case QED_HW_ERR_DMAE_FAIL:
@@ -2485,6 +2488,21 @@ static void __qedi_remove(struct pci_dev *pdev, int mode)
}
}
+static void qedi_board_disable_work(struct work_struct *work)
+{
+ struct qedi_ctx *qedi =
+ container_of(work, struct qedi_ctx,
+ board_disable_work.work);
+
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
+ "Fan failure, Unloading firmware context.\n");
+
+ if (test_and_set_bit(QEDI_IN_SHUTDOWN, &qedi->flags))
+ return;
+
+ __qedi_remove(qedi->pdev, QEDI_MODE_SHUTDOWN);
+}
+
static void qedi_shutdown(struct pci_dev *pdev)
{
struct qedi_ctx *qedi = pci_get_drvdata(pdev);
@@ -2752,6 +2770,8 @@ retry_probe:
}
INIT_DELAYED_WORK(&qedi->recovery_work, qedi_recovery_handler);
+ INIT_DELAYED_WORK(&qedi->board_disable_work,
+ qedi_board_disable_work);
/* F/w needs 1st task context memory entry for performance */
set_bit(QEDI_RESERVE_TASK_ID, qedi->task_idx_map);