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