1 /* 2 * Main midi driver for FreeBSD. This file provides the main 3 * entry points for probe/attach and all i/o demultiplexing, including 4 * default routines for generic devices. 5 * 6 * (C) 1999 Seigo Tanimura 7 * 8 * Redistribution and use in source and binary forms, with or 9 * without modification, are permitted provided that the following 10 * conditions are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS 19 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 * AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 * 32 * For each card type a template "mididev_info" structure contains 33 * all the relevant parameters, both for configuration and runtime. 34 * 35 * In this file we build tables of pointers to the descriptors for 36 * the various supported cards. The generic probe routine scans 37 * the table(s) looking for a matching entry, then invokes the 38 * board-specific probe routine. If successful, a pointer to the 39 * correct mididev_info is stored in mididev_last_probed, for subsequent 40 * use in the attach routine. The generic attach routine copies 41 * the template to a permanent descriptor (midi_info and 42 * friends), initializes all generic parameters, and calls the 43 * board-specific attach routine. 44 * 45 * On device calls, the generic routines do the checks on unit and 46 * device parameters, then call the board-specific routines if 47 * available, or try to perform the task using the default code. 48 * 49 * $FreeBSD$ 50 * 51 */ 52 53 #include <dev/sound/midi/midi.h> 54 55 static devclass_t midi_devclass; 56 57 static d_open_t midiopen; 58 static d_close_t midiclose; 59 static d_ioctl_t midiioctl; 60 static d_read_t midiread; 61 static d_write_t midiwrite; 62 static d_poll_t midipoll; 63 64 /* These functions are local. */ 65 static d_open_t midistat_open; 66 static d_close_t midistat_close; 67 static d_read_t midistat_read; 68 static int midi_initstatus(char *buf, int size); 69 static int midi_readstatus(char *buf, int *ptr, struct uio *uio); 70 71 #define CDEV_MAJOR MIDI_CDEV_MAJOR 72 static struct cdevsw midi_cdevsw = { 73 .d_open = midiopen, 74 .d_close = midiclose, 75 .d_read = midiread, 76 .d_write = midiwrite, 77 .d_ioctl = midiioctl, 78 .d_poll = midipoll, 79 .d_name = "midi", 80 .d_maj = CDEV_MAJOR, 81 }; 82 83 /* 84 * descriptors for active devices. also used as the public softc 85 * of a device. 86 */ 87 static TAILQ_HEAD(,_mididev_info) midi_info; 88 static int nmidi, nsynth; 89 /* Mutex to protect midi_info, nmidi and nsynth. */ 90 static struct mtx midiinfo_mtx; 91 static int midiinfo_mtx_init; 92 93 /* These make the buffer for /dev/midistat */ 94 static int midistatbusy; 95 static char midistatbuf[4096]; 96 static int midistatptr; 97 98 SYSCTL_NODE(_hw, OID_AUTO, midi, CTLFLAG_RD, 0, "Midi driver"); 99 100 int midi_debug; 101 SYSCTL_INT(_hw_midi, OID_AUTO, debug, CTLFLAG_RW, &midi_debug, 0, ""); 102 103 midi_cmdtab cmdtab_midiioctl[] = { 104 {SNDCTL_MIDI_PRETIME, "SNDCTL_MIDI_PRETIME"}, 105 {SNDCTL_MIDI_MPUMODE, "SNDCTL_MIDI_MPUMODE"}, 106 {SNDCTL_MIDI_MPUCMD, "SNDCTL_MIDI_MPUCMD"}, 107 {SNDCTL_SYNTH_INFO, "SNDCTL_SYNTH_INFO"}, 108 {SNDCTL_MIDI_INFO, "SNDCTL_MIDI_INFO"}, 109 {SNDCTL_SYNTH_MEMAVL, "SNDCTL_SYNTH_MEMAVL"}, 110 {SNDCTL_FM_LOAD_INSTR, "SNDCTL_FM_LOAD_INSTR"}, 111 {SNDCTL_FM_4OP_ENABLE, "SNDCTL_FM_4OP_ENABLE"}, 112 {MIOSPASSTHRU, "MIOSPASSTHRU"}, 113 {MIOGPASSTHRU, "MIOGPASSTHRU"}, 114 {AIONWRITE, "AIONWRITE"}, 115 {AIOGSIZE, "AIOGSIZE"}, 116 {AIOSSIZE, "AIOSSIZE"}, 117 {AIOGFMT, "AIOGFMT"}, 118 {AIOSFMT, "AIOSFMT"}, 119 {AIOGMIX, "AIOGMIX"}, 120 {AIOSMIX, "AIOSMIX"}, 121 {AIOSTOP, "AIOSTOP"}, 122 {AIOSYNC, "AIOSYNC"}, 123 {AIOGCAP, "AIOGCAP"}, 124 {-1, NULL}, 125 }; 126 127 /* 128 * This is the generic init routine. 129 * Must be called after device-specific init. 130 */ 131 int 132 midiinit(mididev_info *d, device_t dev) 133 { 134 int unit; 135 136 /* 137 * initialize standard parameters for the device. This can be 138 * overridden by device-specific configurations but better do 139 * here the generic things. 140 */ 141 142 MIDI_DEBUG(printf("midiinit: unit %d.\n", d->unit)); 143 144 unit = d->unit; 145 d->softc = device_get_softc(dev); 146 d->dev = dev; 147 d->magic = MAGIC(d->unit); /* debugging... */ 148 d->flags = 0; 149 d->fflags = 0; 150 d->midi_dbuf_in.unit_size = 1; 151 d->midi_dbuf_out.unit_size = 1; 152 d->midi_dbuf_passthru.unit_size = 1; 153 154 mtx_unlock(&d->flagqueue_mtx); 155 156 if (midi_devclass == NULL) { 157 midi_devclass = device_get_devclass(dev); 158 make_dev(&midi_cdevsw, MIDIMKMINOR(0, MIDI_DEV_STATUS), 159 UID_ROOT, GID_WHEEL, 0444, "midistat"); 160 } 161 make_dev(&midi_cdevsw, MIDIMKMINOR(unit, MIDI_DEV_MIDIN), 162 UID_ROOT, GID_WHEEL, 0666, "midi%d", unit); 163 164 return 0 ; 165 } 166 167 /* 168 * a small utility function which, given a device number, returns 169 * a pointer to the associated mididev_info struct, and sets the unit 170 * number. 171 */ 172 mididev_info * 173 get_mididev_info(dev_t i_dev, int *unit) 174 { 175 int u; 176 177 if (MIDIDEV(i_dev) != MIDI_DEV_MIDIN) 178 return NULL; 179 u = MIDIUNIT(i_dev); 180 if (unit) 181 *unit = u; 182 183 return get_mididev_info_unit(u); 184 } 185 186 /* 187 * a small utility function which, given a unit number, returns 188 * a pointer to the associated mididev_info struct. 189 */ 190 mididev_info * 191 get_mididev_info_unit(int unit) 192 { 193 mididev_info *md; 194 195 /* XXX */ 196 if (!midiinfo_mtx_init) { 197 midiinfo_mtx_init = 1; 198 mtx_init(&midiinfo_mtx, "midinf", NULL, MTX_DEF); 199 TAILQ_INIT(&midi_info); 200 } 201 202 mtx_lock(&midiinfo_mtx); 203 TAILQ_FOREACH(md, &midi_info, md_link) { 204 if (md->unit == unit) 205 break; 206 } 207 mtx_unlock(&midiinfo_mtx); 208 209 return md; 210 } 211 212 /* 213 * a small utility function which, given a unit number, returns 214 * a pointer to the associated mididev_info struct with MDT_MIDI. 215 */ 216 mididev_info * 217 get_mididev_midi_unit(int unit) 218 { 219 mididev_info *md; 220 221 /* XXX */ 222 if (!midiinfo_mtx_init) { 223 midiinfo_mtx_init = 1; 224 mtx_init(&midiinfo_mtx, "midinf", NULL, MTX_DEF); 225 TAILQ_INIT(&midi_info); 226 } 227 228 mtx_lock(&midiinfo_mtx); 229 TAILQ_FOREACH(md, &midi_info, md_link) { 230 if (md->midiunit == unit) 231 break; 232 } 233 mtx_unlock(&midiinfo_mtx); 234 235 return md; 236 } 237 238 /* 239 * a small utility function which, given a unit number, returns 240 * a pointer to the associated mididev_info struct with MDT_SYNTH. 241 */ 242 mididev_info * 243 get_mididev_synth_unit(int unit) 244 { 245 mididev_info *md; 246 247 /* XXX */ 248 if (!midiinfo_mtx_init) { 249 midiinfo_mtx_init = 1; 250 mtx_init(&midiinfo_mtx, "midinf", NULL, MTX_DEF); 251 TAILQ_INIT(&midi_info); 252 } 253 254 mtx_lock(&midiinfo_mtx); 255 TAILQ_FOREACH(md, &midi_info, md_link) { 256 if (md->synthunit == unit) 257 break; 258 } 259 mtx_unlock(&midiinfo_mtx); 260 261 return md; 262 } 263 264 /* Create a new midi device info structure. */ 265 /* TODO: lock md, then exit. */ 266 mididev_info * 267 create_mididev_info_unit(int type, mididev_info *mdinf, synthdev_info *syninf) 268 { 269 int unit; 270 mididev_info *md, *mdnew; 271 272 /* XXX */ 273 if (!midiinfo_mtx_init) { 274 midiinfo_mtx_init = 1; 275 mtx_init(&midiinfo_mtx, "midinf", NULL, MTX_DEF); 276 TAILQ_INIT(&midi_info); 277 } 278 279 /* As malloc(9) might block, allocate mididev_info now. */ 280 mdnew = malloc(sizeof(mididev_info), M_DEVBUF, M_WAITOK | M_ZERO); 281 if (mdnew == NULL) 282 return NULL; 283 bcopy(mdinf, mdnew, sizeof(mididev_info)); 284 bcopy(syninf, &mdnew->synth, sizeof(synthdev_info)); 285 midibuf_init(&mdnew->midi_dbuf_in); 286 midibuf_init(&mdnew->midi_dbuf_out); 287 midibuf_init(&mdnew->midi_dbuf_passthru); 288 mtx_init(&mdnew->flagqueue_mtx, "midflq", NULL, MTX_DEF); 289 mtx_init(&mdnew->synth.vc_mtx, "synsvc", NULL, MTX_DEF); 290 mtx_init(&mdnew->synth.status_mtx, "synsst", NULL, MTX_DEF); 291 292 mtx_lock(&midiinfo_mtx); 293 294 switch (type) { 295 case MDT_MIDI: 296 mdnew->midiunit = nmidi; 297 mdnew->synthunit = nmidi; 298 nmidi++; 299 break; 300 case MDT_SYNTH: 301 mdnew->midiunit = -1; 302 mdnew->synthunit = nsynth; 303 nsynth++; 304 break; 305 default: 306 mtx_unlock(&midiinfo_mtx); 307 midibuf_destroy(&mdnew->midi_dbuf_in); 308 midibuf_destroy(&mdnew->midi_dbuf_out); 309 midibuf_destroy(&mdnew->midi_dbuf_passthru); 310 mtx_destroy(&mdnew->flagqueue_mtx); 311 mtx_destroy(&mdnew->synth.vc_mtx); 312 mtx_destroy(&mdnew->synth.status_mtx); 313 free(mdnew, M_DEVBUF); 314 panic("unsupported device type"); 315 return NULL; 316 } 317 mdnew->mdtype = type; 318 319 for (unit = 0 ; ; unit++) { 320 TAILQ_FOREACH(md, &midi_info, md_link) { 321 if (md->unit == unit) 322 break; 323 } 324 if (md == NULL) 325 break; 326 } 327 328 mdnew->unit = unit; 329 mtx_lock(&mdnew->flagqueue_mtx); 330 TAILQ_INSERT_TAIL(&midi_info, mdnew, md_link); 331 332 mtx_unlock(&midiinfo_mtx); 333 334 return mdnew; 335 } 336 337 /* Return the number of configured devices. */ 338 int 339 mididev_info_number(void) 340 { 341 return nmidi + nsynth; 342 } 343 344 /* Return the number of configured midi devices. */ 345 int 346 mididev_midi_number(void) 347 { 348 return nmidi; 349 } 350 351 /* Return the number of configured synth devices. */ 352 int 353 mididev_synth_number(void) 354 { 355 return nsynth; 356 } 357 358 /* 359 * here are the switches for the main functions. The switches do 360 * all necessary checks on the device number to make sure 361 * that the device is configured. They also provide some default 362 * functionalities so that device-specific drivers have to deal 363 * only with special cases. 364 */ 365 366 static int 367 midiopen(dev_t i_dev, int flags, int mode, struct thread *td) 368 { 369 int ret; 370 371 switch (MIDIDEV(i_dev)) { 372 case MIDI_DEV_MIDIN: 373 ret = midi_open(i_dev, flags, mode, td); 374 break; 375 case MIDI_DEV_STATUS: 376 ret = midistat_open(i_dev, flags, mode, td); 377 break; 378 default: 379 ret = ENXIO; 380 break; 381 } 382 383 return (ret); 384 } 385 386 static int 387 midiclose(dev_t i_dev, int flags, int mode, struct thread *td) 388 { 389 int ret; 390 391 switch (MIDIDEV(i_dev)) { 392 case MIDI_DEV_MIDIN: 393 ret = midi_close(i_dev, flags, mode, td); 394 break; 395 case MIDI_DEV_STATUS: 396 ret = midistat_close(i_dev, flags, mode, td); 397 break; 398 default: 399 ret = ENXIO; 400 break; 401 } 402 403 return (ret); 404 } 405 406 static int 407 midiread(dev_t i_dev, struct uio * buf, int flag) 408 { 409 int ret; 410 411 switch (MIDIDEV(i_dev)) { 412 case MIDI_DEV_MIDIN: 413 ret = midi_read(i_dev, buf, flag); 414 break; 415 case MIDI_DEV_STATUS: 416 ret = midistat_read(i_dev, buf, flag); 417 break; 418 default: 419 ret = ENXIO; 420 break; 421 } 422 423 return (ret); 424 } 425 426 static int 427 midiwrite(dev_t i_dev, struct uio * buf, int flag) 428 { 429 int ret; 430 431 switch (MIDIDEV(i_dev)) { 432 case MIDI_DEV_MIDIN: 433 ret = midi_write(i_dev, buf, flag); 434 break; 435 default: 436 ret = ENXIO; 437 break; 438 } 439 440 return (ret); 441 } 442 443 static int 444 midiioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td) 445 { 446 int ret; 447 448 switch (MIDIDEV(i_dev)) { 449 case MIDI_DEV_MIDIN: 450 ret = midi_ioctl(i_dev, cmd, arg, mode, td); 451 break; 452 default: 453 ret = ENXIO; 454 break; 455 } 456 457 return (ret); 458 } 459 460 static int 461 midipoll(dev_t i_dev, int events, struct thread *td) 462 { 463 int ret; 464 465 switch (MIDIDEV(i_dev)) { 466 case MIDI_DEV_MIDIN: 467 ret = midi_poll(i_dev, events, td); 468 break; 469 default: 470 ret = ENXIO; 471 break; 472 } 473 474 return (ret); 475 } 476 477 /* 478 * Followings are the generic methods in midi drivers. 479 */ 480 481 int 482 midi_open(dev_t i_dev, int flags, int mode, struct thread *td) 483 { 484 int dev, unit, ret; 485 mididev_info *d; 486 487 dev = minor(i_dev); 488 d = get_mididev_info(i_dev, &unit); 489 490 MIDI_DEBUG(printf("midi_open: unit %d, flags 0x%x.\n", unit, flags)); 491 492 if (d == NULL) 493 return (ENXIO); 494 495 /* Mark this device busy. */ 496 mtx_lock(&d->flagqueue_mtx); 497 device_busy(d->dev); 498 if ((d->flags & MIDI_F_BUSY) != 0) { 499 mtx_unlock(&d->flagqueue_mtx); 500 printf("midi_open: unit %d is busy.\n", unit); 501 return (EBUSY); 502 } 503 d->fflags = flags; 504 d->flags |= MIDI_F_BUSY; 505 d->flags &= ~(MIDI_F_READING | MIDI_F_WRITING); 506 if ((d->fflags & O_NONBLOCK) != 0) 507 d->flags |= MIDI_F_NBIO; 508 509 /* Init the queue. */ 510 if ((flags & FREAD) != 0) 511 midibuf_clear(&d->midi_dbuf_in); 512 if ((flags & FWRITE) != 0) { 513 midibuf_clear(&d->midi_dbuf_out); 514 midibuf_clear(&d->midi_dbuf_passthru); 515 } 516 517 mtx_unlock(&d->flagqueue_mtx); 518 519 if (d->open == NULL) 520 ret = 0; 521 else 522 ret = d->open(i_dev, flags, mode, td); 523 524 mtx_lock(&d->flagqueue_mtx); 525 526 /* Begin recording if nonblocking. */ 527 if ((d->flags & (MIDI_F_READING | MIDI_F_NBIO)) == MIDI_F_NBIO && (d->fflags & FREAD) != 0) 528 d->callback(d, MIDI_CB_START | MIDI_CB_RD); 529 530 mtx_unlock(&d->flagqueue_mtx); 531 532 MIDI_DEBUG(printf("midi_open: opened.\n")); 533 534 return (ret); 535 } 536 537 int 538 midi_close(dev_t i_dev, int flags, int mode, struct thread *td) 539 { 540 int dev, unit, ret; 541 mididev_info *d; 542 543 dev = minor(i_dev); 544 d = get_mididev_info(i_dev, &unit); 545 546 MIDI_DEBUG(printf("midi_close: unit %d.\n", unit)); 547 548 if (d == NULL) 549 return (ENXIO); 550 551 mtx_lock(&d->flagqueue_mtx); 552 553 /* Stop recording and playing. */ 554 if ((d->flags & MIDI_F_READING) != 0) 555 d->callback(d, MIDI_CB_ABORT | MIDI_CB_RD); 556 if ((d->flags & MIDI_F_WRITING) != 0) 557 d->callback(d, MIDI_CB_ABORT | MIDI_CB_WR); 558 559 /* Clear the queues. */ 560 if ((d->fflags & FREAD) != 0) 561 midibuf_clear(&d->midi_dbuf_in); 562 if ((d->fflags & FWRITE) != 0) { 563 midibuf_clear(&d->midi_dbuf_out); 564 midibuf_clear(&d->midi_dbuf_passthru); 565 } 566 567 /* Stop playing and unmark this device busy. */ 568 d->flags &= ~MIDI_F_BUSY; 569 d->fflags = 0; 570 571 device_unbusy(d->dev); 572 573 mtx_unlock(&d->flagqueue_mtx); 574 575 if (d->close == NULL) 576 ret = 0; 577 else 578 ret = d->close(i_dev, flags, mode, td); 579 580 MIDI_DEBUG(printf("midi_close: closed.\n")); 581 582 return (ret); 583 } 584 585 int 586 midi_read(dev_t i_dev, struct uio * buf, int flag) 587 { 588 int dev, unit, len, lenr, ret; 589 mididev_info *d ; 590 u_char *uiobuf; 591 592 dev = minor(i_dev); 593 594 d = get_mididev_info(i_dev, &unit); 595 MIDI_DEBUG(printf("midi_read: unit %d, resid %d.\n", unit, buf->uio_resid)); 596 597 if (d == NULL) 598 return (ENXIO); 599 600 ret = 0; 601 602 len = buf->uio_resid; 603 lenr = 0; 604 605 uiobuf = (u_char *)malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); 606 if (uiobuf == NULL) 607 return (ENOMEM); 608 609 mtx_lock(&d->flagqueue_mtx); 610 611 /* Begin recording. */ 612 d->callback(d, MIDI_CB_START | MIDI_CB_RD); 613 614 /* Have we got the data to read? */ 615 if ((d->flags & MIDI_F_NBIO) != 0 && d->midi_dbuf_in.rl == 0) 616 ret = EAGAIN; 617 else { 618 if ((d->flags & MIDI_F_NBIO) != 0 && len > d->midi_dbuf_in.rl) 619 len = d->midi_dbuf_in.rl; 620 ret = midibuf_seqread(&d->midi_dbuf_in, uiobuf, len, &lenr, 621 d->callback, d, MIDI_CB_START | MIDI_CB_RD, 622 &d->flagqueue_mtx); 623 } 624 625 mtx_unlock(&d->flagqueue_mtx); 626 627 if (lenr > 0) 628 ret = uiomove(uiobuf, lenr, buf); 629 630 free(uiobuf, M_DEVBUF); 631 632 MIDI_DEBUG(printf("midi_read: ret %d, resid %d.\n", ret, buf->uio_resid)); 633 634 return (ret); 635 } 636 637 int 638 midi_write(dev_t i_dev, struct uio * buf, int flag) 639 { 640 int dev, unit, len, len2, lenw, ret; 641 mididev_info *d; 642 u_char *uiobuf; 643 644 dev = minor(i_dev); 645 d = get_mididev_info(i_dev, &unit); 646 647 MIDI_DEBUG(printf("midi_write: unit %d.\n", unit)); 648 649 if (d == NULL) 650 return (ENXIO); 651 652 ret = 0; 653 654 len = buf->uio_resid; 655 lenw = 0; 656 657 uiobuf = (u_char *)malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); 658 if (uiobuf == NULL) 659 return (ENOMEM); 660 661 ret = uiomove(uiobuf, len, buf); 662 if (ret != 0) { 663 free(uiobuf, M_DEVBUF); 664 return (ret); 665 } 666 667 mtx_lock(&d->flagqueue_mtx); 668 669 /* Have we got the data to write? */ 670 if ((d->flags & MIDI_F_NBIO) != 0 && d->midi_dbuf_out.fl == 0) { 671 /* Begin playing. */ 672 d->callback(d, MIDI_CB_START | MIDI_CB_WR); 673 ret = EAGAIN; 674 } else { 675 len2 = len; 676 if ((d->flags & MIDI_F_NBIO) != 0 && len2 > d->midi_dbuf_out.fl) 677 len2 = d->midi_dbuf_out.fl; 678 ret = midibuf_seqwrite(&d->midi_dbuf_out, uiobuf, len2, &lenw, 679 d->callback, d, MIDI_CB_START | MIDI_CB_WR, 680 &d->flagqueue_mtx); 681 } 682 683 mtx_unlock(&d->flagqueue_mtx); 684 685 free(uiobuf, M_DEVBUF); 686 buf->uio_resid = len - lenw; 687 688 return (ret); 689 } 690 691 /* 692 * generic midi ioctl. Functions of the default driver can be 693 * overridden by the device-specific ioctl call. 694 * If a device-specific call returns ENOSYS (Function not implemented), 695 * the default driver is called. Otherwise, the returned value 696 * is passed up. 697 * 698 * The default handler, for many parameters, sets the value in the 699 * descriptor, sets MIDI_F_INIT, and calls the callback function with 700 * reason INIT. If successful, the callback returns 1 and the caller 701 * can update the parameter. 702 */ 703 704 int 705 midi_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td) 706 { 707 int ret = ENOSYS, dev, unit; 708 mididev_info *d; 709 struct snd_size *sndsize; 710 snd_sync_parm *sp; 711 712 dev = minor(i_dev); 713 d = get_mididev_info(i_dev, &unit); 714 715 if (d == NULL) 716 return (ENXIO); 717 718 if (d->ioctl) 719 ret = d->ioctl(i_dev, cmd, arg, mode, td); 720 if (ret != ENOSYS) 721 return ret; 722 723 /* 724 * pass control to the default ioctl handler. Set ret to 0 now. 725 */ 726 ret = 0; 727 728 MIDI_DEBUG(printf("midi_ioctl: unit %d, cmd %s.\n", unit, midi_cmdname(cmd, cmdtab_midiioctl))); 729 730 /* 731 * all routines are called with int. blocked. Make sure that 732 * ints are re-enabled when calling slow or blocking functions! 733 */ 734 switch(cmd) { 735 736 /* 737 * we start with the new ioctl interface. 738 */ 739 case AIONWRITE: /* how many bytes can write ? */ 740 mtx_lock(&d->flagqueue_mtx); 741 *(int *)arg = d->midi_dbuf_out.fl; 742 mtx_unlock(&d->flagqueue_mtx); 743 MIDI_DEBUG(printf("midi_ioctl: fl %d.\n", *(int *)arg)); 744 break; 745 746 case AIOSSIZE: /* set the current blocksize */ 747 sndsize = (struct snd_size *)arg; 748 MIDI_DEBUG(printf("midi_ioctl: play %d, rec %d.\n", sndsize->play_size, sndsize->rec_size)); 749 mtx_lock(&d->flagqueue_mtx); 750 if (sndsize->play_size <= d->midi_dbuf_out.unit_size && sndsize->rec_size <= d->midi_dbuf_in.unit_size) { 751 d->midi_dbuf_out.blocksize = d->midi_dbuf_out.unit_size; 752 d->midi_dbuf_in.blocksize = d->midi_dbuf_in.unit_size; 753 sndsize->play_size = d->midi_dbuf_out.blocksize; 754 sndsize->rec_size = d->midi_dbuf_in.blocksize; 755 d->flags &= ~MIDI_F_HAS_SIZE; 756 mtx_unlock(&d->flagqueue_mtx); 757 } 758 else { 759 if (sndsize->play_size > d->midi_dbuf_out.bufsize / 4) 760 sndsize->play_size = d->midi_dbuf_out.bufsize / 4; 761 if (sndsize->rec_size > d->midi_dbuf_in.bufsize / 4) 762 sndsize->rec_size = d->midi_dbuf_in.bufsize / 4; 763 /* Round up the size to the multiple of EV_SZ. */ 764 d->midi_dbuf_out.blocksize = 765 ((sndsize->play_size + d->midi_dbuf_out.unit_size - 1) 766 / d->midi_dbuf_out.unit_size) * d->midi_dbuf_out.unit_size; 767 d->midi_dbuf_in.blocksize = 768 ((sndsize->rec_size + d->midi_dbuf_in.unit_size - 1) 769 / d->midi_dbuf_in.unit_size) * d->midi_dbuf_in.unit_size; 770 sndsize->play_size = d->midi_dbuf_out.blocksize; 771 sndsize->rec_size = d->midi_dbuf_in.blocksize; 772 d->flags |= MIDI_F_HAS_SIZE; 773 mtx_unlock(&d->flagqueue_mtx); 774 } 775 776 ret = 0; 777 break; 778 779 case AIOGSIZE: /* get the current blocksize */ 780 sndsize = (struct snd_size *)arg; 781 mtx_lock(&d->flagqueue_mtx); 782 sndsize->play_size = d->midi_dbuf_out.blocksize; 783 sndsize->rec_size = d->midi_dbuf_in.blocksize; 784 mtx_unlock(&d->flagqueue_mtx); 785 MIDI_DEBUG(printf("midi_ioctl: play %d, rec %d.\n", sndsize->play_size, sndsize->rec_size)); 786 787 ret = 0; 788 break; 789 790 case AIOSTOP: 791 mtx_lock(&d->flagqueue_mtx); 792 if (*(int *)arg == AIOSYNC_PLAY) /* play */ 793 *(int *)arg = d->callback(d, MIDI_CB_STOP | MIDI_CB_WR); 794 else if (*(int *)arg == AIOSYNC_CAPTURE) 795 *(int *)arg = d->callback(d, MIDI_CB_STOP | MIDI_CB_RD); 796 else { 797 MIDI_DEBUG(printf("midi_ioctl: bad channel 0x%x.\n", *(int *)arg)); 798 *(int *)arg = 0 ; 799 } 800 mtx_unlock(&d->flagqueue_mtx); 801 break ; 802 803 case AIOSYNC: 804 sp = (snd_sync_parm *)arg; 805 MIDI_DEBUG(printf("midi_ioctl: unimplemented, chan 0x%03lx pos %lu.\n", 806 sp->chan, 807 sp->pos)); 808 break; 809 /* 810 * here follow the standard ioctls (filio.h etc.) 811 */ 812 case FIONREAD: /* get # bytes to read */ 813 mtx_lock(&d->flagqueue_mtx); 814 *(int *)arg = d->midi_dbuf_in.rl; 815 mtx_unlock(&d->flagqueue_mtx); 816 MIDI_DEBUG(printf("midi_ioctl: rl %d.\n", *(int *)arg)); 817 break; 818 819 case FIOASYNC: /*set/clear async i/o */ 820 MIDI_DEBUG(printf("FIOASYNC\n")); 821 break; 822 823 case FIONBIO: /* set/clear non-blocking i/o */ 824 mtx_lock(&d->flagqueue_mtx); 825 if (*(int *)arg == 0) 826 d->flags &= ~MIDI_F_NBIO ; 827 else 828 d->flags |= MIDI_F_NBIO ; 829 mtx_unlock(&d->flagqueue_mtx); 830 MIDI_DEBUG(printf("midi_ioctl: arg %d.\n", *(int *)arg)); 831 break ; 832 833 case MIOSPASSTHRU: /* set/clear passthru */ 834 mtx_lock(&d->flagqueue_mtx); 835 if (*(int *)arg == 0) 836 d->flags &= ~MIDI_F_PASSTHRU ; 837 else 838 d->flags |= MIDI_F_PASSTHRU ; 839 840 /* Init the queue. */ 841 midibuf_clear(&d->midi_dbuf_passthru); 842 843 mtx_unlock(&d->flagqueue_mtx); 844 MIDI_DEBUG(printf("midi_ioctl: passthru %d.\n", *(int *)arg)); 845 846 /* FALLTHROUGH */ 847 case MIOGPASSTHRU: /* get passthru */ 848 mtx_lock(&d->flagqueue_mtx); 849 if ((d->flags & MIDI_F_PASSTHRU) != 0) 850 *(int *)arg = 1; 851 else 852 *(int *)arg = 0; 853 mtx_unlock(&d->flagqueue_mtx); 854 MIDI_DEBUG(printf("midi_ioctl: passthru %d.\n", *(int *)arg)); 855 break; 856 857 default: 858 MIDI_DEBUG(printf("midi_ioctl: default ioctl midi%d subdev %d fn 0x%08lx fail\n", 859 unit, dev & 0xf, cmd)); 860 ret = EINVAL; 861 break ; 862 } 863 return ret ; 864 } 865 866 int 867 midi_poll(dev_t i_dev, int events, struct thread *td) 868 { 869 int unit, dev, ret, lim; 870 mididev_info *d; 871 872 dev = minor(i_dev); 873 d = get_mididev_info(i_dev, &unit); 874 875 MIDI_DEBUG(printf("midi_poll: unit %d.\n", unit)); 876 877 if (d == NULL) 878 return (ENXIO); 879 880 ret = 0; 881 882 mtx_lock(&d->flagqueue_mtx); 883 884 /* Look up the apropriate queue and select it. */ 885 if ((events & (POLLOUT | POLLWRNORM)) != 0) { 886 /* Start playing. */ 887 d->callback(d, MIDI_CB_START | MIDI_CB_WR); 888 889 /* Find out the boundary. */ 890 if ((d->flags & MIDI_F_HAS_SIZE) != 0) 891 lim = d->midi_dbuf_out.blocksize; 892 else 893 lim = d->midi_dbuf_out.unit_size; 894 if (d->midi_dbuf_out.fl < lim) 895 /* No enough space, record select. */ 896 selrecord(td, &d->midi_dbuf_out.sel); 897 else 898 /* We can write now. */ 899 ret |= events & (POLLOUT | POLLWRNORM); 900 } 901 if ((events & (POLLIN | POLLRDNORM)) != 0) { 902 /* Start recording. */ 903 d->callback(d, MIDI_CB_START | MIDI_CB_RD); 904 905 /* Find out the boundary. */ 906 if ((d->flags & MIDI_F_HAS_SIZE) != 0) 907 lim = d->midi_dbuf_in.blocksize; 908 else 909 lim = d->midi_dbuf_in.unit_size; 910 if (d->midi_dbuf_in.rl < lim) 911 /* No data ready, record select. */ 912 selrecord(td, &d->midi_dbuf_in.sel); 913 else 914 /* We can write now. */ 915 ret |= events & (POLLIN | POLLRDNORM); 916 } 917 918 mtx_unlock(&d->flagqueue_mtx); 919 920 return (ret); 921 } 922 923 void 924 midi_intr(mididev_info *d) 925 { 926 if (d->intr != NULL) 927 d->intr(d->intrarg, d); 928 } 929 930 /* Flush the output queue. */ 931 #define MIDI_SYNC_TIMEOUT 1 932 int 933 midi_sync(mididev_info *d) 934 { 935 int i, rl; 936 937 mtx_assert(&d->flagqueue_mtx, MA_OWNED); 938 939 MIDI_DEBUG(printf("midi_sync: unit %d.\n", d->unit)); 940 941 while (d->midi_dbuf_out.rl > 0) { 942 if ((d->flags & MIDI_F_WRITING) == 0) 943 d->callback(d, MIDI_CB_START | MIDI_CB_WR); 944 rl = d->midi_dbuf_out.rl; 945 i = cv_timedwait_sig(&d->midi_dbuf_out.cv_out, 946 &d->flagqueue_mtx, 947 (d->midi_dbuf_out.bufsize * 10 * hz / 38400) 948 + MIDI_SYNC_TIMEOUT * hz); 949 if (i == EINTR || i == ERESTART) { 950 if (i == EINTR) 951 d->callback(d, MIDI_CB_STOP | MIDI_CB_WR); 952 return (i); 953 } 954 if (i == EWOULDBLOCK && rl == d->midi_dbuf_out.rl) { 955 /* A queue seems to be stuck up. Give up and clear the queue. */ 956 d->callback(d, MIDI_CB_STOP | MIDI_CB_WR); 957 midibuf_clear(&d->midi_dbuf_out); 958 return (0); 959 } 960 } 961 962 return 0; 963 } 964 965 /* 966 * These handle the status message of the midi drivers. 967 */ 968 969 int 970 midistat_open(dev_t i_dev, int flags, int mode, struct thread *td) 971 { 972 if (midistatbusy) 973 return (EBUSY); 974 975 bzero(midistatbuf, sizeof(midistatbuf)); 976 midistatptr = 0; 977 if (midi_initstatus(midistatbuf, sizeof(midistatbuf) - 1)) 978 return (ENOMEM); 979 980 midistatbusy = 1; 981 982 return (0); 983 } 984 985 int 986 midistat_close(dev_t i_dev, int flags, int mode, struct thread *td) 987 { 988 midistatbusy = 0; 989 990 return (0); 991 } 992 993 int 994 midistat_read(dev_t i_dev, struct uio * buf, int flag) 995 { 996 return midi_readstatus(midistatbuf, &midistatptr, buf); 997 } 998 999 /* 1000 * finally, some "libraries" 1001 */ 1002 1003 /* Inits the buffer for /dev/midistat. */ 1004 static int 1005 midi_initstatus(char *buf, int size) 1006 { 1007 int i, p; 1008 device_t dev; 1009 mididev_info *md; 1010 1011 p = 0; 1012 p += snprintf(buf, size, "FreeBSD Midi Driver (newmidi) %s %s\nInstalled devices:\n", __DATE__, __TIME__); 1013 for (i = 0 ; i < mididev_info_number() ; i++) { 1014 md = get_mididev_info_unit(i); 1015 if (!MIDICONFED(md)) 1016 continue; 1017 dev = devclass_get_device(midi_devclass, i); 1018 if (p < size) 1019 p += snprintf(&buf[p], size - p, "midi%d: <%s> %s\n", i, device_get_desc(dev), md->midistat); 1020 else 1021 return (1); 1022 } 1023 1024 return (0); 1025 } 1026 1027 /* Reads the status message. */ 1028 static int 1029 midi_readstatus(char *buf, int *ptr, struct uio *uio) 1030 { 1031 int len; 1032 1033 len = min(uio->uio_resid, strlen(&buf[*ptr])); 1034 if (len > 0) { 1035 uiomove(&buf[*ptr], len, uio); 1036 *ptr += len; 1037 } 1038 1039 return (0); 1040 } 1041 1042 char 1043 *midi_cmdname(int cmd, midi_cmdtab *tab) 1044 { 1045 while (tab->name != NULL) { 1046 if (cmd == tab->cmd) 1047 return (tab->name); 1048 tab++; 1049 } 1050 1051 return ("unknown"); 1052 } 1053