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