diff options
author | Manfred Spraul <manfred@colorfullife.com> | 2007-10-17 21:52:33 +0200 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-10-17 20:17:34 -0400 |
commit | a7475906bc496456ded9e4b062f94067fb93057a (patch) | |
tree | b22c55299909fb2fc2f7168fb9e74867bdba2fc1 /drivers/net/forcedeth.c | |
parent | db0e8e3f71dbd9a67e44eaa01d10e468d11fa73e (diff) | |
download | linux-stable-a7475906bc496456ded9e4b062f94067fb93057a.tar.gz linux-stable-a7475906bc496456ded9e4b062f94067fb93057a.tar.bz2 linux-stable-a7475906bc496456ded9e4b062f94067fb93057a.zip |
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>
Diffstat (limited to 'drivers/net/forcedeth.c')
-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) if (np->msi_flags & NV_MSI_X_ENABLED) enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - enable_irq(dev->irq); + enable_irq(np->pci_dev->irq); } else { enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); 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) if (np->msi_flags & NV_MSI_X_ENABLED) disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - disable_irq(dev->irq); + disable_irq(np->pci_dev->irq); } else { disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); 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) if (np->msi_flags & NV_MSI_X_ENABLED) disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - disable_irq(dev->irq); + disable_irq(np->pci_dev->irq); } else { disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); } @@ -1625,7 +1625,7 @@ static void nv_do_rx_refill(unsigned long data) if (np->msi_flags & NV_MSI_X_ENABLED) enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - enable_irq(dev->irq); + enable_irq(np->pci_dev->irq); } else { enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); } @@ -3560,10 +3560,12 @@ static int nv_request_irq(struct net_device *dev, int intr_test) if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { if ((ret = pci_enable_msi(np->pci_dev)) == 0) { np->msi_flags |= NV_MSI_ENABLED; + dev->irq = np->pci_dev->irq; if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) { printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); pci_disable_msi(np->pci_dev); np->msi_flags &= ~NV_MSI_ENABLED; + dev->irq = np->pci_dev->irq; goto out_err; } @@ -3626,7 +3628,7 @@ static void nv_do_nic_poll(unsigned long data) if (np->msi_flags & NV_MSI_X_ENABLED) disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - disable_irq_lockdep(dev->irq); + disable_irq_lockdep(np->pci_dev->irq); mask = np->irqmask; } else { if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { @@ -3644,6 +3646,8 @@ static void nv_do_nic_poll(unsigned long data) } np->nic_poll_irq = 0; + /* disable_irq() contains synchronize_irq, thus no irq handler can run now */ + if (np->recover_error) { np->recover_error = 0; printk(KERN_INFO "forcedeth: MAC in recoverable error state\n"); @@ -3680,7 +3684,6 @@ static void nv_do_nic_poll(unsigned long data) } } - /* FIXME: Do we need synchronize_irq(dev->irq) here? */ writel(mask, base + NvRegIrqMask); pci_push(base); @@ -3693,7 +3696,7 @@ static void nv_do_nic_poll(unsigned long data) if (np->msi_flags & NV_MSI_X_ENABLED) enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - enable_irq_lockdep(dev->irq); + enable_irq_lockdep(np->pci_dev->irq); } else { if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { nv_nic_irq_rx(0, dev); @@ -4950,7 +4953,7 @@ static int nv_close(struct net_device *dev) #ifdef CONFIG_FORCEDETH_NAPI napi_disable(&np->napi); #endif - synchronize_irq(dev->irq); + synchronize_irq(np->pci_dev->irq); del_timer_sync(&np->oom_kick); del_timer_sync(&np->nic_poll); |