summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraoyama <aoyama@openbsd.org>2015-02-18 22:42:04 +0000
committeraoyama <aoyama@openbsd.org>2015-02-18 22:42:04 +0000
commit3471ae31a7e1139d582d50aa079616e338bf945c (patch)
tree21ed952ae9da6b8a5f6b8356ab0353c95786ddb1
parentconvert calloc/realloc pairs to reallocarray (diff)
downloadwireguard-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.c79
-rw-r--r--sys/arch/luna88k/cbus/cbusvar.h7
-rw-r--r--sys/arch/luna88k/cbus/necsb.c5
-rw-r--r--sys/arch/luna88k/cbus/pcex.c4
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;