The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/sound/midi/sequencer.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * The sequencer personality manager.
    3  * 
    4  * Copyright by Hannu Savolainen 1993
    5  * 
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions are
    8  * met: 1. Redistributions of source code must retain the above copyright
    9  * notice, this list of conditions and the following disclaimer. 2.
   10  * Redistributions in binary form must reproduce the above copyright notice,
   11  * this list of conditions and the following disclaimer in the documentation
   12  * and/or other materials provided with the distribution.
   13  * 
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
   15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   17  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   18  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   20  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   21  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * $FreeBSD: releng/5.2/sys/dev/sound/midi/sequencer.c 111815 2003-03-03 12:15:54Z phk $
   27  *
   28  */
   29 
   30 /*
   31  * This is the newmidi sequencer driver. This driver handles io against
   32  * /dev/sequencer, midi input and output event queues and event transmittion
   33  * to and from a midi device or synthesizer.
   34  */
   35 
   36 #include <dev/sound/midi/midi.h>
   37 #include <dev/sound/midi/sequencer.h>
   38 
   39 #define SND_DEV_SEQ     1       /* Sequencer output /dev/sequencer (FM
   40                                    synthesizer and MIDI output) */
   41 #define SND_DEV_MIDIN   2       /* Raw midi access */
   42 #define SND_DEV_MUSIC   8       /* /dev/music, level 2 interface */
   43 
   44 #define MIDIDEV_MODE 0x2000
   45 
   46 /* Length of a sequencer event. */
   47 #define EV_SZ 8
   48 #define IEV_SZ 8
   49 
   50 /* Lookup modes */
   51 #define LOOKUP_EXIST    (0)
   52 #define LOOKUP_OPEN     (1)
   53 #define LOOKUP_CLOSE    (2)
   54 
   55 /*
   56  * These functions goes into seq_op_desc to get called
   57  * from sound.c.
   58  */
   59 
   60 static midi_intr_t seq_intr;
   61 static midi_callback_t seq_callback;
   62 
   63 /* These are the entries to the sequencer driver. */
   64 static d_open_t seq_open;
   65 static d_close_t seq_close;
   66 static d_ioctl_t seq_ioctl;
   67 static d_read_t seq_read;
   68 static d_write_t seq_write;
   69 static d_poll_t seq_poll;
   70 
   71 /*
   72  * This is the device descriptor for the midi sequencer.
   73  */
   74 seqdev_info seq_op_desc = {
   75         "midi sequencer",
   76 
   77         0,
   78 
   79         seq_open,
   80         seq_close,
   81         seq_read,
   82         seq_write,
   83         seq_ioctl,
   84         seq_poll,
   85 
   86         seq_callback,
   87 
   88         SEQ_BUFFSIZE, /* Queue Length */
   89 
   90         0, /* XXX This is not an *audio* device! */
   91 };
   92 
   93 
   94 /* Here is the parameter structure per a device. */
   95 struct seq_softc {
   96         seqdev_info     *devinfo;               /* sequencer device information */
   97 
   98         /* Flags (protected by flag_mtx of mididev_info) */
   99         int             fflags;                 /* Access mode */
  100         int             queueout_pending;       /* Pending for the output queue */
  101         int             seq_mode;               /* Sequencer mode */
  102 
  103         /* Timer counters */
  104         u_long          seq_time;               /* The beggining time of this sequence */
  105         u_long          prev_event_time;        /* The time of the previous event output */
  106         u_long          prev_input_time;        /* The time of the previous event input */
  107         u_long          prev_wakeup_time;       /* The time of the previous wakeup */
  108         struct callout  timeout_ch;             /* Timer callout handler */
  109         long            timer_current;          /* Current timer value */
  110         int             timer_running;          /* State of timer */
  111         int             pending_timer;          /* Timer change operation */
  112         int             pre_event_timeout;      /* Time to wait event input */
  113 
  114         /* Devices */
  115         TAILQ_HEAD(,_mididev_info)      midi_open;      /* Midi devices opened by this sequencer. */
  116         timerdev_info   *timer;                 /* A timer device for /dev/music */
  117 
  118         /*
  119          * XXX not sure to which category these belong.
  120          * (and some might be no-op)
  121          */
  122         int             output_threshould;      /* Sequence output threshould */
  123         snd_sync_parm   sync_parm;              /* AIOSYNC parameter set */
  124         struct thread   *sync_thread;           /* AIOSYNCing thread */
  125 };
  126 
  127 typedef struct seq_softc *sc_p;
  128 
  129 static d_open_t seqopen;
  130 static d_close_t seqclose;
  131 static d_ioctl_t seqioctl;
  132 static d_read_t seqread;
  133 static d_write_t seqwrite;
  134 static d_poll_t seqpoll;
  135 
  136 #define CDEV_MAJOR SEQ_CDEV_MAJOR
  137 static struct cdevsw seq_cdevsw = {
  138         .d_open =       seqopen,
  139         .d_close =      seqclose,
  140         .d_read =       seqread,
  141         .d_write =      seqwrite,
  142         .d_ioctl =      seqioctl,
  143         .d_poll =       seqpoll,
  144         .d_name =       "midi", /* XXX */
  145         .d_maj =        CDEV_MAJOR,
  146 };
  147 
  148 
  149 static TAILQ_HEAD(,_seqdev_info)        seq_info;
  150 /* Mutex to protect seq_info and nseq. */
  151 static struct mtx                       seqinfo_mtx;
  152 /* total number of sequencers */
  153 static u_long                           nseq;
  154 static dev_t                            seq_alias = NODEV;
  155 static dev_t                            music_alias = NODEV;
  156 
  157 SYSCTL_NODE(_hw_midi, OID_AUTO, seq, CTLFLAG_RD, 0, "Midi sequencer");
  158 
  159 int                                     seq_debug;
  160 SYSCTL_INT(_hw_midi_seq, OID_AUTO, debug, CTLFLAG_RW, &seq_debug, 0, "");
  161 
  162 static midi_cmdtab      cmdtab_seqevent[] = {
  163         {SEQ_NOTEOFF,           "SEQ_NOTEOFF"},
  164         {SEQ_NOTEON,            "SEQ_NOTEON"},
  165         {SEQ_WAIT,              "SEQ_WAIT"},
  166         {SEQ_PGMCHANGE,         "SEQ_PGMCHANGE"},
  167         {SEQ_SYNCTIMER,         "SEQ_SYNCTIMER"},
  168         {SEQ_MIDIPUTC,          "SEQ_MIDIPUTC"},
  169         {SEQ_DRUMON,            "SEQ_DRUMON"},
  170         {SEQ_DRUMOFF,           "SEQ_DRUMOFF"},
  171         {SEQ_ECHO,              "SEQ_ECHO"},
  172         {SEQ_AFTERTOUCH,        "SEQ_AFTERTOUCH"},
  173         {SEQ_CONTROLLER,        "SEQ_CONTROLLER"},
  174         {SEQ_BALANCE,           "SEQ_BALANCE"},
  175         {SEQ_VOLMODE,           "SEQ_VOLMODE"},
  176         {SEQ_FULLSIZE,          "SEQ_FULLSIZE"},
  177         {SEQ_PRIVATE,           "SEQ_PRIVATE"},
  178         {SEQ_EXTENDED,          "SEQ_EXTENDED"},
  179         {EV_SEQ_LOCAL,          "EV_SEQ_LOCAL"},
  180         {EV_TIMING,             "EV_TIMING"},
  181         {EV_CHN_COMMON,         "EV_CHN_COMMON"},
  182         {EV_CHN_VOICE,          "EV_CHN_VOICE"},
  183         {EV_SYSEX,              "EV_SYSEX"},
  184         {-1,                    NULL},
  185 };
  186 
  187 midi_cmdtab     cmdtab_seqioctl[] = {
  188         {SNDCTL_SEQ_RESET,      "SNDCTL_SEQ_RESET"},
  189         {SNDCTL_SEQ_SYNC,       "SNDCTL_SEQ_SYNC"},
  190         {SNDCTL_SYNTH_INFO,     "SNDCTL_SYNTH_INFO"},
  191         {SNDCTL_SEQ_CTRLRATE,   "SNDCTL_SEQ_CTRLRATE"},
  192         {SNDCTL_SEQ_GETOUTCOUNT,        "SNDCTL_SEQ_GETOUTCOUNT"},
  193         {SNDCTL_SEQ_GETINCOUNT, "SNDCTL_SEQ_GETINCOUNT"},
  194         {SNDCTL_SEQ_PERCMODE,   "SNDCTL_SEQ_PERCMODE"},
  195         {SNDCTL_FM_LOAD_INSTR,  "SNDCTL_FM_LOAD_INSTR"},
  196         {SNDCTL_SEQ_TESTMIDI,   "SNDCTL_SEQ_TESTMIDI"},
  197         {SNDCTL_SEQ_RESETSAMPLES,       "SNDCTL_SEQ_RESETSAMPLES"},
  198         {SNDCTL_SEQ_NRSYNTHS,   "SNDCTL_SEQ_NRSYNTHS"},
  199         {SNDCTL_SEQ_NRMIDIS,    "SNDCTL_SEQ_NRMIDIS"},
  200         {SNDCTL_MIDI_INFO,      "SNDCTL_MIDI_INFO"},
  201         {SNDCTL_SEQ_THRESHOLD,  "SNDCTL_SEQ_THRESHOLD"},
  202         {SNDCTL_SYNTH_MEMAVL,   "SNDCTL_SYNTH_MEMAVL"},
  203         {SNDCTL_FM_4OP_ENABLE,  "SNDCTL_FM_4OP_ENABLE"},
  204         {SNDCTL_PMGR_ACCESS,    "SNDCTL_PMGR_ACCESS"},
  205         {SNDCTL_SEQ_PANIC,      "SNDCTL_SEQ_PANIC"},
  206         {SNDCTL_SEQ_OUTOFBAND,  "SNDCTL_SEQ_OUTOFBAND"},
  207         {SNDCTL_TMR_TIMEBASE,   "SNDCTL_TMR_TIMEBASE"},
  208         {SNDCTL_TMR_START,      "SNDCTL_TMR_START"},
  209         {SNDCTL_TMR_STOP,       "SNDCTL_TMR_STOP"},
  210         {SNDCTL_TMR_CONTINUE,   "SNDCTL_TMR_CONTINUE"},
  211         {SNDCTL_TMR_TEMPO,      "SNDCTL_TMR_TEMPO"},
  212         {SNDCTL_TMR_SOURCE,     "SNDCTL_TMR_SOURCE"},
  213         {SNDCTL_TMR_METRONOME,  "SNDCTL_TMR_METRONOME"},
  214         {SNDCTL_TMR_SELECT,     "SNDCTL_TMR_SELECT"},
  215         {SNDCTL_MIDI_PRETIME,   "SNDCTL_MIDI_PRETIME"},
  216         {AIONWRITE,             "AIONWRITE"},
  217         {AIOGSIZE,              "AIOGSIZE"},
  218         {AIOSSIZE,              "AIOSSIZE"},
  219         {AIOGFMT,               "AIOGFMT"},
  220         {AIOSFMT,               "AIOSFMT"},
  221         {AIOGMIX,               "AIOGMIX"},
  222         {AIOSMIX,               "AIOSMIX"},
  223         {AIOSTOP,               "AIOSTOP"},
  224         {AIOSYNC,               "AIOSYNC"},
  225         {AIOGCAP,               "AIOGCAP"},
  226         {-1,                    NULL},
  227 };
  228 
  229 midi_cmdtab     cmdtab_timer[] = {
  230         {TMR_WAIT_REL,  "TMR_WAIT_REL"},
  231         {TMR_WAIT_ABS,  "TMR_WAIT_ABS"},
  232         {TMR_STOP,      "TMR_STOP"},
  233         {TMR_START,     "TMR_START"},
  234         {TMR_CONTINUE,  "TMR_CONTINUE"},
  235         {TMR_TEMPO,     "TMR_TEMPO"},
  236         {TMR_ECHO,      "TMR_ECHO"},
  237         {TMR_CLOCK,     "TMR_CLOCK"},
  238         {TMR_SPP,       "TMR_SPP"},
  239         {TMR_TIMESIG,   "TMR_TIMESIG"},
  240         {-1,            NULL},
  241 };
  242 
  243 static midi_cmdtab      cmdtab_seqcv[] = {
  244         {MIDI_NOTEOFF,          "MIDI_NOTEOFF"},
  245         {MIDI_NOTEON,           "MIDI_NOTEON"},
  246         {MIDI_KEY_PRESSURE,     "MIDI_KEY_PRESSURE"},
  247         {-1,                    NULL},
  248 };
  249 
  250 static midi_cmdtab      cmdtab_seqccmn[] = {
  251         {MIDI_CTL_CHANGE,       "MIDI_CTL_CHANGE"},
  252         {MIDI_PGM_CHANGE,       "MIDI_PGM_CHANGE"},
  253         {MIDI_CHN_PRESSURE,     "MIDI_CHN_PRESSURE"},
  254         {MIDI_PITCH_BEND,       "MIDI_PITCH_BEND"},
  255         {MIDI_SYSTEM_PREFIX,    "MIDI_SYSTEM_PREFIX"},
  256         {-1,                    NULL},
  257 };
  258 
  259 
  260 /* The followings are the local function. */
  261 static int seq_init(void);
  262 static int seq_initunit(int unit);
  263 static int seq_queue(sc_p scp, u_char *note);
  264 static void seq_startplay(sc_p scp);
  265 static int seq_playevent(sc_p scp, u_char *event);
  266 static u_long seq_gettime(void);
  267 static int seq_requesttimer(sc_p scp, int delay);
  268 static void seq_stoptimer(sc_p scp);
  269 static void seq_midiinput(sc_p scp, mididev_info *md);
  270 static int seq_extended(sc_p scp, u_char *event);
  271 static int seq_chnvoice(sc_p scp, u_char *event);
  272 static int seq_findvoice(mididev_info *md, int chn, int note) __unused;
  273 static int seq_allocvoice(sc_p scp, mididev_info *md, int chn, int note) __unused;
  274 static int seq_chncommon(sc_p scp, u_char *event);
  275 static int seq_timing(sc_p scp, u_char *event);
  276 static int seq_local(sc_p scp, u_char *event);
  277 static int seq_sysex(sc_p scp, u_char *event);
  278 static int seq_reset(sc_p scp);
  279 static int seq_openmidi(sc_p scp, mididev_info *md, int flags, int mode, struct thread *p);
  280 static int seq_closemidi(sc_p scp, mididev_info *md, int flags, int mode, struct thread *p);
  281 static void seq_panic(sc_p scp);
  282 static int seq_sync(sc_p scp);
  283 
  284 static seqdev_info *get_seqdev_info(dev_t i_dev, int *unit);
  285 static seqdev_info *get_seqdev_info_unit(int unit);
  286 static seqdev_info *create_seqdev_info_unit(int unit, seqdev_info *seq);
  287 static int lookup_mididev(sc_p scp, int unit, int mode, mididev_info **mdp);
  288 static int lookup_mididev_midi(sc_p scp, int unit, int mode, mididev_info **mdp);
  289 static void seq_clone(void *arg, char *name, int namelen, dev_t *dev);
  290 
  291 /*
  292  * Here are the main functions to interact to the user process.
  293  * These are called from snd* functions in sys/i386/isa/snd/sound.c.
  294  */
  295 
  296 static int
  297 seq_init(void)
  298 {
  299         SEQ_DEBUG(printf("seq: initing.\n"));
  300 
  301         mtx_init(&seqinfo_mtx, "seqinf", NULL, MTX_DEF);
  302         TAILQ_INIT(&seq_info);
  303 
  304         seq_initunit(0);
  305         EVENTHANDLER_REGISTER(dev_clone, seq_clone, 0, 1000);
  306 
  307         SEQ_DEBUG(printf("seq: inited.\n"));
  308 
  309         return (0);
  310 }
  311 
  312 static int
  313 seq_initunit(int unit)
  314 {
  315         sc_p scp;
  316         seqdev_info *devinfo;
  317         dev_t seqdev, musicdev;
  318 
  319         /* Allocate the softc. */
  320         scp = malloc(sizeof(*scp), M_DEVBUF, M_WAITOK | M_ZERO);
  321         if (scp == (sc_p)NULL) {
  322                 printf("seq_initunit: unit %d, softc allocation failed.\n", unit);
  323                 return (1);
  324         }
  325 
  326         /* Fill the softc and the seq_info for this unit. */
  327         scp->seq_time = seq_gettime();
  328         scp->prev_event_time = 0;
  329         scp->prev_input_time = 0;
  330         scp->prev_wakeup_time = scp->seq_time;
  331 #if defined(MIDI_OUTOFGIANT)
  332         callout_init(&scp->timeout_ch, 1);
  333 #else
  334         callout_init(&scp->timeout_ch, 0);
  335 #endif /* MIDI_OUTOFGIANT */
  336         scp->timer_current = 0;
  337         scp->timer_running = 0;
  338         scp->queueout_pending = 0;
  339         TAILQ_INIT(&scp->midi_open);
  340         scp->pending_timer = -1;
  341 
  342         scp->devinfo = devinfo = create_seqdev_info_unit(unit, &seq_op_desc);
  343         devinfo->midi_dbuf_in.unit_size = devinfo->midi_dbuf_out.unit_size = EV_SZ;
  344         devinfo->softc = scp;
  345         devinfo->flags = 0;
  346         mtx_unlock(&devinfo->flagqueue_mtx);
  347 
  348         seqdev = make_dev(&seq_cdevsw, MIDIMKMINOR(unit, SND_DEV_SEQ),
  349                           UID_ROOT, GID_WHEEL, 0666, "sequencer%d", unit);
  350         musicdev = make_dev(&seq_cdevsw, MIDIMKMINOR(unit, SND_DEV_MUSIC),
  351                             UID_ROOT, GID_WHEEL, 0666, "music%d", unit);
  352 
  353         mtx_lock(&seqinfo_mtx);
  354         if (seq_alias != NODEV) {
  355                 destroy_dev(seq_alias);
  356                 seq_alias = NODEV;
  357         }
  358         seq_alias = make_dev_alias(seqdev, "sequencer");
  359         if (music_alias != NODEV) {
  360                 destroy_dev(music_alias);
  361                 music_alias = NODEV;
  362         }
  363         music_alias = make_dev_alias(musicdev, "music");
  364         mtx_unlock(&seqinfo_mtx);
  365 
  366         if (timerdev_install() != 0)
  367                 printf("seq_initunit: timerdev_install failed.\n");
  368 
  369         return (0);
  370 }
  371 
  372 int
  373 seq_open(dev_t i_dev, int flags, int mode, struct thread *td)
  374 {
  375         int unit;
  376         sc_p scp;
  377         seqdev_info *sd;
  378 
  379         unit = MIDIUNIT(i_dev);
  380 
  381         SEQ_DEBUG(printf("seq_open: unit %d, flags 0x%x.\n", unit, flags));
  382 
  383         if (unit >= NSEQ_MAX) {
  384                 SEQ_DEBUG(printf("seq_open: unit %d does not exist.\n", unit));
  385                 return (ENXIO);
  386         }
  387 
  388         sd = get_seqdev_info(i_dev, &unit);
  389         if (sd == NULL) {
  390                 SEQ_DEBUG(printf("seq_open: unit %d is not configured.\n", unit));
  391                 return (ENXIO);
  392         }
  393         scp = sd->softc;
  394 
  395         /* Mark this device busy. */
  396         mtx_lock(&sd->flagqueue_mtx);
  397         if ((sd->flags & SEQ_F_BUSY) != 0) {
  398                 mtx_unlock(&sd->flagqueue_mtx);
  399                 SEQ_DEBUG(printf("seq_open: unit %d is busy.\n", unit));
  400                 return (EBUSY);
  401         }
  402         scp->fflags = flags;
  403         sd->flags |= SEQ_F_BUSY;
  404         sd->flags &= ~(SEQ_F_READING | SEQ_F_WRITING);
  405         if ((scp->fflags & O_NONBLOCK) != 0)
  406                 sd->flags |= SEQ_F_NBIO;
  407         scp->seq_mode = MIDIDEV(i_dev);
  408 
  409         /* Init the queue. */
  410         midibuf_clear(&sd->midi_dbuf_in);
  411         midibuf_clear(&sd->midi_dbuf_out);
  412 
  413         /* Init timestamp. */
  414         scp->seq_time = seq_gettime();
  415         scp->prev_event_time = 0;
  416         scp->prev_input_time = 0;
  417         scp->prev_wakeup_time = scp->seq_time;
  418 
  419         if (scp->pending_timer != -1) {
  420                 scp->timer = get_timerdev_info_unit(scp->pending_timer);
  421                 scp->pending_timer = -1;
  422         }
  423         if (scp->timer == NULL)
  424                 scp->timer = get_timerdev_info();
  425         if (scp->timer != NULL) {
  426                 scp->timer->seq = scp;
  427                 mtx_unlock(&scp->timer->mtx);
  428         } else if (scp->seq_mode == SND_DEV_MUSIC) {
  429                 mtx_unlock(&sd->flagqueue_mtx);
  430                 printf("seq_open: no timer available.\n");
  431                 sd->flags &= ~SEQ_F_BUSY;
  432                 return (ENXIO);
  433         }
  434 
  435         if (scp->seq_mode == SND_DEV_MUSIC)
  436                 scp->timer->open(scp->timer, flags, mode, td);
  437 
  438         /* Begin recording if nonblocking. */
  439         if ((sd->flags & (SEQ_F_READING | SEQ_F_NBIO)) == SEQ_F_NBIO && (scp->fflags & FREAD) != 0)
  440                 sd->callback(sd, SEQ_CB_START | SEQ_CB_RD);
  441 
  442         mtx_unlock(&sd->flagqueue_mtx);
  443 
  444         SEQ_DEBUG(printf("seq_open: opened, mode %d.\n", scp->seq_mode == SND_DEV_MUSIC ? 2 : 1));
  445 
  446         return (0);
  447 }
  448 
  449 int
  450 seq_close(dev_t i_dev, int flags, int mode, struct thread *td)
  451 {
  452         int unit;
  453         sc_p scp;
  454         seqdev_info *sd;
  455         mididev_info *md;
  456         timerdev_info *tmd;
  457 
  458         unit = MIDIUNIT(i_dev);
  459 
  460         SEQ_DEBUG(printf("seq_close: unit %d.\n", unit));
  461 
  462         if (unit >= NSEQ_MAX) {
  463                 SEQ_DEBUG(printf("seq_close: unit %d does not exist.\n", unit));
  464                 return (ENXIO);
  465         }
  466 
  467         sd = get_seqdev_info(i_dev, &unit);
  468         if (sd == NULL) {
  469                 SEQ_DEBUG(printf("seq_close: unit %d is not configured.\n", unit));
  470                 return (ENXIO);
  471         }
  472         scp = sd->softc;
  473 
  474         mtx_lock(&sd->flagqueue_mtx);
  475 
  476         if (!(sd->flags & MIDI_F_NBIO))
  477                 seq_sync(scp);
  478 
  479         /* Stop the timer. */
  480         seq_stoptimer(scp);
  481 
  482         /* Reset the sequencer. */
  483         seq_reset(scp);
  484         seq_sync(scp);
  485 
  486         /* Clean up the midi device. */
  487         TAILQ_FOREACH(md, &scp->midi_open, md_linkseq)
  488                 lookup_mididev(scp, md->unit, LOOKUP_CLOSE, NULL);
  489 
  490         /* Stop playing and unmark this device busy. */
  491         sd->flags &= ~(SEQ_F_BUSY | SEQ_F_READING | SEQ_F_WRITING | SEQ_F_INSYNC);
  492 
  493         if (scp->seq_mode == SND_DEV_MUSIC)
  494                 scp->timer->close(scp->timer, flags, mode, td);
  495 
  496         if (scp->timer != NULL) {
  497                 tmd = scp->timer;
  498                 mtx_lock(&tmd->mtx);
  499                 scp->timer = NULL;
  500                 tmd->seq = NULL;
  501                 mtx_unlock(&tmd->mtx);
  502         }
  503 
  504         mtx_unlock(&sd->flagqueue_mtx);
  505 
  506         SEQ_DEBUG(printf("seq_close: closed.\n"));
  507 
  508         return (0);
  509 }
  510 
  511 int
  512 seq_read(dev_t i_dev, struct uio *buf, int flag)
  513 {
  514         int unit, ret, len, lenr;
  515         sc_p scp;
  516         seqdev_info *sd;
  517         u_char *uiobuf;
  518 
  519         unit = MIDIUNIT(i_dev);
  520 
  521         SEQ_DEBUG(printf("seq_read: unit %d, resid %d.\n", unit, buf->uio_resid));
  522 
  523         if (unit >= NSEQ_MAX) {
  524                 SEQ_DEBUG(printf("seq_read: unit %d does not exist.\n", unit));
  525                 return (ENXIO);
  526         }
  527 
  528         sd = get_seqdev_info(i_dev, &unit);
  529         if (sd == NULL) {
  530                 SEQ_DEBUG(printf("seq_read: unit %d is not configured.\n", unit));
  531                 return (ENXIO);
  532         }
  533         scp = sd->softc;
  534         if ((scp->fflags & FREAD) == 0) {
  535                 SEQ_DEBUG(printf("seq_read: unit %d is not for reading.\n", unit));
  536                 return (EIO);
  537         }
  538 
  539         len = buf->uio_resid;
  540         lenr = 0;
  541 
  542         uiobuf = (u_char *)malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
  543         if (uiobuf == NULL)
  544                 return (ENOMEM);
  545 
  546         mtx_lock(&sd->flagqueue_mtx);
  547 
  548         /* Begin recording. */
  549         if ((sd->flags & SEQ_F_READING) == 0)
  550                 sd->callback(sd, SEQ_CB_START | SEQ_CB_RD);
  551 
  552         /* Have we got the data to read? */
  553         if ((sd->flags & SEQ_F_NBIO) != 0 && sd->midi_dbuf_in.rl == 0)
  554                 ret = EAGAIN;
  555         else {
  556                 if ((sd->flags & SEQ_F_NBIO) != 0 && len > sd->midi_dbuf_in.rl)
  557                         len = sd->midi_dbuf_in.rl;
  558                 ret = midibuf_seqread(&sd->midi_dbuf_in, uiobuf, len, &lenr,
  559                                       sd->callback, sd, SEQ_CB_START | SEQ_CB_RD,
  560                                       &sd->flagqueue_mtx);
  561         }
  562 
  563         mtx_unlock(&sd->flagqueue_mtx);
  564 
  565         if (ret == 0 && lenr > 0)
  566                 ret = uiomove(uiobuf, lenr, buf);
  567 
  568         free(uiobuf, M_DEVBUF);
  569 
  570         SEQ_DEBUG(printf("seq_read: ret %d, resid %d.\n", ret, buf->uio_resid));
  571 
  572         return (ret);
  573 }
  574 
  575 int
  576 seq_write(dev_t i_dev, struct uio *buf, int flag)
  577 {
  578         u_char event[EV_SZ], ev_code;
  579         int unit, count, countorg, midiunit, ev_size, p, ret;
  580         sc_p scp;
  581         seqdev_info *sd;
  582         mididev_info *md;
  583 
  584         unit = MIDIUNIT(i_dev);
  585 
  586         SEQ_DEBUG(printf("seq_write: unit %d, resid %d.\n", unit, buf->uio_resid));
  587 
  588         if (unit >= NSEQ_MAX) {
  589                 SEQ_DEBUG(printf("seq_write: unit %d does not exist.\n", unit));
  590                 return (ENXIO);
  591         }
  592 
  593         sd = get_seqdev_info(i_dev, &unit);
  594         if (sd == NULL) {
  595                 SEQ_DEBUG(printf("seq_write: unit %d is not configured.\n", unit));
  596                 return (ENXIO);
  597         }
  598         scp = sd->softc;
  599         if ((scp->fflags & FWRITE) == 0) {
  600                 SEQ_DEBUG(printf("seq_write: unit %d is not for writing.\n", unit));
  601                 return (EIO);
  602         }
  603 
  604         p = 0;
  605         countorg = buf->uio_resid;
  606         count = countorg;
  607 
  608         /* Pick up an event. */
  609         while (count >= 4) {
  610                 if (uiomove((caddr_t)event, 4, buf))
  611                         printf("seq_write: user memory mangled?\n");
  612                 ev_code = event[0];
  613                 SEQ_DEBUG(printf("seq_write: unit %d, event %s.\n", unit, midi_cmdname(ev_code, cmdtab_seqevent)));
  614 
  615                 /* Have a look at the event code. */
  616                 if (ev_code == SEQ_FULLSIZE) {
  617 
  618                         /* A long event, these are the patches/samples for a synthesizer. */
  619                         midiunit = *(u_short *)&event[2];
  620                         mtx_lock(&sd->flagqueue_mtx);
  621                         ret = lookup_mididev(scp, midiunit, LOOKUP_OPEN, &md);
  622                         mtx_unlock(&sd->flagqueue_mtx);
  623                         if (ret != 0)
  624                                 return (ret);
  625 
  626                         SEQ_DEBUG(printf("seq_write: loading a patch to the unit %d.\n", midiunit));
  627 
  628                         ret = md->synth.loadpatch(md, *(short *)&event[0], buf, p + 4, count, 0);
  629                         return (ret);
  630                 }
  631 
  632                 if (ev_code >= 128) {
  633 
  634                         /* Some sort of an extended event. The size is eight bytes. */
  635                         if (scp->seq_mode == SND_DEV_MUSIC && ev_code == SEQ_EXTENDED) {
  636                                 printf("seq_write: invalid level two event %x.\n", ev_code);
  637                                 return (EINVAL);
  638                         }
  639                         ev_size = 8;
  640 
  641                         if (count < ev_size) {
  642                                 /* No more data. Start playing now. */
  643                                 mtx_lock(&sd->flagqueue_mtx);
  644                                 if ((sd->flags & SEQ_F_WRITING) == 0)
  645                                         sd->callback(sd, SEQ_CB_START | SEQ_CB_WR);
  646                                 mtx_unlock(&sd->flagqueue_mtx);
  647                                 buf->uio_resid += 4;
  648 
  649                                 return (0);
  650                         }
  651                         if (uiomove((caddr_t)&event[4], 4, buf))
  652                                 printf("seq_write: user memory mangled?\n");
  653                 } else {
  654 
  655                         /* Not an extended event. The size is four bytes. */
  656                         if (scp->seq_mode == SND_DEV_MUSIC) {
  657                                 printf("seq_write: four byte event in level two mode.\n");
  658                                 return (EINVAL);
  659                         }
  660                         ev_size = 4;
  661                 }
  662                 if (ev_code == SEQ_MIDIPUTC) {
  663                         /* An event passed to the midi device itself. */
  664                         midiunit = event[2];
  665                         mtx_lock(&sd->flagqueue_mtx);
  666                         ret = lookup_mididev_midi(scp, midiunit, LOOKUP_OPEN, &md);
  667                         mtx_unlock(&sd->flagqueue_mtx);
  668                         if (ret != 0)
  669                                 return (ret);
  670                 }
  671 
  672                 SEQ_DEBUG(printf("seq_write: queueing event %s.\n", midi_cmdname(event[0], cmdtab_seqevent)));
  673                 /* Now we queue the event. */
  674                 mtx_lock(&sd->flagqueue_mtx);
  675                 switch (seq_queue(scp, event)) {
  676                 case EAGAIN:
  677                         /* The queue is full. Start playing now. */
  678                         if ((sd->flags & SEQ_F_WRITING) == 0)
  679                                 sd->callback(sd, SEQ_CB_START | SEQ_CB_WR);
  680                         mtx_unlock(&sd->flagqueue_mtx);
  681                         buf->uio_resid = count;
  682                         SEQ_DEBUG(printf("seq_write: resid %d.\n", buf->uio_resid));
  683                         if (count < countorg)
  684                                 return (0);
  685                         return (EAGAIN);
  686                 case EINTR:
  687                         mtx_unlock(&sd->flagqueue_mtx);
  688                         SEQ_DEBUG(printf("seq_write: resid %d.\n", buf->uio_resid));
  689                         return (EINTR);
  690                 case ERESTART:
  691                         mtx_unlock(&sd->flagqueue_mtx);
  692                         SEQ_DEBUG(printf("seq_write: resid %d.\n", buf->uio_resid));
  693                         return (ERESTART);
  694                 }
  695                 mtx_unlock(&sd->flagqueue_mtx);
  696                 p += ev_size;
  697                 count -= ev_size;
  698         }
  699 
  700         /* We have written every single data. Start playing now. */
  701         mtx_lock(&sd->flagqueue_mtx);
  702         if ((sd->flags & SEQ_F_WRITING) == 0)
  703                 sd->callback(sd, SEQ_CB_START | SEQ_CB_WR);
  704         mtx_unlock(&sd->flagqueue_mtx);
  705 
  706         SEQ_DEBUG(printf("seq_write: resid %d.\n", buf->uio_resid));
  707 
  708         return (0);
  709 }
  710 
  711 int
  712 seq_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
  713 {
  714         int unit, midiunit, ret, tmp;
  715         sc_p scp;
  716         seqdev_info *sd;
  717         mididev_info *md;
  718         struct synth_info *synthinfo;
  719         struct midi_info *midiinfo;
  720         struct patmgr_info *patinfo;
  721         struct seq_event_rec *event;
  722         struct snd_size *sndsize;
  723 
  724         unit = MIDIUNIT(i_dev);
  725 
  726         SEQ_DEBUG(printf("seq_ioctl: unit %d, cmd %s.\n", unit, midi_cmdname(cmd, cmdtab_seqioctl)));
  727 
  728         if (unit >= NSEQ_MAX) {
  729                 SEQ_DEBUG(printf("seq_ioctl: unit %d does not exist.\n", unit));
  730                 return (ENXIO);
  731         }
  732         sd = get_seqdev_info(i_dev, &unit);
  733         if (sd == NULL) {
  734                 SEQ_DEBUG(printf("seq_ioctl: unit %d is not configured.\n", unit));
  735                 return (ENXIO);
  736         }
  737         scp = sd->softc;
  738 
  739         ret = 0;
  740 
  741         switch (cmd) {
  742 
  743                 /*
  744                  * we start with the new ioctl interface.
  745                  */
  746         case AIONWRITE: /* how many bytes can be written ? */
  747                 mtx_lock(&sd->flagqueue_mtx);
  748                 *(int *)arg = sd->midi_dbuf_out.fl;
  749                 mtx_unlock(&sd->flagqueue_mtx);
  750                 SEQ_DEBUG(printf("seq_ioctl: fl %d.\n", *(int *)arg));
  751                 break;
  752 
  753         case AIOSSIZE:     /* set the current blocksize */
  754                 sndsize = (struct snd_size *)arg;
  755                 SEQ_DEBUG(printf("seq_ioctl: play %d, rec %d.\n", sndsize->play_size, sndsize->rec_size));
  756                 mtx_lock(&sd->flagqueue_mtx);
  757                 if (sndsize->play_size <= sd->midi_dbuf_out.unit_size && sndsize->rec_size <= sd->midi_dbuf_in.unit_size) {
  758                         sd->midi_dbuf_out.blocksize = sd->midi_dbuf_out.unit_size;
  759                         sd->midi_dbuf_in.blocksize = sd->midi_dbuf_in.unit_size;
  760                         sndsize->play_size = sd->midi_dbuf_out.blocksize;
  761                         sndsize->rec_size = sd->midi_dbuf_in.blocksize;
  762                         sd->flags &= ~MIDI_F_HAS_SIZE;
  763                         mtx_unlock(&sd->flagqueue_mtx);
  764                 }
  765                 else {
  766                         if (sndsize->play_size > sd->midi_dbuf_out.bufsize / 4)
  767                                 sndsize->play_size = sd->midi_dbuf_out.bufsize / 4;
  768                         if (sndsize->rec_size > sd->midi_dbuf_in.bufsize / 4)
  769                                 sndsize->rec_size = sd->midi_dbuf_in.bufsize / 4;
  770                         /* Round up the size to the multiple of EV_SZ. */
  771                         sd->midi_dbuf_out.blocksize =
  772                             ((sndsize->play_size + sd->midi_dbuf_out.unit_size - 1)
  773                              / sd->midi_dbuf_out.unit_size) * sd->midi_dbuf_out.unit_size;
  774                         sd->midi_dbuf_in.blocksize =
  775                             ((sndsize->rec_size + sd->midi_dbuf_in.unit_size - 1)
  776                              / sd->midi_dbuf_in.unit_size) * sd->midi_dbuf_in.unit_size;
  777                         sndsize->play_size = sd->midi_dbuf_out.blocksize;
  778                         sndsize->rec_size = sd->midi_dbuf_in.blocksize;
  779                         sd->flags |= MIDI_F_HAS_SIZE;
  780                         mtx_unlock(&sd->flagqueue_mtx);
  781                 }       
  782 
  783                 ret = 0;
  784                 break;
  785 
  786         case AIOGSIZE:  /* get the current blocksize */
  787                 sndsize = (struct snd_size *)arg;
  788                 mtx_lock(&sd->flagqueue_mtx);
  789                 sndsize->play_size = sd->midi_dbuf_out.blocksize;
  790                 sndsize->rec_size = sd->midi_dbuf_in.blocksize;
  791                 mtx_unlock(&sd->flagqueue_mtx);
  792                 SEQ_DEBUG(printf("seq_ioctl: play %d, rec %d.\n", sndsize->play_size, sndsize->rec_size));
  793 
  794                 ret = 0;
  795                 break;
  796 
  797         case AIOSTOP:
  798                 if (*(int *)arg == AIOSYNC_PLAY) {
  799 
  800                         /* Stop writing. */
  801                         mtx_lock(&sd->flagqueue_mtx);
  802                         sd->callback(sd, SEQ_CB_ABORT | SEQ_CB_WR);
  803                         mtx_unlock(&sd->flagqueue_mtx);
  804 
  805                         /* Pass the ioctl to the midi devices. */
  806                         TAILQ_FOREACH(md, &scp->midi_open, md_linkseq) {
  807                                 if ((md->flags & MIDI_F_WRITING) != 0)
  808                                         midi_ioctl(MIDIMKDEV(major(i_dev), md->unit, SND_DEV_MIDIN), cmd, (caddr_t)arg, mode, td);
  809                         }
  810 
  811                         mtx_lock(&sd->flagqueue_mtx);
  812                         *(int *)arg = sd->midi_dbuf_out.rl;
  813                         mtx_unlock(&sd->flagqueue_mtx);
  814                 }
  815                 else if (*(int *)arg == AIOSYNC_CAPTURE) {
  816 
  817                         /* Stop reading. */
  818                         mtx_lock(&sd->flagqueue_mtx);
  819                         sd->callback(sd, SEQ_CB_ABORT | SEQ_CB_RD);
  820                         mtx_unlock(&sd->flagqueue_mtx);
  821 
  822                         /* Pass the ioctl to the midi devices. */
  823                         TAILQ_FOREACH(md, &scp->midi_open, md_linkseq) {
  824                                 if ((md->flags & MIDI_F_WRITING) != 0)
  825                                         midi_ioctl(MIDIMKDEV(major(i_dev), md->unit, SND_DEV_MIDIN), cmd, (caddr_t)arg, mode, td);
  826                         }
  827 
  828                         mtx_lock(&sd->flagqueue_mtx);
  829                         *(int *)arg = sd->midi_dbuf_in.rl;
  830                         mtx_unlock(&sd->flagqueue_mtx);
  831                 }
  832 
  833                 ret = 0;
  834                 break;
  835 
  836         case AIOSYNC:
  837                 mtx_lock(&sd->flagqueue_mtx);
  838                 scp->sync_parm = *(snd_sync_parm *)arg;
  839                 mtx_unlock(&sd->flagqueue_mtx);
  840 
  841                 /* XXX Should select(2) against us watch the blocksize, or sync_parm? */
  842 
  843                 ret = 0;
  844                 break;
  845 
  846         case FIONBIO: /* set/clear non-blocking i/o */
  847                 mtx_lock(&sd->flagqueue_mtx);
  848                 if (*(int *)arg == 0)
  849                         sd->flags &= ~SEQ_F_NBIO ;
  850                 else
  851                         sd->flags |= SEQ_F_NBIO ;
  852                 mtx_unlock(&sd->flagqueue_mtx);
  853                 MIDI_DEBUG(printf("seq_ioctl: arg %d.\n", *(int *)arg));
  854                 break ;
  855 
  856         case SNDCTL_TMR_TIMEBASE:
  857         case SNDCTL_TMR_TEMPO:
  858         case SNDCTL_TMR_START:
  859         case SNDCTL_TMR_STOP:
  860         case SNDCTL_TMR_CONTINUE:
  861         case SNDCTL_TMR_METRONOME:
  862         case SNDCTL_TMR_SOURCE:
  863                 mtx_lock(&sd->flagqueue_mtx);
  864                 if (scp->seq_mode != SND_DEV_MUSIC) {
  865                         ret = EINVAL;
  866                         mtx_unlock(&sd->flagqueue_mtx);
  867                         break;
  868                 }
  869                 mtx_unlock(&sd->flagqueue_mtx);
  870                 /* XXX We should adopt am sx to protect scp->timer */
  871                 ret = scp->timer->ioctl(scp->timer, cmd, arg, mode, td);
  872                 break;
  873         case SNDCTL_TMR_SELECT:
  874                 mtx_lock(&sd->flagqueue_mtx);
  875                 if (scp->seq_mode != SND_DEV_MUSIC) {
  876                         ret = EINVAL;
  877                         mtx_unlock(&sd->flagqueue_mtx);
  878                         break;
  879                 }
  880                 mtx_unlock(&sd->flagqueue_mtx);
  881                 scp->pending_timer = *(int *)arg;
  882                 mtx_lock(&sd->flagqueue_mtx);
  883                 if (scp->pending_timer < 0) {
  884                         scp->pending_timer = -1;
  885                         ret = EINVAL;
  886                         mtx_unlock(&sd->flagqueue_mtx);
  887                         break;
  888                 }
  889                 mtx_unlock(&sd->flagqueue_mtx);
  890                 SEQ_DEBUG(printf("seq_ioctl: new timer %d.\n", *(int *)arg));
  891                 ret = 0;
  892                 break;
  893         case SNDCTL_SEQ_PANIC:
  894                 mtx_lock(&sd->flagqueue_mtx);
  895                 seq_panic(scp);
  896                 mtx_unlock(&sd->flagqueue_mtx);
  897                 ret = 0;
  898                 break;
  899         case SNDCTL_SEQ_SYNC:
  900                 if (mode == O_RDONLY) {
  901                         ret = 0;
  902                         break;
  903                 }
  904                 mtx_lock(&scp->devinfo->flagqueue_mtx);
  905                 ret = seq_sync(scp);
  906                 mtx_unlock(&scp->devinfo->flagqueue_mtx);
  907                 break;
  908         case SNDCTL_SEQ_RESET:
  909                 mtx_lock(&scp->devinfo->flagqueue_mtx);
  910                 seq_reset(scp);
  911                 mtx_unlock(&scp->devinfo->flagqueue_mtx);
  912                 ret = 0;
  913                 break;
  914         case SNDCTL_SEQ_TESTMIDI:
  915                 mtx_lock(&sd->flagqueue_mtx);
  916                 ret = lookup_mididev_midi(scp, *(int *)arg, LOOKUP_OPEN, &md);
  917                 mtx_unlock(&sd->flagqueue_mtx);
  918                 break;
  919         case SNDCTL_SEQ_GETINCOUNT:
  920                 if (mode == O_WRONLY)
  921                         *(int *)arg = 0;
  922                 else {
  923                         mtx_lock(&sd->flagqueue_mtx);
  924                         *(int *)arg = sd->midi_dbuf_in.rl;
  925                         mtx_unlock(&sd->flagqueue_mtx);
  926                         SEQ_DEBUG(printf("seq_ioctl: incount %d.\n", *(int *)arg));
  927                 }
  928                 ret = 0;
  929                 break;
  930         case SNDCTL_SEQ_GETOUTCOUNT:
  931                 if (mode == O_RDONLY)
  932                         *(int *)arg = 0;
  933                 else {
  934                         mtx_lock(&sd->flagqueue_mtx);
  935                         *(int *)arg = sd->midi_dbuf_out.fl;
  936                         mtx_unlock(&sd->flagqueue_mtx);
  937                         SEQ_DEBUG(printf("seq_ioctl: outcount %d.\n", *(int *)arg));
  938                 }
  939                 ret = 0;
  940                 break;
  941         case SNDCTL_SEQ_CTRLRATE:
  942                 mtx_lock(&sd->flagqueue_mtx);
  943                 if (scp->seq_mode == SND_DEV_MUSIC) {
  944                         mtx_unlock(&sd->flagqueue_mtx);
  945                         ret = scp->timer->ioctl(scp->timer, cmd, arg, mode, td);
  946                         break;
  947                 }
  948                 mtx_unlock(&sd->flagqueue_mtx);
  949                 if (*(int *)arg != 0) {
  950                         ret = EINVAL;
  951                         break;
  952                 }
  953                 *(int *)arg = hz;
  954                 SEQ_DEBUG(printf("seq_ioctl: ctrlrate %d.\n", *(int *)arg));
  955                 ret = 0;
  956                 break;
  957         case SNDCTL_SEQ_RESETSAMPLES:
  958                 mtx_lock(&sd->flagqueue_mtx);
  959                 ret = lookup_mididev(scp, *(int *)arg, LOOKUP_OPEN, &md);
  960                 mtx_unlock(&sd->flagqueue_mtx);
  961                 if (ret != 0)
  962                         break;
  963                 ret = midi_ioctl(MIDIMKDEV(major(i_dev), *(int *)arg, SND_DEV_MIDIN), cmd, arg, mode, td);
  964                 break;
  965         case SNDCTL_SEQ_NRSYNTHS:
  966                 mtx_lock(&sd->flagqueue_mtx);
  967                 if (scp->seq_mode == SND_DEV_MUSIC)
  968                         *(int *)arg = mididev_synth_number() + mididev_midi_number();
  969                 else
  970                         *(int *)arg = mididev_synth_number();
  971                 mtx_unlock(&sd->flagqueue_mtx);
  972                 SEQ_DEBUG(printf("seq_ioctl: synths %d.\n", *(int *)arg));
  973                 ret = 0;
  974                 break;
  975         case SNDCTL_SEQ_NRMIDIS:
  976                 mtx_lock(&sd->flagqueue_mtx);
  977                 if (scp->seq_mode == SND_DEV_MUSIC)
  978                         *(int *)arg = 0;
  979                 else
  980                         *(int *)arg = mididev_midi_number();
  981                 mtx_unlock(&sd->flagqueue_mtx);
  982                 SEQ_DEBUG(printf("seq_ioctl: midis %d.\n", *(int *)arg));
  983                 ret = 0;
  984                 break;
  985         case SNDCTL_SYNTH_MEMAVL:
  986                 mtx_lock(&sd->flagqueue_mtx);
  987                 ret = lookup_mididev(scp, *(int *)arg, LOOKUP_OPEN, &md);
  988                 mtx_unlock(&sd->flagqueue_mtx);
  989                 if (ret != 0)
  990                         break;
  991                 ret = midi_ioctl(MIDIMKDEV(major(i_dev), *(int *)arg, SND_DEV_MIDIN), cmd, arg, mode, td);
  992                 break;
  993         case SNDCTL_FM_4OP_ENABLE:
  994                 mtx_lock(&sd->flagqueue_mtx);
  995                 ret = lookup_mididev(scp, *(int *)arg, LOOKUP_OPEN, &md);
  996                 mtx_unlock(&sd->flagqueue_mtx);
  997                 if (ret != 0)
  998                         break;
  999                 ret = midi_ioctl(MIDIMKDEV(major(i_dev), *(int *)arg, SND_DEV_MIDIN), cmd, arg, mode, td);
 1000                 break;
 1001         case SNDCTL_SYNTH_INFO:
 1002                 synthinfo = (struct synth_info *)arg;
 1003                 midiunit = synthinfo->device;
 1004                 mtx_lock(&sd->flagqueue_mtx);
 1005                 ret = lookup_mididev(scp, midiunit, LOOKUP_OPEN, &md);
 1006                 mtx_unlock(&sd->flagqueue_mtx);
 1007                 if (ret != 0)
 1008                         break;
 1009                 ret = midi_ioctl(MIDIMKDEV(major(i_dev), midiunit, SND_DEV_MIDIN), cmd, arg, mode, td);
 1010                 break;
 1011         case SNDCTL_SEQ_OUTOFBAND:
 1012                 event = (struct seq_event_rec *)arg;
 1013                 mtx_lock(&sd->flagqueue_mtx);
 1014                 ret = seq_playevent(scp, event->arr);
 1015                 mtx_unlock(&sd->flagqueue_mtx);
 1016                 break;
 1017         case SNDCTL_MIDI_INFO:
 1018                 midiinfo = (struct midi_info *)arg;
 1019                 midiunit = midiinfo->device;
 1020                 mtx_lock(&sd->flagqueue_mtx);
 1021                 ret = lookup_mididev_midi(scp, midiunit, LOOKUP_OPEN, &md);
 1022                 mtx_unlock(&sd->flagqueue_mtx);
 1023                 if (ret != 0)
 1024                         break;
 1025                 ret = midi_ioctl(MIDIMKDEV(major(i_dev), midiunit, SND_DEV_MIDIN), cmd, arg, mode, td);
 1026                 break;
 1027         case SNDCTL_PMGR_IFACE:
 1028                 patinfo = (struct patmgr_info *)arg;
 1029                 midiunit = patinfo->device;
 1030                 mtx_lock(&sd->flagqueue_mtx);
 1031                 ret = lookup_mididev(scp, midiunit, LOOKUP_OPEN, &md);
 1032                 mtx_unlock(&sd->flagqueue_mtx);
 1033                 if (ret != 0)
 1034                         break;
 1035                 ret = midi_ioctl(MIDIMKDEV(major(i_dev), midiunit, SND_DEV_MIDIN), cmd, arg, mode, td);
 1036                 break;
 1037         case SNDCTL_PMGR_ACCESS:
 1038                 patinfo = (struct patmgr_info *)arg;
 1039                 midiunit = patinfo->device;
 1040                 mtx_lock(&sd->flagqueue_mtx);
 1041                 ret = lookup_mididev(scp, midiunit, LOOKUP_OPEN, &md);
 1042                 mtx_unlock(&sd->flagqueue_mtx);
 1043                 if (ret != 0)
 1044                         break;
 1045                 ret = midi_ioctl(MIDIMKDEV(major(i_dev), midiunit, SND_DEV_MIDIN), cmd, arg, mode, td);
 1046                 break;
 1047         case SNDCTL_SEQ_THRESHOLD:
 1048                 mtx_lock(&sd->flagqueue_mtx);
 1049                 RANGE(*(int *)arg, 1, sd->midi_dbuf_out.bufsize - 1);
 1050                 scp->output_threshould = *(int *)arg;
 1051                 mtx_unlock(&sd->flagqueue_mtx);
 1052                 SEQ_DEBUG(printf("seq_ioctl: threshold %d.\n", *(int *)arg));
 1053                 ret = 0;
 1054                 break;
 1055         case SNDCTL_MIDI_PRETIME:
 1056                 tmp = *(int *)arg;
 1057                 if (tmp < 0)
 1058                         tmp = 0;
 1059                 mtx_lock(&sd->flagqueue_mtx);
 1060                 scp->pre_event_timeout = (hz * tmp) / 10;
 1061                 *(int *)arg = scp->pre_event_timeout;
 1062                 mtx_unlock(&sd->flagqueue_mtx);
 1063                 SEQ_DEBUG(printf("seq_ioctl: pretime %d.\n", *(int *)arg));
 1064                 ret = 0;
 1065                 break;
 1066         default:
 1067                 if ((scp->fflags & O_ACCMODE) == FREAD) {
 1068                         ret = EIO;
 1069                         break;
 1070                 }
 1071                 mtx_lock(&sd->flagqueue_mtx);
 1072                 ret = lookup_mididev(scp, 0, LOOKUP_OPEN, &md);
 1073                 mtx_unlock(&sd->flagqueue_mtx);
 1074                 if (ret != 0)
 1075                         break;
 1076                 ret = midi_ioctl(MIDIMKDEV(major(i_dev), 0, SND_DEV_MIDIN), cmd, arg, mode, td);
 1077                 break;
 1078         }
 1079 
 1080         return (ret);
 1081 }
 1082 
 1083 int
 1084 seq_poll(dev_t i_dev, int events, struct thread *td)
 1085 {
 1086         int unit, ret, lim;
 1087         sc_p scp;
 1088         seqdev_info *sd;
 1089 
 1090         unit = MIDIUNIT(i_dev);
 1091 
 1092         SEQ_DEBUG(printf("seq_poll: unit %d.\n", unit));
 1093 
 1094         if (unit >= NSEQ_MAX) {
 1095                 SEQ_DEBUG(printf("seq_poll: unit %d does not exist.\n", unit));
 1096                 return (ENXIO);
 1097         }
 1098         sd = get_seqdev_info(i_dev, &unit);
 1099         if (sd == NULL) {
 1100                 SEQ_DEBUG(printf("seq_poll: unit %d is not configured.\n", unit));
 1101                 return (ENXIO);
 1102         }
 1103         scp = sd->softc;
 1104 
 1105         mtx_lock(&sd->flagqueue_mtx);
 1106 
 1107         ret = 0;
 1108 
 1109         /* Look up the apropriate queue and select it. */
 1110         if ((events & (POLLOUT | POLLWRNORM)) != 0) {
 1111                 /* Start playing. */
 1112                 sd->callback(sd, SEQ_CB_START | SEQ_CB_WR);
 1113 
 1114                 /* Find out the boundary. */
 1115                 if ((sd->flags & SEQ_F_HAS_SIZE) != 0)
 1116                         lim = sd->midi_dbuf_out.blocksize;
 1117                 else
 1118                         lim = sd->midi_dbuf_out.unit_size;
 1119                 if (sd->midi_dbuf_out.fl < lim)
 1120                         /* No enough space, record select. */
 1121                         selrecord(td, &sd->midi_dbuf_out.sel);
 1122                 else
 1123                         /* We can write now. */
 1124                         ret |= events & (POLLOUT | POLLWRNORM);
 1125         }
 1126         if ((events & (POLLIN | POLLRDNORM)) != 0) {
 1127                 /* Start recording. */
 1128                 sd->callback(sd, SEQ_CB_START | SEQ_CB_RD);
 1129 
 1130                 /* Find out the boundary. */
 1131                 if ((sd->flags & SEQ_F_HAS_SIZE) != 0)
 1132                         lim = sd->midi_dbuf_in.blocksize;
 1133                 else
 1134                         lim = sd->midi_dbuf_in.unit_size;
 1135                 if (sd->midi_dbuf_in.rl < lim)
 1136                         /* No data ready, record select. */
 1137                         selrecord(td, &sd->midi_dbuf_in.sel);
 1138                 else
 1139                         /* We can write now. */
 1140                         ret |= events & (POLLIN | POLLRDNORM);
 1141         }
 1142 
 1143         mtx_unlock(&sd->flagqueue_mtx);
 1144 
 1145         return (ret);
 1146 }
 1147 
 1148 static void
 1149 seq_intr(void *p, mididev_info *md)
 1150 {
 1151         sc_p scp;
 1152         seqdev_info *sd;
 1153 
 1154         sd = (seqdev_info *)p;
 1155         scp = sd->softc;
 1156 
 1157         mtx_lock(&sd->flagqueue_mtx);
 1158 
 1159         /* Restart playing if we have the data to output. */
 1160         if (scp->queueout_pending)
 1161                 sd->callback(sd, SEQ_CB_START | SEQ_CB_WR);
 1162         /* Check the midi device if we are reading. */
 1163         if ((sd->flags & SEQ_F_READING) != 0)
 1164                 seq_midiinput(scp, md);
 1165 
 1166         mtx_unlock(&sd->flagqueue_mtx);
 1167 }
 1168 
 1169 static int
 1170 seq_callback(void *d, int reason)
 1171 {
 1172         int unit;
 1173         sc_p scp;
 1174         seqdev_info *sd;
 1175 
 1176         sd = (seqdev_info *)d;
 1177 
 1178         SEQ_DEBUG(printf("seq_callback: reason 0x%x.\n", reason));
 1179 
 1180         if (sd == NULL) {
 1181                 SEQ_DEBUG(printf("seq_callback: device not configured.\n"));
 1182                 return (ENXIO);
 1183         }
 1184         scp = sd->softc;
 1185         unit = sd->unit;
 1186 
 1187         mtx_assert(&sd->flagqueue_mtx, MA_OWNED);
 1188 
 1189         switch (reason & SEQ_CB_REASON_MASK) {
 1190         case SEQ_CB_START:
 1191                 if ((reason & SEQ_CB_RD) != 0 && (sd->flags & SEQ_F_READING) == 0)
 1192                         /* Begin recording. */
 1193                         sd->flags |= SEQ_F_READING;
 1194                 if ((reason & SEQ_CB_WR) != 0 && (sd->flags & SEQ_F_WRITING) == 0)
 1195                         /* Start playing. */
 1196                         seq_startplay(scp);
 1197                 break;
 1198         case SEQ_CB_STOP:
 1199         case SEQ_CB_ABORT:
 1200                 if ((reason & SEQ_CB_RD) != 0 && (sd->flags & SEQ_F_READING) != 0) {
 1201                         /* Stop recording. */
 1202                         sd->flags &= ~SEQ_F_READING;
 1203                         scp->seq_time = seq_gettime();
 1204                         scp->prev_input_time = 0;
 1205                 }
 1206                 if ((reason & SEQ_CB_WR) != 0 && (sd->flags & SEQ_F_WRITING) != 0) {
 1207                         /* Stop Playing. */
 1208                         sd->flags &= ~SEQ_F_WRITING;
 1209                         scp->queueout_pending = 0;
 1210                         scp->seq_time = seq_gettime();
 1211                         scp->prev_input_time = 0;
 1212 
 1213                         /* Stop the timer. */
 1214                         seq_stoptimer(scp);
 1215                 }
 1216         }
 1217 
 1218         return (0);
 1219 }
 1220 
 1221 /*
 1222  * The functions below here are the libraries for the above ones.
 1223  */
 1224 
 1225 static int
 1226 seq_queue(sc_p scp, u_char *note)
 1227 {
 1228         int unit, err, lenw;
 1229         seqdev_info *sd;
 1230 
 1231         sd = scp->devinfo;
 1232         unit = sd->unit;
 1233 
 1234         mtx_assert(&sd->flagqueue_mtx, MA_OWNED);
 1235 
 1236         SEQ_DEBUG(printf("seq_queue: unit %d.\n", unit));
 1237 
 1238         if ((sd->flags & SEQ_F_INSYNC) != 0)
 1239                 cv_wait(&sd->insync_cv, &sd->flagqueue_mtx);
 1240 
 1241         if (sd->midi_dbuf_out.fl < EV_SZ) {
 1242                 /* We have no space. Start playing if not yet. */
 1243                 if ((sd->flags & SEQ_F_WRITING) == 0)
 1244                         sd->callback(sd, SEQ_CB_START | SEQ_CB_WR);
 1245                 if ((sd->flags & SEQ_F_NBIO) != 0 && sd->midi_dbuf_out.fl < EV_SZ)
 1246                         /* We would block. */
 1247                         return (EAGAIN);
 1248         }
 1249 
 1250         /* Write to the queue. */
 1251         err = midibuf_seqwrite(&sd->midi_dbuf_out, note, EV_SZ, &lenw,
 1252                                sd->callback, sd, SEQ_CB_START | SEQ_CB_WR,
 1253                                &sd->flagqueue_mtx);
 1254 
 1255         if (err == 0) {
 1256                 /* Start playing if we have some data in the queue. */
 1257                 if (sd->midi_dbuf_out.rl >= EV_SZ && ((sd->flags & SEQ_F_WRITING) == 0))
 1258                         sd->callback(sd, SEQ_CB_START | SEQ_CB_WR);
 1259         }
 1260 
 1261         return (err);
 1262 }
 1263 
 1264 static void
 1265 seq_startplay(sc_p scp)
 1266 {
 1267         int unit, lenr;
 1268         u_char event[EV_SZ];
 1269         seqdev_info *sd;
 1270 
 1271         sd = scp->devinfo;
 1272         unit = sd->unit;
 1273 
 1274         mtx_assert(&sd->flagqueue_mtx, MA_OWNED);
 1275 
 1276         sd->flags |= SEQ_F_WRITING;
 1277 
 1278         /* Dequeue the events to play. */
 1279         while (sd->midi_dbuf_out.rl >= EV_SZ) {
 1280 
 1281                 midibuf_seqcopy(&sd->midi_dbuf_out, event, EV_SZ, &lenr,
 1282                                 NULL, NULL, 0,
 1283                                 &sd->flagqueue_mtx);
 1284 
 1285                 switch (seq_playevent(scp, event)) {
 1286                 case TIMERARMED:
 1287                         midibuf_seqdelete(&sd->midi_dbuf_out, EV_SZ, &lenr,
 1288                                           NULL, NULL, 0,
 1289                                           &sd->flagqueue_mtx);
 1290                         return;
 1291                 case QUEUEFULL:
 1292                         /* We cannot play any further. */
 1293                         return;
 1294                 case MORE:
 1295                         midibuf_seqdelete(&sd->midi_dbuf_out, EV_SZ, &lenr,
 1296                                           NULL, NULL, 0,
 1297                                           &sd->flagqueue_mtx);
 1298                         break;
 1299                 }
 1300         }
 1301 
 1302         /* Played every event in the queue. */
 1303         sd->flags &= ~SEQ_F_WRITING;
 1304 }
 1305 
 1306 static int
 1307 seq_playevent(sc_p scp, u_char *event)
 1308 {
 1309         int unit, ret, lenw;
 1310         long *delay;
 1311         seqdev_info *sd;
 1312         mididev_info *md;
 1313 
 1314         sd = scp->devinfo;
 1315         unit = sd->unit;
 1316 
 1317         mtx_assert(&sd->flagqueue_mtx, MA_OWNED);
 1318 
 1319         ret = lookup_mididev(scp, 0, LOOKUP_OPEN, &md);
 1320         if (ret != 0)
 1321                 return (MORE);
 1322 
 1323         SEQ_DEBUG(printf("seq_playevent: unit %d, event %s.\n", sd->unit, midi_cmdname(event[0], cmdtab_seqevent)));
 1324 
 1325         switch(event[0]) {
 1326         case SEQ_NOTEOFF:
 1327                 mtx_unlock(&sd->flagqueue_mtx);
 1328                 SEQ_DEBUG(printf("seq_playevent: chn %d, note %d, vel %d.\n", event[1], event[2], event[3]));
 1329                 if (md->synth.killnote(md, event[1], 255, event[3]) == EAGAIN) {
 1330                         mtx_lock(&sd->flagqueue_mtx);
 1331                         ret = QUEUEFULL;
 1332                         break;
 1333                 }
 1334                 mtx_lock(&sd->flagqueue_mtx);
 1335                 ret = MORE;
 1336                 break;
 1337         case SEQ_NOTEON:
 1338                 mtx_unlock(&sd->flagqueue_mtx);
 1339                 SEQ_DEBUG(printf("seq_playevent: chn %d, note %d, vel %d, aux %d.\n", event[1], event[2], event[3], event[4]));
 1340                 if ((event[4] < 128 || event[4] == 255) && md->synth.startnote(md, event[1], event[2], event[3]) == EAGAIN) {
 1341                         mtx_lock(&sd->flagqueue_mtx);
 1342                         ret = QUEUEFULL;
 1343                         break;
 1344                 }
 1345                 mtx_lock(&sd->flagqueue_mtx);
 1346                 ret = MORE;
 1347                 break;
 1348         case SEQ_WAIT:
 1349 
 1350                 /* Extract the delay. */
 1351                 delay = (long *)event;
 1352                 *delay = (*delay >> 8) & 0xffffff;
 1353                 SEQ_DEBUG(printf("seq_playevent: delay %ld.\n", *delay));
 1354                 if (*delay > 0) {
 1355                         /* Arm the timer. */
 1356                         sd->flags |= SEQ_F_WRITING;
 1357                         if (seq_requesttimer(scp, *delay)) {
 1358                                 ret = TIMERARMED;
 1359                                 break;
 1360                         }
 1361                 }
 1362                 ret = MORE;
 1363                 break;
 1364         case SEQ_PGMCHANGE:
 1365                 SEQ_DEBUG(printf("seq_playevent: chn %d, instr %d.\n", event[1], event[2]));
 1366                 mtx_unlock(&sd->flagqueue_mtx);
 1367                 if (md->synth.setinstr(md, event[1], event[2]) == EAGAIN) {
 1368                         mtx_lock(&sd->flagqueue_mtx);
 1369                         ret = QUEUEFULL;
 1370                         break;
 1371                 }
 1372                 mtx_lock(&sd->flagqueue_mtx);
 1373                 ret = MORE;
 1374                 break;
 1375         case SEQ_SYNCTIMER:
 1376                 /* Reset the timer. */
 1377                 scp->seq_time = seq_gettime();
 1378                 scp->prev_input_time = 0;
 1379                 scp->prev_event_time = 0;
 1380                 scp->prev_wakeup_time = scp->seq_time;
 1381                 ret = MORE;
 1382                 break;
 1383         case SEQ_MIDIPUTC:
 1384                 SEQ_DEBUG(printf("seq_playevent: data 0x%02x, unit %d.\n", event[1], event[2]));
 1385                 /* Pass through to the midi device. */
 1386                 ret = lookup_mididev_midi(scp, event[2], LOOKUP_OPEN, &md);
 1387                 if (ret != 0) {
 1388                         ret = MORE;
 1389                         break;
 1390                 }
 1391                 mtx_unlock(&sd->flagqueue_mtx);
 1392                 if (md->synth.writeraw(md, &event[1], sizeof(event[1]), &lenw, 1) == EAGAIN)
 1393                         /* The queue was full. Try again later. */
 1394                         ret = QUEUEFULL;
 1395                 else
 1396                         ret = MORE;
 1397                 mtx_lock(&sd->flagqueue_mtx);
 1398                 break;
 1399         case SEQ_ECHO:
 1400                 /* Echo this event back. */
 1401                 if (seq_copytoinput(scp, event, 4) == EAGAIN) {
 1402                         ret = QUEUEFULL;
 1403                         break;
 1404                 }
 1405                 ret = MORE;
 1406                 break;
 1407         case SEQ_PRIVATE:
 1408                 ret = lookup_mididev(scp, event[1], LOOKUP_OPEN, &md);
 1409                 if (ret != 0) {
 1410                         ret = MORE;
 1411                         break;
 1412                 }
 1413                 mtx_unlock(&sd->flagqueue_mtx);
 1414                 if (md->synth.hwcontrol(md, event) == EAGAIN) {
 1415                         mtx_lock(&sd->flagqueue_mtx);
 1416                         ret = QUEUEFULL;
 1417                         break;
 1418                 }
 1419                 mtx_lock(&sd->flagqueue_mtx);
 1420                 ret = MORE;
 1421                 break;
 1422         case SEQ_EXTENDED:
 1423                 ret = seq_extended(scp, event);
 1424                 break;
 1425         case EV_CHN_VOICE:
 1426                 ret = seq_chnvoice(scp, event);
 1427                 break;
 1428         case EV_CHN_COMMON:
 1429                 ret = seq_chncommon(scp, event);
 1430                 break;
 1431         case EV_TIMING:
 1432                 ret = seq_timing(scp, event);
 1433                 break;
 1434         case EV_SEQ_LOCAL:
 1435                 ret = seq_local(scp, event);
 1436                 break;
 1437         case EV_SYSEX:
 1438                 ret = seq_sysex(scp, event);
 1439                 break;
 1440         default:
 1441                 ret = MORE;
 1442                 break;
 1443         }
 1444 
 1445         switch (ret) {
 1446         case QUEUEFULL:
 1447                 SEQ_DEBUG(printf("seq_playevent: the queue is full.\n"));
 1448                 /* The queue was full. Try again on the interrupt by the midi device. */
 1449                 sd->flags |= SEQ_F_WRITING;
 1450                 scp->queueout_pending = 1;
 1451                 break;
 1452         case TIMERARMED:
 1453                 SEQ_DEBUG(printf("seq_playevent: armed timer.\n"));
 1454                 sd->flags |= SEQ_F_WRITING;
 1455                 /* FALLTHRU */
 1456         case MORE:
 1457                 scp->queueout_pending = 0;
 1458                 break;
 1459         }
 1460 
 1461         return (ret);
 1462 }
 1463 
 1464 static u_long
 1465 seq_gettime(void)
 1466 {
 1467         struct timeval  timecopy;
 1468 
 1469         getmicrotime(&timecopy);
 1470         return timecopy.tv_usec / (1000000 / hz) + (u_long) timecopy.tv_sec * hz;
 1471 }
 1472 
 1473 static int
 1474 seq_requesttimer(sc_p scp, int delay)
 1475 {
 1476         u_long cur_time, rel_base;
 1477 
 1478         SEQ_DEBUG(printf("seq_requesttimer: unit %d, delay %d.\n", scp->devinfo->unit, delay));
 1479 
 1480         mtx_assert(&scp->devinfo->flagqueue_mtx, MA_OWNED);
 1481 
 1482         cur_time = seq_gettime();
 1483 
 1484         scp->prev_event_time = delay;
 1485         if (delay < 0)
 1486                 /* Request a new timer. */
 1487                 delay = -delay;
 1488         else {
 1489                 rel_base = cur_time - scp->seq_time;
 1490                 if (delay <= rel_base) {
 1491                         seq_stoptimer(scp);
 1492                         return 0;
 1493                 }
 1494                 delay -= rel_base;
 1495         }
 1496 
 1497 #if notdef
 1498         /*
 1499          * Compensate the delay of midi message transmission.
 1500          * XXX Do we have to consider the accumulation of errors
 1501          * less than 1/hz second?
 1502          */
 1503         delay -= (cur_time - scp->prev_wakeup_time);
 1504         if (delay < 1) {
 1505                 printf("sequencer: prev = %lu, cur = %lu, delay = %d, skip sleeping.\n",
 1506                         scp->prev_wakeup_time, cur_time, delay);
 1507                 seq_stoptimer(scp);
 1508                 return 0;
 1509         }
 1510 #endif /* notdef */
 1511 
 1512         callout_reset(&scp->timeout_ch, delay, seq_timer, (void *)scp);
 1513         scp->timer_running = 1;
 1514 
 1515         return 1;
 1516 }
 1517 
 1518 static void
 1519 seq_stoptimer(sc_p scp)
 1520 {
 1521         SEQ_DEBUG(printf("seq_stoptimer: unit %d.\n", scp->devinfo->unit));
 1522 
 1523         mtx_assert(&scp->devinfo->flagqueue_mtx, MA_OWNED);
 1524 
 1525         if (scp->timer_running) {
 1526                 callout_stop(&scp->timeout_ch);
 1527                 scp->timer_running = 0;
 1528         }
 1529 }
 1530 
 1531 static void
 1532 seq_midiinput(sc_p scp, mididev_info *md)
 1533 {
 1534         int unit, midiunit, lenr;
 1535         u_long tstamp;
 1536         u_char event[4];
 1537         seqdev_info *sd;
 1538 
 1539         mtx_assert(&scp->devinfo->flagqueue_mtx, MA_OWNED);
 1540 
 1541         sd = scp->devinfo;
 1542         unit = sd->unit;
 1543 
 1544         /* Can this midi device interrupt for input? */
 1545         midiunit = md->midiunit;
 1546         if (lookup_mididev_midi(scp, midiunit, LOOKUP_EXIST, NULL) != 0)
 1547                 return;
 1548 
 1549         if ((md->flags & MIDI_F_READING) != 0 && md->intrarg == sd) {
 1550                 /* Read the input data. */
 1551                 mtx_unlock(&scp->devinfo->flagqueue_mtx);
 1552                 while (md->synth.readraw(md, &event[1], sizeof(event[1]), &lenr, 1) == 0) {
 1553                         mtx_lock(&scp->devinfo->flagqueue_mtx);
 1554                         tstamp = seq_gettime() - scp->seq_time;
 1555                         if (tstamp != scp->prev_input_time) {
 1556                                 /* Insert a wait between events. */
 1557                                 tstamp = (tstamp << 8) | SEQ_WAIT;
 1558                                 seq_copytoinput(scp, (u_char *)&tstamp, 4);
 1559                                 scp->prev_input_time = tstamp;
 1560                         }
 1561                         bzero(event, sizeof(event));
 1562                         event[0] = SEQ_MIDIPUTC;
 1563                         event[2] = midiunit;
 1564                         event[3] = 0;
 1565                         seq_copytoinput(scp, event, sizeof(event));
 1566                         mtx_unlock(&scp->devinfo->flagqueue_mtx);
 1567                 }
 1568                 mtx_lock(&scp->devinfo->flagqueue_mtx);
 1569         }
 1570 }
 1571 
 1572 int
 1573 seq_copytoinput(void *arg, u_char *event, int len)
 1574 {
 1575         int ret, leni;
 1576         sc_p scp;
 1577         seqdev_info *sd;
 1578 
 1579         scp = arg;
 1580         sd = scp->devinfo;
 1581 
 1582         mtx_assert(&sd->flagqueue_mtx, MA_OWNED);
 1583 
 1584         if (len != 4 && len != 8)
 1585                 return (EINVAL);
 1586         if (scp->seq_mode == SND_DEV_MUSIC && len != 8)
 1587                 return (EINVAL);
 1588 
 1589         ret = midibuf_input_intr(&sd->midi_dbuf_in, event, len, &leni);
 1590         if (ret == EAGAIN)
 1591                 ret = 0;
 1592 
 1593         return (ret);
 1594 }
 1595 
 1596 static int
 1597 seq_extended(sc_p scp, u_char *event)
 1598 {
 1599         int unit;
 1600         seqdev_info *sd;
 1601         mididev_info *md;
 1602 
 1603         sd = scp->devinfo;
 1604         unit = sd->unit;
 1605 
 1606         mtx_assert(&sd->flagqueue_mtx, MA_OWNED);
 1607 
 1608         if (lookup_mididev(scp, event[2], LOOKUP_OPEN, &md) != 0)
 1609                 return (MORE);
 1610 
 1611         SEQ_DEBUG(printf("seq_extended: unit %d, event %s, midiunit %d.\n", unit, midi_cmdname(event[1], cmdtab_seqevent), event[2]));
 1612 
 1613         switch (event[1]) {
 1614         case SEQ_NOTEOFF:
 1615                 mtx_unlock(&sd->flagqueue_mtx);
 1616                 SEQ_DEBUG(printf("seq_extended: chn %d, note %d, vel %d.\n", event[3], event[4], event[5]));
 1617                 if (md->synth.killnote(md, event[3], event[4], event[5]) == EAGAIN) {
 1618                         mtx_lock(&sd->flagqueue_mtx);
 1619                         return (QUEUEFULL);
 1620                 }
 1621                 mtx_lock(&sd->flagqueue_mtx);
 1622                 break;
 1623         case SEQ_NOTEON:
 1624                 mtx_unlock(&sd->flagqueue_mtx);
 1625                 SEQ_DEBUG(printf("seq_extended: chn %d, note %d, vel %d.\n", event[3], event[4], event[5]));
 1626                 if ((event[4] < 128 || event[4] == 255) && md->synth.startnote(md, event[3], event[4], event[5]) == EAGAIN) {
 1627                         mtx_lock(&sd->flagqueue_mtx);
 1628                         return (QUEUEFULL);
 1629                 }
 1630                 mtx_lock(&sd->flagqueue_mtx);
 1631                 break;
 1632         case SEQ_PGMCHANGE:
 1633                 mtx_unlock(&sd->flagqueue_mtx);
 1634                 SEQ_DEBUG(printf("seq_extended: chn %d, instr %d.\n", event[3], event[4]));
 1635                 if (md->synth.setinstr(md, event[3], event[4]) == EAGAIN) {
 1636                         mtx_lock(&sd->flagqueue_mtx);
 1637                         return (QUEUEFULL);
 1638                 }
 1639                 mtx_lock(&sd->flagqueue_mtx);
 1640                 break;
 1641         case SEQ_AFTERTOUCH:
 1642                 mtx_unlock(&sd->flagqueue_mtx);
 1643                 SEQ_DEBUG(printf("seq_extended: chn %d, press %d.\n", event[3], event[4]));
 1644                 if (md->synth.aftertouch(md, event[3], event[4]) == EAGAIN) {
 1645                         mtx_lock(&sd->flagqueue_mtx);
 1646                         return (QUEUEFULL);
 1647                 }
 1648                 mtx_lock(&sd->flagqueue_mtx);
 1649                 break;
 1650         case SEQ_BALANCE:
 1651                 mtx_unlock(&sd->flagqueue_mtx);
 1652                 SEQ_DEBUG(printf("seq_extended: chn %d, pan %d.\n", event[3], event[4]));
 1653                 if (md->synth.panning(md, event[3], (char)event[4]) == EAGAIN) {
 1654                         mtx_lock(&sd->flagqueue_mtx);
 1655                         return (QUEUEFULL);
 1656                 }
 1657                 mtx_lock(&sd->flagqueue_mtx);
 1658                 break;
 1659         case SEQ_CONTROLLER:
 1660                 mtx_unlock(&sd->flagqueue_mtx);
 1661                 SEQ_DEBUG(printf("seq_extended: chn %d, ctrlnum %d, val %d.\n", event[3], event[4], *(short *)&event[5]));
 1662                 if (md->synth.controller(md, event[3], event[4], *(short *)&event[5]) == EAGAIN) {
 1663                         mtx_lock(&sd->flagqueue_mtx);
 1664                         return (QUEUEFULL);
 1665                 }
 1666                 mtx_lock(&sd->flagqueue_mtx);
 1667                 break;
 1668         case SEQ_VOLMODE:
 1669                 mtx_unlock(&sd->flagqueue_mtx);
 1670                 SEQ_DEBUG(printf("seq_extended: mode %d.\n", event[3]));
 1671                 if (md->synth.volumemethod != NULL && md->synth.volumemethod(md, event[3]) == EAGAIN) {
 1672                         mtx_lock(&sd->flagqueue_mtx);
 1673                         return (QUEUEFULL);
 1674                 }
 1675                 mtx_lock(&sd->flagqueue_mtx);
 1676                 break;
 1677         }
 1678 
 1679         return (MORE);
 1680 }
 1681 
 1682 static int
 1683 seq_chnvoice(sc_p scp, u_char *event)
 1684 {
 1685         int voice;
 1686         seqdev_info *sd;
 1687         mididev_info *md;
 1688         u_char dev, cmd, chn, note, parm;
 1689 
 1690         voice = -1;
 1691         dev = event[1];
 1692         cmd = event[2];
 1693         chn = event[3];
 1694         note = event[4];
 1695         parm = event[5];
 1696 
 1697         sd = scp->devinfo;
 1698 
 1699         mtx_assert(&sd->flagqueue_mtx, MA_OWNED);
 1700 
 1701         if (lookup_mididev(scp, dev, LOOKUP_OPEN, &md) != 0)
 1702                 return (MORE);
 1703 
 1704         SEQ_DEBUG(printf("seq_chnvoice: unit %d, dev %d, cmd %s, chn %d, note %d, parm %d.\n",
 1705                          sd->unit,
 1706                          dev,
 1707                          midi_cmdname(cmd, cmdtab_seqcv),
 1708                          chn,
 1709                          note,
 1710                          parm));
 1711 
 1712         if (scp->seq_mode == SND_DEV_MUSIC && md->synth.allocvoice != NULL)
 1713                 voice = seq_allocvoice(scp, md, chn, note);
 1714         switch (cmd) {
 1715         case MIDI_NOTEON:
 1716                 if (note < 128 || note == 255) {
 1717                         if (voice == -1 && scp->seq_mode == SND_DEV_MUSIC && md->synth.allocvoice)
 1718                                 /* This is an internal synthesizer. (FM, GUS, etc) */
 1719                                 if ((voice = seq_allocvoice(scp, md, chn, note)) == EAGAIN)
 1720                                         return (QUEUEFULL);
 1721                         if (voice == -1)
 1722                                 voice = chn;
 1723 
 1724                         if (scp->seq_mode == SND_DEV_MUSIC && chn == 9) {
 1725                                 /* This channel is a percussion. The note number is the patch number. */
 1726                                 mtx_unlock(&sd->flagqueue_mtx);
 1727                                 if (md->synth.setinstr(md, voice, 128 + note) == EAGAIN) {
 1728                                         mtx_lock(&sd->flagqueue_mtx);
 1729                                         return (QUEUEFULL);
 1730                                 }
 1731                                 mtx_lock(&sd->flagqueue_mtx);
 1732 
 1733                                 note = 60; /* Middle C. */
 1734                         }
 1735                         if (scp->seq_mode == SND_DEV_MUSIC) {
 1736                                 mtx_unlock(&sd->flagqueue_mtx);
 1737                                 if (md->synth.setupvoice(md, voice, chn) == EAGAIN) {
 1738                                         mtx_lock(&sd->flagqueue_mtx);
 1739                                         return (QUEUEFULL);
 1740                                 }
 1741                                 mtx_lock(&sd->flagqueue_mtx);
 1742                         }
 1743                         mtx_unlock(&sd->flagqueue_mtx);
 1744                         if (md->synth.startnote(md, voice, note, parm) == EAGAIN) {
 1745                                 mtx_lock(&sd->flagqueue_mtx);
 1746                                 return (QUEUEFULL);
 1747                         }
 1748                         mtx_lock(&sd->flagqueue_mtx);
 1749                 }
 1750                 break;
 1751         case MIDI_NOTEOFF:
 1752                 if (voice == -1)
 1753                         voice = chn;
 1754                 mtx_unlock(&sd->flagqueue_mtx);
 1755                 if (md->synth.killnote(md, voice, note, parm) == EAGAIN) {
 1756                         mtx_lock(&sd->flagqueue_mtx);
 1757                         return (QUEUEFULL);
 1758                 }
 1759                 mtx_lock(&sd->flagqueue_mtx);
 1760                 break;
 1761         case MIDI_KEY_PRESSURE:
 1762                 if (voice == -1)
 1763                         voice = chn;
 1764                 mtx_unlock(&sd->flagqueue_mtx);
 1765                 if (md->synth.aftertouch(md, voice, parm) == EAGAIN) {
 1766                         mtx_lock(&sd->flagqueue_mtx);
 1767                         return (QUEUEFULL);
 1768                 }
 1769                 mtx_lock(&sd->flagqueue_mtx);
 1770                 break;
 1771         }
 1772 
 1773         return (MORE);
 1774 }
 1775 
 1776 static int
 1777 seq_findvoice(mididev_info *md, int chn, int note)
 1778 {
 1779         int i;
 1780         u_short key;
 1781 
 1782         key = (chn << 8) | (note + 1);
 1783 
 1784         mtx_lock(&md->synth.vc_mtx);
 1785         for (i = 0 ; i < md->synth.alloc.max_voice ; i++)
 1786                 if (md->synth.alloc.map[i] == key) {
 1787                         mtx_unlock(&md->synth.vc_mtx);
 1788                         return (i);
 1789                 }
 1790         mtx_unlock(&md->synth.vc_mtx);
 1791 
 1792         return (-1);
 1793 }
 1794 
 1795 static int
 1796 seq_allocvoice(sc_p scp, mididev_info *md, int chn, int note)
 1797 {
 1798         int voice;
 1799         u_short key;
 1800 
 1801         mtx_assert(&scp->devinfo->flagqueue_mtx, MA_OWNED);
 1802 
 1803         key = (chn << 8) | (note + 1);
 1804 
 1805         mtx_unlock(&scp->devinfo->flagqueue_mtx);
 1806         if ((voice = md->synth.allocvoice(md, chn, note, &md->synth.alloc)) == EAGAIN) {
 1807                 mtx_lock(&scp->devinfo->flagqueue_mtx);
 1808                 return (EAGAIN);
 1809         }
 1810         mtx_lock(&scp->devinfo->flagqueue_mtx);
 1811 
 1812         mtx_lock(&md->synth.vc_mtx);
 1813         md->synth.alloc.map[voice] = key;
 1814         md->synth.alloc.alloc_times[voice] = md->synth.alloc.timestamp++;
 1815         mtx_unlock(&md->synth.vc_mtx);
 1816 
 1817         return (voice);
 1818 }
 1819 
 1820 static int
 1821 seq_chncommon(sc_p scp, u_char *event)
 1822 {
 1823         int unit, i, val, key;
 1824         u_short w14;
 1825         u_char dev, cmd, chn, p1;
 1826         seqdev_info *sd;
 1827         mididev_info *md;
 1828 
 1829         dev = event[1];
 1830         cmd = event[2];
 1831         chn = event[3];
 1832         p1 = event[4];
 1833         w14 = *(u_short *)&event[6];
 1834 
 1835         sd = scp->devinfo;
 1836         unit = sd->unit;
 1837 
 1838         mtx_assert(&sd->flagqueue_mtx, MA_OWNED);
 1839 
 1840         if (lookup_mididev(scp, dev, LOOKUP_OPEN, &md) != 0)
 1841                 return (MORE);
 1842 
 1843         SEQ_DEBUG(printf("seq_chnvoice: unit %d, dev %d, cmd %s, chn %d, p1 %d, w14 %d.\n",
 1844                          sd->unit,
 1845                          dev,
 1846                          midi_cmdname(cmd, cmdtab_seqccmn),
 1847                          chn,
 1848                          p1,
 1849                          w14));
 1850 
 1851         switch (cmd) {
 1852         case MIDI_PGM_CHANGE:
 1853                 if (scp->seq_mode == SND_DEV_MUSIC) {
 1854                         mtx_lock(&md->synth.vc_mtx);
 1855                         md->synth.chn_info[chn].pgm_num = p1;
 1856                         mtx_unlock(&md->synth.vc_mtx);
 1857                         mtx_unlock(&sd->flagqueue_mtx);
 1858                         if (md->midiunit >= 0) {
 1859                                 if (md->synth.setinstr(md, chn, p1) == EAGAIN) {
 1860                                         mtx_lock(&sd->flagqueue_mtx);
 1861                                         return (QUEUEFULL);
 1862                                 }
 1863                         }
 1864                         mtx_lock(&sd->flagqueue_mtx);
 1865                 } else {
 1866                         /* For Mode 1. */
 1867                         mtx_unlock(&sd->flagqueue_mtx);
 1868                         if (md->synth.setinstr(md, chn, p1) == EAGAIN) {        
 1869                                 mtx_lock(&sd->flagqueue_mtx);
 1870                                 return (QUEUEFULL);
 1871                         }
 1872                         mtx_lock(&sd->flagqueue_mtx);
 1873                 }
 1874                 break;
 1875         case MIDI_CTL_CHANGE:
 1876                 /* mtx_lock(&md->giant); */
 1877                 if (scp->seq_mode == SND_DEV_MUSIC) {
 1878                         if (chn < 16 && p1 < 128) {
 1879                                 mtx_lock(&md->synth.vc_mtx);
 1880                                 md->synth.chn_info[chn].controllers[p1] = w14 & 0x7f;
 1881                                 if (p1 < 32)
 1882                                         /* We have set the MSB, clear the LSB. */
 1883                                         md->synth.chn_info[chn].controllers[p1 + 32] = 0;
 1884                                 if (md->midiunit >= 0) {
 1885                                         val = w14 & 0x7f;
 1886                                         if (p1 < 64) {
 1887                                                 /* Combine the MSB and the LSB. */
 1888                                                 val = ((md->synth.chn_info[chn].controllers[p1 & ~32] & 0x7f) << 7)
 1889                                                     | (md->synth.chn_info[chn].controllers[p1 | 32] & 0x7f);
 1890                                                 p1 &= ~32;
 1891                                         }
 1892                                         /* Handle all of the notes playing on this channel. */
 1893                                         key = ((int)chn << 8);
 1894                                         for (i = 0 ; i < md->synth.alloc.max_voice ; i++)
 1895                                                 if ((md->synth.alloc.map[i] & 0xff00) == key) {
 1896                                                         mtx_unlock(&md->synth.vc_mtx);
 1897                                                         mtx_unlock(&sd->flagqueue_mtx);
 1898                                                         if (md->synth.controller(md, i, p1, val) == EAGAIN) {
 1899                                                                 mtx_lock(&sd->flagqueue_mtx);
 1900                                                                 return (QUEUEFULL);
 1901                                                         }
 1902                                                         mtx_lock(&sd->flagqueue_mtx);
 1903                                                         mtx_lock(&md->synth.vc_mtx);
 1904                                                 }
 1905                                         mtx_unlock(&md->synth.vc_mtx);
 1906                                 } else {
 1907                                         mtx_unlock(&md->synth.vc_mtx);
 1908                                         mtx_unlock(&sd->flagqueue_mtx);
 1909                                         if (md->synth.controller(md, chn, p1, w14) == EAGAIN) {
 1910                                                 mtx_lock(&sd->flagqueue_mtx);
 1911                                                 return (QUEUEFULL);
 1912                                         }
 1913                                         mtx_lock(&sd->flagqueue_mtx);
 1914                                 }
 1915                         }
 1916                 } else {
 1917                         /* For Mode 1. */
 1918                         mtx_unlock(&sd->flagqueue_mtx);
 1919                         if (md->synth.controller(md, chn, p1, w14) == EAGAIN) {
 1920                                 mtx_lock(&sd->flagqueue_mtx);
 1921                                 return (QUEUEFULL);
 1922                         }
 1923                         mtx_lock(&sd->flagqueue_mtx);
 1924                 }
 1925                 break;
 1926         case MIDI_PITCH_BEND:
 1927                 if (scp->seq_mode == SND_DEV_MUSIC) {
 1928                         mtx_lock(&md->synth.vc_mtx);
 1929                         md->synth.chn_info[chn].bender_value = w14;
 1930                         if (md->midiunit >= 0) {
 1931                                 /* Handle all of the notes playing on this channel. */
 1932                                 key = ((int)chn << 8);
 1933                                 for (i = 0 ; i < md->synth.alloc.max_voice ; i++)
 1934                                         if ((md->synth.alloc.map[i] & 0xff00) == key) {
 1935                                                 mtx_unlock(&md->synth.vc_mtx);
 1936                                                 mtx_unlock(&sd->flagqueue_mtx);
 1937                                                 if (md->synth.bender(md, i, w14) == EAGAIN) {
 1938                                                         mtx_lock(&sd->flagqueue_mtx);
 1939                                                         return (QUEUEFULL);
 1940                                                 }
 1941                                                 mtx_lock(&sd->flagqueue_mtx);
 1942                                         }
 1943                         } else {
 1944                                 mtx_unlock(&md->synth.vc_mtx);
 1945                                 mtx_unlock(&sd->flagqueue_mtx);
 1946                                 if (md->synth.bender(md, chn, w14) == EAGAIN) {
 1947                                         mtx_lock(&sd->flagqueue_mtx);
 1948                                         return (QUEUEFULL);
 1949                                 }
 1950                                 mtx_lock(&sd->flagqueue_mtx);
 1951                         }
 1952                 } else {
 1953                         /* For Mode 1. */
 1954                         mtx_unlock(&sd->flagqueue_mtx);
 1955                         if (md->synth.bender(md, chn, w14) == EAGAIN) {
 1956                                 mtx_lock(&sd->flagqueue_mtx);
 1957                                 return (QUEUEFULL);
 1958                         }
 1959                         mtx_lock(&sd->flagqueue_mtx);
 1960                 }
 1961                 break;
 1962         }
 1963 
 1964         return (MORE);
 1965 }
 1966 
 1967 static int
 1968 seq_timing(sc_p scp, u_char *event)
 1969 {
 1970         int unit, ret;
 1971         long parm;
 1972         seqdev_info *sd;
 1973 
 1974         sd = scp->devinfo;
 1975         unit = sd->unit;
 1976 
 1977         mtx_assert(&sd->flagqueue_mtx, MA_OWNED);
 1978 
 1979         parm = *(long *)&event[4];
 1980 
 1981         if (scp->seq_mode == SND_DEV_MUSIC) {
 1982                 ret = scp->timer->event(scp->timer, event);
 1983                 if (ret == TIMERARMED)
 1984                         sd->flags |= SEQ_F_WRITING;
 1985                 return (ret);
 1986         }
 1987 
 1988         SEQ_DEBUG(printf("seq_timing: unit %d, cmd %s, parm %lu.\n",
 1989                          unit, midi_cmdname(event[1], cmdtab_timer), parm));
 1990 
 1991         ret = MORE;
 1992         switch (event[1]) {
 1993         case TMR_WAIT_REL:
 1994                 parm += scp->prev_event_time;
 1995                 /* FALLTHRU */
 1996         case TMR_WAIT_ABS:
 1997                 if (parm > 0) {
 1998                         sd->flags |= SEQ_F_WRITING;
 1999                         if (seq_requesttimer(scp, parm))
 2000                                 ret = TIMERARMED;
 2001                 }
 2002                 break;
 2003         case TMR_START:
 2004                 scp->seq_time = seq_gettime();
 2005                 scp->prev_input_time = 0;
 2006                 scp->prev_event_time = 0;
 2007                 scp->prev_wakeup_time = scp->seq_time;
 2008                 break;
 2009         case TMR_STOP:
 2010                 break;
 2011         case TMR_CONTINUE:
 2012                 break;
 2013         case TMR_TEMPO:
 2014                 break;
 2015         case TMR_ECHO:
 2016                 if (scp->seq_mode == SND_DEV_MUSIC)
 2017                         seq_copytoinput(scp, event, 8);
 2018                 else {
 2019                         parm = (parm << 8 | SEQ_ECHO);
 2020                         seq_copytoinput(scp, (u_char *)&parm, 4);
 2021                 }
 2022                 break;
 2023         }
 2024 
 2025         SEQ_DEBUG(printf("seq_timing: timer %s.\n",
 2026                          ret == TIMERARMED ? "armed" : "not armed"));
 2027 
 2028         return (ret);
 2029 }
 2030 
 2031 static int
 2032 seq_local(sc_p scp, u_char *event)
 2033 {
 2034         int unit;
 2035         seqdev_info *sd;
 2036 
 2037         sd = scp->devinfo;
 2038         unit = sd->unit;
 2039 
 2040         mtx_assert(&sd->flagqueue_mtx, MA_OWNED);
 2041 
 2042         switch (event[1]) {
 2043         case LOCL_STARTAUDIO:
 2044 #if notyet
 2045                 DMAbuf_start_devices(*(u_int *)&event[4]);
 2046 #endif /* notyet */
 2047                 break;
 2048         }
 2049 
 2050         return (MORE);
 2051 }
 2052 
 2053 static int
 2054 seq_sysex(sc_p scp, u_char *event)
 2055 {
 2056         int unit, i, l;
 2057         seqdev_info *sd;
 2058         mididev_info *md;
 2059 
 2060         sd = scp->devinfo;
 2061         unit = sd->unit;
 2062 
 2063         mtx_assert(&sd->flagqueue_mtx, MA_OWNED);
 2064 
 2065         if (lookup_mididev(scp, event[1], LOOKUP_OPEN, &md) != 0)
 2066                 return (MORE);
 2067 
 2068         l = 0;
 2069         for (i = 0 ; i < 6 && event[i + 2] != 0xff ; i++)
 2070                 l = i + 1;
 2071         if (l > 0) {
 2072                 mtx_unlock(&sd->flagqueue_mtx);
 2073                 if (md->synth.sendsysex(md, &event[2], l) == EAGAIN) {
 2074                         mtx_lock(&sd->flagqueue_mtx);
 2075                         return (QUEUEFULL);
 2076                 }
 2077                 mtx_lock(&sd->flagqueue_mtx);
 2078         }
 2079 
 2080         return (MORE);
 2081 }
 2082 
 2083 void
 2084 seq_timer(void *arg)
 2085 {
 2086         sc_p scp;
 2087         seqdev_info *sd;
 2088 
 2089         scp = arg;
 2090         sd = scp->devinfo;
 2091 
 2092         SEQ_DEBUG(printf("seq_timer: unit %d, timer fired.\n", sd->unit));
 2093 
 2094         /* Record the current timestamp. */
 2095         mtx_lock(&sd->flagqueue_mtx);
 2096 
 2097         scp->timer_running = 0;
 2098         scp->prev_wakeup_time = seq_gettime();
 2099         seq_startplay(scp);
 2100 
 2101         mtx_unlock(&sd->flagqueue_mtx);
 2102 }
 2103 
 2104 static int
 2105 seq_openmidi(sc_p scp, mididev_info *md, int flags, int mode, struct thread *td)
 2106 {
 2107         int midiunit, err, insync, chn;
 2108 
 2109         mtx_assert(&scp->devinfo->flagqueue_mtx, MA_OWNED);
 2110 
 2111         midiunit = md->unit;
 2112 
 2113         SEQ_DEBUG(printf("seq_openmidi: opening midi unit %d.\n", midiunit));
 2114 
 2115         err = midi_open(MIDIMKDEV(MIDI_CDEV_MAJOR, midiunit, SND_DEV_MIDIN), flags, mode, td);
 2116         if (err != 0) {
 2117                 printf("seq_openmidi: failed to open midi device %d.\n", midiunit);
 2118                 return (err);
 2119         }
 2120         mtx_lock(&md->synth.status_mtx);
 2121         mtx_lock(&md->flagqueue_mtx);
 2122         md->intr = seq_intr;
 2123         md->intrarg = scp->devinfo;
 2124         mtx_unlock(&md->flagqueue_mtx);
 2125         md->synth.sysex_state = 0;
 2126         if (scp->seq_mode == SND_DEV_MUSIC) {
 2127                 for (chn = 0 ; chn < 16 ; chn++) {
 2128                         md->synth.chn_info[chn].pgm_num = 0;
 2129                         md->synth.reset(md);
 2130                         md->synth.chn_info[chn].bender_value = (1 << 7);
 2131                 }
 2132         }
 2133         mtx_unlock(&md->synth.status_mtx);
 2134 
 2135         insync = 0;
 2136         if ((scp->devinfo->flags & SEQ_F_INSYNC) != 0) {
 2137                 insync = 1;
 2138                 cv_wait(&scp->devinfo->insync_cv, &scp->devinfo->flagqueue_mtx);
 2139         }
 2140 
 2141         TAILQ_INSERT_TAIL(&scp->midi_open, md, md_linkseq);
 2142 
 2143         if (insync)
 2144                 cv_broadcast(&scp->devinfo->insync_cv);
 2145 
 2146         return (0);
 2147 }
 2148 
 2149 static int
 2150 seq_closemidi(sc_p scp, mididev_info *md, int flags, int mode, struct thread *td)
 2151 {
 2152         int midiunit, insync;
 2153 
 2154         mtx_assert(&scp->devinfo->flagqueue_mtx, MA_OWNED);
 2155 
 2156         if (md == NULL || !MIDICONFED(md)) {
 2157                 SEQ_DEBUG(printf("seq_closemidi: midi device does not exist.\n"));
 2158                 return (ENXIO);
 2159         }
 2160         midiunit = md->unit;
 2161 
 2162         SEQ_DEBUG(printf("seq_closemidi: closing midi unit %d.\n", midiunit));
 2163 
 2164         midi_close(MIDIMKDEV(MIDI_CDEV_MAJOR, midiunit, SND_DEV_MIDIN), flags, mode, td);
 2165         mtx_lock(&md->flagqueue_mtx);
 2166         md->intr = NULL;
 2167         md->intrarg = NULL;
 2168         mtx_unlock(&md->flagqueue_mtx);
 2169 
 2170         insync = 0;
 2171         if ((scp->devinfo->flags & SEQ_F_INSYNC) != 0) {
 2172                 insync = 1;
 2173                 cv_wait(&scp->devinfo->insync_cv, &scp->devinfo->flagqueue_mtx);
 2174         }
 2175 
 2176         TAILQ_REMOVE(&scp->midi_open, md, md_linkseq);
 2177 
 2178         if (insync)
 2179                 cv_broadcast(&scp->devinfo->insync_cv);
 2180 
 2181         return (0);
 2182 }
 2183 
 2184 static void
 2185 seq_panic(sc_p scp)
 2186 {
 2187         mtx_assert(&scp->devinfo->flagqueue_mtx, MA_OWNED);
 2188 
 2189         seq_reset(scp);
 2190 }
 2191 
 2192 static int
 2193 seq_reset(sc_p scp)
 2194 {
 2195         int unit, chn, lenw, ret;
 2196         seqdev_info *sd;
 2197         mididev_info *md;
 2198         u_char c[3];
 2199 
 2200         sd = scp->devinfo;
 2201         unit = sd->unit;
 2202 
 2203         mtx_assert(&sd->flagqueue_mtx, MA_OWNED);
 2204 
 2205         SEQ_DEBUG(printf("seq_reset: unit %d.\n", unit));
 2206 
 2207         if ((sd->flags & SEQ_F_INSYNC) != 0)
 2208                 cv_wait(&sd->insync_cv, &sd->flagqueue_mtx);
 2209 
 2210         /* Stop reading and writing. */
 2211         sd->callback(sd, SEQ_CB_ABORT | SEQ_CB_RD | SEQ_CB_WR);
 2212 
 2213         /* Clear the queues. */
 2214         midibuf_clear(&sd->midi_dbuf_in);
 2215         midibuf_clear(&sd->midi_dbuf_out);
 2216 
 2217         /* Reset the synthesizers. */
 2218         TAILQ_FOREACH(md, &scp->midi_open, md_linkseq)
 2219                 md->synth.reset(md);
 2220 
 2221         if (scp->seq_mode == SND_DEV_MUSIC) {
 2222                 for (chn = 0 ; chn < 16 ; chn++) {
 2223                         TAILQ_FOREACH(md, &scp->midi_open, md_linkseq) {
 2224                                 mtx_unlock(&sd->flagqueue_mtx);
 2225                                 ret = 0;
 2226                                 if (md->synth.controller(md, chn, 123, 0) == EAGAIN /* All notes off. */
 2227                                     || md->synth.controller(md, chn, 121, 0) == EAGAIN /* Reset all controllers. */
 2228                                     || md->synth.bender(md, chn, 1 << 13) == EAGAIN) /* Reset pitch bend. */
 2229                                         ret = EAGAIN;
 2230                                 mtx_lock(&sd->flagqueue_mtx);
 2231                                 return (ret);
 2232                         }
 2233                 }
 2234         } else {
 2235                 TAILQ_FOREACH(md, &scp->midi_open, md_linkseq) {
 2236                         for (chn = 0 ; chn < 16 ; chn++) {
 2237                                 mtx_unlock(&sd->flagqueue_mtx);
 2238                                 c[0] = 0xb0 | (chn & 0x0f);
 2239                                 c[1] = (u_char)0x78; /* All sound off */
 2240                                 c[2] = (u_char)0;
 2241                                 md->synth.writeraw(md, c, 3, &lenw, 0);
 2242                                 c[1] = (u_char)0x7b; /* All note off */
 2243                                 md->synth.writeraw(md, c, 3, &lenw, 0);
 2244                                 c[1] = (u_char)0x79; /* Reset all controller */
 2245                                 md->synth.writeraw(md, c, 3, &lenw, 0);
 2246                                 mtx_lock(&sd->flagqueue_mtx);
 2247                         }
 2248                 }
 2249                 seq_sync(scp);
 2250                 TAILQ_FOREACH(md, &scp->midi_open, md_linkseq)
 2251                         lookup_mididev(scp, md->unit, LOOKUP_CLOSE, NULL);
 2252         }
 2253 
 2254         return (0);
 2255 }
 2256 
 2257 #define SEQ_SYNC_TIMEOUT 8
 2258 static int
 2259 seq_sync(sc_p scp)
 2260 {
 2261         int i, rl;
 2262         seqdev_info *sd;
 2263         mididev_info *md;
 2264 
 2265         sd = scp->devinfo;
 2266 
 2267         mtx_assert(&sd->flagqueue_mtx, MA_OWNED);
 2268 
 2269         SEQ_DEBUG(printf("seq_sync: unit %d.\n", sd->unit));
 2270         sd->flags |= SEQ_F_INSYNC;
 2271 
 2272         while (sd->midi_dbuf_out.rl >= EV_SZ) {
 2273                 if ((sd->flags & SEQ_F_WRITING) == 0)
 2274                         sd->callback(sd, SEQ_CB_START | SEQ_CB_WR);
 2275                 rl = sd->midi_dbuf_out.rl;
 2276                 i = cv_timedwait_sig(&sd->midi_dbuf_out.cv_out, &sd->flagqueue_mtx, SEQ_SYNC_TIMEOUT * hz);
 2277                 if (i == EINTR || i == ERESTART) {
 2278                         if (i == EINTR)
 2279                                 sd->callback(sd, SEQ_CB_STOP | SEQ_CB_WR);
 2280                         sd->flags &= ~SEQ_F_INSYNC;
 2281                         return (i);
 2282                 }
 2283                 if (i == EWOULDBLOCK && rl == sd->midi_dbuf_out.rl && !scp->timer_running) {
 2284                         /* A queue seems to be stuck up. Give up and clear queues. */
 2285                         sd->callback(sd, SEQ_CB_STOP | SEQ_CB_WR);
 2286                         midibuf_clear(&sd->midi_dbuf_out);
 2287                         TAILQ_FOREACH(md, &scp->midi_open, md_linkseq) {
 2288                                 mtx_lock(&md->flagqueue_mtx);
 2289                                 md->callback(md, MIDI_CB_ABORT | MIDI_CB_WR);
 2290                                 midibuf_clear(&md->midi_dbuf_out);
 2291                                 mtx_unlock(&md->flagqueue_mtx);
 2292                         }
 2293                         break;
 2294                 }
 2295         }
 2296 
 2297         /*
 2298          * Since syncing a midi device might block, unlock sd->flagqueue_mtx.
 2299          * Keep sd->midi_dbuf_out from writing by setting SEQ_F_INSYNC.
 2300          * sd->insync_cv is signalled when sync is finished.
 2301          */
 2302         mtx_unlock(&sd->flagqueue_mtx);
 2303 
 2304         TAILQ_FOREACH(md, &scp->midi_open, md_linkseq) {
 2305                 mtx_lock(&md->flagqueue_mtx);
 2306                 midi_sync(md);
 2307                 mtx_unlock(&md->flagqueue_mtx);
 2308         }
 2309 
 2310         mtx_lock(&sd->flagqueue_mtx);
 2311         sd->flags &= ~SEQ_F_INSYNC;
 2312         cv_broadcast(&sd->insync_cv);
 2313 
 2314         return (0);
 2315 }
 2316 
 2317 /*
 2318  * a small utility function which, given a device number, returns
 2319  * a pointer to the associated seqdev_info struct, and sets the unit
 2320  * number.
 2321  */
 2322 static seqdev_info *
 2323 get_seqdev_info(dev_t i_dev, int *unit)
 2324 {
 2325         int u;
 2326 
 2327         if (MIDIDEV(i_dev) != SND_DEV_SEQ && MIDIDEV(i_dev) != SND_DEV_MUSIC)
 2328                 return NULL;
 2329         u = MIDIUNIT(i_dev);
 2330         if (unit)
 2331                 *unit = u ;
 2332 
 2333         return get_seqdev_info_unit(u);
 2334 }
 2335 
 2336 /*
 2337  * a small utility function which, given a unit number, returns
 2338  * a pointer to the associated mididev_info struct.
 2339  */
 2340 seqdev_info *
 2341 get_seqdev_info_unit(int unit)
 2342 {
 2343         seqdev_info *sd;
 2344 
 2345         mtx_lock(&seqinfo_mtx);
 2346         TAILQ_FOREACH(sd, &seq_info, sd_link) {
 2347                 if (sd->unit == unit)
 2348                         break;
 2349         }
 2350         mtx_unlock(&seqinfo_mtx);
 2351 
 2352         return sd;
 2353 }
 2354 
 2355 /* Create a new sequencer device info structure. */
 2356 seqdev_info *
 2357 create_seqdev_info_unit(int unit, seqdev_info *seq)
 2358 {
 2359         seqdev_info *sd, *sdnew;
 2360 
 2361         /* As malloc(9) might block, allocate seqdev_info now. */
 2362         sdnew = malloc(sizeof(seqdev_info), M_DEVBUF, M_WAITOK | M_ZERO);
 2363         if (sdnew == NULL)
 2364                 return NULL;
 2365         bcopy(seq, sdnew, sizeof(seqdev_info));
 2366         sdnew->unit = unit;
 2367         midibuf_init(&sdnew->midi_dbuf_in);
 2368         midibuf_init(&sdnew->midi_dbuf_out);
 2369         mtx_init(&sdnew->flagqueue_mtx, "seqflq", NULL, MTX_DEF);
 2370         cv_init(&sdnew->insync_cv, "seqins");
 2371 
 2372         mtx_lock(&seqinfo_mtx);
 2373 
 2374         TAILQ_FOREACH(sd, &seq_info, sd_link) {
 2375                 if (sd->unit == unit) {
 2376                         mtx_unlock(&seqinfo_mtx);
 2377                         midibuf_destroy(&sdnew->midi_dbuf_in);
 2378                         midibuf_destroy(&sdnew->midi_dbuf_out);
 2379                         mtx_destroy(&sdnew->flagqueue_mtx);
 2380                         cv_destroy(&sdnew->insync_cv);
 2381                         free(sdnew, M_DEVBUF);
 2382                         return sd;
 2383                 }
 2384         }
 2385 
 2386         mtx_lock(&sdnew->flagqueue_mtx);
 2387         TAILQ_INSERT_TAIL(&seq_info, sdnew, sd_link);
 2388         nseq++;
 2389 
 2390         mtx_unlock(&seqinfo_mtx);
 2391 
 2392         return sdnew;
 2393 }
 2394 
 2395 /*
 2396  * Look up a midi device by its unit number opened by this sequencer.
 2397  * If the device is not opened and mode is LOOKUP_OPEN, open the device.
 2398  */
 2399 static int
 2400 lookup_mididev(sc_p scp, int unit, int mode, mididev_info **mdp)
 2401 {
 2402         int ret;
 2403         mididev_info *md;
 2404 
 2405         if (mdp == NULL)
 2406                 mdp = &md;
 2407 
 2408         *mdp = NULL;
 2409 
 2410         mtx_assert(&scp->devinfo->flagqueue_mtx, MA_OWNED);
 2411 
 2412         TAILQ_FOREACH(md, &scp->midi_open, md_linkseq) {
 2413                 if (scp->seq_mode == SND_DEV_MUSIC ? md->unit == unit : md->synthunit == unit) {
 2414                         *mdp = md;
 2415                         if (mode == LOOKUP_CLOSE)
 2416                                 return seq_closemidi(scp, md, scp->fflags, MIDIDEV_MODE, curthread);
 2417 
 2418                         return (md != NULL && MIDICONFED(md)) ? 0 : ENXIO;
 2419                 }
 2420         }
 2421 
 2422         if (mode == LOOKUP_OPEN) {
 2423                 if (scp->seq_mode == SND_DEV_MUSIC)
 2424                         md = get_mididev_info_unit(unit);
 2425                 else
 2426                         md = get_mididev_synth_unit(unit);
 2427                 if (md != NULL) {
 2428                         *mdp = md;
 2429                         ret = seq_openmidi(scp, md, scp->fflags, MIDIDEV_MODE, curthread);
 2430                         return ret;
 2431                 }
 2432         }
 2433 
 2434         return ENXIO;
 2435 }
 2436 
 2437 /*
 2438  * Look up a midi device by its midi unit number opened by this sequencer.
 2439  * If the device is not opened and mode is LOOKUP_OPEN, open the device.
 2440  */
 2441 static int
 2442 lookup_mididev_midi(sc_p scp, int unit, int mode, mididev_info **mdp)
 2443 {
 2444         int ret;
 2445         mididev_info *md;
 2446 
 2447         if (mdp == NULL)
 2448                 mdp = &md;
 2449 
 2450         *mdp = NULL;
 2451 
 2452         if (scp->seq_mode == SND_DEV_MUSIC)
 2453                 return (ENXIO);
 2454 
 2455         mtx_assert(&scp->devinfo->flagqueue_mtx, MA_OWNED);
 2456 
 2457         TAILQ_FOREACH(md, &scp->midi_open, md_linkseq) {
 2458                 if (md->midiunit == unit) {
 2459                         *mdp = md;
 2460                         if (mode == LOOKUP_CLOSE)
 2461                                 return seq_closemidi(scp, md, scp->fflags, MIDIDEV_MODE, curthread);
 2462 
 2463                         return (md != NULL && MIDICONFED(md)) ? 0 : ENXIO;
 2464                 }
 2465         }
 2466 
 2467         if (mode == LOOKUP_OPEN) {
 2468                 md = get_mididev_midi_unit(unit);
 2469                 if (md != NULL) {
 2470                         *mdp = md;
 2471                         ret = seq_openmidi(scp, md, scp->fflags, MIDIDEV_MODE, curthread);
 2472                         return ret;
 2473                 }
 2474         }
 2475 
 2476         return ENXIO;
 2477 }
 2478 
 2479 /* XXX These functions are actually redundant. */
 2480 static int
 2481 seqopen(dev_t i_dev, int flags, int mode, struct thread *td)
 2482 {
 2483         switch (MIDIDEV(i_dev)) {
 2484         case MIDI_DEV_SEQ:
 2485         case MIDI_DEV_MUSIC:
 2486                 return seq_open(i_dev, flags, mode, td);
 2487         }
 2488 
 2489         return (ENXIO);
 2490 }
 2491 
 2492 static int
 2493 seqclose(dev_t i_dev, int flags, int mode, struct thread *td)
 2494 {
 2495         switch (MIDIDEV(i_dev)) {
 2496         case MIDI_DEV_SEQ:
 2497         case MIDI_DEV_MUSIC:
 2498                 return seq_close(i_dev, flags, mode, td);
 2499         }
 2500 
 2501         return (ENXIO);
 2502 }
 2503 
 2504 static int
 2505 seqread(dev_t i_dev, struct uio * buf, int flag)
 2506 {
 2507         switch (MIDIDEV(i_dev)) {
 2508         case MIDI_DEV_SEQ:
 2509         case MIDI_DEV_MUSIC:
 2510                 return seq_read(i_dev, buf, flag);
 2511         }
 2512 
 2513         return (ENXIO);
 2514 }
 2515 
 2516 static int
 2517 seqwrite(dev_t i_dev, struct uio * buf, int flag)
 2518 {
 2519         switch (MIDIDEV(i_dev)) {
 2520         case MIDI_DEV_SEQ:
 2521         case MIDI_DEV_MUSIC:
 2522                 return seq_write(i_dev, buf, flag);
 2523         }
 2524 
 2525         return (ENXIO);
 2526 }
 2527 
 2528 static int
 2529 seqioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
 2530 {
 2531         switch (MIDIDEV(i_dev)) {
 2532         case MIDI_DEV_SEQ:
 2533         case MIDI_DEV_MUSIC:
 2534                 return seq_ioctl(i_dev, cmd, arg, mode, td);
 2535         }
 2536 
 2537         return (ENXIO);
 2538 }
 2539 
 2540 static int
 2541 seqpoll(dev_t i_dev, int events, struct thread *td)
 2542 {
 2543         switch (MIDIDEV(i_dev)) {
 2544         case MIDI_DEV_SEQ:
 2545         case MIDI_DEV_MUSIC:
 2546                 return seq_poll(i_dev, events, td);
 2547         }
 2548 
 2549         return (ENXIO);
 2550 }
 2551 
 2552 static int
 2553 seq_modevent(module_t mod, int type, void *data)
 2554 {
 2555         int retval;
 2556 
 2557         retval = 0;
 2558 
 2559         switch (type) {
 2560         case MOD_LOAD:
 2561                 seq_init();
 2562                 break;
 2563 
 2564         case MOD_UNLOAD:
 2565                 printf("sequencer: unload not supported yet.\n");
 2566                 retval = EOPNOTSUPP;
 2567                 break;
 2568 
 2569         default:
 2570                 break;
 2571         }
 2572 
 2573         return retval;
 2574 }
 2575 
 2576 DEV_MODULE(seq, seq_modevent, NULL);
 2577 
 2578 static void
 2579 seq_clone(arg, name, namelen, dev)
 2580         void *arg;
 2581         char *name;
 2582         int namelen;
 2583         dev_t *dev;
 2584 {
 2585         int u;
 2586 
 2587         if (*dev != NODEV)
 2588                 return;
 2589         if (bcmp(name, "sequencer", 9) != 0)
 2590                 return;
 2591         if (name[10] != '\0' && name[11] != '\0')
 2592                 return;
 2593         u = name[9] - '';
 2594         if (name[10] != '\0') {
 2595                 u *= 10;
 2596                 u += name[10] - '';
 2597         }
 2598         seq_initunit(u);
 2599         *dev = MIDIMKDEV(SEQ_CDEV_MAJOR, u, MIDI_DEV_SEQ);
 2600         return;
 2601 }

Cache object: dfee34cad139a6d82312a8c2ab68b50c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.