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

Cache object: 59c9b2f1df30dd04171607ae75420686


[ 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.