diff options
author | Ron Mercer <ron.mercer@qlogic.com> | 2007-11-07 16:59:06 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-11-10 04:25:15 -0500 |
commit | 3e23b7d3b54c07f1c4fee1ebc418d1a37248654e (patch) | |
tree | 8b2e236ded93e0c98176e1afb60b812b7577c438 | |
parent | 32bee776533eea839f9499d985c1490b5ac98512 (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>
-rw-r--r-- | drivers/net/qla3xxx.c | 27 | ||||
-rw-r--r-- | drivers/net/qla3xxx.h | 1 |
2 files changed, 14 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 | ||
1648 | static void ql_link_state_machine(struct ql3_adapter *qdev) | 1648 | static 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) | |||
3941 | static void ql3xxx_timer(unsigned long ptr) | 3951 | static 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. */ | ||
3955 | end: | ||
3956 | mod_timer(&qdev->adapter_timer, jiffies + HZ * 1); | ||
3957 | } | 3955 | } |
3958 | 3956 | ||
3959 | static int __devinit ql3xxx_probe(struct pci_dev *pdev, | 3957 | static 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; |
diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h index fbcb0b949639..d0ffb30ef371 100644 --- a/drivers/net/qla3xxx.h +++ b/drivers/net/qla3xxx.h | |||
@@ -1286,6 +1286,7 @@ struct ql3_adapter { | |||
1286 | struct workqueue_struct *workqueue; | 1286 | struct workqueue_struct *workqueue; |
1287 | struct delayed_work reset_work; | 1287 | struct delayed_work reset_work; |
1288 | struct delayed_work tx_timeout_work; | 1288 | struct delayed_work tx_timeout_work; |
1289 | struct delayed_work link_state_work; | ||
1289 | u32 max_frame_size; | 1290 | u32 max_frame_size; |
1290 | u32 device_id; | 1291 | u32 device_id; |
1291 | u16 phyType; | 1292 | u16 phyType; |