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