forcedeth: fix irq clearing and napi spin lock changes
authorAyaz Abdulla <aabdulla@nvidia.com>
Thu, 5 Mar 2009 08:02:34 +0000 (08:02 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 10 Mar 2009 12:29:51 +0000 (05:29 -0700)
This patch clears the irqstatus register with the exact same events it
has read from it. Since the read-write operation is not atomic, a new
irqstatus bit could have been set in between these operations and would
then be cleared accidentally.

Secondly, we now don't need any spin lock protection when
scheduling/completing napi poll as the isr will not execute anymore (as
we turn off all interrupts now).

Signed-off-by: Ayaz Abdulla <aabdulla@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/forcedeth.c

index 28fc3357268a7c3a6fa67c9929c94cde87e18e13..514aaf189af98f24a65411a56bb600943206827c 100644 (file)
@@ -3464,10 +3464,10 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
 
        if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
                np->events = readl(base + NvRegIrqStatus);
-               writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
+               writel(np->events, base + NvRegIrqStatus);
        } else {
                np->events = readl(base + NvRegMSIXIrqStatus);
-               writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
+               writel(np->events, base + NvRegMSIXIrqStatus);
        }
        dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
        if (!(np->events & np->irqmask))
@@ -3476,15 +3476,12 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
        nv_msi_workaround(np);
 
 #ifdef CONFIG_FORCEDETH_NAPI
-       spin_lock(&np->lock);
        napi_schedule(&np->napi);
 
        /* Disable furthur irq's
           (msix not enabled with napi) */
        writel(0, base + NvRegIrqMask);
 
-       spin_unlock(&np->lock);
-
 #else
        do
        {
@@ -3568,10 +3565,10 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
 
        if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
                np->events = readl(base + NvRegIrqStatus);
-               writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
+               writel(np->events, base + NvRegIrqStatus);
        } else {
                np->events = readl(base + NvRegMSIXIrqStatus);
-               writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
+               writel(np->events, base + NvRegMSIXIrqStatus);
        }
        dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
        if (!(np->events & np->irqmask))
@@ -3580,15 +3577,12 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
        nv_msi_workaround(np);
 
 #ifdef CONFIG_FORCEDETH_NAPI
-       spin_lock(&np->lock);
        napi_schedule(&np->napi);
 
        /* Disable furthur irq's
           (msix not enabled with napi) */
        writel(0, base + NvRegIrqMask);
 
-       spin_unlock(&np->lock);
-
 #else
        do
        {
@@ -3758,13 +3752,9 @@ static int nv_napi_poll(struct napi_struct *napi, int budget)
        if (rx_work < budget) {
                /* re-enable interrupts
                   (msix not enabled in napi) */
-               spin_lock_irqsave(&np->lock, flags);
-
                __napi_complete(napi);
 
                writel(np->irqmask, base + NvRegIrqMask);
-
-               spin_unlock_irqrestore(&np->lock, flags);
        }
        return rx_work;
 }