summaryrefslogtreecommitdiff
path: root/sys/dev/sequencer.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/sequencer.c')
-rw-r--r--sys/dev/sequencer.c44
1 files changed, 34 insertions, 10 deletions
diff --git a/sys/dev/sequencer.c b/sys/dev/sequencer.c
index 1fc8d70e1a8..a28abc3c8c1 100644
--- a/sys/dev/sequencer.c
+++ b/sys/dev/sequencer.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sequencer.c,v 1.38 2006/11/24 19:46:59 christos Exp $ */
+/* $NetBSD: sequencer.c,v 1.39 2007/02/09 21:55:26 ad Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sequencer.c,v 1.38 2006/11/24 19:46:59 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sequencer.c,v 1.39 2007/02/09 21:55:26 ad Exp $");
#include "sequencer.h"
@@ -109,6 +109,7 @@ static int seq_to_new(seq_event_t *, struct uio *);
static int seq_sleep_timo(int *, const char *, int);
static int seq_sleep(int *, const char *);
static void seq_wakeup(int *);
+static void seq_softintr(void *);
struct midi_softc;
static int midiseq_out(struct midi_dev *, u_char *, u_int, int);
@@ -142,9 +143,13 @@ const struct cdevsw sequencer_cdevsw = {
void
sequencerattach(int n)
{
+ struct sequencer_softc *sc;
- for (n = 0; n < NSEQUENCER; n++)
- callout_init(&seqdevs[n].sc_callout);
+ for (n = 0; n < NSEQUENCER; n++) {
+ sc = &seqdevs[n];
+ callout_init(&sc->sc_callout);
+ sc->sih = softintr_establish(IPL_SOFTSERIAL, seq_softintr, sc);
+ }
}
static int
@@ -256,14 +261,20 @@ static void
seq_timeout(void *addr)
{
struct sequencer_softc *sc = addr;
+ struct proc *p;
+
DPRINTFN(4, ("seq_timeout: %p\n", sc));
sc->timeout = 0;
seq_startoutput(sc);
if (SEQ_QLEN(&sc->outq) < sc->lowat) {
seq_wakeup(&sc->wchan);
selnotify(&sc->wsel, 0);
- if (sc->async)
- psignal(sc->async, SIGIO);
+ if (sc->async != NULL) {
+ mutex_enter(&proclist_mutex);
+ if ((p = sc->async) != NULL)
+ psignal(p, SIGIO);
+ mutex_exit(&proclist_mutex);
+ }
}
}
@@ -307,6 +318,22 @@ sequencerclose(dev_t dev, int flags, int ifmt,
return (0);
}
+static void
+seq_softintr(void *cookie)
+{
+ struct sequencer_softc *sc = cookie;
+ struct proc *p;
+
+ seq_wakeup(&sc->rchan);
+ selnotify(&sc->rsel, 0);
+ if (sc->async != NULL) {
+ mutex_enter(&proclist_mutex);
+ if ((p = sc->async) != NULL)
+ psignal(p, SIGIO);
+ mutex_exit(&proclist_mutex);
+ }
+}
+
static int
seq_input_event(struct sequencer_softc *sc, seq_event_t *cmd)
{
@@ -321,10 +348,7 @@ seq_input_event(struct sequencer_softc *sc, seq_event_t *cmd)
if (SEQ_QFULL(q))
return (ENOMEM);
SEQ_QPUT(q, *cmd);
- seq_wakeup(&sc->rchan);
- selnotify(&sc->rsel, 0);
- if (sc->async)
- psignal(sc->async, SIGIO);
+ softintr_schedule(sc->sih);
return 0;
}