diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 9169c4cf413a3c80c76f728c1969591a279fa773..780a38731bcc5dbbf6859371c994eaabbe78beec 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -2005,6 +2005,7 @@ enum { QL_SELFTEST = 9, QL_LB_LINK_UP = 10, QL_FRC_COREDUMP = 11, + QL_EEH_FATAL = 12, }; /* link_status bit definitions */ diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 87ec7206415889834a383de24e818cf1dcf94ade..7e000295f3599cb5a8789cac576b050a54fbc4d9 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -3929,6 +3929,16 @@ static int qlge_close(struct net_device *ndev) { struct ql_adapter *qdev = netdev_priv(ndev); + /* If we hit pci_channel_io_perm_failure + * failure condition, then we already + * brought the adapter down. + */ + if (test_bit(QL_EEH_FATAL, &qdev->flags)) { + QPRINTK(qdev, DRV, ERR, "EEH fatal did unload.\n"); + clear_bit(QL_EEH_FATAL, &qdev->flags); + return 0; + } + /* * Wait for device to recover from a reset. * (Rarely happens, but possible.) @@ -4677,6 +4687,7 @@ static pci_ers_result_t qlge_io_error_detected(struct pci_dev *pdev, enum pci_channel_state state) { struct net_device *ndev = pci_get_drvdata(pdev); + struct ql_adapter *qdev = netdev_priv(ndev); switch (state) { case pci_channel_io_normal: @@ -4690,6 +4701,8 @@ static pci_ers_result_t qlge_io_error_detected(struct pci_dev *pdev, case pci_channel_io_perm_failure: dev_err(&pdev->dev, "%s: pci_channel_io_perm_failure.\n", __func__); + ql_eeh_close(ndev); + set_bit(QL_EEH_FATAL, &qdev->flags); return PCI_ERS_RESULT_DISCONNECT; } @@ -4720,6 +4733,7 @@ static pci_ers_result_t qlge_io_slot_reset(struct pci_dev *pdev) if (ql_adapter_reset(qdev)) { QPRINTK(qdev, DRV, ERR, "reset FAILED!\n"); + set_bit(QL_EEH_FATAL, &qdev->flags); return PCI_ERS_RESULT_DISCONNECT; }