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