aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qedi/qedi_main.c
diff options
context:
space:
mode:
authorManish Rangankar <mrangankar@marvell.com>2020-09-08 02:56:57 -0700
committerMartin K. Petersen <martin.petersen@oracle.com>2020-09-08 22:40:25 -0400
commit96a766a789eb49d85c9a15eac9456fbddadb1158 (patch)
treec789a4fa4fda9bb3ab3a258c8cbfbb67027b0697 /drivers/scsi/qedi/qedi_main.c
parentscsi: qedi: Add firmware error recovery invocation support (diff)
downloadlinux-dev-96a766a789eb49d85c9a15eac9456fbddadb1158.tar.xz
linux-dev-96a766a789eb49d85c9a15eac9456fbddadb1158.zip
scsi: qedi: Add support for handling PCIe errors
The error recovery is handled by management firmware (MFW) with the help of qed/qedi drivers. Upon detecting errors, driver informs MFW about this event which in turn starts a recovery process. MFW sends ERROR_RECOVERY notification to the driver which performs the required cleanup/recovery from the driver side. Link: https://lore.kernel.org/r/20200908095657.26821-9-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/qedi_main.c')
-rw-r--r--drivers/scsi/qedi/qedi_main.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c
index 8fde35f843f7..642790b2d9be 100644
--- a/drivers/scsi/qedi/qedi_main.c
+++ b/drivers/scsi/qedi/qedi_main.c
@@ -2390,6 +2390,25 @@ kset_free:
return -ENOMEM;
}
+static pci_ers_result_t qedi_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct qedi_ctx *qedi = pci_get_drvdata(pdev);
+
+ QEDI_ERR(&qedi->dbg_ctx, "%s: PCI error detected [%d]\n",
+ __func__, state);
+
+ if (test_and_set_bit(QEDI_IN_RECOVERY, &qedi->flags)) {
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
+ "Recovery already in progress.\n");
+ return PCI_ERS_RESULT_NONE;
+ }
+
+ qedi_ops->common->recovery_process(qedi->cdev);
+
+ return PCI_ERS_RESULT_CAN_RECOVER;
+}
+
static void __qedi_remove(struct pci_dev *pdev, int mode)
{
struct qedi_ctx *qedi = pci_get_drvdata(pdev);
@@ -2819,12 +2838,17 @@ MODULE_DEVICE_TABLE(pci, qedi_pci_tbl);
static enum cpuhp_state qedi_cpuhp_state;
+static struct pci_error_handlers qedi_err_handler = {
+ .error_detected = qedi_io_error_detected,
+};
+
static struct pci_driver qedi_pci_driver = {
.name = QEDI_MODULE_NAME,
.id_table = qedi_pci_tbl,
.probe = qedi_probe,
.remove = qedi_remove,
.shutdown = qedi_shutdown,
+ .err_handler = &qedi_err_handler,
};
static int __init qedi_init(void)