The branch main has been updated by christos:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=79b968063998e67a3c65b580908da640c4544a56

commit 79b968063998e67a3c65b580908da640c4544a56
Author:     Christos Margiolis <chris...@freebsd.org>
AuthorDate: 2025-07-06 13:08:10 +0000
Commit:     Christos Margiolis <chris...@freebsd.org>
CommitDate: 2025-07-06 13:08:10 +0000

    sound: Retire the MIDI sequencer
    
    The in-kernel MIDI sequencer is not used anymore, since this is done by
    userland applications nowadays. It also contains bugs, and we are not
    exactly sure how it works, or if it worked properly in the first place.
    
    Sponsored by:   The FreeBSD Foundation
    Reviewed by:    vishwin, markj
    Differential Revision:  https://reviews.freebsd.org/D50605
---
 sys/conf/files                   |    1 -
 sys/dev/sound/midi/midi.c        |   14 -
 sys/dev/sound/midi/midi.h        |    1 -
 sys/dev/sound/midi/sequencer.c   | 2107 --------------------------------------
 sys/dev/sound/midi/sequencer.h   |   89 --
 sys/dev/sound/pcm/sndstat.c      |    3 -
 sys/dev/sound/pcm/sound.h        |    1 -
 sys/modules/sound/sound/Makefile |    2 +-
 8 files changed, 1 insertion(+), 2217 deletions(-)

diff --git a/sys/conf/files b/sys/conf/files
index dd6f9a3021d4..7c023af39b2a 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -3173,7 +3173,6 @@ dev/sound/midi/midi.c             optional sound
 dev/sound/midi/mpu401.c                optional sound
 dev/sound/midi/mpu_if.m                optional sound
 dev/sound/midi/mpufoi_if.m     optional sound
-dev/sound/midi/sequencer.c     optional sound
 dev/sound/midi/synth_if.m      optional sound
 dev/spibus/acpi_spibus.c       optional acpi spibus
 dev/spibus/ofw_spibus.c                optional fdt spibus
diff --git a/sys/dev/sound/midi/midi.c b/sys/dev/sound/midi/midi.c
index fbfb69de2913..93a535b940a2 100644
--- a/sys/dev/sound/midi/midi.c
+++ b/sys/dev/sound/midi/midi.c
@@ -1441,8 +1441,6 @@ exit0:
        return retval;
 }
 
