diff options
author | 2015-02-18 22:42:04 +0000 | |
---|---|---|
committer | 2015-02-18 22:42:04 +0000 | |
commit | 3471ae31a7e1139d582d50aa079616e338bf945c (patch) | |
tree | 21ed952ae9da6b8a5f6b8356ab0353c95786ddb1 | |
parent | convert calloc/realloc pairs to reallocarray (diff) | |
download | wireguard-openbsd-3471ae31a7e1139d582d50aa079616e338bf945c.tar.xz wireguard-openbsd-3471ae31a7e1139d582d50aa079616e338bf945c.zip |
Some modifications on cbus(4):
- Handle interrupt priority level (IPL_XXX) in cbus_isrdispatch().
- Add a function that returns the status of registered cbus(4) interrupt
levels.
suggestions and ok miod@
-rw-r--r-- | sys/arch/luna88k/cbus/cbus.c | 79 | ||||
-rw-r--r-- | sys/arch/luna88k/cbus/cbusvar.h | 7 | ||||
-rw-r--r-- | sys/arch/luna88k/cbus/necsb.c | 5 | ||||
-rw-r--r-- | sys/arch/luna88k/cbus/pcex.c | 4 |
4 files changed, 61 insertions, 34 deletions
diff --git a/sys/arch/luna88k/cbus/cbus.c b/sys/arch/luna88k/cbus/cbus.c index 150c5e24aa6..82408c07366 100644 --- a/sys/arch/luna88k/cbus/cbus.c +++ b/sys/arch/luna88k/cbus/cbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cbus.c,v 1.3 2014/12/31 11:38:27 aoyama Exp $ */ +/* $OpenBSD: cbus.c,v 1.4 2015/02/18 22:42:04 aoyama Exp $ */ /* * Copyright (c) 2014 Kenji Aoyama. @@ -71,8 +71,6 @@ struct cfdriver cbus_cd = { }; /* prototypes */ -int cbus_isrlink(int (*)(void *), void *, int, const char *); -int cbus_isrunlink(int (*)(void *), int); void cbus_isrdispatch(int); int cbus_intr(void *); @@ -101,10 +99,11 @@ cbus_attach(struct device *parent, struct device *self, void *args) struct cbus_isr_t *ci = &sc->cbus_isr[i]; ci->isr_func = NULL; ci->isr_arg = NULL; - ci->isr_intlevel = -1; + ci->isr_intlevel = ci->isr_ipl = -1; /* clearing interrupt flags (INT0-INT6) */ - *cbus_isreg = (u_int8_t)i; + *cbus_isreg = (u_int8_t)(6 - i); } + sc->registered = 0x00; /* register C-bus interrupt service routine on mainbus */ isrlink_autovec(cbus_intr, (void *)self, ma->ma_ilvl, @@ -135,7 +134,8 @@ cbus_print(void *aux, const char *pnp) * Register a C-bus interrupt service routine. */ int -cbus_isrlink(int (*func)(void *), void *arg, int ipl, const char *name) +cbus_isrlink(int (*func)(void *), void *arg, int intlevel, int ipl, + const char *name) { struct cbus_softc *sc = NULL; struct cbus_isr_t *ci; @@ -146,25 +146,27 @@ cbus_isrlink(int (*func)(void *), void *arg, int ipl, const char *name) panic("cbus_isrlink: can't find cbus_softc"); #ifdef DIAGNOSTIC - if (ipl < 0 || ipl >= NCBUSISR) { - printf("cbus_isrlink: bad ipl %d\n", ipl); + if (intlevel < 0 || intlevel >= NCBUSISR) { + printf("cbus_isrlink: bad INT level %d\n", intlevel); return -1; } #endif - ci = &sc->cbus_isr[ipl]; + ci = &sc->cbus_isr[intlevel]; if (ci->isr_func != NULL) { - printf("cbus_isrlink: isr already assigned on INT%d\n", ipl); + printf("cbus_isrlink: isr already assigned on INT%d\n", + intlevel); return -1; } /* set the entry */ ci->isr_func = func; ci->isr_arg = arg; - ci->isr_intlevel = ipl; + ci->isr_intlevel = intlevel; + ci->isr_ipl = ipl; evcount_attach(&ci->isr_count, name, &ci->isr_intlevel); - sc->registered |= (1 << (6 - ipl)); + sc->registered |= (1 << (6 - intlevel)); #ifdef CBUS_DEBUG printf("cbus_isrlink: sc->registered = 0x%02x\n", sc->registered); #endif @@ -176,7 +178,7 @@ cbus_isrlink(int (*func)(void *), void *arg, int ipl, const char *name) * Unregister a C-bus interrupt service routine. */ int -cbus_isrunlink(int (*func)(void *), int ipl) +cbus_isrunlink(int (*func)(void *), int intlevel) { struct cbus_softc *sc = NULL; struct cbus_isr_t *ci; @@ -187,25 +189,28 @@ cbus_isrunlink(int (*func)(void *), int ipl) panic("cbus_isrunlink: can't find cbus_softc"); #ifdef DIAGNOSTIC - if (ipl < 0 || ipl >= NCBUSISR) { - printf("cbus_isrunlink: bad ipl %d\n", ipl); + if (intlevel < 0 || intlevel >= NCBUSISR) { + printf("cbus_isrunlink: bad INT level %d\n", intlevel); return -1; } #endif - ci = &sc->cbus_isr[ipl]; + ci = &sc->cbus_isr[intlevel]; if (ci->isr_func == NULL) { - printf("cbus_isrunlink: isr not assigned on INT%d\n", ipl); + printf("cbus_isrunlink: isr not assigned on INT%d\n", intlevel); return -1; } /* reset the entry */ ci->isr_func = NULL; ci->isr_arg = NULL; - ci->isr_intlevel = -1; + ci->isr_intlevel = ci->isr_ipl = -1; evcount_detach(&ci->isr_count); - sc->registered &= ~(1 << (6 - ipl)); + sc->registered &= ~(1 << (6 - intlevel)); + + /* clear interrupt flags */ + *cbus_isreg = (u_int8_t)(6 - intlevel); #ifdef CBUS_DEBUG printf("cbus_isrunlink: sc->registered = 0x%02x\n", sc->registered); #endif @@ -217,9 +222,9 @@ cbus_isrunlink(int (*func)(void *), int ipl) * Dispatch C-bus interrupt service routines. */ void -cbus_isrdispatch(int ipl) +cbus_isrdispatch(int intlevel) { - int rc; + int rc, s; static int straycount, unexpected; struct cbus_softc *sc = NULL; struct cbus_isr_t *ci; @@ -230,20 +235,23 @@ cbus_isrdispatch(int ipl) panic("cbus_isrdispatch: can't find cbus_softc"); #ifdef DIAGNOSTIC - if (ipl < 0 || ipl >= NCBUSISR) - panic("cbus_isrdispatch: bad ipl 0x%d", ipl); + if (intlevel < 0 || intlevel >= NCBUSISR) + panic("cbus_isrdispatch: bad INT level 0x%d", intlevel); #endif - ci = &sc->cbus_isr[ipl]; + ci = &sc->cbus_isr[intlevel]; if (ci->isr_func == NULL) { - printf("cbus_isrdispatch: ipl %d unexpected\n", ipl); + printf("cbus_isrdispatch: INT%d unexpected\n", intlevel); if (++unexpected > 10) panic("too many unexpected interrupts"); return; } + s = raiseipl(ci->isr_ipl); /* splraise() */ rc = ci->isr_func(ci->isr_arg); + splx(s); + if (rc != 0) ci->isr_count.ec_count++; @@ -252,7 +260,24 @@ cbus_isrdispatch(int ipl) else if (++straycount > 50) panic("cbus_isrdispatch: too many stray interrupts"); else - printf("cbus_isrdispatch: stray level %d interrupt\n", ipl); + printf("cbus_isrdispatch: stray INT%d, IPL=%d\n", intlevel, + ci->isr_ipl); +} + +/* + * Return registered status of interrupt service routines. + */ +u_int8_t +cbus_intr_registered(void) +{ + struct cbus_softc *sc = NULL; + + if (cbus_cd.cd_ndevs != 0) + sc = cbus_cd.cd_devs[0]; + if (sc == NULL) + panic("cbus_intr_used: can't find cbus_softc"); + + return sc->registered; } /* @@ -261,7 +286,7 @@ cbus_isrdispatch(int ipl) * PC-9801 extension board slot bus (so-called 'C-bus' in Japan) use 8 own * interrupt levels, INT0-INT6, and NMI. On LUNA-88K2, they all trigger * level 4 interrupt on mainbus, so we need to check the dedicated interrupt - * status register to know which C-bus interrupt is occurred. + * status register to know which C-bus interrupt is occurred. * * The interrupt status register for C-bus is located at * (u_int8_t *)CBUS_INTR_STAT. Each bit of the register becomes 0 when diff --git a/sys/arch/luna88k/cbus/cbusvar.h b/sys/arch/luna88k/cbus/cbusvar.h index 3b3b8d94dea..57911cfbb48 100644 --- a/sys/arch/luna88k/cbus/cbusvar.h +++ b/sys/arch/luna88k/cbus/cbusvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cbusvar.h,v 1.3 2014/12/31 11:38:27 aoyama Exp $ */ +/* $OpenBSD: cbusvar.h,v 1.4 2015/02/18 22:42:04 aoyama Exp $ */ /* * Copyright (c) 2014 Kenji Aoyama. @@ -35,12 +35,13 @@ struct cbus_isr_t { int (*isr_func)(void *); void *isr_arg; int isr_intlevel; + int isr_ipl; struct evcount isr_count; }; -int cbus_isrlink(int (*)(void *), void *, int, const char *); +int cbus_isrlink(int (*)(void *), void *, int, int, const char *); int cbus_isrunlink(int (*)(void *), int); -void cbus_isrdispatch(int); +u_int8_t cbus_intr_registered(void); struct cbus_attach_args { char *ca_name; diff --git a/sys/arch/luna88k/cbus/necsb.c b/sys/arch/luna88k/cbus/necsb.c index 3d2eeefc54c..bcde11cfeae 100644 --- a/sys/arch/luna88k/cbus/necsb.c +++ b/sys/arch/luna88k/cbus/necsb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: necsb.c,v 1.2 2015/02/14 14:54:13 aoyama Exp $ */ +/* $OpenBSD: necsb.c,v 1.3 2015/02/18 22:42:04 aoyama Exp $ */ /* $NecBSD: nec86_isa.c,v 1.9 1998/09/26 11:31:11 kmatsuda Exp $ */ /* $NetBSD$ */ @@ -114,5 +114,6 @@ necsb_attach(struct device *parent, struct device *self, void *aux) panic("necsb_attach: bad INT level"); /* XXX: check return value ? */ - cbus_isrlink(nec86hw_intr, ysc, nsc->sc_intlevel, self->dv_xname); + cbus_isrlink(nec86hw_intr, ysc, nsc->sc_intlevel, IPL_AUDIO, + self->dv_xname); } diff --git a/sys/arch/luna88k/cbus/pcex.c b/sys/arch/luna88k/cbus/pcex.c index 6063da3d73f..ff28ee1c9dd 100644 --- a/sys/arch/luna88k/cbus/pcex.c +++ b/sys/arch/luna88k/cbus/pcex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pcex.c,v 1.2 2014/12/28 13:03:18 aoyama Exp $ */ +/* $OpenBSD: pcex.c,v 1.3 2015/02/18 22:42:04 aoyama Exp $ */ /* * Copyright (c) 2014 Kenji Aoyama. @@ -164,7 +164,7 @@ pcex_set_int(struct pcex_softc *sc, u_int level) return EINVAL; /* Duplicate */ sc->intr_use[level] = 1; - cbus_isrlink(pcex_intr, &(sc->intr_use[level]), level, + cbus_isrlink(pcex_intr, &(sc->intr_use[level]), level, IPL_NET, sc->sc_dev.dv_xname); return 0; |