diff options
author | Manish Rangankar <mrangankar@marvell.com> | 2020-09-08 11:56:57 +0200 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2020-09-09 04:40:25 +0200 |
commit | 96a766a789eb49d85c9a15eac9456fbddadb1158 (patch) | |
tree | c789a4fa4fda9bb3ab3a258c8cbfbb67027b0697 /drivers/scsi/qedi | |
parent | scsi: qedi: Add firmware error recovery invocation support (diff) | |
download | linux-96a766a789eb49d85c9a15eac9456fbddadb1158.tar.xz linux-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')
-rw-r--r-- | drivers/scsi/qedi/qedi_main.c | 24 |
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) |