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