diff options
author | Mike Ditto <mditto@google.com> | 2011-11-05 10:38:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-07 13:31:24 -0500 |
commit | 2a4e7a085fb44369c450c92cf8bd53b91f874a57 (patch) | |
tree | c96dd683da76b9698281521d249a11ece0ad59ea /drivers/net/ethernet | |
parent | f9c4082df59e43c6667db197a4fb3eb3286f3fc1 (diff) |
forcedeth: Acknowledge only interrupts that are being processed
This is to avoid a race, accidentally acknowledging an interrupt that
we didn't notice and won't immediately process. This is based solely
on code inspection; it is not known if there was an actual bug here.
Signed-off-by: David Decotigny <david.decotigny@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/nvidia/forcedeth.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 344cb5fa512d..b7cf4b6e15ec 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c | |||
@@ -3398,7 +3398,8 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) | |||
3398 | 3398 | ||
3399 | for (i = 0;; i++) { | 3399 | for (i = 0;; i++) { |
3400 | events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_TX_ALL; | 3400 | events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_TX_ALL; |
3401 | writel(NVREG_IRQ_TX_ALL, base + NvRegMSIXIrqStatus); | 3401 | writel(events, base + NvRegMSIXIrqStatus); |
3402 | netdev_dbg(dev, "tx irq events: %08x\n", events); | ||
3402 | if (!(events & np->irqmask)) | 3403 | if (!(events & np->irqmask)) |
3403 | break; | 3404 | break; |
3404 | 3405 | ||
@@ -3509,7 +3510,8 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) | |||
3509 | 3510 | ||
3510 | for (i = 0;; i++) { | 3511 | for (i = 0;; i++) { |
3511 | events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL; | 3512 | events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL; |
3512 | writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus); | 3513 | writel(events, base + NvRegMSIXIrqStatus); |
3514 | netdev_dbg(dev, "rx irq events: %08x\n", events); | ||
3513 | if (!(events & np->irqmask)) | 3515 | if (!(events & np->irqmask)) |
3514 | break; | 3516 | break; |
3515 | 3517 | ||
@@ -3553,7 +3555,8 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) | |||
3553 | 3555 | ||
3554 | for (i = 0;; i++) { | 3556 | for (i = 0;; i++) { |
3555 | events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_OTHER; | 3557 | events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_OTHER; |
3556 | writel(NVREG_IRQ_OTHER, base + NvRegMSIXIrqStatus); | 3558 | writel(events, base + NvRegMSIXIrqStatus); |
3559 | netdev_dbg(dev, "irq events: %08x\n", events); | ||
3557 | if (!(events & np->irqmask)) | 3560 | if (!(events & np->irqmask)) |
3558 | break; | 3561 | break; |
3559 | 3562 | ||
@@ -3617,10 +3620,10 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data) | |||
3617 | 3620 | ||
3618 | if (!(np->msi_flags & NV_MSI_X_ENABLED)) { | 3621 | if (!(np->msi_flags & NV_MSI_X_ENABLED)) { |
3619 | events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; | 3622 | events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; |
3620 | writel(NVREG_IRQ_TIMER, base + NvRegIrqStatus); | 3623 | writel(events & NVREG_IRQ_TIMER, base + NvRegIrqStatus); |
3621 | } else { | 3624 | } else { |
3622 | events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK; | 3625 | events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK; |
3623 | writel(NVREG_IRQ_TIMER, base + NvRegMSIXIrqStatus); | 3626 | writel(events & NVREG_IRQ_TIMER, base + NvRegMSIXIrqStatus); |
3624 | } | 3627 | } |
3625 | pci_push(base); | 3628 | pci_push(base); |
3626 | if (!(events & NVREG_IRQ_TIMER)) | 3629 | if (!(events & NVREG_IRQ_TIMER)) |