scsi: qedi: Add schedule_hw_err_handler callback for fan failure
authorManish Rangankar <mrangankar@marvell.com>
Thu, 24 Sep 2020 07:03:38 +0000 (00:03 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Sat, 3 Oct 2020 01:24:15 +0000 (21:24 -0400)
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>
drivers/scsi/qedi/qedi.h
drivers/scsi/qedi/qedi_main.c

index 7e59d50f2fabbf4c857351522ace84593cb979e4..c342defc3f522d3e87c4fcfa6c6e0ee12769a450 100644 (file)
@@ -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;
index 642790b2d9be5a25cfc6d2b238df6f65cf4fdad0..61fab01d2d527797f7216ec126963e76db410a71 100644 (file)
@@ -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);