1 /* $OpenBSD: midi.c,v 1.16 2006/12/21 02:28:47 krw Exp $ */ 2 3 /* 4 * Copyright (c) 2003, 2004 Alexandre Ratchov 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * TODO 21 * - put the sequencer stuff in sequencer.c and sequencervar.h 22 * there is no reason to have it here. The sequencer 23 * driver need only to open the midi hw_if thus it does not 24 * need this driver 25 */ 26 27 #include "midi.h" 28 #include "sequencer.h" 29 #if NMIDI > 0 30 31 #include <sys/param.h> 32 #include <sys/fcntl.h> 33 #include <sys/systm.h> 34 #include <sys/ioctl.h> 35 #include <sys/exec.h> 36 #include <sys/conf.h> 37 #include <sys/lkm.h> 38 #include <sys/proc.h> 39 #include <sys/poll.h> 40 #include <sys/kernel.h> 41 #include <sys/timeout.h> 42 #include <sys/vnode.h> 43 #include <sys/signalvar.h> 44 #include <sys/malloc.h> 45 #include <sys/device.h> 46 47 #include <dev/midi_if.h> 48 #include <dev/audio_if.h> 49 #include <dev/midivar.h> 50 51 52 int midiopen(dev_t, int, int, struct proc *); 53 int midiclose(dev_t, int, int, struct proc *); 54 int midiread(dev_t, struct uio *, int); 55 int midiwrite(dev_t, struct uio *, int); 56 int midipoll(dev_t, int, struct proc *); 57 int midiioctl(dev_t, u_long, caddr_t, int, struct proc *); 58 int midiprobe(struct device *, void *, void *); 59 void midiattach(struct device *, struct device *, void *); 60 int mididetach(struct device *, int); 61 int midiprint(void *, const char *); 62 63 void midi_iintr(void *, int); 64 void midi_ointr(void *); 65 void midi_out_start(struct midi_softc *); 66 void midi_out_stop(struct midi_softc *); 67 void midi_out_do(struct midi_softc *); 68 void midi_attach(struct midi_softc *, struct device *); 69 70 71 #if NSEQUENCER > 0 72 int midi_unit_count(void); 73 struct midi_hw_if *midi_get_hwif(int); 74 void midi_toevent(struct midi_softc *, int); 75 int midi_writebytes(int, u_char *, int); 76 void midiseq_in(struct midi_dev *, u_char *, int); 77 #endif 78 79 struct cfattach midi_ca = { 80 sizeof(struct midi_softc), midiprobe, midiattach, mididetach 81 }; 82 83 struct cfdriver midi_cd = { 84 NULL, "midi", DV_DULL 85 }; 86 87 88 void 89 midi_iintr(void *addr, int data) 90 { 91 struct midi_softc *sc = (struct midi_softc *)addr; 92 struct midi_buffer *mb = &sc->inbuf; 93 94 if (sc->isdying || !sc->isopen || !(sc->flags & FREAD)) return; 95 96 #if NSEQUENCER > 0 97 if (sc->seqopen) { 98 midi_toevent(sc, data); 99 return; 100 } 101 #endif 102 if (MIDIBUF_ISFULL(mb)) 103 return; /* discard data */ 104 if (MIDIBUF_ISEMPTY(mb)) { 105 if (sc->rchan) { 106 sc->rchan = 0; 107 wakeup(&sc->rchan); 108 } 109 selwakeup(&sc->rsel); 110 if (sc->async) 111 psignal(sc->async, SIGIO); 112 } 113 MIDIBUF_WRITE(mb, data); 114 } 115 116 117 int 118 midiread(dev_t dev, struct uio *uio, int ioflag) 119 { 120 struct midi_softc *sc = MIDI_DEV2SC(dev); 121 struct midi_buffer *mb = &sc->inbuf; 122 unsigned count; 123 int s, error; 124 125 if (!(sc->flags & FREAD)) 126 return ENXIO; 127 128 /* if there is no data then sleep (unless IO_NDELAY flag is set) */ 129 130 s = splaudio(); 131 while(MIDIBUF_ISEMPTY(mb)) { 132 if (sc->isdying) { 133 splx(s); 134 return EIO; 135 } 136 if (ioflag & IO_NDELAY) { 137 splx(s); 138 return EWOULDBLOCK; 139 } 140 sc->rchan = 1; 141 error = tsleep(&sc->rchan, PWAIT|PCATCH, "mid_rd", 0); 142 if (error) { 143 splx(s); 144 return error; 145 } 146 } 147 148 /* at this stage, there is at least 1 byte */ 149 150 while (uio->uio_resid > 0 && mb->used > 0) { 151 count = MIDIBUF_SIZE - mb->start; 152 if (count > mb->used) 153 count = mb->used; 154 if (count > uio->uio_resid) 155 count = uio->uio_resid; 156 error = uiomove(mb->data + mb->start, count, uio); 157 if (error) { 158 splx(s); 159 return error; 160 } 161 MIDIBUF_REMOVE(mb, count); 162 } 163 splx(s); 164 return 0; 165 } 166 167 168 void 169 midi_ointr(void *addr) 170 { 171 struct midi_softc *sc = (struct midi_softc *)addr; 172 struct midi_buffer *mb; 173 int s; 174 175 if (sc->isopen && !sc->isdying) { 176 #ifdef MIDI_DEBUG 177 if (!sc->isbusy) { 178 printf("midi_ointr: output should be busy\n"); 179 } 180 #endif 181 mb = &sc->outbuf; 182 s = splaudio(); 183 if (mb->used == 0) 184 midi_out_stop(sc); 185 else 186 midi_out_do(sc); /* restart output */ 187 splx(s); 188 } 189 } 190 191 192 void 193 midi_out_start(struct midi_softc *sc) 194 { 195 if (!sc->isbusy) { 196 sc->isbusy = 1; 197 midi_out_do(sc); 198 } 199 } 200 201 void 202 midi_out_stop(struct midi_softc *sc) 203 { 204 sc->isbusy = 0; 205 if (sc->wchan) { 206 sc->wchan = 0; 207 wakeup(&sc->wchan); 208 } 209 selwakeup(&sc->wsel); 210 if (sc->async) 211 psignal(sc->async, SIGIO); 212 } 213 214 215 /* 216 * drain output buffer, must be called with 217 * interrupts disabled 218 */ 219 void 220 midi_out_do(struct midi_softc *sc) 221 { 222 struct midi_buffer *mb = &sc->outbuf; 223 unsigned i, max; 224 int error; 225 226 /* 227 * If output interrupts are not supported then we write MIDI_MAXWRITE 228 * bytes instead of 1, and then we wait sc->wait 229 */ 230 231 max = sc->props & MIDI_PROP_OUT_INTR ? 1 : MIDI_MAXWRITE; 232 for (i = max; i != 0;) { 233 if (mb->used == 0) 234 break; 235 error = sc->hw_if->output(sc->hw_hdl, mb->data[mb->start]); 236 /* 237 * 0 means that data is being sent, an interrupt will 238 * be generated when the interface becomes ready again 239 * 240 * EINPROGRESS means that data has been queued, but 241 * will not be sent immediately and thus will not 242 * generate interrupt, in this case we can send 243 * another byte. The flush() method can be called 244 * to force the transfer. 245 * 246 * EAGAIN means that data cannot be queued or sent; 247 * because the interface isn't ready. An interrupt 248 * will be generated once the interface is ready again 249 * 250 * any other (fatal) error code means that data couldn't 251 * be sent and was lost, interrupt will not be generated 252 */ 253 if (error == EINPROGRESS) { 254 MIDIBUF_REMOVE(mb, 1); 255 if (MIDIBUF_ISEMPTY(mb)) { 256 if (sc->hw_if->flush != NULL) 257 sc->hw_if->flush(sc->hw_hdl); 258 midi_out_stop(sc); 259 return; 260 } 261 } else if (error == 0) { 262 MIDIBUF_REMOVE(mb, 1); 263 i--; 264 } else if (error == EAGAIN) { 265 break; 266 } else { 267 MIDIBUF_INIT(mb); 268 midi_out_stop(sc); 269 return; 270 } 271 } 272 273 if (!(sc->props & MIDI_PROP_OUT_INTR)) { 274 if (MIDIBUF_ISEMPTY(mb)) 275 midi_out_stop(sc); 276 else 277 timeout_add(&sc->timeo, sc->wait); 278 } 279 } 280 281 282 int 283 midiwrite(dev_t dev, struct uio *uio, int ioflag) 284 { 285 struct midi_softc *sc = MIDI_DEV2SC(dev); 286 struct midi_buffer *mb = &sc->outbuf; 287 unsigned count; 288 int s, error; 289 290 if (!(sc->flags & FWRITE)) 291 return ENXIO; 292 if (sc->isdying) 293 return EIO; 294 295 /* 296 * If IO_NDELAY flag is set then check if there is enough room 297 * in the buffer to store at least one byte. If not then dont 298 * start the write process. 299 */ 300 301 if ((ioflag & IO_NDELAY) && MIDIBUF_ISFULL(mb) && 302 (uio->uio_resid > 0)) 303 return EWOULDBLOCK; 304 305 while (uio->uio_resid > 0) { 306 s = splaudio(); 307 while (MIDIBUF_ISFULL(mb)) { 308 if (ioflag & IO_NDELAY) { 309 /* 310 * At this stage at least one byte is already 311 * moved so we do not return EWOULDBLOCK 312 */ 313 splx(s); 314 return 0; 315 } 316 sc->wchan = 1; 317 error = tsleep(&sc->wchan, PWAIT|PCATCH, "mid_wr", 0); 318 if (error) { 319 splx(s); 320 return error; 321 } 322 if (sc->isdying) { 323 splx(s); 324 return EIO; 325 } 326 } 327 328 count = MIDIBUF_SIZE - MIDIBUF_END(mb); 329 if (count > MIDIBUF_AVAIL(mb)) 330 count = MIDIBUF_AVAIL(mb); 331 if (count > uio->uio_resid) 332 count = uio->uio_resid; 333 error = uiomove(mb->data + MIDIBUF_END(mb), count, uio); 334 if (error) { 335 splx(s); 336 return error; 337 } 338 mb->used += count; 339 midi_out_start(sc); 340 splx(s); 341 } 342 return 0; 343 } 344 345 346 int 347 midipoll(dev_t dev, int events, struct proc *p) 348 { 349 struct midi_softc *sc = MIDI_DEV2SC(dev); 350 int s, revents; 351 352 if (sc->isdying) 353 return POLLERR; 354 355 revents = 0; 356 s = splaudio(); 357 if (events & (POLLIN | POLLRDNORM)) { 358 if (!MIDIBUF_ISEMPTY(&sc->inbuf)) 359 revents |= events & (POLLIN | POLLRDNORM); 360 } 361 if (events & (POLLOUT | POLLWRNORM)) { 362 if (!MIDIBUF_ISFULL(&sc->outbuf)) 363 revents |= events & (POLLOUT | POLLWRNORM); 364 } 365 if (revents == 0) { 366 if (events & (POLLIN | POLLRDNORM)) 367 selrecord(p, &sc->rsel); 368 if (events & (POLLOUT | POLLWRNORM)) 369 selrecord(p, &sc->wsel); 370 } 371 splx(s); 372 return (revents); 373 } 374 375 376 int 377 midiioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 378 { 379 struct midi_softc *sc = MIDI_DEV2SC(dev); 380 381 if (sc->isdying) return EIO; 382 383 switch(cmd) { 384 case FIONBIO: 385 /* All handled in the upper FS layer */ 386 break; 387 case FIOASYNC: 388 if (*(int *)addr) { 389 if (sc->async) return EBUSY; 390 sc->async = p; 391 } else 392 sc->async = 0; 393 break; 394 default: 395 return ENOTTY; 396 break; 397 } 398 return 0; 399 } 400 401 402 int 403 midiopen(dev_t dev, int flags, int mode, struct proc *p) 404 { 405 struct midi_softc *sc; 406 int err; 407 408 if (MIDI_UNIT(dev) >= midi_cd.cd_ndevs) 409 return ENXIO; 410 sc = MIDI_DEV2SC(dev); 411 if (sc == NULL) /* there may be more units than devices */ 412 return ENXIO; 413 if (sc->isdying) 414 return EIO; 415 if (sc->isopen) 416 return EBUSY; 417 418 MIDIBUF_INIT(&sc->inbuf); 419 MIDIBUF_INIT(&sc->outbuf); 420 sc->isbusy = 0; 421 sc->rchan = sc->wchan = 0; 422 sc->async = 0; 423 sc->flags = flags; 424 425 err = sc->hw_if->open(sc->hw_hdl, flags, midi_iintr, midi_ointr, sc); 426 if (err) 427 return err; 428 sc->isopen = 1; 429 #if NSEQUENCER > 0 430 sc->seq_md = 0; 431 sc->seqopen = 0; 432 sc->evstatus = 0xff; 433 #endif 434 return 0; 435 } 436 437 438 int 439 midiclose(dev_t dev, int fflag, int devtype, struct proc *p) 440 { 441 struct midi_softc *sc = MIDI_DEV2SC(dev); 442 struct midi_buffer *mb; 443 int error; 444 int s; 445 446 mb = &sc->outbuf; 447 if (!sc->isdying) { 448 /* start draining output buffer */ 449 s = splaudio(); 450 if (!MIDIBUF_ISEMPTY(mb)) 451 midi_out_start(sc); 452 while (sc->isbusy) { 453 sc->wchan = 1; 454 error = tsleep(&sc->wchan, PWAIT|PCATCH, "mid_dr", 0); 455 if (error || sc->isdying) 456 break; 457 } 458 splx(s); 459 } 460 461 /* 462 * some hw_if->close() reset immediately the midi uart 463 * which flushes the internal buffer of the uart device, 464 * so we may lose some (important) data. To avoid this, we sleep 2*wait, 465 * which gives the time to the uart to drain its internal buffers. 466 * 467 * Note: we'd better sleep in the corresponding hw_if->close() 468 */ 469 470 tsleep(&sc->wchan, PWAIT|PCATCH, "mid_cl", 2 * sc->wait); 471 sc->hw_if->close(sc->hw_hdl); 472 sc->isopen = 0; 473 return 0; 474 } 475 476 477 int 478 midiprobe(struct device *parent, void *match, void *aux) 479 { 480 struct audio_attach_args *sa = aux; 481 return (sa != NULL && (sa->type == AUDIODEV_TYPE_MIDI) ? 1 : 0); 482 } 483 484 485 void 486 midi_attach(struct midi_softc *sc, struct device *parent) 487 { 488 struct midi_info mi; 489 490 sc->isdying = 0; 491 sc->wait = (hz * MIDI_MAXWRITE) / MIDI_RATE; 492 if (sc->wait == 0) 493 sc->wait = 1; 494 sc->hw_if->getinfo(sc->hw_hdl, &mi); 495 sc->props = mi.props; 496 sc->isopen = 0; 497 timeout_set(&sc->timeo, midi_ointr, sc); 498 printf(": <%s>\n", mi.name); 499 } 500 501 502 void 503 midiattach(struct device *parent, struct device *self, void *aux) 504 { 505 struct midi_softc *sc = (struct midi_softc *)self; 506 struct audio_attach_args *sa = (struct audio_attach_args *)aux; 507 struct midi_hw_if *hwif = sa->hwif; 508 void *hdl = sa->hdl; 509 510 #ifdef DIAGNOSTIC 511 if (hwif == 0 || 512 hwif->open == 0 || 513 hwif->close == 0 || 514 hwif->output == 0 || 515 hwif->getinfo == 0) { 516 printf("midi: missing method\n"); 517 return; 518 } 519 #endif 520 sc->hw_if = hwif; 521 sc->hw_hdl = hdl; 522 midi_attach(sc, parent); 523 } 524 525 526 int 527 mididetach(struct device *self, int flags) 528 { 529 struct midi_softc *sc = (struct midi_softc *)self; 530 int maj, mn; 531 532 sc->isdying = 1; 533 if (sc->wchan) { 534 sc->wchan = 0; 535 wakeup(&sc->wchan); 536 } 537 if (sc->rchan) { 538 sc->rchan = 0; 539 wakeup(&sc->rchan); 540 } 541 542 /* locate the major number */ 543 for (maj = 0; maj < nchrdev; maj++) 544 if (cdevsw[maj].d_open == midiopen) 545 break; 546 547 /* Nuke the vnodes for any open instances (calls close). */ 548 mn = self->dv_unit; 549 vdevgone(maj, mn, mn, VCHR); 550 551 return 0; 552 } 553 554 555 int 556 midiprint(void *aux, const char *pnp) 557 { 558 if (pnp) 559 printf("midi at %s", pnp); 560 return (UNCONF); 561 } 562 563 564 void 565 midi_getinfo(dev_t dev, struct midi_info *mi) 566 { 567 struct midi_softc *sc = MIDI_DEV2SC(dev); 568 if (MIDI_UNIT(dev) >= midi_cd.cd_ndevs || sc == NULL || sc->isdying) { 569 mi->name = "unconfigured"; 570 mi->props = 0; 571 return; 572 } 573 sc->hw_if->getinfo(sc->hw_hdl, mi); 574 } 575 576 577 struct device * 578 midi_attach_mi(struct midi_hw_if *hwif, void *hdl, struct device *dev) 579 { 580 struct audio_attach_args arg; 581 582 arg.type = AUDIODEV_TYPE_MIDI; 583 arg.hwif = hwif; 584 arg.hdl = hdl; 585 return config_found(dev, &arg, midiprint); 586 } 587 588 589 int 590 midi_unit_count(void) 591 { 592 return midi_cd.cd_ndevs; 593 } 594 595 596 #if NSEQUENCER > 0 597 #define MIDI_EVLEN(status) (midi_evlen[((status) >> 4) & 7]) 598 unsigned midi_evlen[] = { 2, 2, 2, 2, 1, 1, 2 }; 599 600 void 601 midi_toevent(struct midi_softc *sc, int data) 602 { 603 unsigned char mesg[3]; 604 605 if (data >= 0xf8) { /* is it a realtime message ? */ 606 switch(data) { 607 case 0xf8: /* midi timer tic */ 608 case 0xfa: /* midi timer start */ 609 case 0xfb: /* midi timer continue (after stop) */ 610 case 0xfc: /* midi timer stop */ 611 mesg[0] = data; 612 midiseq_in(sc->seq_md, mesg, 1); 613 break; 614 default: 615 break; 616 } 617 } else if (data >= 0x80) { /* is it a common or voice message ? */ 618 sc->evstatus = data; 619 sc->evindex = 0; 620 } else { /* else it is a data byte */ 621 /* strip common messages and bogus data */ 622 if (sc->evstatus >= 0xf0 || sc->evstatus < 0x80) 623 return; 624 625 sc->evdata[sc->evindex++] = data; 626 if (sc->evindex == MIDI_EVLEN(sc->evstatus)) { 627 sc->evindex = 0; 628 mesg[0] = sc->evstatus; 629 mesg[1] = sc->evdata[0]; 630 mesg[2] = sc->evdata[1]; 631 midiseq_in(sc->seq_md, mesg, 1 + MIDI_EVLEN(sc->evstatus)); 632 } 633 } 634 } 635 636 637 int 638 midi_writebytes(int unit, unsigned char *mesg, int mesglen) 639 { 640 struct midi_softc *sc = midi_cd.cd_devs[unit]; 641 struct midi_buffer *mb = &sc->outbuf; 642 unsigned count; 643 int s; 644 645 s = splaudio(); 646 if (mesglen > MIDIBUF_AVAIL(mb)) { 647 splx(s); 648 return EWOULDBLOCK; 649 } 650 651 while (mesglen > 0) { 652 count = MIDIBUF_SIZE - MIDIBUF_END(mb); 653 if (count > MIDIBUF_AVAIL(mb)) count = MIDIBUF_AVAIL(mb); 654 if (count > mesglen) count = mesglen; 655 bcopy(mesg, mb->data + MIDIBUF_END(mb), count); 656 mb->used += count; 657 mesg += count; 658 mesglen -= count; 659 midi_out_start(sc); 660 } 661 splx(s); 662 return 0; 663 } 664 665 #endif /* NSEQUENCER > 0 */ 666 #endif /* NMIDI > 0 */ 667