1 /* $NetBSD: midi.c,v 1.64 2008/04/24 15:35:28 ad 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.64 2008/04/24 15:35:28 ad 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/device.h> 63 #include <sys/intr.h> 64 65 #include <dev/audio_if.h> 66 #include <dev/midi_if.h> 67 #include <dev/midivar.h> 68 69 #if NMIDI > 0 70 71 #ifdef AUDIO_DEBUG 72 #define DPRINTF(x) if (mididebug) printf x 73 #define DPRINTFN(n,x) if (mididebug >= (n)) printf x 74 int mididebug = 0; 75 /* 76 * 1: detected protocol errors and buffer overflows 77 * 2: probe, attach, detach 78 * 3: open, close 79 * 4: data received except realtime 80 * 5: ioctl 81 * 6: read, write, poll 82 * 7: data transmitted 83 * 8: uiomoves, synchronization 84 * 9: realtime data received 85 */ 86 #else 87 #define DPRINTF(x) 88 #define DPRINTFN(n,x) 89 #endif 90 91 static struct simplelock hwif_register_lock = SIMPLELOCK_INITIALIZER; 92 static struct midi_softc *hwif_softc = NULL; 93 94 void midi_in(void *, int); 95 void midi_out(void *); 96 int midi_poll_out(struct midi_softc *); 97 int midi_intr_out(struct midi_softc *); 98 int midi_msg_out(struct midi_softc *, 99 u_char **, u_char **, u_char **, u_char **); 100 int midi_start_output(struct midi_softc *); 101 int midi_sleep_timo(int *, const char *, int, struct simplelock *); 102 int midi_sleep(int *, const char *, struct simplelock *); 103 void midi_wakeup(int *); 104 void midi_initbuf(struct midi_buffer *); 105 void midi_xmt_asense(void *); 106 void midi_rcv_asense(void *); 107 void midi_softintr_rd(void *); 108 void midi_softintr_wr(void *); 109 110 int midiprobe(device_t, cfdata_t, void *); 111 void midiattach(device_t, device_t, void *); 112 int mididetach(device_t, int); 113 int midiactivate(device_t, enum devact); 114 115 dev_type_open(midiopen); 116 dev_type_close(midiclose); 117 dev_type_read(midiread); 118 dev_type_write(midiwrite); 119 dev_type_ioctl(midiioctl); 120 dev_type_poll(midipoll); 121 dev_type_kqfilter(midikqfilter); 122 123 const struct cdevsw midi_cdevsw = { 124 midiopen, midiclose, midiread, midiwrite, midiioctl, 125 nostop, notty, midipoll, nommap, midikqfilter, D_OTHER, 126 }; 127 128 CFATTACH_DECL_NEW(midi, sizeof(struct midi_softc), 129 midiprobe, midiattach, mididetach, midiactivate); 130 131 #define MIDI_XMT_ASENSE_PERIOD mstohz(275) 132 #define MIDI_RCV_ASENSE_PERIOD mstohz(300) 133 134 extern struct cfdriver midi_cd; 135 136 int 137 midiprobe(device_t parent, cfdata_t match, 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(device_t parent, device_t self, void *aux) 148 { 149 struct midi_softc *sc = device_private(self); 150 struct audio_attach_args *sa = aux; 151 const struct midi_hw_if *hwp = 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->dev = self; 170 sc->hw_if = hwp; 171 sc->hw_hdl = hdlp; 172 midi_attach(sc, parent); 173 if (!device_pmf_is_registered(self)) 174 if (!pmf_device_register(self, NULL, NULL)) 175 aprint_error_dev(self, 176 "couldn't establish power handler\n"); 177 } 178 179 int 180 midiactivate(device_t self, enum devact act) 181 { 182 struct midi_softc *sc = device_private(self); 183 184 switch (act) { 185 case DVACT_ACTIVATE: 186 return (EOPNOTSUPP); 187 188 case DVACT_DEACTIVATE: 189 sc->dying = 1; 190 break; 191 } 192 return (0); 193 } 194 195 int 196 mididetach(device_t self, int flags) 197 { 198 struct midi_softc *sc = device_private(self); 199 int maj, mn; 200 201 DPRINTFN(2,("midi_detach: sc=%p flags=%d\n", sc, flags)); 202 203 pmf_device_deregister(self); 204 205 sc->dying = 1; 206 207 wakeup(&sc->wchan); 208 wakeup(&sc->rchan); 209 210 /* locate the major number */ 211 maj = cdevsw_lookup_major(&midi_cdevsw); 212 213 /* Nuke the vnodes for any open instances (calls close). */ 214 mn = device_unit(self); 215 vdevgone(maj, mn, mn, VCHR); 216 217 if ( !(sc->props & MIDI_PROP_NO_OUTPUT) ) { 218 evcnt_detach(&sc->xmt.bytesDiscarded); 219 evcnt_detach(&sc->xmt.incompleteMessages); 220 } 221 if ( sc->props & MIDI_PROP_CAN_INPUT ) { 222 evcnt_detach(&sc->rcv.bytesDiscarded); 223 evcnt_detach(&sc->rcv.incompleteMessages); 224 } 225 226 if (sc->sih_rd != NULL) { 227 softint_disestablish(sc->sih_rd); 228 sc->sih_rd = NULL; 229 } 230 if (sc->sih_wr != NULL) { 231 softint_disestablish(sc->sih_wr); 232 sc->sih_wr = NULL; 233 } 234 235 return (0); 236 } 237 238 void 239 midi_attach(struct midi_softc *sc, device_t parent) 240 { 241 struct midi_info mi; 242 int s; 243 244 callout_init(&sc->xmt_asense_co, 0); 245 callout_init(&sc->rcv_asense_co, 0); 246 callout_setfunc(&sc->xmt_asense_co, midi_xmt_asense, sc); 247 callout_setfunc(&sc->rcv_asense_co, midi_rcv_asense, sc); 248 simple_lock_init(&sc->out_lock); 249 simple_lock_init(&sc->in_lock); 250 sc->dying = 0; 251 sc->isopen = 0; 252 253 sc->sc_dev = parent; 254 255 sc->sih_rd = softint_establish(SOFTINT_SERIAL, midi_softintr_rd, sc); 256 sc->sih_wr = softint_establish(SOFTINT_SERIAL, midi_softintr_wr, sc); 257 258 s = splaudio(); 259 simple_lock(&hwif_register_lock); 260 hwif_softc = sc; 261 sc->hw_if->getinfo(sc->hw_hdl, &mi); 262 hwif_softc = NULL; 263 simple_unlock(&hwif_register_lock); 264 splx(s); 265 266 sc->props = mi.props; 267 268 if ( !(sc->props & MIDI_PROP_NO_OUTPUT) ) { 269 evcnt_attach_dynamic(&sc->xmt.bytesDiscarded, 270 EVCNT_TYPE_MISC, NULL, 271 device_xname(sc->dev), "xmt bytes discarded"); 272 evcnt_attach_dynamic(&sc->xmt.incompleteMessages, 273 EVCNT_TYPE_MISC, NULL, 274 device_xname(sc->dev), "xmt incomplete msgs"); 275 } 276 if ( sc->props & MIDI_PROP_CAN_INPUT ) { 277 evcnt_attach_dynamic(&sc->rcv.bytesDiscarded, 278 EVCNT_TYPE_MISC, NULL, 279 device_xname(sc->dev), "rcv bytes discarded"); 280 evcnt_attach_dynamic(&sc->rcv.incompleteMessages, 281 EVCNT_TYPE_MISC, NULL, 282 device_xname(sc->dev), "rcv incomplete msgs"); 283 } 284 285 aprint_normal(": %s%s\n", mi.name, 286 (sc->props & (MIDI_PROP_OUT_INTR|MIDI_PROP_NO_OUTPUT)) ? 287 "" : " (CPU-intensive output)"); 288 } 289 290 void midi_register_hw_if_ext(struct midi_hw_if_ext *exthw) { 291 if ( hwif_softc != NULL ) /* ignore calls resulting from non-init */ 292 hwif_softc->hw_if_ext = exthw; /* uses of getinfo */ 293 } 294 295 int 296 midi_unit_count(void) 297 { 298 int i; 299 for ( i = 0; i < midi_cd.cd_ndevs; ++i ) 300 if ( NULL == midi_cd.cd_devs[i] ) 301 break; 302 return i; 303 } 304 305 void 306 midi_initbuf(struct midi_buffer *mb) 307 { 308 mb->idx_producerp = mb->idx_consumerp = mb->idx; 309 mb->buf_producerp = mb->buf_consumerp = mb->buf; 310 } 311 #define PACK_MB_IDX(cat,len) (((cat)<<4)|(len)) 312 #define MB_IDX_CAT(idx) ((idx)>>4) 313 #define MB_IDX_LEN(idx) ((idx)&0xf) 314 315 int 316 midi_sleep_timo(int *chan, const char *label, int timo, struct simplelock *lk) 317 { 318 int st; 319 320 if (!label) 321 label = "midi"; 322 323 DPRINTFN(8, ("midi_sleep_timo: %p %s %d\n", chan, label, timo)); 324 *chan = 1; 325 st = ltsleep(chan, PWAIT | PCATCH, label, timo, lk); 326 *chan = 0; 327 #ifdef MIDI_DEBUG 328 if (st != 0) 329 printf("midi_sleep: %d\n", st); 330 #endif 331 return st; 332 } 333 334 int 335 midi_sleep(int *chan, const char *label, struct simplelock *lk) 336 { 337 return midi_sleep_timo(chan, label, 0, lk); 338 } 339 340 void 341 midi_wakeup(int *chan) 342 { 343 if (*chan) { 344 DPRINTFN(8, ("midi_wakeup: %p\n", chan)); 345 wakeup(chan); 346 *chan = 0; 347 } 348 } 349 350 /* in midivar.h: 351 #define MIDI_CAT_DATA 0 352 #define MIDI_CAT_STATUS1 1 353 #define MIDI_CAT_STATUS2 2 354 #define MIDI_CAT_COMMON 3 355 */ 356 static char const midi_cats[] = "\0\0\0\0\0\0\0\0\2\2\2\2\1\1\2\3"; 357 #define MIDI_CAT(d) (midi_cats[((d)>>4)&15]) 358 #define FST_RETURN(offp,endp,ret) \ 359 return (s->pos=s->msg+(offp)), (s->end=s->msg+(endp)), (ret) 360 361 enum fst_ret { FST_CHN, FST_CHV, FST_COM, FST_SYX, FST_RT, FST_MORE, FST_ERR, 362 FST_HUH, FST_SXP }; 363 enum fst_form { FST_CANON, FST_COMPR, FST_VCOMP }; 364 static struct { 365 int off; 366 enum fst_ret tag; 367 } const midi_forms[] = { 368 [FST_CANON] = { .off=0, .tag=FST_CHN }, 369 [FST_COMPR] = { .off=1, .tag=FST_CHN }, 370 [FST_VCOMP] = { .off=0, .tag=FST_CHV } 371 }; 372 #define FST_CRETURN(endp) \ 373 FST_RETURN(midi_forms[form].off,endp,midi_forms[form].tag) 374 375 /* 376 * A MIDI finite state transducer suitable for receiving or transmitting. It 377 * will accept correct MIDI input that uses, doesn't use, or sometimes uses the 378 * 'running status' compression technique, and transduce it to fully expanded 379 * (form=FST_CANON) or fully compressed (form=FST_COMPR or FST_VCOMP) form. 380 * 381 * Returns FST_MORE if a complete message has not been parsed yet (SysEx 382 * messages are the exception), FST_ERR or FST_HUH if the input does not 383 * conform to the protocol, or FST_CHN (channel messages), FST_COM (System 384 * Common messages), FST_RT (System Real-Time messages), or FST_SYX (System 385 * Exclusive) to broadly categorize the message parsed. s->pos and s->end 386 * locate the parsed message; while (s->pos<s->end) putchar(*(s->pos++)); 387 * would output it. 388 * 389 * FST_HUH means the character c wasn't valid in the original state, but the 390 * state has now been reset to START and the caller should try again passing 391 * the same c. FST_ERR means c isn't valid in the start state; the caller 392 * should kiss it goodbye and continue to try successive characters from the 393 * input until something other than FST_ERR or FST_HUH is returned, at which 394 * point things are resynchronized. 395 * 396 * A FST_SYX return means that between pos and end are from 1 to 3 397 * bytes of a system exclusive message. A SysEx message will be delivered in 398 * one or more chunks of that form, where the first begins with 0xf0 and the 399 * last (which is the only one that might have length < 3) ends with 0xf7. 400 * 401 * Messages corrupted by a protocol error are discarded and won't be seen at 402 * all; again SysEx is the exception, as one or more chunks of it may already 403 * have been parsed. 404 * 405 * For FST_CHN messages, s->msg[0] always contains the status byte even if 406 * FST_COMPR form was requested (pos then points to msg[1]). That way, the 407 * caller can always identify the exact message if there is a need to do so. 408 * For all other message types except FST_SYX, the status byte is at *pos 409 * (which may not necessarily be msg[0]!). There is only one SysEx status 410 * byte, so the return value FST_SYX is sufficient to identify it. 411 * 412 * To simplify some use cases, compression can also be requested with 413 * form=FST_VCOMP. In this form a compressible channel message is indicated 414 * by returning a classification of FST_CHV instead of FST_CHN, and pos points 415 * to the status byte rather than being advanced past it. If the caller in this 416 * case saves the bytes from pos to end, it will have saved the entire message, 417 * and can act on the FST_CHV tag to drop the first byte later. In this form, 418 * unlike FST_CANON, hidden note-off (i.e. note-on with velocity 0) may occur. 419 * 420 * Two obscure points in the MIDI protocol complicate things further, both to 421 * do with the EndSysEx code, 0xf7. First, this code is permitted (and 422 * meaningless) outside of a System Exclusive message, anywhere a status byte 423 * could appear. Second, it is allowed to be absent at the end of a System 424 * Exclusive message (!) - any status byte at all (non-realtime) is allowed to 425 * terminate the message. Both require accomodation in the interface to 426 * midi_fst's caller. A stray 0xf7 should be ignored BUT should count as a 427 * message received for purposes of Active Sense timeout; the case is 428 * represented by a return of FST_COM with a length of zero (pos == end). A 429 * status byte other than 0xf7 during a system exclusive message will cause an 430 * FST_SXP (sysex plus) return; the bytes from pos to end are the end of the 431 * system exclusive message, and after handling those the caller should call 432 * midi_fst again with the same input byte. 433 * 434 * midi(4) will never produce either such form of rubbish. 435 */ 436 static enum fst_ret 437 midi_fst(struct midi_state *s, u_char c, enum fst_form form) 438 { 439 int syxpos = 0; 440 441 if ( c >= 0xf8 ) { /* All realtime messages bypass state machine */ 442 if ( c == 0xf9 || c == 0xfd ) { 443 DPRINTF( ("midi_fst: s=%p c=0x%02x undefined\n", 444 s, c)); 445 s->bytesDiscarded.ev_count++; 446 return FST_ERR; 447 } 448 DPRINTFN(9, ("midi_fst: s=%p System Real-Time data=0x%02x\n", 449 s, c)); 450 s->msg[2] = c; 451 FST_RETURN(2,3,FST_RT); 452 } 453 454 DPRINTFN(4, ("midi_fst: s=%p data=0x%02x state=%d\n", 455 s, c, s->state)); 456 457 switch ( s->state | MIDI_CAT(c) ) { /* break ==> return FST_MORE */ 458 459 case MIDI_IN_START | MIDI_CAT_COMMON: 460 case MIDI_IN_RUN1_1 | MIDI_CAT_COMMON: 461 case MIDI_IN_RUN2_2 | MIDI_CAT_COMMON: 462 case MIDI_IN_RXX2_2 | MIDI_CAT_COMMON: 463 s->msg[0] = c; 464 switch ( c ) { 465 case 0xf0: s->state = MIDI_IN_SYX1_3; break; 466 case 0xf1: s->state = MIDI_IN_COM0_1; break; 467 case 0xf2: s->state = MIDI_IN_COM0_2; break; 468 case 0xf3: s->state = MIDI_IN_COM0_1; break; 469 case 0xf6: s->state = MIDI_IN_START; FST_RETURN(0,1,FST_COM); 470 case 0xf7: s->state = MIDI_IN_START; FST_RETURN(0,0,FST_COM); 471 default: goto protocol_violation; 472 } 473 break; 474 475 case MIDI_IN_RUN1_1 | MIDI_CAT_STATUS1: 476 if ( c == s->msg[0] ) { 477 s->state = MIDI_IN_RNX0_1; 478 break; 479 } 480 /* FALLTHROUGH */ 481 case MIDI_IN_RUN2_2 | MIDI_CAT_STATUS1: 482 case MIDI_IN_RXX2_2 | MIDI_CAT_STATUS1: 483 case MIDI_IN_START | MIDI_CAT_STATUS1: 484 s->state = MIDI_IN_RUN0_1; 485 s->msg[0] = c; 486 break; 487 488 case MIDI_IN_RUN2_2 | MIDI_CAT_STATUS2: 489 case MIDI_IN_RXX2_2 | MIDI_CAT_STATUS2: 490 if ( c == s->msg[0] ) { 491 s->state = MIDI_IN_RNX0_2; 492 break; 493 } 494 if ( (c ^ s->msg[0]) == 0x10 && (c & 0xe0) == 0x80 ) { 495 s->state = MIDI_IN_RXX0_2; 496 s->msg[0] = c; 497 break; 498 } 499 /* FALLTHROUGH */ 500 case MIDI_IN_RUN1_1 | MIDI_CAT_STATUS2: 501 case MIDI_IN_START | MIDI_CAT_STATUS2: 502 s->state = MIDI_IN_RUN0_2; 503 s->msg[0] = c; 504 break; 505 506 case MIDI_IN_COM0_1 | MIDI_CAT_DATA: 507 s->state = MIDI_IN_START; 508 s->msg[1] = c; 509 FST_RETURN(0,2,FST_COM); 510 511 case MIDI_IN_COM0_2 | MIDI_CAT_DATA: 512 s->state = MIDI_IN_COM1_2; 513 s->msg[1] = c; 514 break; 515 516 case MIDI_IN_COM1_2 | MIDI_CAT_DATA: 517 s->state = MIDI_IN_START; 518 s->msg[2] = c; 519 FST_RETURN(0,3,FST_COM); 520 521 case MIDI_IN_RUN0_1 | MIDI_CAT_DATA: 522 s->state = MIDI_IN_RUN1_1; 523 s->msg[1] = c; 524 FST_RETURN(0,2,FST_CHN); 525 526 case MIDI_IN_RUN1_1 | MIDI_CAT_DATA: 527 case MIDI_IN_RNX0_1 | MIDI_CAT_DATA: 528 s->state = MIDI_IN_RUN1_1; 529 s->msg[1] = c; 530 FST_CRETURN(2); 531 532 case MIDI_IN_RUN0_2 | MIDI_CAT_DATA: 533 s->state = MIDI_IN_RUN1_2; 534 s->msg[1] = c; 535 break; 536 537 case MIDI_IN_RUN1_2 | MIDI_CAT_DATA: 538 if ( FST_CANON == form && 0 == c && (s->msg[0]&0xf0) == 0x90 ) { 539 s->state = MIDI_IN_RXX2_2; 540 s->msg[0] ^= 0x10; 541 s->msg[2] = 64; 542 } else { 543 s->state = MIDI_IN_RUN2_2; 544 s->msg[2] = c; 545 } 546 FST_RETURN(0,3,FST_CHN); 547 548 case MIDI_IN_RUN2_2 | MIDI_CAT_DATA: 549 s->state = MIDI_IN_RNX1_2; 550 s->msg[1] = c; 551 break; 552 553 case MIDI_IN_RXX2_2 | MIDI_CAT_DATA: 554 s->state = MIDI_IN_RXX1_2; 555 s->msg[0] ^= 0x10; 556 s->msg[1] = c; 557 break; 558 559 case MIDI_IN_RNX0_2 | MIDI_CAT_DATA: 560 s->state = MIDI_IN_RNY1_2; 561 s->msg[1] = c; 562 break; 563 564 case MIDI_IN_RXX0_2 | MIDI_CAT_DATA: 565 s->state = MIDI_IN_RXY1_2; 566 s->msg[1] = c; 567 break; 568 569 case MIDI_IN_RNX1_2 | MIDI_CAT_DATA: 570 case MIDI_IN_RNY1_2 | MIDI_CAT_DATA: 571 if ( FST_CANON == form && 0 == c && (s->msg[0]&0xf0) == 0x90 ) { 572 s->state = MIDI_IN_RXX2_2; 573 s->msg[0] ^= 0x10; 574 s->msg[2] = 64; 575 FST_RETURN(0,3,FST_CHN); 576 } 577 s->state = MIDI_IN_RUN2_2; 578 s->msg[2] = c; 579 FST_CRETURN(3); 580 581 case MIDI_IN_RXX1_2 | MIDI_CAT_DATA: 582 case MIDI_IN_RXY1_2 | MIDI_CAT_DATA: 583 if ( ( 0 == c && (s->msg[0]&0xf0) == 0x90) 584 || (64 == c && (s->msg[0]&0xf0) == 0x80 585 && FST_CANON != form) ) { 586 s->state = MIDI_IN_RXX2_2; 587 s->msg[0] ^= 0x10; 588 s->msg[2] = 64 - c; 589 FST_CRETURN(3); 590 } 591 s->state = MIDI_IN_RUN2_2; 592 s->msg[2] = c; 593 FST_RETURN(0,3,FST_CHN); 594 595 case MIDI_IN_SYX1_3 | MIDI_CAT_DATA: 596 s->state = MIDI_IN_SYX2_3; 597 s->msg[1] = c; 598 break; 599 600 case MIDI_IN_SYX2_3 | MIDI_CAT_DATA: 601 s->state = MIDI_IN_SYX0_3; 602 s->msg[2] = c; 603 FST_RETURN(0,3,FST_SYX); 604 605 case MIDI_IN_SYX0_3 | MIDI_CAT_DATA: 606 s->state = MIDI_IN_SYX1_3; 607 s->msg[0] = c; 608 break; 609 610 case MIDI_IN_SYX2_3 | MIDI_CAT_COMMON: 611 case MIDI_IN_SYX2_3 | MIDI_CAT_STATUS1: 612 case MIDI_IN_SYX2_3 | MIDI_CAT_STATUS2: 613 ++ syxpos; 614 /* FALLTHROUGH */ 615 case MIDI_IN_SYX1_3 | MIDI_CAT_COMMON: 616 case MIDI_IN_SYX1_3 | MIDI_CAT_STATUS1: 617 case MIDI_IN_SYX1_3 | MIDI_CAT_STATUS2: 618 ++ syxpos; 619 /* FALLTHROUGH */ 620 case MIDI_IN_SYX0_3 | MIDI_CAT_COMMON: 621 case MIDI_IN_SYX0_3 | MIDI_CAT_STATUS1: 622 case MIDI_IN_SYX0_3 | MIDI_CAT_STATUS2: 623 s->state = MIDI_IN_START; 624 if ( c == 0xf7 ) { 625 s->msg[syxpos] = c; 626 FST_RETURN(0,1+syxpos,FST_SYX); 627 } 628 s->msg[syxpos] = 0xf7; 629 FST_RETURN(0,1+syxpos,FST_SXP); 630 631 default: 632 protocol_violation: 633 DPRINTF(("midi_fst: unexpected %#02x in state %u\n", 634 c, s->state)); 635 switch ( s->state ) { 636 case MIDI_IN_RUN1_1: /* can only get here by seeing an */ 637 case MIDI_IN_RUN2_2: /* INVALID System Common message */ 638 case MIDI_IN_RXX2_2: 639 s->state = MIDI_IN_START; 640 /* FALLTHROUGH */ 641 case MIDI_IN_START: 642 s->bytesDiscarded.ev_count++; 643 return FST_ERR; 644 case MIDI_IN_COM1_2: 645 case MIDI_IN_RUN1_2: 646 case MIDI_IN_RNY1_2: 647 case MIDI_IN_RXY1_2: 648 s->bytesDiscarded.ev_count++; 649 /* FALLTHROUGH */ 650 case MIDI_IN_COM0_1: 651 case MIDI_IN_RUN0_1: 652 case MIDI_IN_RNX0_1: 653 case MIDI_IN_COM0_2: 654 case MIDI_IN_RUN0_2: 655 case MIDI_IN_RNX0_2: 656 case MIDI_IN_RXX0_2: 657 case MIDI_IN_RNX1_2: 658 case MIDI_IN_RXX1_2: 659 s->bytesDiscarded.ev_count++; 660 s->incompleteMessages.ev_count++; 661 break; 662 #if defined(AUDIO_DEBUG) || defined(DIAGNOSTIC) 663 default: 664 printf("midi_fst: mishandled %#02x(%u) in state %u?!\n", 665 c, MIDI_CAT(c), s->state); 666 #endif 667 } 668 s->state = MIDI_IN_START; 669 return FST_HUH; 670 } 671 return FST_MORE; 672 } 673 674 void 675 midi_softintr_rd(void *cookie) 676 { 677 struct midi_softc *sc = cookie; 678 struct proc *p; 679 680 if (sc->async != NULL) { 681 mutex_enter(proc_lock); 682 if ((p = sc->async) != NULL) 683 psignal(p, SIGIO); 684 mutex_exit(proc_lock); 685 } 686 midi_wakeup(&sc->rchan); 687 selnotify(&sc->rsel, 0, 0); /* filter will spin if locked */ 688 } 689 690 void 691 midi_softintr_wr(void *cookie) 692 { 693 struct midi_softc *sc = cookie; 694 struct proc *p; 695 696 if (sc->async != NULL) { 697 mutex_enter(proc_lock); 698 if ((p = sc->async) != NULL) 699 psignal(p, SIGIO); 700 mutex_exit(proc_lock); 701 } 702 midi_wakeup(&sc->wchan); 703 selnotify(&sc->wsel, 0, 0); /* filter will spin if locked */ 704 } 705 706 void 707 midi_in(void *addr, int data) 708 { 709 struct midi_softc *sc = addr; 710 struct midi_buffer *mb = &sc->inbuf; 711 int i; 712 int count; 713 enum fst_ret got; 714 int s; /* hw may have various spls so impose our own */ 715 MIDI_BUF_DECLARE(idx); 716 MIDI_BUF_DECLARE(buf); 717 718 if (!sc->isopen) 719 return; 720 721 if (!(sc->flags & FREAD)) 722 return; /* discard data if not reading */ 723 724 sxp_again: 725 do 726 got = midi_fst(&sc->rcv, data, FST_CANON); 727 while ( got == FST_HUH ); 728 729 switch ( got ) { 730 case FST_MORE: 731 case FST_ERR: 732 return; 733 case FST_CHN: 734 case FST_COM: 735 case FST_RT: 736 #if NSEQUENCER > 0 737 if (sc->seqopen) { 738 extern void midiseq_in(struct midi_dev *,u_char *,int); 739 count = sc->rcv.end - sc->rcv.pos; 740 midiseq_in(sc->seq_md, sc->rcv.pos, count); 741 return; 742 } 743 #endif 744 /* 745 * Pass Active Sense to the sequencer if it's open, but not to 746 * a raw reader. (Really should do something intelligent with 747 * it then, though....) 748 */ 749 if ( got == FST_RT && MIDI_ACK == sc->rcv.pos[0] ) { 750 if ( !sc->rcv_expect_asense ) { 751 sc->rcv_expect_asense = 1; 752 callout_schedule(&sc->rcv_asense_co, 753 MIDI_RCV_ASENSE_PERIOD); 754 } 755 sc->rcv_quiescent = 0; 756 sc->rcv_eof = 0; 757 return; 758 } 759 /* FALLTHROUGH */ 760 /* 761 * Ultimately SysEx msgs should be offered to the sequencer also; the 762 * sequencer API addresses them - but maybe our sequencer can't handle 763 * them yet, so offer only to raw reader. (Which means, ultimately, 764 * discard them if the sequencer's open, as it's not doing reads!) 765 * -> When SysEx support is added to the sequencer, be sure to handle 766 * FST_SXP there too. 767 */ 768 case FST_SYX: 769 case FST_SXP: 770 count = sc->rcv.end - sc->rcv.pos; 771 MIDI_IN_LOCK(sc,s); 772 sc->rcv_quiescent = 0; 773 sc->rcv_eof = 0; 774 if ( 0 == count ) { 775 MIDI_IN_UNLOCK(sc,s); 776 break; 777 } 778 MIDI_BUF_PRODUCER_INIT(mb,idx); 779 MIDI_BUF_PRODUCER_INIT(mb,buf); 780 if (count > buf_lim - buf_cur 781 || 1 > idx_lim - idx_cur) { 782 sc->rcv.bytesDiscarded.ev_count += count; 783 MIDI_IN_UNLOCK(sc,s); 784 DPRINTF(("midi_in: buffer full, discard data=0x%02x\n", 785 sc->rcv.pos[0])); 786 return; 787 } 788 for (i = 0; i < count; i++) { 789 *buf_cur++ = sc->rcv.pos[i]; 790 MIDI_BUF_WRAP(buf); 791 } 792 *idx_cur++ = PACK_MB_IDX(got,count); 793 MIDI_BUF_WRAP(idx); 794 MIDI_BUF_PRODUCER_WBACK(mb,buf); 795 MIDI_BUF_PRODUCER_WBACK(mb,idx); 796 MIDI_IN_UNLOCK(sc,s); 797 softint_schedule(sc->sih_rd); 798 break; 799 default: /* don't #ifdef this away, gcc will say FST_HUH not handled */ 800 printf("midi_in: midi_fst returned %d?!\n", got); 801 } 802 if ( FST_SXP == got ) 803 goto sxp_again; 804 } 805 806 void 807 midi_out(void *addr) 808 { 809 struct midi_softc *sc = addr; 810 811 if (!sc->isopen) 812 return; 813 DPRINTFN(8, ("midi_out: %p\n", sc)); 814 midi_intr_out(sc); 815 } 816 817 int 818 midiopen(dev_t dev, int flags, int ifmt, struct lwp *l) 819 { 820 struct midi_softc *sc; 821 const struct midi_hw_if *hw; 822 int error; 823 824 sc = device_private(device_lookup(&midi_cd, MIDIUNIT(dev))); 825 if (sc == NULL) 826 return (ENXIO); 827 if (sc->dying) 828 return (EIO); 829 830 DPRINTFN(3,("midiopen %p\n", sc)); 831 832 hw = sc->hw_if; 833 if (!hw) 834 return ENXIO; 835 if (sc->isopen) 836 return EBUSY; 837 838 /* put both state machines into known states */ 839 sc->rcv.state = MIDI_IN_START; 840 sc->rcv.pos = sc->rcv.msg; 841 sc->rcv.end = sc->rcv.msg; 842 sc->xmt.state = MIDI_IN_START; 843 sc->xmt.pos = sc->xmt.msg; 844 sc->xmt.end = sc->xmt.msg; 845 846 /* copy error counters so an ioctl (TBA) can give since-open stats */ 847 sc->rcv.atOpen.bytesDiscarded = sc->rcv.bytesDiscarded.ev_count; 848 sc->rcv.atQuery.bytesDiscarded = sc->rcv.bytesDiscarded.ev_count; 849 850 sc->xmt.atOpen.bytesDiscarded = sc->xmt.bytesDiscarded.ev_count; 851 sc->xmt.atQuery.bytesDiscarded = sc->xmt.bytesDiscarded.ev_count; 852 853 /* and the buffers */ 854 midi_initbuf(&sc->outbuf); 855 midi_initbuf(&sc->inbuf); 856 857 /* and the receive flags */ 858 sc->rcv_expect_asense = 0; 859 sc->rcv_quiescent = 0; 860 sc->rcv_eof = 0; 861 862 error = hw->open(sc->hw_hdl, flags, midi_in, midi_out, sc); 863 if (error) 864 return error; 865 sc->isopen++; 866 sc->flags = flags; 867 sc->rchan = 0; 868 sc->wchan = 0; 869 sc->pbus = 0; 870 sc->async = 0; 871 872 #ifdef MIDI_SAVE 873 if (midicnt != 0) { 874 midisave.cnt = midicnt; 875 midicnt = 0; 876 } 877 #endif 878 879 return 0; 880 } 881 882 int 883 midiclose(dev_t dev, int flags, int ifmt, 884 struct lwp *l) 885 { 886 struct midi_softc *sc = 887 device_private(device_lookup(&midi_cd, MIDIUNIT(dev))); 888 const struct midi_hw_if *hw = sc->hw_if; 889 int s, error; 890 891 DPRINTFN(3,("midiclose %p\n", sc)); 892 893 /* midi_start_output(sc); anything buffered => pbus already set! */ 894 error = 0; 895 MIDI_OUT_LOCK(sc,s); 896 while (sc->pbus) { 897 DPRINTFN(8,("midiclose sleep ...\n")); 898 error = 899 midi_sleep_timo(&sc->wchan, "mid_dr", 30*hz, &sc->out_lock); 900 } 901 sc->isopen = 0; 902 MIDI_OUT_UNLOCK(sc,s); 903 callout_stop(&sc->xmt_asense_co); /* xxx fix this - sleep? */ 904 callout_stop(&sc->rcv_asense_co); 905 hw->close(sc->hw_hdl); 906 #if NSEQUENCER > 0 907 sc->seqopen = 0; 908 sc->seq_md = 0; 909 #endif 910 return 0; 911 } 912 913 int 914 midiread(dev_t dev, struct uio *uio, int ioflag) 915 { 916 struct midi_softc *sc = 917 device_private(device_lookup(&midi_cd, MIDIUNIT(dev))); 918 struct midi_buffer *mb = &sc->inbuf; 919 int error; 920 int s; 921 MIDI_BUF_DECLARE(idx); 922 MIDI_BUF_DECLARE(buf); 923 int appetite; 924 int first = 1; 925 926 DPRINTFN(6,("midiread: %p, count=%lu\n", sc, 927 (unsigned long)uio->uio_resid)); 928 929 if (sc->dying) 930 return EIO; 931 if ( !(sc->props & MIDI_PROP_CAN_INPUT) ) 932 return ENXIO; 933 934 MIDI_IN_LOCK(sc,s); 935 MIDI_BUF_CONSUMER_INIT(mb,idx); 936 MIDI_BUF_CONSUMER_INIT(mb,buf); 937 MIDI_IN_UNLOCK(sc,s); 938 939 error = 0; 940 for ( ;; ) { 941 /* 942 * If the used portion of idx wraps around the end, just take 943 * the first part on this iteration, and we'll get the rest on 944 * the next. 945 */ 946 if ( idx_lim > idx_end ) 947 idx_lim = idx_end; 948 /* 949 * Count bytes through the last complete message that will 950 * fit in the requested read. 951 */ 952 for (appetite = uio->uio_resid; idx_cur < idx_lim; ++idx_cur) { 953 if ( appetite < MB_IDX_LEN(*idx_cur) ) 954 break; 955 appetite -= MB_IDX_LEN(*idx_cur); 956 } 957 appetite = uio->uio_resid - appetite; 958 /* 959 * Only if the read is too small to hold even the first 960 * complete message will we return a partial one (updating idx 961 * to reflect the remaining length of the message). 962 */ 963 if ( appetite == 0 && idx_cur < idx_lim ) { 964 if ( !first ) 965 goto unlocked_exit; /* idx_cur not advanced */ 966 appetite = uio->uio_resid; 967 *idx_cur = PACK_MB_IDX(MB_IDX_CAT(*idx_cur), 968 MB_IDX_LEN(*idx_cur) - appetite); 969 } 970 KASSERT(buf_cur + appetite <= buf_lim); 971 972 /* move the bytes */ 973 if ( appetite > 0 ) { 974 first = 0; /* we know we won't return empty-handed */ 975 /* do two uiomoves if data wrap around end of buf */ 976 if ( buf_cur + appetite > buf_end ) { 977 DPRINTFN(8, 978 ("midiread: uiomove cc=%td (prewrap)\n", 979 buf_end - buf_cur)); 980 error = uiomove(buf_cur, buf_end-buf_cur, uio); 981 if ( error ) 982 goto unlocked_exit; 983 appetite -= buf_end - buf_cur; 984 buf_cur = mb->buf; 985 } 986 DPRINTFN(8, ("midiread: uiomove cc=%d\n", appetite)); 987 error = uiomove(buf_cur, appetite, uio); 988 if ( error ) 989 goto unlocked_exit; 990 buf_cur += appetite; 991 } 992 993 MIDI_BUF_WRAP(idx); 994 MIDI_BUF_WRAP(buf); 995 996 MIDI_IN_LOCK(sc,s); 997 MIDI_BUF_CONSUMER_WBACK(mb,idx); 998 MIDI_BUF_CONSUMER_WBACK(mb,buf); 999 if ( 0 == uio->uio_resid ) /* if read satisfied, we're done */ 1000 break; 1001 MIDI_BUF_CONSUMER_REFRESH(mb,idx); 1002 if ( idx_cur == idx_lim ) { /* need to wait for data? */ 1003 if ( !first || sc->rcv_eof ) /* never block reader if */ 1004 break; /* any data already in hand */ 1005 if (ioflag & IO_NDELAY) { 1006 error = EWOULDBLOCK; 1007 break; 1008 } 1009 error = midi_sleep(&sc->rchan, "mid rd", &sc->in_lock); 1010 if ( error ) 1011 break; 1012 MIDI_BUF_CONSUMER_REFRESH(mb,idx); /* what'd we get? */ 1013 } 1014 MIDI_BUF_CONSUMER_REFRESH(mb,buf); 1015 MIDI_IN_UNLOCK(sc,s); 1016 if ( sc->dying ) 1017 return EIO; 1018 } 1019 MIDI_IN_UNLOCK(sc,s); 1020 1021 unlocked_exit: 1022 return error; 1023 } 1024 1025 void 1026 midi_rcv_asense(void *arg) 1027 { 1028 struct midi_softc *sc = arg; 1029 int s; 1030 1031 if ( sc->dying || !sc->isopen ) 1032 return; 1033 1034 if ( sc->rcv_quiescent ) { 1035 MIDI_IN_LOCK(sc,s); 1036 sc->rcv_eof = 1; 1037 sc->rcv_quiescent = 0; 1038 sc->rcv_expect_asense = 0; 1039 MIDI_IN_UNLOCK(sc,s); 1040 softint_schedule(sc->sih_rd); 1041 return; 1042 } 1043 1044 sc->rcv_quiescent = 1; 1045 callout_schedule(&sc->rcv_asense_co, MIDI_RCV_ASENSE_PERIOD); 1046 } 1047 1048 void 1049 midi_xmt_asense(void *arg) 1050 { 1051 struct midi_softc *sc = arg; 1052 int s; 1053 int error; 1054 int armed; 1055 1056 if ( sc->dying || !sc->isopen ) 1057 return; 1058 1059 MIDI_OUT_LOCK(sc,s); 1060 if ( sc->pbus || sc->dying || !sc->isopen ) { 1061 MIDI_OUT_UNLOCK(sc,s); 1062 return; 1063 } 1064 sc->pbus = 1; 1065 DPRINTFN(8,("midi_xmt_asense: %p\n", sc)); 1066 1067 if ( sc->props & MIDI_PROP_OUT_INTR ) { 1068 error = sc->hw_if->output(sc->hw_hdl, MIDI_ACK); 1069 armed = (error == 0); 1070 } else { /* polled output, do with interrupts unmasked */ 1071 MIDI_OUT_UNLOCK(sc,s); 1072 /* running from softclock, so top half won't sneak in here */ 1073 error = sc->hw_if->output(sc->hw_hdl, MIDI_ACK); 1074 MIDI_OUT_LOCK(sc,s); 1075 armed = 0; 1076 } 1077 1078 if ( !armed ) { 1079 sc->pbus = 0; 1080 callout_schedule(&sc->xmt_asense_co, MIDI_XMT_ASENSE_PERIOD); 1081 } 1082 1083 MIDI_OUT_UNLOCK(sc,s); 1084 } 1085 1086 /* 1087 * The way this function was hacked up to plug into poll_out and intr_out 1088 * after they were written won't win it any beauty contests, but it'll work 1089 * (code in haste, refactor at leisure). This may be called with the lock 1090 * (by intr_out) or without the lock (by poll_out) so it only does what could 1091 * be safe either way. 1092 */ 1093 int midi_msg_out(struct midi_softc *sc, 1094 u_char **idx, u_char **idxl, u_char **buf, u_char **bufl) { 1095 MIDI_BUF_DECLARE(idx); 1096 MIDI_BUF_DECLARE(buf); 1097 MIDI_BUF_EXTENT_INIT(&sc->outbuf,idx); 1098 MIDI_BUF_EXTENT_INIT(&sc->outbuf,buf); 1099 int length; 1100 int error; 1101 u_char contig[3]; 1102 u_char *cp; 1103 u_char *ep; 1104 1105 idx_cur = *idx; 1106 idx_lim = *idxl; 1107 buf_cur = *buf; 1108 buf_lim = *bufl; 1109 1110 length = MB_IDX_LEN(*idx_cur); 1111 1112 for ( cp = contig, ep = cp + length; cp < ep; ) { 1113 *cp++ = *buf_cur++; 1114 MIDI_BUF_WRAP(buf); 1115 } 1116 cp = contig; 1117 1118 switch ( MB_IDX_CAT(*idx_cur) ) { 1119 case FST_CHV: /* chnmsg to be compressed (for device that wants it) */ 1120 ++ cp; 1121 -- length; 1122 /* FALLTHROUGH */ 1123 case FST_CHN: 1124 error = sc->hw_if_ext->channel(sc->hw_hdl, 1125 MIDI_GET_STATUS(contig[0]), 1126 MIDI_GET_CHAN(contig[0]), 1127 cp, length); 1128 break; 1129 case FST_COM: 1130 error = sc->hw_if_ext->common(sc->hw_hdl, 1131 MIDI_GET_STATUS(contig[0]), 1132 cp, length); 1133 break; 1134 case FST_SYX: 1135 case FST_SXP: 1136 error = sc->hw_if_ext->sysex(sc->hw_hdl, 1137 cp, length); 1138 break; 1139 case FST_RT: 1140 error = sc->hw_if->output(sc->hw_hdl, *cp); 1141 break; 1142 default: 1143 error = EIO; 1144 } 1145 1146 if ( !error ) { 1147 ++ idx_cur; 1148 MIDI_BUF_WRAP(idx); 1149 *idx = idx_cur; 1150 *idxl = idx_lim; 1151 *buf = buf_cur; 1152 *bufl = buf_lim; 1153 } 1154 1155 return error; 1156 } 1157 1158 /* 1159 * midi_poll_out is intended for the midi hw (the vast majority of MIDI UARTs 1160 * on sound cards, apparently) that _do not have transmit-ready interrupts_. 1161 * Every call to hw_if->output for one of these may busy-wait to output the 1162 * byte; at the standard midi data rate that'll be 320us per byte. The 1163 * technique of writing only MIDI_MAX_WRITE bytes in a row and then waiting 1164 * for MIDI_WAIT does not reduce the total time spent busy-waiting, and it 1165 * adds arbitrary delays in transmission (and, since MIDI_WAIT is roughly the 1166 * same as the time to send MIDI_MAX_WRITE bytes, it effectively halves the 1167 * data rate). Here, a somewhat bolder approach is taken. Since midi traffic 1168 * is bursty but time-sensitive--most of the time there will be none at all, 1169 * but when there is it should go out ASAP--the strategy is to just get it 1170 * over with, and empty the buffer in one go. The effect this can have on 1171 * the rest of the system will be limited by the size of the buffer and the 1172 * sparseness of the traffic. But some precautions are in order. Interrupts 1173 * should all be unmasked when this is called, and midiwrite should not fill 1174 * the buffer more than once (when MIDI_PROP_CAN_INTR is false) without a 1175 * yield() so some other process can get scheduled. If the write is nonblocking, 1176 * midiwrite should return a short count rather than yield. 1177 * 1178 * Someday when there is fine-grained MP support, this should be reworked to 1179 * run in a callout so the writing process really could proceed concurrently. 1180 * But obviously where performance is a concern, interrupt-driven hardware 1181 * such as USB midi or (apparently) clcs will always be preferable. And it 1182 * seems (kern/32651) that many of the devices currently working in poll mode 1183 * may really have tx interrupt capability and want only implementation; that 1184 * ought to happen. 1185 */ 1186 int 1187 midi_poll_out(struct midi_softc *sc) 1188 { 1189 struct midi_buffer *mb = &sc->outbuf; 1190 int error; 1191 int msglen; 1192 int s; 1193 MIDI_BUF_DECLARE(idx); 1194 MIDI_BUF_DECLARE(buf); 1195 1196 error = 0; 1197 1198 MIDI_OUT_LOCK(sc,s); 1199 MIDI_BUF_CONSUMER_INIT(mb,idx); 1200 MIDI_BUF_CONSUMER_INIT(mb,buf); 1201 MIDI_OUT_UNLOCK(sc,s); 1202 1203 for ( ;; ) { 1204 while ( idx_cur != idx_lim ) { 1205 if ( sc->hw_if_ext ) { 1206 error = midi_msg_out(sc, &idx_cur, &idx_lim, 1207 &buf_cur, &buf_lim); 1208 if ( error ) 1209 goto ioerror; 1210 continue; 1211 } 1212 /* or, lacking hw_if_ext ... */ 1213 msglen = MB_IDX_LEN(*idx_cur); 1214 DPRINTFN(7,("midi_poll_out: %p <- %#02x\n", 1215 sc->hw_hdl, *buf_cur)); 1216 error = sc->hw_if->output(sc->hw_hdl, *buf_cur); 1217 if ( error ) 1218 goto ioerror; 1219 ++ buf_cur; 1220 MIDI_BUF_WRAP(buf); 1221 -- msglen; 1222 if ( msglen ) 1223 *idx_cur = PACK_MB_IDX(MB_IDX_CAT(*idx_cur), 1224 msglen); 1225 else { 1226 ++ idx_cur; 1227 MIDI_BUF_WRAP(idx); 1228 } 1229 } 1230 KASSERT(buf_cur == buf_lim); 1231 MIDI_OUT_LOCK(sc,s); 1232 MIDI_BUF_CONSUMER_WBACK(mb,idx); 1233 MIDI_BUF_CONSUMER_WBACK(mb,buf); 1234 MIDI_BUF_CONSUMER_REFRESH(mb,idx); /* any more to transmit? */ 1235 MIDI_BUF_CONSUMER_REFRESH(mb,buf); 1236 if ( idx_lim == idx_cur ) 1237 break; /* still holding lock */ 1238 MIDI_OUT_UNLOCK(sc,s); 1239 } 1240 goto disarm; /* lock held */ 1241 1242 ioerror: 1243 #if defined(AUDIO_DEBUG) || defined(DIAGNOSTIC) 1244 aprint_error_dev(sc->dev, "midi_poll_output error %d\n", 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 aprint_error_dev(sc->dev, "midi_intr_output error %d\n", 1321 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 struct midi_softc *sc = 1444 device_private(device_lookup(&midi_cd, MIDIUNIT(dev))); 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 = 1566 device_private(device_lookup(&midi_cd, unit)); 1567 1568 DPRINTFN(7, ("midi_writebytes: %p, unit=%d, cc=%d %#02x %#02x %#02x\n", 1569 sc, unit, cc, bf[0], bf[1], bf[2])); 1570 return real_writebytes(sc, bf, cc); 1571 } 1572 1573 int 1574 midiioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) 1575 { 1576 struct midi_softc *sc = 1577 device_private(device_lookup(&midi_cd, MIDIUNIT(dev))); 1578 const struct midi_hw_if *hw = sc->hw_if; 1579 int error; 1580 int s; 1581 MIDI_BUF_DECLARE(buf); 1582 1583 DPRINTFN(5,("midiioctl: %p cmd=0x%08lx\n", sc, cmd)); 1584 1585 if (sc->dying) 1586 return EIO; 1587 1588 error = 0; 1589 switch (cmd) { 1590 case FIONBIO: 1591 /* All handled in the upper FS layer. */ 1592 break; 1593 1594 case FIONREAD: 1595 /* 1596 * This code relies on the current implementation of midi_in 1597 * always updating buf and idx together in a critical section, 1598 * so buf always ends at a message boundary. Document this 1599 * ioctl as always returning a value such that the last message 1600 * included is complete (SysEx the only exception), and then 1601 * make sure the implementation doesn't regress. NB that 1602 * means if this ioctl returns n and the proc then issues a 1603 * read of n, n bytes will be read, but if the proc issues a 1604 * read of m < n, fewer than m bytes may be read to ensure the 1605 * read ends at a message boundary. 1606 */ 1607 MIDI_IN_LOCK(sc,s); 1608 MIDI_BUF_CONSUMER_INIT(&sc->inbuf,buf); 1609 MIDI_IN_UNLOCK(sc,s); 1610 *(int *)addr = buf_lim - buf_cur; 1611 break; 1612 1613 case FIOASYNC: 1614 if (*(int *)addr) { 1615 if (sc->async) 1616 return EBUSY; 1617 sc->async = l->l_proc; 1618 DPRINTFN(5,("midi_ioctl: FIOASYNC %p\n", l->l_proc)); 1619 } else 1620 sc->async = 0; 1621 break; 1622 1623 #if 0 1624 case MIDI_PRETIME: 1625 /* XXX OSS 1626 * This should set up a read timeout, but that's 1627 * why we have poll(), so there's nothing yet. */ 1628 error = EINVAL; 1629 break; 1630 #endif 1631 1632 #ifdef MIDI_SAVE 1633 case MIDI_GETSAVE: 1634 error = copyout(&midisave, *(void **)addr, sizeof midisave); 1635 break; 1636 #endif 1637 1638 default: 1639 if (hw->ioctl) 1640 error = hw->ioctl(sc->hw_hdl, cmd, addr, flag, l); 1641 else 1642 error = EINVAL; 1643 break; 1644 } 1645 return error; 1646 } 1647 1648 int 1649 midipoll(dev_t dev, int events, struct lwp *l) 1650 { 1651 struct midi_softc *sc = 1652 device_private(device_lookup(&midi_cd, MIDIUNIT(dev))); 1653 int revents = 0; 1654 int s; 1655 MIDI_BUF_DECLARE(idx); 1656 MIDI_BUF_DECLARE(buf); 1657 1658 DPRINTFN(6,("midipoll: %p events=0x%x\n", sc, events)); 1659 1660 if (sc->dying) 1661 return POLLHUP; 1662 1663 s = splaudio(); 1664 1665 if ((sc->flags&FREAD) && (events & (POLLIN | POLLRDNORM))) { 1666 simple_lock(&sc->in_lock); 1667 MIDI_BUF_CONSUMER_INIT(&sc->inbuf,idx); 1668 if (idx_cur < idx_lim) 1669 revents |= events & (POLLIN | POLLRDNORM); 1670 else 1671 selrecord(l, &sc->rsel); 1672 simple_unlock(&sc->in_lock); 1673 } 1674 1675 if ((sc->flags&FWRITE) && (events & (POLLOUT | POLLWRNORM))) { 1676 simple_lock(&sc->out_lock); 1677 MIDI_BUF_PRODUCER_INIT(&sc->outbuf,idx); 1678 MIDI_BUF_PRODUCER_INIT(&sc->outbuf,buf); 1679 if ( idx_lim - idx_cur >= 1 && buf_lim - buf_cur >= 3 ) 1680 revents |= events & (POLLOUT | POLLWRNORM); 1681 else 1682 selrecord(l, &sc->wsel); 1683 simple_unlock(&sc->out_lock); 1684 } 1685 1686 splx(s); 1687 return revents; 1688 } 1689 1690 static void 1691 filt_midirdetach(struct knote *kn) 1692 { 1693 struct midi_softc *sc = kn->kn_hook; 1694 int s; 1695 1696 s = splaudio(); 1697 SLIST_REMOVE(&sc->rsel.sel_klist, kn, knote, kn_selnext); 1698 splx(s); 1699 } 1700 1701 static int 1702 filt_midiread(struct knote *kn, long hint) 1703 { 1704 struct midi_softc *sc = kn->kn_hook; 1705 int s; 1706 MIDI_BUF_DECLARE(buf); 1707 1708 /* XXXLUKEM (thorpej): please make sure this is correct. */ 1709 1710 MIDI_IN_LOCK(sc,s); 1711 MIDI_BUF_CONSUMER_INIT(&sc->inbuf,buf); 1712 kn->kn_data = buf_lim - buf_cur; 1713 MIDI_IN_UNLOCK(sc,s); 1714 return (kn->kn_data > 0); 1715 } 1716 1717 static const struct filterops midiread_filtops = 1718 { 1, NULL, filt_midirdetach, filt_midiread }; 1719 1720 static void 1721 filt_midiwdetach(struct knote *kn) 1722 { 1723 struct midi_softc *sc = kn->kn_hook; 1724 int s; 1725 1726 s = splaudio(); 1727 SLIST_REMOVE(&sc->wsel.sel_klist, kn, knote, kn_selnext); 1728 splx(s); 1729 } 1730 1731 static int 1732 filt_midiwrite(struct knote *kn, long hint) 1733 { 1734 struct midi_softc *sc = kn->kn_hook; 1735 int s; 1736 MIDI_BUF_DECLARE(idx); 1737 MIDI_BUF_DECLARE(buf); 1738 1739 /* XXXLUKEM (thorpej): please make sure this is correct. */ 1740 1741 MIDI_OUT_LOCK(sc,s); 1742 MIDI_BUF_PRODUCER_INIT(&sc->outbuf,idx); 1743 MIDI_BUF_PRODUCER_INIT(&sc->outbuf,buf); 1744 kn->kn_data = ((buf_lim - buf_cur)-1)>>1; 1745 if ( kn->kn_data > idx_lim - idx_cur ) 1746 kn->kn_data = idx_lim - idx_cur; 1747 MIDI_OUT_UNLOCK(sc,s); 1748 return (kn->kn_data > 0); 1749 } 1750 1751 static const struct filterops midiwrite_filtops = 1752 { 1, NULL, filt_midiwdetach, filt_midiwrite }; 1753 1754 int 1755 midikqfilter(dev_t dev, struct knote *kn) 1756 { 1757 struct midi_softc *sc = 1758 device_private(device_lookup(&midi_cd, MIDIUNIT(dev))); 1759 struct klist *klist; 1760 int s; 1761 1762 switch (kn->kn_filter) { 1763 case EVFILT_READ: 1764 klist = &sc->rsel.sel_klist; 1765 kn->kn_fop = &midiread_filtops; 1766 break; 1767 1768 case EVFILT_WRITE: 1769 klist = &sc->wsel.sel_klist; 1770 kn->kn_fop = &midiwrite_filtops; 1771 break; 1772 1773 default: 1774 return (EINVAL); 1775 } 1776 1777 kn->kn_hook = sc; 1778 1779 s = splaudio(); 1780 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 1781 splx(s); 1782 1783 return (0); 1784 } 1785 1786 void 1787 midi_getinfo(dev_t dev, struct midi_info *mi) 1788 { 1789 struct midi_softc *sc; 1790 1791 sc = device_private(device_lookup(&midi_cd, MIDIUNIT(dev))); 1792 if (sc == NULL) 1793 return; 1794 if (sc->dying) 1795 return; 1796 1797 sc->hw_if->getinfo(sc->hw_hdl, mi); 1798 } 1799 1800 #elif NMIDIBUS > 0 /* but NMIDI == 0 */ 1801 1802 void midi_register_hw_if_ext(struct midi_hw_if_ext *exthw) { /* stub */ 1803 } 1804 1805 #endif /* NMIDI > 0 */ 1806 1807 #if NMIDI > 0 || NMIDIBUS > 0 1808 1809 int audioprint(void *, const char *); 1810 1811 device_t 1812 midi_attach_mi(const struct midi_hw_if *mhwp, void *hdlp, device_t dev) 1813 { 1814 struct audio_attach_args arg; 1815 1816 #ifdef DIAGNOSTIC 1817 if (mhwp == NULL) { 1818 aprint_error("midi_attach_mi: NULL\n"); 1819 return (0); 1820 } 1821 #endif 1822 arg.type = AUDIODEV_TYPE_MIDI; 1823 arg.hwif = mhwp; 1824 arg.hdl = hdlp; 1825 return (config_found(dev, &arg, audioprint)); 1826 } 1827 1828 #endif /* NMIDI > 0 || NMIDIBUS > 0 */ 1829