1 /* $NetBSD: sequencer.c,v 1.52 2009/03/18 10:22:39 cegger Exp $ */ 2 3 /* 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Lennart Augustsson (augustss@NetBSD.org). 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: sequencer.c,v 1.52 2009/03/18 10:22:39 cegger Exp $"); 34 35 #include "sequencer.h" 36 37 #include <sys/param.h> 38 #include <sys/ioctl.h> 39 #include <sys/fcntl.h> 40 #include <sys/vnode.h> 41 #include <sys/select.h> 42 #include <sys/poll.h> 43 #include <sys/malloc.h> 44 #include <sys/proc.h> 45 #include <sys/systm.h> 46 #include <sys/syslog.h> 47 #include <sys/kernel.h> 48 #include <sys/signalvar.h> 49 #include <sys/conf.h> 50 #include <sys/audioio.h> 51 #include <sys/midiio.h> 52 #include <sys/device.h> 53 #include <sys/intr.h> 54 55 #include <dev/midi_if.h> 56 #include <dev/midivar.h> 57 #include <dev/sequencervar.h> 58 59 #define ADDTIMEVAL(a, b) ( \ 60 (a)->tv_sec += (b)->tv_sec, \ 61 (a)->tv_usec += (b)->tv_usec, \ 62 (a)->tv_usec > 1000000 ? ((a)->tv_sec++, (a)->tv_usec -= 1000000) : 0\ 63 ) 64 65 #define SUBTIMEVAL(a, b) ( \ 66 (a)->tv_sec -= (b)->tv_sec, \ 67 (a)->tv_usec -= (b)->tv_usec, \ 68 (a)->tv_usec < 0 ? ((a)->tv_sec--, (a)->tv_usec += 1000000) : 0\ 69 ) 70 71 #ifdef AUDIO_DEBUG 72 #define DPRINTF(x) if (sequencerdebug) printf x 73 #define DPRINTFN(n,x) if (sequencerdebug >= (n)) printf x 74 int sequencerdebug = 0; 75 #else 76 #define DPRINTF(x) 77 #define DPRINTFN(n,x) 78 #endif 79 80 #define SEQ_NOTE_MAX 128 81 #define SEQ_NOTE_XXX 255 82 83 #define RECALC_USPERDIV(t) \ 84 ((t)->usperdiv = 60*1000000L/((t)->tempo_beatpermin*(t)->timebase_divperbeat)) 85 86 struct sequencer_softc seqdevs[NSEQUENCER]; 87 88 void sequencerattach(int); 89 static void seq_reset(struct sequencer_softc *); 90 static int seq_do_command(struct sequencer_softc *, seq_event_t *); 91 static int seq_do_chnvoice(struct sequencer_softc *, seq_event_t *); 92 static int seq_do_chncommon(struct sequencer_softc *, seq_event_t *); 93 static void seq_timer_waitabs(struct sequencer_softc *, uint32_t); 94 static int seq_do_timing(struct sequencer_softc *, seq_event_t *); 95 static int seq_do_local(struct sequencer_softc *, seq_event_t *); 96 static int seq_do_sysex(struct sequencer_softc *, seq_event_t *); 97 static int seq_do_fullsize(struct sequencer_softc *, seq_event_t *, struct uio *); 98 static int seq_input_event(struct sequencer_softc *, seq_event_t *); 99 static int seq_drain(struct sequencer_softc *); 100 static void seq_startoutput(struct sequencer_softc *); 101 static void seq_timeout(void *); 102 static int seq_to_new(seq_event_t *, struct uio *); 103 static int seq_sleep_timo(int *, const char *, int); 104 static int seq_sleep(int *, const char *); 105 static void seq_wakeup(int *); 106 static void seq_softintr(void *); 107 108 struct midi_softc; 109 static int midiseq_out(struct midi_dev *, u_char *, u_int, int); 110 static struct midi_dev *midiseq_open(int, int); 111 static void midiseq_close(struct midi_dev *); 112 static void midiseq_reset(struct midi_dev *); 113 static int midiseq_noteon(struct midi_dev *, int, int, seq_event_t *); 114 static int midiseq_noteoff(struct midi_dev *, int, int, seq_event_t *); 115 static int midiseq_keypressure(struct midi_dev *, int, int, seq_event_t *); 116 static int midiseq_pgmchange(struct midi_dev *, int, seq_event_t *); 117 static int midiseq_chnpressure(struct midi_dev *, int, seq_event_t *); 118 static int midiseq_ctlchange(struct midi_dev *, int, seq_event_t *); 119 static int midiseq_pitchbend(struct midi_dev *, int, seq_event_t *); 120 static int midiseq_loadpatch(struct midi_dev *, struct sysex_info *, struct uio *); 121 void midiseq_in(struct midi_dev *, u_char *, int); 122 123 static dev_type_open(sequenceropen); 124 static dev_type_close(sequencerclose); 125 static dev_type_read(sequencerread); 126 static dev_type_write(sequencerwrite); 127 static dev_type_ioctl(sequencerioctl); 128 static dev_type_poll(sequencerpoll); 129 static dev_type_kqfilter(sequencerkqfilter); 130 131 const struct cdevsw sequencer_cdevsw = { 132 sequenceropen, sequencerclose, sequencerread, sequencerwrite, 133 sequencerioctl, nostop, notty, sequencerpoll, nommap, 134 sequencerkqfilter, D_OTHER, 135 }; 136 137 void 138 sequencerattach(int n) 139 { 140 struct sequencer_softc *sc; 141 142 for (n = 0; n < NSEQUENCER; n++) { 143 sc = &seqdevs[n]; 144 callout_init(&sc->sc_callout, 0); 145 sc->sih = softint_establish(SOFTINT_SERIAL, seq_softintr, sc); 146 } 147 } 148 149 static int 150 sequenceropen(dev_t dev, int flags, int ifmt, struct lwp *l) 151 { 152 int unit = SEQUENCERUNIT(dev); 153 struct sequencer_softc *sc; 154 struct midi_dev *md; 155 int nmidi; 156 157 DPRINTF(("sequenceropen\n")); 158 159 if (unit >= NSEQUENCER) 160 return (ENXIO); 161 sc = &seqdevs[unit]; 162 if (sc->isopen) 163 return EBUSY; 164 if (SEQ_IS_OLD(unit)) 165 sc->mode = SEQ_OLD; 166 else 167 sc->mode = SEQ_NEW; 168 sc->isopen++; 169 sc->flags = flags & (FREAD|FWRITE); 170 sc->rchan = 0; 171 sc->wchan = 0; 172 sc->pbus = 0; 173 sc->async = 0; 174 sc->input_stamp = ~0; 175 176 sc->nmidi = 0; 177 nmidi = midi_unit_count(); 178 179 sc->devs = malloc(nmidi * sizeof(struct midi_dev *), 180 M_DEVBUF, M_WAITOK); 181 for (unit = 0; unit < nmidi; unit++) { 182 md = midiseq_open(unit, flags); 183 if (md) { 184 sc->devs[sc->nmidi++] = md; 185 md->seq = sc; 186 md->doingsysex = 0; 187 } 188 } 189 190 sc->timer.timebase_divperbeat = 100; 191 sc->timer.tempo_beatpermin = 60; 192 RECALC_USPERDIV(&sc->timer); 193 sc->timer.divs_lastevent = sc->timer.divs_lastchange = 0; 194 microtime(&sc->timer.reftime); 195 196 SEQ_QINIT(&sc->inq); 197 SEQ_QINIT(&sc->outq); 198 sc->lowat = SEQ_MAXQ / 2; 199 200 seq_reset(sc); 201 202 DPRINTF(("sequenceropen: mode=%d, nmidi=%d\n", sc->mode, sc->nmidi)); 203 return 0; 204 } 205 206 static int 207 seq_sleep_timo(int *chan, const char *label, int timo) 208 { 209 int st; 210 211 if (!label) 212 label = "seq"; 213 214 DPRINTFN(5, ("seq_sleep_timo: %p %s %d\n", chan, label, timo)); 215 *chan = 1; 216 st = tsleep(chan, PWAIT | PCATCH, label, timo); 217 *chan = 0; 218 #ifdef MIDI_DEBUG 219 if (st != 0) 220 printf("seq_sleep: %d\n", st); 221 #endif 222 return st; 223 } 224 225 static int 226 seq_sleep(int *chan, const char *label) 227 { 228 return seq_sleep_timo(chan, label, 0); 229 } 230 231 static void 232 seq_wakeup(int *chan) 233 { 234 if (*chan) { 235 DPRINTFN(5, ("seq_wakeup: %p\n", chan)); 236 wakeup(chan); 237 *chan = 0; 238 } 239 } 240 241 static int 242 seq_drain(struct sequencer_softc *sc) 243 { 244 int error; 245 246 DPRINTFN(3, ("seq_drain: %p, len=%d\n", sc, SEQ_QLEN(&sc->outq))); 247 seq_startoutput(sc); 248 error = 0; 249 while(!SEQ_QEMPTY(&sc->outq) && !error) 250 error = seq_sleep_timo(&sc->wchan, "seq_dr", 60*hz); 251 return (error); 252 } 253 254 static void 255 seq_timeout(void *addr) 256 { 257 struct sequencer_softc *sc = addr; 258 struct proc *p; 259 260 DPRINTFN(4, ("seq_timeout: %p\n", sc)); 261 sc->timeout = 0; 262 seq_startoutput(sc); 263 if (SEQ_QLEN(&sc->outq) < sc->lowat) { 264 seq_wakeup(&sc->wchan); 265 selnotify(&sc->wsel, 0, 0); 266 if (sc->async != NULL) { 267 mutex_enter(proc_lock); 268 if ((p = sc->async) != NULL) 269 psignal(p, SIGIO); 270 mutex_exit(proc_lock); 271 } 272 } 273 274 } 275 276 static void 277 seq_startoutput(struct sequencer_softc *sc) 278 { 279 struct sequencer_queue *q = &sc->outq; 280 seq_event_t cmd; 281 282 if (sc->timeout) 283 return; 284 DPRINTFN(4, ("seq_startoutput: %p, len=%d\n", sc, SEQ_QLEN(q))); 285 while(!SEQ_QEMPTY(q) && !sc->timeout) { 286 SEQ_QGET(q, cmd); 287 seq_do_command(sc, &cmd); 288 } 289 } 290 291 static int 292 sequencerclose(dev_t dev, int flags, int ifmt, 293 struct lwp *l) 294 { 295 struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)]; 296 int n, s; 297 298 DPRINTF(("sequencerclose: %p\n", sc)); 299 300 seq_drain(sc); 301 s = splaudio(); 302 if (sc->timeout) { 303 callout_stop(&sc->sc_callout); 304 sc->timeout = 0; 305 } 306 splx(s); 307 308 for (n = 0; n < sc->nmidi; n++) 309 midiseq_close(sc->devs[n]); 310 free(sc->devs, M_DEVBUF); 311 sc->isopen = 0; 312 return (0); 313 } 314 315 static void 316 seq_softintr(void *cookie) 317 { 318 struct sequencer_softc *sc = cookie; 319 struct proc *p; 320 321 seq_wakeup(&sc->rchan); 322 selnotify(&sc->rsel, 0, 0); 323 if (sc->async != NULL) { 324 mutex_enter(proc_lock); 325 if ((p = sc->async) != NULL) 326 psignal(p, SIGIO); 327 mutex_exit(proc_lock); 328 } 329 } 330 331 static int 332 seq_input_event(struct sequencer_softc *sc, seq_event_t *cmd) 333 { 334 struct sequencer_queue *q = &sc->inq; 335 336 DPRINTFN(2, ("seq_input_event: %02x %02x %02x %02x %02x %02x %02x %02x\n", 337 cmd->tag, 338 cmd->unknown.byte[0], cmd->unknown.byte[1], 339 cmd->unknown.byte[2], cmd->unknown.byte[3], 340 cmd->unknown.byte[4], cmd->unknown.byte[5], 341 cmd->unknown.byte[6])); 342 if (SEQ_QFULL(q)) 343 return (ENOMEM); 344 SEQ_QPUT(q, *cmd); 345 softint_schedule(sc->sih); 346 return 0; 347 } 348 349 void 350 seq_event_intr(void *addr, seq_event_t *iev) 351 { 352 struct sequencer_softc *sc = addr; 353 u_long t; 354 struct timeval now; 355 int s; 356 357 microtime(&now); 358 s = splsoftclock(); 359 if (!sc->timer.running) 360 now = sc->timer.stoptime; 361 SUBTIMEVAL(&now, &sc->timer.reftime); 362 t = now.tv_sec * 1000000 + now.tv_usec; 363 t /= sc->timer.usperdiv; 364 t += sc->timer.divs_lastchange; 365 splx(s); 366 if (t != sc->input_stamp) { 367 seq_input_event(sc, &SEQ_MK_TIMING(WAIT_ABS, .divisions=t)); 368 sc->input_stamp = t; /* XXX wha hoppen if timer is reset? */ 369 } 370 seq_input_event(sc, iev); 371 } 372 373 static int 374 sequencerread(dev_t dev, struct uio *uio, int ioflag) 375 { 376 struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)]; 377 struct sequencer_queue *q = &sc->inq; 378 seq_event_t ev; 379 int error, s; 380 381 DPRINTFN(20, ("sequencerread: %p, count=%d, ioflag=%x\n", 382 sc, (int) uio->uio_resid, ioflag)); 383 384 if (sc->mode == SEQ_OLD) { 385 DPRINTFN(-1,("sequencerread: old read\n")); 386 return (EINVAL); /* XXX unimplemented */ 387 } 388 389 error = 0; 390 while (SEQ_QEMPTY(q)) { 391 if (ioflag & IO_NDELAY) 392 return EWOULDBLOCK; 393 else { 394 error = seq_sleep(&sc->rchan, "seq rd"); 395 if (error) 396 return error; 397 } 398 } 399 s = splaudio(); 400 while (uio->uio_resid >= sizeof ev && !error && !SEQ_QEMPTY(q)) { 401 SEQ_QGET(q, ev); 402 error = uiomove(&ev, sizeof ev, uio); 403 } 404 splx(s); 405 return error; 406 } 407 408 static int 409 sequencerwrite(dev_t dev, struct uio *uio, int ioflag) 410 { 411 struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)]; 412 struct sequencer_queue *q = &sc->outq; 413 int error; 414 seq_event_t cmdbuf; 415 int size; 416 417 DPRINTFN(2, ("sequencerwrite: %p, count=%d\n", sc, (int) uio->uio_resid)); 418 419 error = 0; 420 size = sc->mode == SEQ_NEW ? sizeof cmdbuf : SEQOLD_CMDSIZE; 421 while (uio->uio_resid >= size) { 422 error = uiomove(&cmdbuf, size, uio); 423 if (error) 424 break; 425 if (sc->mode == SEQ_OLD) 426 if (seq_to_new(&cmdbuf, uio)) 427 continue; 428 if (cmdbuf.tag == SEQ_FULLSIZE) { 429 /* We do it like OSS does, asynchronously */ 430 error = seq_do_fullsize(sc, &cmdbuf, uio); 431 if (error) 432 break; 433 continue; 434 } 435 while (SEQ_QFULL(q)) { 436 seq_startoutput(sc); 437 if (SEQ_QFULL(q)) { 438 if (ioflag & IO_NDELAY) 439 return EWOULDBLOCK; 440 error = seq_sleep(&sc->wchan, "seq_wr"); 441 if (error) 442 return error; 443 } 444 } 445 SEQ_QPUT(q, cmdbuf); 446 } 447 seq_startoutput(sc); 448 449 #ifdef SEQUENCER_DEBUG 450 if (error) 451 DPRINTFN(2, ("sequencerwrite: error=%d\n", error)); 452 #endif 453 return error; 454 } 455 456 static int 457 sequencerioctl(dev_t dev, u_long cmd, void *addr, int flag, 458 struct lwp *l) 459 { 460 struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)]; 461 struct synth_info *si; 462 struct midi_dev *md; 463 int devno; 464 int error; 465 int s; 466 int t; 467 468 DPRINTFN(2, ("sequencerioctl: %p cmd=0x%08lx\n", sc, cmd)); 469 470 error = 0; 471 switch (cmd) { 472 case FIONBIO: 473 /* All handled in the upper FS layer. */ 474 break; 475 476 case FIOASYNC: 477 if (*(int *)addr) { 478 if (sc->async) 479 return EBUSY; 480 sc->async = l->l_proc; 481 DPRINTF(("sequencer_ioctl: FIOASYNC %p\n", l)); 482 } else 483 sc->async = 0; 484 break; 485 486 case SEQUENCER_RESET: 487 seq_reset(sc); 488 break; 489 490 case SEQUENCER_PANIC: 491 seq_reset(sc); 492 /* Do more? OSS doesn't */ 493 break; 494 495 case SEQUENCER_SYNC: 496 if (sc->flags == FREAD) 497 return 0; 498 seq_drain(sc); 499 error = 0; 500 break; 501 502 case SEQUENCER_INFO: 503 si = (struct synth_info*)addr; 504 devno = si->device; 505 if (devno < 0 || devno >= sc->nmidi) 506 return EINVAL; 507 md = sc->devs[devno]; 508 strncpy(si->name, md->name, sizeof si->name); 509 si->synth_type = SYNTH_TYPE_MIDI; 510 si->synth_subtype = md->subtype; 511 si->nr_voices = md->nr_voices; 512 si->instr_bank_size = md->instr_bank_size; 513 si->capabilities = md->capabilities; 514 break; 515 516 case SEQUENCER_NRSYNTHS: 517 *(int *)addr = sc->nmidi; 518 break; 519 520 case SEQUENCER_NRMIDIS: 521 *(int *)addr = sc->nmidi; 522 break; 523 524 case SEQUENCER_OUTOFBAND: 525 DPRINTFN(3, ("sequencer_ioctl: OOB=%02x %02x %02x %02x %02x %02x %02x %02x\n", 526 *(u_char *)addr, *((u_char *)addr+1), 527 *((u_char *)addr+2), *((u_char *)addr+3), 528 *((u_char *)addr+4), *((u_char *)addr+5), 529 *((u_char *)addr+6), *((u_char *)addr+7))); 530 if ( !(sc->flags & FWRITE ) ) 531 return EBADF; 532 error = seq_do_command(sc, (seq_event_t *)addr); 533 break; 534 535 case SEQUENCER_TMR_TIMEBASE: 536 t = *(int *)addr; 537 if (t < 1) 538 t = 1; 539 if (t > 10000) 540 t = 10000; 541 *(int *)addr = t; 542 s = splsoftclock(); 543 sc->timer.timebase_divperbeat = t; 544 sc->timer.divs_lastchange = sc->timer.divs_lastevent; 545 microtime(&sc->timer.reftime); 546 RECALC_USPERDIV(&sc->timer); 547 splx(s); 548 break; 549 550 case SEQUENCER_TMR_START: 551 s = splsoftclock(); 552 error = seq_do_timing(sc, &SEQ_MK_TIMING(START)); 553 splx(s); 554 break; 555 556 case SEQUENCER_TMR_STOP: 557 s = splsoftclock(); 558 error = seq_do_timing(sc, &SEQ_MK_TIMING(STOP)); 559 splx(s); 560 break; 561 562 case SEQUENCER_TMR_CONTINUE: 563 s = splsoftclock(); 564 error = seq_do_timing(sc, &SEQ_MK_TIMING(CONTINUE)); 565 splx(s); 566 break; 567 568 case SEQUENCER_TMR_TEMPO: 569 s = splsoftclock(); 570 error = seq_do_timing(sc, 571 &SEQ_MK_TIMING(TEMPO, .bpm=*(int *)addr)); 572 splx(s); 573 if (!error) 574 *(int *)addr = sc->timer.tempo_beatpermin; 575 break; 576 577 case SEQUENCER_TMR_SOURCE: 578 *(int *)addr = SEQUENCER_TMR_INTERNAL; 579 break; 580 581 case SEQUENCER_TMR_METRONOME: 582 /* noop */ 583 break; 584 585 case SEQUENCER_THRESHOLD: 586 t = SEQ_MAXQ - *(int *)addr / sizeof (seq_event_rec); 587 if (t < 1) 588 t = 1; 589 if (t > SEQ_MAXQ) 590 t = SEQ_MAXQ; 591 sc->lowat = t; 592 break; 593 594 case SEQUENCER_CTRLRATE: 595 s = splsoftclock(); 596 *(int *)addr = (sc->timer.tempo_beatpermin 597 *sc->timer.timebase_divperbeat + 30) / 60; 598 splx(s); 599 break; 600 601 case SEQUENCER_GETTIME: 602 { 603 struct timeval now; 604 u_long tx; 605 microtime(&now); 606 s = splsoftclock(); 607 SUBTIMEVAL(&now, &sc->timer.reftime); 608 tx = now.tv_sec * 1000000 + now.tv_usec; 609 tx /= sc->timer.usperdiv; 610 tx += sc->timer.divs_lastchange; 611 splx(s); 612 *(int *)addr = tx; 613 break; 614 } 615 616 default: 617 DPRINTFN(-1,("sequencer_ioctl: unimpl %08lx\n", cmd)); 618 error = EINVAL; 619 break; 620 } 621 return error; 622 } 623 624 static int 625 sequencerpoll(dev_t dev, int events, struct lwp *l) 626 { 627 struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)]; 628 int revents = 0; 629 630 DPRINTF(("sequencerpoll: %p events=0x%x\n", sc, events)); 631 632 if (events & (POLLIN | POLLRDNORM)) 633 if ((sc->flags&FREAD) && !SEQ_QEMPTY(&sc->inq)) 634 revents |= events & (POLLIN | POLLRDNORM); 635 636 if (events & (POLLOUT | POLLWRNORM)) 637 if ((sc->flags&FWRITE) && SEQ_QLEN(&sc->outq) < sc->lowat) 638 revents |= events & (POLLOUT | POLLWRNORM); 639 640 if (revents == 0) { 641 if ((sc->flags&FREAD) && (events & (POLLIN | POLLRDNORM))) 642 selrecord(l, &sc->rsel); 643 644 if ((sc->flags&FWRITE) && (events & (POLLOUT | POLLWRNORM))) 645 selrecord(l, &sc->wsel); 646 } 647 648 return revents; 649 } 650 651 static void 652 filt_sequencerrdetach(struct knote *kn) 653 { 654 struct sequencer_softc *sc = kn->kn_hook; 655 int s; 656 657 s = splaudio(); 658 SLIST_REMOVE(&sc->rsel.sel_klist, kn, knote, kn_selnext); 659 splx(s); 660 } 661 662 static int 663 filt_sequencerread(struct knote *kn, long hint) 664 { 665 struct sequencer_softc *sc = kn->kn_hook; 666 667 /* XXXLUKEM (thorpej): make sure this is correct */ 668 669 if (SEQ_QEMPTY(&sc->inq)) 670 return (0); 671 kn->kn_data = sizeof(seq_event_rec); 672 return (1); 673 } 674 675 static const struct filterops sequencerread_filtops = 676 { 1, NULL, filt_sequencerrdetach, filt_sequencerread }; 677 678 static void 679 filt_sequencerwdetach(struct knote *kn) 680 { 681 struct sequencer_softc *sc = kn->kn_hook; 682 int s; 683 684 s = splaudio(); 685 SLIST_REMOVE(&sc->wsel.sel_klist, kn, knote, kn_selnext); 686 splx(s); 687 } 688 689 static int 690 filt_sequencerwrite(struct knote *kn, long hint) 691 { 692 struct sequencer_softc *sc = kn->kn_hook; 693 694 /* XXXLUKEM (thorpej): make sure this is correct */ 695 696 if (SEQ_QLEN(&sc->outq) >= sc->lowat) 697 return (0); 698 kn->kn_data = sizeof(seq_event_rec); 699 return (1); 700 } 701 702 static const struct filterops sequencerwrite_filtops = 703 { 1, NULL, filt_sequencerwdetach, filt_sequencerwrite }; 704 705 static int 706 sequencerkqfilter(dev_t dev, struct knote *kn) 707 { 708 struct sequencer_softc *sc = &seqdevs[SEQUENCERUNIT(dev)]; 709 struct klist *klist; 710 int s; 711 712 switch (kn->kn_filter) { 713 case EVFILT_READ: 714 klist = &sc->rsel.sel_klist; 715 kn->kn_fop = &sequencerread_filtops; 716 break; 717 718 case EVFILT_WRITE: 719 klist = &sc->wsel.sel_klist; 720 kn->kn_fop = &sequencerwrite_filtops; 721 break; 722 723 default: 724 return (EINVAL); 725 } 726 727 kn->kn_hook = sc; 728 729 s = splaudio(); 730 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 731 splx(s); 732 733 return (0); 734 } 735 736 static void 737 seq_reset(struct sequencer_softc *sc) 738 { 739 int i, chn; 740 struct midi_dev *md; 741 742 if ( !(sc->flags & FWRITE) ) 743 return; 744 for (i = 0; i < sc->nmidi; i++) { 745 md = sc->devs[i]; 746 midiseq_reset(md); 747 for (chn = 0; chn < MAXCHAN; chn++) { 748 midiseq_ctlchange(md, chn, &SEQ_MK_CHN(CTL_CHANGE, 749 .controller=MIDI_CTRL_NOTES_OFF)); 750 midiseq_ctlchange(md, chn, &SEQ_MK_CHN(CTL_CHANGE, 751 .controller=MIDI_CTRL_RESET)); 752 midiseq_pitchbend(md, chn, &SEQ_MK_CHN(PITCH_BEND, 753 .value=MIDI_BEND_NEUTRAL)); 754 } 755 } 756 } 757 758 static int 759 seq_do_command(struct sequencer_softc *sc, seq_event_t *b) 760 { 761 int dev; 762 763 DPRINTFN(4, ("seq_do_command: %p cmd=0x%02x\n", sc, b->timing.op)); 764 765 switch(b->tag) { 766 case SEQ_LOCAL: 767 return seq_do_local(sc, b); 768 case SEQ_TIMING: 769 return seq_do_timing(sc, b); 770 case SEQ_CHN_VOICE: 771 return seq_do_chnvoice(sc, b); 772 case SEQ_CHN_COMMON: 773 return seq_do_chncommon(sc, b); 774 case SEQ_SYSEX: 775 return seq_do_sysex(sc, b); 776 /* COMPAT */ 777 case SEQOLD_MIDIPUTC: 778 dev = b->putc.device; 779 if (dev < 0 || dev >= sc->nmidi) 780 return (ENXIO); 781 return midiseq_out(sc->devs[dev], &b->putc.byte, 1, 0); 782 default: 783 DPRINTFN(-1,("seq_do_command: unimpl command %02x\n", b->tag)); 784 return (EINVAL); 785 } 786 } 787 788 static int 789 seq_do_chnvoice(struct sequencer_softc *sc, seq_event_t *b) 790 { 791 int dev; 792 int error; 793 struct midi_dev *md; 794 795 dev = b->voice.device; 796 if (dev < 0 || dev >= sc->nmidi || 797 b->voice.channel > 15 || 798 b->voice.key >= SEQ_NOTE_MAX) 799 return ENXIO; 800 md = sc->devs[dev]; 801 switch(b->voice.op) { 802 case MIDI_NOTEON: /* no need to special-case hidden noteoff here */ 803 error = midiseq_noteon(md, b->voice.channel, b->voice.key, b); 804 break; 805 case MIDI_NOTEOFF: 806 error = midiseq_noteoff(md, b->voice.channel, b->voice.key, b); 807 break; 808 case MIDI_KEY_PRESSURE: 809 error = midiseq_keypressure(md, 810 b->voice.channel, b->voice.key, b); 811 break; 812 default: 813 DPRINTFN(-1,("seq_do_chnvoice: unimpl command %02x\n", 814 b->voice.op)); 815 error = EINVAL; 816 break; 817 } 818 return error; 819 } 820 821 static int 822 seq_do_chncommon(struct sequencer_softc *sc, seq_event_t *b) 823 { 824 int dev; 825 int error; 826 struct midi_dev *md; 827 828 dev = b->common.device; 829 if (dev < 0 || dev >= sc->nmidi || 830 b->common.channel > 15) 831 return ENXIO; 832 md = sc->devs[dev]; 833 DPRINTFN(2,("seq_do_chncommon: %02x\n", b->common.op)); 834 835 error = 0; 836 switch(b->common.op) { 837 case MIDI_PGM_CHANGE: 838 error = midiseq_pgmchange(md, b->common.channel, b); 839 break; 840 case MIDI_CTL_CHANGE: 841 error = midiseq_ctlchange(md, b->common.channel, b); 842 break; 843 case MIDI_PITCH_BEND: 844 error = midiseq_pitchbend(md, b->common.channel, b); 845 break; 846 case MIDI_CHN_PRESSURE: 847 error = midiseq_chnpressure(md, b->common.channel, b); 848 break; 849 default: 850 DPRINTFN(-1,("seq_do_chncommon: unimpl command %02x\n", 851 b->common.op)); 852 error = EINVAL; 853 break; 854 } 855 return error; 856 } 857 858 static int 859 seq_do_local(struct sequencer_softc *sc, seq_event_t *b) 860 { 861 return (EINVAL); 862 } 863 864 static int 865 seq_do_sysex(struct sequencer_softc *sc, seq_event_t *b) 866 { 867 int dev, i; 868 struct midi_dev *md; 869 uint8_t *bf = b->sysex.buffer; 870 871 dev = b->sysex.device; 872 if (dev < 0 || dev >= sc->nmidi) 873 return (ENXIO); 874 DPRINTF(("seq_do_sysex: dev=%d\n", dev)); 875 md = sc->devs[dev]; 876 877 if (!md->doingsysex) { 878 midiseq_out(md, (uint8_t[]){MIDI_SYSEX_START}, 1, 0); 879 md->doingsysex = 1; 880 } 881 882 for (i = 0; i < 6 && bf[i] != 0xff; i++) 883 ; 884 midiseq_out(md, bf, i, 0); 885 if (i < 6 || (i > 0 && bf[i-1] == MIDI_SYSEX_END)) 886 md->doingsysex = 0; 887 return 0; 888 } 889 890 static void 891 seq_timer_waitabs(struct sequencer_softc *sc, uint32_t divs) 892 { 893 struct timeval when; 894 long long usec; 895 struct syn_timer *t; 896 int ticks; 897 898 t = &sc->timer; 899 t->divs_lastevent = divs; 900 divs -= t->divs_lastchange; 901 usec = (long long)divs * (long long)t->usperdiv; /* convert to usec */ 902 when.tv_sec = usec / 1000000; 903 when.tv_usec = usec % 1000000; 904 DPRINTFN(4, ("seq_timer_waitabs: adjdivs=%d, sleep when=%"PRId64".%06"PRId64, 905 divs, when.tv_sec, (uint64_t)when.tv_usec)); 906 ADDTIMEVAL(&when, &t->reftime); /* abstime for end */ 907 ticks = tvhzto(&when); 908 DPRINTFN(4, (" when+start=%"PRId64".%06"PRId64", tick=%d\n", 909 when.tv_sec, (uint64_t)when.tv_usec, ticks)); 910 if (ticks > 0) { 911 #ifdef DIAGNOSTIC 912 if (ticks > 20 * hz) { 913 /* Waiting more than 20s */ 914 printf("seq_timer_waitabs: funny ticks=%d, " 915 "usec=%lld\n", ticks, usec); 916 } 917 #endif 918 sc->timeout = 1; 919 callout_reset(&sc->sc_callout, ticks, 920 seq_timeout, sc); 921 } 922 #ifdef SEQUENCER_DEBUG 923 else if (tick < 0) 924 DPRINTF(("seq_timer_waitabs: ticks = %d\n", ticks)); 925 #endif 926 } 927 928 static int 929 seq_do_timing(struct sequencer_softc *sc, seq_event_t *b) 930 { 931 struct syn_timer *t = &sc->timer; 932 struct timeval when; 933 int error; 934 935 error = 0; 936 switch(b->timing.op) { 937 case TMR_WAIT_REL: 938 seq_timer_waitabs(sc, 939 b->t_WAIT_REL.divisions + t->divs_lastevent); 940 break; 941 case TMR_WAIT_ABS: 942 seq_timer_waitabs(sc, b->t_WAIT_ABS.divisions); 943 break; 944 case TMR_START: 945 microtime(&t->reftime); 946 t->divs_lastevent = t->divs_lastchange = 0; 947 t->running = 1; 948 break; 949 case TMR_STOP: 950 microtime(&t->stoptime); 951 t->running = 0; 952 break; 953 case TMR_CONTINUE: 954 if (t->running) 955 break; 956 microtime(&when); 957 SUBTIMEVAL(&when, &t->stoptime); 958 ADDTIMEVAL(&t->reftime, &when); 959 t->running = 1; 960 break; 961 case TMR_TEMPO: 962 /* bpm is unambiguously MIDI clocks per minute / 24 */ 963 /* (24 MIDI clocks are usually but not always a quarter note) */ 964 if (b->t_TEMPO.bpm < 8) /* where are these limits specified? */ 965 t->tempo_beatpermin = 8; 966 else if (b->t_TEMPO.bpm > 360) /* ? */ 967 t->tempo_beatpermin = 360; 968 else 969 t->tempo_beatpermin = b->t_TEMPO.bpm; 970 t->divs_lastchange = t->divs_lastevent; 971 microtime(&t->reftime); 972 RECALC_USPERDIV(t); 973 break; 974 case TMR_ECHO: 975 error = seq_input_event(sc, b); 976 break; 977 case TMR_RESET: 978 t->divs_lastevent = t->divs_lastchange = 0; 979 microtime(&t->reftime); 980 break; 981 case TMR_SPP: 982 case TMR_TIMESIG: 983 DPRINTF(("seq_do_timing: unimplemented %02x\n", b->timing.op)); 984 error = EINVAL; /* not quite accurate... */ 985 break; 986 default: 987 DPRINTF(("seq_timer: unknown %02x\n", b->timing.op)); 988 error = EINVAL; 989 break; 990 } 991 return (error); 992 } 993 994 static int 995 seq_do_fullsize(struct sequencer_softc *sc, seq_event_t *b, struct uio *uio) 996 { 997 struct sysex_info sysex; 998 u_int dev; 999 1000 #ifdef DIAGNOSTIC 1001 if (sizeof(seq_event_rec) != SEQ_SYSEX_HDRSIZE) { 1002 printf("seq_do_fullsize: sysex size ??\n"); 1003 return EINVAL; 1004 } 1005 #endif 1006 memcpy(&sysex, b, sizeof sysex); 1007 dev = sysex.device_no; 1008 if (/* dev < 0 || */ dev >= sc->nmidi) 1009 return (ENXIO); 1010 DPRINTFN(2, ("seq_do_fullsize: fmt=%04x, dev=%d, len=%d\n", 1011 sysex.key, dev, sysex.len)); 1012 return (midiseq_loadpatch(sc->devs[dev], &sysex, uio)); 1013 } 1014 1015 /* 1016 * Convert an old sequencer event to a new one. 1017 * NOTE: on entry, *ev may contain valid data only in the first 4 bytes. 1018 * That may be true even on exit (!) in the case of SEQOLD_MIDIPUTC; the 1019 * caller will only look at the first bytes in that case anyway. Ugly? Sure. 1020 */ 1021 static int 1022 seq_to_new(seq_event_t *ev, struct uio *uio) 1023 { 1024 int cmd, chan, note, parm; 1025 uint32_t tmp_delay; 1026 int error; 1027 uint8_t *bfp; 1028 1029 cmd = ev->tag; 1030 bfp = ev->unknown.byte; 1031 chan = *bfp++; 1032 note = *bfp++; 1033 parm = *bfp++; 1034 DPRINTFN(3, ("seq_to_new: 0x%02x %d %d %d\n", cmd, chan, note, parm)); 1035 1036 if (cmd >= 0x80) { 1037 /* Fill the event record */ 1038 if (uio->uio_resid >= sizeof *ev - SEQOLD_CMDSIZE) { 1039 error = uiomove(bfp, sizeof *ev - SEQOLD_CMDSIZE, uio); 1040 if (error) 1041 return error; 1042 } else 1043 return EINVAL; 1044 } 1045 1046 switch(cmd) { 1047 case SEQOLD_NOTEOFF: 1048 /* 1049 * What's with the SEQ_NOTE_XXX? In OSS this seems to have 1050 * been undocumented magic for messing with the overall volume 1051 * of a 'voice', equated precariously with 'channel' and 1052 * pretty much unimplementable except by directly frobbing a 1053 * synth chip. For us, who treat everything as interfaced over 1054 * MIDI, this will just be unceremoniously discarded as 1055 * invalid in midiseq_noteoff, making the whole event an 1056 * elaborate no-op, and that doesn't seem to be any different 1057 * from what happens on linux with a MIDI-interfaced device, 1058 * by the way. The moral is ... use the new /dev/music API, ok? 1059 */ 1060 *ev = SEQ_MK_CHN(NOTEOFF, .device=0, .channel=chan, 1061 .key=SEQ_NOTE_XXX, .velocity=parm); 1062 break; 1063 case SEQOLD_NOTEON: 1064 *ev = SEQ_MK_CHN(NOTEON, 1065 .device=0, .channel=chan, .key=note, .velocity=parm); 1066 break; 1067 case SEQOLD_WAIT: 1068 /* 1069 * This event cannot even /exist/ on non-littleendian machines, 1070 * and so help me, that's exactly the way OSS defined it. 1071 * Also, the OSS programmer's guide states (p. 74, v1.11) 1072 * that seqold time units are system clock ticks, unlike 1073 * the new 'divisions' which are determined by timebase. In 1074 * that case we would need to do scaling here - but no such 1075 * behavior is visible in linux either--which also treats this 1076 * value, surprisingly, as an absolute, not relative, time. 1077 * My guess is that this event has gone unused so long that 1078 * nobody could agree we got it wrong no matter what we do. 1079 */ 1080 tmp_delay = *(uint32_t *)ev >> 8; 1081 *ev = SEQ_MK_TIMING(WAIT_ABS, .divisions=tmp_delay); 1082 break; 1083 case SEQOLD_SYNCTIMER: 1084 /* 1085 * The TMR_RESET event is not defined in any OSS materials 1086 * I can find; it may have been invented here just to provide 1087 * an accurate _to_new translation of this event. 1088 */ 1089 *ev = SEQ_MK_TIMING(RESET); 1090 break; 1091 case SEQOLD_PGMCHANGE: 1092 *ev = SEQ_MK_CHN(PGM_CHANGE, 1093 .device=0, .channel=chan, .program=note); 1094 break; 1095 case SEQOLD_MIDIPUTC: 1096 break; /* interpret in normal mode */ 1097 case SEQOLD_ECHO: 1098 case SEQOLD_PRIVATE: 1099 case SEQOLD_EXTENDED: 1100 default: 1101 DPRINTF(("seq_to_new: not impl 0x%02x\n", cmd)); 1102 return EINVAL; 1103 /* In case new-style events show up */ 1104 case SEQ_TIMING: 1105 case SEQ_CHN_VOICE: 1106 case SEQ_CHN_COMMON: 1107 case SEQ_FULLSIZE: 1108 break; 1109 } 1110 return 0; 1111 } 1112 1113 /**********************************************/ 1114 1115 void 1116 midiseq_in(struct midi_dev *md, u_char *msg, int len) 1117 { 1118 int unit = md->unit; 1119 seq_event_t ev; 1120 int status, chan; 1121 1122 DPRINTFN(2, ("midiseq_in: %p %02x %02x %02x\n", 1123 md, msg[0], msg[1], msg[2])); 1124 1125 status = MIDI_GET_STATUS(msg[0]); 1126 chan = MIDI_GET_CHAN(msg[0]); 1127 switch (status) { 1128 case MIDI_NOTEON: /* midi(4) always canonicalizes hidden note-off */ 1129 ev = SEQ_MK_CHN(NOTEON, .device=unit, .channel=chan, 1130 .key=msg[1], .velocity=msg[2]); 1131 break; 1132 case MIDI_NOTEOFF: 1133 ev = SEQ_MK_CHN(NOTEOFF, .device=unit, .channel=chan, 1134 .key=msg[1], .velocity=msg[2]); 1135 break; 1136 case MIDI_KEY_PRESSURE: 1137 ev = SEQ_MK_CHN(KEY_PRESSURE, .device=unit, .channel=chan, 1138 .key=msg[1], .pressure=msg[2]); 1139 break; 1140 case MIDI_CTL_CHANGE: /* XXX not correct for MSB */ 1141 ev = SEQ_MK_CHN(CTL_CHANGE, .device=unit, .channel=chan, 1142 .controller=msg[1], .value=msg[2]); 1143 break; 1144 case MIDI_PGM_CHANGE: 1145 ev = SEQ_MK_CHN(PGM_CHANGE, .device=unit, .channel=chan, 1146 .program=msg[1]); 1147 break; 1148 case MIDI_CHN_PRESSURE: 1149 ev = SEQ_MK_CHN(CHN_PRESSURE, .device=unit, .channel=chan, 1150 .pressure=msg[1]); 1151 break; 1152 case MIDI_PITCH_BEND: 1153 ev = SEQ_MK_CHN(PITCH_BEND, .device=unit, .channel=chan, 1154 .value=(msg[1] & 0x7f) | ((msg[2] & 0x7f) << 7)); 1155 break; 1156 default: /* this is now the point where MIDI_ACKs disappear */ 1157 return; 1158 } 1159 seq_event_intr(md->seq, &ev); 1160 } 1161 1162 static struct midi_dev * 1163 midiseq_open(int unit, int flags) 1164 { 1165 extern struct cfdriver midi_cd; 1166 int error; 1167 struct midi_dev *md; 1168 struct midi_softc *sc; 1169 struct midi_info mi; 1170 int major; 1171 dev_t dev; 1172 1173 major = devsw_name2chr("midi", NULL, 0); 1174 dev = makedev(major, unit); 1175 1176 midi_getinfo(dev, &mi); 1177 if ( !(mi.props & MIDI_PROP_CAN_INPUT) ) 1178 flags &= ~FREAD; 1179 if ( 0 == ( flags & ( FREAD | FWRITE ) ) ) 1180 return 0; 1181 DPRINTFN(2, ("midiseq_open: %d %d\n", unit, flags)); 1182 error = cdev_open(dev, flags, 0, 0); 1183 if (error) 1184 return (0); 1185 sc = device_lookup_private(&midi_cd, unit); 1186 sc->seqopen = 1; 1187 md = malloc(sizeof *md, M_DEVBUF, M_WAITOK|M_ZERO); 1188 sc->seq_md = md; 1189 md->msc = sc; 1190 md->unit = unit; 1191 md->name = mi.name; 1192 md->subtype = 0; 1193 md->nr_voices = 128; /* XXX */ 1194 md->instr_bank_size = 128; /* XXX */ 1195 if (mi.props & MIDI_PROP_CAN_INPUT) 1196 md->capabilities |= SYNTH_CAP_INPUT; 1197 return (md); 1198 } 1199 1200 static void 1201 midiseq_close(struct midi_dev *md) 1202 { 1203 int major; 1204 dev_t dev; 1205 1206 major = devsw_name2chr("midi", NULL, 0); 1207 dev = makedev(major, md->unit); 1208 1209 DPRINTFN(2, ("midiseq_close: %d\n", md->unit)); 1210 cdev_close(dev, 0, 0, 0); 1211 free(md, M_DEVBUF); 1212 } 1213 1214 static void 1215 midiseq_reset(struct midi_dev *md) 1216 { 1217 /* XXX send GM reset? */ 1218 DPRINTFN(3, ("midiseq_reset: %d\n", md->unit)); 1219 } 1220 1221 static int 1222 midiseq_out(struct midi_dev *md, u_char *bf, u_int cc, int chk) 1223 { 1224 DPRINTFN(5, ("midiseq_out: m=%p, unit=%d, bf[0]=0x%02x, cc=%d\n", 1225 md->msc, md->unit, bf[0], cc)); 1226 1227 /* midi(4) does running status compression where appropriate. */ 1228 return midi_writebytes(md->unit, bf, cc); 1229 } 1230 1231 /* 1232 * If the writing process hands us a hidden note-off in a note-on event, 1233 * we will simply write it that way; no need to special case it here, 1234 * as midi(4) will always canonicalize or compress as appropriate anyway. 1235 */ 1236 static int 1237 midiseq_noteon(struct midi_dev *md, int chan, int key, seq_event_t *ev) 1238 { 1239 return midiseq_out(md, (uint8_t[]){ 1240 MIDI_NOTEON | chan, key, ev->c_NOTEON.velocity & 0x7f}, 3, 1); 1241 } 1242 1243 static int 1244 midiseq_noteoff(struct midi_dev *md, int chan, int key, seq_event_t *ev) 1245 { 1246 return midiseq_out(md, (uint8_t[]){ 1247 MIDI_NOTEOFF | chan, key, ev->c_NOTEOFF.velocity & 0x7f}, 3, 1); 1248 } 1249 1250 static int 1251 midiseq_keypressure(struct midi_dev *md, int chan, int key, seq_event_t *ev) 1252 { 1253 return midiseq_out(md, (uint8_t[]){ 1254 MIDI_KEY_PRESSURE | chan, key, 1255 ev->c_KEY_PRESSURE.pressure & 0x7f}, 3, 1); 1256 } 1257 1258 static int 1259 midiseq_pgmchange(struct midi_dev *md, int chan, seq_event_t *ev) 1260 { 1261 if (ev->c_PGM_CHANGE.program > 127) 1262 return EINVAL; 1263 return midiseq_out(md, (uint8_t[]){ 1264 MIDI_PGM_CHANGE | chan, ev->c_PGM_CHANGE.program}, 2, 1); 1265 } 1266 1267 static int 1268 midiseq_chnpressure(struct midi_dev *md, int chan, seq_event_t *ev) 1269 { 1270 if (ev->c_CHN_PRESSURE.pressure > 127) 1271 return EINVAL; 1272 return midiseq_out(md, (uint8_t[]){ 1273 MIDI_CHN_PRESSURE | chan, ev->c_CHN_PRESSURE.pressure}, 2, 1); 1274 } 1275 1276 static int 1277 midiseq_ctlchange(struct midi_dev *md, int chan, seq_event_t *ev) 1278 { 1279 if (ev->c_CTL_CHANGE.controller > 127) 1280 return EINVAL; 1281 return midiseq_out( md, (uint8_t[]){ 1282 MIDI_CTL_CHANGE | chan, ev->c_CTL_CHANGE.controller, 1283 ev->c_CTL_CHANGE.value & 0x7f /* XXX this is SO wrong */ 1284 }, 3, 1); 1285 } 1286 1287 static int 1288 midiseq_pitchbend(struct midi_dev *md, int chan, seq_event_t *ev) 1289 { 1290 return midiseq_out(md, (uint8_t[]){ 1291 MIDI_PITCH_BEND | chan, 1292 ev->c_PITCH_BEND.value & 0x7f, 1293 (ev->c_PITCH_BEND.value >> 7) & 0x7f}, 3, 1); 1294 } 1295 1296 static int 1297 midiseq_loadpatch(struct midi_dev *md, 1298 struct sysex_info *sysex, struct uio *uio) 1299 { 1300 u_char c, bf[128]; 1301 int i, cc, error; 1302 1303 if (sysex->key != SEQ_SYSEX_PATCH) { 1304 DPRINTFN(-1,("midiseq_loadpatch: bad patch key 0x%04x\n", 1305 sysex->key)); 1306 return (EINVAL); 1307 } 1308 if (uio->uio_resid < sysex->len) 1309 /* adjust length, should be an error */ 1310 sysex->len = uio->uio_resid; 1311 1312 DPRINTFN(2, ("midiseq_loadpatch: len=%d\n", sysex->len)); 1313 if (sysex->len == 0) 1314 return EINVAL; 1315 error = uiomove(&c, 1, uio); 1316 if (error) 1317 return error; 1318 if (c != MIDI_SYSEX_START) /* must start like this */ 1319 return EINVAL; 1320 error = midiseq_out(md, &c, 1, 0); 1321 if (error) 1322 return error; 1323 --sysex->len; 1324 while (sysex->len > 0) { 1325 cc = sysex->len; 1326 if (cc > sizeof bf) 1327 cc = sizeof bf; 1328 error = uiomove(bf, cc, uio); 1329 if (error) 1330 break; 1331 for(i = 0; i < cc && !MIDI_IS_STATUS(bf[i]); i++) 1332 ; 1333 /* 1334 * XXX midi(4)'s buffer might not accommodate this, and the 1335 * function will not block us (though in this case we have 1336 * a process and could in principle block). 1337 */ 1338 error = midiseq_out(md, bf, i, 0); 1339 if (error) 1340 break; 1341 sysex->len -= i; 1342 if (i != cc) 1343 break; 1344 } 1345 /* 1346 * Any leftover data in uio is rubbish; 1347 * the SYSEX should be one write ending in SYSEX_END. 1348 */ 1349 uio->uio_resid = 0; 1350 c = MIDI_SYSEX_END; 1351 return midiseq_out(md, &c, 1, 0); 1352 } 1353 1354 #include "midi.h" 1355 #if NMIDI == 0 1356 static dev_type_open(midiopen); 1357 static dev_type_close(midiclose); 1358 1359 const struct cdevsw midi_cdevsw = { 1360 midiopen, midiclose, noread, nowrite, noioctl, 1361 nostop, notty, nopoll, nommap, nokqfilter, D_OTHER 1362 }; 1363 1364 /* 1365 * If someone has a sequencer, but no midi devices there will 1366 * be unresolved references, so we provide little stubs. 1367 */ 1368 1369 int 1370 midi_unit_count(void) 1371 { 1372 return (0); 1373 } 1374 1375 static int 1376 midiopen(dev_t dev, int flags, int ifmt, struct lwp *l) 1377 { 1378 return (ENXIO); 1379 } 1380 1381 struct cfdriver midi_cd; 1382 1383 void 1384 midi_getinfo(dev_t dev, struct midi_info *mi) 1385 { 1386 mi->name = "Dummy MIDI device"; 1387 mi->props = 0; 1388 } 1389 1390 static int 1391 midiclose(dev_t dev, int flags, int ifmt, struct lwp *l) 1392 { 1393 return (ENXIO); 1394 } 1395 1396 int 1397 midi_writebytes(int unit, u_char *bf, int cc) 1398 { 1399 return (ENXIO); 1400 } 1401 #endif /* NMIDI == 0 */ 1402