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