diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2007-03-22 18:52:40 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2007-03-22 18:52:40 +0000 |
commit | 4d61b5e3dbeedaff83e17a67a8651f909ded1f4f (patch) | |
tree | 057f8beefee3ccbcfa29370fd63a7a3d1ae8a2b7 /sys | |
parent | 5128ea1357dba8a3d22c04ee1d722d79940194c9 (diff) |
When registering VME interrupts, maintain a direct ipl->vector table, as long
as no more than one interrupt is registered for a given level.
Then, if the VME interrupt vector reading cycle fails on the 188 interrupt
arbiter, we can use this table as a hint if it has a valid entry, since
we know on which ipl line the interrupt occured.
This basically silences the
m188_ext_int: timeout getting VME interrupt vector, level 3, mask 0x400<IRQ3>
occasional messages appearing when the MVME376 is overloaded.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/mvme88k/dev/vme.c | 32 | ||||
-rw-r--r-- | sys/arch/mvme88k/include/cpu.h | 11 | ||||
-rw-r--r-- | sys/arch/mvme88k/mvme88k/m188_machdep.c | 25 |
3 files changed, 57 insertions, 11 deletions
diff --git a/sys/arch/mvme88k/dev/vme.c b/sys/arch/mvme88k/dev/vme.c index ded1048ada3..b50ba20db04 100644 --- a/sys/arch/mvme88k/dev/vme.c +++ b/sys/arch/mvme88k/dev/vme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vme.c,v 1.45 2006/11/16 23:21:56 miod Exp $ */ +/* $OpenBSD: vme.c,v 1.46 2007/03/22 18:52:38 miod Exp $ */ /* * Copyright (c) 2004, Miodrag Vallat. * Copyright (c) 1999 Steve Murphree, Jr. @@ -431,6 +431,18 @@ vmerw(sc, uio, flags, bus) return error; } +#ifdef MVME188 +/* + * Currently registered VME interrupt vectors for a given IPL, if they + * are unique. Used to help the MVME188 interrupt handler when it's getting + * behind. + */ +u_int vmevec_hints[8] = { + (u_int)-1, (u_int)-1, (u_int)-1, (u_int)-1, + (u_int)-1, (u_int)-1, (u_int)-1, (u_int)-1 +}; +#endif + /* * On the VMEbus, only one cpu may be configured to respond to any * particular vme ipl. Therefore, it wouldn't make sense to globally @@ -448,6 +460,12 @@ int vmeintr_establish(int vec, struct intrhand *ih, const char *name) { struct vmesoftc *sc = (struct vmesoftc *) vme_cd.cd_devs[0]; + int rc; + +#ifdef DIAGNOSTIC + if (ih->ih_ipl < 1 || ih->ih_ipl > 7) + return (EINVAL); +#endif switch (vmebustype) { #if NPCCTWO > 0 @@ -459,7 +477,17 @@ vmeintr_establish(int vec, struct intrhand *ih, const char *name) #endif } - return intr_establish(vec, ih, name); + if ((rc = intr_establish(vec, ih, name)) != 0) + return (rc); + +#ifdef MVME188 + if (vmevec_hints[ih->ih_ipl] == (u_int)-1) + vmevec_hints[ih->ih_ipl] = vec; + else + vmevec_hints[ih->ih_ipl] = (u_int)-1; +#endif + + return (0); } #if NPCCTWO > 0 diff --git a/sys/arch/mvme88k/include/cpu.h b/sys/arch/mvme88k/include/cpu.h index fdf59bb1744..0ae4bdd0425 100644 --- a/sys/arch/mvme88k/include/cpu.h +++ b/sys/arch/mvme88k/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.35 2006/05/13 16:05:50 miod Exp $ */ +/* $OpenBSD: cpu.h,v 1.36 2007/03/22 18:52:39 miod Exp $ */ /* * Copyright (c) 1996 Nivas Madhur * Copyright (c) 1992, 1993 @@ -75,6 +75,15 @@ int intr_findvec(int, int, int); typedef SLIST_HEAD(, intrhand) intrhand_t; extern intrhand_t intr_handlers[NVMEINTR]; +#ifdef MVME188 +/* + * Currently registered VME interrupt vectors for a given IPL, if they + * are unique. Used to help the MVME188 interrupt handler when it's getting + * behind. + */ +extern u_int vmevec_hints[8]; +#endif + void doboot(void); void nmihand(void *); diff --git a/sys/arch/mvme88k/mvme88k/m188_machdep.c b/sys/arch/mvme88k/mvme88k/m188_machdep.c index 0054975cfe2..a23cb78938a 100644 --- a/sys/arch/mvme88k/mvme88k/m188_machdep.c +++ b/sys/arch/mvme88k/mvme88k/m188_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: m188_machdep.c,v 1.24 2006/11/20 21:51:33 miod Exp $ */ +/* $OpenBSD: m188_machdep.c,v 1.25 2007/03/22 18:52:39 miod Exp $ */ /* * Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr. * Copyright (c) 1996 Nivas Madhur @@ -478,13 +478,22 @@ m188_ext_int(u_int v, struct trapframe *eframe) */ { - printf("%s: timeout getting VME " - "interrupt vector, " - "level %d, mask 0x%b\n", - __func__, level, - cur_mask, IST_STRING); - ign_mask |= 1 << intbit; - continue; + /* + * If only one VME interrupt is + * registered with this IPL, + * we can reasonably safely + * assume that this is our vector. + */ + vec = vmevec_hints[level]; + if (vec == (u_int)-1) { + printf("%s: timeout getting VME" + " interrupt vector, " + "level %d, mask 0x%b\n", + __func__, level, + cur_mask, IST_STRING); + ign_mask |= 1 << intbit; + continue; + } } } if (vec == 0) { |