1 /* $NetBSD: umidi.c,v 1.22 2004/10/29 12:57:26 yamt 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.22 2004/10/29 12:57:26 yamt 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 const 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, sizeof(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_interface_descriptor_t *interface_desc; 619 usb_config_descriptor_t *config_desc; 620 usb_descriptor_t *desc; 621 int num_ep; 622 size_t remain, descsize; 623 struct umidi_endpoint *p, *q, *lowest, *endep, tmpep; 624 int epaddr; 625 626 interface_desc = usbd_get_interface_descriptor(sc->sc_iface); 627 num_ep = interface_desc->bNumEndpoints; 628 sc->sc_endpoints = p = malloc(sizeof(struct umidi_endpoint) * num_ep, 629 M_USBDEV, M_WAITOK); 630 if (!p) 631 return USBD_NOMEM; 632 633 sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0; 634 sc->sc_out_num_endpoints = sc->sc_in_num_endpoints = 0; 635 epaddr = -1; 636 637 /* get the list of endpoints for midi stream */ 638 config_desc = usbd_get_config_descriptor(sc->sc_udev); 639 desc = (usb_descriptor_t *) config_desc; 640 remain = (size_t)UGETW(config_desc->wTotalLength); 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 & FREAD) && 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 err != USBD_IN_PROGRESS) { 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_FOREACH(tail, 911 &jack->endpoint->queue_head, 912 u.out.queue_entry) 913 if (tail == jack) { 914 LIST_REMOVE(jack, u.out.queue_entry); 915 break; 916 } 917 if (jack == jack->endpoint->queue_tail) { 918 /* find tail */ 919 LIST_FOREACH(tail, 920 &jack->endpoint->queue_head, 921 u.out.queue_entry) { 922 if (!LIST_NEXT(tail, u.out.queue_entry)) { 923 jack->endpoint->queue_tail = tail; 924 } 925 } 926 } 927 splx(s); 928 jack->opened = 0; 929 jack->endpoint->num_open--; 930 } 931 } 932 933 static void 934 close_in_jack(struct umidi_jack *jack) 935 { 936 if (jack->opened) { 937 jack->opened = 0; 938 if (--jack->endpoint->num_open == 0) { 939 usbd_abort_pipe(jack->endpoint->pipe); 940 } 941 } 942 } 943 944 static usbd_status 945 attach_mididev(struct umidi_softc *sc, struct umidi_mididev *mididev) 946 { 947 if (mididev->sc) 948 return USBD_IN_USE; 949 950 mididev->sc = sc; 951 952 mididev->mdev = midi_attach_mi(&umidi_hw_if, mididev, &sc->sc_dev); 953 954 return USBD_NORMAL_COMPLETION; 955 } 956 957 static usbd_status 958 detach_mididev(struct umidi_mididev *mididev, int flags) 959 { 960 if (!mididev->sc) 961 return USBD_NO_ADDR; 962 963 if (mididev->opened) { 964 umidi_close(mididev); 965 } 966 unbind_jacks_from_mididev(mididev); 967 968 if (mididev->mdev) 969 config_detach(mididev->mdev, flags); 970 971 mididev->sc = NULL; 972 973 return USBD_NORMAL_COMPLETION; 974 } 975 976 static usbd_status 977 deactivate_mididev(struct umidi_mididev *mididev) 978 { 979 if (mididev->out_jack) 980 mididev->out_jack->binded = 0; 981 if (mididev->in_jack) 982 mididev->in_jack->binded = 0; 983 config_deactivate(mididev->mdev); 984 985 return USBD_NORMAL_COMPLETION; 986 } 987 988 static usbd_status 989 alloc_all_mididevs(struct umidi_softc *sc, int nmidi) 990 { 991 sc->sc_num_mididevs = nmidi; 992 sc->sc_mididevs = malloc(sizeof(*sc->sc_mididevs)*nmidi, 993 M_USBDEV, M_WAITOK|M_ZERO); 994 if (!sc->sc_mididevs) 995 return USBD_NOMEM; 996 997 return USBD_NORMAL_COMPLETION; 998 } 999 1000 static void 1001 free_all_mididevs(struct umidi_softc *sc) 1002 { 1003 sc->sc_num_mididevs = 0; 1004 if (sc->sc_mididevs) 1005 free(sc->sc_mididevs, M_USBDEV); 1006 } 1007 1008 static usbd_status 1009 attach_all_mididevs(struct umidi_softc *sc) 1010 { 1011 usbd_status err; 1012 int i; 1013 1014 if (sc->sc_mididevs) 1015 for (i=0; i<sc->sc_num_mididevs; i++) { 1016 err = attach_mididev(sc, &sc->sc_mididevs[i]); 1017 if (err!=USBD_NORMAL_COMPLETION) 1018 return err; 1019 } 1020 1021 return USBD_NORMAL_COMPLETION; 1022 } 1023 1024 static usbd_status 1025 detach_all_mididevs(struct umidi_softc *sc, int flags) 1026 { 1027 usbd_status err; 1028 int i; 1029 1030 if (sc->sc_mididevs) 1031 for (i=0; i<sc->sc_num_mididevs; i++) { 1032 err = detach_mididev(&sc->sc_mididevs[i], flags); 1033 if (err!=USBD_NORMAL_COMPLETION) 1034 return err; 1035 } 1036 1037 return USBD_NORMAL_COMPLETION; 1038 } 1039 1040 static usbd_status 1041 deactivate_all_mididevs(struct umidi_softc *sc) 1042 { 1043 usbd_status err; 1044 int i; 1045 1046 if (sc->sc_mididevs) 1047 for (i=0; i<sc->sc_num_mididevs; i++) { 1048 err = deactivate_mididev(&sc->sc_mididevs[i]); 1049 if (err!=USBD_NORMAL_COMPLETION) 1050 return err; 1051 } 1052 1053 return USBD_NORMAL_COMPLETION; 1054 } 1055 1056 #ifdef UMIDI_DEBUG 1057 static void 1058 dump_sc(struct umidi_softc *sc) 1059 { 1060 int i; 1061 1062 DPRINTFN(10, ("%s: dump_sc\n", USBDEVNAME(sc->sc_dev))); 1063 for (i=0; i<sc->sc_out_num_endpoints; i++) { 1064 DPRINTFN(10, ("\tout_ep(%p):\n", &sc->sc_out_ep[i])); 1065 dump_ep(&sc->sc_out_ep[i]); 1066 } 1067 for (i=0; i<sc->sc_in_num_endpoints; i++) { 1068 DPRINTFN(10, ("\tin_ep(%p):\n", &sc->sc_in_ep[i])); 1069 dump_ep(&sc->sc_in_ep[i]); 1070 } 1071 } 1072 1073 static void 1074 dump_ep(struct umidi_endpoint *ep) 1075 { 1076 int i; 1077 for (i=0; i<ep->num_jacks; i++) { 1078 DPRINTFN(10, ("\t\tjack(%p):\n", ep->jacks[i])); 1079 dump_jack(ep->jacks[i]); 1080 } 1081 } 1082 static void 1083 dump_jack(struct umidi_jack *jack) 1084 { 1085 DPRINTFN(10, ("\t\t\tep=%p\n", 1086 jack->endpoint)); 1087 } 1088 1089 #endif /* UMIDI_DEBUG */ 1090 1091 1092 1093 /* 1094 * MUX MIDI PACKET 1095 */ 1096 1097 static const int packet_length[16] = { 1098 /*0*/ -1, 1099 /*1*/ -1, 1100 /*2*/ 2, 1101 /*3*/ 3, 1102 /*4*/ 3, 1103 /*5*/ 1, 1104 /*6*/ 2, 1105 /*7*/ 3, 1106 /*8*/ 3, 1107 /*9*/ 3, 1108 /*A*/ 3, 1109 /*B*/ 3, 1110 /*C*/ 2, 1111 /*D*/ 2, 1112 /*E*/ 3, 1113 /*F*/ 1, 1114 }; 1115 1116 static const struct { 1117 int cin; 1118 packet_state_t next; 1119 } packet_0xFX[16] = { 1120 /*F0: SysEx */ { 0x04, PS_EXCL_1 }, 1121 /*F1: MTC */ { 0x02, PS_NORMAL_1OF2 }, 1122 /*F2: S.POS */ { 0x03, PS_NORMAL_1OF3 }, 1123 /*F3: S.SEL */ { 0x02, PS_NORMAL_1OF2 }, 1124 /*F4: UNDEF */ { 0x00, PS_INITIAL }, 1125 /*F5: UNDEF */ { 0x00, PS_INITIAL }, 1126 /*F6: Tune */ { 0x0F, PS_END }, 1127 /*F7: EofEx */ { 0x00, PS_INITIAL }, 1128 /*F8: Timing */ { 0x0F, PS_END }, 1129 /*F9: UNDEF */ { 0x00, PS_INITIAL }, 1130 /*FA: Start */ { 0x0F, PS_END }, 1131 /*FB: Cont */ { 0x0F, PS_END }, 1132 /*FC: Stop */ { 0x0F, PS_END }, 1133 /*FD: UNDEF */ { 0x00, PS_INITIAL }, 1134 /*FE: ActS */ { 0x0F, PS_END }, 1135 /*FF: Reset */ { 0x0F, PS_END }, 1136 }; 1137 1138 #define GET_CN(p) (((unsigned char)(p)>>4)&0x0F) 1139 #define GET_CIN(p) ((unsigned char)(p)&0x0F) 1140 #define MIX_CN_CIN(cn, cin) \ 1141 ((unsigned char)((((unsigned char)(cn)&0x0F)<<4)| \ 1142 ((unsigned char)(cin)&0x0F))) 1143 1144 static void 1145 init_packet(struct umidi_packet *packet) 1146 { 1147 memset(packet->buffer, 0, UMIDI_PACKET_SIZE); 1148 packet->state = PS_INITIAL; 1149 } 1150 1151 static usbd_status 1152 start_input_transfer(struct umidi_endpoint *ep) 1153 { 1154 usbd_setup_xfer(ep->xfer, ep->pipe, 1155 (usbd_private_handle)ep, 1156 ep->buffer, UMIDI_PACKET_SIZE, 1157 USBD_NO_COPY, USBD_NO_TIMEOUT, in_intr); 1158 return usbd_transfer(ep->xfer); 1159 } 1160 1161 static usbd_status 1162 start_output_transfer(struct umidi_endpoint *ep) 1163 { 1164 usbd_setup_xfer(ep->xfer, ep->pipe, 1165 (usbd_private_handle)ep, 1166 ep->buffer, UMIDI_PACKET_SIZE, 1167 USBD_NO_COPY, USBD_NO_TIMEOUT, out_intr); 1168 return usbd_transfer(ep->xfer); 1169 } 1170 1171 #ifdef UMIDI_DEBUG 1172 #define DPR_PACKET(dir, sc, p) \ 1173 if ((unsigned char)(p)->buffer[1]!=0xFE) \ 1174 DPRINTFN(500, \ 1175 ("%s: umidi packet(" #dir "): %02X %02X %02X %02X\n", \ 1176 USBDEVNAME(sc->sc_dev), \ 1177 (unsigned char)(p)->buffer[0], \ 1178 (unsigned char)(p)->buffer[1], \ 1179 (unsigned char)(p)->buffer[2], \ 1180 (unsigned char)(p)->buffer[3])); 1181 #else 1182 #define DPR_PACKET(dir, sc, p) 1183 #endif 1184 1185 static int 1186 out_jack_output(struct umidi_jack *out_jack, int d) 1187 { 1188 struct umidi_endpoint *ep = out_jack->endpoint; 1189 struct umidi_softc *sc = ep->sc; 1190 int error; 1191 int s; 1192 1193 if (sc->sc_dying) 1194 return EIO; 1195 1196 error = 0; 1197 if (out_jack->opened) { 1198 DPRINTFN(1000, ("umidi_output: ep=%p 0x%02x\n", ep, d)); 1199 out_build_packet(out_jack->cable_number, &out_jack->packet, d); 1200 switch (out_jack->packet.state) { 1201 case PS_EXCL_0: 1202 case PS_END: 1203 DPR_PACKET(out, sc, &out_jack->packet); 1204 s = splusb(); 1205 if (LIST_EMPTY(&ep->queue_head)) { 1206 memcpy(ep->buffer, 1207 out_jack->packet.buffer, 1208 UMIDI_PACKET_SIZE); 1209 start_output_transfer(ep); 1210 } 1211 if (LIST_EMPTY(&ep->queue_head)) 1212 LIST_INSERT_HEAD(&ep->queue_head, 1213 out_jack, u.out.queue_entry); 1214 else 1215 LIST_INSERT_AFTER(ep->queue_tail, 1216 out_jack, u.out.queue_entry); 1217 ep->queue_tail = out_jack; 1218 splx(s); 1219 break; 1220 default: 1221 error = EINPROGRESS; 1222 } 1223 } else 1224 error = ENODEV; 1225 1226 return error; 1227 } 1228 1229 static void 1230 in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1231 { 1232 int cn, len, i; 1233 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv; 1234 struct umidi_jack *jack; 1235 1236 if (ep->sc->sc_dying || !ep->num_open) 1237 return; 1238 1239 cn = GET_CN(ep->buffer[0]); 1240 len = packet_length[GET_CIN(ep->buffer[0])]; 1241 jack = ep->jacks[cn]; 1242 if (cn>=ep->num_jacks || !jack) { 1243 DPRINTF(("%s: stray umidi packet (in): %02X %02X %02X %02X\n", 1244 USBDEVNAME(ep->sc->sc_dev), 1245 (unsigned)ep->buffer[0], 1246 (unsigned)ep->buffer[1], 1247 (unsigned)ep->buffer[2], 1248 (unsigned)ep->buffer[3])); 1249 return; 1250 } 1251 if (!jack->binded || !jack->opened) 1252 return; 1253 DPR_PACKET(in, ep->sc, &jack->packet); 1254 if (jack->u.in.intr) { 1255 for (i=0; i<len; i++) { 1256 (*jack->u.in.intr)(jack->arg, ep->buffer[i+1]); 1257 } 1258 } 1259 1260 (void)start_input_transfer(ep); 1261 } 1262 1263 static void 1264 out_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1265 { 1266 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv; 1267 struct umidi_softc *sc = ep->sc; 1268 struct umidi_jack *jack; 1269 1270 if (sc->sc_dying || !ep->num_open) 1271 return; 1272 1273 jack = LIST_FIRST(&ep->queue_head); 1274 if (jack && jack->opened) { 1275 LIST_REMOVE(jack, u.out.queue_entry); 1276 if (!LIST_EMPTY(&ep->queue_head)) { 1277 memcpy(ep->buffer, 1278 LIST_FIRST(&ep->queue_head)->packet.buffer, 1279 UMIDI_PACKET_SIZE); 1280 (void)start_output_transfer(ep); 1281 } 1282 if (jack->u.out.intr) { 1283 (*jack->u.out.intr)(jack->arg); 1284 } 1285 } 1286 } 1287 1288 static void 1289 out_build_packet(int cable_number, struct umidi_packet *packet, uByte in) 1290 { 1291 int cin; 1292 uByte prev; 1293 1294 retry: 1295 switch (packet->state) { 1296 case PS_END: 1297 case PS_INITIAL: 1298 prev = packet->buffer[1]; 1299 memset(packet->buffer, 0, UMIDI_PACKET_SIZE); 1300 if (in<0x80) { 1301 if (prev>=0x80 && prev<0xf0) { 1302 /* running status */ 1303 out_build_packet(cable_number, packet, prev); 1304 goto retry; 1305 } 1306 /* ??? */ 1307 break; 1308 } 1309 if (in>=0xf0) { 1310 cin=packet_0xFX[in&0x0F].cin; 1311 packet->state=packet_0xFX[in&0x0F].next; 1312 } else { 1313 cin=(unsigned char)in>>4; 1314 switch (packet_length[cin]) { 1315 case 2: 1316 packet->state = PS_NORMAL_1OF2; 1317 break; 1318 case 3: 1319 packet->state = PS_NORMAL_1OF3; 1320 break; 1321 default: 1322 /* ??? */ 1323 packet->state = PS_INITIAL; 1324 } 1325 } 1326 packet->buffer[0] = MIX_CN_CIN(cable_number, cin); 1327 packet->buffer[1] = in; 1328 break; 1329 case PS_NORMAL_1OF3: 1330 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1331 packet->buffer[2] = in; 1332 packet->state = PS_NORMAL_2OF3; 1333 break; 1334 case PS_NORMAL_2OF3: 1335 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1336 packet->buffer[3] = in; 1337 packet->state = PS_END; 1338 break; 1339 case PS_NORMAL_1OF2: 1340 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1341 packet->buffer[2] = in; 1342 packet->state = PS_END; 1343 break; 1344 case PS_EXCL_0: 1345 memset(packet->buffer, 0, UMIDI_PACKET_SIZE); 1346 if (in==0xF7) { 1347 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x05); 1348 packet->buffer[1] = 0xF7; 1349 packet->state = PS_END; 1350 break; 1351 } 1352 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1353 packet->buffer[1] = in; 1354 packet->state = PS_EXCL_1; 1355 break; 1356 case PS_EXCL_1: 1357 if (in==0xF7) { 1358 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x06); 1359 packet->buffer[2] = 0xF7; 1360 packet->state = PS_END; 1361 break; 1362 } 1363 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1364 packet->buffer[2] = in; 1365 packet->state = PS_EXCL_2; 1366 break; 1367 case PS_EXCL_2: 1368 if (in==0xF7) { 1369 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x07); 1370 packet->buffer[3] = 0xF7; 1371 packet->state = PS_END; 1372 break; 1373 } 1374 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1375 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x04); 1376 packet->buffer[3] = in; 1377 packet->state = PS_EXCL_0; 1378 break; 1379 default: 1380 printf("umidi: ambiguous state.\n"); 1381 packet->state = PS_INITIAL; 1382 goto retry; 1383 } 1384 } 1385 1386