aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRon Mercer <ron.mercer@qlogic.com>2009-02-12 19:37:13 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-12 19:37:13 -0500
commit6497b607fb2d918e7588338761bfc6d53f49eeea (patch)
tree09e6e84f99cc55bc166a35164bda82833ac777e8 /drivers
parent7a9deb661f5973b414df0c12b496d6ce49c8ed85 (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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/qlge/qlge_main.c13
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)
3501static void qlge_tx_timeout(struct net_device *ndev) 3510static 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
3507static void ql_asic_reset_work(struct work_struct *work) 3516static void ql_asic_reset_work(struct work_struct *work)