Subject: [PATCH v2 1/3] cxlflash: Base error recovery support
Date: Thu, 16 Jul 2015 18:26:35 -0500
From: Matthew R. Ochs <mrochs@xxxxxxxxxxxxxxxxxx>
To: linux-scsi@xxxxxxxxxxxxxxx,
James.Bottomley@xxxxxxxxxxxxxxxxxxxxx, nab@xxxxxxxxxxxxxxx,
brking@xxxxxxxxxxxxxxxxxx
CC: hch@xxxxxxxxxxxxx, mikey@xxxxxxxxxxx, imunsie@xxxxxxxxxxx,
dja@xxxxxxxxxxxxxxxxx, Manoj N. Kumar <manoj@xxxxxxxxxxxxxxxxxx>
Introduce support for enhanced I/O error handling.
Signed-off-by: Matthew R. Ochs <mrochs@xxxxxxxxxxxxxxxxxx>
Signed-off-by: Manoj N. Kumar <manoj@xxxxxxxxxxxxxxxxxx>
---
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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html