diff options
author | Ron Mercer <ron.mercer@qlogic.com> | 2009-02-13 03:37:13 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-13 03:37:13 +0300 |
commit | 6497b607fb2d918e7588338761bfc6d53f49eeea (patch) | |
tree | 09e6e84f99cc55bc166a35164bda82833ac777e8 /drivers | |
parent | 7a9deb661f5973b414df0c12b496d6ce49c8ed85 (diff) | |
download | linux-6497b607fb2d918e7588338761bfc6d53f49eeea.tar.xz |
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>
Diffstat (limited to 'drivers')
-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 27c5e4de78ec..69f7d057dd27 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) netif_stop_queue(qdev->ndev); netif_carrier_off(qdev->ndev); ql_disable_interrupts(qdev); + /* Clear adapter up bit to signal the recovery + * process that it shouldn't kill the reset worker + * thread + */ + clear_bit(QL_ADAPTER_UP, &qdev->flags); queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); } @@ -3100,7 +3105,11 @@ static int ql_adapter_down(struct ql_adapter *qdev) netif_stop_queue(ndev); netif_carrier_off(ndev); - cancel_delayed_work_sync(&qdev->asic_reset_work); + /* Don't kill the reset worker thread if we + * are in the process of recovery. + */ + if (test_bit(QL_ADAPTER_UP, &qdev->flags)) + cancel_delayed_work_sync(&qdev->asic_reset_work); cancel_delayed_work_sync(&qdev->mpi_reset_work); cancel_delayed_work_sync(&qdev->mpi_work); @@ -3501,7 +3510,7 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p) static void qlge_tx_timeout(struct net_device *ndev) { struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); - queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); + ql_queue_asic_error(qdev); } static void ql_asic_reset_work(struct work_struct *work) |