Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 99f252b0 authored by Francois Romieu's avatar Francois Romieu Committed by Jeff Garzik
Browse files

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: default avatarFrancois Romieu <romieu@fr.zoreil.com>
Cc: Jay Cliburn <jacliburn@bellsouth.net>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent cda22aa9
Loading
Loading
Loading
Loading
+18 −15
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ VERSION 2.2LK <2005/01/25>
#include <linux/init.h>
#include <linux/dma-mapping.h>

#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>

@@ -486,6 +487,7 @@ static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
				void __iomem *);
static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
static void rtl8169_down(struct net_device *dev);
static void rtl8169_rx_clear(struct rtl8169_private *tp);

#ifdef CONFIG_R8169_NAPI
static int rtl8169_poll(struct net_device *dev, int *budget);
@@ -1751,16 +1753,10 @@ static int rtl8169_open(struct net_device *dev)
{
	struct rtl8169_private *tp = netdev_priv(dev);
	struct pci_dev *pdev = tp->pci_dev;
	int retval;
	int retval = -ENOMEM;

	rtl8169_set_rxbufsize(tp, dev);

	retval =
	    request_irq(dev->irq, rtl8169_interrupt, IRQF_SHARED, dev->name, dev);
	if (retval < 0)
		goto out;

	retval = -ENOMEM;
	rtl8169_set_rxbufsize(tp, dev);

	/*
	 * Rx and Tx desscriptors needs 256 bytes alignment.
@@ -1769,19 +1765,26 @@ static int rtl8169_open(struct net_device *dev)
	tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES,
					       &tp->TxPhyAddr);
	if (!tp->TxDescArray)
		goto err_free_irq;
		goto out;

	tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES,
					       &tp->RxPhyAddr);
	if (!tp->RxDescArray)
		goto err_free_tx;
		goto err_free_tx_0;

	retval = rtl8169_init_ring(dev);
	if (retval < 0)
		goto err_free_rx;
		goto err_free_rx_1;

	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_request_timer(dev);
@@ -1790,14 +1793,14 @@ static int rtl8169_open(struct net_device *dev)
out:
	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,
			    tp->RxPhyAddr);
err_free_tx:
err_free_tx_0:
	pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,
			    tp->TxPhyAddr);
err_free_irq:
	free_irq(dev->irq, dev);
	goto out;
}