Commit 2a4e7a085fb44369c450c92cf8bd53b91f874a57
Committed by
David S. Miller
1 parent
f9c4082df5
Exists in
master
and in
6 other branches
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>
Showing 1 changed file with 8 additions and 5 deletions Side-by-side Diff
drivers/net/ethernet/nvidia/forcedeth.c
... | ... | @@ -3398,7 +3398,8 @@ |
3398 | 3398 | |
3399 | 3399 | for (i = 0;; i++) { |
3400 | 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 | 3403 | if (!(events & np->irqmask)) |
3403 | 3404 | break; |
3404 | 3405 | |
... | ... | @@ -3509,7 +3510,8 @@ |
3509 | 3510 | |
3510 | 3511 | for (i = 0;; i++) { |
3511 | 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 | 3515 | if (!(events & np->irqmask)) |
3514 | 3516 | break; |
3515 | 3517 | |
... | ... | @@ -3553,7 +3555,8 @@ |
3553 | 3555 | |
3554 | 3556 | for (i = 0;; i++) { |
3555 | 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 | 3560 | if (!(events & np->irqmask)) |
3558 | 3561 | break; |
3559 | 3562 | |
3560 | 3563 | |
... | ... | @@ -3617,10 +3620,10 @@ |
3617 | 3620 | |
3618 | 3621 | if (!(np->msi_flags & NV_MSI_X_ENABLED)) { |
3619 | 3622 | events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK; |
3620 | - writel(NVREG_IRQ_TIMER, base + NvRegIrqStatus); | |
3623 | + writel(events & NVREG_IRQ_TIMER, base + NvRegIrqStatus); | |
3621 | 3624 | } else { |
3622 | 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 | 3628 | pci_push(base); |
3626 | 3629 | if (!(events & NVREG_IRQ_TIMER)) |