1 /* $OpenBSD: midi.c,v 1.32 2014/10/09 04:04:46 tedu 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 #include <sys/param.h> 20 #include <sys/fcntl.h> 21 #include <sys/systm.h> 22 #include <sys/ioctl.h> 23 #include <sys/exec.h> 24 #include <sys/conf.h> 25 #include <sys/poll.h> 26 #include <sys/kernel.h> 27 #include <sys/timeout.h> 28 #include <sys/vnode.h> 29 #include <sys/signalvar.h> 30 #include <sys/malloc.h> 31 #include <sys/device.h> 32 33 #include <dev/midi_if.h> 34 #include <dev/audio_if.h> 35 #include <dev/midivar.h> 36 37 38 int midiopen(dev_t, int, int, struct proc *); 39 int midiclose(dev_t, int, int, struct proc *); 40 int midiread(dev_t, struct uio *, int); 41 int midiwrite(dev_t, struct uio *, int); 42 int midipoll(dev_t, int, struct proc *); 43 int midikqfilter(dev_t, struct knote *); 44 int midiioctl(dev_t, u_long, caddr_t, int, struct proc *); 45 int midiprobe(struct device *, void *, void *); 46 void midiattach(struct device *, struct device *, void *); 47 int mididetach(struct device *, int); 48 int midiprint(void *, const char *); 49 50 void midi_iintr(void *, int); 51 void midi_ointr(void *); 52 void midi_timeout(void *); 53 void midi_out_start(struct midi_softc *); 54 void midi_out_stop(struct midi_softc *); 55 void midi_out_do(struct midi_softc *); 56 void midi_attach(struct midi_softc *, struct device *); 57 58 59 struct cfattach midi_ca = { 60 sizeof(struct midi_softc), midiprobe, midiattach, mididetach 61 }; 62 63 struct cfdriver midi_cd = { 64 NULL, "midi", DV_DULL 65 }; 66 67 68 void filt_midiwdetach(struct knote *); 69 int filt_midiwrite(struct knote *, long); 70 71 struct filterops midiwrite_filtops = { 72 1, NULL, filt_midiwdetach, filt_midiwrite 73 }; 74 75 void filt_midirdetach(struct knote *); 76 int filt_midiread(struct knote *, long); 77 78 struct filterops midiread_filtops = { 79 1, NULL, filt_midirdetach, filt_midiread 80 }; 81 82 void 83 midi_iintr(void *addr, int data) 84 { 85 struct midi_softc *sc = (struct midi_softc *)addr; 86 struct midi_buffer *mb = &sc->inbuf; 87 88 if (sc->isdying || !sc->isopen || !(sc->flags & FREAD)) 89 return; 90 91 if (MIDIBUF_ISFULL(mb)) 92 return; /* discard data */ 93 94 MIDIBUF_WRITE(mb, data); 95 if (mb->used == 1) { 96 if (sc->rchan) { 97 sc->rchan = 0; 98 wakeup(&sc->rchan); 99 } 100 selwakeup(&sc->rsel); 101 if (sc->async) 102 psignal(sc->async, SIGIO); 103 } 104 } 105 106 int 107 midiread(dev_t dev, struct uio *uio, int ioflag) 108 { 109 struct midi_softc *sc = MIDI_DEV2SC(dev); 110 struct midi_buffer *mb = &sc->inbuf; 111 unsigned int count; 112 int error; 113 114 if (!(sc->flags & FREAD)) 115 return ENXIO; 116 117 /* if there is no data then sleep (unless IO_NDELAY flag is set) */ 118 119 mtx_enter(&audio_lock); 120 while (MIDIBUF_ISEMPTY(mb)) { 121 if (sc->isdying) { 122 mtx_leave(&audio_lock); 123 return EIO; 124 } 125 if (ioflag & IO_NDELAY) { 126 mtx_leave(&audio_lock); 127 return EWOULDBLOCK; 128 } 129 sc->rchan = 1; 130 error = msleep(&sc->rchan, &audio_lock, PWAIT | PCATCH, "mid_rd", 0); 131 if (error) { 132 mtx_leave(&audio_lock); 133 return error; 134 } 135 } 136 137 /* at this stage, there is at least 1 byte */ 138 139 while (uio->uio_resid > 0 && mb->used > 0) { 140 count = MIDIBUF_SIZE - mb->start; 141 if (count > mb->used) 142 count = mb->used; 143 if (count > uio->uio_resid) 144 count = uio->uio_resid; 145 error = uiomove(mb->data + mb->start, count, uio); 146 if (error) { 147 mtx_leave(&audio_lock); 148 return error; 149 } 150 MIDIBUF_REMOVE(mb, count); 151 } 152 mtx_leave(&audio_lock); 153 return 0; 154 } 155 156 void 157 midi_ointr(void *addr) 158 { 159 struct midi_softc *sc = (struct midi_softc *)addr; 160 struct midi_buffer *mb; 161 162 MUTEX_ASSERT_LOCKED(&audio_lock); 163 if (sc->isopen && !sc->isdying) { 164 mb = &sc->outbuf; 165 if (mb->used > 0) { 166 #ifdef MIDI_DEBUG 167 if (!sc->isbusy) { 168 printf("midi_ointr: output must be busy\n"); 169 } 170 #endif 171 midi_out_do(sc); 172 } else if (sc->isbusy) 173 midi_out_stop(sc); 174 } 175 } 176 177 void 178 midi_timeout(void *addr) 179 { 180 mtx_enter(&audio_lock); 181 midi_ointr(addr); 182 mtx_leave(&audio_lock); 183 } 184 185 void 186 midi_out_start(struct midi_softc *sc) 187 { 188 if (!sc->isbusy) { 189 sc->isbusy = 1; 190 midi_out_do(sc); 191 } 192 } 193 194 void 195 midi_out_stop(struct midi_softc *sc) 196 { 197 sc->isbusy = 0; 198 if (sc->wchan) { 199 sc->wchan = 0; 200 wakeup(&sc->wchan); 201 } 202 selwakeup(&sc->wsel); 203 if (sc->async) 204 psignal(sc->async, SIGIO); 205 } 206 207 void 208 midi_out_do(struct midi_softc *sc) 209 { 210 struct midi_buffer *mb = &sc->outbuf; 211 212 while (mb->used > 0) { 213 if (!sc->hw_if->output(sc->hw_hdl, mb->data[mb->start])) 214 break; 215 MIDIBUF_REMOVE(mb, 1); 216 if (MIDIBUF_ISEMPTY(mb)) { 217 if (sc->hw_if->flush != NULL) 218 sc->hw_if->flush(sc->hw_hdl); 219 midi_out_stop(sc); 220 return; 221 } 222 } 223 224 if (!(sc->props & MIDI_PROP_OUT_INTR)) { 225 if (MIDIBUF_ISEMPTY(mb)) 226 midi_out_stop(sc); 227 else 228 timeout_add(&sc->timeo, 1); 229 } 230 } 231 232 int 233 midiwrite(dev_t dev, struct uio *uio, int ioflag) 234 { 235 struct midi_softc *sc = MIDI_DEV2SC(dev); 236 struct midi_buffer *mb = &sc->outbuf; 237 unsigned int count; 238 int error; 239 240 if (!(sc->flags & FWRITE)) 241 return ENXIO; 242 if (sc->isdying) 243 return EIO; 244 245 /* 246 * If IO_NDELAY flag is set then check if there is enough room 247 * in the buffer to store at least one byte. If not then dont 248 * start the write process. 249 */ 250 251 if ((ioflag & IO_NDELAY) && MIDIBUF_ISFULL(mb) && (uio->uio_resid > 0)) 252 return EWOULDBLOCK; 253 254 while (uio->uio_resid > 0) { 255 mtx_enter(&audio_lock); 256 while (MIDIBUF_ISFULL(mb)) { 257 if (ioflag & IO_NDELAY) { 258 /* 259 * At this stage at least one byte is already 260 * moved so we do not return EWOULDBLOCK 261 */ 262 mtx_leave(&audio_lock); 263 return 0; 264 } 265 sc->wchan = 1; 266 error = msleep(&sc->wchan, &audio_lock, 267 PWAIT | PCATCH, "mid_wr", 0); 268 if (error) { 269 mtx_leave(&audio_lock); 270 return error; 271 } 272 if (sc->isdying) { 273 mtx_leave(&audio_lock); 274 return EIO; 275 } 276 } 277 278 count = MIDIBUF_SIZE - MIDIBUF_END(mb); 279 if (count > MIDIBUF_AVAIL(mb)) 280 count = MIDIBUF_AVAIL(mb); 281 if (count > uio->uio_resid) 282 count = uio->uio_resid; 283 error = uiomove(mb->data + MIDIBUF_END(mb), count, uio); 284 if (error) { 285 mtx_leave(&audio_lock); 286 return error; 287 } 288 mb->used += count; 289 midi_out_start(sc); 290 mtx_leave(&audio_lock); 291 } 292 return 0; 293 } 294 295 int 296 midipoll(dev_t dev, int events, struct proc *p) 297 { 298 struct midi_softc *sc = MIDI_DEV2SC(dev); 299 int revents; 300 301 if (sc->isdying) 302 return POLLERR; 303 304 revents = 0; 305 mtx_enter(&audio_lock); 306 if (events & (POLLIN | POLLRDNORM)) { 307 if (!MIDIBUF_ISEMPTY(&sc->inbuf)) 308 revents |= events & (POLLIN | POLLRDNORM); 309 } 310 if (events & (POLLOUT | POLLWRNORM)) { 311 if (!MIDIBUF_ISFULL(&sc->outbuf)) 312 revents |= events & (POLLOUT | POLLWRNORM); 313 } 314 if (revents == 0) { 315 if (events & (POLLIN | POLLRDNORM)) 316 selrecord(p, &sc->rsel); 317 if (events & (POLLOUT | POLLWRNORM)) 318 selrecord(p, &sc->wsel); 319 } 320 mtx_leave(&audio_lock); 321 return (revents); 322 } 323 324 int 325 midikqfilter(dev_t dev, struct knote *kn) 326 { 327 struct midi_softc *sc = MIDI_DEV2SC(dev); 328 struct klist *klist; 329 330 switch (kn->kn_filter) { 331 case EVFILT_READ: 332 klist = &sc->rsel.si_note; 333 kn->kn_fop = &midiread_filtops; 334 break; 335 case EVFILT_WRITE: 336 klist = &sc->wsel.si_note; 337 kn->kn_fop = &midiwrite_filtops; 338 break; 339 default: 340 return (EINVAL); 341 } 342 kn->kn_hook = (void *)sc; 343 344 mtx_enter(&audio_lock); 345 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 346 mtx_leave(&audio_lock); 347 348 return (0); 349 } 350 351 void 352 filt_midirdetach(struct knote *kn) 353 { 354 struct midi_softc *sc = (struct midi_softc *)kn->kn_hook; 355 356 mtx_enter(&audio_lock); 357 SLIST_REMOVE(&sc->rsel.si_note, kn, knote, kn_selnext); 358 mtx_leave(&audio_lock); 359 } 360 361 int 362 filt_midiread(struct knote *kn, long hint) 363 { 364 struct midi_softc *sc = (struct midi_softc *)kn->kn_hook; 365 int retval; 366 367 mtx_enter(&audio_lock); 368 retval = !MIDIBUF_ISEMPTY(&sc->inbuf); 369 mtx_leave(&audio_lock); 370 371 return (retval); 372 } 373 374 void 375 filt_midiwdetach(struct knote *kn) 376 { 377 struct midi_softc *sc = (struct midi_softc *)kn->kn_hook; 378 379 mtx_enter(&audio_lock); 380 SLIST_REMOVE(&sc->wsel.si_note, kn, knote, kn_selnext); 381 mtx_leave(&audio_lock); 382 } 383 384 int 385 filt_midiwrite(struct knote *kn, long hint) 386 { 387 struct midi_softc *sc = (struct midi_softc *)kn->kn_hook; 388 int retval; 389 390 mtx_enter(&audio_lock); 391 retval = !MIDIBUF_ISFULL(&sc->outbuf); 392 mtx_leave(&audio_lock); 393 394 return (retval); 395 } 396 397 int 398 midiioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 399 { 400 struct midi_softc *sc = MIDI_DEV2SC(dev); 401 402 if (sc->isdying) 403 return EIO; 404 405 switch(cmd) { 406 case FIONBIO: 407 /* All handled in the upper FS layer */ 408 break; 409 case FIOASYNC: 410 if (*(int *)addr) { 411 if (sc->async) 412 return EBUSY; 413 sc->async = p; 414 } else 415 sc->async = 0; 416 break; 417 default: 418 return ENOTTY; 419 } 420 return 0; 421 } 422 423 int 424 midiopen(dev_t dev, int flags, int mode, struct proc *p) 425 { 426 struct midi_softc *sc; 427 int err; 428 429 if (MIDI_UNIT(dev) >= midi_cd.cd_ndevs) 430 return ENXIO; 431 sc = MIDI_DEV2SC(dev); 432 if (sc == NULL) /* there may be more units than devices */ 433 return ENXIO; 434 if (sc->isdying) 435 return EIO; 436 if (sc->isopen) 437 return EBUSY; 438 439 MIDIBUF_INIT(&sc->inbuf); 440 MIDIBUF_INIT(&sc->outbuf); 441 sc->isbusy = 0; 442 sc->rchan = sc->wchan = 0; 443 sc->async = 0; 444 sc->flags = flags; 445 446 err = sc->hw_if->open(sc->hw_hdl, flags, midi_iintr, midi_ointr, sc); 447 if (err) 448 return err; 449 sc->isopen = 1; 450 return 0; 451 } 452 453 int 454 midiclose(dev_t dev, int fflag, int devtype, struct proc *p) 455 { 456 struct midi_softc *sc = MIDI_DEV2SC(dev); 457 struct midi_buffer *mb; 458 int error; 459 460 mb = &sc->outbuf; 461 if (!sc->isdying) { 462 /* start draining output buffer */ 463 mtx_enter(&audio_lock); 464 if (!MIDIBUF_ISEMPTY(mb)) 465 midi_out_start(sc); 466 while (sc->isbusy) { 467 sc->wchan = 1; 468 error = msleep(&sc->wchan, &audio_lock, 469 PWAIT, "mid_dr", 5 * hz); 470 if (error || sc->isdying) 471 break; 472 } 473 mtx_leave(&audio_lock); 474 } 475 476 /* 477 * some hw_if->close() reset immediately the midi uart 478 * which flushes the internal buffer of the uart device, 479 * so we may lose some (important) data. To avoid this, 480 * sleep 20ms (around 64 bytes) to give the time to the 481 * uart to drain its internal buffers. 482 */ 483 tsleep(&sc->wchan, PWAIT, "mid_cl", hz * MIDI_MAXWRITE / MIDI_RATE); 484 sc->hw_if->close(sc->hw_hdl); 485 sc->isopen = 0; 486 return 0; 487 } 488 489 int 490 midiprobe(struct device *parent, void *match, void *aux) 491 { 492 struct audio_attach_args *sa = aux; 493 494 return (sa != NULL && (sa->type == AUDIODEV_TYPE_MIDI) ? 1 : 0); 495 } 496 497 void 498 midi_attach(struct midi_softc *sc, struct device *parent) 499 { 500 struct midi_info mi; 501 502 sc->isdying = 0; 503 sc->hw_if->getinfo(sc->hw_hdl, &mi); 504 sc->props = mi.props; 505 sc->isopen = 0; 506 timeout_set(&sc->timeo, midi_timeout, sc); 507 printf(": <%s>\n", mi.name); 508 } 509 510 void 511 midiattach(struct device *parent, struct device *self, void *aux) 512 { 513 struct midi_softc *sc = (struct midi_softc *)self; 514 struct audio_attach_args *sa = (struct audio_attach_args *)aux; 515 struct midi_hw_if *hwif = sa->hwif; 516 void *hdl = sa->hdl; 517 518 #ifdef DIAGNOSTIC 519 if (hwif == 0 || 520 hwif->open == 0 || 521 hwif->close == 0 || 522 hwif->output == 0 || 523 hwif->getinfo == 0) { 524 printf("midi: missing method\n"); 525 return; 526 } 527 #endif 528 sc->hw_if = hwif; 529 sc->hw_hdl = hdl; 530 midi_attach(sc, parent); 531 } 532 533 int 534 mididetach(struct device *self, int flags) 535 { 536 struct midi_softc *sc = (struct midi_softc *)self; 537 int maj, mn; 538 539 sc->isdying = 1; 540 if (sc->wchan) { 541 sc->wchan = 0; 542 wakeup(&sc->wchan); 543 } 544 if (sc->rchan) { 545 sc->rchan = 0; 546 wakeup(&sc->rchan); 547 } 548 549 /* locate the major number */ 550 for (maj = 0; maj < nchrdev; maj++) { 551 if (cdevsw[maj].d_open == midiopen) { 552 /* Nuke the vnodes for any open instances (calls close). */ 553 mn = self->dv_unit; 554 vdevgone(maj, mn, mn, VCHR); 555 } 556 } 557 return 0; 558 } 559 560 int 561 midiprint(void *aux, const char *pnp) 562 { 563 if (pnp) 564 printf("midi at %s", pnp); 565 return (UNCONF); 566 } 567 568 void 569 midi_getinfo(dev_t dev, struct midi_info *mi) 570 { 571 struct midi_softc *sc = MIDI_DEV2SC(dev); 572 573 if (MIDI_UNIT(dev) >= midi_cd.cd_ndevs || sc == NULL || sc->isdying) { 574 mi->name = "unconfigured"; 575 mi->props = 0; 576 return; 577 } 578 sc->hw_if->getinfo(sc->hw_hdl, mi); 579 } 580 581 struct device * 582 midi_attach_mi(struct midi_hw_if *hwif, void *hdl, struct device *dev) 583 { 584 struct audio_attach_args arg; 585 586 arg.type = AUDIODEV_TYPE_MIDI; 587 arg.hwif = hwif; 588 arg.hdl = hdl; 589 return config_found(dev, &arg, midiprint); 590 } 591 592 593 int 594 midi_unit_count(void) 595 { 596 return midi_cd.cd_ndevs; 597 } 598 599