diff options
author | Manfred Spraul <manfred@colorfullife.com> | 2007-10-17 15:52:33 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-10-17 20:17:34 -0400 |
commit | a7475906bc496456ded9e4b062f94067fb93057a (patch) | |
tree | b22c55299909fb2fc2f7168fb9e74867bdba2fc1 | |
parent | db0e8e3f71dbd9a67e44eaa01d10e468d11fa73e (diff) |
forcedeth msi bugfix
pci_enable_msi() replaces the INTx irq number in pci_dev->irq with the
new MSI irq number.
The forcedeth driver did not update the copy in netdevice->irq and
parts of the driver used the stale copy.
See bugzilla.kernel.org, bug 9047.
The patch
- updates netdevice->irq
- replaces all accesses to netdevice->irq with pci_dev->irq.
The patch is against 2.6.23.1. IMHO suitable for both 2.6.23 and 2.6.24
Signed-Off-By: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/net/forcedeth.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index d0bff8a87666..70ddf1acfd88 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -992,7 +992,7 @@ static void nv_enable_irq(struct net_device *dev) | |||
992 | if (np->msi_flags & NV_MSI_X_ENABLED) | 992 | if (np->msi_flags & NV_MSI_X_ENABLED) |
993 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); | 993 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); |
994 | else | 994 | else |
995 | enable_irq(dev->irq); | 995 | enable_irq(np->pci_dev->irq); |
996 | } else { | 996 | } else { |
997 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); | 997 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); |
998 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); | 998 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); |
@@ -1008,7 +1008,7 @@ static void nv_disable_irq(struct net_device *dev) | |||
1008 | if (np->msi_flags & NV_MSI_X_ENABLED) | 1008 | if (np->msi_flags & NV_MSI_X_ENABLED) |
1009 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); | 1009 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); |
1010 | else | 1010 | else |
1011 | disable_irq(dev->irq); | 1011 | disable_irq(np->pci_dev->irq); |
1012 | } else { | 1012 | } else { |
1013 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); | 1013 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); |
1014 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); | 1014 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); |
@@ -1607,7 +1607,7 @@ static void nv_do_rx_refill(unsigned long data) | |||
1607 | if (np->msi_flags & NV_MSI_X_ENABLED) | 1607 | if (np->msi_flags & NV_MSI_X_ENABLED) |
1608 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); | 1608 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); |
1609 | else | 1609 | else |
1610 | disable_irq(dev->irq); | 1610 | disable_irq(np->pci_dev->irq); |
1611 | } else { | 1611 | } else { |
1612 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); | 1612 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); |
1613 | } | 1613 | } |
@@ -1625,7 +1625,7 @@ static void nv_do_rx_refill(unsigned long data) | |||
1625 | if (np->msi_flags & NV_MSI_X_ENABLED) | 1625 | if (np->msi_flags & NV_MSI_X_ENABLED) |
1626 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); | 1626 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); |
1627 | else | 1627 | else |
1628 | enable_irq(dev->irq); | 1628 | enable_irq(np->pci_dev->irq); |
1629 | } else { | 1629 | } else { |
1630 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); | 1630 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); |
1631 | } | 1631 | } |
@@ -3560,10 +3560,12 @@ static int nv_request_irq(struct net_device *dev, int intr_test) | |||
3560 | if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { | 3560 | if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { |
3561 | if ((ret = pci_enable_msi(np->pci_dev)) == 0) { | 3561 | if ((ret = pci_enable_msi(np->pci_dev)) == 0) { |
3562 | np->msi_flags |= NV_MSI_ENABLED; | 3562 | np->msi_flags |= NV_MSI_ENABLED; |
3563 | dev->irq = np->pci_dev->irq; | ||
3563 | if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) { | 3564 | if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) { |
3564 | printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); | 3565 | printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); |
3565 | pci_disable_msi(np->pci_dev); | 3566 | pci_disable_msi(np->pci_dev); |
3566 | np->msi_flags &= ~NV_MSI_ENABLED; | 3567 | np->msi_flags &= ~NV_MSI_ENABLED; |
3568 | dev->irq = np->pci_dev->irq; | ||
3567 | goto out_err; | 3569 | goto out_err; |
3568 | } | 3570 | } |
3569 | 3571 | ||
@@ -3626,7 +3628,7 @@ static void nv_do_nic_poll(unsigned long data) | |||
3626 | if (np->msi_flags & NV_MSI_X_ENABLED) | 3628 | if (np->msi_flags & NV_MSI_X_ENABLED) |
3627 | disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); | 3629 | disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); |
3628 | else | 3630 | else |
3629 | disable_irq_lockdep(dev->irq); | 3631 | disable_irq_lockdep(np->pci_dev->irq); |
3630 | mask = np->irqmask; | 3632 | mask = np->irqmask; |
3631 | } else { | 3633 | } else { |
3632 | if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { | 3634 | if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { |
@@ -3644,6 +3646,8 @@ static void nv_do_nic_poll(unsigned long data) | |||
3644 | } | 3646 | } |
3645 | np->nic_poll_irq = 0; | 3647 | np->nic_poll_irq = 0; |
3646 | 3648 | ||
3649 | /* disable_irq() contains synchronize_irq, thus no irq handler can run now */ | ||
3650 | |||
3647 | if (np->recover_error) { | 3651 | if (np->recover_error) { |
3648 | np->recover_error = 0; | 3652 | np->recover_error = 0; |
3649 | printk(KERN_INFO "forcedeth: MAC in recoverable error state\n"); | 3653 | printk(KERN_INFO "forcedeth: MAC in recoverable error state\n"); |
@@ -3680,7 +3684,6 @@ static void nv_do_nic_poll(unsigned long data) | |||
3680 | } | 3684 | } |
3681 | } | 3685 | } |
3682 | 3686 | ||
3683 | /* FIXME: Do we need synchronize_irq(dev->irq) here? */ | ||
3684 | 3687 | ||
3685 | writel(mask, base + NvRegIrqMask); | 3688 | writel(mask, base + NvRegIrqMask); |
3686 | pci_push(base); | 3689 | pci_push(base); |
@@ -3693,7 +3696,7 @@ static void nv_do_nic_poll(unsigned long data) | |||
3693 | if (np->msi_flags & NV_MSI_X_ENABLED) | 3696 | if (np->msi_flags & NV_MSI_X_ENABLED) |
3694 | enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); | 3697 | enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); |
3695 | else | 3698 | else |
3696 | enable_irq_lockdep(dev->irq); | 3699 | enable_irq_lockdep(np->pci_dev->irq); |
3697 | } else { | 3700 | } else { |
3698 | if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { | 3701 | if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { |
3699 | nv_nic_irq_rx(0, dev); | 3702 | nv_nic_irq_rx(0, dev); |
@@ -4950,7 +4953,7 @@ static int nv_close(struct net_device *dev) | |||
4950 | #ifdef CONFIG_FORCEDETH_NAPI | 4953 | #ifdef CONFIG_FORCEDETH_NAPI |
4951 | napi_disable(&np->napi); | 4954 | napi_disable(&np->napi); |
4952 | #endif | 4955 | #endif |
4953 | synchronize_irq(dev->irq); | 4956 | synchronize_irq(np->pci_dev->irq); |
4954 | 4957 | ||
4955 | del_timer_sync(&np->oom_kick); | 4958 | del_timer_sync(&np->oom_kick); |
4956 | del_timer_sync(&np->nic_poll); | 4959 | del_timer_sync(&np->nic_poll); |