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