46 47#include <sys/param.h> 48#include <sys/queue.h> 49#include <sys/kernel.h> 50#include <sys/lock.h> 51#include <sys/mutex.h> 52#include <sys/proc.h> 53#include <sys/signalvar.h> 54#include <sys/conf.h> 55#include <sys/selinfo.h> 56#include <sys/sysctl.h> 57#include <sys/types.h> 58#include <sys/malloc.h> 59#include <sys/param.h> 60#include <sys/systm.h> 61#include <sys/proc.h> 62#include <sys/fcntl.h> 63#include <sys/types.h> 64#include <sys/uio.h> 65#include <sys/poll.h> 66#include <sys/sbuf.h> 67#include <sys/kobj.h> 68#include <sys/module.h> 69 70#include <dev/sound/midi/midi.h> 71#include "mpu_if.h" 72 73#include <dev/sound/midi/midiq.h> 74#include "synth_if.h" 75MALLOC_DEFINE(M_MIDI, "midi buffers", "Midi data allocation area"); 76 77 78#define PCMMKMINOR(u, d, c) ((((c) & 0xff) << 16) | (((u) & 0x0f) << 4) | ((d) & 0x0f)) 79#define MIDIMKMINOR(u, d, c) PCMMKMINOR(u, d, c) 80 81#define MIDI_DEV_RAW 2 82#define MIDI_DEV_MIDICTL 12 83 84enum midi_states { 85 MIDI_IN_START, MIDI_IN_SYSEX, MIDI_IN_DATA 86}; 87 88/* 89 * The MPU interface current has init() uninit() inqsize(( outqsize() 90 * callback() : fiddle with the tx|rx status. 91 */ 92 93#include "mpu_if.h" 94 95/* 96 * /dev/rmidi Structure definitions 97 */ 98 99#define MIDI_NAMELEN 16 100struct snd_midi { 101 KOBJ_FIELDS; 102 struct mtx lock; /* Protects all but queues */ 103 void *cookie; 104 105 int unit; /* Should only be used in midistat */ 106 int channel;/* Should only be used in midistat */ 107 108 int busy; 109 int flags; /* File flags */ 110 char name[MIDI_NAMELEN]; 111 struct mtx qlock; /* Protects inq, outq and flags */ 112 MIDIQ_HEAD(, char)inq, outq; 113 int rchan, wchan; 114 struct selinfo rsel, wsel; 115 int hiwat; /* QLEN(outq)>High-water -> disable writes 116 * from userland */ 117 enum midi_states inq_state; 118 int inq_status, inq_left; /* Variables for the state 119 * machine in Midi_in, this 120 * is to provide that signals 121 * only get issued only 122 * complete command packets. */ 123 struct proc *async; 124 struct cdev *dev; 125 struct synth_midi *synth; 126 int synth_flags; 127 TAILQ_ENTRY(snd_midi) link; 128}; 129 130struct synth_midi { 131 KOBJ_FIELDS; 132 struct snd_midi *m; 133}; 134 135static synth_open_t midisynth_open; 136static synth_close_t midisynth_close; 137static synth_writeraw_t midisynth_writeraw; 138static synth_killnote_t midisynth_killnote; 139static synth_startnote_t midisynth_startnote; 140static synth_setinstr_t midisynth_setinstr; 141static synth_alloc_t midisynth_alloc; 142static synth_controller_t midisynth_controller; 143static synth_bender_t midisynth_bender; 144 145 146static kobj_method_t midisynth_methods[] = { 147 KOBJMETHOD(synth_open,midisynth_open), 148 KOBJMETHOD(synth_close,midisynth_close), 149 KOBJMETHOD(synth_writeraw,midisynth_writeraw), 150 KOBJMETHOD(synth_setinstr,midisynth_setinstr), 151 KOBJMETHOD(synth_startnote,midisynth_startnote), 152 KOBJMETHOD(synth_killnote,midisynth_killnote), 153 KOBJMETHOD(synth_alloc, midisynth_alloc), 154 KOBJMETHOD(synth_controller, midisynth_controller), 155 KOBJMETHOD(synth_bender, midisynth_bender), 156 { 0, 0 } 157}; 158 159DEFINE_CLASS(midisynth, midisynth_methods, 0); 160 161/* 162 * Module Exports & Interface 163 * 164 * struct midi_chan *midi_init(MPU_CLASS cls, int unit, int chan) int 165 * midi_uninit(struct snd_midi *) 0 == no error EBUSY or other error int 166 * Midi_in(struct midi_chan *, char *buf, int count) int Midi_out(struct 167 * midi_chan *, char *buf, int count) 168 * 169 * midi_{in,out} return actual size transfered 170 * 171 */ 172 173 174/* 175 * midi_devs tailq, holder of all rmidi instances protected by midistat_lock 176 */ 177 178TAILQ_HEAD(, snd_midi) midi_devs; 179 180/* 181 * /dev/midistat variables and declarations, protected by midistat_lock 182 */ 183 184static struct mtx midistat_lock; 185static int midistat_isopen = 0; 186static struct sbuf midistat_sbuf; 187static int midistat_bufptr; 188static struct cdev *midistat_dev; 189 190/* 191 * /dev/midistat dev_t declarations 192 */ 193 194static d_open_t midistat_open; 195static d_close_t midistat_close; 196static d_read_t midistat_read; 197 198static struct cdevsw midistat_cdevsw = { 199 .d_version = D_VERSION, 200 .d_open = midistat_open, 201 .d_close = midistat_close, 202 .d_read = midistat_read, 203 .d_name = "midistat", 204}; 205 206 207/* 208 * /dev/rmidi dev_t declarations, struct variable access is protected by 209 * locks contained within the structure. 210 */ 211 212static d_open_t midi_open; 213static d_close_t midi_close; 214static d_ioctl_t midi_ioctl; 215static d_read_t midi_read; 216static d_write_t midi_write; 217static d_poll_t midi_poll; 218 219static struct cdevsw midi_cdevsw = { 220 .d_version = D_VERSION, 221 .d_open = midi_open, 222 .d_close = midi_close, 223 .d_read = midi_read, 224 .d_write = midi_write, 225 .d_ioctl = midi_ioctl, 226 .d_poll = midi_poll, 227 .d_name = "rmidi", 228}; 229 230/* 231 * Prototypes of library functions 232 */ 233 234static int midi_destroy(struct snd_midi *, int); 235static int midistat_prepare(struct sbuf * s); 236static int midi_load(void); 237static int midi_unload(void); 238 239/* 240 * Misc declr. 241 */ 242SYSCTL_NODE(_hw, OID_AUTO, midi, CTLFLAG_RD, 0, "Midi driver"); 243SYSCTL_NODE(_hw_midi, OID_AUTO, stat, CTLFLAG_RD, 0, "Status device"); 244 245int midi_debug; 246/* XXX: should this be moved into debug.midi? */ 247SYSCTL_INT(_hw_midi, OID_AUTO, debug, CTLFLAG_RW, &midi_debug, 0, ""); 248 249int midi_dumpraw; 250SYSCTL_INT(_hw_midi, OID_AUTO, dumpraw, CTLFLAG_RW, &midi_dumpraw, 0, ""); 251 252int midi_instroff; 253SYSCTL_INT(_hw_midi, OID_AUTO, instroff, CTLFLAG_RW, &midi_instroff, 0, ""); 254 255int midistat_verbose; 256SYSCTL_INT(_hw_midi_stat, OID_AUTO, verbose, CTLFLAG_RW, 257 &midistat_verbose, 0, ""); 258 259#define MIDI_DEBUG(l,a) if(midi_debug>=l) a 260/* 261 * CODE START 262 */ 263 264/* 265 * Register a new rmidi device. cls midi_if interface unit == 0 means 266 * auto-assign new unit number unit != 0 already assigned a unit number, eg. 267 * not the first channel provided by this device. channel, sub-unit 268 * cookie is passed back on MPU calls Typical device drivers will call with 269 * unit=0, channel=1..(number of channels) and cookie=soft_c and won't care 270 * what unit number is used. 271 * 272 * It is an error to call midi_init with an already used unit/channel combo. 273 * 274 * Returns NULL on error 275 * 276 */ 277struct snd_midi * 278midi_init(kobj_class_t cls, int unit, int channel, void *cookie) 279{ 280 struct snd_midi *m; 281 int i; 282 int inqsize, outqsize; 283 MIDI_TYPE *buf; 284 285 MIDI_DEBUG(1,printf("midiinit: unit %d/%d.\n", unit, channel)); 286 mtx_lock(&midistat_lock); 287 /* 288 * Protect against call with existing unit/channel or auto-allocate a 289 * new unit number. 290 */ 291 i = -1; 292 TAILQ_FOREACH(m, &midi_devs, link) { 293 mtx_lock(&m->lock); 294 if (unit != 0) { 295 if (m->unit == unit && m->channel == channel) { 296 mtx_unlock(&m->lock); 297 goto err0; 298 } 299 } else { 300 /* 301 * Find a better unit number 302 */ 303 if (m->unit > i) 304 i = m->unit; 305 } 306 mtx_unlock(&m->lock); 307 } 308 309 if (unit == 0) 310 unit = i + 1; 311 312 MIDI_DEBUG(1, printf("midiinit #2: unit %d/%d.\n", unit, channel)); 313 m = malloc(sizeof(*m), M_MIDI, M_NOWAIT | M_ZERO); 314 if (m == NULL) 315 goto err0; 316 317 m->synth = malloc(sizeof(*m->synth), M_MIDI, M_NOWAIT | M_ZERO); 318 kobj_init((kobj_t)m->synth, &midisynth_class); 319 m->synth->m = m; 320 kobj_init((kobj_t)m, cls); 321 inqsize = MPU_INQSIZE(m, cookie); 322 outqsize = MPU_OUTQSIZE(m, cookie); 323 324 MIDI_DEBUG(1, printf("midiinit queues %d/%d.\n", inqsize, outqsize)); 325 if (!inqsize && !outqsize) 326 goto err1; 327 328 mtx_init(&m->lock, "raw midi", 0, 0); 329 mtx_init(&m->qlock, "q raw midi", 0, 0); 330 331 mtx_lock(&m->lock); 332 mtx_lock(&m->qlock); 333 334 if (inqsize) 335 buf = malloc(sizeof(MIDI_TYPE) * inqsize, M_MIDI, M_NOWAIT); 336 else 337 buf = NULL; 338 339 MIDIQ_INIT(m->inq, buf, inqsize); 340 341 if (outqsize) 342 buf = malloc(sizeof(MIDI_TYPE) * outqsize, M_MIDI, M_NOWAIT); 343 else 344 buf = NULL; 345 m->hiwat = outqsize / 2; 346 347 MIDIQ_INIT(m->outq, buf, outqsize); 348 349 if ((inqsize && !MIDIQ_BUF(m->inq)) || 350 (outqsize && !MIDIQ_BUF(m->outq))) 351 goto err2; 352 353 354 m->busy = 0; 355 m->flags = 0; 356 m->unit = unit; 357 m->channel = channel; 358 m->cookie = cookie; 359 360 if (MPU_INIT(m, cookie)) 361 goto err2; 362 363 mtx_unlock(&m->lock); 364 mtx_unlock(&m->qlock); 365 366 TAILQ_INSERT_TAIL(&midi_devs, m, link); 367 368 mtx_unlock(&midistat_lock); 369 370 m->dev = make_dev(&midi_cdevsw, 371 MIDIMKMINOR(unit, MIDI_DEV_RAW, channel), 372 UID_ROOT, GID_WHEEL, 0666, "midi%d.%d", unit, channel); 373 m->dev->si_drv1 = m; 374 375 return m; 376 377err2: mtx_destroy(&m->qlock); 378 mtx_destroy(&m->lock); 379 380 if (MIDIQ_BUF(m->inq)) 381 free(MIDIQ_BUF(m->inq), M_MIDI); 382 if (MIDIQ_BUF(m->outq)) 383 free(MIDIQ_BUF(m->outq), M_MIDI); 384err1: free(m, M_MIDI); 385err0: mtx_unlock(&midistat_lock); 386 MIDI_DEBUG(1, printf("midi_init ended in error\n")); 387 return NULL; 388} 389 390/* 391 * midi_uninit does not call MIDI_UNINIT, as since this is the implementors 392 * entry point. midi_unint if fact, does not send any methods. A call to 393 * midi_uninit is a defacto promise that you won't manipulate ch anymore 394 * 395 */ 396 397int 398midi_uninit(struct snd_midi * m) 399{ 400 int err; 401 402 err = ENXIO; 403 mtx_lock(&midistat_lock); 404 mtx_lock(&m->lock); 405 if (m->busy) { 406 if (!(m->rchan || m->wchan)) 407 goto err; 408 409 if (m->rchan) { 410 wakeup(&m->rchan); 411 m->rchan = 0; 412 } 413 if (m->wchan) { 414 wakeup(&m->wchan); 415 m->wchan = 0; 416 } 417 } 418 err = midi_destroy(m, 0); 419 if(!err) 420 goto exit; 421 422err: mtx_unlock(&m->lock); 423exit: mtx_unlock(&midistat_lock); 424 return err; 425} 426 427/* 428 * midi_in: process all data until the queue is full, then discards the rest. 429 * Since midi_in is a state machine, data discards can cause it to get out of 430 * whack. Process as much as possible. It calls, wakeup, selnotify and 431 * psignal at most once. 432 */ 433 434#ifdef notdef 435static int midi_lengths[] = {2, 2, 2, 2, 1, 1, 2, 0}; 436#endif /* notdef */ 437/* Number of bytes in a MIDI command */ 438#define MIDI_LENGTH(d) (midi_lengths[((d) >> 4) & 7]) 439#define MIDI_ACK 0xfe 440#define MIDI_IS_STATUS(d) ((d) >= 0x80) 441#define MIDI_IS_COMMON(d) ((d) >= 0xf0) 442 443#define MIDI_SYSEX_START 0xF0 444#define MIDI_SYSEX_END 0xF7 445 446 447int 448midi_in(struct snd_midi * m, MIDI_TYPE * buf, int size) 449{ 450 /* int i, sig, enq; */ 451 int used; 452 /* MIDI_TYPE data; */ 453 MIDI_DEBUG(5, printf("midi_in: m=%p size=%d\n", m, size)); 454 455/* 456 * XXX: locking flub 457 */ 458 if (!(m->flags & M_RX)) 459 return size; 460 461 used = 0; 462 463 mtx_lock(&m->qlock); 464#if 0 465 /* 466 * Don't bother queuing if not in read mode. Discard everything and 467 * return size so the caller doesn't freak out. 468 */ 469 470 if (!(m->flags & M_RX)) 471 return size; 472 473 for (i = sig = 0; i < size; i++) { 474 475 data = buf[i]; 476 enq = 0; 477 if (data == MIDI_ACK) 478 continue; 479 480 switch (m->inq_state) { 481 case MIDI_IN_START: 482 if (MIDI_IS_STATUS(data)) { 483 switch (data) { 484 case 0xf0: /* Sysex */ 485 m->inq_state = MIDI_IN_SYSEX; 486 break; 487 case 0xf1: /* MTC quarter frame */ 488 case 0xf3: /* Song select */ 489 m->inq_state = MIDI_IN_DATA; 490 enq = 1; 491 m->inq_left = 1; 492 break; 493 case 0xf2: /* Song position pointer */ 494 m->inq_state = MIDI_IN_DATA; 495 enq = 1; 496 m->inq_left = 2; 497 break; 498 default: 499 if (MIDI_IS_COMMON(data)) { 500 enq = 1; 501 sig = 1; 502 } else { 503 m->inq_state = MIDI_IN_DATA; 504 enq = 1; 505 m->inq_status = data; 506 m->inq_left = MIDI_LENGTH(data); 507 } 508 break; 509 } 510 } else if (MIDI_IS_STATUS(m->inq_status)) { 511 m->inq_state = MIDI_IN_DATA; 512 if (!MIDIQ_FULL(m->inq)) { 513 used++; 514 MIDIQ_ENQ(m->inq, &m->inq_status, 1); 515 } 516 enq = 1; 517 m->inq_left = MIDI_LENGTH(m->inq_status) - 1; 518 } 519 break; 520 /* 521 * End of case MIDI_IN_START: 522 */ 523 524 case MIDI_IN_DATA: 525 enq = 1; 526 if (--m->inq_left <= 0) 527 sig = 1; /* deliver data */ 528 break; 529 case MIDI_IN_SYSEX: 530 if (data == MIDI_SYSEX_END) 531 m->inq_state = MIDI_IN_START; 532 break; 533 } 534 535 if (enq) 536 if (!MIDIQ_FULL(m->inq)) { 537 MIDIQ_ENQ(m->inq, &data, 1); 538 used++; 539 } 540 /* 541 * End of the state machines main "for loop" 542 */ 543 } 544 if (sig) { 545#endif 546 MIDI_DEBUG(6, printf("midi_in: len %jd avail %jd\n", (intmax_t)MIDIQ_LEN(m->inq), (intmax_t)MIDIQ_AVAIL(m->inq))) ; 547 if (MIDIQ_AVAIL(m->inq) > size) { 548 used=size; 549 MIDIQ_ENQ(m->inq, buf, size); 550 } else { 551 MIDI_DEBUG(4,printf("midi_in: Discarding data qu\n")); 552 mtx_unlock(&m->qlock); 553 return 0; 554 } 555 if (m->rchan) { 556 wakeup(&m->rchan); 557 m->rchan = 0; 558 } 559 selwakeup(&m->rsel); 560 if (m->async) { 561 PROC_LOCK(m->async); 562 psignal(m->async, SIGIO); 563 PROC_UNLOCK(m->async); 564 } 565#if 0 566 } 567#endif 568 mtx_unlock(&m->qlock); 569 return used; 570} 571 572/* 573 * midi_out: The only clearer of the M_TXEN flag. 574 */ 575int 576midi_out(struct snd_midi * m, MIDI_TYPE * buf, int size) 577{ 578 int used; 579 580/* 581 * XXX: locking flub 582 */ 583 if (!(m->flags & M_TXEN)) 584 return 0; 585 586 MIDI_DEBUG(2, printf("midi_out: %p\n", m)); 587 mtx_lock(&m->qlock); 588 used = MIN(size, MIDIQ_LEN(m->outq)); 589 MIDI_DEBUG(3, printf("midi_out: used %d\n", used)); 590 if (used) 591 MIDIQ_DEQ(m->outq, buf, used); 592 if (MIDIQ_EMPTY(m->outq)) { 593 m->flags &= ~M_TXEN; 594 MPU_CALLBACKP(m, m->cookie, m->flags); 595 } 596 if (used && MIDIQ_AVAIL(m->outq) > m->hiwat ) { 597 if (m->wchan) { 598 wakeup(&m->wchan); 599 m->wchan = 0; 600 } 601 selwakeup(&m->wsel); 602 if (m->async) { 603 PROC_LOCK(m->async); 604 psignal(m->async, SIGIO); 605 PROC_UNLOCK(m->async); 606 } 607 } 608 mtx_unlock(&m->qlock); 609 return used; 610} 611 612 613/* 614 * /dev/rmidi#.# device access functions 615 */ 616int 617midi_open(struct cdev *i_dev, int flags, int mode, struct thread * td) 618{ 619 struct snd_midi *m = i_dev->si_drv1; 620 int retval; 621 622 MIDI_DEBUG(1,printf("midiopen %p %s %s\n", td, 623 flags & FREAD?"M_RX":"", flags & FWRITE?"M_TX":"")); 624 if (m == NULL) 625 return ENXIO; 626 627 mtx_lock(&m->lock); 628 mtx_lock(&m->qlock); 629 630 retval = 0; 631 632 if (flags & FREAD) { 633 if (MIDIQ_SIZE(m->inq) == 0) 634 retval = ENXIO; 635 else if (m->flags & M_RX) 636 retval = EBUSY; 637 if (retval) 638 goto err; 639 } 640 if (flags & FWRITE) { 641 if (MIDIQ_SIZE(m->outq) == 0) 642 retval = ENXIO; 643 else if (m->flags & M_TX) 644 retval = EBUSY; 645 if (retval) 646 goto err; 647 } 648 m->busy++; 649 650 m->rchan = 0; 651 m->wchan = 0; 652 m->async = 0; 653 654 if (flags & FREAD) { 655 m->flags |= M_RX | M_RXEN; 656 /* 657 * Only clear the inq, the outq might still have data to drain from 658 * a previous session 659 */ 660 MIDIQ_CLEAR(m->inq); 661 }; 662 663 if (flags & FWRITE) 664 m->flags |= M_TX; 665 666 MPU_CALLBACK(m, m->cookie, m->flags); 667 668 MIDI_DEBUG(2, printf("midi_open: opened.\n")); 669 670err: mtx_unlock(&m->qlock); 671 mtx_unlock(&m->lock); 672 return retval; 673} 674 675int 676midi_close(struct cdev *i_dev, int flags, int mode, struct thread * td) 677{ 678 struct snd_midi *m = i_dev->si_drv1; 679 int retval; 680 int oldflags; 681 682 MIDI_DEBUG(1, printf("midi_close %p %s %s\n", td, 683 flags & FREAD?"M_RX":"", flags & FWRITE?"M_TX":"")); 684 685 if (m == NULL) 686 return ENXIO; 687 688 mtx_lock(&m->lock); 689 mtx_lock(&m->qlock); 690 691 if ( (flags & FREAD && !(m->flags & M_RX)) || 692 (flags & FWRITE && !(m->flags & M_TX)) ) { 693 retval = ENXIO; 694 goto err; 695 } 696 697 m->busy--; 698 699 oldflags = m->flags; 700 701 if (flags & FREAD) 702 m->flags &= ~(M_RX | M_RXEN); 703 if (flags & FWRITE) 704 m->flags &= ~M_TX; 705 706 if( (m->flags & (M_TXEN | M_RXEN)) != (oldflags & (M_RXEN | M_TXEN)) ) 707 MPU_CALLBACK(m, m->cookie, m->flags); 708 709 MIDI_DEBUG(1, printf("midi_close: closed, busy = %d.\n", m->busy)); 710 711 mtx_unlock(&m->qlock); 712 mtx_unlock(&m->lock); 713 retval = 0; 714err: return retval; 715} 716/* 717 * TODO: midi_read, per oss programmer's guide pg. 42 should return as soon as data is available. 718 */ 719int 720midi_read(struct cdev *i_dev, struct uio * uio, int ioflag) 721{ 722#define MIDI_RSIZE 32 723 struct snd_midi *m = i_dev->si_drv1; 724 int retval; 725 int used; 726 char buf[MIDI_RSIZE]; 727 728 MIDI_DEBUG(5, printf("midiread: count=%lu\n", (unsigned long)uio->uio_resid)); 729 730 retval = EIO; 731 732 if (m == NULL) 733 goto err0; 734 735 mtx_lock(&m->lock); 736 mtx_lock(&m->qlock); 737 738 if (!(m->flags & M_RX)) 739 goto err1; 740 741 while (uio->uio_resid > 0) { 742 while (MIDIQ_EMPTY(m->inq)) { 743 retval = EWOULDBLOCK; 744 if (ioflag & O_NONBLOCK) 745 goto err1; 746 mtx_unlock(&m->lock); 747 m->rchan = 1; 748 retval = msleep(&m->rchan, &m->qlock, 749 PCATCH | PDROP, "midi RX", 0); 750 /* 751 * We slept, maybe things have changed since last 752 * dying check 753 */ 754 if (retval == EINTR) 755 goto err0; 756 if (m != i_dev->si_drv1) 757 retval = ENXIO; 758 /* if (retval && retval != ERESTART) */ 759 if (retval) 760 goto err0; 761 mtx_lock(&m->lock); 762 mtx_lock(&m->qlock); 763 m->rchan = 0; 764 if (!m->busy) 765 goto err1; 766 } 767 MIDI_DEBUG(6, printf("midi_read start\n")); 768 /* 769 * At this point, it is certain that m->inq has data 770 */ 771 772 used = MIN(MIDIQ_LEN(m->inq), uio->uio_resid); 773 used = MIN(used, MIDI_RSIZE); 774 775 MIDI_DEBUG(6,printf("midiread: uiomove cc=%d\n", used)); 776 MIDIQ_DEQ(m->inq, buf, used); 777 retval = uiomove(buf, used, uio); 778 if (retval) 779 goto err1; 780 } 781 782 /* 783 * If we Made it here then transfer is good 784 */ 785 retval = 0; 786err1: mtx_unlock(&m->qlock); 787 mtx_unlock(&m->lock); 788err0: MIDI_DEBUG(4, printf("midi_read: ret %d\n",retval)); 789 return retval; 790} 791 792/* 793 * midi_write: The only setter of M_TXEN 794 */ 795 796int 797midi_write(struct cdev *i_dev, struct uio * uio, int ioflag) 798{ 799#define MIDI_WSIZE 32 800 struct snd_midi *m = i_dev->si_drv1; 801 int retval; 802 int used; 803 char buf[MIDI_WSIZE]; 804 805 806 MIDI_DEBUG(4, printf("midi_write\n")); 807 retval = 0; 808 if (m == NULL) 809 goto err0; 810 811 mtx_lock(&m->lock); 812 mtx_lock(&m->qlock); 813 814 if (!(m->flags & M_TX)) 815 goto err1; 816 817 while (uio->uio_resid > 0) { 818 while (MIDIQ_AVAIL(m->outq) == 0) { 819 retval = EWOULDBLOCK; 820 if (ioflag & O_NONBLOCK) 821 goto err1; 822 mtx_unlock(&m->lock); 823 m->wchan = 1; 824 MIDI_DEBUG(3,printf("midi_write msleep\n")); 825 retval = msleep(&m->wchan, &m->qlock, 826 PCATCH | PDROP, "midi TX", 0); 827 /* 828 * We slept, maybe things have changed since last 829 * dying check 830 */ 831 if (retval == EINTR) 832 goto err0; 833 if (m != i_dev->si_drv1) 834 retval = ENXIO; 835 if (retval) 836 goto err0; 837 mtx_lock(&m->lock); 838 mtx_lock(&m->qlock); 839 m->wchan = 0; 840 if (!m->busy) 841 goto err1; 842 } 843 844 /* 845 * We are certain than data can be placed on the queue 846 */ 847 848 used = MIN(MIDIQ_AVAIL(m->outq), uio->uio_resid); 849 used = MIN(used, MIDI_WSIZE); 850 MIDI_DEBUG(5,printf("midiout: resid %d len %jd avail %jd\n", uio->uio_resid, (intmax_t)MIDIQ_LEN(m->outq), (intmax_t)MIDIQ_AVAIL(m->outq))); 851 852 853 MIDI_DEBUG(5,printf("midi_write: uiomove cc=%d\n", used)); 854 retval = uiomove(buf, used, uio); 855 if (retval) 856 goto err1; 857 MIDIQ_ENQ(m->outq, buf, used); 858 /* 859 * Inform the bottom half that data can be written 860 */ 861 if (!(m->flags & M_TXEN)) { 862 m->flags |= M_TXEN; 863 MPU_CALLBACK(m, m->cookie, m->flags); 864 } 865 } 866 /* 867 * If we Made it here then transfer is good 868 */ 869 retval = 0; 870err1: mtx_unlock(&m->qlock); 871 mtx_unlock(&m->lock); 872err0: return retval; 873} 874 875int 876midi_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode, struct thread * td) 877{ 878 return ENXIO; 879} 880 881int 882midi_poll(struct cdev *i_dev, int events, struct thread * td) 883{ 884 struct snd_midi *m = i_dev->si_drv1; 885 int revents; 886 887 if (m == NULL) 888 return 0; 889 890 revents = 0; 891 892 mtx_lock(&m->lock); 893 mtx_lock(&m->qlock); 894 895 if (events & (POLLIN | POLLRDNORM)) 896 if (!MIDIQ_EMPTY(m->inq)) 897 events |= events & (POLLIN | POLLRDNORM); 898 899 if (events & (POLLOUT | POLLWRNORM)) 900 if (MIDIQ_AVAIL(m->outq) < m->hiwat) 901 events |= events & (POLLOUT | POLLWRNORM); 902 903 if (revents == 0) { 904 if (events & (POLLIN | POLLRDNORM)) 905 selrecord(td, &m->rsel); 906 907 if (events & (POLLOUT | POLLWRNORM)) 908 selrecord(td, &m->wsel); 909 } 910 mtx_unlock(&m->lock); 911 mtx_unlock(&m->qlock); 912 913 return (revents); 914} 915 916/* 917 * /dev/midistat device functions 918 * 919 */ 920static int 921midistat_open(struct cdev *i_dev, int flags, int mode, struct thread * td) 922{ 923 int error; 924 925 MIDI_DEBUG(1,printf("midistat_open\n")); 926 mtx_lock(&midistat_lock); 927 928 if (midistat_isopen) { 929 mtx_unlock(&midistat_lock); 930 return EBUSY; 931 } 932 midistat_isopen = 1; 933 mtx_unlock(&midistat_lock); 934 935 if (sbuf_new(&midistat_sbuf, NULL, 4096, SBUF_AUTOEXTEND) == NULL) { 936 error = ENXIO; 937 mtx_lock(&midistat_lock); 938 goto out; 939 } 940 941 mtx_lock(&midistat_lock); 942 midistat_bufptr = 0; 943 error = (midistat_prepare(&midistat_sbuf) > 0) ? 0 : ENOMEM; 944 945out: if (error) 946 midistat_isopen = 0; 947 mtx_unlock(&midistat_lock); 948 return error; 949} 950 951static int 952midistat_close(struct cdev *i_dev, int flags, int mode, struct thread * td) 953{ 954 MIDI_DEBUG(1,printf("midistat_close\n")); 955 mtx_lock(&midistat_lock); 956 if (!midistat_isopen) { 957 mtx_unlock(&midistat_lock); 958 return EBADF; 959 } 960 sbuf_delete(&midistat_sbuf); 961 midistat_isopen = 0; 962 963 mtx_unlock(&midistat_lock); 964 return 0; 965} 966 967static int 968midistat_read(struct cdev *i_dev, struct uio * buf, int flag) 969{ 970 int l, err; 971 972 MIDI_DEBUG(4,printf("midistat_read\n")); 973 mtx_lock(&midistat_lock); 974 if (!midistat_isopen) { 975 mtx_unlock(&midistat_lock); 976 return EBADF; 977 } 978 l = min(buf->uio_resid, sbuf_len(&midistat_sbuf) - midistat_bufptr); 979 err = 0; 980 if (l > 0) { 981 mtx_unlock(&midistat_lock); 982 err = uiomove(sbuf_data(&midistat_sbuf) + midistat_bufptr, l, buf); 983 mtx_lock(&midistat_lock); 984 } else 985 l = 0; 986 midistat_bufptr += l; 987 mtx_unlock(&midistat_lock); 988 return err; 989} 990 991/* 992 * Module library functions 993 */ 994 995static int 996midistat_prepare(struct sbuf * s) 997{ 998 struct snd_midi *m; 999 1000 mtx_assert(&midistat_lock, MA_OWNED); 1001 1002 sbuf_printf(s, "FreeBSD Midi Driver (midi2)\n"); 1003 if (TAILQ_EMPTY(&midi_devs)) { 1004 sbuf_printf(s, "No devices installed.\n"); 1005 sbuf_finish(s); 1006 return sbuf_len(s); 1007 } 1008 sbuf_printf(s, "Installed devices:\n"); 1009 1010 TAILQ_FOREACH(m, &midi_devs, link) { 1011 mtx_lock(&m->lock); 1012 sbuf_printf(s, "%s [%d/%d:%s]", m->name, m->unit, m->channel, 1013 MPU_PROVIDER(m, m->cookie)); 1014 sbuf_printf(s, "%s", MPU_DESCR(m, m->cookie, midistat_verbose)); 1015 sbuf_printf(s, "\n"); 1016 mtx_unlock(&m->lock); 1017 } 1018 1019 sbuf_finish(s); 1020 return sbuf_len(s); 1021} 1022 1023#ifdef notdef 1024/* 1025 * Convert IOCTL command to string for debugging 1026 */ 1027 1028static char * 1029midi_cmdname(int cmd) 1030{ 1031 static struct { 1032 int cmd; 1033 char *name; 1034 } *tab, cmdtab_midiioctl[] = { 1035#define A(x) {x, ## x} 1036 /* 1037 * Once we have some real IOCTLs define, the following will 1038 * be relavant. 1039 * 1040 * A(SNDCTL_MIDI_PRETIME), A(SNDCTL_MIDI_MPUMODE), 1041 * A(SNDCTL_MIDI_MPUCMD), A(SNDCTL_SYNTH_INFO), 1042 * A(SNDCTL_MIDI_INFO), A(SNDCTL_SYNTH_MEMAVL), 1043 * A(SNDCTL_FM_LOAD_INSTR), A(SNDCTL_FM_4OP_ENABLE), 1044 * A(MIOSPASSTHRU), A(MIOGPASSTHRU), A(AIONWRITE), 1045 * A(AIOGSIZE), A(AIOSSIZE), A(AIOGFMT), A(AIOSFMT), 1046 * A(AIOGMIX), A(AIOSMIX), A(AIOSTOP), A(AIOSYNC), 1047 * A(AIOGCAP), 1048 */ 1049#undef A 1050 { 1051 -1, "unknown" 1052 }, 1053 }; 1054 1055 for (tab = cmdtab_midiioctl; tab->cmd != cmd && tab->cmd != -1; tab++) 1056 ; 1057 return tab->name; 1058} 1059#endif /* notdef */ 1060 1061/* 1062 * midisynth 1063 */ 1064 1065 1066int 1067midisynth_open(void *n, void *arg, int flags) 1068{ 1069 struct snd_midi *m = ((struct synth_midi * ) n)->m; 1070 int retval; 1071 1072 MIDI_DEBUG(1,printf("midisynth_open %s %s\n", 1073 flags & FREAD?"M_RX":"", flags & FWRITE?"M_TX":"")); 1074 1075 if (m == NULL) 1076 return ENXIO; 1077 1078 mtx_lock(&m->lock); 1079 mtx_lock(&m->qlock); 1080 1081 retval = 0; 1082 1083 if (flags & FREAD) { 1084 if (MIDIQ_SIZE(m->inq) == 0) 1085 retval = ENXIO; 1086 else if (m->flags & M_RX) 1087 retval = EBUSY; 1088 if (retval) 1089 goto err; 1090 } 1091 if (flags & FWRITE) { 1092 if (MIDIQ_SIZE(m->outq) == 0) 1093 retval = ENXIO; 1094 else if (m->flags & M_TX) 1095 retval = EBUSY; 1096 if (retval) 1097 goto err; 1098 } 1099 m->busy++; 1100 1101 /* 1102 * TODO: Consider m->async = 0; 1103 */ 1104 1105 if (flags & FREAD) { 1106 m->flags |= M_RX | M_RXEN; 1107 /* 1108 * Only clear the inq, the outq might still have data to drain from 1109 * a previous session 1110 */ 1111 MIDIQ_CLEAR(m->inq); 1112 m->rchan = 0; 1113 }; 1114 1115 if (flags & FWRITE) { 1116 m->flags |= M_TX; 1117 m->wchan = 0; 1118 } 1119 1120 m->synth_flags = flags & (FREAD | FWRITE); 1121 1122 MPU_CALLBACK(m, m->cookie, m->flags); 1123 1124 1125err: mtx_unlock(&m->qlock); 1126 mtx_unlock(&m->lock); 1127 MIDI_DEBUG(2, printf("midisynth_open: return %d.\n", retval)); 1128 return retval; 1129} 1130 1131int 1132midisynth_close(void *n) 1133{ 1134 struct snd_midi *m = ((struct synth_midi *)n)->m; 1135 int retval; 1136 int oldflags; 1137 1138 MIDI_DEBUG(1, printf("midisynth_close %s %s\n", 1139 m->synth_flags & FREAD ? "M_RX" : "", 1140 m->synth_flags & FWRITE ? "M_TX" : "")); 1141 1142 if (m == NULL) 1143 return ENXIO; 1144 1145 mtx_lock(&m->lock); 1146 mtx_lock(&m->qlock); 1147 1148 if ( (m->synth_flags & FREAD && !(m->flags & M_RX)) || 1149 (m->synth_flags & FWRITE && !(m->flags & M_TX)) ) { 1150 retval = ENXIO; 1151 goto err; 1152 } 1153 1154 m->busy--; 1155 1156 oldflags = m->flags; 1157 1158 if (m->synth_flags & FREAD) 1159 m->flags &= ~(M_RX | M_RXEN); 1160 if (m->synth_flags & FWRITE) 1161 m->flags &= ~M_TX; 1162 1163 if( (m->flags & (M_TXEN | M_RXEN)) != (oldflags & (M_RXEN | M_TXEN)) ) 1164 MPU_CALLBACK(m, m->cookie, m->flags); 1165 1166 MIDI_DEBUG(1, printf("midi_close: closed, busy = %d.\n", m->busy)); 1167 1168 mtx_unlock(&m->qlock); 1169 mtx_unlock(&m->lock); 1170 retval = 0; 1171err: return retval; 1172} 1173 1174/* 1175 * Always blocking. 1176 */ 1177 1178int 1179midisynth_writeraw(void *n, uint8_t *buf, size_t len) 1180{ 1181 struct snd_midi *m = ((struct synth_midi *)n)->m; 1182 int retval; 1183 int used; 1184 int i; 1185 1186 MIDI_DEBUG(4, printf("midisynth_writeraw\n")); 1187 1188 retval = 0; 1189 1190 if (m == NULL) 1191 return ENXIO; 1192 1193 mtx_lock(&m->lock); 1194 mtx_lock(&m->qlock); 1195 1196 if (!(m->flags & M_TX)) 1197 goto err1; 1198 1199 if (midi_dumpraw) 1200 printf("midi dump: "); 1201 1202 while (len > 0) { 1203 while (MIDIQ_AVAIL(m->outq) == 0) { 1204 if (!(m->flags & M_TXEN)) { 1205 m->flags |= M_TXEN; 1206 MPU_CALLBACK(m, m->cookie, m->flags); 1207 } 1208 mtx_unlock(&m->lock); 1209 m->wchan = 1; 1210 MIDI_DEBUG(3,printf("midisynth_writeraw msleep\n")); 1211 retval = msleep(&m->wchan, &m->qlock, 1212 PCATCH | PDROP, "midi TX", 0); 1213 /* 1214 * We slept, maybe things have changed since last 1215 * dying check 1216 */ 1217 if (retval == EINTR) 1218 goto err0; 1219 1220 if (retval) 1221 goto err0; 1222 mtx_lock(&m->lock); 1223 mtx_lock(&m->qlock); 1224 m->wchan = 0; 1225 if (!m->busy) 1226 goto err1; 1227 } 1228 1229 /* 1230 * We are certain than data can be placed on the queue 1231 */ 1232 1233 used = MIN(MIDIQ_AVAIL(m->outq), len); 1234 used = MIN(used, MIDI_WSIZE); 1235 MIDI_DEBUG(5,printf("midi_synth: resid %zu len %jd avail %jd\n", 1236 len, (intmax_t)MIDIQ_LEN(m->outq), 1237 (intmax_t)MIDIQ_AVAIL(m->outq))); 1238 1239 if (midi_dumpraw) 1240 for(i=0;i<used;i++) printf("%x ", buf[i]); 1241 1242 MIDIQ_ENQ(m->outq, buf, used); 1243 len -= used; 1244 1245 /* 1246 * Inform the bottom half that data can be written 1247 */ 1248 if (!(m->flags & M_TXEN)) { 1249 m->flags |= M_TXEN; 1250 MPU_CALLBACK(m, m->cookie, m->flags); 1251 } 1252 } 1253 /* 1254 * If we Made it here then transfer is good 1255 */ 1256 if (midi_dumpraw) 1257 printf("\n"); 1258 1259 retval = 0; 1260err1: mtx_unlock(&m->qlock); 1261 mtx_unlock(&m->lock); 1262err0: return retval; 1263} 1264 1265static int 1266midisynth_killnote(void *n, uint8_t chn, uint8_t note, uint8_t vel) 1267{ 1268 u_char c[3]; 1269 1270 1271 if (note > 127 || chn > 15) 1272 return (EINVAL); 1273 1274 if (vel > 127) 1275 vel = 127; 1276 1277 if (vel == 64) { 1278 c[0] = 0x90 | (chn & 0x0f); /* Note on. */ 1279 c[1] = (u_char)note; 1280 c[2] = 0; 1281 } else { 1282 c[0] = 0x80 | (chn & 0x0f); /* Note off. */ 1283 c[1] = (u_char)note; 1284 c[2] = (u_char)vel; 1285 } 1286 1287 return midisynth_writeraw(n, c, 3); 1288} 1289 1290static int 1291midisynth_setinstr(void *n, uint8_t chn, uint16_t instr) 1292{ 1293 u_char c[2]; 1294 1295 if (instr > 127 || chn > 15) 1296 return EINVAL; 1297 1298 c[0] = 0xc0 | (chn & 0x0f); /* Progamme change. */ 1299 c[1] = instr + midi_instroff; 1300 1301 return midisynth_writeraw(n, c, 2); 1302} 1303 1304static int 1305midisynth_startnote(void *n, uint8_t chn, uint8_t note, uint8_t vel) 1306{ 1307 u_char c[3]; 1308 1309 if (note > 127 || chn > 15) 1310 return EINVAL; 1311 1312 if (vel > 127) 1313 vel = 127; 1314 1315 c[0] = 0x90 | (chn & 0x0f); /* Note on. */ 1316 c[1] = (u_char)note; 1317 c[2] = (u_char)vel; 1318 1319 return midisynth_writeraw(n, c, 3); 1320} 1321static int 1322midisynth_alloc(void *n, uint8_t chan, uint8_t note) 1323{ 1324 return chan; 1325} 1326 1327static int 1328midisynth_controller(void *n, uint8_t chn, uint8_t ctrlnum, uint16_t val) 1329{ 1330 u_char c[3]; 1331 1332 if (ctrlnum > 127 || chn > 15) 1333 return EINVAL; 1334 1335 c[0] = 0xb0 | (chn & 0x0f); /* Control Message. */ 1336 c[1] = ctrlnum; 1337 c[2] = val; 1338 return midisynth_writeraw(n, c, 3); 1339} 1340 1341static int 1342midisynth_bender(void *n, uint8_t chn, uint16_t val) 1343{ 1344 u_char c[3]; 1345 1346 1347 if (val > 16383 || chn > 15) 1348 return EINVAL; 1349 1350 c[0] = 0xe0 | (chn & 0x0f); /* Pitch bend. */ 1351 c[1] = (u_char)val & 0x7f; 1352 c[2] = (u_char)(val >> 7) & 0x7f; 1353 1354 return midisynth_writeraw(n, c, 3); 1355} 1356 1357/* 1358 * Single point of midi destructions. 1359 */ 1360static int 1361midi_destroy(struct snd_midi * m, int midiuninit) 1362{ 1363 1364 mtx_assert(&midistat_lock, MA_OWNED); 1365 mtx_assert(&m->lock, MA_OWNED); 1366 1367 MIDI_DEBUG(3,printf("midi_destroy\n")); 1368 m->dev->si_drv1 = NULL; 1369 destroy_dev(m->dev); 1370 TAILQ_REMOVE(&midi_devs, m, link); 1371 if (midiuninit) 1372 MPU_UNINIT(m, m->cookie); 1373 free(MIDIQ_BUF(m->inq), M_MIDI); 1374 free(MIDIQ_BUF(m->outq), M_MIDI); 1375 mtx_destroy(&m->qlock); 1376 mtx_destroy(&m->lock); 1377 free(m, M_MIDI); 1378 return 0; 1379} 1380 1381/* 1382 * Load and unload functions, creates the /dev/midistat device 1383 */ 1384 1385static int 1386midi_load() 1387{ 1388 mtx_init(&midistat_lock, "midistat lock", 0, 0); 1389 TAILQ_INIT(&midi_devs); /* Initialize the queue. */ 1390 1391 midistat_dev = make_dev(&midistat_cdevsw, 1392 MIDIMKMINOR(0, MIDI_DEV_MIDICTL, 0), 1393 UID_ROOT, GID_WHEEL, 0666, "midistat"); 1394 1395 return 0; 1396} 1397 1398static int 1399midi_unload() 1400{ 1401 struct snd_midi *m; 1402 int retval; 1403 1404 MIDI_DEBUG(1,printf("midi_unload()\n")); 1405 retval = EBUSY; 1406 mtx_lock(&midistat_lock); 1407 if (midistat_isopen) 1408 goto exit0; 1409 1410 TAILQ_FOREACH(m, &midi_devs, link) { 1411 mtx_lock(&m->lock); 1412 if (m->busy) 1413 retval = EBUSY; 1414 else 1415 retval = midi_destroy(m, 1); 1416 if (retval) 1417 goto exit1; 1418 } 1419 1420 destroy_dev(midistat_dev); 1421 /* 1422 * Made it here then unload is complete 1423 */ 1424 mtx_destroy(&midistat_lock); 1425 return 0; 1426 1427exit1: 1428 mtx_unlock(&m->lock); 1429exit0: 1430 mtx_unlock(&midistat_lock); 1431 if(retval) MIDI_DEBUG(2,printf("midi_unload: failed\n")); 1432 return retval; 1433} 1434 1435extern int seq_modevent(module_t mod, int type, void *data); 1436 1437static int 1438midi_modevent(module_t mod, int type, void *data) 1439{ 1440 int retval; 1441 1442 retval = 0; 1443 1444 switch (type) { 1445 case MOD_LOAD: 1446 retval = midi_load(); 1447 if (retval == 0) 1448 retval = seq_modevent(mod, type, data); 1449 break; 1450 1451 case MOD_UNLOAD: 1452 retval = midi_unload(); 1453 if (retval == 0) 1454 retval = seq_modevent(mod, type, data); 1455 break; 1456 1457 default: 1458 break; 1459 } 1460 1461 return retval; 1462} 1463 1464kobj_t 1465midimapper_addseq(void *arg1, int *unit, void **cookie) 1466{ 1467 unit = 0; 1468 1469 return (kobj_t) arg1; 1470} 1471 1472int 1473midimapper_open(void *arg1, void **cookie) 1474{ 1475 int retval = 0; 1476 struct snd_midi *m; 1477 1478 mtx_lock(&midistat_lock); 1479 1480 TAILQ_FOREACH(m, &midi_devs, link) { 1481 retval++; 1482 } 1483 1484 mtx_unlock(&midistat_lock); 1485 return retval; 1486} 1487 1488int 1489midimapper_close(void *arg1, void *cookie) 1490{ 1491 return 0; 1492} 1493 1494kobj_t 1495midimapper_fetch_synth(void *arg, void *cookie, int unit) 1496{ 1497 struct snd_midi *m; 1498 int retval = 0; 1499 1500 mtx_lock(&midistat_lock); 1501 1502 TAILQ_FOREACH(m, &midi_devs, link) { 1503 if (unit == retval) { 1504 mtx_unlock(&midistat_lock); 1505 return (kobj_t)m->synth; 1506 } 1507 retval++; 1508 } 1509 1510 mtx_unlock(&midistat_lock); 1511 return NULL; 1512} 1513 1514DEV_MODULE(midi, midi_modevent, NULL); 1515MODULE_VERSION(midi, 1);
|