midi.c revision 1.85.2.2 1 /* $NetBSD: midi.c,v 1.85.2.2 2016/07/26 07:42:39 pgoyette Exp $ */
2
3 /*
4 * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (augustss (at) NetBSD.org), (MIDI FST and Active
9 * Sense handling) Chapman Flack (chap (at) NetBSD.org), and Andrew Doran.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: midi.c,v 1.85.2.2 2016/07/26 07:42:39 pgoyette Exp $");
35
36 #include "midi.h"
37 #include "sequencer.h"
38
39 #include <sys/param.h>
40 #include <sys/ioctl.h>
41 #include <sys/fcntl.h>
42 #include <sys/vnode.h>
43 #include <sys/select.h>
44 #include <sys/poll.h>
45 #include <sys/proc.h>
46 #include <sys/systm.h>
47 #include <sys/callout.h>
48 #include <sys/syslog.h>
49 #include <sys/kernel.h>
50 #include <sys/signalvar.h>
51 #include <sys/conf.h>
52 #include <sys/audioio.h>
53 #include <sys/midiio.h>
54 #include <sys/device.h>
55 #include <sys/intr.h>
56
57 #include <dev/audio_if.h>
58 #include <dev/midi_if.h>
59 #include <dev/midivar.h>
60
61 #if NMIDI > 0
62
63 #ifdef AUDIO_DEBUG
64 #define DPRINTF(x) if (mididebug) printf x
65 #define DPRINTFN(n,x) if (mididebug >= (n)) printf x
66 int mididebug = 0;
67 /*
68 * 1: detected protocol errors and buffer overflows
69 * 2: probe, attach, detach
70 * 3: open, close
71 * 4: data received except realtime
72 * 5: ioctl
73 * 6: read, write, poll
74 * 7: data transmitted
75 * 8: uiomoves, synchronization
76 * 9: realtime data received
77 */
78 #else
79 #define DPRINTF(x)
80 #define DPRINTFN(n,x)
81 #endif
82
83 static struct midi_softc *hwif_softc = NULL;
84 static kmutex_t hwif_softc_lock;
85
86 static void midi_in(void *, int);
87 static void midi_out(void *);
88 static int midi_poll_out(struct midi_softc *);
89 static int midi_intr_out(struct midi_softc *);
90 static int midi_msg_out(struct midi_softc *, u_char **, u_char **,
91 u_char **, u_char **);
92 static int midi_start_output(struct midi_softc *);
93 static void midi_initbuf(struct midi_buffer *);
94 static void midi_xmt_asense(void *);
95 static void midi_rcv_asense(void *);
96 static void midi_softint(void *);
97
98 static int midiprobe(device_t, cfdata_t, void *);
99 static void midiattach(device_t, device_t, void *);
100 int mididetach(device_t, int);
101 static int midiactivate(device_t, enum devact);
102
103 static dev_type_open(midiopen);
104 static dev_type_close(midiclose);
105 static dev_type_read(midiread);
106 static dev_type_write(midiwrite);
107 static dev_type_ioctl(midiioctl);
108 static dev_type_poll(midipoll);
109 static dev_type_kqfilter(midikqfilter);
110
111 const struct cdevsw midi_cdevsw = {
112 .d_open = midiopen,
113 .d_close = midiclose,
114 .d_read = midiread,
115 .d_write = midiwrite,
116 .d_ioctl = midiioctl,
117 .d_stop = nostop,
118 .d_tty = notty,
119 .d_poll = midipoll,
120 .d_mmap = nommap,
121 .d_kqfilter = midikqfilter,
122 .d_discard = nodiscard,
123 .d_flag = D_OTHER | D_MPSAFE
124 };
125
126 CFATTACH_DECL_NEW(midi, sizeof(struct midi_softc),
127 midiprobe, midiattach, mididetach, midiactivate);
128
129 #define MIDI_XMT_ASENSE_PERIOD mstohz(275)
130 #define MIDI_RCV_ASENSE_PERIOD mstohz(300)
131
132 extern struct cfdriver midi_cd;
133
134 static int
135 midiprobe(device_t parent, cfdata_t match, void *aux)
136 {
137 struct audio_attach_args *sa;
138
139 sa = aux;
140
141 DPRINTFN(2,("midiprobe: type=%d sa=%p hw=%p\n", sa->type, sa,
142 sa->hwif));
143
144 return sa->type == AUDIODEV_TYPE_MIDI;
145 }
146
147 static void
148 midiattach(device_t parent, device_t self, void *aux)
149 {
150 struct midi_softc *sc = device_private(self);
151 struct audio_attach_args *sa = aux;
152 const struct midi_hw_if *hwp;
153 void *hdlp;
154
155 hwp = sa->hwif;
156 hdlp = sa->hdl;
157
158 aprint_naive("\n");
159
160 DPRINTFN(2, ("MIDI attach\n"));
161
162 #ifdef DIAGNOSTIC
163 if (hwp == 0 ||
164 hwp->open == 0 ||
165 hwp->close == 0 ||
166 hwp->output == 0 ||
167 hwp->getinfo == 0) {
168 aprint_error_dev(self, "missing method\n");
169 return;
170 }
171 #endif
172
173 sc->dev = self;
174 sc->hw_if = hwp;
175 sc->hw_hdl = hdlp;
176 midi_attach(sc);
177 }
178
179 static int
180 midiactivate(device_t self, enum devact act)
181 {
182 struct midi_softc *sc = device_private(self);
183
184 switch (act) {
185 case DVACT_DEACTIVATE:
186 mutex_enter(sc->lock);
187 sc->dying = 1;
188 mutex_exit(sc->lock);
189 return 0;
190 default:
191 return EOPNOTSUPP;
192 }
193 }
194
195 int
196 mididetach(device_t self, int flags)
197 {
198 struct midi_softc *sc = device_private(self);
199 int maj, mn;
200
201 DPRINTFN(2,("%s: sc=%p flags=%d\n", __func__, sc, flags));
202
203 pmf_device_deregister(self);
204
205 mutex_enter(sc->lock);
206 sc->dying = 1;
207
208 if (--sc->refcnt >= 0) {
209 /* Wake anything? */
210 (void)cv_timedwait(&sc->detach_cv, sc->lock, hz * 60);
211 }
212 cv_broadcast(&sc->wchan);
213 cv_broadcast(&sc->rchan);
214 mutex_exit(sc->lock);
215
216 /* locate the major number */
217 maj = cdevsw_lookup_major(&midi_cdevsw);
218
219 /*
220 * Nuke the vnodes for any open instances (calls close).
221 * Will wait until any activity on the device nodes has ceased.
222 *
223 * XXXAD NOT YET.
224 *
225 * XXXAD NEED TO PREVENT NEW REFERENCES THROUGH AUDIO_ENTER().
226 */
227 mn = device_unit(self);
228 vdevgone(maj, mn, mn, VCHR);
229
230 if (!(sc->props & MIDI_PROP_NO_OUTPUT)) {
231 evcnt_detach(&sc->xmt.bytesDiscarded);
232 evcnt_detach(&sc->xmt.incompleteMessages);
233 }
234 if (sc->props & MIDI_PROP_CAN_INPUT) {
235 evcnt_detach(&sc->rcv.bytesDiscarded);
236 evcnt_detach(&sc->rcv.incompleteMessages);
237 }
238
239 if (sc->sih != NULL) {
240 softint_disestablish(sc->sih);
241 sc->sih = NULL;
242 }
243
244 mutex_enter(sc->lock);
245 callout_halt(&sc->xmt_asense_co, sc->lock);
246 callout_halt(&sc->rcv_asense_co, sc->lock);
247 mutex_exit(sc->lock);
248
249 callout_destroy(&sc->xmt_asense_co);
250 callout_destroy(&sc->rcv_asense_co);
251
252 cv_destroy(&sc->wchan);
253 cv_destroy(&sc->rchan);
254 cv_destroy(&sc->detach_cv);
255
256 return (0);
257 }
258
259 void
260 midi_attach(struct midi_softc *sc)
261 {
262 struct midi_info mi;
263 kmutex_t *dummy;
264 static int first = 1;
265
266 if (first) {
267 mutex_init(&hwif_softc_lock, MUTEX_DEFAULT, IPL_NONE);
268 first = 0;
269 }
270
271 sc->hw_if->get_locks(sc->hw_hdl, &sc->lock, &dummy);
272
273 callout_init(&sc->xmt_asense_co, CALLOUT_MPSAFE);
274 callout_init(&sc->rcv_asense_co, CALLOUT_MPSAFE);
275 callout_setfunc(&sc->xmt_asense_co, midi_xmt_asense, sc);
276 callout_setfunc(&sc->rcv_asense_co, midi_rcv_asense, sc);
277
278 sc->sih = softint_establish(SOFTINT_CLOCK | SOFTINT_MPSAFE,
279 midi_softint, sc);
280
281 cv_init(&sc->rchan, "midird");
282 cv_init(&sc->wchan, "midiwr");
283 cv_init(&sc->detach_cv, "mididet");
284
285 sc->dying = 0;
286 sc->isopen = 0;
287 sc->refcnt = 0;
288
289 mutex_enter(&hwif_softc_lock);
290 mutex_enter(sc->lock);
291 hwif_softc = sc;
292 sc->hw_if->getinfo(sc->hw_hdl, &mi);
293 hwif_softc = NULL;
294 mutex_exit(sc->lock);
295 mutex_exit(&hwif_softc_lock);
296
297 sc->props = mi.props;
298
299 if (!(sc->props & MIDI_PROP_NO_OUTPUT)) {
300 evcnt_attach_dynamic(&sc->xmt.bytesDiscarded,
301 EVCNT_TYPE_MISC, NULL,
302 device_xname(sc->dev), "xmt bytes discarded");
303 evcnt_attach_dynamic(&sc->xmt.incompleteMessages,
304 EVCNT_TYPE_MISC, NULL,
305 device_xname(sc->dev), "xmt incomplete msgs");
306 }
307 if (sc->props & MIDI_PROP_CAN_INPUT) {
308 evcnt_attach_dynamic(&sc->rcv.bytesDiscarded,
309 EVCNT_TYPE_MISC, NULL,
310 device_xname(sc->dev), "rcv bytes discarded");
311 evcnt_attach_dynamic(&sc->rcv.incompleteMessages,
312 EVCNT_TYPE_MISC, NULL,
313 device_xname(sc->dev), "rcv incomplete msgs");
314 }
315
316 aprint_naive("\n");
317 aprint_normal(": %s\n", mi.name);
318
319 if (!pmf_device_register(sc->dev, NULL, NULL))
320 aprint_error_dev(sc->dev, "couldn't establish power handler\n");
321 }
322
323 void
324 midi_register_hw_if_ext(struct midi_hw_if_ext *exthw)
325 {
326 if (hwif_softc != NULL) /* ignore calls resulting from non-init */
327 hwif_softc->hw_if_ext = exthw; /* uses of getinfo */
328 }
329
330 int
331 midi_unit_count(void)
332 {
333 int i;
334 for ( i = 0; i < midi_cd.cd_ndevs; ++i)
335 if (NULL == device_lookup(&midi_cd, i))
336 break;
337 return i;
338 }
339
340 static void
341 midi_initbuf(struct midi_buffer *mb)
342 {
343 mb->idx_producerp = mb->idx_consumerp = mb->idx;
344 mb->buf_producerp = mb->buf_consumerp = mb->buf;
345 }
346
347 #define PACK_MB_IDX(cat,len) (((cat)<<4)|(len))
348 #define MB_IDX_CAT(idx) ((idx)>>4)
349 #define MB_IDX_LEN(idx) ((idx)&0xf)
350
351 static char const midi_cats[] = "\0\0\0\0\0\0\0\0\2\2\2\2\1\1\2\3";
352 #define MIDI_CAT(d) (midi_cats[((d)>>4)&15])
353 #define FST_RETURN(offp,endp,ret) \
354 return (s->pos=s->msg+(offp)), (s->end=s->msg+(endp)), (ret)
355
356 enum fst_ret { FST_CHN, FST_CHV, FST_COM, FST_SYX, FST_RT, FST_MORE, FST_ERR,
357 FST_HUH, FST_SXP };
358 enum fst_form { FST_CANON, FST_COMPR, FST_VCOMP };
359 static struct {
360 int off;
361 enum fst_ret tag;
362 } const midi_forms[] = {
363 [FST_CANON] = { .off=0, .tag=FST_CHN },
364 [FST_COMPR] = { .off=1, .tag=FST_CHN },
365 [FST_VCOMP] = { .off=0, .tag=FST_CHV }
366 };
367 #define FST_CRETURN(endp) \
368 FST_RETURN(midi_forms[form].off,endp,midi_forms[form].tag)
369
370 /*
371 * A MIDI finite state transducer suitable for receiving or transmitting. It
372 * will accept correct MIDI input that uses, doesn't use, or sometimes uses the
373 * 'running status' compression technique, and transduce it to fully expanded
374 * (form=FST_CANON) or fully compressed (form=FST_COMPR or FST_VCOMP) form.
375 *
376 * Returns FST_MORE if a complete message has not been parsed yet (SysEx
377 * messages are the exception), FST_ERR or FST_HUH if the input does not
378 * conform to the protocol, or FST_CHN (channel messages), FST_COM (System
379 * Common messages), FST_RT (System Real-Time messages), or FST_SYX (System
380 * Exclusive) to broadly categorize the message parsed. s->pos and s->end
381 * locate the parsed message; while (s->pos<s->end) putchar(*(s->pos++));
382 * would output it.
383 *
384 * FST_HUH means the character c wasn't valid in the original state, but the
385 * state has now been reset to START and the caller should try again passing
386 * the same c. FST_ERR means c isn't valid in the start state; the caller
387 * should kiss it goodbye and continue to try successive characters from the
388 * input until something other than FST_ERR or FST_HUH is returned, at which
389 * point things are resynchronized.
390 *
391 * A FST_SYX return means that between pos and end are from 1 to 3
392 * bytes of a system exclusive message. A SysEx message will be delivered in
393 * one or more chunks of that form, where the first begins with 0xf0 and the
394 * last (which is the only one that might have length < 3) ends with 0xf7.
395 *
396 * Messages corrupted by a protocol error are discarded and won't be seen at
397 * all; again SysEx is the exception, as one or more chunks of it may already
398 * have been parsed.
399 *
400 * For FST_CHN messages, s->msg[0] always contains the status byte even if
401 * FST_COMPR form was requested (pos then points to msg[1]). That way, the
402 * caller can always identify the exact message if there is a need to do so.
403 * For all other message types except FST_SYX, the status byte is at *pos
404 * (which may not necessarily be msg[0]!). There is only one SysEx status
405 * byte, so the return value FST_SYX is sufficient to identify it.
406 *
407 * To simplify some use cases, compression can also be requested with
408 * form=FST_VCOMP. In this form a compressible channel message is indicated
409 * by returning a classification of FST_CHV instead of FST_CHN, and pos points
410 * to the status byte rather than being advanced past it. If the caller in this
411 * case saves the bytes from pos to end, it will have saved the entire message,
412 * and can act on the FST_CHV tag to drop the first byte later. In this form,
413 * unlike FST_CANON, hidden note-off (i.e. note-on with velocity 0) may occur.
414 *
415 * Two obscure points in the MIDI protocol complicate things further, both to
416 * do with the EndSysEx code, 0xf7. First, this code is permitted (and
417 * meaningless) outside of a System Exclusive message, anywhere a status byte
418 * could appear. Second, it is allowed to be absent at the end of a System
419 * Exclusive message (!) - any status byte at all (non-realtime) is allowed to
420 * terminate the message. Both require accomodation in the interface to
421 * midi_fst's caller. A stray 0xf7 should be ignored BUT should count as a
422 * message received for purposes of Active Sense timeout; the case is
423 * represented by a return of FST_COM with a length of zero (pos == end). A
424 * status byte other than 0xf7 during a system exclusive message will cause an
425 * FST_SXP (sysex plus) return; the bytes from pos to end are the end of the
426 * system exclusive message, and after handling those the caller should call
427 * midi_fst again with the same input byte.
428 *
429 * midi(4) will never produce either such form of rubbish.
430 */
431 static enum fst_ret
432 midi_fst(struct midi_state *s, u_char c, enum fst_form form)
433 {
434 int syxpos = 0;
435
436 if (c >= 0xf8) { /* All realtime messages bypass state machine */
437 if (c == 0xf9 || c == 0xfd) {
438 DPRINTF( ("midi_fst: s=%p c=0x%02x undefined\n",
439 s, c));
440 s->bytesDiscarded.ev_count++;
441 return FST_ERR;
442 }
443 DPRINTFN(9, ("midi_fst: s=%p System Real-Time data=0x%02x\n",
444 s, c));
445 s->msg[2] = c;
446 FST_RETURN(2,3,FST_RT);
447 }
448
449 DPRINTFN(4, ("midi_fst: s=%p data=0x%02x state=%d\n",
450 s, c, s->state));
451
452 switch (s->state | MIDI_CAT(c)) { /* break ==> return FST_MORE */
453 case MIDI_IN_START | MIDI_CAT_COMMON:
454 case MIDI_IN_RUN1_1 | MIDI_CAT_COMMON:
455 case MIDI_IN_RUN2_2 | MIDI_CAT_COMMON:
456 case MIDI_IN_RXX2_2 | MIDI_CAT_COMMON:
457 s->msg[0] = c;
458 switch ( c) {
459 case 0xf0: s->state = MIDI_IN_SYX1_3; break;
460 case 0xf1: s->state = MIDI_IN_COM0_1; break;
461 case 0xf2: s->state = MIDI_IN_COM0_2; break;
462 case 0xf3: s->state = MIDI_IN_COM0_1; break;
463 case 0xf6: s->state = MIDI_IN_START; FST_RETURN(0,1,FST_COM);
464 case 0xf7: s->state = MIDI_IN_START; FST_RETURN(0,0,FST_COM);
465 default: goto protocol_violation;
466 }
467 break;
468
469 case MIDI_IN_RUN1_1 | MIDI_CAT_STATUS1:
470 if (c == s->msg[0]) {
471 s->state = MIDI_IN_RNX0_1;
472 break;
473 }
474 /* FALLTHROUGH */
475 case MIDI_IN_RUN2_2 | MIDI_CAT_STATUS1:
476 case MIDI_IN_RXX2_2 | MIDI_CAT_STATUS1:
477 case MIDI_IN_START | MIDI_CAT_STATUS1:
478 s->state = MIDI_IN_RUN0_1;
479 s->msg[0] = c;
480 break;
481
482 case MIDI_IN_RUN2_2 | MIDI_CAT_STATUS2:
483 case MIDI_IN_RXX2_2 | MIDI_CAT_STATUS2:
484 if (c == s->msg[0]) {
485 s->state = MIDI_IN_RNX0_2;
486 break;
487 }
488 if ((c ^ s->msg[0]) == 0x10 && (c & 0xe0) == 0x80) {
489 s->state = MIDI_IN_RXX0_2;
490 s->msg[0] = c;
491 break;
492 }
493 /* FALLTHROUGH */
494 case MIDI_IN_RUN1_1 | MIDI_CAT_STATUS2:
495 case MIDI_IN_START | MIDI_CAT_STATUS2:
496 s->state = MIDI_IN_RUN0_2;
497 s->msg[0] = c;
498 break;
499
500 case MIDI_IN_COM0_1 | MIDI_CAT_DATA:
501 s->state = MIDI_IN_START;
502 s->msg[1] = c;
503 FST_RETURN(0,2,FST_COM);
504
505 case MIDI_IN_COM0_2 | MIDI_CAT_DATA:
506 s->state = MIDI_IN_COM1_2;
507 s->msg[1] = c;
508 break;
509
510 case MIDI_IN_COM1_2 | MIDI_CAT_DATA:
511 s->state = MIDI_IN_START;
512 s->msg[2] = c;
513 FST_RETURN(0,3,FST_COM);
514
515 case MIDI_IN_RUN0_1 | MIDI_CAT_DATA:
516 s->state = MIDI_IN_RUN1_1;
517 s->msg[1] = c;
518 FST_RETURN(0,2,FST_CHN);
519
520 case MIDI_IN_RUN1_1 | MIDI_CAT_DATA:
521 case MIDI_IN_RNX0_1 | MIDI_CAT_DATA:
522 s->state = MIDI_IN_RUN1_1;
523 s->msg[1] = c;
524 FST_CRETURN(2);
525
526 case MIDI_IN_RUN0_2 | MIDI_CAT_DATA:
527 s->state = MIDI_IN_RUN1_2;
528 s->msg[1] = c;
529 break;
530
531 case MIDI_IN_RUN1_2 | MIDI_CAT_DATA:
532 if (FST_CANON == form && 0 == c && (s->msg[0]&0xf0) == 0x90) {
533 s->state = MIDI_IN_RXX2_2;
534 s->msg[0] ^= 0x10;
535 s->msg[2] = 64;
536 } else {
537 s->state = MIDI_IN_RUN2_2;
538 s->msg[2] = c;
539 }
540 FST_RETURN(0,3,FST_CHN);
541
542 case MIDI_IN_RUN2_2 | MIDI_CAT_DATA:
543 s->state = MIDI_IN_RNX1_2;
544 s->msg[1] = c;
545 break;
546
547 case MIDI_IN_RXX2_2 | MIDI_CAT_DATA:
548 s->state = MIDI_IN_RXX1_2;
549 s->msg[0] ^= 0x10;
550 s->msg[1] = c;
551 break;
552
553 case MIDI_IN_RNX0_2 | MIDI_CAT_DATA:
554 s->state = MIDI_IN_RNY1_2;
555 s->msg[1] = c;
556 break;
557
558 case MIDI_IN_RXX0_2 | MIDI_CAT_DATA:
559 s->state = MIDI_IN_RXY1_2;
560 s->msg[1] = c;
561 break;
562
563 case MIDI_IN_RNX1_2 | MIDI_CAT_DATA:
564 case MIDI_IN_RNY1_2 | MIDI_CAT_DATA:
565 if (FST_CANON == form && 0 == c && (s->msg[0]&0xf0) == 0x90) {
566 s->state = MIDI_IN_RXX2_2;
567 s->msg[0] ^= 0x10;
568 s->msg[2] = 64;
569 FST_RETURN(0,3,FST_CHN);
570 }
571 s->state = MIDI_IN_RUN2_2;
572 s->msg[2] = c;
573 FST_CRETURN(3);
574
575 case MIDI_IN_RXX1_2 | MIDI_CAT_DATA:
576 case MIDI_IN_RXY1_2 | MIDI_CAT_DATA:
577 if (( 0 == c && (s->msg[0]&0xf0) == 0x90)
578 || (64 == c && (s->msg[0]&0xf0) == 0x80
579 && FST_CANON != form)) {
580 s->state = MIDI_IN_RXX2_2;
581 s->msg[0] ^= 0x10;
582 s->msg[2] = 64 - c;
583 FST_CRETURN(3);
584 }
585 s->state = MIDI_IN_RUN2_2;
586 s->msg[2] = c;
587 FST_RETURN(0,3,FST_CHN);
588
589 case MIDI_IN_SYX1_3 | MIDI_CAT_DATA:
590 s->state = MIDI_IN_SYX2_3;
591 s->msg[1] = c;
592 break;
593
594 case MIDI_IN_SYX2_3 | MIDI_CAT_DATA:
595 s->state = MIDI_IN_SYX0_3;
596 s->msg[2] = c;
597 FST_RETURN(0,3,FST_SYX);
598
599 case MIDI_IN_SYX0_3 | MIDI_CAT_DATA:
600 s->state = MIDI_IN_SYX1_3;
601 s->msg[0] = c;
602 break;
603
604 case MIDI_IN_SYX2_3 | MIDI_CAT_COMMON:
605 case MIDI_IN_SYX2_3 | MIDI_CAT_STATUS1:
606 case MIDI_IN_SYX2_3 | MIDI_CAT_STATUS2:
607 ++ syxpos;
608 /* FALLTHROUGH */
609 case MIDI_IN_SYX1_3 | MIDI_CAT_COMMON:
610 case MIDI_IN_SYX1_3 | MIDI_CAT_STATUS1:
611 case MIDI_IN_SYX1_3 | MIDI_CAT_STATUS2:
612 ++ syxpos;
613 /* FALLTHROUGH */
614 case MIDI_IN_SYX0_3 | MIDI_CAT_COMMON:
615 case MIDI_IN_SYX0_3 | MIDI_CAT_STATUS1:
616 case MIDI_IN_SYX0_3 | MIDI_CAT_STATUS2:
617 s->state = MIDI_IN_START;
618 if (c == 0xf7) {
619 s->msg[syxpos] = c;
620 FST_RETURN(0,1+syxpos,FST_SYX);
621 }
622 s->msg[syxpos] = 0xf7;
623 FST_RETURN(0,1+syxpos,FST_SXP);
624
625 default:
626 protocol_violation:
627 DPRINTF(("midi_fst: unexpected %#02x in state %u\n",
628 c, s->state));
629 switch ( s->state) {
630 case MIDI_IN_RUN1_1: /* can only get here by seeing an */
631 case MIDI_IN_RUN2_2: /* INVALID System Common message */
632 case MIDI_IN_RXX2_2:
633 s->state = MIDI_IN_START;
634 /* FALLTHROUGH */
635 case MIDI_IN_START:
636 s->bytesDiscarded.ev_count++;
637 return FST_ERR;
638 case MIDI_IN_COM1_2:
639 case MIDI_IN_RUN1_2:
640 case MIDI_IN_RNY1_2:
641 case MIDI_IN_RXY1_2:
642 s->bytesDiscarded.ev_count++;
643 /* FALLTHROUGH */
644 case MIDI_IN_COM0_1:
645 case MIDI_IN_RUN0_1:
646 case MIDI_IN_RNX0_1:
647 case MIDI_IN_COM0_2:
648 case MIDI_IN_RUN0_2:
649 case MIDI_IN_RNX0_2:
650 case MIDI_IN_RXX0_2:
651 case MIDI_IN_RNX1_2:
652 case MIDI_IN_RXX1_2:
653 s->bytesDiscarded.ev_count++;
654 s->incompleteMessages.ev_count++;
655 break;
656 default:
657 DPRINTF(("midi_fst: mishandled %#02x(%u) in state %u?!\n",
658 c, MIDI_CAT(c), s->state));
659 break;
660 }
661 s->state = MIDI_IN_START;
662 return FST_HUH;
663 }
664 return FST_MORE;
665 }
666
667 static void
668 midi_softint(void *cookie)
669 {
670 struct midi_softc *sc;
671 proc_t *p;
672 pid_t pid;
673
674 sc = cookie;
675
676 mutex_enter(proc_lock);
677 pid = sc->async;
678 if (pid != 0 && (p = proc_find(pid)) != NULL)
679 psignal(p, SIGIO);
680 mutex_exit(proc_lock);
681 }
682
683 static void
684 midi_in(void *addr, int data)
685 {
686 struct midi_softc *sc;
687 struct midi_buffer *mb;
688 int i, count;
689 enum fst_ret got;
690 MIDI_BUF_DECLARE(idx);
691 MIDI_BUF_DECLARE(buf);
692
693 sc = addr;
694 mb = &sc->inbuf;
695
696 KASSERT(mutex_owned(sc->lock));
697
698 if (!sc->isopen)
699 return;
700
701 if ((sc->flags & FREAD) == 0)
702 return; /* discard data if not reading */
703
704 sxp_again:
705 do {
706 got = midi_fst(&sc->rcv, data, FST_CANON);
707 } while (got == FST_HUH);
708
709 switch (got) {
710 case FST_MORE:
711 case FST_ERR:
712 return;
713 case FST_CHN:
714 case FST_COM:
715 case FST_RT:
716 #if NSEQUENCER > 0
717 if (sc->seqopen) {
718 extern void midiseq_in(struct midi_dev *,u_char *,int);
719 count = sc->rcv.end - sc->rcv.pos;
720 midiseq_in(sc->seq_md, sc->rcv.pos, count);
721 return;
722 }
723 #endif
724 /*
725 * Pass Active Sense to the sequencer if it's open, but not to
726 * a raw reader. (Really should do something intelligent with
727 * it then, though....)
728 */
729 if (got == FST_RT && MIDI_ACK == sc->rcv.pos[0]) {
730 if (!sc->rcv_expect_asense) {
731 sc->rcv_expect_asense = 1;
732 callout_schedule(&sc->rcv_asense_co,
733 MIDI_RCV_ASENSE_PERIOD);
734 }
735 sc->rcv_quiescent = 0;
736 sc->rcv_eof = 0;
737 return;
738 }
739 /* FALLTHROUGH */
740 /*
741 * Ultimately SysEx msgs should be offered to the sequencer also; the
742 * sequencer API addresses them - but maybe our sequencer can't handle
743 * them yet, so offer only to raw reader. (Which means, ultimately,
744 * discard them if the sequencer's open, as it's not doing reads!)
745 * -> When SysEx support is added to the sequencer, be sure to handle
746 * FST_SXP there too.
747 */
748 case FST_SYX:
749 case FST_SXP:
750 count = sc->rcv.end - sc->rcv.pos;
751 sc->rcv_quiescent = 0;
752 sc->rcv_eof = 0;
753 if (0 == count)
754 break;
755 MIDI_BUF_PRODUCER_INIT(mb,idx);
756 MIDI_BUF_PRODUCER_INIT(mb,buf);
757 if (count > buf_lim - buf_cur
758 || 1 > idx_lim - idx_cur) {
759 sc->rcv.bytesDiscarded.ev_count += count;
760 DPRINTF(("midi_in: buffer full, discard data=0x%02x\n",
761 sc->rcv.pos[0]));
762 return;
763 }
764 for (i = 0; i < count; i++) {
765 *buf_cur++ = sc->rcv.pos[i];
766 MIDI_BUF_WRAP(buf);
767 }
768 *idx_cur++ = PACK_MB_IDX(got,count);
769 MIDI_BUF_WRAP(idx);
770 MIDI_BUF_PRODUCER_WBACK(mb,buf);
771 MIDI_BUF_PRODUCER_WBACK(mb,idx);
772 cv_broadcast(&sc->rchan);
773 selnotify(&sc->rsel, 0, NOTE_SUBMIT);
774 if (sc->async != 0)
775 softint_schedule(sc->sih);
776 break;
777 default: /* don't #ifdef this away, gcc will say FST_HUH not handled */
778 printf("midi_in: midi_fst returned %d?!\n", got);
779 }
780 if (FST_SXP == got)
781 goto sxp_again;
782 }
783
784 static void
785 midi_out(void *addr)
786 {
787 struct midi_softc *sc = addr;
788
789 KASSERT(mutex_owned(sc->lock));
790
791 if (!sc->isopen)
792 return;
793 DPRINTFN(8, ("midi_out: %p\n", sc));
794 midi_intr_out(sc);
795 }
796
797 static int
798 midiopen(dev_t dev, int flags, int ifmt, struct lwp *l)
799 {
800 device_t self = device_lookup_acquire(&midi_cd, MIDIUNIT(dev));
801 struct midi_softc *sc;
802 const struct midi_hw_if *hw;
803 int error;
804
805 if (self == NULL)
806 return (ENXIO);
807 sc = device_private(self);
808
809 DPRINTFN(3,("midiopen %p\n", sc));
810
811 mutex_enter(sc->lock);
812 if (sc->dying) {
813 mutex_exit(sc->lock);
814 device_release(self);
815 return (EIO);
816 }
817 hw = sc->hw_if;
818 if (hw == NULL) {
819 mutex_exit(sc->lock);
820 device_release(self);
821 return ENXIO;
822 }
823 if (sc->isopen) {
824 mutex_exit(sc->lock);
825 device_release(self);
826 return EBUSY;
827 }
828
829 /* put both state machines into known states */
830 sc->rcv.state = MIDI_IN_START;
831 sc->rcv.pos = sc->rcv.msg;
832 sc->rcv.end = sc->rcv.msg;
833 sc->xmt.state = MIDI_IN_START;
834 sc->xmt.pos = sc->xmt.msg;
835 sc->xmt.end = sc->xmt.msg;
836
837 /* copy error counters so an ioctl (TBA) can give since-open stats */
838 sc->rcv.atOpen.bytesDiscarded = sc->rcv.bytesDiscarded.ev_count;
839 sc->rcv.atQuery.bytesDiscarded = sc->rcv.bytesDiscarded.ev_count;
840
841 sc->xmt.atOpen.bytesDiscarded = sc->xmt.bytesDiscarded.ev_count;
842 sc->xmt.atQuery.bytesDiscarded = sc->xmt.bytesDiscarded.ev_count;
843
844 /* and the buffers */
845 midi_initbuf(&sc->outbuf);
846 midi_initbuf(&sc->inbuf);
847
848 /* and the receive flags */
849 sc->rcv_expect_asense = 0;
850 sc->rcv_quiescent = 0;
851 sc->rcv_eof = 0;
852 sc->isopen++;
853 sc->flags = flags;
854 sc->pbus = 0;
855 sc->async = 0;
856
857 #ifdef MIDI_SAVE
858 if (midicnt != 0) {
859 midisave.cnt = midicnt;
860 midicnt = 0;
861 }
862 #endif
863
864 error = hw->open(sc->hw_hdl, flags, midi_in, midi_out, sc);
865 if (error) {
866 mutex_exit(sc->lock);
867 device_release(self);
868 return error;
869 }
870
871 mutex_exit(sc->lock);
872 device_release(self);
873 return 0;
874 }
875
876 static int
877 midiclose(dev_t dev, int flags, int ifmt, struct lwp *l)
878 {
879 device_t self = device_lookup_acquire(&midi_cd, MIDIUNIT(dev));
880 struct midi_softc *sc;
881 const struct midi_hw_if *hw;
882
883 if (self == NULL)
884 return ENXIO;
885
886 sc = device_private(self);
887 hw = sc->hw_if;
888
889 DPRINTFN(3,("midiclose %p\n", sc));
890
891 mutex_enter(sc->lock);
892 /* midi_start_output(sc); anything buffered => pbus already set! */
893 while (sc->pbus) {
894 if (sc->dying)
895 break;
896 DPRINTFN(8,("midiclose sleep ...\n"));
897 cv_wait(&sc->wchan, sc->lock);
898 }
899 sc->isopen = 0;
900 callout_halt(&sc->xmt_asense_co, sc->lock);
901 callout_halt(&sc->rcv_asense_co, sc->lock);
902 hw->close(sc->hw_hdl);
903 sc->seqopen = 0;
904 sc->seq_md = 0;
905 mutex_exit(sc->lock);
906
907 device_release(self);
908 return 0;
909 }
910
911 static int
912 midiread(dev_t dev, struct uio *uio, int ioflag)
913 {
914 device_t self = device_lookup_acquire(&midi_cd, MIDIUNIT(dev));
915 struct midi_softc *sc;
916 struct midi_buffer *mb;
917 int appetite, error, first;
918 MIDI_BUF_DECLARE(idx);
919 MIDI_BUF_DECLARE(buf);
920
921 if (self == NULL)
922 return ENXIO;
923 sc = device_private(self);
924 mb = &sc->inbuf;
925 first = 1;
926
927 DPRINTFN(6,("midiread: %p, count=%lu\n", sc,
928 (unsigned long)uio->uio_resid));
929
930 mutex_enter(sc->lock);
931 if (sc->dying) {
932 mutex_exit(sc->lock);
933 device_release(self);
934 return EIO;
935 }
936 if ((sc->props & MIDI_PROP_CAN_INPUT) == 0) {
937 mutex_exit(sc->lock);
938 device_release(self);
939 return ENXIO;
940 }
941 MIDI_BUF_CONSUMER_INIT(mb,idx);
942 MIDI_BUF_CONSUMER_INIT(mb,buf);
943 error = 0;
944 for (;;) {
945 /*
946 * If the used portion of idx wraps around the end, just take
947 * the first part on this iteration, and we'll get the rest on
948 * the next.
949 */
950 if (idx_lim > idx_end)
951 idx_lim = idx_end;
952 /*
953 * Count bytes through the last complete message that will
954 * fit in the requested read.
955 */
956 for (appetite = uio->uio_resid; idx_cur < idx_lim; ++idx_cur) {
957 if (appetite < MB_IDX_LEN(*idx_cur))
958 break;
959 appetite -= MB_IDX_LEN(*idx_cur);
960 }
961 appetite = uio->uio_resid - appetite;
962
963 /*
964 * Only if the read is too small to hold even the first
965 * complete message will we return a partial one (updating idx
966 * to reflect the remaining length of the message).
967 */
968 if (appetite == 0 && idx_cur < idx_lim) {
969 if (!first)
970 break;
971 appetite = uio->uio_resid;
972 *idx_cur = PACK_MB_IDX(MB_IDX_CAT(*idx_cur),
973 MB_IDX_LEN(*idx_cur) - appetite);
974 }
975 KASSERT(buf_cur + appetite <= buf_lim);
976
977 /* move the bytes */
978 if (appetite > 0) {
979 first = 0; /* we know we won't return empty-handed */
980 /* do two uiomoves if data wrap around end of buf */
981 if (buf_cur + appetite > buf_end) {
982 DPRINTFN(8,
983 ("midiread: uiomove cc=%td (prewrap)\n",
984 buf_end - buf_cur));
985 mutex_exit(sc->lock);
986 error = uiomove(buf_cur, buf_end - buf_cur, uio);
987 mutex_enter(sc->lock);
988 if (error)
989 break;
990 if (sc->dying) {
991 error = EIO;
992 break;
993 }
994 appetite -= buf_end - buf_cur;
995 buf_cur = mb->buf;
996 }
997 DPRINTFN(8, ("midiread: uiomove cc=%d\n", appetite));
998 mutex_exit(sc->lock);
999 error = uiomove(buf_cur, appetite, uio);
1000 mutex_enter(sc->lock);
1001 if (error)
1002 break;
1003 if (sc->dying) {
1004 error = EIO;
1005 break;
1006 }
1007 buf_cur += appetite;
1008 }
1009
1010 MIDI_BUF_WRAP(idx);
1011 MIDI_BUF_WRAP(buf);
1012 MIDI_BUF_CONSUMER_WBACK(mb,idx);
1013 MIDI_BUF_CONSUMER_WBACK(mb,buf);
1014 if (0 == uio->uio_resid) /* if read satisfied, we're done */
1015 break;
1016 MIDI_BUF_CONSUMER_REFRESH(mb,idx);
1017 if (idx_cur == idx_lim) { /* need to wait for data? */
1018 if (!first || sc->rcv_eof) /* never block reader if */
1019 break; /* any data already in hand */
1020 if (ioflag & IO_NDELAY) {
1021 error = EWOULDBLOCK;
1022 break;
1023 }
1024 error = cv_wait_sig(&sc->rchan, sc->lock);
1025 if (error)
1026 break;
1027 MIDI_BUF_CONSUMER_REFRESH(mb,idx); /* what'd we get? */
1028 }
1029 MIDI_BUF_CONSUMER_REFRESH(mb,buf);
1030 if (sc->dying) {
1031 error = EIO;
1032 break;
1033 }
1034 }
1035 mutex_exit(sc->lock);
1036
1037 device_release(self);
1038 return error;
1039 }
1040
1041 static void
1042 midi_rcv_asense(void *arg)
1043 {
1044 struct midi_softc *sc;
1045
1046 sc = arg;
1047
1048 mutex_enter(sc->lock);
1049 if (sc->dying || !sc->isopen) {
1050 mutex_exit(sc->lock);
1051 return;
1052 }
1053 if (sc->rcv_quiescent) {
1054 sc->rcv_eof = 1;
1055 sc->rcv_quiescent = 0;
1056 sc->rcv_expect_asense = 0;
1057 cv_broadcast(&sc->rchan);
1058 selnotify(&sc->rsel, 0, NOTE_SUBMIT);
1059 if (sc->async)
1060 softint_schedule(sc->sih);
1061 mutex_exit(sc->lock);
1062 return;
1063 }
1064 sc->rcv_quiescent = 1;
1065 callout_schedule(&sc->rcv_asense_co, MIDI_RCV_ASENSE_PERIOD);
1066 mutex_exit(sc->lock);
1067 }
1068
1069 static void
1070 midi_xmt_asense(void *arg)
1071 {
1072 struct midi_softc *sc;
1073 int error, armed;
1074
1075 sc = arg;
1076
1077 mutex_enter(sc->lock);
1078 if (sc->pbus || sc->dying || !sc->isopen) {
1079 mutex_exit(sc->lock);
1080 return;
1081 }
1082 sc->pbus = 1;
1083 if (sc->props & MIDI_PROP_OUT_INTR) {
1084 error = sc->hw_if->output(sc->hw_hdl, MIDI_ACK);
1085 armed = (error == 0);
1086 } else {
1087 error = sc->hw_if->output(sc->hw_hdl, MIDI_ACK);
1088 armed = 0;
1089 }
1090 if (!armed) {
1091 sc->pbus = 0;
1092 callout_schedule(&sc->xmt_asense_co, MIDI_XMT_ASENSE_PERIOD);
1093 }
1094 mutex_exit(sc->lock);
1095 }
1096
1097 /*
1098 * The way this function was hacked up to plug into poll_out and intr_out
1099 * after they were written won't win it any beauty contests, but it'll work
1100 * (code in haste, refactor at leisure).
1101 */
1102 static int
1103 midi_msg_out(struct midi_softc *sc, u_char **idx, u_char **idxl, u_char **buf,
1104 u_char **bufl)
1105 {
1106 MIDI_BUF_DECLARE(idx);
1107 MIDI_BUF_DECLARE(buf);
1108 MIDI_BUF_EXTENT_INIT(&sc->outbuf,idx);
1109 MIDI_BUF_EXTENT_INIT(&sc->outbuf,buf);
1110 int length;
1111 int error;
1112 u_char contig[3];
1113 u_char *cp;
1114 u_char *ep;
1115
1116 KASSERT(mutex_owned(sc->lock));
1117
1118 idx_cur = *idx;
1119 idx_lim = *idxl;
1120 buf_cur = *buf;
1121 buf_lim = *bufl;
1122
1123 length = MB_IDX_LEN(*idx_cur);
1124
1125 for ( cp = contig, ep = cp + length; cp < ep;) {
1126 *cp++ = *buf_cur++;
1127 MIDI_BUF_WRAP(buf);
1128 }
1129 cp = contig;
1130
1131 switch ( MB_IDX_CAT(*idx_cur)) {
1132 case FST_CHV: /* chnmsg to be compressed (for device that wants it) */
1133 ++ cp;
1134 -- length;
1135 /* FALLTHROUGH */
1136 case FST_CHN:
1137 error = sc->hw_if_ext->channel(sc->hw_hdl,
1138 MIDI_GET_STATUS(contig[0]), MIDI_GET_CHAN(contig[0]),
1139 cp, length);
1140 break;
1141 case FST_COM:
1142 error = sc->hw_if_ext->common(sc->hw_hdl,
1143 MIDI_GET_STATUS(contig[0]), cp, length);
1144 break;
1145 case FST_SYX:
1146 case FST_SXP:
1147 error = sc->hw_if_ext->sysex(sc->hw_hdl, cp, length);
1148 break;
1149 case FST_RT:
1150 error = sc->hw_if->output(sc->hw_hdl, *cp);
1151 break;
1152 default:
1153 error = EIO;
1154 }
1155
1156 if (!error) {
1157 ++ idx_cur;
1158 MIDI_BUF_WRAP(idx);
1159 *idx = idx_cur;
1160 *idxl = idx_lim;
1161 *buf = buf_cur;
1162 *bufl = buf_lim;
1163 }
1164
1165 return error;
1166 }
1167
1168 /*
1169 * midi_poll_out is intended for the midi hw (the vast majority of MIDI UARTs
1170 * on sound cards, apparently) that _do not have transmit-ready interrupts_.
1171 * Every call to hw_if->output for one of these may busy-wait to output the
1172 * byte; at the standard midi data rate that'll be 320us per byte. The
1173 * technique of writing only MIDI_MAX_WRITE bytes in a row and then waiting
1174 * for MIDI_WAIT does not reduce the total time spent busy-waiting, and it
1175 * adds arbitrary delays in transmission (and, since MIDI_WAIT is roughly the
1176 * same as the time to send MIDI_MAX_WRITE bytes, it effectively halves the
1177 * data rate). Here, a somewhat bolder approach is taken. Since midi traffic
1178 * is bursty but time-sensitive--most of the time there will be none at all,
1179 * but when there is it should go out ASAP--the strategy is to just get it
1180 * over with, and empty the buffer in one go. The effect this can have on
1181 * the rest of the system will be limited by the size of the buffer and the
1182 * sparseness of the traffic. But some precautions are in order. Interrupts
1183 * should all be unmasked when this is called, and midiwrite should not fill
1184 * the buffer more than once (when MIDI_PROP_CAN_INTR is false) without a
1185 * yield() so some other process can get scheduled. If the write is nonblocking,
1186 * midiwrite should return a short count rather than yield.
1187 *
1188 * Someday when there is fine-grained MP support, this should be reworked to
1189 * run in a callout so the writing process really could proceed concurrently.
1190 * But obviously where performance is a concern, interrupt-driven hardware
1191 * such as USB midi or (apparently) clcs will always be preferable. And it
1192 * seems (kern/32651) that many of the devices currently working in poll mode
1193 * may really have tx interrupt capability and want only implementation; that
1194 * ought to happen.
1195 */
1196 static int
1197 midi_poll_out(struct midi_softc *sc)
1198 {
1199 struct midi_buffer *mb = &sc->outbuf;
1200 int error;
1201 int msglen;
1202 MIDI_BUF_DECLARE(idx);
1203 MIDI_BUF_DECLARE(buf);
1204
1205 KASSERT(mutex_owned(sc->lock));
1206
1207 error = 0;
1208 MIDI_BUF_CONSUMER_INIT(mb,idx);
1209 MIDI_BUF_CONSUMER_INIT(mb,buf);
1210
1211 for (;;) {
1212 while (idx_cur != idx_lim) {
1213 if (sc->hw_if_ext) {
1214 error = midi_msg_out(sc, &idx_cur, &idx_lim,
1215 &buf_cur, &buf_lim);
1216 if (error != 0) {
1217 break;
1218 }
1219 continue;
1220 }
1221 /* or, lacking hw_if_ext ... */
1222 msglen = MB_IDX_LEN(*idx_cur);
1223 DPRINTFN(7,("midi_poll_out: %p <- %#02x\n",
1224 sc->hw_hdl, *buf_cur));
1225 error = sc->hw_if->output(sc->hw_hdl, *buf_cur);
1226 if (error) {
1227 break;
1228 }
1229 buf_cur++;
1230 MIDI_BUF_WRAP(buf);
1231 msglen--;
1232 if (msglen) {
1233 *idx_cur = PACK_MB_IDX(MB_IDX_CAT(*idx_cur),
1234 msglen);
1235 } else {
1236 idx_cur++;
1237 MIDI_BUF_WRAP(idx);
1238 }
1239 }
1240 if (error != 0) {
1241 break;
1242 }
1243 KASSERT(buf_cur == buf_lim);
1244 MIDI_BUF_CONSUMER_WBACK(mb,idx);
1245 MIDI_BUF_CONSUMER_WBACK(mb,buf);
1246 MIDI_BUF_CONSUMER_REFRESH(mb,idx); /* any more to transmit? */
1247 MIDI_BUF_CONSUMER_REFRESH(mb,buf);
1248 if (idx_lim == idx_cur)
1249 break;
1250 }
1251
1252 if (error != 0) {
1253 DPRINTF(("midi_poll_output error %d\n", error));
1254 MIDI_BUF_CONSUMER_WBACK(mb,idx);
1255 MIDI_BUF_CONSUMER_WBACK(mb,buf);
1256 }
1257 sc->pbus = 0;
1258 callout_schedule(&sc->xmt_asense_co, MIDI_XMT_ASENSE_PERIOD);
1259 return error;
1260 }
1261
1262 /*
1263 * The interrupt flavor acquires spl and lock once and releases at the end,
1264 * as it expects to write only one byte or message. The interface convention
1265 * is that if hw_if->output returns 0, it has initiated transmission and the
1266 * completion interrupt WILL be forthcoming; if it has not returned 0, NO
1267 * interrupt will be forthcoming, and if it returns EINPROGRESS it wants
1268 * another byte right away.
1269 */
1270 static int
1271 midi_intr_out(struct midi_softc *sc)
1272 {
1273 struct midi_buffer *mb;
1274 int error, msglen;
1275 MIDI_BUF_DECLARE(idx);
1276 MIDI_BUF_DECLARE(buf);
1277 int armed = 0;
1278
1279 KASSERT(mutex_owned(sc->lock));
1280
1281 error = 0;
1282 mb = &sc->outbuf;
1283
1284 MIDI_BUF_CONSUMER_INIT(mb,idx);
1285 MIDI_BUF_CONSUMER_INIT(mb,buf);
1286
1287 while (idx_cur != idx_lim) {
1288 if (sc->hw_if_ext) {
1289 error = midi_msg_out(sc, &idx_cur, &idx_lim,
1290 &buf_cur, &buf_lim);
1291 if (!error ) /* no EINPROGRESS from extended hw_if */
1292 armed = 1;
1293 break;
1294 }
1295 /* or, lacking hw_if_ext ... */
1296 msglen = MB_IDX_LEN(*idx_cur);
1297 error = sc->hw_if->output(sc->hw_hdl, *buf_cur);
1298 if (error && error != EINPROGRESS)
1299 break;
1300 ++buf_cur;
1301 MIDI_BUF_WRAP(buf);
1302 --msglen;
1303 if (msglen)
1304 *idx_cur = PACK_MB_IDX(MB_IDX_CAT(*idx_cur),msglen);
1305 else {
1306 ++idx_cur;
1307 MIDI_BUF_WRAP(idx);
1308 }
1309 if (!error) {
1310 armed = 1;
1311 break;
1312 }
1313 }
1314 MIDI_BUF_CONSUMER_WBACK(mb,idx);
1315 MIDI_BUF_CONSUMER_WBACK(mb,buf);
1316 if (!armed) {
1317 sc->pbus = 0;
1318 callout_schedule(&sc->xmt_asense_co, MIDI_XMT_ASENSE_PERIOD);
1319 }
1320 cv_broadcast(&sc->wchan);
1321 selnotify(&sc->wsel, 0, NOTE_SUBMIT);
1322 if (sc->async) {
1323 softint_schedule(sc->sih);
1324 }
1325 if (error) {
1326 DPRINTF(("midi_intr_output error %d\n", error));
1327 }
1328 return error;
1329 }
1330
1331 static int
1332 midi_start_output(struct midi_softc *sc)
1333 {
1334
1335 KASSERT(mutex_owned(sc->lock));
1336
1337 if (sc->dying)
1338 return EIO;
1339 if (sc->props & MIDI_PROP_OUT_INTR)
1340 return midi_intr_out(sc);
1341 return midi_poll_out(sc);
1342 }
1343
1344 static int
1345 real_writebytes(struct midi_softc *sc, u_char *ibuf, int cc)
1346 {
1347 u_char *iend;
1348 struct midi_buffer *mb;
1349 int arming, count, got;
1350 enum fst_form form;
1351 MIDI_BUF_DECLARE(idx);
1352 MIDI_BUF_DECLARE(buf);
1353 int error;
1354
1355 KASSERT(mutex_owned(sc->lock));
1356
1357 if (sc->dying || !sc->isopen)
1358 return EIO;
1359
1360 sc->refcnt++;
1361
1362 iend = ibuf + cc;
1363 mb = &sc->outbuf;
1364 arming = 0;
1365
1366 /*
1367 * If the hardware uses the extended hw_if, pass it canonicalized
1368 * messages (or compressed ones if it specifically requests, using
1369 * VCOMP form so the bottom half can still pass the op and chan along);
1370 * if it does not, send it compressed messages (using COMPR form as
1371 * there is no need to preserve the status for the bottom half).
1372 */
1373 if (NULL == sc->hw_if_ext)
1374 form = FST_COMPR;
1375 else if (sc->hw_if_ext->compress)
1376 form = FST_VCOMP;
1377 else
1378 form = FST_CANON;
1379
1380 MIDI_BUF_PRODUCER_INIT(mb,idx);
1381 MIDI_BUF_PRODUCER_INIT(mb,buf);
1382
1383 while (ibuf < iend) {
1384 got = midi_fst(&sc->xmt, *ibuf, form);
1385 ++ibuf;
1386 switch ( got) {
1387 case FST_MORE:
1388 continue;
1389 case FST_ERR:
1390 case FST_HUH:
1391 error = EPROTO;
1392 goto out;
1393 case FST_CHN:
1394 case FST_CHV: /* only occurs in VCOMP form */
1395 case FST_COM:
1396 case FST_RT:
1397 case FST_SYX:
1398 case FST_SXP:
1399 break; /* go add to buffer */
1400 #if defined(AUDIO_DEBUG) || defined(DIAGNOSTIC)
1401 default:
1402 printf("midi_wr: midi_fst returned %d?!\n", got);
1403 #endif
1404 }
1405 count = sc->xmt.end - sc->xmt.pos;
1406 if (0 == count ) /* can happen with stray 0xf7; see midi_fst */
1407 continue;
1408 /*
1409 * return EWOULDBLOCK if the data passed will not fit in
1410 * the buffer; the caller should have taken steps to avoid that.
1411 * If got==FST_SXP we lose the new status byte, but we're losing
1412 * anyway, so c'est la vie.
1413 */
1414 if (idx_cur == idx_lim || count > buf_lim - buf_cur) {
1415 MIDI_BUF_PRODUCER_REFRESH(mb,idx); /* get the most */
1416 MIDI_BUF_PRODUCER_REFRESH(mb,buf); /* current facts */
1417 if (idx_cur == idx_lim || count > buf_lim - buf_cur) {
1418 error = EWOULDBLOCK; /* caller's problem */
1419 goto out;
1420 }
1421 }
1422 *idx_cur++ = PACK_MB_IDX(got,count);
1423 MIDI_BUF_WRAP(idx);
1424 while (count) {
1425 *buf_cur++ = *(sc->xmt.pos)++;
1426 MIDI_BUF_WRAP(buf);
1427 -- count;
1428 }
1429 if (FST_SXP == got)
1430 -- ibuf; /* again with same status byte */
1431 }
1432 MIDI_BUF_PRODUCER_WBACK(mb,buf);
1433 MIDI_BUF_PRODUCER_WBACK(mb,idx);
1434 /*
1435 * If the output transfer is not already busy, and there is a message
1436 * buffered, mark it busy, stop the Active Sense callout (what if we're
1437 * too late and it's expired already? No big deal, an extra Active Sense
1438 * never hurt anybody) and start the output transfer once we're out of
1439 * the critical section (pbus==1 will stop anyone else doing the same).
1440 */
1441 MIDI_BUF_CONSUMER_INIT(mb,idx); /* check what consumer's got to read */
1442 if (!sc->pbus && idx_cur < idx_lim) {
1443 sc->pbus = 1;
1444 callout_stop(&sc->xmt_asense_co);
1445 arming = 1;
1446 }
1447
1448 error = arming ? midi_start_output(sc) : 0;
1449
1450 out:
1451 if (--sc->refcnt < 0)
1452 cv_broadcast(&sc->detach_cv);
1453
1454 return error;
1455 }
1456
1457 static int
1458 midiwrite(dev_t dev, struct uio *uio, int ioflag)
1459 {
1460 device_t self;
1461 struct midi_softc *sc;
1462 struct midi_buffer *mb;
1463 int error;
1464 u_char inp[256];
1465 MIDI_BUF_DECLARE(idx);
1466 MIDI_BUF_DECLARE(buf);
1467 size_t idxspace;
1468 size_t bufspace;
1469 size_t xfrcount;
1470 int pollout = 0;
1471
1472 (void)buf_end; (void)idx_end;
1473 self = device_lookup_acquire(&midi_cd, MIDIUNIT(dev));
1474 if (self == NULL)
1475 return ENXIO;
1476
1477 sc = device_private(self);
1478
1479 DPRINTFN(6,("midiwrite: %p, unit=%d, count=%lu\n", sc, (int)minor(dev),
1480 (unsigned long)uio->uio_resid));
1481
1482 mutex_enter(sc->lock);
1483 if (sc->dying) {
1484 mutex_exit(sc->lock);
1485 device_release(self);
1486 return EIO;
1487 }
1488
1489 sc->refcnt++;
1490
1491 mb = &sc->outbuf;
1492 error = 0;
1493 while (uio->uio_resid > 0 && !error) {
1494 /*
1495 * block if necessary for the minimum buffer space to guarantee
1496 * we can write something.
1497 */
1498 MIDI_BUF_PRODUCER_INIT(mb,idx); /* init can't go above loop; */
1499 MIDI_BUF_PRODUCER_INIT(mb,buf); /* real_writebytes moves cur */
1500 for (;;) {
1501 idxspace = MIDI_BUF_PRODUCER_REFRESH(mb,idx) - idx_cur;
1502 bufspace = MIDI_BUF_PRODUCER_REFRESH(mb,buf) - buf_cur;
1503 if (idxspace >= 1 && bufspace >= 3 && !pollout)
1504 break;
1505 DPRINTFN(8,("midi_write: sleep idx=%zd buf=%zd\n",
1506 idxspace, bufspace));
1507 if (ioflag & IO_NDELAY) {
1508 /*
1509 * If some amount has already been transferred,
1510 * the common syscall code will automagically
1511 * convert this to success with a short count.
1512 */
1513 error = EWOULDBLOCK;
1514 goto out;
1515 }
1516 if (pollout) {
1517 mutex_exit(sc->lock);
1518 yield(); /* see midi_poll_output */
1519 mutex_enter(sc->lock);
1520 pollout = 0;
1521 } else
1522 error = cv_wait_sig(&sc->wchan, sc->lock);
1523 if (sc->dying)
1524 error = EIO;
1525 if (error) {
1526 /*
1527 * Similarly, the common code will handle
1528 * EINTR and ERESTART properly here, changing to
1529 * a short count if something transferred.
1530 */
1531 goto out;
1532 }
1533 }
1534
1535 /*
1536 * The number of bytes we can safely extract from the uio
1537 * depends on the available idx and buf space. Worst case,
1538 * every byte is a message so 1 idx is required per byte.
1539 * Worst case, the first byte completes a 3-byte msg in prior
1540 * state, and every subsequent byte is a Program Change or
1541 * Channel Pressure msg with running status and expands to 2
1542 * bytes, so the buf space reqd is 3+2(n-1) or 2n+1. So limit
1543 * the transfer to the min of idxspace and (bufspace-1)>>1.
1544 */
1545 xfrcount = (bufspace - 1) >> 1;
1546 if (xfrcount > idxspace)
1547 xfrcount = idxspace;
1548 if (xfrcount > sizeof inp)
1549 xfrcount = sizeof inp;
1550 if (xfrcount > uio->uio_resid)
1551 xfrcount = uio->uio_resid;
1552
1553 mutex_exit(sc->lock);
1554 error = uiomove(inp, xfrcount, uio);
1555 mutex_enter(sc->lock);
1556 #ifdef MIDI_DEBUG
1557 if (error)
1558 printf("midi_write:(1) uiomove failed %d; "
1559 "xfrcount=%zu inp=%p\n",
1560 error, xfrcount, inp);
1561 #endif
1562 if (error)
1563 break;
1564
1565 /*
1566 * The number of bytes we extracted being calculated to
1567 * definitely fit in the buffer even with canonicalization,
1568 * there is no excuse for real_writebytes to return EWOULDBLOCK.
1569 */
1570 error = real_writebytes(sc, inp, xfrcount);
1571 KASSERT(error != EWOULDBLOCK);
1572 if (error)
1573 break;
1574
1575 /*
1576 * If this is a polling device and we just sent a buffer, let's
1577 * not send another without giving some other process a chance.
1578 */
1579 if ((sc->props & MIDI_PROP_OUT_INTR) == 0)
1580 pollout = 1;
1581 DPRINTFN(8,("midiwrite: uio_resid now %zu, props=%d\n",
1582 uio->uio_resid, sc->props));
1583 }
1584
1585 out:
1586 if (--sc->refcnt < 0)
1587 cv_broadcast(&sc->detach_cv);
1588
1589 mutex_exit(sc->lock);
1590 device_release(self);
1591 return error;
1592 }
1593
1594 /*
1595 * This write routine is only called from sequencer code and expects
1596 * a write that is smaller than the MIDI buffer.
1597 */
1598 int
1599 midi_writebytes(int unit, u_char *bf, int cc)
1600 {
1601 device_t self = device_lookup_acquire(&midi_cd, unit);
1602 struct midi_softc *sc;
1603 int error;
1604
1605 if (self == NULL)
1606 return ENXIO;
1607 sc = device_private(self);
1608 if (!sc) {
1609 device_release(self);
1610 return EIO;
1611 }
1612
1613 DPRINTFN(7, ("midi_writebytes: %p, unit=%d, cc=%d %#02x %#02x %#02x\n",
1614 sc, unit, cc, bf[0], bf[1], bf[2]));
1615
1616 mutex_enter(sc->lock);
1617 if (sc->dying)
1618 error = EIO;
1619 else
1620 error = real_writebytes(sc, bf, cc);
1621 mutex_exit(sc->lock);
1622
1623 device_release(self);
1624 return error;
1625 }
1626
1627 static int
1628 midiioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
1629 {
1630 device_t self;
1631 struct midi_softc *sc;
1632 const struct midi_hw_if *hw;
1633 int error;
1634 MIDI_BUF_DECLARE(buf);
1635
1636 (void)buf_end;
1637 self = device_lookup_acquire(&midi_cd, MIDIUNIT(dev));
1638 if (self == NULL)
1639 return ENXIO;
1640
1641 sc = device_private(self);
1642
1643 mutex_enter(sc->lock);
1644 if (sc->dying) {
1645 mutex_exit(sc->lock);
1646 device_release(self);
1647 return EIO;
1648 }
1649 hw = sc->hw_if;
1650 error = 0;
1651
1652 sc->refcnt++;
1653
1654 DPRINTFN(5,("midiioctl: %p cmd=0x%08lx\n", sc, cmd));
1655
1656 switch (cmd) {
1657 case FIONBIO:
1658 /* All handled in the upper layer. */
1659 break;
1660
1661 case FIONREAD:
1662 /*
1663 * This code relies on the current implementation of midi_in
1664 * always updating buf and idx together in a critical section,
1665 * so buf always ends at a message boundary. Document this
1666 * ioctl as always returning a value such that the last message
1667 * included is complete (SysEx the only exception), and then
1668 * make sure the implementation doesn't regress. NB that
1669 * means if this ioctl returns n and the proc then issues a
1670 * read of n, n bytes will be read, but if the proc issues a
1671 * read of m < n, fewer than m bytes may be read to ensure the
1672 * read ends at a message boundary.
1673 */
1674 MIDI_BUF_CONSUMER_INIT(&sc->inbuf,buf);
1675 *(int *)addr = buf_lim - buf_cur;
1676 break;
1677
1678 case FIOASYNC:
1679 mutex_exit(sc->lock);
1680 mutex_enter(proc_lock);
1681 if (*(int *)addr) {
1682 if (sc->async) {
1683 error = EBUSY;
1684 } else {
1685 sc->async = curproc->p_pid;
1686 }
1687 DPRINTFN(5,("midi_ioctl: FIOASYNC %d\n",
1688 curproc->p_pid));
1689 } else {
1690 sc->async = 0;
1691 }
1692 mutex_exit(proc_lock);
1693 mutex_enter(sc->lock);
1694 break;
1695
1696 #if 0
1697 case MIDI_PRETIME:
1698 /* XXX OSS
1699 * This should set up a read timeout, but that's
1700 * why we have poll(), so there's nothing yet. */
1701 error = EINVAL;
1702 break;
1703 #endif
1704
1705 #ifdef MIDI_SAVE
1706 case MIDI_GETSAVE:
1707 mutex_exit(sc->lock);
1708 error = copyout(&midisave, *(void **)addr, sizeof midisave);
1709 mutex_enter(sc->lock);
1710 break;
1711 #endif
1712
1713 default:
1714 if (hw->ioctl != NULL) {
1715 error = hw->ioctl(sc->hw_hdl, cmd, addr, flag, l);
1716 } else {
1717 error = EINVAL;
1718 }
1719 break;
1720 }
1721
1722 if (--sc->refcnt < 0)
1723 cv_broadcast(&sc->detach_cv);
1724 mutex_exit(sc->lock);
1725 device_release(self);
1726 return error;
1727 }
1728
1729 static int
1730 midipoll(dev_t dev, int events, struct lwp *l)
1731 {
1732 device_t self;
1733 struct midi_softc *sc;
1734 int revents;
1735 MIDI_BUF_DECLARE(idx);
1736 MIDI_BUF_DECLARE(buf);
1737
1738 (void)buf_end; (void)idx_end;
1739 self = device_lookup_acquire(&midi_cd, MIDIUNIT(dev));
1740 if (self == NULL)
1741 return ENXIO;
1742
1743 sc = device_private(self);
1744 revents = 0;
1745
1746 DPRINTFN(6,("midipoll: %p events=0x%x\n", sc, events));
1747
1748 mutex_enter(sc->lock);
1749 if (sc->dying) {
1750 mutex_exit(sc->lock);
1751 device_release(self);
1752 return POLLHUP;
1753 }
1754
1755 sc->refcnt++;
1756
1757 if ((events & (POLLIN | POLLRDNORM)) != 0) {
1758 MIDI_BUF_CONSUMER_INIT(&sc->inbuf, idx);
1759 if (idx_cur < idx_lim)
1760 revents |= events & (POLLIN | POLLRDNORM);
1761 else
1762 selrecord(l, &sc->rsel);
1763 }
1764 if ((events & (POLLOUT | POLLWRNORM)) != 0) {
1765 MIDI_BUF_PRODUCER_INIT(&sc->outbuf, idx);
1766 MIDI_BUF_PRODUCER_INIT(&sc->outbuf, buf);
1767 if (idx_lim - idx_cur >= 1 && buf_lim - buf_cur >= 3)
1768 revents |= events & (POLLOUT | POLLWRNORM);
1769 else
1770 selrecord(l, &sc->wsel);
1771 }
1772
1773 if (--sc->refcnt < 0)
1774 cv_broadcast(&sc->detach_cv);
1775
1776 mutex_exit(sc->lock);
1777
1778 device_release(self);
1779 return revents;
1780 }
1781
1782 static void
1783 filt_midirdetach(struct knote *kn)
1784 {
1785 struct midi_softc *sc = kn->kn_hook;
1786
1787 mutex_enter(sc->lock);
1788 SLIST_REMOVE(&sc->rsel.sel_klist, kn, knote, kn_selnext);
1789 mutex_exit(sc->lock);
1790 }
1791
1792 static int
1793 filt_midiread(struct knote *kn, long hint)
1794 {
1795 struct midi_softc *sc = kn->kn_hook;
1796 MIDI_BUF_DECLARE(buf);
1797
1798 (void)buf_end;
1799 if (hint != NOTE_SUBMIT)
1800 mutex_enter(sc->lock);
1801 MIDI_BUF_CONSUMER_INIT(&sc->inbuf,buf);
1802 kn->kn_data = buf_lim - buf_cur;
1803 if (hint != NOTE_SUBMIT)
1804 mutex_exit(sc->lock);
1805 return (kn->kn_data > 0);
1806 }
1807
1808 static const struct filterops midiread_filtops =
1809 { 1, NULL, filt_midirdetach, filt_midiread };
1810
1811 static void
1812 filt_midiwdetach(struct knote *kn)
1813 {
1814 struct midi_softc *sc = kn->kn_hook;
1815
1816 mutex_enter(sc->lock);
1817 SLIST_REMOVE(&sc->wsel.sel_klist, kn, knote, kn_selnext);
1818 mutex_exit(sc->lock);
1819 }
1820
1821 static int
1822 filt_midiwrite(struct knote *kn, long hint)
1823 {
1824 struct midi_softc *sc = kn->kn_hook;
1825 MIDI_BUF_DECLARE(idx);
1826 MIDI_BUF_DECLARE(buf);
1827
1828 mutex_exit(sc->lock);
1829 sc->refcnt++;
1830 mutex_enter(sc->lock);
1831
1832 (void)idx_end; (void)buf_end;
1833 if (hint != NOTE_SUBMIT)
1834 mutex_enter(sc->lock);
1835 MIDI_BUF_PRODUCER_INIT(&sc->outbuf,idx);
1836 MIDI_BUF_PRODUCER_INIT(&sc->outbuf,buf);
1837 kn->kn_data = ((buf_lim - buf_cur)-1)>>1;
1838 if (kn->kn_data > idx_lim - idx_cur)
1839 kn->kn_data = idx_lim - idx_cur;
1840 if (hint != NOTE_SUBMIT)
1841 mutex_exit(sc->lock);
1842
1843 // XXXMRG -- move this up, avoid the relock?
1844 mutex_enter(sc->lock);
1845 if (--sc->refcnt < 0)
1846 cv_broadcast(&sc->detach_cv);
1847 mutex_exit(sc->lock);
1848
1849 return (kn->kn_data > 0);
1850 }
1851
1852 static const struct filterops midiwrite_filtops =
1853 { 1, NULL, filt_midiwdetach, filt_midiwrite };
1854
1855 int
1856 midikqfilter(dev_t dev, struct knote *kn)
1857 {
1858 device_t self;
1859 struct midi_softc *sc;
1860 struct klist *klist;
1861
1862 self = device_lookup_acquire(&midi_cd, MIDIUNIT(dev));
1863 if (self == NULL)
1864 return ENXIO;
1865 sc = device_private(self);
1866
1867 mutex_exit(sc->lock);
1868 sc->refcnt++;
1869 mutex_enter(sc->lock);
1870
1871 switch (kn->kn_filter) {
1872 case EVFILT_READ:
1873 klist = &sc->rsel.sel_klist;
1874 kn->kn_fop = &midiread_filtops;
1875 break;
1876
1877 case EVFILT_WRITE:
1878 klist = &sc->wsel.sel_klist;
1879 kn->kn_fop = &midiwrite_filtops;
1880 break;
1881
1882 default:
1883 device_release(self);
1884 return (EINVAL);
1885 }
1886
1887 kn->kn_hook = sc;
1888
1889 mutex_enter(sc->lock);
1890 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
1891 if (--sc->refcnt < 0)
1892 cv_broadcast(&sc->detach_cv);
1893 mutex_exit(sc->lock);
1894
1895 device_release(self);
1896 return (0);
1897 }
1898
1899 void
1900 midi_getinfo(dev_t dev, struct midi_info *mi)
1901 {
1902 device_t self;
1903 struct midi_softc *sc;
1904
1905 self = device_lookup_acquire(&midi_cd, MIDIUNIT(dev));
1906 if (self == NULL)
1907 return;
1908 sc = device_private(self);
1909
1910 mutex_enter(sc->lock);
1911 sc->hw_if->getinfo(sc->hw_hdl, mi);
1912 mutex_exit(sc->lock);
1913 device_release(self);
1914 }
1915
1916 #elif NMIDIBUS > 0 /* but NMIDI == 0 */
1917
1918 void
1919 midi_register_hw_if_ext(struct midi_hw_if_ext *exthw)
1920 {
1921
1922 /* nothing */
1923 }
1924
1925 #endif /* NMIDI > 0 */
1926
1927 #if NMIDI > 0 || NMIDIBUS > 0
1928
1929 device_t
1930 midi_attach_mi(const struct midi_hw_if *mhwp, void *hdlp, device_t dev)
1931 {
1932 struct audio_attach_args arg;
1933
1934 if (mhwp == NULL) {
1935 panic("midi_attach_mi: NULL\n");
1936 return (0);
1937 }
1938
1939 arg.type = AUDIODEV_TYPE_MIDI;
1940 arg.hwif = mhwp;
1941 arg.hdl = hdlp;
1942 return (config_found(dev, &arg, audioprint));
1943 }
1944
1945 #endif /* NMIDI > 0 || NMIDIBUS > 0 */
1946