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