2 * Copyright (c) 2003 Mathew Kanner
3 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Lennart Augustsson (augustss@netbsd.org).
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
32 * Parts of this file started out as NetBSD: midi.c 1.31
33 * They are mostly gone. Still the most obvious will be the state
37 #include <sys/cdefs.h>
38 __FBSDID("$FreeBSD: head/sys/dev/sound/midi/midi.c 227309 2011-11-07 15:43:11Z ed $");
40 #include <sys/param.h>
41 #include <sys/queue.h>
42 #include <sys/kernel.h>
44 #include <sys/mutex.h>
46 #include <sys/signalvar.h>
48 #include <sys/sysctl.h>
49 #include <sys/types.h>
50 #include <sys/malloc.h>
51 #include <sys/systm.h>
52 #include <sys/fcntl.h>
57 #include <sys/module.h>
58 #include <sys/device.h>
60 #ifdef HAVE_KERNEL_OPTION_HEADERS
64 #include <dev/sound/midi/midi.h>
67 #include <dev/sound/midi/midiq.h>
69 MALLOC_DEFINE(M_MIDI, "midi buffers", "Midi data allocation area");
71 #define PCMMKMINOR(u, d, c) ((((c) & 0xff) << 16) | (((u) & 0x0f) << 4) | ((d) & 0x0f))
72 #define MIDIMKMINOR(u, d, c) PCMMKMINOR(u, d, c)
74 #define MIDI_DEV_RAW 2
75 #define MIDI_DEV_MIDICTL 12
78 MIDI_IN_START, MIDI_IN_SYSEX, MIDI_IN_DATA
82 * The MPU interface current has init() uninit() inqsize(( outqsize()
83 * callback() : fiddle with the tx|rx status.
89 * /dev/rmidi Structure definitions
92 #define MIDI_NAMELEN 16
95 struct lock lock; /* Protects all but queues */
98 int unit; /* Should only be used in midistat */
99 int channel; /* Should only be used in midistat */
102 int flags; /* File flags */
103 char name[MIDI_NAMELEN];
104 struct lock qlock; /* Protects inq, outq and flags */
105 MIDIQ_HEAD(, char) inq, outq;
107 struct kqinfo rkq, wkq;
108 int hiwat; /* QLEN(outq)>High-water -> disable
109 * writes from userland */
110 enum midi_states inq_state;
111 int inq_status, inq_left; /* Variables for the state machine in
112 * Midi_in, this is to provide that
113 * signals only get issued only
114 * complete command packets. */
117 struct synth_midi *synth;
119 TAILQ_ENTRY(snd_midi) link;
127 static synth_open_t midisynth_open;
128 static synth_close_t midisynth_close;
129 static synth_writeraw_t midisynth_writeraw;
130 static synth_killnote_t midisynth_killnote;
131 static synth_startnote_t midisynth_startnote;
132 static synth_setinstr_t midisynth_setinstr;
133 static synth_alloc_t midisynth_alloc;
134 static synth_controller_t midisynth_controller;
135 static synth_bender_t midisynth_bender;
138 static kobj_method_t midisynth_methods[] = {
139 KOBJMETHOD(synth_open, midisynth_open),
140 KOBJMETHOD(synth_close, midisynth_close),
141 KOBJMETHOD(synth_writeraw, midisynth_writeraw),
142 KOBJMETHOD(synth_setinstr, midisynth_setinstr),
143 KOBJMETHOD(synth_startnote, midisynth_startnote),
144 KOBJMETHOD(synth_killnote, midisynth_killnote),
145 KOBJMETHOD(synth_alloc, midisynth_alloc),
146 KOBJMETHOD(synth_controller, midisynth_controller),
147 KOBJMETHOD(synth_bender, midisynth_bender),
151 DEFINE_CLASS(midisynth, midisynth_methods, 0);
154 * Module Exports & Interface
156 * struct midi_chan *midi_init(MPU_CLASS cls, int unit, int chan) int
157 * midi_uninit(struct snd_midi *) 0 == no error EBUSY or other error int
158 * Midi_in(struct midi_chan *, char *buf, int count) int Midi_out(struct
159 * midi_chan *, char *buf, int count)
161 * midi_{in,out} return actual size transfered
167 * midi_devs tailq, holder of all rmidi instances protected by midistat_lock
170 TAILQ_HEAD(, snd_midi) midi_devs;
173 * /dev/midistat variables and declarations, protected by midistat_lock
176 static struct lock midistat_lock;
177 static int midistat_isopen = 0;
178 static struct sbuf midistat_sbuf;
179 static struct cdev *midistat_dev;
182 * /dev/midistat dev_t declarations
185 static d_open_t midistat_open;
186 static d_close_t midistat_close;
187 static d_read_t midistat_read;
189 static void midi_filter_detach(struct knote *);
190 static int midi_filter_read(struct knote *, long);
191 static int midi_filter_write(struct knote *, long);
193 static struct dev_ops midistat_ops = {
194 { "midistat", 0, D_MPSAFE },
195 .d_open = midistat_open,
196 .d_close = midistat_close,
197 .d_read = midistat_read,
200 static struct filterops midi_read_filterops =
201 { FILTEROP_ISFD, NULL, midi_filter_detach, midi_filter_read };
202 static struct filterops midi_write_filterops =
203 { FILTEROP_ISFD, NULL, midi_filter_detach, midi_filter_write };
206 * /dev/rmidi dev_t declarations, struct variable access is protected by
207 * locks contained within the structure.
210 static d_open_t midi_open;
211 static d_close_t midi_close;
212 static d_ioctl_t midi_ioctl;
213 static d_read_t midi_read;
214 static d_write_t midi_write;
215 static d_kqfilter_t midi_kqfilter;
217 static struct dev_ops midi_ops = {
218 { "rmidi", 0, D_MPSAFE },
220 .d_close = midi_close,
222 .d_write = midi_write,
223 .d_ioctl = midi_ioctl,
224 .d_kqfilter = midi_kqfilter,
228 * Prototypes of library functions
231 static int midi_destroy(struct snd_midi *, int);
232 static int midistat_prepare(struct sbuf * s);
233 static int midi_load(void);
234 static int midi_unload(void);
239 SYSCTL_NODE(_hw, OID_AUTO, midi, CTLFLAG_RD, 0, "Midi driver");
240 static SYSCTL_NODE(_hw_midi, OID_AUTO, stat, CTLFLAG_RD, 0, "Status device");
243 /* XXX: should this be moved into debug.midi? */
244 SYSCTL_INT(_hw_midi, OID_AUTO, debug, CTLFLAG_RW, &midi_debug, 0, "");
247 SYSCTL_INT(_hw_midi, OID_AUTO, dumpraw, CTLFLAG_RW, &midi_dumpraw, 0, "");
250 SYSCTL_INT(_hw_midi, OID_AUTO, instroff, CTLFLAG_RW, &midi_instroff, 0, "");
252 int midistat_verbose;
253 SYSCTL_INT(_hw_midi_stat, OID_AUTO, verbose, CTLFLAG_RW,
254 &midistat_verbose, 0, "");
256 #define MIDI_DEBUG(l,a) if(midi_debug>=l) a
262 * Register a new rmidi device. cls midi_if interface unit == 0 means
263 * auto-assign new unit number unit != 0 already assigned a unit number, eg.
264 * not the first channel provided by this device. channel, sub-unit
265 * cookie is passed back on MPU calls Typical device drivers will call with
266 * unit=0, channel=1..(number of channels) and cookie=soft_c and won't care
267 * what unit number is used.
269 * It is an error to call midi_init with an already used unit/channel combo.
271 * Returns NULL on error
275 midi_init(kobj_class_t cls, int unit, int channel, void *cookie)
279 int inqsize, outqsize;
282 MIDI_DEBUG(1, kprintf("midiinit: unit %d/%d.\n", unit, channel));
283 lockmgr(&midistat_lock, LK_EXCLUSIVE);
285 * Protect against call with existing unit/channel or auto-allocate a
289 TAILQ_FOREACH(m, &midi_devs, link) {
290 lockmgr(&m->lock, LK_EXCLUSIVE);
292 if (m->unit == unit && m->channel == channel) {
293 lockmgr(&m->lock, LK_RELEASE);
298 * Find a better unit number
303 lockmgr(&m->lock, LK_RELEASE);
309 MIDI_DEBUG(1, kprintf("midiinit #2: unit %d/%d.\n", unit, channel));
310 m = kmalloc(sizeof(*m), M_MIDI, M_WAITOK | M_ZERO);
312 m->synth = kmalloc(sizeof(*m->synth), M_MIDI, M_WAITOK | M_ZERO);
313 kobj_init((kobj_t)m->synth, &midisynth_class);
315 kobj_init((kobj_t)m, cls);
316 inqsize = MPU_INQSIZE(m, cookie);
317 outqsize = MPU_OUTQSIZE(m, cookie);
319 MIDI_DEBUG(1, kprintf("midiinit queues %d/%d.\n", inqsize, outqsize));
320 if (!inqsize && !outqsize)
323 lockinit(&m->lock, "raw midi", 0, LK_CANRECURSE);
324 lockinit(&m->qlock, "q raw midi", 0, LK_CANRECURSE);
326 lockmgr(&m->lock, LK_EXCLUSIVE);
327 lockmgr(&m->qlock, LK_EXCLUSIVE);
330 buf = kmalloc(sizeof(MIDI_TYPE) * inqsize, M_MIDI, M_WAITOK);
334 MIDIQ_INIT(m->inq, buf, inqsize);
337 buf = kmalloc(sizeof(MIDI_TYPE) * outqsize, M_MIDI, M_WAITOK);
340 m->hiwat = outqsize / 2;
342 MIDIQ_INIT(m->outq, buf, outqsize);
344 if ((inqsize && !MIDIQ_BUF(m->inq)) ||
345 (outqsize && !MIDIQ_BUF(m->outq)))
352 m->channel = channel;
355 if (MPU_INIT(m, cookie))
358 lockmgr(&m->lock, LK_RELEASE);
359 lockmgr(&m->qlock, LK_RELEASE);
361 TAILQ_INSERT_TAIL(&midi_devs, m, link);
363 lockmgr(&midistat_lock, LK_RELEASE);
365 m->dev = make_dev(&midi_ops,
366 MIDIMKMINOR(unit, MIDI_DEV_RAW, channel),
367 UID_ROOT, GID_WHEEL, 0666, "midi%d.%d", unit, channel);
373 lockuninit(&m->qlock);
374 lockuninit(&m->lock);
376 if (MIDIQ_BUF(m->inq))
377 kfree(MIDIQ_BUF(m->inq), M_MIDI);
378 if (MIDIQ_BUF(m->outq))
379 kfree(MIDIQ_BUF(m->outq), M_MIDI);
383 lockmgr(&midistat_lock, LK_RELEASE);
384 MIDI_DEBUG(1, kprintf("midi_init ended in error\n"));
389 * midi_uninit does not call MIDI_UNINIT, as since this is the implementors
390 * entry point. midi_unint if fact, does not send any methods. A call to
391 * midi_uninit is a defacto promise that you won't manipulate ch anymore
396 midi_uninit(struct snd_midi *m)
401 lockmgr(&midistat_lock, LK_EXCLUSIVE);
402 lockmgr(&m->lock, LK_EXCLUSIVE);
404 if (!(m->rchan || m->wchan))
416 err = midi_destroy(m, 0);
420 err: lockmgr(&m->lock, LK_RELEASE);
421 exit: lockmgr(&midistat_lock, LK_RELEASE);
426 * midi_in: process all data until the queue is full, then discards the rest.
427 * Since midi_in is a state machine, data discards can cause it to get out of
428 * whack. Process as much as possible. It calls, wakeup, selnotify and
429 * psignal at most once.
433 static int midi_lengths[] = {2, 2, 2, 2, 1, 1, 2, 0};
436 /* Number of bytes in a MIDI command */
437 #define MIDI_LENGTH(d) (midi_lengths[((d) >> 4) & 7])
438 #define MIDI_ACK 0xfe
439 #define MIDI_IS_STATUS(d) ((d) >= 0x80)
440 #define MIDI_IS_COMMON(d) ((d) >= 0xf0)
442 #define MIDI_SYSEX_START 0xF0
443 #define MIDI_SYSEX_END 0xF7
447 midi_in(struct snd_midi *m, MIDI_TYPE *buf, int size)
449 /* int i, sig, enq; */
452 /* MIDI_TYPE data; */
453 MIDI_DEBUG(5, kprintf("midi_in: m=%p size=%d\n", m, size));
458 if (!(m->flags & M_RX))
463 lockmgr(&m->qlock, LK_EXCLUSIVE);
466 * Don't bother queuing if not in read mode. Discard everything and
467 * return size so the caller doesn't freak out.
470 if (!(m->flags & M_RX))
473 for (i = sig = 0; i < size; i++) {
477 if (data == MIDI_ACK)
480 switch (m->inq_state) {
482 if (MIDI_IS_STATUS(data)) {
484 case 0xf0: /* Sysex */
485 m->inq_state = MIDI_IN_SYSEX;
487 case 0xf1: /* MTC quarter frame */
488 case 0xf3: /* Song select */
489 m->inq_state = MIDI_IN_DATA;
493 case 0xf2: /* Song position pointer */
494 m->inq_state = MIDI_IN_DATA;
499 if (MIDI_IS_COMMON(data)) {
503 m->inq_state = MIDI_IN_DATA;
505 m->inq_status = data;
506 m->inq_left = MIDI_LENGTH(data);
510 } else if (MIDI_IS_STATUS(m->inq_status)) {
511 m->inq_state = MIDI_IN_DATA;
512 if (!MIDIQ_FULL(m->inq)) {
514 MIDIQ_ENQ(m->inq, &m->inq_status, 1);
517 m->inq_left = MIDI_LENGTH(m->inq_status) - 1;
521 * End of case MIDI_IN_START:
526 if (--m->inq_left <= 0)
527 sig = 1;/* deliver data */
530 if (data == MIDI_SYSEX_END)
531 m->inq_state = MIDI_IN_START;
536 if (!MIDIQ_FULL(m->inq)) {
537 MIDIQ_ENQ(m->inq, &data, 1);
541 * End of the state machines main "for loop"
546 MIDI_DEBUG(6, kprintf("midi_in: len %jd avail %jd\n",
547 (intmax_t)MIDIQ_LEN(m->inq),
548 (intmax_t)MIDIQ_AVAIL(m->inq)));
549 if (MIDIQ_AVAIL(m->inq) > size) {
551 MIDIQ_ENQ(m->inq, buf, size);
553 MIDI_DEBUG(4, kprintf("midi_in: Discarding data qu\n"));
554 lockmgr(&m->qlock, LK_RELEASE);
561 KNOTE(&m->rkq.ki_note, 0);
564 ksignal(m->async, SIGIO);
570 lockmgr(&m->qlock, LK_RELEASE);
575 * midi_out: The only clearer of the M_TXEN flag.
578 midi_out(struct snd_midi *m, MIDI_TYPE *buf, int size)
585 if (!(m->flags & M_TXEN))
588 MIDI_DEBUG(2, kprintf("midi_out: %p\n", m));
589 lockmgr(&m->qlock, LK_EXCLUSIVE);
590 used = MIN(size, MIDIQ_LEN(m->outq));
591 MIDI_DEBUG(3, kprintf("midi_out: used %d\n", used));
593 MIDIQ_DEQ(m->outq, buf, used);
594 if (MIDIQ_EMPTY(m->outq)) {
596 MPU_CALLBACKP(m, m->cookie, m->flags);
598 if (used && MIDIQ_AVAIL(m->outq) > m->hiwat) {
603 KNOTE(&m->wkq.ki_note, 0);
606 ksignal(m->async, SIGIO);
610 lockmgr(&m->qlock, LK_RELEASE);
616 * /dev/rmidi#.# device access functions
619 midi_open(struct dev_open_args *ap)
621 cdev_t i_dev = ap->a_head.a_dev;
622 int flags = ap->a_oflags;
623 struct snd_midi *m = i_dev->si_drv1;
627 MIDI_DEBUG(1, kprintf("midiopen %p %s %s\n", td,
628 flags & FREAD ? "M_RX" : "", flags & FWRITE ? "M_TX" : ""));
633 lockmgr(&m->lock, LK_EXCLUSIVE);
634 lockmgr(&m->qlock, LK_EXCLUSIVE);
639 if (MIDIQ_SIZE(m->inq) == 0)
641 else if (m->flags & M_RX)
646 if (flags & FWRITE) {
647 if (MIDIQ_SIZE(m->outq) == 0)
649 else if (m->flags & M_TX)
661 m->flags |= M_RX | M_RXEN;
663 * Only clear the inq, the outq might still have data to drain
664 * from a previous session
672 MPU_CALLBACK(m, m->cookie, m->flags);
674 MIDI_DEBUG(2, kprintf("midi_open: opened.\n"));
676 err: lockmgr(&m->qlock, LK_RELEASE);
677 lockmgr(&m->lock, LK_RELEASE);
682 midi_close(struct dev_close_args *ap)
684 cdev_t i_dev = ap->a_head.a_dev;
685 int flags = ap->a_fflag;
686 struct snd_midi *m = i_dev->si_drv1;
691 MIDI_DEBUG(1, kprintf("midi_close %p %s %s\n", td,
692 flags & FREAD ? "M_RX" : "", flags & FWRITE ? "M_TX" : ""));
698 lockmgr(&m->lock, LK_EXCLUSIVE);
699 lockmgr(&m->qlock, LK_EXCLUSIVE);
701 if ((flags & FREAD && !(m->flags & M_RX)) ||
702 (flags & FWRITE && !(m->flags & M_TX))) {
711 m->flags &= ~(M_RX | M_RXEN);
715 if ((m->flags & (M_TXEN | M_RXEN)) != (oldflags & (M_RXEN | M_TXEN)))
716 MPU_CALLBACK(m, m->cookie, m->flags);
718 MIDI_DEBUG(1, kprintf("midi_close: closed, busy = %d.\n", m->busy));
720 lockmgr(&m->qlock, LK_RELEASE);
721 lockmgr(&m->lock, LK_RELEASE);
727 * TODO: midi_read, per oss programmer's guide pg. 42 should return as soon
728 * as data is available.
731 midi_read(struct dev_read_args *ap)
733 cdev_t i_dev = ap->a_head.a_dev;
734 struct uio *uio = ap->a_uio;
735 int ioflag = ap->a_ioflag;
736 #define MIDI_RSIZE 32
737 struct snd_midi *m = i_dev->si_drv1;
740 char buf[MIDI_RSIZE];
742 MIDI_DEBUG(5, kprintf("midiread: count=%lu\n",
743 (unsigned long)uio->uio_resid));
750 lockmgr(&m->lock, LK_EXCLUSIVE);
751 lockmgr(&m->qlock, LK_EXCLUSIVE);
753 if (!(m->flags & M_RX))
756 while (uio->uio_resid > 0) {
757 while (MIDIQ_EMPTY(m->inq)) {
758 retval = EWOULDBLOCK;
759 if (ioflag & O_NONBLOCK)
761 lockmgr(&m->lock, LK_RELEASE);
763 retval = lksleep(&m->rchan, &m->qlock,
764 PCATCH, "midi RX", 0);
766 * We slept, maybe things have changed since last
771 if (m != i_dev->si_drv1)
773 /* if (retval && retval != ERESTART) */
776 lockmgr(&m->lock, LK_EXCLUSIVE);
777 lockmgr(&m->qlock, LK_EXCLUSIVE);
782 MIDI_DEBUG(6, kprintf("midi_read start\n"));
784 * At this point, it is certain that m->inq has data
787 used = MIN(MIDIQ_LEN(m->inq), uio->uio_resid);
788 used = MIN(used, MIDI_RSIZE);
790 MIDI_DEBUG(6, kprintf("midiread: uiomove cc=%d\n", used));
791 MIDIQ_DEQ(m->inq, buf, used);
792 retval = uiomove(buf, used, uio);
798 * If we Made it here then transfer is good
801 err1: lockmgr(&m->qlock, LK_RELEASE);
802 lockmgr(&m->lock, LK_RELEASE);
803 err0: MIDI_DEBUG(4, kprintf("midi_read: ret %d\n", retval));
808 * midi_write: The only setter of M_TXEN
812 midi_write(struct dev_write_args *ap)
814 cdev_t i_dev = ap->a_head.a_dev;
815 struct uio *uio = ap->a_uio;
816 int ioflag = ap->a_ioflag;
817 #define MIDI_WSIZE 32
818 struct snd_midi *m = i_dev->si_drv1;
821 char buf[MIDI_WSIZE];
824 MIDI_DEBUG(4, kprintf("midi_write\n"));
829 lockmgr(&m->lock, LK_EXCLUSIVE);
830 lockmgr(&m->qlock, LK_EXCLUSIVE);
832 if (!(m->flags & M_TX))
835 while (uio->uio_resid > 0) {
836 while (MIDIQ_AVAIL(m->outq) == 0) {
837 retval = EWOULDBLOCK;
838 if (ioflag & O_NONBLOCK)
840 lockmgr(&m->lock, LK_RELEASE);
842 MIDI_DEBUG(3, kprintf("midi_write lksleep\n"));
843 retval = lksleep(&m->wchan, &m->qlock,
844 PCATCH, "midi TX", 0);
846 * We slept, maybe things have changed since last
851 if (m != i_dev->si_drv1)
855 lockmgr(&m->lock, LK_EXCLUSIVE);
856 lockmgr(&m->qlock, LK_EXCLUSIVE);
863 * We are certain than data can be placed on the queue
866 used = MIN(MIDIQ_AVAIL(m->outq), uio->uio_resid);
867 used = MIN(used, MIDI_WSIZE);
868 MIDI_DEBUG(5, kprintf("midiout: resid %zd len %jd avail %jd\n",
869 uio->uio_resid, (intmax_t)MIDIQ_LEN(m->outq),
870 (intmax_t)MIDIQ_AVAIL(m->outq)));
873 MIDI_DEBUG(5, kprintf("midi_write: uiomove cc=%d\n", used));
874 retval = uiomove(buf, used, uio);
877 MIDIQ_ENQ(m->outq, buf, used);
879 * Inform the bottom half that data can be written
881 if (!(m->flags & M_TXEN)) {
883 MPU_CALLBACK(m, m->cookie, m->flags);
887 * If we Made it here then transfer is good
890 err1: lockmgr(&m->qlock, LK_RELEASE);
891 lockmgr(&m->lock, LK_RELEASE);
896 midi_ioctl(struct dev_ioctl_args *ap)
902 midi_kqfilter(struct dev_kqfilter_args *ap)
904 cdev_t dev = ap->a_head.a_dev;
905 struct knote *kn = ap->a_kn;
912 switch (kn->kn_filter) {
914 kn->kn_fop = &midi_read_filterops;
915 kn->kn_hook = (caddr_t)m;
916 klist = &m->rkq.ki_note;
919 kn->kn_fop = &midi_write_filterops;
920 kn->kn_hook = (caddr_t)m;
921 klist = &m->wkq.ki_note;
924 ap->a_result = EOPNOTSUPP;
928 knote_insert(klist, kn);
934 midi_filter_detach(struct knote *kn)
936 struct snd_midi *m = (struct snd_midi *)kn->kn_hook;
937 struct klist *rklist = &m->rkq.ki_note;
938 struct klist *wklist = &m->wkq.ki_note;
940 knote_remove(rklist, kn);
941 knote_remove(wklist, kn);
945 midi_filter_read(struct knote *kn, long hint)
947 struct snd_midi *m = (struct snd_midi *)kn->kn_hook;
950 lockmgr(&m->lock, LK_EXCLUSIVE);
951 lockmgr(&m->qlock, LK_EXCLUSIVE);
953 if (!MIDIQ_EMPTY(m->inq))
956 lockmgr(&m->lock, LK_RELEASE);
957 lockmgr(&m->qlock, LK_RELEASE);
963 midi_filter_write(struct knote *kn, long hint)
965 struct snd_midi *m = (struct snd_midi *)kn->kn_hook;
968 lockmgr(&m->lock, LK_EXCLUSIVE);
969 lockmgr(&m->qlock, LK_EXCLUSIVE);
971 if (MIDIQ_AVAIL(m->outq) < m->hiwat)
974 lockmgr(&m->lock, LK_RELEASE);
975 lockmgr(&m->qlock, LK_RELEASE);
981 * /dev/midistat device functions
985 midistat_open(struct dev_open_args *ap)
989 MIDI_DEBUG(1, kprintf("midistat_open\n"));
990 lockmgr(&midistat_lock, LK_EXCLUSIVE);
992 if (midistat_isopen) {
993 lockmgr(&midistat_lock, LK_RELEASE);
998 if (sbuf_new(&midistat_sbuf, NULL, 4096, SBUF_AUTOEXTEND) == NULL) {
1002 error = (midistat_prepare(&midistat_sbuf) > 0) ? 0 : ENOMEM;
1006 midistat_isopen = 0;
1007 lockmgr(&midistat_lock, LK_RELEASE);
1012 midistat_close(struct dev_close_args *ap)
1014 MIDI_DEBUG(1, kprintf("midistat_close\n"));
1015 lockmgr(&midistat_lock, LK_EXCLUSIVE);
1016 if (!midistat_isopen) {
1017 lockmgr(&midistat_lock, LK_RELEASE);
1020 sbuf_delete(&midistat_sbuf);
1021 midistat_isopen = 0;
1023 lockmgr(&midistat_lock, LK_RELEASE);
1028 midistat_read(struct dev_read_args *ap)
1030 struct uio *uio = ap->a_uio;
1033 MIDI_DEBUG(4, kprintf("midistat_read\n"));
1034 lockmgr(&midistat_lock, LK_EXCLUSIVE);
1035 if (!midistat_isopen) {
1036 lockmgr(&midistat_lock, LK_RELEASE);
1039 l = min(uio->uio_resid, sbuf_len(&midistat_sbuf) - uio->uio_offset);
1042 err = uiomove(sbuf_data(&midistat_sbuf) + uio->uio_offset,
1045 lockmgr(&midistat_lock, LK_RELEASE);
1051 * Module library functions
1055 midistat_prepare(struct sbuf *s)
1059 KKASSERT(lockowned(&midistat_lock));
1061 sbuf_printf(s, "FreeBSD Midi Driver (midi2)\n");
1062 if (TAILQ_EMPTY(&midi_devs)) {
1063 sbuf_printf(s, "No devices installed.\n");
1067 sbuf_printf(s, "Installed devices:\n");
1069 TAILQ_FOREACH(m, &midi_devs, link) {
1070 lockmgr(&m->lock, LK_EXCLUSIVE);
1071 sbuf_printf(s, "%s [%d/%d:%s]", m->name, m->unit, m->channel,
1072 MPU_PROVIDER(m, m->cookie));
1073 sbuf_printf(s, "%s", MPU_DESCR(m, m->cookie, midistat_verbose));
1074 sbuf_printf(s, "\n");
1075 lockmgr(&m->lock, LK_RELEASE);
1084 * Convert IOCTL command to string for debugging
1088 midi_cmdname(int cmd)
1093 } *tab, cmdtab_midiioctl[] = {
1094 #define A(x) {x, ## x}
1096 * Once we have some real IOCTLs define, the following will
1099 * A(SNDCTL_MIDI_PRETIME), A(SNDCTL_MIDI_MPUMODE),
1100 * A(SNDCTL_MIDI_MPUCMD), A(SNDCTL_SYNTH_INFO),
1101 * A(SNDCTL_MIDI_INFO), A(SNDCTL_SYNTH_MEMAVL),
1102 * A(SNDCTL_FM_LOAD_INSTR), A(SNDCTL_FM_4OP_ENABLE),
1103 * A(MIOSPASSTHRU), A(MIOGPASSTHRU), A(AIONWRITE),
1104 * A(AIOGSIZE), A(AIOSSIZE), A(AIOGFMT), A(AIOSFMT),
1105 * A(AIOGMIX), A(AIOSMIX), A(AIOSTOP), A(AIOSYNC),
1114 for (tab = cmdtab_midiioctl; tab->cmd != cmd && tab->cmd != -1; tab++);
1126 midisynth_open(void *n, void *arg, int flags)
1128 struct snd_midi *m = ((struct synth_midi *)n)->m;
1131 MIDI_DEBUG(1, kprintf("midisynth_open %s %s\n",
1132 flags & FREAD ? "M_RX" : "", flags & FWRITE ? "M_TX" : ""));
1137 lockmgr(&m->lock, LK_EXCLUSIVE);
1138 lockmgr(&m->qlock, LK_EXCLUSIVE);
1142 if (flags & FREAD) {
1143 if (MIDIQ_SIZE(m->inq) == 0)
1145 else if (m->flags & M_RX)
1150 if (flags & FWRITE) {
1151 if (MIDIQ_SIZE(m->outq) == 0)
1153 else if (m->flags & M_TX)
1161 * TODO: Consider m->async = 0;
1164 if (flags & FREAD) {
1165 m->flags |= M_RX | M_RXEN;
1167 * Only clear the inq, the outq might still have data to drain
1168 * from a previous session
1170 MIDIQ_CLEAR(m->inq);
1174 if (flags & FWRITE) {
1178 m->synth_flags = flags & (FREAD | FWRITE);
1180 MPU_CALLBACK(m, m->cookie, m->flags);
1183 err: lockmgr(&m->qlock, LK_RELEASE);
1184 lockmgr(&m->lock, LK_RELEASE);
1185 MIDI_DEBUG(2, kprintf("midisynth_open: return %d.\n", retval));
1190 midisynth_close(void *n)
1192 struct snd_midi *m = ((struct synth_midi *)n)->m;
1196 MIDI_DEBUG(1, kprintf("midisynth_close %s %s\n",
1197 m->synth_flags & FREAD ? "M_RX" : "",
1198 m->synth_flags & FWRITE ? "M_TX" : ""));
1203 lockmgr(&m->lock, LK_EXCLUSIVE);
1204 lockmgr(&m->qlock, LK_EXCLUSIVE);
1206 if ((m->synth_flags & FREAD && !(m->flags & M_RX)) ||
1207 (m->synth_flags & FWRITE && !(m->flags & M_TX))) {
1213 oldflags = m->flags;
1215 if (m->synth_flags & FREAD)
1216 m->flags &= ~(M_RX | M_RXEN);
1217 if (m->synth_flags & FWRITE)
1220 if ((m->flags & (M_TXEN | M_RXEN)) != (oldflags & (M_RXEN | M_TXEN)))
1221 MPU_CALLBACK(m, m->cookie, m->flags);
1223 MIDI_DEBUG(1, kprintf("midi_close: closed, busy = %d.\n", m->busy));
1225 lockmgr(&m->qlock, LK_RELEASE);
1226 lockmgr(&m->lock, LK_RELEASE);
1236 midisynth_writeraw(void *n, uint8_t *buf, size_t len)
1238 struct snd_midi *m = ((struct synth_midi *)n)->m;
1243 MIDI_DEBUG(4, kprintf("midisynth_writeraw\n"));
1250 lockmgr(&m->lock, LK_EXCLUSIVE);
1251 lockmgr(&m->qlock, LK_EXCLUSIVE);
1253 if (!(m->flags & M_TX))
1257 kprintf("midi dump: ");
1260 while (MIDIQ_AVAIL(m->outq) == 0) {
1261 if (!(m->flags & M_TXEN)) {
1263 MPU_CALLBACK(m, m->cookie, m->flags);
1265 lockmgr(&m->lock, LK_RELEASE);
1267 MIDI_DEBUG(3, kprintf("midisynth_writeraw lksleep\n"));
1268 retval = lksleep(&m->wchan, &m->qlock,
1269 PCATCH, "midi TX", 0);
1271 * We slept, maybe things have changed since last
1274 if (retval == EINTR)
1279 lockmgr(&m->lock, LK_EXCLUSIVE);
1280 lockmgr(&m->qlock, LK_EXCLUSIVE);
1287 * We are certain than data can be placed on the queue
1290 used = MIN(MIDIQ_AVAIL(m->outq), len);
1291 used = MIN(used, MIDI_WSIZE);
1293 kprintf("midi_synth: resid %zu len %jd avail %jd\n",
1294 len, (intmax_t)MIDIQ_LEN(m->outq),
1295 (intmax_t)MIDIQ_AVAIL(m->outq)));
1298 for (i = 0; i < used; i++)
1299 kprintf("%x ", buf[i]);
1301 MIDIQ_ENQ(m->outq, buf, used);
1305 * Inform the bottom half that data can be written
1307 if (!(m->flags & M_TXEN)) {
1309 MPU_CALLBACK(m, m->cookie, m->flags);
1313 * If we Made it here then transfer is good
1319 err1: lockmgr(&m->qlock, LK_RELEASE);
1320 lockmgr(&m->lock, LK_RELEASE);
1321 err0: return retval;
1325 midisynth_killnote(void *n, uint8_t chn, uint8_t note, uint8_t vel)
1330 if (note > 127 || chn > 15)
1337 c[0] = 0x90 | (chn & 0x0f); /* Note on. */
1338 c[1] = (u_char)note;
1341 c[0] = 0x80 | (chn & 0x0f); /* Note off. */
1342 c[1] = (u_char)note;
1346 return midisynth_writeraw(n, c, 3);
1350 midisynth_setinstr(void *n, uint8_t chn, uint16_t instr)
1354 if (instr > 127 || chn > 15)
1357 c[0] = 0xc0 | (chn & 0x0f); /* Progamme change. */
1358 c[1] = instr + midi_instroff;
1360 return midisynth_writeraw(n, c, 2);
1364 midisynth_startnote(void *n, uint8_t chn, uint8_t note, uint8_t vel)
1368 if (note > 127 || chn > 15)
1374 c[0] = 0x90 | (chn & 0x0f); /* Note on. */
1375 c[1] = (u_char)note;
1378 return midisynth_writeraw(n, c, 3);
1381 midisynth_alloc(void *n, uint8_t chan, uint8_t note)
1387 midisynth_controller(void *n, uint8_t chn, uint8_t ctrlnum, uint16_t val)
1391 if (ctrlnum > 127 || chn > 15)
1394 c[0] = 0xb0 | (chn & 0x0f); /* Control Message. */
1397 return midisynth_writeraw(n, c, 3);
1401 midisynth_bender(void *n, uint8_t chn, uint16_t val)
1406 if (val > 16383 || chn > 15)
1409 c[0] = 0xe0 | (chn & 0x0f); /* Pitch bend. */
1410 c[1] = (u_char)val & 0x7f;
1411 c[2] = (u_char)(val >> 7) & 0x7f;
1413 return midisynth_writeraw(n, c, 3);
1417 * Single point of midi destructions.
1420 midi_destroy(struct snd_midi *m, int midiuninit)
1423 KKASSERT(lockowned(&midistat_lock));
1424 KKASSERT(lockowned(&m->lock));
1426 MIDI_DEBUG(3, kprintf("midi_destroy\n"));
1427 m->dev->si_drv1 = NULL;
1428 lockmgr(&m->lock, LK_RELEASE); /* XXX */
1429 destroy_dev(m->dev);
1430 TAILQ_REMOVE(&midi_devs, m, link);
1432 MPU_UNINIT(m, m->cookie);
1433 kfree(MIDIQ_BUF(m->inq), M_MIDI);
1434 kfree(MIDIQ_BUF(m->outq), M_MIDI);
1435 lockuninit(&m->qlock);
1436 lockuninit(&m->lock);
1442 * Load and unload functions, creates the /dev/midistat device
1448 lockinit(&midistat_lock, "midistat lock", 0, LK_CANRECURSE);
1449 TAILQ_INIT(&midi_devs); /* Initialize the queue. */
1451 midistat_dev = make_dev(&midistat_ops,
1452 MIDIMKMINOR(0, MIDI_DEV_MIDICTL, 0),
1453 UID_ROOT, GID_WHEEL, 0666, "midistat");
1464 MIDI_DEBUG(1, kprintf("midi_unload()\n"));
1466 lockmgr(&midistat_lock, LK_EXCLUSIVE);
1467 if (midistat_isopen)
1470 TAILQ_FOREACH(m, &midi_devs, link) {
1471 lockmgr(&m->lock, LK_EXCLUSIVE);
1475 retval = midi_destroy(m, 1);
1480 lockmgr(&midistat_lock, LK_RELEASE); /* XXX */
1482 destroy_dev(midistat_dev);
1484 * Made it here then unload is complete
1486 lockuninit(&midistat_lock);
1490 lockmgr(&m->lock, LK_RELEASE);
1492 lockmgr(&midistat_lock, LK_RELEASE);
1494 MIDI_DEBUG(2, kprintf("midi_unload: failed\n"));
1498 extern int seq_modevent(module_t mod, int type, void *data);
1501 midi_modevent(module_t mod, int type, void *data)
1509 retval = midi_load();
1512 retval = seq_modevent(mod, type, data);
1517 retval = midi_unload();
1520 retval = seq_modevent(mod, type, data);
1532 midimapper_addseq(void *arg1, int *unit, void **cookie)
1536 return (kobj_t)arg1;
1540 midimapper_open(void *arg1, void **cookie)
1545 lockmgr(&midistat_lock, LK_EXCLUSIVE);
1547 TAILQ_FOREACH(m, &midi_devs, link) {
1551 lockmgr(&midistat_lock, LK_RELEASE);
1556 midimapper_close(void *arg1, void *cookie)
1562 midimapper_fetch_synth(void *arg, void *cookie, int unit)
1567 lockmgr(&midistat_lock, LK_EXCLUSIVE);
1569 TAILQ_FOREACH(m, &midi_devs, link) {
1570 if (unit == retval) {
1571 lockmgr(&midistat_lock, LK_RELEASE);
1572 return (kobj_t)m->synth;
1577 lockmgr(&midistat_lock, LK_RELEASE);
1581 DEV_MODULE(midi, midi_modevent, NULL);
1582 MODULE_VERSION(midi, 1);