diff options
-rw-r--r-- | sys/arch/alpha/alpha/interrupt.c | 8 | ||||
-rw-r--r-- | sys/arch/alpha/dev/shared_intr.c | 10 | ||||
-rw-r--r-- | sys/arch/alpha/include/intr.h | 4 | ||||
-rw-r--r-- | sys/arch/alpha/pci/sio_pic.c | 4 | ||||
-rw-r--r-- | sys/arch/landisk/landisk/intr.c | 4 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/generic2e_machdep.c | 9 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/yeeloong_machdep.c | 9 | ||||
-rw-r--r-- | sys/arch/mvmeppc/dev/openpic.c | 6 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/intr_template.c | 9 |
9 files changed, 46 insertions, 17 deletions
diff --git a/sys/arch/alpha/alpha/interrupt.c b/sys/arch/alpha/alpha/interrupt.c index 3390277aba1..4fff2042e1e 100644 --- a/sys/arch/alpha/alpha/interrupt.c +++ b/sys/arch/alpha/alpha/interrupt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: interrupt.c,v 1.30 2010/12/21 14:56:23 claudio Exp $ */ +/* $OpenBSD: interrupt.c,v 1.31 2011/04/15 20:40:03 deraadt Exp $ */ /* $NetBSD: interrupt.c,v 1.46 2000/06/03 20:47:36 thorpej Exp $ */ /*- @@ -101,6 +101,12 @@ struct scbvec scb_iovectab[SCB_VECTOIDX(SCB_SIZE - SCB_IOVECBASE)]; void scb_stray(void *, u_long); +/* + * True if the system has any non-level interrupts which are shared + * on the same pin. + */ +int intr_shared_edge; + void scb_init(void) { diff --git a/sys/arch/alpha/dev/shared_intr.c b/sys/arch/alpha/dev/shared_intr.c index a0fdb4ca9b6..847541c8a9a 100644 --- a/sys/arch/alpha/dev/shared_intr.c +++ b/sys/arch/alpha/dev/shared_intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: shared_intr.c,v 1.17 2010/09/20 06:33:46 matthew Exp $ */ +/* $OpenBSD: shared_intr.c,v 1.18 2011/04/15 20:40:05 deraadt Exp $ */ /* $NetBSD: shared_intr.c,v 1.13 2000/03/19 01:46:18 thorpej Exp $ */ /* @@ -104,10 +104,12 @@ alpha_shared_intr_dispatch(intr, num) * -1: This interrupt might have been for me, but I can't say * for sure. */ - if ((rv = (*ih->ih_fn)(ih->ih_arg))) + rv = (*ih->ih_fn)(ih->ih_arg); + if (rv) ih->ih_count.ec_count++; - handled = handled || (rv != 0); + if (intr_shared_edge == 0 && rv == 1) + break; } return (handled); @@ -142,6 +144,8 @@ alpha_shared_intr_establish(intr, num, type, level, fn, arg, basename) switch (intr[num].intr_sharetype) { case IST_EDGE: + intr_shared_edge = 1; + /* FALLTHROUGH */ case IST_LEVEL: if (type == intr[num].intr_sharetype) break; diff --git a/sys/arch/alpha/include/intr.h b/sys/arch/alpha/include/intr.h index 29eae0d7006..03af2a9e156 100644 --- a/sys/arch/alpha/include/intr.h +++ b/sys/arch/alpha/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.38 2011/03/23 16:54:34 pirofti Exp $ */ +/* $OpenBSD: intr.h,v 1.39 2011/04/15 20:40:05 deraadt Exp $ */ /* $NetBSD: intr.h,v 1.26 2000/06/03 20:47:41 thorpej Exp $ */ /*- @@ -235,6 +235,8 @@ struct alpha_shared_intr { ((asi)[num].intr_maxstrays != 0 && \ (asi)[num].intr_nstrays == (asi)[num].intr_maxstrays) +extern int intr_shared_edge; + /* * simulated software interrupt register */ diff --git a/sys/arch/alpha/pci/sio_pic.c b/sys/arch/alpha/pci/sio_pic.c index 8b65a4638b3..9ae639cf39d 100644 --- a/sys/arch/alpha/pci/sio_pic.c +++ b/sys/arch/alpha/pci/sio_pic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sio_pic.c,v 1.31 2009/09/30 20:16:31 miod Exp $ */ +/* $OpenBSD: sio_pic.c,v 1.32 2011/04/15 20:40:05 deraadt Exp $ */ /* $NetBSD: sio_pic.c,v 1.28 2000/06/06 03:10:13 thorpej Exp $ */ /*- @@ -586,6 +586,8 @@ sio_intr_alloc(v, mask, type, irq) return (0); case IST_EDGE: + intr_shared_edge = 1; + /* FALLTHROUGH */ case IST_LEVEL: if (type != sio_intr[i].intr_sharetype) continue; diff --git a/sys/arch/landisk/landisk/intr.c b/sys/arch/landisk/landisk/intr.c index 59f35869a99..1410089540e 100644 --- a/sys/arch/landisk/landisk/intr.c +++ b/sys/arch/landisk/landisk/intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.c,v 1.6 2010/09/20 06:33:47 matthew Exp $ */ +/* $OpenBSD: intr.c,v 1.7 2011/04/15 20:40:07 deraadt Exp $ */ /* $NetBSD: intr.c,v 1.1 2006/09/01 21:26:18 uwe Exp $ */ /*- @@ -360,6 +360,8 @@ extintr_intr_handler(void *arg) r = (*ih->ih_fun)(ih->ih_arg); if (__predict_true(r != 0)) { ih->ih_count.ec_count++; + if (r == 1) + break; } } } diff --git a/sys/arch/loongson/loongson/generic2e_machdep.c b/sys/arch/loongson/loongson/generic2e_machdep.c index e08ccb1b260..f98d7ae034d 100644 --- a/sys/arch/loongson/loongson/generic2e_machdep.c +++ b/sys/arch/loongson/loongson/generic2e_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: generic2e_machdep.c,v 1.1 2010/05/08 21:59:56 miod Exp $ */ +/* $OpenBSD: generic2e_machdep.c,v 1.2 2011/04/15 20:40:06 deraadt Exp $ */ /* * Copyright (c) 2010 Miodrag Vallat. @@ -239,7 +239,7 @@ generic2e_isa_intr(uint32_t hwpend, struct trap_frame *frame) { struct intrhand *ih; uint64_t isr, mask = 0; - int rc, irq; + int rc, irq, ret; uint8_t ocw1, ocw2; extern uint loongson_isaimr; @@ -283,7 +283,8 @@ generic2e_isa_intr(uint32_t hwpend, struct trap_frame *frame) ih = ih->ih_next) { splraise(ih->ih_level); - if ((*ih->ih_fun)(ih->ih_arg) != 0) { + ret = (*ih->ih_fun)(ih->ih_arg); + if (ret) { rc = 1; ih->ih_count.ec_count++; } @@ -291,6 +292,8 @@ generic2e_isa_intr(uint32_t hwpend, struct trap_frame *frame) __asm__ (".set noreorder\n"); curcpu()->ci_ipl = frame->ipl; __asm__ ("sync\n\t.set reorder\n"); + if (ret == 1) + break; } /* Send a specific EOI to the 8259. */ diff --git a/sys/arch/loongson/loongson/yeeloong_machdep.c b/sys/arch/loongson/loongson/yeeloong_machdep.c index 17481469c93..eca1b5ce4d7 100644 --- a/sys/arch/loongson/loongson/yeeloong_machdep.c +++ b/sys/arch/loongson/loongson/yeeloong_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: yeeloong_machdep.c,v 1.15 2010/10/14 21:23:04 pirofti Exp $ */ +/* $OpenBSD: yeeloong_machdep.c,v 1.16 2011/04/15 20:40:06 deraadt Exp $ */ /* * Copyright (c) 2009, 2010 Miodrag Vallat. @@ -346,7 +346,7 @@ lemote_isa_intr(uint32_t hwpend, struct trap_frame *frame) * Now process allowed interrupts. */ if (isr != 0) { - int lvl, bitno; + int lvl, bitno, ret; uint64_t tmpisr; /* Service higher level interrupts first */ @@ -365,13 +365,16 @@ lemote_isa_intr(uint32_t hwpend, struct trap_frame *frame) for (ih = bonito_intrhand[BONITO_ISA_IRQ(bitno)]; ih != NULL; ih = ih->ih_next) { splraise(ih->ih_level); - if ((*ih->ih_fun)(ih->ih_arg) != 0) { + ret = (*ih->ih_fun)(ih->ih_arg); + if (ret) { rc = 1; ih->ih_count.ec_count++; } __asm__ (".set noreorder\n"); curcpu()->ci_ipl = frame->ipl; __asm__ ("sync\n\t.set reorder\n"); + if (ret == 1) + break; } if (rc == 0) printf("spurious isa interrupt %d\n", diff --git a/sys/arch/mvmeppc/dev/openpic.c b/sys/arch/mvmeppc/dev/openpic.c index b4220d0e07a..9fb92603221 100644 --- a/sys/arch/mvmeppc/dev/openpic.c +++ b/sys/arch/mvmeppc/dev/openpic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: openpic.c,v 1.23 2010/09/20 06:33:47 matthew Exp $ */ +/* $OpenBSD: openpic.c,v 1.24 2011/04/15 20:40:06 deraadt Exp $ */ /*- * Copyright (c) 1995 Per Fogelstrom @@ -291,6 +291,8 @@ i8259_intr_establish(lcv, irq, type, level, ih_fun, ih_arg, what) switch (intrtype[irq]) { case IST_EDGE: + intr_shared_edge = 1; + /* FALLTHROUGH */ case IST_LEVEL: if (type == intrtype[irq]) break; @@ -374,6 +376,8 @@ openpic_intr_establish(lcv, irq, type, level, ih_fun, ih_arg, what) switch (intrtype[irq]) { case IST_EDGE: + intr_shared_edge = 1; + /* FALLTHROUGH */ case IST_LEVEL: if (type == intrtype[irq]) break; diff --git a/sys/arch/sgi/sgi/intr_template.c b/sys/arch/sgi/sgi/intr_template.c index 1bec1c095a6..2f9f6e95b3e 100644 --- a/sys/arch/sgi/sgi/intr_template.c +++ b/sys/arch/sgi/sgi/intr_template.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr_template.c,v 1.10 2010/01/18 17:01:14 miod Exp $ */ +/* $OpenBSD: intr_template.c,v 1.11 2011/04/15 20:40:06 deraadt Exp $ */ /* * Copyright (c) 2009 Miodrag Vallat. @@ -103,7 +103,7 @@ INTR_FUNCTIONNAME(uint32_t hwpend, struct trap_frame *frame) int ipl; int bit; struct intrhand *ih; - int rc; + int rc, ret; INTR_LOCAL_DECLS INTR_GETMASKS; @@ -166,7 +166,8 @@ INTR_FUNCTIONNAME(uint32_t hwpend, struct trap_frame *frame) __mp_lock(&kernel_lock); } #endif - if ((*ih->ih_fun)(ih->ih_arg) != 0) { + ret = (*ih->ih_fun)(ih->ih_arg); + if (ret != 0) { rc = 1; atomic_add_uint64(&ih->ih_count.ec_count, 1); } @@ -180,6 +181,8 @@ INTR_FUNCTIONNAME(uint32_t hwpend, struct trap_frame *frame) __asm__ (".set noreorder\n"); ci->ci_ipl = ipl; __asm__ ("sync\n\t.set reorder\n"); + if (ret == 1) + break; } if (rc == 0) INTR_SPURIOUS(bitno); |