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