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
|