aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorFrancois Romieu <romieu@fr.zoreil.com>2007-04-02 16:59:59 -0400
committerJeff Garzik <jeff@garzik.org>2007-04-03 22:31:10 -0400
commit99f252b097a3bd6280047ba2175b605671da4a23 (patch)
tree7fe5ce38a500ea390f133027afa2ca1dd3d009fb /drivers/net
parentcda22aa94d3fe3942476b3652b8b92c653b96ee3 (diff)
r8169: issue request_irq after the private data are completely initialized
The irq handler schedules a NAPI poll request unconditionally as soon as the status register is not clean. It has been there - and wrong - for ages but a recent timing change made it apparently easier to trigger. Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> Cc: Jay Cliburn <jacliburn@bellsouth.net> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/r8169.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 521b5f0618a4..60f630e84bf0 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -66,6 +66,7 @@ VERSION 2.2LK <2005/01/25>
66#include <linux/init.h> 66#include <linux/init.h>
67#include <linux/dma-mapping.h> 67#include <linux/dma-mapping.h>
68 68
69#include <asm/system.h>
69#include <asm/io.h> 70#include <asm/io.h>
70#include <asm/irq.h> 71#include <asm/irq.h>
71 72
@@ -486,6 +487,7 @@ static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
486 void __iomem *); 487 void __iomem *);
487static int rtl8169_change_mtu(struct net_device *dev, int new_mtu); 488static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
488static void rtl8169_down(struct net_device *dev); 489static void rtl8169_down(struct net_device *dev);
490static void rtl8169_rx_clear(struct rtl8169_private *tp);
489 491
490#ifdef CONFIG_R8169_NAPI 492#ifdef CONFIG_R8169_NAPI
491static int rtl8169_poll(struct net_device *dev, int *budget); 493static int rtl8169_poll(struct net_device *dev, int *budget);
@@ -1751,16 +1753,10 @@ static int rtl8169_open(struct net_device *dev)
1751{ 1753{
1752 struct rtl8169_private *tp = netdev_priv(dev); 1754 struct rtl8169_private *tp = netdev_priv(dev);
1753 struct pci_dev *pdev = tp->pci_dev; 1755 struct pci_dev *pdev = tp->pci_dev;
1754 int retval; 1756 int retval = -ENOMEM;
1755 1757
1756 rtl8169_set_rxbufsize(tp, dev);
1757
1758 retval =
1759 request_irq(dev->irq, rtl8169_interrupt, IRQF_SHARED, dev->name, dev);
1760 if (retval < 0)
1761 goto out;
1762 1758
1763 retval = -ENOMEM; 1759 rtl8169_set_rxbufsize(tp, dev);
1764 1760
1765 /* 1761 /*
1766 * Rx and Tx desscriptors needs 256 bytes alignment. 1762 * Rx and Tx desscriptors needs 256 bytes alignment.
@@ -1769,19 +1765,26 @@ static int rtl8169_open(struct net_device *dev)
1769 tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES, 1765 tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES,
1770 &tp->TxPhyAddr); 1766 &tp->TxPhyAddr);
1771 if (!tp->TxDescArray) 1767 if (!tp->TxDescArray)
1772 goto err_free_irq; 1768 goto out;
1773 1769
1774 tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES, 1770 tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES,
1775 &tp->RxPhyAddr); 1771 &tp->RxPhyAddr);
1776 if (!tp->RxDescArray) 1772 if (!tp->RxDescArray)
1777 goto err_free_tx; 1773 goto err_free_tx_0;
1778 1774
1779 retval = rtl8169_init_ring(dev); 1775 retval = rtl8169_init_ring(dev);
1780 if (retval < 0) 1776 if (retval < 0)
1781 goto err_free_rx; 1777 goto err_free_rx_1;
1782 1778
1783 INIT_DELAYED_WORK(&tp->task, NULL); 1779 INIT_DELAYED_WORK(&tp->task, NULL);
1784 1780
1781 smp_mb();
1782
1783 retval = request_irq(dev->irq, rtl8169_interrupt, IRQF_SHARED,
1784 dev->name, dev);
1785 if (retval < 0)
1786 goto err_release_ring_2;
1787
1785 rtl8169_hw_start(dev); 1788 rtl8169_hw_start(dev);
1786 1789
1787 rtl8169_request_timer(dev); 1790 rtl8169_request_timer(dev);
@@ -1790,14 +1793,14 @@ static int rtl8169_open(struct net_device *dev)
1790out: 1793out:
1791 return retval; 1794 return retval;
1792 1795
1793err_free_rx: 1796err_release_ring_2:
1797 rtl8169_rx_clear(tp);
1798err_free_rx_1:
1794 pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, 1799 pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
1795 tp->RxPhyAddr); 1800 tp->RxPhyAddr);
1796err_free_tx: 1801err_free_tx_0:
1797 pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, 1802 pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,
1798 tp->TxPhyAddr); 1803 tp->TxPhyAddr);
1799err_free_irq:
1800 free_irq(dev->irq, dev);
1801 goto out; 1804 goto out;
1802} 1805}
1803 1806