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