1 /* $NetBSD: midi.c,v 1.21 2001/01/31 16:19:35 tshiozak Exp $ */ 2 3 /* 4 * Copyright (c) 1998 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). 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include "midi.h" 40 #include "sequencer.h" 41 42 #include <sys/param.h> 43 #include <sys/ioctl.h> 44 #include <sys/fcntl.h> 45 #include <sys/vnode.h> 46 #include <sys/select.h> 47 #include <sys/poll.h> 48 #include <sys/malloc.h> 49 #include <sys/proc.h> 50 #include <sys/systm.h> 51 #include <sys/callout.h> 52 #include <sys/syslog.h> 53 #include <sys/kernel.h> 54 #include <sys/signalvar.h> 55 #include <sys/conf.h> 56 #include <sys/audioio.h> 57 #include <sys/midiio.h> 58 #include <sys/device.h> 59 60 #include <dev/audio_if.h> 61 #include <dev/midi_if.h> 62 #include <dev/midivar.h> 63 64 #if NMIDI > 0 65 66 #ifdef AUDIO_DEBUG 67 #define DPRINTF(x) if (mididebug) printf x 68 #define DPRINTFN(n,x) if (mididebug >= (n)) printf x 69 int mididebug = 0; 70 #else 71 #define DPRINTF(x) 72 #define DPRINTFN(n,x) 73 #endif 74 75 int midi_wait; 76 77 void midi_in __P((void *, int)); 78 void midi_out __P((void *)); 79 int midi_start_output __P((struct midi_softc *, int)); 80 int midi_sleep_timo __P((int *, char *, int)); 81 int midi_sleep __P((int *, char *)); 82 void midi_wakeup __P((int *)); 83 void midi_initbuf __P((struct midi_buffer *)); 84 void midi_timeout __P((void *)); 85 86 int midiprobe __P((struct device *, struct cfdata *, void *)); 87 void midiattach __P((struct device *, struct device *, void *)); 88 int mididetach __P((struct device *, int)); 89 int midiactivate __P((struct device *, enum devact)); 90 91 struct cfattach midi_ca = { 92 sizeof(struct midi_softc), midiprobe, midiattach, 93 mididetach, midiactivate 94 }; 95 96 #ifdef MIDI_SAVE 97 #define MIDI_SAVE_SIZE 100000 98 int midicnt; 99 struct { 100 int cnt; 101 u_char buf[MIDI_SAVE_SIZE]; 102 } midisave; 103 #define MIDI_GETSAVE _IOWR('m', 100, int) 104 105 #endif 106 107 extern struct cfdriver midi_cd; 108 109 int 110 midiprobe(parent, match, aux) 111 struct device *parent; 112 struct cfdata *match; 113 void *aux; 114 { 115 struct audio_attach_args *sa = aux; 116 117 DPRINTFN(6,("midiprobe: type=%d sa=%p hw=%p\n", 118 sa->type, sa, sa->hwif)); 119 return (sa->type == AUDIODEV_TYPE_MIDI); 120 } 121 122 void 123 midiattach(parent, self, aux) 124 struct device *parent, *self; 125 void *aux; 126 { 127 struct midi_softc *sc = (void *)self; 128 struct audio_attach_args *sa = aux; 129 struct midi_hw_if *hwp = sa->hwif; 130 void *hdlp = sa->hdl; 131 132 DPRINTFN(6, ("MIDI attach\n")); 133 134 #ifdef DIAGNOSTIC 135 if (hwp == 0 || 136 hwp->open == 0 || 137 hwp->close == 0 || 138 hwp->output == 0 || 139 hwp->getinfo == 0) { 140 printf("midi: missing method\n"); 141 return; 142 } 143 #endif 144 145 callout_init(&sc->sc_callout); 146 147 sc->hw_if = hwp; 148 sc->hw_hdl = hdlp; 149 sc->dying = 0; 150 midi_attach(sc, parent); 151 } 152 153 int 154 midiactivate(self, act) 155 struct device *self; 156 enum devact act; 157 { 158 struct midi_softc *sc = (struct midi_softc *)self; 159 160 switch (act) { 161 case DVACT_ACTIVATE: 162 return (EOPNOTSUPP); 163 break; 164 165 case DVACT_DEACTIVATE: 166 sc->dying = 1; 167 break; 168 } 169 return (0); 170 } 171 172 int 173 mididetach(self, flags) 174 struct device *self; 175 int flags; 176 { 177 struct midi_softc *sc = (struct midi_softc *)self; 178 int maj, mn; 179 180 DPRINTF(("midi_detach: sc=%p flags=%d\n", sc, flags)); 181 182 sc->dying = 1; 183 184 wakeup(&sc->wchan); 185 wakeup(&sc->rchan); 186 187 /* locate the major number */ 188 for (maj = 0; maj < nchrdev; maj++) 189 if (cdevsw[maj].d_open == midiopen) 190 break; 191 192 /* Nuke the vnodes for any open instances (calls close). */ 193 mn = self->dv_unit; 194 vdevgone(maj, mn, mn, VCHR); 195 196 return (0); 197 } 198 199 void 200 midi_attach(sc, parent) 201 struct midi_softc *sc; 202 struct device *parent; 203 { 204 struct midi_info mi; 205 206 sc->isopen = 0; 207 208 midi_wait = MIDI_WAIT * hz / 1000000; 209 if (midi_wait == 0) 210 midi_wait = 1; 211 212 sc->sc_dev = parent; 213 sc->hw_if->getinfo(sc->hw_hdl, &mi); 214 sc->props = mi.props; 215 printf(": %s\n", mi.name); 216 } 217 218 int 219 midi_unit_count() 220 { 221 return midi_cd.cd_ndevs; 222 } 223 224 void 225 midi_initbuf(mb) 226 struct midi_buffer *mb; 227 { 228 mb->used = 0; 229 mb->usedhigh = MIDI_BUFSIZE; 230 mb->end = mb->start + mb->usedhigh; 231 mb->inp = mb->outp = mb->start; 232 } 233 234 int 235 midi_sleep_timo(chan, label, timo) 236 int *chan; 237 char *label; 238 int timo; 239 { 240 int st; 241 242 if (!label) 243 label = "midi"; 244 245 DPRINTFN(5, ("midi_sleep_timo: %p %s %d\n", chan, label, timo)); 246 *chan = 1; 247 st = tsleep(chan, PWAIT | PCATCH, label, timo); 248 *chan = 0; 249 #ifdef MIDI_DEBUG 250 if (st != 0) 251 printf("midi_sleep: %d\n", st); 252 #endif 253 return st; 254 } 255 256 int 257 midi_sleep(chan, label) 258 int *chan; 259 char *label; 260 { 261 return midi_sleep_timo(chan, label, 0); 262 } 263 264 void 265 midi_wakeup(chan) 266 int *chan; 267 { 268 if (*chan) { 269 DPRINTFN(5, ("midi_wakeup: %p\n", chan)); 270 wakeup(chan); 271 *chan = 0; 272 } 273 } 274 275 static int midi_lengths[] = { 2,2,2,2,1,1,2,0 }; 276 /* Number of bytes in a MIDI command */ 277 #define MIDI_LENGTH(d) (midi_lengths[((d) >> 4) & 7]) 278 279 void 280 midi_in(addr, data) 281 void *addr; 282 int data; 283 { 284 struct midi_softc *sc = addr; 285 struct midi_buffer *mb = &sc->inbuf; 286 int i; 287 288 if (!sc->isopen) 289 return; 290 if (data == MIDI_ACK) 291 return; 292 293 DPRINTFN(3, ("midi_in: sc=%p data=0x%02x state=%d pos=%d\n", 294 sc, data, sc->in_state, sc->in_pos)); 295 296 if (!(sc->flags & FREAD)) 297 return; /* discard data if not reading */ 298 299 switch(sc->in_state) { 300 case MIDI_IN_START: 301 if (MIDI_IS_STATUS(data)) { 302 switch(data) { 303 case 0xf0: /* Sysex */ 304 sc->in_state = MIDI_IN_SYSEX; 305 break; 306 case 0xf1: /* MTC quarter frame */ 307 case 0xf3: /* Song select */ 308 sc->in_state = MIDI_IN_DATA; 309 sc->in_msg[0] = data; 310 sc->in_pos = 1; 311 sc->in_left = 1; 312 break; 313 case 0xf2: /* Song position pointer */ 314 sc->in_state = MIDI_IN_DATA; 315 sc->in_msg[0] = data; 316 sc->in_pos = 1; 317 sc->in_left = 2; 318 break; 319 default: 320 if (MIDI_IS_COMMON(data)) { 321 sc->in_msg[0] = data; 322 sc->in_pos = 1; 323 goto deliver; 324 } else { 325 sc->in_state = MIDI_IN_DATA; 326 sc->in_msg[0] = sc->in_status = data; 327 sc->in_pos = 1; 328 sc->in_left = MIDI_LENGTH(data); 329 } 330 break; 331 } 332 } else { 333 if (MIDI_IS_STATUS(sc->in_status)) { 334 sc->in_state = MIDI_IN_DATA; 335 sc->in_msg[0] = sc->in_status; 336 sc->in_msg[1] = data; 337 sc->in_pos = 2; 338 sc->in_left = MIDI_LENGTH(sc->in_status) - 1; 339 } 340 } 341 return; 342 case MIDI_IN_DATA: 343 sc->in_msg[sc->in_pos++] = data; 344 if (--sc->in_left <= 0) 345 break; /* deliver data */ 346 return; 347 case MIDI_IN_SYSEX: 348 if (data == MIDI_SYSEX_END) 349 sc->in_state = MIDI_IN_START; 350 return; 351 } 352 deliver: 353 sc->in_state = MIDI_IN_START; 354 #if NSEQUENCER > 0 355 if (sc->seqopen) { 356 extern void midiseq_in __P((struct midi_dev *,u_char *,int)); 357 midiseq_in(sc->seq_md, sc->in_msg, sc->in_pos); 358 return; 359 } 360 #endif 361 362 if (mb->used + sc->in_pos > mb->usedhigh) { 363 DPRINTF(("midi_in: buffer full, discard data=0x%02x\n", 364 sc->in_msg[0])); 365 return; 366 } 367 for (i = 0; i < sc->in_pos; i++) { 368 *mb->inp++ = sc->in_msg[i]; 369 if (mb->inp >= mb->end) 370 mb->inp = mb->start; 371 mb->used++; 372 } 373 midi_wakeup(&sc->rchan); 374 selwakeup(&sc->rsel); 375 if (sc->async) 376 psignal(sc->async, SIGIO); 377 } 378 379 void 380 midi_out(addr) 381 void *addr; 382 { 383 struct midi_softc *sc = addr; 384 385 if (!sc->isopen) 386 return; 387 DPRINTFN(3, ("midi_out: %p\n", sc)); 388 midi_start_output(sc, 1); 389 } 390 391 int 392 midiopen(dev, flags, ifmt, p) 393 dev_t dev; 394 int flags, ifmt; 395 struct proc *p; 396 { 397 struct midi_softc *sc; 398 struct midi_hw_if *hw; 399 int error; 400 401 sc = device_lookup(&midi_cd, MIDIUNIT(dev)); 402 if (sc == NULL) 403 return (ENXIO); 404 if (sc->dying) 405 return (EIO); 406 407 DPRINTF(("midiopen %p\n", sc)); 408 409 hw = sc->hw_if; 410 if (!hw) 411 return ENXIO; 412 if (sc->isopen) 413 return EBUSY; 414 sc->in_state = MIDI_IN_START; 415 sc->in_status = 0; 416 error = hw->open(sc->hw_hdl, flags, midi_in, midi_out, sc); 417 if (error) 418 return error; 419 sc->isopen++; 420 midi_initbuf(&sc->outbuf); 421 midi_initbuf(&sc->inbuf); 422 sc->flags = flags; 423 sc->rchan = 0; 424 sc->wchan = 0; 425 sc->pbus = 0; 426 sc->async = 0; 427 428 #ifdef MIDI_SAVE 429 if (midicnt != 0) { 430 midisave.cnt = midicnt; 431 midicnt = 0; 432 } 433 #endif 434 435 return 0; 436 } 437 438 int 439 midiclose(dev, flags, ifmt, p) 440 dev_t dev; 441 int flags, ifmt; 442 struct proc *p; 443 { 444 int unit = MIDIUNIT(dev); 445 struct midi_softc *sc = midi_cd.cd_devs[unit]; 446 struct midi_hw_if *hw = sc->hw_if; 447 int s, error; 448 449 DPRINTF(("midiclose %p\n", sc)); 450 451 midi_start_output(sc, 0); 452 error = 0; 453 s = splaudio(); 454 while (sc->outbuf.used > 0 && !error) { 455 DPRINTFN(2,("midiclose sleep used=%d\n", sc->outbuf.used)); 456 error = midi_sleep_timo(&sc->wchan, "mid_dr", 30*hz); 457 } 458 splx(s); 459 sc->isopen = 0; 460 hw->close(sc->hw_hdl); 461 #if NSEQUENCER > 0 462 sc->seqopen = 0; 463 sc->seq_md = 0; 464 #endif 465 return 0; 466 } 467 468 int 469 midiread(dev, uio, ioflag) 470 dev_t dev; 471 struct uio *uio; 472 int ioflag; 473 { 474 int unit = MIDIUNIT(dev); 475 struct midi_softc *sc = midi_cd.cd_devs[unit]; 476 struct midi_buffer *mb = &sc->inbuf; 477 int error; 478 u_char *outp; 479 int used, cc, n, resid; 480 int s; 481 482 DPRINTF(("midiread: %p, count=%lu\n", sc, 483 (unsigned long)uio->uio_resid)); 484 485 if (sc->dying) 486 return EIO; 487 488 error = 0; 489 resid = uio->uio_resid; 490 while (uio->uio_resid == resid && !error) { 491 s = splaudio(); 492 while (mb->used <= 0) { 493 if (ioflag & IO_NDELAY) { 494 splx(s); 495 return EWOULDBLOCK; 496 } 497 error = midi_sleep(&sc->rchan, "mid rd"); 498 if (error) { 499 splx(s); 500 return error; 501 } 502 } 503 used = mb->used; 504 outp = mb->outp; 505 splx(s); 506 if (sc->dying) 507 return EIO; 508 cc = used; /* maximum to read */ 509 n = mb->end - outp; 510 if (n < cc) 511 cc = n; /* don't read beyond end of buffer */ 512 if (uio->uio_resid < cc) 513 cc = uio->uio_resid; /* and no more than we want */ 514 DPRINTFN(3, ("midiread: uiomove cc=%d\n", cc)); 515 error = uiomove(outp, cc, uio); 516 if (error) 517 break; 518 used -= cc; 519 outp += cc; 520 if (outp >= mb->end) 521 outp = mb->start; 522 s = splaudio(); 523 mb->outp = outp; 524 mb->used = used; 525 splx(s); 526 } 527 return error; 528 } 529 530 void 531 midi_timeout(arg) 532 void *arg; 533 { 534 struct midi_softc *sc = arg; 535 536 DPRINTFN(3,("midi_timeout: %p\n", sc)); 537 midi_start_output(sc, 1); 538 } 539 540 int 541 midi_start_output(sc, intr) 542 struct midi_softc *sc; 543 int intr; 544 { 545 struct midi_buffer *mb = &sc->outbuf; 546 u_char out; 547 int error; 548 int s; 549 int i; 550 551 error = 0; 552 553 if (sc->dying) 554 return EIO; 555 556 if (sc->pbus && !intr) { 557 DPRINTFN(4, ("midi_start_output: busy\n")); 558 return 0; 559 } 560 sc->pbus = (mb->used > 0)?1:0; 561 for (i = 0; i < MIDI_MAX_WRITE && mb->used > 0 && 562 (!error || error==EINPROGRESS); i++) { 563 s = splaudio(); 564 out = *mb->outp; 565 mb->outp++; 566 if (mb->outp >= mb->end) 567 mb->outp = mb->start; 568 mb->used--; 569 splx(s); 570 #ifdef MIDI_SAVE 571 midisave.buf[midicnt] = out; 572 midicnt = (midicnt + 1) % MIDI_SAVE_SIZE; 573 #endif 574 DPRINTFN(4, ("midi_start_output: %p i=%d, data=0x%02x\n", 575 sc, i, out)); 576 error = sc->hw_if->output(sc->hw_hdl, out); 577 if ((sc->props & MIDI_PROP_OUT_INTR) && error!=EINPROGRESS) 578 /* If ointr is enabled, midi_start_output() 579 * normally writes only one byte, 580 * except hw_if->output() returns EINPROGRESS. 581 */ 582 break; 583 } 584 midi_wakeup(&sc->wchan); 585 selwakeup(&sc->wsel); 586 if (sc->async) 587 psignal(sc->async, SIGIO); 588 if (!(sc->props & MIDI_PROP_OUT_INTR) || error==EINPROGRESS) { 589 if (mb->used > 0) 590 callout_reset(&sc->sc_callout, midi_wait, 591 midi_timeout, sc); 592 else 593 sc->pbus = 0; 594 } 595 if ((sc->props & MIDI_PROP_OUT_INTR) && error==EINPROGRESS) 596 error = 0; 597 598 return error; 599 } 600 601 int 602 midiwrite(dev, uio, ioflag) 603 dev_t dev; 604 struct uio *uio; 605 int ioflag; 606 { 607 int unit = MIDIUNIT(dev); 608 struct midi_softc *sc = midi_cd.cd_devs[unit]; 609 struct midi_buffer *mb = &sc->outbuf; 610 int error; 611 u_char *inp; 612 int used, cc, n; 613 int s; 614 615 DPRINTFN(2, ("midiwrite: %p, unit=%d, count=%lu\n", sc, unit, 616 (unsigned long)uio->uio_resid)); 617 618 if (sc->dying) 619 return EIO; 620 621 error = 0; 622 while (uio->uio_resid > 0 && !error) { 623 s = splaudio(); 624 if (mb->used >= mb->usedhigh) { 625 DPRINTFN(3,("midi_write: sleep used=%d hiwat=%d\n", 626 mb->used, mb->usedhigh)); 627 if (ioflag & IO_NDELAY) { 628 splx(s); 629 return EWOULDBLOCK; 630 } 631 error = midi_sleep(&sc->wchan, "mid wr"); 632 if (error) { 633 splx(s); 634 return error; 635 } 636 } 637 used = mb->used; 638 inp = mb->inp; 639 splx(s); 640 if (sc->dying) 641 return EIO; 642 cc = mb->usedhigh - used; /* maximum to write */ 643 n = mb->end - inp; 644 if (n < cc) 645 cc = n; /* don't write beyond end of buffer */ 646 if (uio->uio_resid < cc) 647 cc = uio->uio_resid; /* and no more than we have */ 648 error = uiomove(inp, cc, uio); 649 #ifdef MIDI_DEBUG 650 if (error) 651 printf("midi_write:(1) uiomove failed %d; " 652 "cc=%d inp=%p\n", 653 error, cc, inp); 654 #endif 655 if (error) 656 break; 657 inp = mb->inp + cc; 658 if (inp >= mb->end) 659 inp = mb->start; 660 s = splaudio(); 661 mb->inp = inp; 662 mb->used += cc; 663 splx(s); 664 error = midi_start_output(sc, 0); 665 } 666 return error; 667 } 668 669 /* 670 * This write routine is only called from sequencer code and expects 671 * a write that is smaller than the MIDI buffer. 672 */ 673 int 674 midi_writebytes(unit, buf, cc) 675 int unit; 676 u_char *buf; 677 int cc; 678 { 679 struct midi_softc *sc = midi_cd.cd_devs[unit]; 680 struct midi_buffer *mb = &sc->outbuf; 681 int n, s; 682 683 DPRINTFN(2, ("midi_writebytes: %p, unit=%d, cc=%d\n", sc, unit, cc)); 684 DPRINTFN(3, ("midi_writebytes: %x %x %x\n",buf[0],buf[1],buf[2])); 685 686 if (sc->dying) 687 return EIO; 688 689 s = splaudio(); 690 if (mb->used + cc >= mb->usedhigh) { 691 splx(s); 692 return (EWOULDBLOCK); 693 } 694 n = mb->end - mb->inp; 695 if (cc < n) 696 n = cc; 697 mb->used += cc; 698 memcpy(mb->inp, buf, n); 699 mb->inp += n; 700 if (mb->inp >= mb->end) { 701 mb->inp = mb->start; 702 cc -= n; 703 if (cc > 0) { 704 memcpy(mb->inp, buf + n, cc); 705 mb->inp += cc; 706 } 707 } 708 splx(s); 709 return (midi_start_output(sc, 0)); 710 } 711 712 int 713 midiioctl(dev, cmd, addr, flag, p) 714 dev_t dev; 715 u_long cmd; 716 caddr_t addr; 717 int flag; 718 struct proc *p; 719 { 720 int unit = MIDIUNIT(dev); 721 struct midi_softc *sc = midi_cd.cd_devs[unit]; 722 struct midi_hw_if *hw = sc->hw_if; 723 int error; 724 725 DPRINTF(("midiioctl: %p cmd=0x%08lx\n", sc, cmd)); 726 727 if (sc->dying) 728 return EIO; 729 730 error = 0; 731 switch (cmd) { 732 case FIONBIO: 733 /* All handled in the upper FS layer. */ 734 break; 735 736 case FIOASYNC: 737 if (*(int *)addr) { 738 if (sc->async) 739 return EBUSY; 740 sc->async = p; 741 DPRINTF(("midi_ioctl: FIOASYNC %p\n", p)); 742 } else 743 sc->async = 0; 744 break; 745 746 #if 0 747 case MIDI_PRETIME: 748 /* XXX OSS 749 * This should set up a read timeout, but that's 750 * why we have poll(), so there's nothing yet. */ 751 error = EINVAL; 752 break; 753 #endif 754 755 #ifdef MIDI_SAVE 756 case MIDI_GETSAVE: 757 error = copyout(&midisave, *(void **)addr, sizeof midisave); 758 break; 759 #endif 760 761 default: 762 if (hw->ioctl) 763 error = hw->ioctl(sc->hw_hdl, cmd, addr, flag, p); 764 else 765 error = EINVAL; 766 break; 767 } 768 return error; 769 } 770 771 int 772 midipoll(dev, events, p) 773 dev_t dev; 774 int events; 775 struct proc *p; 776 { 777 int unit = MIDIUNIT(dev); 778 struct midi_softc *sc = midi_cd.cd_devs[unit]; 779 int revents = 0; 780 int s = splaudio(); 781 782 DPRINTF(("midipoll: %p events=0x%x\n", sc, events)); 783 784 if (sc->dying) 785 return EIO; 786 787 if (events & (POLLIN | POLLRDNORM)) 788 if (sc->inbuf.used > 0) 789 revents |= events & (POLLIN | POLLRDNORM); 790 791 if (events & (POLLOUT | POLLWRNORM)) 792 if (sc->outbuf.used < sc->outbuf.usedhigh) 793 revents |= events & (POLLOUT | POLLWRNORM); 794 795 if (revents == 0) { 796 if (events & (POLLIN | POLLRDNORM)) 797 selrecord(p, &sc->rsel); 798 799 if (events & (POLLOUT | POLLWRNORM)) 800 selrecord(p, &sc->wsel); 801 } 802 803 splx(s); 804 return revents; 805 } 806 807 void 808 midi_getinfo(dev, mi) 809 dev_t dev; 810 struct midi_info *mi; 811 { 812 struct midi_softc *sc; 813 814 sc = device_lookup(&midi_cd, MIDIUNIT(dev)); 815 if (sc == NULL) 816 return; 817 if (sc->dying) 818 return; 819 820 sc->hw_if->getinfo(sc->hw_hdl, mi); 821 } 822 823 #endif /* NMIDI > 0 */ 824 825 #if NMIDI > 0 || NMIDIBUS > 0 826 827 int audioprint __P((void *, const char *)); 828 829 struct device * 830 midi_attach_mi(mhwp, hdlp, dev) 831 struct midi_hw_if *mhwp; 832 void *hdlp; 833 struct device *dev; 834 { 835 struct audio_attach_args arg; 836 837 #ifdef DIAGNOSTIC 838 if (mhwp == NULL) { 839 printf("midi_attach_mi: NULL\n"); 840 return (0); 841 } 842 #endif 843 arg.type = AUDIODEV_TYPE_MIDI; 844 arg.hwif = mhwp; 845 arg.hdl = hdlp; 846 return (config_found(dev, &arg, audioprint)); 847 } 848 849 #endif /* NMIDI > 0 || NMIDIBUS > 0 */ 850