Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/powerpc/booke/pci When delivering MSIs, sometimes a...



details:   https://anonhg.NetBSD.org/src/rev/e46881a6847c
branches:  trunk
changeset: 765858:e46881a6847c
user:      matt <matt%NetBSD.org@localhost>
date:      Wed Jun 08 05:21:42 2011 +0000

description:
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.

diffstat:

 sys/arch/powerpc/booke/pci/pq3pci.c |  14 +++++++++++---
 1 files changed, 11 insertions(+), 3 deletions(-)

diffs (58 lines):

diff -r f752984ff365 -r e46881a6847c sys/arch/powerpc/booke/pci/pq3pci.c
--- a/sys/arch/powerpc/booke/pci/pq3pci.c       Wed Jun 08 05:13:00 2011 +0000
+++ b/sys/arch/powerpc/booke/pci/pq3pci.c       Wed Jun 08 05:21:42 2011 +0000
@@ -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;
                }
        }
 }



Home | Main Index | Thread Index | Old Index