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