1 /* $OpenBSD: umidi.c,v 1.39 2014/07/12 18:48:52 tedu Exp $ */ 2 /* $NetBSD: umidi.c,v 1.16 2002/07/11 21:14:32 augustss Exp $ */ 3 /* 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Takuya SHIOZAKI (tshiozak@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/param.h> 33 #include <sys/systm.h> 34 #include <sys/kernel.h> 35 #include <sys/malloc.h> 36 #include <sys/device.h> 37 #include <sys/ioctl.h> 38 #include <sys/conf.h> 39 #include <sys/file.h> 40 #include <sys/selinfo.h> 41 #include <sys/poll.h> 42 43 #include <dev/usb/usb.h> 44 #include <dev/usb/usbdi.h> 45 #include <dev/usb/usbdi_util.h> 46 47 #include <dev/usb/usbdevs.h> 48 #include <dev/usb/uaudioreg.h> 49 #include <dev/usb/umidireg.h> 50 #include <dev/usb/umidivar.h> 51 #include <dev/usb/umidi_quirks.h> 52 53 #include <dev/audio_if.h> 54 #include <dev/midi_if.h> 55 56 #ifdef UMIDI_DEBUG 57 #define DPRINTF(x) if (umididebug) printf x 58 #define DPRINTFN(n,x) if (umididebug >= (n)) printf x 59 int umididebug = 0; 60 #else 61 #define DPRINTF(x) 62 #define DPRINTFN(n,x) 63 #endif 64 65 66 static int umidi_open(void *, int, 67 void (*)(void *, int), void (*)(void *), void *); 68 static void umidi_close(void *); 69 static int umidi_output(void *, int); 70 static void umidi_flush(void *); 71 static void umidi_getinfo(void *, struct midi_info *); 72 73 static usbd_status alloc_pipe(struct umidi_endpoint *); 74 static void free_pipe(struct umidi_endpoint *); 75 76 static usbd_status alloc_all_endpoints(struct umidi_softc *); 77 static void free_all_endpoints(struct umidi_softc *); 78 79 static usbd_status alloc_all_jacks(struct umidi_softc *); 80 static void free_all_jacks(struct umidi_softc *); 81 static usbd_status bind_jacks_to_mididev(struct umidi_softc *, 82 struct umidi_jack *, 83 struct umidi_jack *, 84 struct umidi_mididev *); 85 static void unbind_jacks_from_mididev(struct umidi_mididev *); 86 static void unbind_all_jacks(struct umidi_softc *); 87 static usbd_status assign_all_jacks_automatically(struct umidi_softc *); 88 static usbd_status open_out_jack(struct umidi_jack *, void *, 89 void (*)(void *)); 90 static usbd_status open_in_jack(struct umidi_jack *, void *, 91 void (*)(void *, int)); 92 static void close_out_jack(struct umidi_jack *); 93 static void close_in_jack(struct umidi_jack *); 94 95 static usbd_status attach_mididev(struct umidi_softc *, 96 struct umidi_mididev *); 97 static usbd_status detach_mididev(struct umidi_mididev *, int); 98 static usbd_status deactivate_mididev(struct umidi_mididev *); 99 static usbd_status alloc_all_mididevs(struct umidi_softc *, int); 100 static void free_all_mididevs(struct umidi_softc *); 101 static usbd_status attach_all_mididevs(struct umidi_softc *); 102 static usbd_status detach_all_mididevs(struct umidi_softc *, int); 103 static usbd_status deactivate_all_mididevs(struct umidi_softc *); 104 105 #ifdef UMIDI_DEBUG 106 static void dump_sc(struct umidi_softc *); 107 static void dump_ep(struct umidi_endpoint *); 108 static void dump_jack(struct umidi_jack *); 109 #endif 110 111 static void init_packet(struct umidi_packet *); 112 113 static usbd_status start_input_transfer(struct umidi_endpoint *); 114 static usbd_status start_output_transfer(struct umidi_endpoint *); 115 static int out_jack_output(struct umidi_jack *, int); 116 static void out_jack_flush(struct umidi_jack *); 117 static void in_intr(struct usbd_xfer *, void *, usbd_status); 118 static void out_intr(struct usbd_xfer *, void *, usbd_status); 119 static int out_build_packet(int, struct umidi_packet *, uByte, u_char *); 120 121 122 struct midi_hw_if umidi_hw_if = { 123 umidi_open, 124 umidi_close, 125 umidi_output, 126 umidi_flush, /* flush */ 127 umidi_getinfo, 128 0, /* ioctl */ 129 }; 130 131 int umidi_match(struct device *, void *, void *); 132 void umidi_attach(struct device *, struct device *, void *); 133 int umidi_detach(struct device *, int); 134 int umidi_activate(struct device *, int); 135 136 struct cfdriver umidi_cd = { 137 NULL, "umidi", DV_DULL 138 }; 139 140 const struct cfattach umidi_ca = { 141 sizeof(struct umidi_softc), 142 umidi_match, 143 umidi_attach, 144 umidi_detach, 145 umidi_activate, 146 }; 147 148 int 149 umidi_match(struct device *parent, void *match, void *aux) 150 { 151 struct usb_attach_arg *uaa = aux; 152 usb_interface_descriptor_t *id; 153 154 DPRINTFN(1,("umidi_match\n")); 155 156 if (uaa->iface == NULL) 157 return UMATCH_NONE; 158 159 if (umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno)) 160 return UMATCH_IFACECLASS_IFACESUBCLASS; 161 162 id = usbd_get_interface_descriptor(uaa->iface); 163 if (id!=NULL && 164 id->bInterfaceClass==UICLASS_AUDIO && 165 id->bInterfaceSubClass==UISUBCLASS_MIDISTREAM) 166 return UMATCH_IFACECLASS_IFACESUBCLASS; 167 168 return UMATCH_NONE; 169 } 170 171 void 172 umidi_attach(struct device *parent, struct device *self, void *aux) 173 { 174 usbd_status err; 175 struct umidi_softc *sc = (struct umidi_softc *)self; 176 struct usb_attach_arg *uaa = aux; 177 int i; 178 179 DPRINTFN(1,("umidi_attach\n")); 180 181 sc->sc_iface = uaa->iface; 182 sc->sc_udev = uaa->device; 183 184 sc->sc_quirk = 185 umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno); 186 printf("%s: ", sc->sc_dev.dv_xname); 187 umidi_print_quirk(sc->sc_quirk); 188 189 190 err = alloc_all_endpoints(sc); 191 if (err!=USBD_NORMAL_COMPLETION) { 192 goto error; 193 } 194 err = alloc_all_jacks(sc); 195 if (err!=USBD_NORMAL_COMPLETION) { 196 free_all_endpoints(sc); 197 goto error; 198 } 199 printf("%s: out=%d, in=%d\n", 200 sc->sc_dev.dv_xname, 201 sc->sc_out_num_jacks, sc->sc_in_num_jacks); 202 203 err = assign_all_jacks_automatically(sc); 204 if (err!=USBD_NORMAL_COMPLETION) { 205 unbind_all_jacks(sc); 206 free_all_jacks(sc); 207 free_all_endpoints(sc); 208 goto error; 209 } 210 err = attach_all_mididevs(sc); 211 if (err!=USBD_NORMAL_COMPLETION) { 212 free_all_jacks(sc); 213 free_all_endpoints(sc); 214 } 215 216 #ifdef UMIDI_DEBUG 217 dump_sc(sc); 218 #endif 219 220 for (i = 0; i < sc->sc_in_num_endpoints; i++) { 221 (void)start_input_transfer(&sc->sc_in_ep[i]); 222 } 223 224 return; 225 error: 226 printf("%s: disabled.\n", sc->sc_dev.dv_xname); 227 usbd_deactivate(sc->sc_udev); 228 } 229 230 int 231 umidi_activate(struct device *self, int act) 232 { 233 struct umidi_softc *sc = (struct umidi_softc *)self; 234 235 switch (act) { 236 case DVACT_DEACTIVATE: 237 DPRINTFN(1,("umidi_activate (deactivate)\n")); 238 usbd_deactivate(sc->sc_udev); 239 deactivate_all_mididevs(sc); 240 break; 241 } 242 return 0; 243 } 244 245 int 246 umidi_detach(struct device *self, int flags) 247 { 248 struct umidi_softc *sc = (struct umidi_softc *)self; 249 250 DPRINTFN(1,("umidi_detach\n")); 251 252 detach_all_mididevs(sc, flags); 253 free_all_mididevs(sc); 254 free_all_jacks(sc); 255 free_all_endpoints(sc); 256 257 return 0; 258 } 259 260 261 /* 262 * midi_if stuffs 263 */ 264 int 265 umidi_open(void *addr, 266 int flags, 267 void (*iintr)(void *, int), 268 void (*ointr)(void *), 269 void *arg) 270 { 271 struct umidi_mididev *mididev = addr; 272 struct umidi_softc *sc = mididev->sc; 273 274 DPRINTF(("umidi_open: sc=%p\n", sc)); 275 276 if (!sc) 277 return ENXIO; 278 if (mididev->opened) 279 return EBUSY; 280 if (usbd_is_dying(sc->sc_udev)) 281 return EIO; 282 283 mididev->opened = 1; 284 mididev->flags = flags; 285 if ((mididev->flags & FWRITE) && mididev->out_jack) 286 open_out_jack(mididev->out_jack, arg, ointr); 287 if ((mididev->flags & FREAD) && mididev->in_jack) { 288 open_in_jack(mididev->in_jack, arg, iintr); 289 } 290 291 return 0; 292 } 293 294 void 295 umidi_close(void *addr) 296 { 297 int s; 298 struct umidi_mididev *mididev = addr; 299 300 s = splusb(); 301 if ((mididev->flags & FWRITE) && mididev->out_jack) 302 close_out_jack(mididev->out_jack); 303 if ((mididev->flags & FREAD) && mididev->in_jack) 304 close_in_jack(mididev->in_jack); 305 mididev->opened = 0; 306 splx(s); 307 } 308 309 int 310 umidi_output(void *addr, int d) 311 { 312 struct umidi_mididev *mididev = addr; 313 314 if (!mididev->out_jack || !mididev->opened) 315 return 1; 316 317 return out_jack_output(mididev->out_jack, d); 318 } 319 320 void 321 umidi_flush(void *addr) 322 { 323 struct umidi_mididev *mididev = addr; 324 325 if (!mididev->out_jack || !mididev->opened) 326 return; 327 328 return out_jack_flush(mididev->out_jack); 329 } 330 331 void 332 umidi_getinfo(void *addr, struct midi_info *mi) 333 { 334 struct umidi_mididev *mididev = addr; 335 336 mi->name = "USB MIDI I/F"; /* XXX: model name */ 337 mi->props = MIDI_PROP_OUT_INTR; 338 if (mididev->in_jack) 339 mi->props |= MIDI_PROP_CAN_INPUT; 340 } 341 342 343 /* 344 * each endpoint stuffs 345 */ 346 347 /* alloc/free pipe */ 348 static usbd_status 349 alloc_pipe(struct umidi_endpoint *ep) 350 { 351 struct umidi_softc *sc = ep->sc; 352 usbd_status err; 353 354 DPRINTF(("%s: alloc_pipe %p\n", sc->sc_dev.dv_xname, ep)); 355 SIMPLEQ_INIT(&ep->intrq); 356 ep->pending = 0; 357 ep->busy = 0; 358 ep->used = 0; 359 ep->xfer = usbd_alloc_xfer(sc->sc_udev); 360 if (ep->xfer == NULL) { 361 return USBD_NOMEM; 362 } 363 ep->buffer = usbd_alloc_buffer(ep->xfer, ep->packetsize); 364 if (ep->buffer == NULL) { 365 usbd_free_xfer(ep->xfer); 366 return USBD_NOMEM; 367 } 368 err = usbd_open_pipe(sc->sc_iface, ep->addr, 0, &ep->pipe); 369 if (err != USBD_NORMAL_COMPLETION) { 370 usbd_free_xfer(ep->xfer); 371 return err; 372 } 373 return USBD_NORMAL_COMPLETION; 374 } 375 376 static void 377 free_pipe(struct umidi_endpoint *ep) 378 { 379 DPRINTF(("%s: free_pipe %p\n", ep->sc->sc_dev.dv_xname, ep)); 380 usbd_abort_pipe(ep->pipe); 381 usbd_close_pipe(ep->pipe); 382 usbd_free_xfer(ep->xfer); 383 } 384 385 386 /* alloc/free the array of endpoint structures */ 387 388 static usbd_status alloc_all_endpoints_fixed_ep(struct umidi_softc *); 389 static usbd_status alloc_all_endpoints_yamaha(struct umidi_softc *); 390 static usbd_status alloc_all_endpoints_genuine(struct umidi_softc *); 391 392 static usbd_status 393 alloc_all_endpoints(struct umidi_softc *sc) 394 { 395 usbd_status err; 396 struct umidi_endpoint *ep; 397 int i; 398 399 if (UMQ_ISTYPE(sc, UMQ_TYPE_FIXED_EP)) { 400 err = alloc_all_endpoints_fixed_ep(sc); 401 } else if (UMQ_ISTYPE(sc, UMQ_TYPE_YAMAHA)) { 402 err = alloc_all_endpoints_yamaha(sc); 403 } else { 404 err = alloc_all_endpoints_genuine(sc); 405 } 406 if (err!=USBD_NORMAL_COMPLETION) 407 return err; 408 409 ep = sc->sc_endpoints; 410 for (i=sc->sc_out_num_endpoints+sc->sc_in_num_endpoints; i>0; i--) { 411 err = alloc_pipe(ep); 412 if (err!=USBD_NORMAL_COMPLETION) { 413 while(ep != sc->sc_endpoints) { 414 ep--; 415 free_pipe(ep); 416 } 417 free(sc->sc_endpoints, M_USBDEV, 0); 418 sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL; 419 break; 420 } 421 ep++; 422 } 423 return err; 424 } 425 426 static void 427 free_all_endpoints(struct umidi_softc *sc) 428 { 429 int i; 430 for (i=0; i<sc->sc_in_num_endpoints+sc->sc_out_num_endpoints; i++) 431 free_pipe(&sc->sc_endpoints[i]); 432 if (sc->sc_endpoints != NULL) 433 free(sc->sc_endpoints, M_USBDEV, 0); 434 sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL; 435 } 436 437 static usbd_status 438 alloc_all_endpoints_fixed_ep(struct umidi_softc *sc) 439 { 440 usbd_status err; 441 struct umq_fixed_ep_desc *fp; 442 struct umidi_endpoint *ep; 443 usb_endpoint_descriptor_t *epd; 444 int i; 445 446 fp = umidi_get_quirk_data_from_type(sc->sc_quirk, 447 UMQ_TYPE_FIXED_EP); 448 sc->sc_out_num_jacks = 0; 449 sc->sc_in_num_jacks = 0; 450 sc->sc_out_num_endpoints = fp->num_out_ep; 451 sc->sc_in_num_endpoints = fp->num_in_ep; 452 sc->sc_endpoints = malloc(sizeof(*sc->sc_out_ep)* 453 (sc->sc_out_num_endpoints+ 454 sc->sc_in_num_endpoints), 455 M_USBDEV, M_WAITOK | M_CANFAIL); 456 if (!sc->sc_endpoints) { 457 return USBD_NOMEM; 458 } 459 sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL; 460 sc->sc_in_ep = 461 sc->sc_in_num_endpoints ? 462 sc->sc_endpoints+sc->sc_out_num_endpoints : NULL; 463 464 ep = &sc->sc_out_ep[0]; 465 for (i=0; i<sc->sc_out_num_endpoints; i++) { 466 epd = usbd_interface2endpoint_descriptor( 467 sc->sc_iface, 468 fp->out_ep[i].ep); 469 if (!epd) { 470 DPRINTF(("%s: cannot get endpoint descriptor(out:%d)\n", 471 sc->sc_dev.dv_xname, fp->out_ep[i].ep)); 472 err = USBD_INVAL; 473 goto error; 474 } 475 if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK || 476 UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_OUT) { 477 printf("%s: illegal endpoint(out:%d)\n", 478 sc->sc_dev.dv_xname, fp->out_ep[i].ep); 479 err = USBD_INVAL; 480 goto error; 481 } 482 ep->sc = sc; 483 ep->packetsize = UGETW(epd->wMaxPacketSize); 484 ep->addr = epd->bEndpointAddress; 485 ep->num_jacks = fp->out_ep[i].num_jacks; 486 sc->sc_out_num_jacks += fp->out_ep[i].num_jacks; 487 ep->num_open = 0; 488 memset(ep->jacks, 0, sizeof(ep->jacks)); 489 ep++; 490 } 491 ep = &sc->sc_in_ep[0]; 492 for (i=0; i<sc->sc_in_num_endpoints; i++) { 493 epd = usbd_interface2endpoint_descriptor( 494 sc->sc_iface, 495 fp->in_ep[i].ep); 496 if (!epd) { 497 DPRINTF(("%s: cannot get endpoint descriptor(in:%d)\n", 498 sc->sc_dev.dv_xname, fp->in_ep[i].ep)); 499 err = USBD_INVAL; 500 goto error; 501 } 502 if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK || 503 UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_IN) { 504 printf("%s: illegal endpoint(in:%d)\n", 505 sc->sc_dev.dv_xname, fp->in_ep[i].ep); 506 err = USBD_INVAL; 507 goto error; 508 } 509 ep->sc = sc; 510 ep->addr = epd->bEndpointAddress; 511 ep->packetsize = UGETW(epd->wMaxPacketSize); 512 ep->num_jacks = fp->in_ep[i].num_jacks; 513 sc->sc_in_num_jacks += fp->in_ep[i].num_jacks; 514 ep->num_open = 0; 515 memset(ep->jacks, 0, sizeof(ep->jacks)); 516 ep++; 517 } 518 519 return USBD_NORMAL_COMPLETION; 520 error: 521 free(sc->sc_endpoints, M_USBDEV, 0); 522 sc->sc_endpoints = NULL; 523 return err; 524 } 525 526 static usbd_status 527 alloc_all_endpoints_yamaha(struct umidi_softc *sc) 528 { 529 /* This driver currently supports max 1in/1out bulk endpoints */ 530 usb_descriptor_t *desc; 531 usb_endpoint_descriptor_t *epd; 532 int out_addr, in_addr, in_packetsize, i; 533 int dir; 534 size_t remain, descsize; 535 536 sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0; 537 out_addr = in_addr = 0; 538 539 /* detect endpoints */ 540 desc = TO_D(usbd_get_interface_descriptor(sc->sc_iface)); 541 for (i=(int)TO_IFD(desc)->bNumEndpoints-1; i>=0; i--) { 542 epd = usbd_interface2endpoint_descriptor(sc->sc_iface, i); 543 if (UE_GET_XFERTYPE(epd->bmAttributes) == UE_BULK) { 544 dir = UE_GET_DIR(epd->bEndpointAddress); 545 if (dir==UE_DIR_OUT && !out_addr) 546 out_addr = epd->bEndpointAddress; 547 else if (dir==UE_DIR_IN && !in_addr) { 548 in_addr = epd->bEndpointAddress; 549 in_packetsize = UGETW(epd->wMaxPacketSize); 550 } 551 } 552 } 553 desc = NEXT_D(desc); 554 555 /* count jacks */ 556 if (!(desc->bDescriptorType==UDESC_CS_INTERFACE && 557 desc->bDescriptorSubtype==UMIDI_MS_HEADER)) 558 return USBD_INVAL; 559 remain = (size_t)UGETW(TO_CSIFD(desc)->wTotalLength) - 560 (size_t)desc->bLength; 561 desc = NEXT_D(desc); 562 563 while (remain>=sizeof(usb_descriptor_t)) { 564 descsize = desc->bLength; 565 if (descsize>remain || descsize==0) 566 break; 567 if (desc->bDescriptorType==UDESC_CS_INTERFACE && 568 remain>=UMIDI_JACK_DESCRIPTOR_SIZE) { 569 if (desc->bDescriptorSubtype==UMIDI_OUT_JACK) 570 sc->sc_out_num_jacks++; 571 else if (desc->bDescriptorSubtype==UMIDI_IN_JACK) 572 sc->sc_in_num_jacks++; 573 } 574 desc = NEXT_D(desc); 575 remain-=descsize; 576 } 577 578 /* validate some parameters */ 579 if (sc->sc_out_num_jacks>UMIDI_MAX_EPJACKS) 580 sc->sc_out_num_jacks = UMIDI_MAX_EPJACKS; 581 if (sc->sc_in_num_jacks>UMIDI_MAX_EPJACKS) 582 sc->sc_in_num_jacks = UMIDI_MAX_EPJACKS; 583 if (sc->sc_out_num_jacks && out_addr) { 584 sc->sc_out_num_endpoints = 1; 585 } else { 586 sc->sc_out_num_endpoints = 0; 587 sc->sc_out_num_jacks = 0; 588 } 589 if (sc->sc_in_num_jacks && in_addr) { 590 sc->sc_in_num_endpoints = 1; 591 } else { 592 sc->sc_in_num_endpoints = 0; 593 sc->sc_in_num_jacks = 0; 594 } 595 sc->sc_endpoints = malloc(sizeof(struct umidi_endpoint)* 596 (sc->sc_out_num_endpoints+ 597 sc->sc_in_num_endpoints), 598 M_USBDEV, M_WAITOK | M_CANFAIL); 599 if (!sc->sc_endpoints) 600 return USBD_NOMEM; 601 if (sc->sc_out_num_endpoints) { 602 sc->sc_out_ep = sc->sc_endpoints; 603 sc->sc_out_ep->sc = sc; 604 sc->sc_out_ep->addr = out_addr; 605 sc->sc_out_ep->packetsize = UGETW(epd->wMaxPacketSize); 606 sc->sc_out_ep->num_jacks = sc->sc_out_num_jacks; 607 sc->sc_out_ep->num_open = 0; 608 memset(sc->sc_out_ep->jacks, 0, sizeof(sc->sc_out_ep->jacks)); 609 } else 610 sc->sc_out_ep = NULL; 611 612 if (sc->sc_in_num_endpoints) { 613 sc->sc_in_ep = sc->sc_endpoints+sc->sc_out_num_endpoints; 614 sc->sc_in_ep->sc = sc; 615 sc->sc_in_ep->addr = in_addr; 616 sc->sc_in_ep->packetsize = in_packetsize; 617 sc->sc_in_ep->num_jacks = sc->sc_in_num_jacks; 618 sc->sc_in_ep->num_open = 0; 619 memset(sc->sc_in_ep->jacks, 0, sizeof(sc->sc_in_ep->jacks)); 620 } else 621 sc->sc_in_ep = NULL; 622 623 return USBD_NORMAL_COMPLETION; 624 } 625 626 static usbd_status 627 alloc_all_endpoints_genuine(struct umidi_softc *sc) 628 { 629 usb_interface_descriptor_t *interface_desc; 630 usb_config_descriptor_t *config_desc; 631 usb_descriptor_t *desc; 632 int num_ep; 633 size_t remain, descsize; 634 struct umidi_endpoint *p, *q, *lowest, *endep, tmpep; 635 int epaddr, eppacketsize; 636 637 interface_desc = usbd_get_interface_descriptor(sc->sc_iface); 638 num_ep = interface_desc->bNumEndpoints; 639 sc->sc_endpoints = p = malloc(sizeof(struct umidi_endpoint) * num_ep, 640 M_USBDEV, M_WAITOK | M_CANFAIL); 641 if (!p) 642 return USBD_NOMEM; 643 644 sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0; 645 sc->sc_out_num_endpoints = sc->sc_in_num_endpoints = 0; 646 epaddr = -1; 647 648 /* get the list of endpoints for midi stream */ 649 config_desc = usbd_get_config_descriptor(sc->sc_udev); 650 desc = (usb_descriptor_t *) config_desc; 651 remain = (size_t)UGETW(config_desc->wTotalLength); 652 while (remain>=sizeof(usb_descriptor_t)) { 653 descsize = desc->bLength; 654 if (descsize>remain || descsize==0) 655 break; 656 if (desc->bDescriptorType==UDESC_ENDPOINT && 657 remain>=USB_ENDPOINT_DESCRIPTOR_SIZE && 658 UE_GET_XFERTYPE(TO_EPD(desc)->bmAttributes) == UE_BULK) { 659 epaddr = TO_EPD(desc)->bEndpointAddress; 660 eppacketsize = UGETW(TO_EPD(desc)->wMaxPacketSize); 661 } else if (desc->bDescriptorType==UDESC_CS_ENDPOINT && 662 remain>=UMIDI_CS_ENDPOINT_DESCRIPTOR_SIZE && 663 epaddr!=-1) { 664 if (num_ep>0) { 665 num_ep--; 666 p->sc = sc; 667 p->addr = epaddr; 668 p->packetsize = eppacketsize; 669 p->num_jacks = TO_CSEPD(desc)->bNumEmbMIDIJack; 670 if (UE_GET_DIR(epaddr)==UE_DIR_OUT) { 671 sc->sc_out_num_endpoints++; 672 sc->sc_out_num_jacks += p->num_jacks; 673 } else { 674 sc->sc_in_num_endpoints++; 675 sc->sc_in_num_jacks += p->num_jacks; 676 } 677 p++; 678 } 679 } else 680 epaddr = -1; 681 desc = NEXT_D(desc); 682 remain-=descsize; 683 } 684 685 /* sort endpoints */ 686 num_ep = sc->sc_out_num_endpoints + sc->sc_in_num_endpoints; 687 p = sc->sc_endpoints; 688 endep = p + num_ep; 689 while (p<endep) { 690 lowest = p; 691 for (q=p+1; q<endep; q++) { 692 if ((UE_GET_DIR(lowest->addr)==UE_DIR_IN && 693 UE_GET_DIR(q->addr)==UE_DIR_OUT) || 694 ((UE_GET_DIR(lowest->addr)== 695 UE_GET_DIR(q->addr)) && 696 (UE_GET_ADDR(lowest->addr)> 697 UE_GET_ADDR(q->addr)))) 698 lowest = q; 699 } 700 if (lowest != p) { 701 memcpy((void *)&tmpep, (void *)p, sizeof(tmpep)); 702 memcpy((void *)p, (void *)lowest, sizeof(tmpep)); 703 memcpy((void *)lowest, (void *)&tmpep, sizeof(tmpep)); 704 } 705 p->num_open = 0; 706 p++; 707 } 708 709 sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL; 710 sc->sc_in_ep = 711 sc->sc_in_num_endpoints ? 712 sc->sc_endpoints+sc->sc_out_num_endpoints : NULL; 713 714 return USBD_NORMAL_COMPLETION; 715 } 716 717 718 /* 719 * jack stuffs 720 */ 721 722 static usbd_status 723 alloc_all_jacks(struct umidi_softc *sc) 724 { 725 int i, j; 726 struct umidi_endpoint *ep; 727 struct umidi_jack *jack, **rjack; 728 729 /* allocate/initialize structures */ 730 sc->sc_jacks = 731 malloc(sizeof(*sc->sc_out_jacks)*(sc->sc_in_num_jacks+ 732 sc->sc_out_num_jacks), 733 M_USBDEV, M_WAITOK | M_CANFAIL); 734 if (!sc->sc_jacks) 735 return USBD_NOMEM; 736 sc->sc_out_jacks = 737 sc->sc_out_num_jacks ? sc->sc_jacks : NULL; 738 sc->sc_in_jacks = 739 sc->sc_in_num_jacks ? sc->sc_jacks+sc->sc_out_num_jacks : NULL; 740 741 jack = &sc->sc_out_jacks[0]; 742 for (i=0; i<sc->sc_out_num_jacks; i++) { 743 jack->opened = 0; 744 jack->binded = 0; 745 jack->arg = NULL; 746 jack->u.out.intr = NULL; 747 jack->intr = 0; 748 jack->cable_number = i; 749 jack++; 750 } 751 jack = &sc->sc_in_jacks[0]; 752 for (i=0; i<sc->sc_in_num_jacks; i++) { 753 jack->opened = 0; 754 jack->binded = 0; 755 jack->arg = NULL; 756 jack->u.in.intr = NULL; 757 jack->cable_number = i; 758 jack++; 759 } 760 761 /* assign each jacks to each endpoints */ 762 jack = &sc->sc_out_jacks[0]; 763 ep = &sc->sc_out_ep[0]; 764 for (i=0; i<sc->sc_out_num_endpoints; i++) { 765 rjack = &ep->jacks[0]; 766 for (j=0; j<ep->num_jacks; j++) { 767 *rjack = jack; 768 jack->endpoint = ep; 769 jack++; 770 rjack++; 771 } 772 ep++; 773 } 774 jack = &sc->sc_in_jacks[0]; 775 ep = &sc->sc_in_ep[0]; 776 for (i=0; i<sc->sc_in_num_endpoints; i++) { 777 rjack = &ep->jacks[0]; 778 for (j=0; j<ep->num_jacks; j++) { 779 *rjack = jack; 780 jack->endpoint = ep; 781 jack++; 782 rjack++; 783 } 784 ep++; 785 } 786 787 return USBD_NORMAL_COMPLETION; 788 } 789 790 static void 791 free_all_jacks(struct umidi_softc *sc) 792 { 793 int s; 794 795 s = splusb(); 796 if (sc->sc_out_jacks) { 797 free(sc->sc_jacks, M_USBDEV, 0); 798 sc->sc_jacks = sc->sc_in_jacks = sc->sc_out_jacks = NULL; 799 } 800 splx(s); 801 } 802 803 static usbd_status 804 bind_jacks_to_mididev(struct umidi_softc *sc, 805 struct umidi_jack *out_jack, 806 struct umidi_jack *in_jack, 807 struct umidi_mididev *mididev) 808 { 809 if ((out_jack && out_jack->binded) || (in_jack && in_jack->binded)) 810 return USBD_IN_USE; 811 if (mididev->out_jack || mididev->in_jack) 812 return USBD_IN_USE; 813 814 if (out_jack) 815 out_jack->binded = 1; 816 if (in_jack) 817 in_jack->binded = 1; 818 mididev->in_jack = in_jack; 819 mididev->out_jack = out_jack; 820 821 return USBD_NORMAL_COMPLETION; 822 } 823 824 static void 825 unbind_jacks_from_mididev(struct umidi_mididev *mididev) 826 { 827 if ((mididev->flags & FWRITE) && mididev->out_jack) 828 close_out_jack(mididev->out_jack); 829 if ((mididev->flags & FREAD) && mididev->in_jack) 830 close_in_jack(mididev->in_jack); 831 832 if (mididev->out_jack) 833 mididev->out_jack->binded = 0; 834 if (mididev->in_jack) 835 mididev->in_jack->binded = 0; 836 mididev->out_jack = mididev->in_jack = NULL; 837 } 838 839 static void 840 unbind_all_jacks(struct umidi_softc *sc) 841 { 842 int i; 843 844 if (sc->sc_mididevs) 845 for (i=0; i<sc->sc_num_mididevs; i++) { 846 unbind_jacks_from_mididev(&sc->sc_mididevs[i]); 847 } 848 } 849 850 static usbd_status 851 assign_all_jacks_automatically(struct umidi_softc *sc) 852 { 853 usbd_status err; 854 int i; 855 struct umidi_jack *out, *in; 856 857 err = 858 alloc_all_mididevs(sc, 859 max(sc->sc_out_num_jacks, sc->sc_in_num_jacks)); 860 if (err!=USBD_NORMAL_COMPLETION) 861 return err; 862 863 for (i=0; i<sc->sc_num_mididevs; i++) { 864 out = (i<sc->sc_out_num_jacks) ? &sc->sc_out_jacks[i]:NULL; 865 in = (i<sc->sc_in_num_jacks) ? &sc->sc_in_jacks[i]:NULL; 866 err = bind_jacks_to_mididev(sc, out, in, &sc->sc_mididevs[i]); 867 if (err!=USBD_NORMAL_COMPLETION) { 868 free_all_mididevs(sc); 869 return err; 870 } 871 } 872 873 return USBD_NORMAL_COMPLETION; 874 } 875 876 static usbd_status 877 open_out_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *)) 878 { 879 if (jack->opened) 880 return USBD_IN_USE; 881 882 jack->arg = arg; 883 jack->u.out.intr = intr; 884 init_packet(&jack->packet); 885 jack->opened = 1; 886 jack->endpoint->num_open++; 887 888 return USBD_NORMAL_COMPLETION; 889 } 890 891 static usbd_status 892 open_in_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *, int)) 893 { 894 if (jack->opened) 895 return USBD_IN_USE; 896 897 jack->arg = arg; 898 jack->u.in.intr = intr; 899 jack->opened = 1; 900 jack->endpoint->num_open++; 901 902 return USBD_NORMAL_COMPLETION; 903 } 904 905 static void 906 close_out_jack(struct umidi_jack *jack) 907 { 908 if (jack->opened) { 909 jack->opened = 0; 910 jack->endpoint->num_open--; 911 } 912 } 913 914 static void 915 close_in_jack(struct umidi_jack *jack) 916 { 917 if (jack->opened) { 918 jack->opened = 0; 919 jack->endpoint->num_open--; 920 } 921 } 922 923 static usbd_status 924 attach_mididev(struct umidi_softc *sc, struct umidi_mididev *mididev) 925 { 926 if (mididev->sc) 927 return USBD_IN_USE; 928 929 mididev->sc = sc; 930 931 mididev->mdev = midi_attach_mi(&umidi_hw_if, mididev, &sc->sc_dev); 932 933 return USBD_NORMAL_COMPLETION; 934 } 935 936 static usbd_status 937 detach_mididev(struct umidi_mididev *mididev, int flags) 938 { 939 if (!mididev->sc) 940 return USBD_NO_ADDR; 941 942 if (mididev->opened) { 943 umidi_close(mididev); 944 } 945 unbind_jacks_from_mididev(mididev); 946 947 if (mididev->mdev) 948 config_detach(mididev->mdev, flags); 949 950 mididev->sc = NULL; 951 952 return USBD_NORMAL_COMPLETION; 953 } 954 955 static usbd_status 956 deactivate_mididev(struct umidi_mididev *mididev) 957 { 958 if (mididev->out_jack) 959 mididev->out_jack->binded = 0; 960 if (mididev->in_jack) 961 mididev->in_jack->binded = 0; 962 config_deactivate(mididev->mdev); 963 964 return USBD_NORMAL_COMPLETION; 965 } 966 967 static usbd_status 968 alloc_all_mididevs(struct umidi_softc *sc, int nmidi) 969 { 970 sc->sc_num_mididevs = nmidi; 971 sc->sc_mididevs = malloc(sizeof(*sc->sc_mididevs)*nmidi, M_USBDEV, 972 M_WAITOK | M_CANFAIL | M_ZERO); 973 if (!sc->sc_mididevs) 974 return USBD_NOMEM; 975 976 return USBD_NORMAL_COMPLETION; 977 } 978 979 static void 980 free_all_mididevs(struct umidi_softc *sc) 981 { 982 sc->sc_num_mididevs = 0; 983 if (sc->sc_mididevs) 984 free(sc->sc_mididevs, M_USBDEV, 0); 985 } 986 987 static usbd_status 988 attach_all_mididevs(struct umidi_softc *sc) 989 { 990 usbd_status err; 991 int i; 992 993 if (sc->sc_mididevs) 994 for (i=0; i<sc->sc_num_mididevs; i++) { 995 err = attach_mididev(sc, &sc->sc_mididevs[i]); 996 if (err!=USBD_NORMAL_COMPLETION) 997 return err; 998 } 999 1000 return USBD_NORMAL_COMPLETION; 1001 } 1002 1003 static usbd_status 1004 detach_all_mididevs(struct umidi_softc *sc, int flags) 1005 { 1006 usbd_status err; 1007 int i; 1008 1009 if (sc->sc_mididevs) 1010 for (i=0; i<sc->sc_num_mididevs; i++) { 1011 err = detach_mididev(&sc->sc_mididevs[i], flags); 1012 if (err!=USBD_NORMAL_COMPLETION) 1013 return err; 1014 } 1015 1016 return USBD_NORMAL_COMPLETION; 1017 } 1018 1019 static usbd_status 1020 deactivate_all_mididevs(struct umidi_softc *sc) 1021 { 1022 usbd_status err; 1023 int i; 1024 1025 if (sc->sc_mididevs) 1026 for (i=0; i<sc->sc_num_mididevs; i++) { 1027 err = deactivate_mididev(&sc->sc_mididevs[i]); 1028 if (err!=USBD_NORMAL_COMPLETION) 1029 return err; 1030 } 1031 1032 return USBD_NORMAL_COMPLETION; 1033 } 1034 1035 #ifdef UMIDI_DEBUG 1036 static void 1037 dump_sc(struct umidi_softc *sc) 1038 { 1039 int i; 1040 1041 DPRINTFN(10, ("%s: dump_sc\n", sc->sc_dev.dv_xname)); 1042 for (i=0; i<sc->sc_out_num_endpoints; i++) { 1043 DPRINTFN(10, ("\tout_ep(%p):\n", &sc->sc_out_ep[i])); 1044 dump_ep(&sc->sc_out_ep[i]); 1045 } 1046 for (i=0; i<sc->sc_in_num_endpoints; i++) { 1047 DPRINTFN(10, ("\tin_ep(%p):\n", &sc->sc_in_ep[i])); 1048 dump_ep(&sc->sc_in_ep[i]); 1049 } 1050 } 1051 1052 static void 1053 dump_ep(struct umidi_endpoint *ep) 1054 { 1055 int i; 1056 for (i=0; i<ep->num_jacks; i++) { 1057 DPRINTFN(10, ("\t\tjack(%p):\n", ep->jacks[i])); 1058 dump_jack(ep->jacks[i]); 1059 } 1060 } 1061 static void 1062 dump_jack(struct umidi_jack *jack) 1063 { 1064 DPRINTFN(10, ("\t\t\tep=%p\n", 1065 jack->endpoint)); 1066 } 1067 1068 #endif /* UMIDI_DEBUG */ 1069 1070 1071 1072 /* 1073 * MUX MIDI PACKET 1074 */ 1075 1076 static const int packet_length[16] = { 1077 /*0*/ -1, 1078 /*1*/ -1, 1079 /*2*/ 2, 1080 /*3*/ 3, 1081 /*4*/ 3, 1082 /*5*/ 1, 1083 /*6*/ 2, 1084 /*7*/ 3, 1085 /*8*/ 3, 1086 /*9*/ 3, 1087 /*A*/ 3, 1088 /*B*/ 3, 1089 /*C*/ 2, 1090 /*D*/ 2, 1091 /*E*/ 3, 1092 /*F*/ 1, 1093 }; 1094 1095 #define GET_CN(p) (((unsigned char)(p)>>4)&0x0F) 1096 #define GET_CIN(p) ((unsigned char)(p)&0x0F) 1097 #define MIX_CN_CIN(cn, cin) \ 1098 ((unsigned char)((((unsigned char)(cn)&0x0F)<<4)| \ 1099 ((unsigned char)(cin)&0x0F))) 1100 1101 static void 1102 init_packet(struct umidi_packet *packet) 1103 { 1104 packet->status = 0; 1105 packet->index = 0; 1106 } 1107 1108 static usbd_status 1109 start_input_transfer(struct umidi_endpoint *ep) 1110 { 1111 usbd_status err; 1112 usbd_setup_xfer(ep->xfer, ep->pipe, 1113 (void *)ep, 1114 ep->buffer, ep->packetsize, 1115 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, in_intr); 1116 err = usbd_transfer(ep->xfer); 1117 if (err != USBD_NORMAL_COMPLETION && err != USBD_IN_PROGRESS) { 1118 DPRINTF(("%s: start_input_transfer: usbd_transfer() failed err=%s\n", 1119 ep->sc->sc_dev.dv_xname, usbd_errstr(err))); 1120 return err; 1121 } 1122 return USBD_NORMAL_COMPLETION; 1123 } 1124 1125 static usbd_status 1126 start_output_transfer(struct umidi_endpoint *ep) 1127 { 1128 usbd_status err; 1129 usbd_setup_xfer(ep->xfer, ep->pipe, 1130 (void *)ep, 1131 ep->buffer, ep->used, 1132 USBD_NO_COPY, USBD_NO_TIMEOUT, out_intr); 1133 err = usbd_transfer(ep->xfer); 1134 if (err != USBD_NORMAL_COMPLETION && err != USBD_IN_PROGRESS) { 1135 DPRINTF(("%s: start_output_transfer: usbd_transfer() failed err=%s\n", 1136 ep->sc->sc_dev.dv_xname, usbd_errstr(err))); 1137 return err; 1138 } 1139 ep->used = ep->packetsize; 1140 return USBD_NORMAL_COMPLETION; 1141 } 1142 1143 1144 #ifdef UMIDI_DEBUG 1145 #define DPR_PACKET(dir, sc, p) \ 1146 DPRINTFN(500, \ 1147 ("%s: umidi packet(" #dir "): %02X %02X %02X %02X\n", \ 1148 sc->sc_dev.dv_xname, \ 1149 (unsigned char)(p)->buffer[0], \ 1150 (unsigned char)(p)->buffer[1], \ 1151 (unsigned char)(p)->buffer[2], \ 1152 (unsigned char)(p)->buffer[3])); 1153 #else 1154 #define DPR_PACKET(dir, sc, p) 1155 #endif 1156 1157 static int 1158 out_jack_output(struct umidi_jack *j, int d) 1159 { 1160 struct umidi_endpoint *ep = j->endpoint; 1161 struct umidi_softc *sc = ep->sc; 1162 int s; 1163 1164 if (usbd_is_dying(sc->sc_udev)) 1165 return 1; 1166 if (!j->opened) 1167 return 1; 1168 s = splusb(); 1169 if (ep->busy) { 1170 if (!j->intr) { 1171 SIMPLEQ_INSERT_TAIL(&ep->intrq, j, intrq_entry); 1172 ep->pending++; 1173 j->intr = 1; 1174 } 1175 splx(s); 1176 return 0; 1177 } 1178 if (!out_build_packet(j->cable_number, &j->packet, d, 1179 ep->buffer + ep->used)) { 1180 splx(s); 1181 return 1; 1182 } 1183 ep->used += UMIDI_PACKET_SIZE; 1184 if (ep->used == ep->packetsize) { 1185 ep->busy = 1; 1186 start_output_transfer(ep); 1187 } 1188 splx(s); 1189 return 1; 1190 } 1191 1192 static void 1193 out_jack_flush(struct umidi_jack *j) 1194 { 1195 struct umidi_endpoint *ep = j->endpoint; 1196 int s; 1197 1198 if (usbd_is_dying(ep->sc->sc_udev) || !j->opened) 1199 return; 1200 1201 s = splusb(); 1202 if (ep->used != 0 && !ep->busy) { 1203 ep->busy = 1; 1204 start_output_transfer(ep); 1205 } 1206 splx(s); 1207 } 1208 1209 1210 static void 1211 in_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) 1212 { 1213 int cn, evlen, remain, i; 1214 unsigned char *buf; 1215 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv; 1216 struct umidi_jack *jack; 1217 1218 if (usbd_is_dying(ep->sc->sc_udev)) 1219 return; 1220 1221 usbd_get_xfer_status(xfer, NULL, NULL, &remain, NULL); 1222 if (status != USBD_NORMAL_COMPLETION) { 1223 DPRINTF(("in_intr: abnormal status: %s\n", usbd_errstr(status))); 1224 return; 1225 } 1226 buf = ep->buffer; 1227 while (remain >= UMIDI_PACKET_SIZE) { 1228 cn = GET_CN(buf[0]); 1229 if (cn < ep->num_jacks && (jack = ep->jacks[cn]) && 1230 jack->binded && jack->opened && jack->u.in.intr) { 1231 evlen = packet_length[GET_CIN(buf[0])]; 1232 mtx_enter(&audio_lock); 1233 for (i=0; i<evlen; i++) 1234 (*jack->u.in.intr)(jack->arg, buf[i+1]); 1235 mtx_leave(&audio_lock); 1236 } 1237 buf += UMIDI_PACKET_SIZE; 1238 remain -= UMIDI_PACKET_SIZE; 1239 } 1240 (void)start_input_transfer(ep); 1241 } 1242 1243 static void 1244 out_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) 1245 { 1246 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv; 1247 struct umidi_softc *sc = ep->sc; 1248 struct umidi_jack *j; 1249 unsigned pending; 1250 1251 if (usbd_is_dying(sc->sc_udev)) 1252 return; 1253 1254 ep->used = 0; 1255 ep->busy = 0; 1256 for (pending = ep->pending; pending > 0; pending--) { 1257 j = SIMPLEQ_FIRST(&ep->intrq); 1258 #ifdef DIAGNOSTIC 1259 if (j == NULL) { 1260 printf("umidi: missing intr entry\n"); 1261 break; 1262 } 1263 #endif 1264 SIMPLEQ_REMOVE_HEAD(&ep->intrq, intrq_entry); 1265 ep->pending--; 1266 j->intr = 0; 1267 mtx_enter(&audio_lock); 1268 if (j->opened && j->u.out.intr) 1269 (*j->u.out.intr)(j->arg); 1270 mtx_leave(&audio_lock); 1271 } 1272 } 1273 1274 #define UMIDI_VOICELEN(status) (umidi_evlen[((status) >> 4) & 7]) 1275 unsigned umidi_evlen[] = { 4, 4, 4, 4, 3, 3, 4 }; 1276 1277 #define EV_SYSEX 0xf0 1278 #define EV_MTC 0xf1 1279 #define EV_SPP 0xf2 1280 #define EV_SONGSEL 0xf3 1281 #define EV_TUNE_REQ 0xf6 1282 #define EV_SYSEX_STOP 0xf7 1283 1284 static int 1285 out_build_packet(int cable_number, struct umidi_packet *packet, 1286 uByte data, u_char *obuf) 1287 { 1288 if (data >= 0xf8) { /* is it a realtime message ? */ 1289 obuf[0] = data >> 4 | cable_number << 4; 1290 obuf[1] = data; 1291 obuf[2] = 0; 1292 obuf[3] = 0; 1293 return 1; 1294 } 1295 if (data >= 0xf0) { /* is it a common message ? */ 1296 switch(data) { 1297 case EV_SYSEX: 1298 packet->buf[1] = packet->status = data; 1299 packet->index = 2; 1300 break; 1301 case EV_SYSEX_STOP: 1302 if (packet->status != EV_SYSEX) break; 1303 if (packet->index == 0) 1304 packet->index = 1; 1305 packet->status = data; 1306 packet->buf[packet->index++] = data; 1307 packet->buf[0] = (0x4 - 1 + packet->index) | cable_number << 4; 1308 goto packetready; 1309 case EV_TUNE_REQ: 1310 packet->status = data; 1311 packet->buf[0] = 0x5 | cable_number << 4; 1312 packet->index = 1; 1313 goto packetready; 1314 default: 1315 packet->status = data; 1316 break; 1317 } 1318 return 0; 1319 } 1320 if (data >= 0x80) { /* is it a voice message ? */ 1321 packet->status = data; 1322 packet->index = 0; 1323 return 0; 1324 } 1325 1326 /* else it is a data byte */ 1327 if (packet->status >= 0xf0) { 1328 switch(packet->status) { 1329 case EV_SYSEX: /* sysex starts or continues */ 1330 if (packet->index == 0) 1331 packet->index = 1; 1332 1333 packet->buf[packet->index++] = data; 1334 if (packet->index >= UMIDI_PACKET_SIZE) { 1335 packet->buf[0] = 0x4 | cable_number << 4; 1336 goto packetready; 1337 } 1338 break; 1339 case EV_MTC: /* messages with 1 data byte */ 1340 case EV_SONGSEL: 1341 packet->buf[0] = 0x2 | cable_number << 4; 1342 packet->buf[1] = packet->status; 1343 packet->buf[2] = data; 1344 packet->index = 3; 1345 goto packetready; 1346 case EV_SPP: /* messages with 2 data bytes */ 1347 if (packet->index == 0) { 1348 packet->buf[0] = 0x3 | cable_number << 4; 1349 packet->index = 1; 1350 } 1351 packet->buf[packet->index++] = data; 1352 if (packet->index >= UMIDI_PACKET_SIZE) { 1353 packet->buf[1] = packet->status; 1354 goto packetready; 1355 } 1356 break; 1357 default: /* ignore data with unknown status */ 1358 break; 1359 } 1360 return 0; 1361 } 1362 if (packet->status >= 0x80) { /* is it a voice message ? */ 1363 if (packet->index == 0) { 1364 packet->buf[0] = packet->status >> 4 | cable_number << 4; 1365 packet->buf[1] = packet->status; 1366 packet->index = 2; 1367 } 1368 packet->buf[packet->index++] = data; 1369 if (packet->index >= UMIDI_VOICELEN(packet->status)) 1370 goto packetready; 1371 } 1372 /* ignore data with unknown status */ 1373 return 0; 1374 1375 packetready: 1376 while (packet->index < UMIDI_PACKET_SIZE) 1377 packet->buf[packet->index++] = 0; 1378 packet->index = 0; 1379 memcpy(obuf, packet->buf, UMIDI_PACKET_SIZE); 1380 return 1; 1381 } 1382