Module Name:    src
Committed By:   matt
Date:           Wed Jun  8 05:21:42 UTC 2011

Modified Files:
        src/sys/arch/powerpc/booke/pci: pq3pci.c

Log Message:
When delivering MSIs, sometimes after clearing the MSI but before the interrupt
routine get called the MSI reasserts and we loop around and would detect a
spurious interrupt.

So now we keep track of the interrupts we have serviced successfully for this
dispatch loop.  If we have to invoke an interrupt handler and that handler
indicates nothing was serviced, if we previously serviced it it isn't counter
as a spurious interrupt.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/powerpc/booke/pci/pq3pci.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/powerpc/booke/pci/pq3pci.c
diff -u src/sys/arch/powerpc/booke/pci/pq3pci.c:1.6 src/sys/arch/powerpc/booke/pci/pq3pci.c:1.7
--- src/sys/arch/powerpc/booke/pci/pq3pci.c:1.6	Tue May 17 17:34:51 2011
+++ src/sys/arch/powerpc/booke/pci/pq3pci.c	Wed Jun  8 05:21:42 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: pq3pci.c,v 1.6 2011/05/17 17:34:51 dyoung Exp $	*/
+/*	$NetBSD: pq3pci.c,v 1.7 2011/06/08 05:21:42 matt Exp $	*/
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -44,7 +44,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: pq3pci.c,v 1.6 2011/05/17 17:34:51 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pq3pci.c,v 1.7 2011/06/08 05:21:42 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -509,6 +509,7 @@
 	mutex_spin_enter(msig->msig_lock);
 	KASSERT(curcpu()->ci_cpl == msig->msig_ipl);
 	//KASSERT(curcpu()->ci_idepth == 0);
+	uint32_t matches = 0;
 	for (int rv = 0;;) {
 		uint32_t group = cpu_read_4(msig->msig_msir);
 		if (group == 0) {
@@ -522,6 +523,10 @@
 			/*
 			 * if MSIs are working, just clear the free MSIs.
 			 */
+			KASSERTMSG((group & msig->msig_free_mask) == 0,
+			   ("%s: group#%u: unexpected MSIs (%#x)",
+			    __func__, msig->msig_group,
+			    group & msig->msig_free_mask));
 			group &= ~msig->msig_free_mask;
 		} else {
 			/*
@@ -538,6 +543,7 @@
 			}
 			group = ~msig->msig_free_mask;
 		}
+		uint32_t this_msi = __BIT(31);
 		for (struct pq3pci_msihand *msih = msig->msig_ihands + 31;
 		     group != 0;
 		     msih--) {
@@ -550,9 +556,11 @@
 			if ((*msih->msih_ih.ih_func)(msih->msih_ih.ih_arg)) {
 				rv = 1;
 				msih->msih_ev.ev_count += !working_msi_p;
-			} else {
+				matches |= this_msi;
+			} else if ((matches & this_msi) == 0) {
 				msih->msih_ev_spurious.ev_count += working_msi_p;
 			}
+			this_msi >>= n + 1;
 		}
 	}
 }

Reply via email to