diff options
author | Ayaz Abdulla <aabdulla@nvidia.com> | 2009-03-05 03:02:34 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-03-10 08:29:51 -0400 |
commit | 1b2bb76f575699eff3f58b18dcfebf5d3b1f6ddb (patch) | |
tree | 19f8327f23dd7137b3b67588b3484d6f8dc62ade /drivers/net/forcedeth.c | |
parent | 6cef67a02f7994c97dbd716dbeb592265fb5b7b0 (diff) |
forcedeth: fix irq clearing and napi spin lock changes
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>
Diffstat (limited to 'drivers/net/forcedeth.c')
-rw-r--r-- | drivers/net/forcedeth.c | 18 |
1 files changed, 4 insertions, 14 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 28fc3357268a..514aaf189af9 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -3464,10 +3464,10 @@ static irqreturn_t nv_nic_irq(int foo, void *data) | |||
3464 | 3464 | ||
3465 | if (!(np->msi_flags & NV_MSI_X_ENABLED)) { | 3465 | if (!(np->msi_flags & NV_MSI_X_ENABLED)) { |
3466 | np->events = readl(base + NvRegIrqStatus); | 3466 | np->events = readl(base + NvRegIrqStatus); |
3467 | writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); | 3467 | writel(np->events, base + NvRegIrqStatus); |
3468 | } else { | 3468 | } else { |
3469 | np->events = readl(base + NvRegMSIXIrqStatus); | 3469 | np->events = readl(base + NvRegMSIXIrqStatus); |
3470 | writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus); | 3470 | writel(np->events, base + NvRegMSIXIrqStatus); |
3471 | } | 3471 | } |
3472 | dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events); | 3472 | dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events); |
3473 | if (!(np->events & np->irqmask)) | 3473 | if (!(np->events & np->irqmask)) |
@@ -3476,15 +3476,12 @@ static irqreturn_t nv_nic_irq(int foo, void *data) | |||
3476 | nv_msi_workaround(np); | 3476 | nv_msi_workaround(np); |
3477 | 3477 | ||
3478 | #ifdef CONFIG_FORCEDETH_NAPI | 3478 | #ifdef CONFIG_FORCEDETH_NAPI |
3479 | spin_lock(&np->lock); | ||
3480 | napi_schedule(&np->napi); | 3479 | napi_schedule(&np->napi); |
3481 | 3480 | ||
3482 | /* Disable furthur irq's | 3481 | /* Disable furthur irq's |
3483 | (msix not enabled with napi) */ | 3482 | (msix not enabled with napi) */ |
3484 | writel(0, base + NvRegIrqMask); | 3483 | writel(0, base + NvRegIrqMask); |
3485 | 3484 | ||
3486 | spin_unlock(&np->lock); | ||
3487 | |||
3488 | #else | 3485 | #else |
3489 | do | 3486 | do |
3490 | { | 3487 | { |
@@ -3568,10 +3565,10 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) | |||
3568 | 3565 | ||
3569 | if (!(np->msi_flags & NV_MSI_X_ENABLED)) { | 3566 | if (!(np->msi_flags & NV_MSI_X_ENABLED)) { |
3570 | np->events = readl(base + NvRegIrqStatus); | 3567 | np->events = readl(base + NvRegIrqStatus); |
3571 | writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); | 3568 | writel(np->events, base + NvRegIrqStatus); |
3572 | } else { | 3569 | } else { |
3573 | np->events = readl(base + NvRegMSIXIrqStatus); | 3570 | np->events = readl(base + NvRegMSIXIrqStatus); |
3574 | writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus); | 3571 | writel(np->events, base + NvRegMSIXIrqStatus); |
3575 | } | 3572 | } |
3576 | dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events); | 3573 | dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events); |
3577 | if (!(np->events & np->irqmask)) | 3574 | if (!(np->events & np->irqmask)) |
@@ -3580,15 +3577,12 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) | |||
3580 | nv_msi_workaround(np); | 3577 | nv_msi_workaround(np); |
3581 | 3578 | ||
3582 | #ifdef CONFIG_FORCEDETH_NAPI | 3579 | #ifdef CONFIG_FORCEDETH_NAPI |
3583 | spin_lock(&np->lock); | ||
3584 | napi_schedule(&np->napi); | 3580 | napi_schedule(&np->napi); |
3585 | 3581 | ||
3586 | /* Disable furthur irq's | 3582 | /* Disable furthur irq's |
3587 | (msix not enabled with napi) */ | 3583 | (msix not enabled with napi) */ |
3588 | writel(0, base + NvRegIrqMask); | 3584 | writel(0, base + NvRegIrqMask); |
3589 | 3585 | ||
3590 | spin_unlock(&np->lock); | ||
3591 | |||
3592 | #else | 3586 | #else |
3593 | do | 3587 | do |
3594 | { | 3588 | { |
@@ -3758,13 +3752,9 @@ static int nv_napi_poll(struct napi_struct *napi, int budget) | |||
3758 | if (rx_work < budget) { | 3752 | if (rx_work < budget) { |
3759 | /* re-enable interrupts | 3753 | /* re-enable interrupts |
3760 | (msix not enabled in napi) */ | 3754 | (msix not enabled in napi) */ |
3761 | spin_lock_irqsave(&np->lock, flags); | ||
3762 | |||
3763 | __napi_complete(napi); | 3755 | __napi_complete(napi); |
3764 | 3756 | ||
3765 | writel(np->irqmask, base + NvRegIrqMask); | 3757 | writel(np->irqmask, base + NvRegIrqMask); |
3766 | |||
3767 | spin_unlock_irqrestore(&np->lock, flags); | ||
3768 | } | 3758 | } |
3769 | return rx_work; | 3759 | return rx_work; |
3770 | } | 3760 | } |