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