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