[TG3]: Flush status block in tg3_interrupt()

Linux Kernel Mailing List <[email protected]> Wed, 23 Mar 2005 19:05:37 +0000
Newsgroups gmane.linux.kernel.commits.2-4
Message-ID <[email protected]>
ChangeSet 1.1448.127.9, 2005/03/23 11:05:37-08:00, [email protected]

	[TG3]: Flush status block in tg3_interrupt()
	
	Add register read of PCI state register in tg3_interrupt() if status block's
	updated bit is not set. This will flush the status block and confirm whether
	the interrupt is ours or not. PCI ordering rules allow the interrupt to
	arrive at the CPU ahead of the status block that may be posted at the
	chipset.
	
	Signed-off-by: Michael Chan <[email protected]>
	ACKed-by: Jeff Garzik <[email protected]>
	Signed-off-by: David S. Miller <[email protected]>



 tg3.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletion(-)


diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c
--- a/drivers/net/tg3.c	2005-03-25 17:03:34 -08:00
+++ b/drivers/net/tg3.c	2005-03-25 17:03:34 -08:00
@@ -2868,7 +2868,13 @@
 
 	spin_lock_irqsave(&tp->lock, flags);
 
-	if (sblk->status & SD_STATUS_UPDATED) {
+	/* In INTx mode, it is possible for the interrupt to arrive at
+	 * the CPU before the status block posted prior to the interrupt.
+	 * Reading the PCI State register will confirm whether the
+	 * interrupt is ours and will flush the status block.
+	 */
+	if ((sblk->status & SD_STATUS_UPDATED) ||
+	    !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
 		/*
 		 * writing any value to intr-mbox-0 clears PCI INTA# and
 		 * chip-internal interrupt pending events.