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