summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/arm/arm/softintr.c16
-rw-r--r--sys/arch/arm/include/softintr.h15
-rw-r--r--sys/arch/sh/include/intr.h9
-rw-r--r--sys/arch/sh/sh/interrupt.c33
4 files changed, 36 insertions, 37 deletions
diff --git a/sys/arch/arm/arm/softintr.c b/sys/arch/arm/arm/softintr.c
index 96480df841e..b7d8202e30d 100644
--- a/sys/arch/arm/arm/softintr.c
+++ b/sys/arch/arm/arm/softintr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softintr.c,v 1.5 2009/04/08 21:19:30 kettenis Exp $ */
+/* $OpenBSD: softintr.c,v 1.6 2009/04/19 18:54:06 oga Exp $ */
/* $NetBSD: softintr.c,v 1.2 2003/07/15 00:24:39 lukem Exp $ */
/*
@@ -67,6 +67,7 @@ softintr_init(void)
for (i = 0; i < SI_NQUEUES; i++) {
siq = &soft_intrq[i];
TAILQ_INIT(&siq->siq_list);
+ mtx_init(&siq->siq_mtx, IPL_HIGH);
siq->siq_si = i;
}
@@ -89,13 +90,12 @@ softintr_dispatch(int si)
{
struct soft_intrq *siq = &soft_intrq[si];
struct soft_intrhand *sih;
- int oldirqstate;
for (;;) {
- oldirqstate = disable_interrupts(I32_bit);
+ mtx_enter(&siq->siq_mtx);
sih = TAILQ_FIRST(&siq->siq_list);
if (sih == NULL) {
- restore_interrupts(oldirqstate);
+ mtx_leave(&siq->siq_mtx);
break;
}
@@ -103,8 +103,7 @@ softintr_dispatch(int si)
sih->sih_pending = 0;
uvmexp.softs++;
-
- restore_interrupts(oldirqstate);
+ mtx_leave(&siq->siq_mtx);
(*sih->sih_func)(sih->sih_arg);
}
@@ -163,14 +162,13 @@ softintr_disestablish(void *arg)
{
struct soft_intrhand *sih = arg;
struct soft_intrq *siq = sih->sih_siq;
- int oldirqstate;
- oldirqstate = disable_interrupts(I32_bit);
+ mtx_enter(&siq->siq_mtx);
if (sih->sih_pending) {
TAILQ_REMOVE(&siq->siq_list, sih, sih_list);
sih->sih_pending = 0;
}
- restore_interrupts(oldirqstate);
+ mtx_leave(&siq->siq_mtx);
free(sih, M_DEVBUF);
}
diff --git a/sys/arch/arm/include/softintr.h b/sys/arch/arm/include/softintr.h
index cc4065ba67c..8d3feb39fba 100644
--- a/sys/arch/arm/include/softintr.h
+++ b/sys/arch/arm/include/softintr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: softintr.h,v 1.3 2009/04/08 21:19:30 kettenis Exp $ */
+/* $OpenBSD: softintr.h,v 1.4 2009/04/19 18:54:06 oga Exp $ */
/* $NetBSD: softintr.h,v 1.1 2002/01/29 22:54:14 thorpej Exp $ */
/*
@@ -41,6 +41,8 @@
#ifdef _KERNEL
+#include <sys/mutex.h>
+
/*
* Generic software interrupt support for all ARM platforms.
*
@@ -64,8 +66,10 @@ struct soft_intrhand {
};
struct soft_intrq {
- TAILQ_HEAD(, soft_intrhand) siq_list;
- int siq_si;
+ TAILQ_HEAD(, soft_intrhand)
+ siq_list;
+ int siq_si;
+ struct mutex siq_mtx;
};
void *softintr_establish(int, void (*)(void *), void *);
@@ -77,15 +81,14 @@ void softintr_dispatch(int);
do { \
struct soft_intrhand *__sih = (arg); \
struct soft_intrq *__siq = __sih->sih_siq; \
- int __s; \
\
- __s = splhigh(); \
+ mtx_enter(&__siq->siq_mtx); \
if (__sih->sih_pending == 0) { \
TAILQ_INSERT_TAIL(&__siq->siq_list, __sih, sih_list); \
__sih->sih_pending = 1; \
_setsoftintr(__siq->siq_si); \
} \
- splx(__s); \
+ mtx_leave(&__siq->siq_mtx); \
} while (/*CONSTCOND*/0)
/* XXX For legacy software interrupts. */
diff --git a/sys/arch/sh/include/intr.h b/sys/arch/sh/include/intr.h
index ce274d1245f..886494c6dd7 100644
--- a/sys/arch/sh/include/intr.h
+++ b/sys/arch/sh/include/intr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.h,v 1.6 2009/03/25 21:40:56 miod Exp $ */
+/* $OpenBSD: intr.h,v 1.7 2009/04/19 18:54:06 oga Exp $ */
/* $NetBSD: intr.h,v 1.22 2006/01/24 23:51:42 uwe Exp $ */
/*-
@@ -35,6 +35,7 @@
#include <sys/device.h>
#include <sys/evcount.h>
#include <sys/lock.h>
+#include <sys/mutex.h>
#include <sys/queue.h>
#include <sh/psl.h>
@@ -101,8 +102,10 @@ struct sh_soft_intrhand {
};
struct sh_soft_intr {
- TAILQ_HEAD(, sh_soft_intrhand) softintr_q;
- unsigned long softintr_ipl;
+ TAILQ_HEAD(, sh_soft_intrhand)
+ softintr_q;
+ unsigned long softintr_ipl;
+ struct mutex softintr_lock;
};
void softintr_disestablish(void *);
diff --git a/sys/arch/sh/sh/interrupt.c b/sys/arch/sh/sh/interrupt.c
index b46588cf123..17ff868bb6c 100644
--- a/sys/arch/sh/sh/interrupt.c
+++ b/sys/arch/sh/sh/interrupt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: interrupt.c,v 1.9 2009/03/25 21:41:00 miod Exp $ */
+/* $OpenBSD: interrupt.c,v 1.10 2009/04/19 18:54:06 oga Exp $ */
/* $NetBSD: interrupt.c,v 1.18 2006/01/25 00:02:57 uwe Exp $ */
/*-
@@ -585,7 +585,7 @@ softintr_init(void)
for (i = 0; i < _IPL_NSOFT; i++) {
asi = &sh_soft_intrs[i];
TAILQ_INIT(&asi->softintr_q);
-
+ mtx_init(&asi->softintr_lock, IPL_HIGH);
asi->softintr_ipl = IPL_SOFT + i;
}
@@ -605,24 +605,24 @@ softintr_dispatch(int ipl)
{
struct sh_soft_intr *asi;
struct sh_soft_intrhand *sih;
- int s;
-
- s = _cpu_intr_suspend();
asi = &sh_soft_intrs[ipl - IPL_SOFT];
- while ((sih = TAILQ_FIRST(&asi->softintr_q)) != NULL) {
+ for (;;) {
+ mtx_enter(&asi->softintr_lock);
+ sih = TAILQ_FIRST(&asi->softintr_q);
+ if (sih == NULL) {
+ mtx_leave(&asi->softintr_lock);
+ break;
+ }
TAILQ_REMOVE(&asi->softintr_q, sih, sih_q);
sih->sih_pending = 0;
uvmexp.softs++;
+ mtx_leave(&asi->softintr_lock);
- _cpu_intr_resume(s);
(*sih->sih_fn)(sih->sih_arg);
- s = _cpu_intr_suspend();
}
-
- _cpu_intr_resume(s);
}
void
@@ -640,7 +640,6 @@ softintr_establish(int ipl, void (*func)(void *), void *arg)
{
struct sh_soft_intr *asi;
struct sh_soft_intrhand *sih;
- int s;
if (__predict_false(ipl >= (IPL_SOFT + _IPL_NSOFT) ||
ipl < IPL_SOFT))
@@ -648,7 +647,6 @@ softintr_establish(int ipl, void (*func)(void *), void *arg)
sih = malloc(sizeof(*sih), M_DEVBUF, M_NOWAIT);
- s = _cpu_intr_suspend();
asi = &sh_soft_intrs[ipl - IPL_SOFT];
if (__predict_true(sih != NULL)) {
sih->sih_intrhead = asi;
@@ -656,7 +654,6 @@ softintr_establish(int ipl, void (*func)(void *), void *arg)
sih->sih_arg = arg;
sih->sih_pending = 0;
}
- _cpu_intr_resume(s);
return (sih);
}
@@ -667,14 +664,13 @@ softintr_disestablish(void *arg)
{
struct sh_soft_intrhand *sih = arg;
struct sh_soft_intr *asi = sih->sih_intrhead;
- int s;
- s = _cpu_intr_suspend();
+ mtx_enter(&asi->softintr_lock);
if (sih->sih_pending) {
TAILQ_REMOVE(&asi->softintr_q, sih, sih_q);
sih->sih_pending = 0;
}
- _cpu_intr_resume(s);
+ mtx_leave(&asi->softintr_lock);
free(sih, M_DEVBUF);
}
@@ -684,15 +680,14 @@ void softintr_schedule(void *arg)
{
struct sh_soft_intrhand *sih = arg;
struct sh_soft_intr *si = sih->sih_intrhead;
- int s;
- s = _cpu_intr_suspend();
+ mtx_enter(&si->softintr_lock);
if (sih->sih_pending == 0) {
TAILQ_INSERT_TAIL(&si->softintr_q, sih, sih_q);
sih->sih_pending = 1;
setsoft(si->softintr_ipl);
}
- _cpu_intr_resume(s);
+ mtx_leave(&si->softintr_lock);
}
/*