diff --git a/sys/dev/sound/midi/midi.h b/sys/dev/sound/midi/midi.h --- a/sys/dev/sound/midi/midi.h +++ b/sys/dev/sound/midi/midi.h @@ -41,6 +41,8 @@ #define MIDI_TYPE unsigned char +extern struct sx midistat_lock; + struct snd_midi; struct snd_midi * @@ -50,8 +52,10 @@ int midi_in(struct snd_midi *_m, MIDI_TYPE *_buf, int _size); kobj_t midimapper_addseq(void *arg1, int *unit, void **cookie); +int midimapper_open_locked(void *arg1, void **cookie); int midimapper_open(void *arg1, void **cookie); int midimapper_close(void *arg1, void *cookie); +kobj_t midimapper_fetch_synth_locked(void *arg, void *cookie, int unit); kobj_t midimapper_fetch_synth(void *arg, void *cookie, int unit); #endif diff --git a/sys/dev/sound/midi/midi.c b/sys/dev/sound/midi/midi.c --- a/sys/dev/sound/midi/midi.c +++ b/sys/dev/sound/midi/midi.c @@ -181,7 +181,8 @@ * /dev/midistat variables and declarations, protected by midistat_lock */ -static struct sx midistat_lock; +struct sx midistat_lock; + static int midistat_isopen = 0; static struct sbuf midistat_sbuf; static struct cdev *midistat_dev; @@ -1470,16 +1471,28 @@ } int -midimapper_open(void *arg1, void **cookie) +midimapper_open_locked(void *arg1, void **cookie) { int retval = 0; struct snd_midi *m; - sx_xlock(&midistat_lock); + sx_assert(&midistat_lock, SX_XLOCKED); TAILQ_FOREACH(m, &midi_devs, link) { retval++; } + + return retval; +} + +int +midimapper_open(void *arg1, void **cookie) +{ + int retval; + + sx_xlock(&midistat_lock); + retval = midimapper_open_locked(arg1, cookie); sx_xunlock(&midistat_lock); + return retval; } @@ -1490,22 +1503,32 @@ } kobj_t -midimapper_fetch_synth(void *arg, void *cookie, int unit) +midimapper_fetch_synth_locked(void *arg, void *cookie, int unit) { struct snd_midi *m; int retval = 0; - sx_xlock(&midistat_lock); + sx_assert(&midistat_lock, SX_XLOCKED); TAILQ_FOREACH(m, &midi_devs, link) { - if (unit == retval) { - sx_xunlock(&midistat_lock); + if (unit == retval) return (kobj_t)m->synth; - } retval++; } - sx_xunlock(&midistat_lock); + return NULL; } +kobj_t +midimapper_fetch_synth(void *arg, void *cookie, int unit) +{ + kobj_t synth; + + sx_xlock(&midistat_lock); + synth = midimapper_fetch_synth_locked(arg, cookie, unit); + sx_xunlock(&midistat_lock); + + return synth; +} + DEV_MODULE(midi, midi_modevent, NULL); MODULE_VERSION(midi, 1); diff --git a/sys/dev/sound/midi/sequencer.c b/sys/dev/sound/midi/sequencer.c --- a/sys/dev/sound/midi/sequencer.c +++ b/sys/dev/sound/midi/sequencer.c @@ -64,6 +64,7 @@ #include #include #include +#include #ifdef HAVE_KERNEL_OPTION_HEADERS #include "opt_snd.h" @@ -751,6 +752,7 @@ * Mark this device busy. */ + sx_xlock(&midistat_lock); mtx_lock(&scp->seq_lock); if (scp->busy) { mtx_unlock(&scp->seq_lock); @@ -768,14 +770,15 @@ * Enumerate the available midi devices */ scp->midi_number = 0; - scp->maxunits = midimapper_open(scp->mapper, &scp->mapper_cookie); + scp->maxunits = midimapper_open_locked(scp->mapper, &scp->mapper_cookie); if (scp->maxunits == 0) SEQ_DEBUG(2, printf("seq_open: no midi devices\n")); for (i = 0; i < scp->maxunits; i++) { scp->midis[scp->midi_number] = - midimapper_fetch_synth(scp->mapper, scp->mapper_cookie, i); + midimapper_fetch_synth_locked(scp->mapper, + scp->mapper_cookie, i); if (scp->midis[scp->midi_number]) { if (SYNTH_OPEN(scp->midis[scp->midi_number], scp, scp->fflags) != 0) @@ -803,6 +806,7 @@ scp->busy = 1; mtx_unlock(&scp->seq_lock); + sx_xunlock(&midistat_lock); SEQ_DEBUG(2, printf("seq_open: opened, mode %s.\n", scp->music ? "music" : "sequencer"));