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[unit] 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 /* open */ midiopen, 74 /* close */ midiclose, 75 /* read */ midiread, 76 /* write */ midiwrite, 77 /* ioctl */ midiioctl, 78 /* poll */ midipoll, 79 /* mmap */ nommap, 80 /* strategy */ nostrategy, 81 /* name */ "midi", 82 /* maj */ CDEV_MAJOR, 83 /* dump */ nodump, 84 /* psize */ nopsize, 85 /* flags */ 0, 86 /* bmaj */ -1 87 }; 88 89 /* 90 * descriptors for active devices. also used as the public softc 91 * of a device. 92 */ 93 mididev_info midi_info[NMIDI_MAX]; 94 95 u_long nmidi; /* total number of midi devices, filled in by the driver */ 96 u_long nsynth; /* total number of synthesizers, filled in by the driver */ 97 98 /* These make the buffer for /dev/midistat */ 99 static int midistatbusy; 100 static char midistatbuf[4096]; 101 static int midistatptr; 102 103 /* 104 * This is the generic init routine 105 */ 106 int 107 midiinit(mididev_info *d, device_t dev) 108 { 109 int unit; 110 111 if (midi_devclass == NULL) { 112 midi_devclass = device_get_devclass(dev); 113 make_dev(&midi_cdevsw, MIDIMKMINOR(0, MIDI_DEV_STATUS), 114 UID_ROOT, GID_WHEEL, 0444, "midistat"); 115 } 116 117 unit = device_get_unit(dev); 118 make_dev(&midi_cdevsw, MIDIMKMINOR(unit, MIDI_DEV_MIDIN), 119 UID_ROOT, GID_WHEEL, 0666, "midi%d", unit); 120 121 /* 122 * initialize standard parameters for the device. This can be 123 * overridden by device-specific configurations but better do 124 * here the generic things. 125 */ 126 127 d->unit = device_get_unit(dev); 128 d->softc = device_get_softc(dev); 129 d->dev = dev; 130 d->magic = MAGIC(d->unit); /* debugging... */ 131 132 return 0 ; 133 } 134 135 /* 136 * a small utility function which, given a device number, returns 137 * a pointer to the associated mididev_info struct, and sets the unit 138 * number. 139 */ 140 mididev_info * 141 get_mididev_info(dev_t i_dev, int *unit) 142 { 143 int u; 144 mididev_info *d = NULL; 145 146 if (MIDIDEV(i_dev) != MIDI_DEV_MIDIN) 147 return NULL; 148 u = MIDIUNIT(i_dev); 149 if (unit) 150 *unit = u; 151 152 if (u >= nmidi + nsynth) { 153 DEB(printf("get_mididev_info: unit %d is not configured.\n", u)); 154 return NULL; 155 } 156 d = &midi_info[u]; 157 158 return d; 159 } 160 161 /* 162 * here are the switches for the main functions. The switches do 163 * all necessary checks on the device number to make sure 164 * that the device is configured. They also provide some default 165 * functionalities so that device-specific drivers have to deal 166 * only with special cases. 167 */ 168 169 static int 170 midiopen(dev_t i_dev, int flags, int mode, struct proc * p) 171 { 172 switch (MIDIDEV(i_dev)) { 173 case MIDI_DEV_MIDIN: 174 return midi_open(i_dev, flags, mode, p); 175 case MIDI_DEV_STATUS: 176 return midistat_open(i_dev, flags, mode, p); 177 } 178 179 return (ENXIO); 180 } 181 182 static int 183 midiclose(dev_t i_dev, int flags, int mode, struct proc * p) 184 { 185 switch (MIDIDEV(i_dev)) { 186 case MIDI_DEV_MIDIN: 187 return midi_close(i_dev, flags, mode, p); 188 case MIDI_DEV_STATUS: 189 return midistat_close(i_dev, flags, mode, p); 190 } 191 192 return (ENXIO); 193 } 194 195 static int 196 midiread(dev_t i_dev, struct uio * buf, int flag) 197 { 198 switch (MIDIDEV(i_dev)) { 199 case MIDI_DEV_MIDIN: 200 return midi_read(i_dev, buf, flag); 201 case MIDI_DEV_STATUS: 202 return midistat_read(i_dev, buf, flag); 203 } 204 205 return (ENXIO); 206 } 207 208 static int 209 midiwrite(dev_t i_dev, struct uio * buf, int flag) 210 { 211 switch (MIDIDEV(i_dev)) { 212 case MIDI_DEV_MIDIN: 213 return midi_write(i_dev, buf, flag); 214 } 215 216 return (ENXIO); 217 } 218 219 static int 220 midiioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc * p) 221 { 222 switch (MIDIDEV(i_dev)) { 223 case MIDI_DEV_MIDIN: 224 return midi_ioctl(i_dev, cmd, arg, mode, p); 225 } 226 227 return (ENXIO); 228 } 229 230 static int 231 midipoll(dev_t i_dev, int events, struct proc * p) 232 { 233 switch (MIDIDEV(i_dev)) { 234 case MIDI_DEV_MIDIN: 235 return midi_poll(i_dev, events, p); 236 } 237 238 return (ENXIO); 239 } 240 241 /* 242 * Followings are the generic methods in midi drivers. 243 */ 244 245 int 246 midi_open(dev_t i_dev, int flags, int mode, struct proc * p) 247 { 248 int dev, unit, s, ret; 249 mididev_info *d; 250 251 dev = minor(i_dev); 252 d = get_mididev_info(i_dev, &unit); 253 254 DEB(printf("open midi%d subdev %d flags 0x%08x mode 0x%08x\n", 255 unit, dev & 0xf, flags, mode)); 256 257 if (d == NULL) 258 return (ENXIO); 259 260 s = splmidi(); 261 262 /* Mark this device busy. */ 263 device_busy(d->dev); 264 if ((d->flags & MIDI_F_BUSY) != 0) { 265 splx(s); 266 DEB(printf("opl_open: unit %d is busy.\n", unit)); 267 return (EBUSY); 268 } 269 d->flags |= MIDI_F_BUSY; 270 d->flags &= ~(MIDI_F_READING | MIDI_F_WRITING); 271 d->fflags = flags; 272 273 /* Init the queue. */ 274 if ((d->fflags & FREAD) != 0) 275 midibuf_init(&d->midi_dbuf_in); 276 if ((d->fflags & FWRITE) != 0) { 277 midibuf_init(&d->midi_dbuf_out); 278 midibuf_init(&d->midi_dbuf_passthru); 279 } 280 281 if (d->open == NULL) 282 ret = 0; 283 else 284 ret = d->open(i_dev, flags, mode, p); 285 286 splx(s); 287 288 return (ret); 289 } 290 291 int 292 midi_close(dev_t i_dev, int flags, int mode, struct proc * p) 293 { 294 int dev, unit, s, ret; 295 mididev_info *d; 296 297 dev = minor(i_dev); 298 d = get_mididev_info(i_dev, &unit); 299 300 DEB(printf("close midi%d subdev %d\n", unit, dev & 0xf)); 301 302 if (d == NULL) 303 return (ENXIO); 304 305 s = splmidi(); 306 307 /* Clear the queues. */ 308 if ((d->fflags & FREAD) != 0) 309 midibuf_init(&d->midi_dbuf_in); 310 if ((d->fflags & FWRITE) != 0) { 311 midibuf_init(&d->midi_dbuf_out); 312 midibuf_init(&d->midi_dbuf_passthru); 313 } 314 315 /* Stop playing and unmark this device busy. */ 316 d->flags &= ~MIDI_F_BUSY; 317 d->fflags = 0; 318 319 device_unbusy(d->dev); 320 321 if (d->close == NULL) 322 ret = 0; 323 else 324 ret = d->close(i_dev, flags, mode, p); 325 326 splx(s); 327 328 return (ret); 329 } 330 331 int 332 midi_read(dev_t i_dev, struct uio * buf, int flag) 333 { 334 int dev, unit, s, len, ret; 335 mididev_info *d ; 336 337 dev = minor(i_dev); 338 339 d = get_mididev_info(i_dev, &unit); 340 DEB(printf("read midi%d subdev %d flag 0x%08x\n", unit, dev & 0xf, flag)); 341 342 if (d == NULL) 343 return (ENXIO); 344 345 ret = 0; 346 s = splmidi(); 347 348 /* Begin recording. */ 349 d->callback(d, MIDI_CB_START | MIDI_CB_RD); 350 351 /* Have we got the data to read? */ 352 if ((d->flags & MIDI_F_NBIO) != 0 && d->midi_dbuf_in.rl == 0) 353 ret = EAGAIN; 354 else { 355 len = buf->uio_resid; 356 ret = midibuf_uioread(&d->midi_dbuf_in, buf, len); 357 if (ret < 0) 358 ret = -ret; 359 else 360 ret = 0; 361 } 362 363 if (ret == 0 && d->read != NULL) 364 ret = d->read(i_dev, buf, flag); 365 366 splx(s); 367 368 return (ret); 369 } 370 371 int 372 midi_write(dev_t i_dev, struct uio * buf, int flag) 373 { 374 int dev, unit, s, len, ret; 375 mididev_info *d; 376 377 dev = minor(i_dev); 378 d = get_mididev_info(i_dev, &unit); 379 380 DEB(printf("write midi%d subdev %d flag 0x%08x\n", unit, dev & 0xf, flag)); 381 382 if (d == NULL) 383 return (ENXIO); 384 385 ret = 0; 386 s = splmidi(); 387 388 /* Begin playing. */ 389 d->callback(d, MIDI_CB_START | MIDI_CB_WR); 390 391 /* Have we got the data to write? */ 392 if ((d->flags & MIDI_F_NBIO) != 0 && d->midi_dbuf_out.fl == 0) 393 ret = EAGAIN; 394 else { 395 len = buf->uio_resid; 396 if (len > d->midi_dbuf_out.fl && 397 (d->flags & MIDI_F_NBIO)) 398 len = d->midi_dbuf_out.fl; 399 ret = midibuf_uiowrite(&d->midi_dbuf_out, buf, len); 400 if (ret < 0) 401 ret = -ret; 402 else 403 ret = 0; 404 } 405 406 /* Begin playing. */ 407 d->callback(d, MIDI_CB_START | MIDI_CB_WR); 408 409 if (ret == 0 && d->write != NULL) 410 ret = d->write(i_dev, buf, flag); 411 412 splx(s); 413 414 return (ret); 415 } 416 417 /* 418 * generic midi ioctl. Functions of the default driver can be 419 * overridden by the device-specific ioctl call. 420 * If a device-specific call returns ENOSYS (Function not implemented), 421 * the default driver is called. Otherwise, the returned value 422 * is passed up. 423 * 424 * The default handler, for many parameters, sets the value in the 425 * descriptor, sets MIDI_F_INIT, and calls the callback function with 426 * reason INIT. If successful, the callback returns 1 and the caller 427 * can update the parameter. 428 */ 429 430 int 431 midi_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct proc * p) 432 { 433 int ret = ENOSYS, dev, unit; 434 mididev_info *d; 435 struct snd_size *sndsize; 436 u_long s; 437 438 dev = minor(i_dev); 439 d = get_mididev_info(i_dev, &unit); 440 441 if (d == NULL) 442 return (ENXIO); 443 444 if (d->ioctl) 445 ret = d->ioctl(i_dev, cmd, arg, mode, p); 446 if (ret != ENOSYS) 447 return ret; 448 449 /* 450 * pass control to the default ioctl handler. Set ret to 0 now. 451 */ 452 ret = 0; 453 454 /* 455 * all routines are called with int. blocked. Make sure that 456 * ints are re-enabled when calling slow or blocking functions! 457 */ 458 s = splmidi(); 459 switch(cmd) { 460 461 /* 462 * we start with the new ioctl interface. 463 */ 464 case AIONWRITE: /* how many bytes can write ? */ 465 *(int *)arg = d->midi_dbuf_out.fl; 466 break; 467 468 case AIOSSIZE: /* set the current blocksize */ 469 sndsize = (struct snd_size *)arg; 470 if (sndsize->play_size <= d->midi_dbuf_out.unit_size && sndsize->rec_size <= d->midi_dbuf_in.unit_size) { 471 d->flags &= ~MIDI_F_HAS_SIZE; 472 d->midi_dbuf_out.blocksize = d->midi_dbuf_out.unit_size; 473 d->midi_dbuf_in.blocksize = d->midi_dbuf_in.unit_size; 474 } 475 else { 476 if (sndsize->play_size > d->midi_dbuf_out.bufsize / 4) 477 sndsize->play_size = d->midi_dbuf_out.bufsize / 4; 478 if (sndsize->rec_size > d->midi_dbuf_in.bufsize / 4) 479 sndsize->rec_size = d->midi_dbuf_in.bufsize / 4; 480 /* Round up the size to the multiple of EV_SZ. */ 481 d->midi_dbuf_out.blocksize = 482 ((sndsize->play_size + d->midi_dbuf_out.unit_size - 1) 483 / d->midi_dbuf_out.unit_size) * d->midi_dbuf_out.unit_size; 484 d->midi_dbuf_in.blocksize = 485 ((sndsize->rec_size + d->midi_dbuf_in.unit_size - 1) 486 / d->midi_dbuf_in.unit_size) * d->midi_dbuf_in.unit_size; 487 d->flags |= MIDI_F_HAS_SIZE; 488 } 489 /* FALLTHROUGH */ 490 case AIOGSIZE: /* get the current blocksize */ 491 sndsize = (struct snd_size *)arg; 492 sndsize->play_size = d->midi_dbuf_out.blocksize; 493 sndsize->rec_size = d->midi_dbuf_in.blocksize; 494 495 ret = 0; 496 break; 497 498 case AIOSTOP: 499 if (*(int *)arg == AIOSYNC_PLAY) /* play */ 500 *(int *)arg = d->callback(d, MIDI_CB_STOP | MIDI_CB_WR); 501 else if (*(int *)arg == AIOSYNC_CAPTURE) 502 *(int *)arg = d->callback(d, MIDI_CB_STOP | MIDI_CB_RD); 503 else { 504 splx(s); 505 DEB(printf("AIOSTOP: bad channel 0x%x\n", *(int *)arg)); 506 *(int *)arg = 0 ; 507 } 508 break ; 509 510 case AIOSYNC: 511 DEB(printf("AIOSYNC chan 0x%03lx pos %lu unimplemented\n", 512 ((snd_sync_parm *)arg)->chan, 513 ((snd_sync_parm *)arg)->pos)); 514 break; 515 /* 516 * here follow the standard ioctls (filio.h etc.) 517 */ 518 case FIONREAD: /* get # bytes to read */ 519 *(int *)arg = d->midi_dbuf_in.rl; 520 break; 521 522 case FIOASYNC: /*set/clear async i/o */ 523 DEB( printf("FIOASYNC\n") ; ) 524 break; 525 526 case FIONBIO: /* set/clear non-blocking i/o */ 527 if ( *(int *)arg == 0 ) 528 d->flags &= ~MIDI_F_NBIO ; 529 else 530 d->flags |= MIDI_F_NBIO ; 531 break ; 532 533 case MIOSPASSTHRU: /* set/clear passthru */ 534 if ( *(int *)arg == 0 ) 535 d->flags &= ~MIDI_F_PASSTHRU ; 536 else 537 d->flags |= MIDI_F_PASSTHRU ; 538 539 /* Init the queue. */ 540 midibuf_init(&d->midi_dbuf_passthru); 541 542 /* FALLTHROUGH */ 543 case MIOGPASSTHRU: /* get passthru */ 544 if ((d->flags & MIDI_F_PASSTHRU) != 0) 545 (int *)arg = 1; 546 else 547 (int *)arg = 0; 548 break ; 549 550 default: 551 DEB(printf("default ioctl midi%d subdev %d fn 0x%08x fail\n", 552 unit, dev & 0xf, cmd)); 553 ret = EINVAL; 554 break ; 555 } 556 splx(s); 557 return ret ; 558 } 559 560 int 561 midi_poll(dev_t i_dev, int events, struct proc * p) 562 { 563 int unit, dev, ret, s, lim; 564 mididev_info *d; 565 566 dev = minor(i_dev); 567 d = get_mididev_info(i_dev, &unit); 568 569 if (d == NULL) 570 return (ENXIO); 571 572 if (d->poll) 573 ret = d->poll(i_dev, events, p); 574 575 ret = 0; 576 s = splmidi(); 577 578 /* Look up the apropriate queue and select it. */ 579 if ((events & (POLLOUT | POLLWRNORM)) != 0) { 580 /* Start playing. */ 581 d->callback(d, MIDI_CB_START | MIDI_CB_WR); 582 583 /* Find out the boundary. */ 584 if ((d->flags & MIDI_F_HAS_SIZE) != 0) 585 lim = d->midi_dbuf_out.blocksize; 586 else 587 lim = d->midi_dbuf_out.unit_size; 588 if (d->midi_dbuf_out.fl < lim) 589 /* No enough space, record select. */ 590 selrecord(p, &d->midi_dbuf_out.sel); 591 else 592 /* We can write now. */ 593 ret |= events & (POLLOUT | POLLWRNORM); 594 } 595 if ((events & (POLLIN | POLLRDNORM)) != 0) { 596 /* Start recording. */ 597 d->callback(d, MIDI_CB_START | MIDI_CB_RD); 598 599 /* Find out the boundary. */ 600 if ((d->flags & MIDI_F_HAS_SIZE) != 0) 601 lim = d->midi_dbuf_in.blocksize; 602 else 603 lim = d->midi_dbuf_in.unit_size; 604 if (d->midi_dbuf_in.rl < lim) 605 /* No data ready, record select. */ 606 selrecord(p, &d->midi_dbuf_in.sel); 607 else 608 /* We can write now. */ 609 ret |= events & (POLLIN | POLLRDNORM); 610 } 611 splx(s); 612 613 return (ret); 614 } 615 616 void 617 midi_intr(mididev_info *d) 618 { 619 if (d->intr != NULL) 620 d->intr(d->intrarg, d); 621 } 622 623 /* 624 * These handle the status message of the midi drivers. 625 */ 626 627 int 628 midistat_open(dev_t i_dev, int flags, int mode, struct proc * p) 629 { 630 if (midistatbusy) 631 return (EBUSY); 632 633 bzero(midistatbuf, sizeof(midistatbuf)); 634 midistatptr = 0; 635 if (midi_initstatus(midistatbuf, sizeof(midistatbuf) - 1)) 636 return (ENOMEM); 637 638 midistatbusy = 1; 639 640 return (0); 641 } 642 643 int 644 midistat_close(dev_t i_dev, int flags, int mode, struct proc * p) 645 { 646 midistatbusy = 0; 647 648 return (0); 649 } 650 651 int 652 midistat_read(dev_t i_dev, struct uio * buf, int flag) 653 { 654 return midi_readstatus(midistatbuf, &midistatptr, buf); 655 } 656 657 /* 658 * finally, some "libraries" 659 */ 660 661 /* Inits the buffer for /dev/midistat. */ 662 static int 663 midi_initstatus(char *buf, int size) 664 { 665 int i, p; 666 device_t dev; 667 mididev_info *md; 668 669 p = 0; 670 p += snprintf(buf, size, "FreeBSD Midi Driver (newmidi) %s %s\nInstalled devices:\n", __DATE__, __TIME__); 671 for (i = 0 ; i < NMIDI_MAX ; i++) { 672 md = &midi_info[i]; 673 if (!MIDICONFED(md)) 674 continue; 675 dev = devclass_get_device(midi_devclass, i); 676 if (p < size) 677 p += snprintf(&buf[p], size - p, "midi%d: <%s> %s\n", i, device_get_desc(dev), md->midistat); 678 else 679 return (1); 680 } 681 682 return (0); 683 } 684 685 /* Reads the status message. */ 686 static int 687 midi_readstatus(char *buf, int *ptr, struct uio *uio) 688 { 689 int s, len; 690 691 s = splmidi(); 692 len = min(uio->uio_resid, strlen(&buf[*ptr])); 693 if (len > 0) { 694 uiomove(&buf[*ptr], len, uio); 695 *ptr += len; 696 } 697 splx(s); 698 699 return (0); 700 } 701