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