1 /* $NetBSD: umidi.c,v 1.14 2002/03/08 17:24:06 kent Exp $ */ 2 /* 3 * Copyright (c) 2001 The NetBSD Foundation, Inc. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to The NetBSD Foundation 7 * by Takuya SHIOZAKI (tshiozak@netbsd.org). 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the NetBSD 20 * Foundation, Inc. and its contributors. 21 * 4. Neither the name of The NetBSD Foundation nor the names of its 22 * contributors may be used to endorse or promote products derived 23 * from this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: umidi.c,v 1.14 2002/03/08 17:24:06 kent Exp $"); 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/kernel.h> 44 #include <sys/malloc.h> 45 #include <sys/device.h> 46 #include <sys/ioctl.h> 47 #include <sys/conf.h> 48 #include <sys/file.h> 49 #include <sys/select.h> 50 #include <sys/proc.h> 51 #include <sys/vnode.h> 52 #include <sys/poll.h> 53 #include <sys/lock.h> 54 55 #include <dev/usb/usb.h> 56 #include <dev/usb/usbdi.h> 57 #include <dev/usb/usbdi_util.h> 58 59 #include <dev/usb/usbdevs.h> 60 #include <dev/usb/uaudioreg.h> 61 #include <dev/usb/umidireg.h> 62 #include <dev/usb/umidivar.h> 63 #include <dev/usb/umidi_quirks.h> 64 65 #include <dev/midi_if.h> 66 67 #ifdef UMIDI_DEBUG 68 #define DPRINTF(x) if (umididebug) printf x 69 #define DPRINTFN(n,x) if (umididebug >= (n)) printf x 70 int umididebug = 0; 71 #else 72 #define DPRINTF(x) 73 #define DPRINTFN(n,x) 74 #endif 75 76 77 static int umidi_open(void *, int, 78 void (*)(void *, int), void (*)(void *), void *); 79 static void umidi_close(void *); 80 static int umidi_output(void *, int); 81 static void umidi_getinfo(void *, struct midi_info *); 82 83 static usbd_status alloc_pipe(struct umidi_endpoint *); 84 static void free_pipe(struct umidi_endpoint *); 85 86 static usbd_status alloc_all_endpoints(struct umidi_softc *); 87 static void free_all_endpoints(struct umidi_softc *); 88 89 static usbd_status alloc_all_jacks(struct umidi_softc *); 90 static void free_all_jacks(struct umidi_softc *); 91 static usbd_status bind_jacks_to_mididev(struct umidi_softc *, 92 struct umidi_jack *, 93 struct umidi_jack *, 94 struct umidi_mididev *); 95 static void unbind_jacks_from_mididev(struct umidi_mididev *); 96 static void unbind_all_jacks(struct umidi_softc *); 97 static usbd_status assign_all_jacks_automatically(struct umidi_softc *); 98 static usbd_status open_out_jack(struct umidi_jack *, void *, 99 void (*)(void *)); 100 static usbd_status open_in_jack(struct umidi_jack *, void *, 101 void (*)(void *, int)); 102 static void close_out_jack(struct umidi_jack *); 103 static void close_in_jack(struct umidi_jack *); 104 105 static usbd_status attach_mididev(struct umidi_softc *, 106 struct umidi_mididev *); 107 static usbd_status detach_mididev(struct umidi_mididev *, int); 108 static usbd_status deactivate_mididev(struct umidi_mididev *); 109 static usbd_status alloc_all_mididevs(struct umidi_softc *, int); 110 static void free_all_mididevs(struct umidi_softc *); 111 static usbd_status attach_all_mididevs(struct umidi_softc *); 112 static usbd_status detach_all_mididevs(struct umidi_softc *, int); 113 static usbd_status deactivate_all_mididevs(struct umidi_softc *); 114 115 #ifdef UMIDI_DEBUG 116 static void dump_sc(struct umidi_softc *); 117 static void dump_ep(struct umidi_endpoint *); 118 static void dump_jack(struct umidi_jack *); 119 #endif 120 121 static void init_packet(struct umidi_packet *); 122 123 static usbd_status start_input_transfer(struct umidi_endpoint *); 124 static usbd_status start_output_transfer(struct umidi_endpoint *); 125 static int out_jack_output(struct umidi_jack *, int); 126 static void in_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); 127 static void out_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); 128 static void out_build_packet(int, struct umidi_packet *, uByte); 129 130 131 struct midi_hw_if umidi_hw_if = { 132 umidi_open, 133 umidi_close, 134 umidi_output, 135 umidi_getinfo, 136 0, /* ioctl */ 137 }; 138 139 USB_DECLARE_DRIVER(umidi); 140 141 USB_MATCH(umidi) 142 { 143 USB_MATCH_START(umidi, uaa); 144 usb_interface_descriptor_t *id; 145 146 DPRINTFN(1,("umidi_match\n")); 147 148 if (uaa->iface == NULL) 149 return UMATCH_NONE; 150 151 if (umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno)) 152 return UMATCH_IFACECLASS_IFACESUBCLASS; 153 154 id = usbd_get_interface_descriptor(uaa->iface); 155 if (id!=NULL && 156 id->bInterfaceClass==UICLASS_AUDIO && 157 id->bInterfaceSubClass==UISUBCLASS_MIDISTREAM) 158 return UMATCH_IFACECLASS_IFACESUBCLASS; 159 160 return UMATCH_NONE; 161 } 162 163 USB_ATTACH(umidi) 164 { 165 usbd_status err; 166 USB_ATTACH_START(umidi, sc, uaa); 167 char devinfo[1024]; 168 169 DPRINTFN(1,("umidi_attach\n")); 170 171 usbd_devinfo(uaa->device, 0, devinfo); 172 printf("\n%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo); 173 174 sc->sc_iface = uaa->iface; 175 sc->sc_udev = uaa->device; 176 177 sc->sc_quirk = 178 umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno); 179 printf("%s: ", USBDEVNAME(sc->sc_dev)); 180 umidi_print_quirk(sc->sc_quirk); 181 182 183 err = alloc_all_endpoints(sc); 184 if (err!=USBD_NORMAL_COMPLETION) { 185 printf("%s: alloc_all_endpoints failed. (err=%d)\n", 186 USBDEVNAME(sc->sc_dev), err); 187 goto error; 188 } 189 err = alloc_all_jacks(sc); 190 if (err!=USBD_NORMAL_COMPLETION) { 191 free_all_endpoints(sc); 192 printf("%s: alloc_all_jacks failed. (err=%d)\n", 193 USBDEVNAME(sc->sc_dev), err); 194 goto error; 195 } 196 printf("%s: out=%d, in=%d\n", 197 USBDEVNAME(sc->sc_dev), 198 sc->sc_out_num_jacks, sc->sc_in_num_jacks); 199 200 err = assign_all_jacks_automatically(sc); 201 if (err!=USBD_NORMAL_COMPLETION) { 202 unbind_all_jacks(sc); 203 free_all_jacks(sc); 204 free_all_endpoints(sc); 205 printf("%s: assign_all_jacks_automatically failed. (err=%d)\n", 206 USBDEVNAME(sc->sc_dev), err); 207 goto error; 208 } 209 err = attach_all_mididevs(sc); 210 if (err!=USBD_NORMAL_COMPLETION) { 211 free_all_jacks(sc); 212 free_all_endpoints(sc); 213 printf("%s: attach_all_mididevs failed. (err=%d)\n", 214 USBDEVNAME(sc->sc_dev), err); 215 } 216 217 #ifdef UMIDI_DEBUG 218 dump_sc(sc); 219 #endif 220 221 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, 222 sc->sc_udev, USBDEV(sc->sc_dev)); 223 224 USB_ATTACH_SUCCESS_RETURN; 225 error: 226 printf("%s: disabled.\n", USBDEVNAME(sc->sc_dev)); 227 sc->sc_dying = 1; 228 USB_ATTACH_ERROR_RETURN; 229 } 230 231 int 232 umidi_activate(device_ptr_t self, enum devact act) 233 { 234 struct umidi_softc *sc = (struct umidi_softc *)self; 235 236 switch (act) { 237 case DVACT_ACTIVATE: 238 DPRINTFN(1,("umidi_activate (activate)\n")); 239 240 return EOPNOTSUPP; 241 break; 242 case DVACT_DEACTIVATE: 243 DPRINTFN(1,("umidi_activate (deactivate)\n")); 244 sc->sc_dying = 1; 245 deactivate_all_mididevs(sc); 246 break; 247 } 248 return 0; 249 } 250 251 USB_DETACH(umidi) 252 { 253 USB_DETACH_START(umidi, sc); 254 255 DPRINTFN(1,("umidi_detach\n")); 256 257 sc->sc_dying = 1; 258 detach_all_mididevs(sc, flags); 259 free_all_mididevs(sc); 260 free_all_jacks(sc); 261 free_all_endpoints(sc); 262 263 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 264 USBDEV(sc->sc_dev)); 265 266 return 0; 267 } 268 269 270 /* 271 * midi_if stuffs 272 */ 273 int 274 umidi_open(void *addr, 275 int flags, 276 void (*iintr)(void *, int), 277 void (*ointr)(void *), 278 void *arg) 279 { 280 struct umidi_mididev *mididev = addr; 281 struct umidi_softc *sc = mididev->sc; 282 283 DPRINTF(("umidi_open: sc=%p\n", sc)); 284 285 if (!sc) 286 return ENXIO; 287 if (mididev->opened) 288 return EBUSY; 289 if (sc->sc_dying) 290 return EIO; 291 292 mididev->opened = 1; 293 mididev->flags = flags; 294 if ((mididev->flags & FWRITE) && mididev->out_jack) 295 open_out_jack(mididev->out_jack, arg, ointr); 296 if ((mididev->flags & FREAD) && mididev->in_jack) { 297 open_in_jack(mididev->in_jack, arg, iintr); 298 } 299 300 return 0; 301 } 302 303 void 304 umidi_close(void *addr) 305 { 306 int s; 307 struct umidi_mididev *mididev = addr; 308 309 s = splusb(); 310 if ((mididev->flags & FWRITE) && mididev->out_jack) 311 close_out_jack(mididev->out_jack); 312 if ((mididev->flags & FREAD) && mididev->in_jack) 313 close_in_jack(mididev->in_jack); 314 mididev->opened = 0; 315 splx(s); 316 } 317 318 int 319 umidi_output(void *addr, int d) 320 { 321 struct umidi_mididev *mididev = addr; 322 323 if (!mididev->out_jack || !mididev->opened) 324 return EIO; 325 326 return out_jack_output(mididev->out_jack, d); 327 } 328 329 void 330 umidi_getinfo(void *addr, struct midi_info *mi) 331 { 332 struct umidi_mididev *mididev = addr; 333 /* struct umidi_softc *sc = mididev->sc; */ 334 335 mi->name = "USB MIDI I/F"; /* XXX: model name */ 336 mi->props = MIDI_PROP_OUT_INTR; 337 if (mididev->in_jack) 338 mi->props |= MIDI_PROP_CAN_INPUT; 339 } 340 341 342 /* 343 * each endpoint stuffs 344 */ 345 346 /* alloc/free pipe */ 347 static usbd_status 348 alloc_pipe(struct umidi_endpoint *ep) 349 { 350 struct umidi_softc *sc = ep->sc; 351 usbd_status err; 352 353 DPRINTF(("%s: alloc_pipe %p\n", USBDEVNAME(sc->sc_dev), ep)); 354 LIST_INIT(&ep->queue_head); 355 ep->xfer = usbd_alloc_xfer(sc->sc_udev); 356 if (ep->xfer == NULL) { 357 err = USBD_NOMEM; 358 goto quit; 359 } 360 ep->buffer = usbd_alloc_buffer(ep->xfer, UMIDI_PACKET_SIZE); 361 if (ep->buffer == NULL) { 362 usbd_free_xfer(ep->xfer); 363 err = USBD_NOMEM; 364 goto quit; 365 } 366 err = usbd_open_pipe(sc->sc_iface, ep->addr, 0, &ep->pipe); 367 if (err) 368 usbd_free_xfer(ep->xfer); 369 quit: 370 return err; 371 } 372 373 static void 374 free_pipe(struct umidi_endpoint *ep) 375 { 376 DPRINTF(("%s: free_pipe %p\n", USBDEVNAME(ep->sc->sc_dev), ep)); 377 usbd_abort_pipe(ep->pipe); 378 usbd_close_pipe(ep->pipe); 379 usbd_free_xfer(ep->xfer); 380 } 381 382 383 /* alloc/free the array of endpoint structures */ 384 385 static usbd_status alloc_all_endpoints_fixed_ep(struct umidi_softc *); 386 static usbd_status alloc_all_endpoints_yamaha(struct umidi_softc *); 387 static usbd_status alloc_all_endpoints_genuine(struct umidi_softc *); 388 389 static usbd_status 390 alloc_all_endpoints(struct umidi_softc *sc) 391 { 392 usbd_status err; 393 struct umidi_endpoint *ep; 394 int i; 395 396 if (UMQ_ISTYPE(sc, UMQ_TYPE_FIXED_EP)) { 397 err = alloc_all_endpoints_fixed_ep(sc); 398 } else if (UMQ_ISTYPE(sc, UMQ_TYPE_YAMAHA)) { 399 err = alloc_all_endpoints_yamaha(sc); 400 } else { 401 err = alloc_all_endpoints_genuine(sc); 402 } 403 if (err!=USBD_NORMAL_COMPLETION) 404 return err; 405 406 ep = sc->sc_endpoints; 407 for (i=sc->sc_out_num_endpoints+sc->sc_in_num_endpoints; i>0; i--) { 408 err = alloc_pipe(ep++); 409 if (err!=USBD_NORMAL_COMPLETION) { 410 for (; ep!=sc->sc_endpoints; ep--) 411 free_pipe(ep-1); 412 free(sc->sc_endpoints, M_USBDEV); 413 sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL; 414 break; 415 } 416 } 417 return err; 418 } 419 420 static void 421 free_all_endpoints(struct umidi_softc *sc) 422 { 423 int i; 424 for (i=0; i<sc->sc_in_num_endpoints+sc->sc_out_num_endpoints; i++) 425 free_pipe(&sc->sc_endpoints[i]); 426 if (sc->sc_endpoints != NULL) 427 free(sc->sc_endpoints, M_USBDEV); 428 sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL; 429 } 430 431 static usbd_status 432 alloc_all_endpoints_fixed_ep(struct umidi_softc *sc) 433 { 434 usbd_status err; 435 struct umq_fixed_ep_desc *fp; 436 struct umidi_endpoint *ep; 437 usb_endpoint_descriptor_t *epd; 438 int i; 439 440 fp = umidi_get_quirk_data_from_type(sc->sc_quirk, 441 UMQ_TYPE_FIXED_EP); 442 sc->sc_out_num_jacks = 0; 443 sc->sc_in_num_jacks = 0; 444 sc->sc_out_num_endpoints = fp->num_out_ep; 445 sc->sc_in_num_endpoints = fp->num_in_ep; 446 sc->sc_endpoints = malloc(sizeof(*sc->sc_out_ep)* 447 (sc->sc_out_num_endpoints+ 448 sc->sc_in_num_endpoints), 449 M_USBDEV, M_WAITOK); 450 if (!sc->sc_endpoints) { 451 return USBD_NOMEM; 452 } 453 sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL; 454 sc->sc_in_ep = 455 sc->sc_in_num_endpoints ? 456 sc->sc_endpoints+sc->sc_out_num_endpoints : NULL; 457 458 ep = &sc->sc_out_ep[0]; 459 for (i=0; i<sc->sc_out_num_endpoints; i++) { 460 epd = usbd_interface2endpoint_descriptor( 461 sc->sc_iface, 462 fp->out_ep[i].ep); 463 if (!epd) { 464 printf("%s: cannot get endpoint descriptor(out:%d)\n", 465 USBDEVNAME(sc->sc_dev), fp->out_ep[i].ep); 466 err = USBD_INVAL; 467 goto error; 468 } 469 if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK || 470 UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_OUT) { 471 printf("%s: illegal endpoint(out:%d)\n", 472 USBDEVNAME(sc->sc_dev), fp->out_ep[i].ep); 473 err = USBD_INVAL; 474 goto error; 475 } 476 ep->sc = sc; 477 ep->addr = epd->bEndpointAddress; 478 ep->num_jacks = fp->out_ep[i].num_jacks; 479 sc->sc_out_num_jacks += fp->out_ep[i].num_jacks; 480 ep->num_open = 0; 481 memset(ep->jacks, 0, sizeof(ep->jacks)); 482 LIST_INIT(&ep->queue_head); 483 ep++; 484 } 485 ep = &sc->sc_in_ep[0]; 486 for (i=0; i<sc->sc_in_num_endpoints; i++) { 487 epd = usbd_interface2endpoint_descriptor( 488 sc->sc_iface, 489 fp->in_ep[i].ep); 490 if (!epd) { 491 printf("%s: cannot get endpoint descriptor(in:%d)\n", 492 USBDEVNAME(sc->sc_dev), fp->in_ep[i].ep); 493 err = USBD_INVAL; 494 goto error; 495 } 496 if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK || 497 UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_IN) { 498 printf("%s: illegal endpoint(in:%d)\n", 499 USBDEVNAME(sc->sc_dev), fp->in_ep[i].ep); 500 err = USBD_INVAL; 501 goto error; 502 } 503 ep->sc = sc; 504 ep->addr = epd->bEndpointAddress; 505 ep->num_jacks = fp->in_ep[i].num_jacks; 506 sc->sc_in_num_jacks += fp->in_ep[i].num_jacks; 507 ep->num_open = 0; 508 memset(ep->jacks, 0, sizeof(ep->jacks)); 509 ep++; 510 } 511 512 return USBD_NORMAL_COMPLETION; 513 error: 514 free(sc->sc_endpoints, M_USBDEV); 515 sc->sc_endpoints = NULL; 516 return err; 517 } 518 519 static usbd_status 520 alloc_all_endpoints_yamaha(struct umidi_softc *sc) 521 { 522 /* This driver currently supports max 1in/1out bulk endpoints */ 523 usb_descriptor_t *desc; 524 usb_endpoint_descriptor_t *epd; 525 int out_addr, in_addr, i; 526 int dir; 527 size_t remain, descsize; 528 529 sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0; 530 out_addr = in_addr = 0; 531 532 /* detect endpoints */ 533 desc = TO_D(usbd_get_interface_descriptor(sc->sc_iface)); 534 for (i=(int)TO_IFD(desc)->bNumEndpoints-1; i>=0; i--) { 535 epd = usbd_interface2endpoint_descriptor(sc->sc_iface, i); 536 if (UE_GET_XFERTYPE(epd->bmAttributes) == UE_BULK) { 537 dir = UE_GET_DIR(epd->bEndpointAddress); 538 if (dir==UE_DIR_OUT && !out_addr) 539 out_addr = epd->bEndpointAddress; 540 else if (dir==UE_DIR_IN && !in_addr) 541 in_addr = epd->bEndpointAddress; 542 } 543 } 544 desc = NEXT_D(desc); 545 546 /* count jacks */ 547 if (!(desc->bDescriptorType==UDESC_CS_INTERFACE && 548 desc->bDescriptorSubtype==UMIDI_MS_HEADER)) 549 return USBD_INVAL; 550 remain = (size_t)UGETW(TO_CSIFD(desc)->wTotalLength) - 551 (size_t)desc->bLength; 552 desc = NEXT_D(desc); 553 554 while (remain>=sizeof(usb_descriptor_t)) { 555 descsize = desc->bLength; 556 if (descsize>remain || descsize==0) 557 break; 558 if (desc->bDescriptorType==UDESC_CS_INTERFACE && 559 remain>=UMIDI_JACK_DESCRIPTOR_SIZE) { 560 if (desc->bDescriptorSubtype==UMIDI_OUT_JACK) 561 sc->sc_out_num_jacks++; 562 else if (desc->bDescriptorSubtype==UMIDI_IN_JACK) 563 sc->sc_in_num_jacks++; 564 } 565 desc = NEXT_D(desc); 566 remain-=descsize; 567 } 568 569 /* validate some parameters */ 570 if (sc->sc_out_num_jacks>UMIDI_MAX_EPJACKS) 571 sc->sc_out_num_jacks = UMIDI_MAX_EPJACKS; 572 if (sc->sc_in_num_jacks>UMIDI_MAX_EPJACKS) 573 sc->sc_in_num_jacks = UMIDI_MAX_EPJACKS; 574 if (sc->sc_out_num_jacks && out_addr) { 575 sc->sc_out_num_endpoints = 1; 576 } else { 577 sc->sc_out_num_endpoints = 0; 578 sc->sc_out_num_jacks = 0; 579 } 580 if (sc->sc_in_num_jacks && in_addr) { 581 sc->sc_in_num_endpoints = 1; 582 } else { 583 sc->sc_in_num_endpoints = 0; 584 sc->sc_in_num_jacks = 0; 585 } 586 sc->sc_endpoints = malloc(sizeof(struct umidi_endpoint)* 587 (sc->sc_out_num_endpoints+ 588 sc->sc_in_num_endpoints), 589 M_USBDEV, M_WAITOK); 590 if (!sc->sc_endpoints) 591 return USBD_NOMEM; 592 if (sc->sc_out_num_endpoints) { 593 sc->sc_out_ep = sc->sc_endpoints; 594 sc->sc_out_ep->sc = sc; 595 sc->sc_out_ep->addr = out_addr; 596 sc->sc_out_ep->num_jacks = sc->sc_out_num_jacks; 597 sc->sc_out_ep->num_open = 0; 598 memset(sc->sc_out_ep->jacks, 0, sizeof(sc->sc_out_ep->jacks)); 599 } else 600 sc->sc_out_ep = NULL; 601 602 if (sc->sc_in_num_endpoints) { 603 sc->sc_in_ep = sc->sc_endpoints+sc->sc_out_num_endpoints; 604 sc->sc_in_ep->sc = sc; 605 sc->sc_in_ep->addr = in_addr; 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_descriptor_t *desc; 619 int num_ep; 620 size_t remain, descsize; 621 struct umidi_endpoint *p, *q, *lowest, *endep, tmpep; 622 int epaddr; 623 624 desc = TO_D(usbd_get_interface_descriptor(sc->sc_iface)); 625 num_ep = TO_IFD(desc)->bNumEndpoints; 626 desc = NEXT_D(desc); /* ifd -> csifd */ 627 remain = ((size_t)UGETW(TO_CSIFD(desc)->wTotalLength) - 628 (size_t)desc->bLength); 629 desc = NEXT_D(desc); 630 631 sc->sc_endpoints = p = malloc(sizeof(struct umidi_endpoint)*num_ep, 632 M_USBDEV, M_WAITOK); 633 if (!p) 634 return USBD_NOMEM; 635 636 sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0; 637 sc->sc_out_num_endpoints = sc->sc_in_num_endpoints = 0; 638 epaddr = -1; 639 640 /* get the list of endpoints for midi stream */ 641 while (remain>=sizeof(usb_descriptor_t)) { 642 descsize = desc->bLength; 643 if (descsize>remain || descsize==0) 644 break; 645 if (desc->bDescriptorType==UDESC_ENDPOINT && 646 remain>=USB_ENDPOINT_DESCRIPTOR_SIZE && 647 UE_GET_XFERTYPE(TO_EPD(desc)->bmAttributes) == UE_BULK) { 648 epaddr = TO_EPD(desc)->bEndpointAddress; 649 } else if (desc->bDescriptorType==UDESC_CS_ENDPOINT && 650 remain>=UMIDI_CS_ENDPOINT_DESCRIPTOR_SIZE && 651 epaddr!=-1) { 652 if (num_ep>0) { 653 num_ep--; 654 p->sc = sc; 655 p->addr = epaddr; 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 = 718 malloc(sizeof(*sc->sc_out_jacks)*(sc->sc_in_num_jacks+ 719 sc->sc_out_num_jacks), 720 M_USBDEV, M_WAITOK); 721 if (!sc->sc_jacks) 722 return USBD_NOMEM; 723 sc->sc_out_jacks = 724 sc->sc_out_num_jacks ? sc->sc_jacks : NULL; 725 sc->sc_in_jacks = 726 sc->sc_in_num_jacks ? sc->sc_jacks+sc->sc_out_num_jacks : NULL; 727 728 jack = &sc->sc_out_jacks[0]; 729 for (i=0; i<sc->sc_out_num_jacks; i++) { 730 jack->opened = 0; 731 jack->binded = 0; 732 jack->arg = NULL; 733 jack->u.out.intr = NULL; 734 jack->cable_number = i; 735 jack++; 736 } 737 jack = &sc->sc_in_jacks[0]; 738 for (i=0; i<sc->sc_in_num_jacks; i++) { 739 jack->opened = 0; 740 jack->binded = 0; 741 jack->arg = NULL; 742 jack->u.in.intr = NULL; 743 jack->cable_number = i; 744 jack++; 745 } 746 747 /* assign each jacks to each endpoints */ 748 jack = &sc->sc_out_jacks[0]; 749 ep = &sc->sc_out_ep[0]; 750 for (i=0; i<sc->sc_out_num_endpoints; i++) { 751 rjack = &ep->jacks[0]; 752 for (j=0; j<ep->num_jacks; j++) { 753 *rjack = jack; 754 jack->endpoint = ep; 755 jack++; 756 rjack++; 757 } 758 ep++; 759 } 760 jack = &sc->sc_in_jacks[0]; 761 ep = &sc->sc_in_ep[0]; 762 for (i=0; i<sc->sc_in_num_endpoints; i++) { 763 rjack = &ep->jacks[0]; 764 for (j=0; j<ep->num_jacks; j++) { 765 *rjack = jack; 766 jack->endpoint = ep; 767 jack++; 768 rjack++; 769 } 770 ep++; 771 } 772 773 return USBD_NORMAL_COMPLETION; 774 } 775 776 static void 777 free_all_jacks(struct umidi_softc *sc) 778 { 779 int s; 780 781 s = splaudio(); 782 if (sc->sc_out_jacks) { 783 free(sc->sc_jacks, M_USBDEV); 784 sc->sc_jacks = sc->sc_in_jacks = sc->sc_out_jacks = NULL; 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_out_jack(mididev->out_jack); 815 if ((mididev->flags&FWRITE) && mididev->in_jack) 816 close_in_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 struct umidi_endpoint *ep = jack->endpoint; 866 867 if (jack->opened) 868 return USBD_IN_USE; 869 870 jack->arg = arg; 871 jack->u.out.intr = intr; 872 init_packet(&jack->packet); 873 jack->opened = 1; 874 ep->num_open++; 875 876 return USBD_NORMAL_COMPLETION; 877 } 878 879 static usbd_status 880 open_in_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *, int)) 881 { 882 usbd_status err = USBD_NORMAL_COMPLETION; 883 struct umidi_endpoint *ep = jack->endpoint; 884 885 if (jack->opened) 886 return USBD_IN_USE; 887 888 jack->arg = arg; 889 jack->u.in.intr = intr; 890 jack->opened = 1; 891 if (ep->num_open++==0 && UE_GET_DIR(ep->addr)==UE_DIR_IN) { 892 err = start_input_transfer(ep); 893 if (err!=USBD_NORMAL_COMPLETION) { 894 ep->num_open--; 895 } 896 } 897 898 return err; 899 } 900 901 static void 902 close_out_jack(struct umidi_jack *jack) 903 { 904 struct umidi_jack *tail; 905 int s; 906 907 if (jack->opened) { 908 s = splusb(); 909 LIST_REMOVE(jack, u.out.queue_entry); 910 if (jack==jack->endpoint->queue_tail) { 911 /* find tail */ 912 LIST_FOREACH(tail, 913 &jack->endpoint->queue_head, 914 u.out.queue_entry) { 915 if (!LIST_NEXT(tail, u.out.queue_entry)) { 916 jack->endpoint->queue_tail = tail; 917 } 918 } 919 } 920 splx(s); 921 jack->opened = 0; 922 jack->endpoint->num_open--; 923 } 924 } 925 926 static void 927 close_in_jack(struct umidi_jack *jack) 928 { 929 if (jack->opened) { 930 jack->opened = 0; 931 jack->endpoint->num_open--; 932 } 933 } 934 935 static usbd_status 936 attach_mididev(struct umidi_softc *sc, struct umidi_mididev *mididev) 937 { 938 if (mididev->sc) 939 return USBD_IN_USE; 940 941 mididev->sc = sc; 942 943 mididev->mdev = midi_attach_mi(&umidi_hw_if, mididev, &sc->sc_dev); 944 945 return USBD_NORMAL_COMPLETION; 946 } 947 948 static usbd_status 949 detach_mididev(struct umidi_mididev *mididev, int flags) 950 { 951 if (!mididev->sc) 952 return USBD_NO_ADDR; 953 954 if (mididev->opened) { 955 umidi_close(mididev); 956 } 957 unbind_jacks_from_mididev(mididev); 958 959 if (mididev->mdev) 960 config_detach(mididev->mdev, flags); 961 962 mididev->sc = NULL; 963 964 return USBD_NORMAL_COMPLETION; 965 } 966 967 static usbd_status 968 deactivate_mididev(struct umidi_mididev *mididev) 969 { 970 if (mididev->out_jack) 971 mididev->out_jack->binded = 0; 972 if (mididev->in_jack) 973 mididev->in_jack->binded = 0; 974 config_deactivate(mididev->mdev); 975 976 return USBD_NORMAL_COMPLETION; 977 } 978 979 static usbd_status 980 alloc_all_mididevs(struct umidi_softc *sc, int nmidi) 981 { 982 sc->sc_num_mididevs = nmidi; 983 sc->sc_mididevs = malloc(sizeof(*sc->sc_mididevs)*nmidi, 984 M_USBDEV, M_WAITOK|M_ZERO); 985 if (!sc->sc_mididevs) 986 return USBD_NOMEM; 987 988 return USBD_NORMAL_COMPLETION; 989 } 990 991 static void 992 free_all_mididevs(struct umidi_softc *sc) 993 { 994 sc->sc_num_mididevs = 0; 995 if (sc->sc_mididevs) 996 free(sc->sc_mididevs, M_USBDEV); 997 } 998 999 static usbd_status 1000 attach_all_mididevs(struct umidi_softc *sc) 1001 { 1002 usbd_status err; 1003 int i; 1004 1005 if (sc->sc_mididevs) 1006 for (i=0; i<sc->sc_num_mididevs; i++) { 1007 err = attach_mididev(sc, &sc->sc_mididevs[i]); 1008 if (err!=USBD_NORMAL_COMPLETION) 1009 return err; 1010 } 1011 1012 return USBD_NORMAL_COMPLETION; 1013 } 1014 1015 static usbd_status 1016 detach_all_mididevs(struct umidi_softc *sc, int flags) 1017 { 1018 usbd_status err; 1019 int i; 1020 1021 if (sc->sc_mididevs) 1022 for (i=0; i<sc->sc_num_mididevs; i++) { 1023 err = detach_mididev(&sc->sc_mididevs[i], flags); 1024 if (err!=USBD_NORMAL_COMPLETION) 1025 return err; 1026 } 1027 1028 return USBD_NORMAL_COMPLETION; 1029 } 1030 1031 static usbd_status 1032 deactivate_all_mididevs(struct umidi_softc *sc) 1033 { 1034 usbd_status err; 1035 int i; 1036 1037 if (sc->sc_mididevs) 1038 for (i=0; i<sc->sc_num_mididevs; i++) { 1039 err = deactivate_mididev(&sc->sc_mididevs[i]); 1040 if (err!=USBD_NORMAL_COMPLETION) 1041 return err; 1042 } 1043 1044 return USBD_NORMAL_COMPLETION; 1045 } 1046 1047 #ifdef UMIDI_DEBUG 1048 static void 1049 dump_sc(struct umidi_softc *sc) 1050 { 1051 int i; 1052 1053 DPRINTFN(10, ("%s: dump_sc\n", USBDEVNAME(sc->sc_dev))); 1054 for (i=0; i<sc->sc_out_num_endpoints; i++) { 1055 DPRINTFN(10, ("\tout_ep(%p):\n", &sc->sc_out_ep[i])); 1056 dump_ep(&sc->sc_out_ep[i]); 1057 } 1058 for (i=0; i<sc->sc_in_num_endpoints; i++) { 1059 DPRINTFN(10, ("\tin_ep(%p):\n", &sc->sc_in_ep[i])); 1060 dump_ep(&sc->sc_in_ep[i]); 1061 } 1062 } 1063 1064 static void 1065 dump_ep(struct umidi_endpoint *ep) 1066 { 1067 int i; 1068 for (i=0; i<ep->num_jacks; i++) { 1069 DPRINTFN(10, ("\t\tjack(%p):\n", ep->jacks[i])); 1070 dump_jack(ep->jacks[i]); 1071 } 1072 } 1073 static void 1074 dump_jack(struct umidi_jack *jack) 1075 { 1076 DPRINTFN(10, ("\t\t\tep=%p, mididev=%p\n", 1077 jack->endpoint, jack->mididev)); 1078 } 1079 1080 #endif /* UMIDI_DEBUG */ 1081 1082 1083 1084 /* 1085 * MUX MIDI PACKET 1086 */ 1087 1088 static const int packet_length[16] = { 1089 /*0*/ -1, 1090 /*1*/ -1, 1091 /*2*/ 2, 1092 /*3*/ 3, 1093 /*4*/ 3, 1094 /*5*/ 1, 1095 /*6*/ 2, 1096 /*7*/ 3, 1097 /*8*/ 3, 1098 /*9*/ 3, 1099 /*A*/ 3, 1100 /*B*/ 3, 1101 /*C*/ 2, 1102 /*D*/ 2, 1103 /*E*/ 3, 1104 /*F*/ 1, 1105 }; 1106 1107 static const struct { 1108 int cin; 1109 packet_state_t next; 1110 } packet_0xFX[16] = { 1111 /*F0: SysEx */ { 0x04, PS_EXCL_1 }, 1112 /*F1: MTC */ { 0x02, PS_NORMAL_1OF2 }, 1113 /*F2: S.POS */ { 0x03, PS_NORMAL_1OF3 }, 1114 /*F3: S.SEL */ { 0x02, PS_NORMAL_1OF2 }, 1115 /*F4: UNDEF */ { 0x00, PS_INITIAL }, 1116 /*F5: UNDEF */ { 0x00, PS_INITIAL }, 1117 /*F6: Tune */ { 0x0F, PS_END }, 1118 /*F7: EofEx */ { 0x00, PS_INITIAL }, 1119 /*F8: Timing */ { 0x0F, PS_END }, 1120 /*F9: UNDEF */ { 0x00, PS_INITIAL }, 1121 /*FA: Start */ { 0x0F, PS_END }, 1122 /*FB: Cont */ { 0x0F, PS_END }, 1123 /*FC: Stop */ { 0x0F, PS_END }, 1124 /*FD: UNDEF */ { 0x00, PS_INITIAL }, 1125 /*FE: ActS */ { 0x0F, PS_END }, 1126 /*FF: Reset */ { 0x0F, PS_END }, 1127 }; 1128 1129 #define GET_CN(p) (((unsigned char)(p)>>4)&0x0F) 1130 #define GET_CIN(p) ((unsigned char)(p)&0x0F) 1131 #define MIX_CN_CIN(cn, cin) \ 1132 ((unsigned char)((((unsigned char)(cn)&0x0F)<<4)| \ 1133 ((unsigned char)(cin)&0x0F))) 1134 1135 static void 1136 init_packet(struct umidi_packet *packet) 1137 { 1138 memset(packet->buffer, 0, UMIDI_PACKET_SIZE); 1139 packet->state = PS_INITIAL; 1140 } 1141 1142 static usbd_status 1143 start_input_transfer(struct umidi_endpoint *ep) 1144 { 1145 usbd_setup_xfer(ep->xfer, ep->pipe, 1146 (usbd_private_handle)ep, 1147 ep->buffer, UMIDI_PACKET_SIZE, 1148 USBD_NO_COPY, USBD_NO_TIMEOUT, in_intr); 1149 return usbd_transfer(ep->xfer); 1150 } 1151 1152 static usbd_status 1153 start_output_transfer(struct umidi_endpoint *ep) 1154 { 1155 usbd_setup_xfer(ep->xfer, ep->pipe, 1156 (usbd_private_handle)ep, 1157 ep->buffer, UMIDI_PACKET_SIZE, 1158 USBD_NO_COPY, USBD_NO_TIMEOUT, out_intr); 1159 return usbd_transfer(ep->xfer); 1160 } 1161 1162 #ifdef UMIDI_DEBUG 1163 #define DPR_PACKET(dir, sc, p) \ 1164 if ((unsigned char)(p)->buffer[1]!=0xFE) \ 1165 DPRINTFN(500, \ 1166 ("%s: umidi packet(" #dir "): %02X %02X %02X %02X\n", \ 1167 USBDEVNAME(sc->sc_dev), \ 1168 (unsigned char)(p)->buffer[0], \ 1169 (unsigned char)(p)->buffer[1], \ 1170 (unsigned char)(p)->buffer[2], \ 1171 (unsigned char)(p)->buffer[3])); 1172 #else 1173 #define DPR_PACKET(dir, sc, p) 1174 #endif 1175 1176 static int 1177 out_jack_output(struct umidi_jack *out_jack, int d) 1178 { 1179 struct umidi_endpoint *ep = out_jack->endpoint; 1180 struct umidi_softc *sc = ep->sc; 1181 int error; 1182 int s; 1183 1184 if (sc->sc_dying) 1185 return EIO; 1186 1187 error = 0; 1188 if (out_jack->opened) { 1189 DPRINTFN(1000, ("umidi_output: ep=%p 0x%02x\n", ep, d)); 1190 out_build_packet(out_jack->cable_number, &out_jack->packet, d); 1191 switch (out_jack->packet.state) { 1192 case PS_EXCL_0: 1193 case PS_END: 1194 DPR_PACKET(out, sc, &out_jack->packet); 1195 s = splusb(); 1196 if (LIST_EMPTY(&ep->queue_head)) { 1197 memcpy(ep->buffer, 1198 out_jack->packet.buffer, 1199 UMIDI_PACKET_SIZE); 1200 start_output_transfer(ep); 1201 } 1202 if (LIST_EMPTY(&ep->queue_head)) 1203 LIST_INSERT_HEAD(&ep->queue_head, 1204 out_jack, u.out.queue_entry); 1205 else 1206 LIST_INSERT_AFTER(ep->queue_tail, 1207 out_jack, u.out.queue_entry); 1208 ep->queue_tail = out_jack; 1209 splx(s); 1210 break; 1211 default: 1212 error = EINPROGRESS; 1213 } 1214 } else 1215 error = ENODEV; 1216 1217 return error; 1218 } 1219 1220 static void 1221 in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1222 { 1223 int cn, len, i; 1224 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv; 1225 struct umidi_jack *jack; 1226 1227 if (ep->sc->sc_dying || !ep->num_open) 1228 return; 1229 1230 cn = GET_CN(ep->buffer[0]); 1231 len = packet_length[GET_CIN(ep->buffer[0])]; 1232 jack = ep->jacks[cn]; 1233 if (cn>=ep->num_jacks || !jack) { 1234 DPRINTF(("%s: stray umidi packet (in): %02X %02X %02X %02X\n", 1235 USBDEVNAME(ep->sc->sc_dev), 1236 (unsigned)ep->buffer[0], 1237 (unsigned)ep->buffer[1], 1238 (unsigned)ep->buffer[2], 1239 (unsigned)ep->buffer[3])); 1240 return; 1241 } 1242 if (!jack->binded || !jack->opened) 1243 return; 1244 DPR_PACKET(in, ep->sc, &jack->buffer); 1245 if (jack->u.in.intr) { 1246 for (i=0; i<len; i++) { 1247 (*jack->u.in.intr)(jack->arg, ep->buffer[i+1]); 1248 } 1249 } 1250 1251 (void)start_input_transfer(ep); 1252 } 1253 1254 static void 1255 out_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1256 { 1257 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv; 1258 struct umidi_softc *sc = ep->sc; 1259 struct umidi_jack *jack; 1260 1261 if (sc->sc_dying || !ep->num_open) 1262 return; 1263 1264 jack = LIST_FIRST(&ep->queue_head); 1265 if (jack && jack->opened) { 1266 LIST_REMOVE(jack, u.out.queue_entry); 1267 if (!LIST_EMPTY(&ep->queue_head)) { 1268 memcpy(ep->buffer, 1269 LIST_FIRST(&ep->queue_head)->packet.buffer, 1270 UMIDI_PACKET_SIZE); 1271 (void)start_output_transfer(ep); 1272 } 1273 if (jack->u.out.intr) { 1274 (*jack->u.out.intr)(jack->arg); 1275 } 1276 } 1277 } 1278 1279 static void 1280 out_build_packet(int cable_number, struct umidi_packet *packet, uByte in) 1281 { 1282 int cin; 1283 uByte prev; 1284 1285 retry: 1286 switch (packet->state) { 1287 case PS_END: 1288 case PS_INITIAL: 1289 prev = packet->buffer[1]; 1290 memset(packet->buffer, 0, UMIDI_PACKET_SIZE); 1291 if (in<0x80) { 1292 if (prev>=0x80 && prev<0xf0) { 1293 /* running status */ 1294 out_build_packet(cable_number, packet, prev); 1295 goto retry; 1296 } 1297 /* ??? */ 1298 break; 1299 } 1300 if (in>=0xf0) { 1301 cin=packet_0xFX[in&0x0F].cin; 1302 packet->state=packet_0xFX[in&0x0F].next; 1303 } else { 1304 cin=(unsigned char)in>>4; 1305 switch (packet_length[cin]) { 1306 case 2: 1307 packet->state = PS_NORMAL_1OF2; 1308 break; 1309 case 3: 1310 packet->state = PS_NORMAL_1OF3; 1311 break; 1312 default: 1313 /* ??? */ 1314 packet->state = PS_INITIAL; 1315 } 1316 } 1317 packet->buffer[0] = MIX_CN_CIN(cable_number, cin); 1318 packet->buffer[1] = in; 1319 break; 1320 case PS_NORMAL_1OF3: 1321 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1322 packet->buffer[2] = in; 1323 packet->state = PS_NORMAL_2OF3; 1324 break; 1325 case PS_NORMAL_2OF3: 1326 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1327 packet->buffer[3] = in; 1328 packet->state = PS_END; 1329 break; 1330 case PS_NORMAL_1OF2: 1331 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1332 packet->buffer[2] = in; 1333 packet->state = PS_END; 1334 break; 1335 case PS_EXCL_0: 1336 memset(packet->buffer, 0, UMIDI_PACKET_SIZE); 1337 if (in==0xF7) { 1338 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x05); 1339 packet->buffer[1] = 0xF7; 1340 packet->state = PS_END; 1341 break; 1342 } 1343 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1344 packet->buffer[1] = in; 1345 packet->state = PS_EXCL_1; 1346 break; 1347 case PS_EXCL_1: 1348 if (in==0xF7) { 1349 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x06); 1350 packet->buffer[2] = 0xF7; 1351 packet->state = PS_END; 1352 break; 1353 } 1354 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1355 packet->buffer[2] = in; 1356 packet->state = PS_EXCL_2; 1357 break; 1358 case PS_EXCL_2: 1359 if (in==0xF7) { 1360 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x07); 1361 packet->buffer[3] = 0xF7; 1362 packet->state = PS_END; 1363 break; 1364 } 1365 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1366 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x04); 1367 packet->buffer[3] = in; 1368 packet->state = PS_EXCL_0; 1369 break; 1370 default: 1371 printf("umidi: ambiguous state.\n"); 1372 packet->state = PS_INITIAL; 1373 goto retry; 1374 } 1375 } 1376 1377