Subject: [PATCH v2 1/3] cxlflash: Base error recovery support
Date: Thu, 16 Jul 2015 18:26:35 -0500
From: Matthew R. Ochs <mro...@linux.vnet.ibm.com>
To: linux-scsi@vger.kernel.org, james.bottom...@hansenpartnership.com, n...@linux-iscsi.org, brk...@linux.vnet.ibm.com CC: h...@infradead.org, mi...@neuling.org, imun...@au1.ibm.com, d...@ozlabs.au.ibm.com, Manoj N. Kumar <ma...@linux.vnet.ibm.com>

Introduce support for enhanced I/O error handling.

Signed-off-by: Matthew R. Ochs <mro...@linux.vnet.ibm.com>
Signed-off-by: Manoj N. Kumar <ma...@linux.vnet.ibm.com>
---
 drivers/scsi/cxlflash/common.h |  11 +++-
drivers/scsi/cxlflash/main.c | 135 ++++++++++++++++++++++++++++++++++++++---
 2 files changed, 133 insertions(+), 13 deletions(-)


+/**
+ * cxlflash_pci_error_detected() - called when a PCI error is detected
+ * @pdev:      PCI device struct.
+ * @state:     PCI channel state.
+ *
+ * Return: PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT
+ */
+static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev,
+                                                   pci_channel_state_t state)
+{
+       struct cxlflash_cfg *cfg = pci_get_drvdata(pdev);
+
+       pr_debug("%s: pdev=%p state=%u\n", __func__, pdev, state);
+
+       switch (state) {
+       case pci_channel_io_frozen:
+               cfg->eeh_active = EEH_STATE_ACTIVE;
+               udelay(100);
+
+               term_mc(cfg, UNDO_START);
+               stop_afu(cfg);
+
+               return PCI_ERS_RESULT_CAN_RECOVER;
+       case pci_channel_io_perm_failure:
+               cfg->eeh_active = EEH_STATE_FAILED;
+               wake_up_all(&cfg->eeh_waitq);
+               return PCI_ERS_RESULT_DISCONNECT;
+       default:
+               break;
+       }
+       return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * cxlflash_pci_slot_reset() - called when PCI slot has been reset
+ * @pdev:      PCI device struct.
+ *
+ * This routine is called by the pci error recovery code after the PCI
+ * slot has been reset, just before we should resume normal operations.
+ *
+ * Return: PCI_ERS_RESULT_RECOVERED or PCI_ERS_RESULT_DISCONNECT
+ */
+static pci_ers_result_t cxlflash_pci_slot_reset(struct pci_dev *pdev)
+{
+       int rc = 0;
+       struct cxlflash_cfg *cfg = pci_get_drvdata(pdev);
+
+       pr_debug("%s: pdev=%p\n", __func__, pdev);
+
+       rc = init_afu(cfg);
+       if (unlikely(rc)) {
+               pr_err("%s: EEH recovery failed! (%d)\n", __func__, rc);
+               return PCI_ERS_RESULT_DISCONNECT;
+       }
+
+       return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * cxlflash_pci_resume() - called when normal operation can resume
+ * @pdev:      PCI device struct
+ */
+static void cxlflash_pci_resume(struct pci_dev *pdev)
+{
+       struct cxlflash_cfg *cfg = pci_get_drvdata(pdev);
+
+       pr_debug("%s: pdev=%p\n", __func__, pdev);
+
+       cfg->eeh_active = EEH_STATE_NONE;
+       wake_up_all(&cfg->eeh_waitq);
+}
+

Do you need host->lock in these EEH callback functions?

+static const struct pci_error_handlers cxlflash_err_handler = {
+       .error_detected = cxlflash_pci_error_detected,
+       .slot_reset = cxlflash_pci_slot_reset,
+       .resume = cxlflash_pci_resume,
+};
+
 /*
  * PCI device structure
  */
@@ -2267,6 +2381,7 @@ static struct pci_driver cxlflash_driver = {
        .id_table = cxlflash_pci_table,
        .probe = cxlflash_probe,
        .remove = cxlflash_remove,
+       .err_handler = &cxlflash_err_handler,
 };

 /**
--
2.1.0

Thanks,
Wendy

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to