aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qla3xxx.c
diff options
context:
space:
mode:
authorRon Mercer <ron.mercer@qlogic.com>2007-11-07 16:59:06 -0500
committerJeff Garzik <jeff@garzik.org>2007-11-10 04:25:15 -0500
commit3e23b7d3b54c07f1c4fee1ebc418d1a37248654e (patch)
tree8b2e236ded93e0c98176e1afb60b812b7577c438 /drivers/net/qla3xxx.c
parent32bee776533eea839f9499d985c1490b5ac98512 (diff)
qla3xxx: bugfix: Move link state machine into a worker thread
The link state machine requires access to some resources that are shared with the iSCSI function on the chip. (See iSCSI driver at drivers/scsi/qla4xxx) If the interface is being up/downed at a rapid pace this driver may need to sleep waiting to get access to the common resources. For this we are moving the state machine to run as a work thread. Signed-off-by: Ron Mercer <ron.mercer@qlogic.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/qla3xxx.c')
-rw-r--r--drivers/net/qla3xxx.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 30adf726743c..4f0fd41dce19 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -1645,8 +1645,11 @@ static int ql_finish_auto_neg(struct ql3_adapter *qdev)
1645 return 0; 1645 return 0;
1646} 1646}
1647 1647
1648static void ql_link_state_machine(struct ql3_adapter *qdev) 1648static void ql_link_state_machine_work(struct work_struct *work)
1649{ 1649{
1650 struct ql3_adapter *qdev =
1651 container_of(work, struct ql3_adapter, link_state_work.work);
1652
1650 u32 curr_link_state; 1653 u32 curr_link_state;
1651 unsigned long hw_flags; 1654 unsigned long hw_flags;
1652 1655
@@ -1661,6 +1664,10 @@ static void ql_link_state_machine(struct ql3_adapter *qdev)
1661 "state.\n", qdev->ndev->name); 1664 "state.\n", qdev->ndev->name);
1662 1665
1663 spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); 1666 spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
1667
1668 /* Restart timer on 2 second interval. */
1669 mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);\
1670
1664 return; 1671 return;
1665 } 1672 }
1666 1673
@@ -1705,6 +1712,9 @@ static void ql_link_state_machine(struct ql3_adapter *qdev)
1705 break; 1712 break;
1706 } 1713 }
1707 spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); 1714 spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
1715
1716 /* Restart timer on 2 second interval. */
1717 mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);
1708} 1718}
1709 1719
1710/* 1720/*
@@ -3941,19 +3951,7 @@ static void ql_get_board_info(struct ql3_adapter *qdev)
3941static void ql3xxx_timer(unsigned long ptr) 3951static void ql3xxx_timer(unsigned long ptr)
3942{ 3952{
3943 struct ql3_adapter *qdev = (struct ql3_adapter *)ptr; 3953 struct ql3_adapter *qdev = (struct ql3_adapter *)ptr;
3944 3954 queue_delayed_work(qdev->workqueue, &qdev->link_state_work, 0);
3945 if (test_bit(QL_RESET_ACTIVE,&qdev->flags)) {
3946 printk(KERN_DEBUG PFX
3947 "%s: Reset in progress.\n",
3948 qdev->ndev->name);
3949 goto end;
3950 }
3951
3952 ql_link_state_machine(qdev);
3953
3954 /* Restart timer on 2 second interval. */
3955end:
3956 mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);
3957} 3955}
3958 3956
3959static int __devinit ql3xxx_probe(struct pci_dev *pdev, 3957static int __devinit ql3xxx_probe(struct pci_dev *pdev,
@@ -4103,6 +4101,7 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
4103 qdev->workqueue = create_singlethread_workqueue(ndev->name); 4101 qdev->workqueue = create_singlethread_workqueue(ndev->name);
4104 INIT_DELAYED_WORK(&qdev->reset_work, ql_reset_work); 4102 INIT_DELAYED_WORK(&qdev->reset_work, ql_reset_work);
4105 INIT_DELAYED_WORK(&qdev->tx_timeout_work, ql_tx_timeout_work); 4103 INIT_DELAYED_WORK(&qdev->tx_timeout_work, ql_tx_timeout_work);
4104 INIT_DELAYED_WORK(&qdev->link_state_work, ql_link_state_machine_work);
4106 4105
4107 init_timer(&qdev->adapter_timer); 4106 init_timer(&qdev->adapter_timer);
4108 qdev->adapter_timer.function = ql3xxx_timer; 4107 qdev->adapter_timer.function = ql3xxx_timer;