Skip to content

Commit

Permalink
qlge: Add check for eeh failure when closing device.
Browse files Browse the repository at this point in the history
Fix crash where resources are freed twice on an eeh recovery failure.
If eeh recovery fails we set a flag to indicate to close() that
resources have been freed.

Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Ron Mercer authored and David S. Miller committed Feb 4, 2010
1 parent a112fd4 commit 4bbd1a1
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/net/qlge/qlge.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
14 changes: 14 additions & 0 deletions drivers/net/qlge/qlge_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.)
Expand Down Expand Up @@ -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:
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 4bbd1a1

Please sign in to comment.