diff options
author | Ron Mercer <ron.mercer@qlogic.com> | 2009-02-12 19:37:13 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-12 19:37:13 -0500 |
commit | 6497b607fb2d918e7588338761bfc6d53f49eeea (patch) | |
tree | 09e6e84f99cc55bc166a35164bda82833ac777e8 | |
parent | 7a9deb661f5973b414df0c12b496d6ce49c8ed85 (diff) |
qlge: bugfix: Fix fatal error recovery hang.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/qlge/qlge_main.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 27c5e4de78e..69f7d057dd2 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -1511,6 +1511,11 @@ void ql_queue_asic_error(struct ql_adapter *qdev) | |||
1511 | netif_stop_queue(qdev->ndev); | 1511 | netif_stop_queue(qdev->ndev); |
1512 | netif_carrier_off(qdev->ndev); | 1512 | netif_carrier_off(qdev->ndev); |
1513 | ql_disable_interrupts(qdev); | 1513 | ql_disable_interrupts(qdev); |
1514 | /* Clear adapter up bit to signal the recovery | ||
1515 | * process that it shouldn't kill the reset worker | ||
1516 | * thread | ||
1517 | */ | ||
1518 | clear_bit(QL_ADAPTER_UP, &qdev->flags); | ||
1514 | queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); | 1519 | queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); |
1515 | } | 1520 | } |
1516 | 1521 | ||
@@ -3100,7 +3105,11 @@ static int ql_adapter_down(struct ql_adapter *qdev) | |||
3100 | netif_stop_queue(ndev); | 3105 | netif_stop_queue(ndev); |
3101 | netif_carrier_off(ndev); | 3106 | netif_carrier_off(ndev); |
3102 | 3107 | ||
3103 | cancel_delayed_work_sync(&qdev->asic_reset_work); | 3108 | /* Don't kill the reset worker thread if we |
3109 | * are in the process of recovery. | ||
3110 | */ | ||
3111 | if (test_bit(QL_ADAPTER_UP, &qdev->flags)) | ||
3112 | cancel_delayed_work_sync(&qdev->asic_reset_work); | ||
3104 | cancel_delayed_work_sync(&qdev->mpi_reset_work); | 3113 | cancel_delayed_work_sync(&qdev->mpi_reset_work); |
3105 | cancel_delayed_work_sync(&qdev->mpi_work); | 3114 | cancel_delayed_work_sync(&qdev->mpi_work); |
3106 | 3115 | ||
@@ -3501,7 +3510,7 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p) | |||
3501 | static void qlge_tx_timeout(struct net_device *ndev) | 3510 | static void qlge_tx_timeout(struct net_device *ndev) |
3502 | { | 3511 | { |
3503 | struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); | 3512 | struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); |
3504 | queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); | 3513 | ql_queue_asic_error(qdev); |
3505 | } | 3514 | } |
3506 | 3515 | ||
3507 | static void ql_asic_reset_work(struct work_struct *work) | 3516 | static void ql_asic_reset_work(struct work_struct *work) |