]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/net/ethernet/mellanox/mlx4/main.c
mlx4: Add support for EEH error recovery
[mirror_ubuntu-bionic-kernel.git] / drivers / net / ethernet / mellanox / mlx4 / main.c
index 42645166bae2d3f1de36632f059ac5b597d5e365..e717091734d016fdb4e3d5c612a497d12e887457 100644 (file)
@@ -1775,6 +1775,9 @@ static int mlx4_get_ownership(struct mlx4_dev *dev)
        void __iomem *owner;
        u32 ret;
 
+       if (pci_channel_offline(dev->pdev))
+               return -EIO;
+
        owner = ioremap(pci_resource_start(dev->pdev, 0) + MLX4_OWNER_BASE,
                        MLX4_OWNER_SIZE);
        if (!owner) {
@@ -1791,6 +1794,9 @@ static void mlx4_free_ownership(struct mlx4_dev *dev)
 {
        void __iomem *owner;
 
+       if (pci_channel_offline(dev->pdev))
+               return;
+
        owner = ioremap(pci_resource_start(dev->pdev, 0) + MLX4_OWNER_BASE,
                        MLX4_OWNER_SIZE);
        if (!owner) {
@@ -2237,11 +2243,33 @@ static DEFINE_PCI_DEVICE_TABLE(mlx4_pci_table) = {
 
 MODULE_DEVICE_TABLE(pci, mlx4_pci_table);
 
+static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev,
+                                             pci_channel_state_t state)
+{
+       mlx4_remove_one(pdev);
+
+       return state == pci_channel_io_perm_failure ?
+               PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev)
+{
+       int ret = __mlx4_init_one(pdev, NULL);
+
+       return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
+}
+
+static struct pci_error_handlers mlx4_err_handler = {
+       .error_detected = mlx4_pci_err_detected,
+       .slot_reset     = mlx4_pci_slot_reset,
+};
+
 static struct pci_driver mlx4_driver = {
        .name           = DRV_NAME,
        .id_table       = mlx4_pci_table,
        .probe          = mlx4_init_one,
-       .remove         = __devexit_p(mlx4_remove_one)
+       .remove         = __devexit_p(mlx4_remove_one),
+       .err_handler    = &mlx4_err_handler,
 };
 
 static int __init mlx4_verify_params(void)