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