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>
This commit is contained in:
committed by
Jeff Garzik
parent
cda22aa94d
commit
99f252b097
@@ -66,6 +66,7 @@ VERSION 2.2LK <2005/01/25>
|
|||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
|
|
||||||
|
#include <asm/system.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
||||||
@@ -486,6 +487,7 @@ static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
|
|||||||
void __iomem *);
|
void __iomem *);
|
||||||
static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
|
static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
|
||||||
static void rtl8169_down(struct net_device *dev);
|
static void rtl8169_down(struct net_device *dev);
|
||||||
|
static void rtl8169_rx_clear(struct rtl8169_private *tp);
|
||||||
|
|
||||||
#ifdef CONFIG_R8169_NAPI
|
#ifdef CONFIG_R8169_NAPI
|
||||||
static int rtl8169_poll(struct net_device *dev, int *budget);
|
static int rtl8169_poll(struct net_device *dev, int *budget);
|
||||||
@@ -1751,17 +1753,11 @@ static int rtl8169_open(struct net_device *dev)
|
|||||||
{
|
{
|
||||||
struct rtl8169_private *tp = netdev_priv(dev);
|
struct rtl8169_private *tp = netdev_priv(dev);
|
||||||
struct pci_dev *pdev = tp->pci_dev;
|
struct pci_dev *pdev = tp->pci_dev;
|
||||||
int retval;
|
int retval = -ENOMEM;
|
||||||
|
|
||||||
|
|
||||||
rtl8169_set_rxbufsize(tp, dev);
|
rtl8169_set_rxbufsize(tp, dev);
|
||||||
|
|
||||||
retval =
|
|
||||||
request_irq(dev->irq, rtl8169_interrupt, IRQF_SHARED, dev->name, dev);
|
|
||||||
if (retval < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
retval = -ENOMEM;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rx and Tx desscriptors needs 256 bytes alignment.
|
* Rx and Tx desscriptors needs 256 bytes alignment.
|
||||||
* pci_alloc_consistent provides more.
|
* pci_alloc_consistent provides more.
|
||||||
@@ -1769,19 +1765,26 @@ static int rtl8169_open(struct net_device *dev)
|
|||||||
tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES,
|
tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES,
|
||||||
&tp->TxPhyAddr);
|
&tp->TxPhyAddr);
|
||||||
if (!tp->TxDescArray)
|
if (!tp->TxDescArray)
|
||||||
goto err_free_irq;
|
goto out;
|
||||||
|
|
||||||
tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES,
|
tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES,
|
||||||
&tp->RxPhyAddr);
|
&tp->RxPhyAddr);
|
||||||
if (!tp->RxDescArray)
|
if (!tp->RxDescArray)
|
||||||
goto err_free_tx;
|
goto err_free_tx_0;
|
||||||
|
|
||||||
retval = rtl8169_init_ring(dev);
|
retval = rtl8169_init_ring(dev);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto err_free_rx;
|
goto err_free_rx_1;
|
||||||
|
|
||||||
INIT_DELAYED_WORK(&tp->task, NULL);
|
INIT_DELAYED_WORK(&tp->task, NULL);
|
||||||
|
|
||||||
|
smp_mb();
|
||||||
|
|
||||||
|
retval = request_irq(dev->irq, rtl8169_interrupt, IRQF_SHARED,
|
||||||
|
dev->name, dev);
|
||||||
|
if (retval < 0)
|
||||||
|
goto err_release_ring_2;
|
||||||
|
|
||||||
rtl8169_hw_start(dev);
|
rtl8169_hw_start(dev);
|
||||||
|
|
||||||
rtl8169_request_timer(dev);
|
rtl8169_request_timer(dev);
|
||||||
@@ -1790,14 +1793,14 @@ static int rtl8169_open(struct net_device *dev)
|
|||||||
out:
|
out:
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
err_free_rx:
|
err_release_ring_2:
|
||||||
|
rtl8169_rx_clear(tp);
|
||||||
|
err_free_rx_1:
|
||||||
pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
|
pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
|
||||||
tp->RxPhyAddr);
|
tp->RxPhyAddr);
|
||||||
err_free_tx:
|
err_free_tx_0:
|
||||||
pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,
|
pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,
|
||||||
tp->TxPhyAddr);
|
tp->TxPhyAddr);
|
||||||
err_free_irq:
|
|
||||||
free_irq(dev->irq, dev);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user