-extern int seq_modevent(module_t mod, int type, void *data);
-
 static int
 midi_modevent(module_t mod, int type, void *data)
 {
@@ -1453,14 +1451,10 @@ midi_modevent(module_t mod, int type, void *data)
        switch (type) {
        case MOD_LOAD:
                retval = midi_load();
-               if (retval == 0)
-                       retval = seq_modevent(mod, type, data);
                break;
 
        case MOD_UNLOAD:
                retval = midi_unload();
-               if (retval == 0)
-                       retval = seq_modevent(mod, type, data);
                break;
 
        default:
@@ -1470,14 +1464,6 @@ midi_modevent(module_t mod, int type, void *data)
        return retval;
 }
 
-kobj_t
-midimapper_addseq(void *arg1, int *unit, void **cookie)
-{
-       unit = NULL;
-
-       return (kobj_t)arg1;
-}
-
 int
 midimapper_open_locked(void *arg1, void **cookie)
 {
diff --git a/sys/dev/sound/midi/midi.h b/sys/dev/sound/midi/midi.h
index 2254fab690e9..8becc20d35e6 100644
--- a/sys/dev/sound/midi/midi.h
+++ b/sys/dev/sound/midi/midi.h
@@ -51,7 +51,6 @@ int   midi_uninit(struct snd_midi *_m);
 int    midi_out(struct snd_midi *_m, uint8_t *_buf, int _size);
 int    midi_in(struct snd_midi *_m, uint8_t *_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);
diff --git a/sys/dev/sound/midi/sequencer.c b/sys/dev/sound/midi/sequencer.c
deleted file mode 100644
index 03b71688175c..000000000000
--- a/sys/dev/sound/midi/sequencer.c
+++ /dev/null
@@ -1,2107 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2003 Mathew Kanner
- * Copyright (c) 1993 Hannu Savolainen
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * The sequencer personality manager.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/ioccom.h>
-
-#include <sys/filio.h>
-#include <sys/lock.h>
-#include <sys/sockio.h>
-#include <sys/fcntl.h>
-#include <sys/proc.h>
-#include <sys/sysctl.h>
-
-#include <sys/kernel.h>                        /* for DATA_SET */
-
-#include <sys/module.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/uio.h>
-#include <sys/syslog.h>
-#include <sys/errno.h>
-#include <sys/malloc.h>
-#include <sys/bus.h>
-#include <machine/resource.h>
-#include <machine/bus.h>
-#include <machine/clock.h>             /* for DELAY */
-#include <sys/soundcard.h>
-#include <sys/rman.h>
-#include <sys/mman.h>
-#include <sys/poll.h>
-#include <sys/mutex.h>
-#include <sys/condvar.h>
-#include <sys/kthread.h>
-#include <sys/unistd.h>
-#include <sys/selinfo.h>
-#include <sys/sx.h>
-
-#ifdef HAVE_KERNEL_OPTION_HEADERS
-#include "opt_snd.h"
-#endif
-
-#include <dev/sound/midi/midi.h>
-#include <dev/sound/midi/midiq.h>
-#include "synth_if.h"
-
-#include <dev/sound/midi/sequencer.h>
-
-#define TMR_TIMERBASE 13
-
-#define SND_DEV_SEQ    1               /* Sequencer output /dev/sequencer (FM
-                                        * synthesizer and MIDI output) */
-#define SND_DEV_MUSIC  8               /* /dev/music, level 2 interface */
-
-/* Length of a sequencer event. */
-#define EV_SZ 8
-#define IEV_SZ 8
-
-/* Lookup modes */
-#define LOOKUP_EXIST   (0)
-#define LOOKUP_OPEN    (1)
-#define LOOKUP_CLOSE   (2)
-
-#define MIDIDEV(y) (dev2unit(y) & 0x0f)
-
-/* These are the entries to the sequencer driver. */
-static d_open_t mseq_open;
-static d_close_t mseq_close;
-static d_ioctl_t mseq_ioctl;
-static d_read_t mseq_read;
-static d_write_t mseq_write;
-static d_poll_t mseq_poll;
-
-static struct cdevsw seq_cdevsw = {
-       .d_version = D_VERSION,
-       .d_open = mseq_open,
-       .d_close = mseq_close,
-       .d_read = mseq_read,
-       .d_write = mseq_write,
-       .d_ioctl = mseq_ioctl,
-       .d_poll = mseq_poll,
-       .d_name = "sequencer",
-};
-
-struct seq_softc {
-       KOBJ_FIELDS;
-
-       struct mtx seq_lock, q_lock;
-       struct cv empty_cv, reset_cv, in_cv, out_cv, state_cv, th_cv;
-
-       MIDIQ_HEAD(, u_char) in_q, out_q;
-
-       u_long  flags;
-       /* Flags (protected by flag_mtx of mididev_info) */
-       int     fflags;                 /* Access mode */
-       int     music;
-
-       int     out_water;              /* Sequence output threshould */
-       snd_sync_parm sync_parm;        /* AIOSYNC parameter set */
-       struct thread *sync_thread;     /* AIOSYNCing thread */
-       struct selinfo in_sel, out_sel;
-       int     midi_number;
-       struct cdev *seqdev, *musicdev;
-       int     unit;
-       int     maxunits;
-       kobj_t *midis;
-       int    *midi_flags;
-       kobj_t  mapper;
-       void   *mapper_cookie;
-       struct timeval timerstop, timersub;
-       int     timerbase, tempo;
-       int     timerrun;
-       int     done;
-       int     playing;
-       int     recording;
-       int     busy;
-       int     pre_event_timeout;
-       int     waiting;
-};
-
-/*
- * Module specific stuff, including how many sequecers
- * we currently own.
- */
-
-SYSCTL_NODE(_hw_midi, OID_AUTO, seq, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
-    "Midi sequencer");
-
-int                                    seq_debug;
-/* XXX: should this be moved into debug.midi? */
-SYSCTL_INT(_hw_midi_seq, OID_AUTO, debug, CTLFLAG_RW, &seq_debug, 0, "");
-
-midi_cmdtab    cmdtab_seqevent[] = {
-       {SEQ_NOTEOFF,           "SEQ_NOTEOFF"},
-       {SEQ_NOTEON,            "SEQ_NOTEON"},
-       {SEQ_WAIT,              "SEQ_WAIT"},
-       {SEQ_PGMCHANGE,         "SEQ_PGMCHANGE"},
-       {SEQ_SYNCTIMER,         "SEQ_SYNCTIMER"},
-       {SEQ_MIDIPUTC,          "SEQ_MIDIPUTC"},
-       {SEQ_DRUMON,            "SEQ_DRUMON"},
-       {SEQ_DRUMOFF,           "SEQ_DRUMOFF"},
-       {SEQ_ECHO,              "SEQ_ECHO"},
-       {SEQ_AFTERTOUCH,        "SEQ_AFTERTOUCH"},
-       {SEQ_CONTROLLER,        "SEQ_CONTROLLER"},
-       {SEQ_BALANCE,           "SEQ_BALANCE"},
-       {SEQ_VOLMODE,           "SEQ_VOLMODE"},
-       {SEQ_FULLSIZE,          "SEQ_FULLSIZE"},
-       {SEQ_PRIVATE,           "SEQ_PRIVATE"},
-       {SEQ_EXTENDED,          "SEQ_EXTENDED"},
-       {EV_SEQ_LOCAL,          "EV_SEQ_LOCAL"},
-       {EV_TIMING,             "EV_TIMING"},
-       {EV_CHN_COMMON,         "EV_CHN_COMMON"},
-       {EV_CHN_VOICE,          "EV_CHN_VOICE"},
-       {EV_SYSEX,              "EV_SYSEX"},
-       {-1,                    NULL},
-};
-
-midi_cmdtab    cmdtab_seqioctl[] = {
-       {SNDCTL_SEQ_RESET,      "SNDCTL_SEQ_RESET"},
-       {SNDCTL_SEQ_SYNC,       "SNDCTL_SEQ_SYNC"},
-       {SNDCTL_SYNTH_INFO,     "SNDCTL_SYNTH_INFO"},
-       {SNDCTL_SEQ_CTRLRATE,   "SNDCTL_SEQ_CTRLRATE"},
-       {SNDCTL_SEQ_GETOUTCOUNT,        "SNDCTL_SEQ_GETOUTCOUNT"},
-       {SNDCTL_SEQ_GETINCOUNT, "SNDCTL_SEQ_GETINCOUNT"},
-       {SNDCTL_SEQ_PERCMODE,   "SNDCTL_SEQ_PERCMODE"},
-       {SNDCTL_FM_LOAD_INSTR,  "SNDCTL_FM_LOAD_INSTR"},
-       {SNDCTL_SEQ_TESTMIDI,   "SNDCTL_SEQ_TESTMIDI"},
-       {SNDCTL_SEQ_RESETSAMPLES,       "SNDCTL_SEQ_RESETSAMPLES"},
-       {SNDCTL_SEQ_NRSYNTHS,   "SNDCTL_SEQ_NRSYNTHS"},
-       {SNDCTL_SEQ_NRMIDIS,    "SNDCTL_SEQ_NRMIDIS"},
-       {SNDCTL_SEQ_GETTIME,    "SNDCTL_SEQ_GETTIME"},
-       {SNDCTL_MIDI_INFO,      "SNDCTL_MIDI_INFO"},
-       {SNDCTL_SEQ_THRESHOLD,  "SNDCTL_SEQ_THRESHOLD"},
-       {SNDCTL_SYNTH_MEMAVL,   "SNDCTL_SYNTH_MEMAVL"},
-       {SNDCTL_FM_4OP_ENABLE,  "SNDCTL_FM_4OP_ENABLE"},
-       {SNDCTL_PMGR_ACCESS,    "SNDCTL_PMGR_ACCESS"},
-       {SNDCTL_SEQ_PANIC,      "SNDCTL_SEQ_PANIC"},
-       {SNDCTL_SEQ_OUTOFBAND,  "SNDCTL_SEQ_OUTOFBAND"},
-       {SNDCTL_TMR_TIMEBASE,   "SNDCTL_TMR_TIMEBASE"},
-       {SNDCTL_TMR_START,      "SNDCTL_TMR_START"},
-       {SNDCTL_TMR_STOP,       "SNDCTL_TMR_STOP"},
-       {SNDCTL_TMR_CONTINUE,   "SNDCTL_TMR_CONTINUE"},
-       {SNDCTL_TMR_TEMPO,      "SNDCTL_TMR_TEMPO"},
-       {SNDCTL_TMR_SOURCE,     "SNDCTL_TMR_SOURCE"},
-       {SNDCTL_TMR_METRONOME,  "SNDCTL_TMR_METRONOME"},
-       {SNDCTL_TMR_SELECT,     "SNDCTL_TMR_SELECT"},
-       {SNDCTL_MIDI_PRETIME,   "SNDCTL_MIDI_PRETIME"},
-       {AIONWRITE,             "AIONWRITE"},
-       {AIOGSIZE,              "AIOGSIZE"},
-       {AIOSSIZE,              "AIOSSIZE"},
-       {AIOGFMT,               "AIOGFMT"},
-       {AIOSFMT,               "AIOSFMT"},
-       {AIOGMIX,               "AIOGMIX"},
-       {AIOSMIX,               "AIOSMIX"},
-       {AIOSTOP,               "AIOSTOP"},
-       {AIOSYNC,               "AIOSYNC"},
-       {AIOGCAP,               "AIOGCAP"},
-       {-1,                    NULL},
-};
-
-midi_cmdtab    cmdtab_timer[] = {
-       {TMR_WAIT_REL,  "TMR_WAIT_REL"},
-       {TMR_WAIT_ABS,  "TMR_WAIT_ABS"},
-       {TMR_STOP,      "TMR_STOP"},
-       {TMR_START,     "TMR_START"},
-       {TMR_CONTINUE,  "TMR_CONTINUE"},
-       {TMR_TEMPO,     "TMR_TEMPO"},
-       {TMR_ECHO,      "TMR_ECHO"},
-       {TMR_CLOCK,     "TMR_CLOCK"},
-       {TMR_SPP,       "TMR_SPP"},
-       {TMR_TIMESIG,   "TMR_TIMESIG"},
-       {-1,            NULL},
-};
-
-midi_cmdtab    cmdtab_seqcv[] = {
-       {MIDI_NOTEOFF,          "MIDI_NOTEOFF"},
-       {MIDI_NOTEON,           "MIDI_NOTEON"},
-       {MIDI_KEY_PRESSURE,     "MIDI_KEY_PRESSURE"},
-       {-1,                    NULL},
-};
-
-midi_cmdtab    cmdtab_seqccmn[] = {
-       {MIDI_CTL_CHANGE,       "MIDI_CTL_CHANGE"},
-       {MIDI_PGM_CHANGE,       "MIDI_PGM_CHANGE"},
-       {MIDI_CHN_PRESSURE,     "MIDI_CHN_PRESSURE"},
-       {MIDI_PITCH_BEND,       "MIDI_PITCH_BEND"},
-       {MIDI_SYSTEM_PREFIX,    "MIDI_SYSTEM_PREFIX"},
-       {-1,                    NULL},
-};
-
-#ifndef KOBJMETHOD_END
-#define KOBJMETHOD_END { NULL, NULL }
-#endif
-
-/*
- * static const char *mpu401_mprovider(kobj_t obj, struct mpu401 *m);
- */
-
-static kobj_method_t seq_methods[] = {
-       /* KOBJMETHOD(mpu_provider,mpu401_mprovider), */
-       KOBJMETHOD_END
-};
-
-DEFINE_CLASS(sequencer, seq_methods, 0);
-
-/* The followings are the local function. */
-static int seq_convertold(u_char *event, u_char *out);
-
-/*
- * static void seq_midiinput(struct seq_softc * scp, void *md);
- */
-static void seq_reset(struct seq_softc *scp);
-static int seq_sync(struct seq_softc *scp);
-
-static int seq_processevent(struct seq_softc *scp, u_char *event);
-
-static int seq_timing(struct seq_softc *scp, u_char *event);
-static int seq_local(struct seq_softc *scp, u_char *event);
-
-static int seq_chnvoice(struct seq_softc *scp, kobj_t md, u_char *event);
-static int seq_chncommon(struct seq_softc *scp, kobj_t md, u_char *event);
-static int seq_sysex(struct seq_softc *scp, kobj_t md, u_char *event);
-
-static int seq_fetch_mid(struct seq_softc *scp, int unit, kobj_t *md);
-void   seq_copytoinput(struct seq_softc *scp, u_char *event, int len);
-int    seq_modevent(module_t mod, int type, void *data);
-struct seq_softc *seqs[10];
-static struct mtx seqinfo_mtx;
-static u_long nseq = 0;
-
-static void timer_start(struct seq_softc *t);
-static void timer_stop(struct seq_softc *t);
-static void timer_setvals(struct seq_softc *t, int tempo, int timerbase);
-static void timer_wait(struct seq_softc *t, int ticks, int wait_abs);
-static int timer_now(struct seq_softc *t);
-
-static void
-timer_start(struct seq_softc *t)
-{
-       t->timerrun = 1;
-       getmicrotime(&t->timersub);
-}
-
-static void
-timer_continue(struct seq_softc *t)
-{
-       struct timeval now;
-
-       if (t->timerrun == 1)
-               return;
-       t->timerrun = 1;
-       getmicrotime(&now);
-       timevalsub(&now, &t->timerstop);
-       timevaladd(&t->timersub, &now);
-}
-
-static void
-timer_stop(struct seq_softc *t)
-{
-       t->timerrun = 0;
-       getmicrotime(&t->timerstop);
-}
-
-static void
-timer_setvals(struct seq_softc *t, int tempo, int timerbase)
-{
-       t->tempo = tempo;
-       t->timerbase = timerbase;
-}
-
-static void
-timer_wait(struct seq_softc *t, int ticks, int wait_abs)
-{
-       struct timeval now, when;
-       int ret;
-       unsigned long long i;
-
-       while (t->timerrun == 0) {
-               SEQ_DEBUG(2, printf("Timer wait when timer isn't running\n"));
-               /*
-                * The old sequencer used timeouts that only increased
-                * the timer when the timer was running.
-                * Hence the sequencer would stick (?) if the
-                * timer was disabled.
-                */
-               cv_wait(&t->reset_cv, &t->seq_lock);
-               if (t->playing == 0)
-                       return;
-       }
-
-       i = ticks * 60ull * 1000000ull / (t->tempo * t->timerbase);
-
-       when.tv_sec = i / 1000000;
-       when.tv_usec = i % 1000000;
-
-#if 0
-       printf("timer_wait tempo %d timerbase %d ticks %d abs %d u_sec %llu\n",
-           t->tempo, t->timerbase, ticks, wait_abs, i);
-#endif
-
-       if (wait_abs != 0) {
-               getmicrotime(&now);
-               timevalsub(&now, &t->timersub);
-               timevalsub(&when, &now);
-       }
-       if (when.tv_sec < 0 || when.tv_usec < 0) {
-               SEQ_DEBUG(3,
-                   printf("seq_timer error negative time %lds.%06lds\n",
-                   (long)when.tv_sec, (long)when.tv_usec));
-               return;
-       }
-       i = when.tv_sec * 1000000ull;
-       i += when.tv_usec;
-       i *= hz;
-       i /= 1000000ull;
-#if 0
-       printf("seq_timer usec %llu ticks %llu\n",
-           when.tv_sec * 1000000ull + when.tv_usec, i);
-#endif
-       t->waiting = 1;
-       ret = cv_timedwait(&t->reset_cv, &t->seq_lock, i + 1);
-       t->waiting = 0;
-
-       if (ret != EWOULDBLOCK)
-               SEQ_DEBUG(3, printf("seq_timer didn't timeout\n"));
-
-}
-
-static int
-timer_now(struct seq_softc *t)
-{
-       struct timeval now;
-       unsigned long long i;
-       int ret;
-
-       if (t->timerrun == 0)
-               now = t->timerstop;
-       else
-               getmicrotime(&now);
-
-       timevalsub(&now, &t->timersub);
-
-       i = now.tv_sec * 1000000ull;
-       i += now.tv_usec;
-       i *= t->timerbase;
-/*     i /= t->tempo; */
-       i /= 1000000ull;
-
-       ret = i;
-       /*
-        * printf("timer_now: %llu %d\n", i, ret);
-        */
-
-       return ret;
-}
-
-static void
-seq_eventthread(void *arg)
-{
-       struct seq_softc *scp = arg;
-       u_char event[EV_SZ];
-
-       mtx_lock(&scp->seq_lock);
-       SEQ_DEBUG(2, printf("seq_eventthread started\n"));
-       while (scp->done == 0) {
-restart:
-               while (scp->playing == 0) {
-                       cv_wait(&scp->state_cv, &scp->seq_lock);
-                       if (scp->done)
-                               goto done;
-               }
-
-               while (MIDIQ_EMPTY(scp->out_q)) {
-                       cv_broadcast(&scp->empty_cv);
-                       cv_wait(&scp->out_cv, &scp->seq_lock);
-                       if (scp->playing == 0)
-                               goto restart;
-                       if (scp->done)
-                               goto done;
-               }
-
-               MIDIQ_DEQ(scp->out_q, event, EV_SZ);
-
-               if (MIDIQ_AVAIL(scp->out_q) < scp->out_water) {
-                       cv_broadcast(&scp->out_cv);
-                       selwakeup(&scp->out_sel);
-               }
-               seq_processevent(scp, event);
-       }
-
-done:
-       cv_broadcast(&scp->th_cv);
-       mtx_unlock(&scp->seq_lock);
-       SEQ_DEBUG(2, printf("seq_eventthread finished\n"));
-       kproc_exit(0);
-}
-
-/*
- * seq_processevent:  This maybe called by the event thread or the IOCTL
- * handler for queued and out of band events respectively.
- */
-static int
-seq_processevent(struct seq_softc *scp, u_char *event)
-{
-       int ret;
-       kobj_t m;
-
-       ret = 0;
-
-       if (event[0] == EV_SEQ_LOCAL)
-               ret = seq_local(scp, event);
-       else if (event[0] == EV_TIMING)
-               ret = seq_timing(scp, event);
-       else if (event[0] != EV_CHN_VOICE &&
-                   event[0] != EV_CHN_COMMON &&
-                   event[0] != EV_SYSEX &&
-           event[0] != SEQ_MIDIPUTC) {
-               ret = 1;
-               SEQ_DEBUG(2, printf("seq_processevent not known %d\n",
-                   event[0]));
-       } else if (seq_fetch_mid(scp, event[1], &m) != 0) {
-               ret = 1;
-               SEQ_DEBUG(2, printf("seq_processevent midi unit not found %d\n",
-                   event[1]));
-       } else
-               switch (event[0]) {
-               case EV_CHN_VOICE:
-                       ret = seq_chnvoice(scp, m, event);
-                       break;
-               case EV_CHN_COMMON:
-                       ret = seq_chncommon(scp, m, event);
-                       break;
-               case EV_SYSEX:
-                       ret = seq_sysex(scp, m, event);
-                       break;
-               case SEQ_MIDIPUTC:
-                       mtx_unlock(&scp->seq_lock);
-                       ret = SYNTH_WRITERAW(m, &event[2], 1);
-                       mtx_lock(&scp->seq_lock);
-                       break;
-               }
-       return ret;
-}
-
-static int
-seq_addunit(void)
-{
-       struct seq_softc *scp;
-       int ret;
-       u_char *buf;
-
-       gone_in(15, "Warning! MIDI sequencer to be removed soon: no longer "
-           "needed or used\n");
-
-       /* Allocate the softc. */
-       ret = ENOMEM;
-       scp = malloc(sizeof(*scp), M_DEVBUF, M_NOWAIT | M_ZERO);
-       if (scp == NULL) {
-               SEQ_DEBUG(1, printf("seq_addunit: softc allocation failed.\n"));
-               goto err;
-       }
-       kobj_init((kobj_t)scp, &sequencer_class);
-
-       buf = malloc(sizeof(*buf) * EV_SZ * 1024, M_TEMP, M_NOWAIT | M_ZERO);
-       if (buf == NULL)
-               goto err;
-       MIDIQ_INIT(scp->in_q, buf, EV_SZ * 1024);
-       buf = malloc(sizeof(*buf) * EV_SZ * 1024, M_TEMP, M_NOWAIT | M_ZERO);
-       if (buf == NULL)
-               goto err;
-       MIDIQ_INIT(scp->out_q, buf, EV_SZ * 1024);
-       ret = EINVAL;
-
-       scp->midis = malloc(sizeof(kobj_t) * 32, M_TEMP, M_NOWAIT | M_ZERO);
-       scp->midi_flags = malloc(sizeof(*scp->midi_flags) * 32, M_TEMP,
-           M_NOWAIT | M_ZERO);
-
-       if (scp->midis == NULL || scp->midi_flags == NULL)
-               goto err;
-
-       scp->flags = 0;
-
-       mtx_init(&scp->seq_lock, "seqflq", NULL, 0);
-       cv_init(&scp->state_cv, "seqstate");
-       cv_init(&scp->empty_cv, "seqempty");
-       cv_init(&scp->reset_cv, "seqtimer");
-       cv_init(&scp->out_cv, "seqqout");
-       cv_init(&scp->in_cv, "seqqin");
-       cv_init(&scp->th_cv, "seqstart");
-
-       /*
-        * Init the damn timer
-        */
-
-       scp->mapper = midimapper_addseq(scp, &scp->unit, &scp->mapper_cookie);
-       if (scp->mapper == NULL)
-               goto err;
-
-       scp->seqdev = make_dev(&seq_cdevsw, SND_DEV_SEQ, UID_ROOT, GID_WHEEL,
-           0666, "sequencer%d", scp->unit);
-
-       scp->musicdev = make_dev(&seq_cdevsw, SND_DEV_MUSIC, UID_ROOT,
-           GID_WHEEL, 0666, "music%d", scp->unit);
-
-       if (scp->seqdev == NULL || scp->musicdev == NULL)
-               goto err;
-       /*
-        * TODO: Add to list of sequencers this module provides
-        */
-
-       ret =
-           kproc_create
-           (seq_eventthread, scp, NULL, RFHIGHPID, 0,
-           "sequencer %02d", scp->unit);
-
-       if (ret)
-               goto err;
-
-       scp->seqdev->si_drv1 = scp->musicdev->si_drv1 = scp;
-
-       SEQ_DEBUG(2, printf("sequencer %d created scp %p\n", scp->unit, scp));
-
-       ret = 0;
-
-       mtx_lock(&seqinfo_mtx);
-       seqs[nseq++] = scp;
-       mtx_unlock(&seqinfo_mtx);
-
-       goto ok;
-
-err:
-       if (scp != NULL) {
-               if (scp->seqdev != NULL)
-                       destroy_dev(scp->seqdev);
-               if (scp->musicdev != NULL)
-                       destroy_dev(scp->musicdev);
-               /*
-                * TODO: Destroy mutex and cv
-                */
-               if (scp->midis != NULL)
-                       free(scp->midis, M_TEMP);
-               if (scp->midi_flags != NULL)
-                       free(scp->midi_flags, M_TEMP);
-               if (scp->out_q.b)
-                       free(scp->out_q.b, M_TEMP);
-               if (scp->in_q.b)
-                       free(scp->in_q.b, M_TEMP);
-               free(scp, M_DEVBUF);
-       }
-ok:
-       return ret;
-}
-
-static int
-seq_delunit(int unit)
-{
-       struct seq_softc *scp = seqs[unit];
-       int i;
-
-       //SEQ_DEBUG(4, printf("seq_delunit: %d\n", unit));
-       SEQ_DEBUG(1, printf("seq_delunit: 1 \n"));
-       mtx_lock(&scp->seq_lock);
-
-       scp->playing = 0;
-       scp->done = 1;
-       cv_broadcast(&scp->out_cv);
-       cv_broadcast(&scp->state_cv);
-       cv_broadcast(&scp->reset_cv);
-       SEQ_DEBUG(1, printf("seq_delunit: 2 \n"));
-       cv_wait(&scp->th_cv, &scp->seq_lock);
-       SEQ_DEBUG(1, printf("seq_delunit: 3.0 \n"));
-       mtx_unlock(&scp->seq_lock);
-       SEQ_DEBUG(1, printf("seq_delunit: 3.1 \n"));
-
-       cv_destroy(&scp->state_cv);
-       SEQ_DEBUG(1, printf("seq_delunit: 4 \n"));
-       cv_destroy(&scp->empty_cv);
-       SEQ_DEBUG(1, printf("seq_delunit: 5 \n"));
-       cv_destroy(&scp->reset_cv);
-       SEQ_DEBUG(1, printf("seq_delunit: 6 \n"));
-       cv_destroy(&scp->out_cv);
-       SEQ_DEBUG(1, printf("seq_delunit: 7 \n"));
-       cv_destroy(&scp->in_cv);
-       SEQ_DEBUG(1, printf("seq_delunit: 8 \n"));
-       cv_destroy(&scp->th_cv);
-
-       SEQ_DEBUG(1, printf("seq_delunit: 10 \n"));
-       if (scp->seqdev)
-               destroy_dev(scp->seqdev);
-       SEQ_DEBUG(1, printf("seq_delunit: 11 \n"));
-       if (scp->musicdev)
-               destroy_dev(scp->musicdev);
-       SEQ_DEBUG(1, printf("seq_delunit: 12 \n"));
-       scp->seqdev = scp->musicdev = NULL;
-       if (scp->midis != NULL)
-               free(scp->midis, M_TEMP);
-       SEQ_DEBUG(1, printf("seq_delunit: 13 \n"));
-       if (scp->midi_flags != NULL)
-               free(scp->midi_flags, M_TEMP);
-       SEQ_DEBUG(1, printf("seq_delunit: 14 \n"));
-       free(scp->out_q.b, M_TEMP);
-       SEQ_DEBUG(1, printf("seq_delunit: 15 \n"));
-       free(scp->in_q.b, M_TEMP);
-
-       SEQ_DEBUG(1, printf("seq_delunit: 16 \n"));
-
-       mtx_destroy(&scp->seq_lock);
-       SEQ_DEBUG(1, printf("seq_delunit: 17 \n"));
-       free(scp, M_DEVBUF);
-
-       mtx_lock(&seqinfo_mtx);
-       for (i = unit; i < (nseq - 1); i++)
-               seqs[i] = seqs[i + 1];
-       nseq--;
-       mtx_unlock(&seqinfo_mtx);
-
-       return 0;
-}
-
-int
-seq_modevent(module_t mod, int type, void *data)
-{
-       int retval, r;
-
-       retval = 0;
-
-       switch (type) {
-       case MOD_LOAD:
-               mtx_init(&seqinfo_mtx, "seqmod", NULL, 0);
-               retval = seq_addunit();
-               break;
-
-       case MOD_UNLOAD:
-               while (nseq) {
-                       r = seq_delunit(nseq - 1);
-                       if (r) {
-                               retval = r;
-                               break;
-                       }
-               }
-               if (nseq == 0) {
-                       retval = 0;
-                       mtx_destroy(&seqinfo_mtx);
-               }
-               break;
-
-       default:
-               break;
-       }
-
-       return retval;
-}
-
-static int
-seq_fetch_mid(struct seq_softc *scp, int unit, kobj_t *md)
-{
-
-       if (unit >= scp->midi_number || unit < 0)
-               return EINVAL;
-
-       *md = scp->midis[unit];
-
-       return 0;
-}
-
-int
-mseq_open(struct cdev *i_dev, int flags, int mode, struct thread *td)
-{
-       struct seq_softc *scp = i_dev->si_drv1;
-       int i;
-
-       gone_in(15, "Warning! MIDI sequencer to be removed soon: no longer "
-           "needed or used\n");
-
-       if (scp == NULL)
-               return ENXIO;
-
-       SEQ_DEBUG(3, printf("seq_open: scp %p unit %d, flags 0x%x.\n",
-           scp, scp->unit, flags));
-
-       /*
-        * Mark this device busy.
-        */
-
-       midistat_lock();
-       mtx_lock(&scp->seq_lock);
-       if (scp->busy) {
-               mtx_unlock(&scp->seq_lock);
-               midistat_unlock();
-               SEQ_DEBUG(2, printf("seq_open: unit %d is busy.\n", scp->unit));
-               return EBUSY;
-       }
-       scp->fflags = flags;
-       /*
-       if ((scp->fflags & O_NONBLOCK) != 0)
-               scp->flags |= SEQ_F_NBIO;
-               */
-       scp->music = MIDIDEV(i_dev) == SND_DEV_MUSIC;
-
-       /*
-        * Enumerate the available midi devices
-        */
-       scp->midi_number = 0;
-       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_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)
-                               scp->midis[scp->midi_number] = NULL;
-                       else {
-                               scp->midi_flags[scp->midi_number] =
-                                   SYNTH_QUERY(scp->midis[scp->midi_number]);
-                               scp->midi_number++;
-                       }
-               }
-       }
-       midistat_unlock();
-
-       timer_setvals(scp, 60, 100);
-
-       timer_start(scp);
-       timer_stop(scp);
-       /*
-        * actually, if we're in rdonly mode, we should start the timer
-        */
-       /*
-        * TODO: Handle recording now
-        */
-
-       scp->out_water = MIDIQ_SIZE(scp->out_q) / 2;
-
-       scp->busy = 1;
-       mtx_unlock(&scp->seq_lock);
-
-       SEQ_DEBUG(2, printf("seq_open: opened, mode %s.\n",
-           scp->music ? "music" : "sequencer"));
-       SEQ_DEBUG(2,
-           printf("Sequencer %d %p opened maxunits %d midi_number %d:\n",
-               scp->unit, scp, scp->maxunits, scp->midi_number));
-       for (i = 0; i < scp->midi_number; i++)
-               SEQ_DEBUG(3, printf("  midi %d %p\n", i, scp->midis[i]));
-
-       return 0;
-}
-
-/*
- * mseq_close
- */
-int
-mseq_close(struct cdev *i_dev, int flags, int mode, struct thread *td)
-{
-       int i;
-       struct seq_softc *scp = i_dev->si_drv1;
-       int ret;
-
-       if (scp == NULL)
-               return ENXIO;
-
-       SEQ_DEBUG(2, printf("seq_close: unit %d.\n", scp->unit));
-
-       mtx_lock(&scp->seq_lock);
-
-       ret = ENXIO;
-       if (scp->busy == 0)
-               goto err;
-
-       seq_reset(scp);
-       seq_sync(scp);
-
-       for (i = 0; i < scp->midi_number; i++)
-               if (scp->midis[i])
-                       SYNTH_CLOSE(scp->midis[i]);
-
-       midimapper_close(scp->mapper, scp->mapper_cookie);
-
-       timer_stop(scp);
-
-       scp->busy = 0;
-       ret = 0;
-
-err:
-       SEQ_DEBUG(3, printf("seq_close: closed ret = %d.\n", ret));
-       mtx_unlock(&scp->seq_lock);
-       return ret;
-}
-
-int
-mseq_read(struct cdev *i_dev, struct uio *uio, int ioflag)
-{
-       int retval, used;
-       struct seq_softc *scp = i_dev->si_drv1;
-
-#define SEQ_RSIZE 32
-       u_char buf[SEQ_RSIZE];
-
-       if (scp == NULL)
-               return ENXIO;
-
-       SEQ_DEBUG(7, printf("mseq_read: unit %d, resid %zd.\n",
-           scp->unit, uio->uio_resid));
-
-       mtx_lock(&scp->seq_lock);
-       if ((scp->fflags & FREAD) == 0) {
-               SEQ_DEBUG(2, printf("mseq_read: unit %d is not for reading.\n",
-                   scp->unit));
-               retval = EIO;
-               goto err1;
*** 1364 LINES SKIPPED ***

Reply via email to