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