1 /* $NetBSD: umidi.c,v 1.24 2005/12/11 12:24:01 christos 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.24 2005/12/11 12:24:01 christos 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 *devinfop; 168 169 DPRINTFN(1,("umidi_attach\n")); 170 171 devinfop = usbd_devinfo_alloc(uaa->device, 0); 172 printf("\n%s: %s\n", USBDEVNAME(sc->sc_dev), devinfop); 173 usbd_devinfo_free(devinfop); 174 175 sc->sc_iface = uaa->iface; 176 sc->sc_udev = uaa->device; 177 178 sc->sc_quirk = 179 umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno); 180 printf("%s: ", USBDEVNAME(sc->sc_dev)); 181 umidi_print_quirk(sc->sc_quirk); 182 183 184 err = alloc_all_endpoints(sc); 185 if (err!=USBD_NORMAL_COMPLETION) { 186 printf("%s: alloc_all_endpoints failed. (err=%d)\n", 187 USBDEVNAME(sc->sc_dev), err); 188 goto error; 189 } 190 err = alloc_all_jacks(sc); 191 if (err!=USBD_NORMAL_COMPLETION) { 192 free_all_endpoints(sc); 193 printf("%s: alloc_all_jacks failed. (err=%d)\n", 194 USBDEVNAME(sc->sc_dev), err); 195 goto error; 196 } 197 printf("%s: out=%d, in=%d\n", 198 USBDEVNAME(sc->sc_dev), 199 sc->sc_out_num_jacks, sc->sc_in_num_jacks); 200 201 err = assign_all_jacks_automatically(sc); 202 if (err!=USBD_NORMAL_COMPLETION) { 203 unbind_all_jacks(sc); 204 free_all_jacks(sc); 205 free_all_endpoints(sc); 206 printf("%s: assign_all_jacks_automatically failed. (err=%d)\n", 207 USBDEVNAME(sc->sc_dev), err); 208 goto error; 209 } 210 err = attach_all_mididevs(sc); 211 if (err!=USBD_NORMAL_COMPLETION) { 212 free_all_jacks(sc); 213 free_all_endpoints(sc); 214 printf("%s: attach_all_mididevs failed. (err=%d)\n", 215 USBDEVNAME(sc->sc_dev), err); 216 } 217 218 #ifdef UMIDI_DEBUG 219 dump_sc(sc); 220 #endif 221 222 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, 223 sc->sc_udev, USBDEV(sc->sc_dev)); 224 225 USB_ATTACH_SUCCESS_RETURN; 226 error: 227 printf("%s: disabled.\n", USBDEVNAME(sc->sc_dev)); 228 sc->sc_dying = 1; 229 USB_ATTACH_ERROR_RETURN; 230 } 231 232 int 233 umidi_activate(device_ptr_t self, enum devact act) 234 { 235 struct umidi_softc *sc = (struct umidi_softc *)self; 236 237 switch (act) { 238 case DVACT_ACTIVATE: 239 DPRINTFN(1,("umidi_activate (activate)\n")); 240 241 return EOPNOTSUPP; 242 break; 243 case DVACT_DEACTIVATE: 244 DPRINTFN(1,("umidi_activate (deactivate)\n")); 245 sc->sc_dying = 1; 246 deactivate_all_mididevs(sc); 247 break; 248 } 249 return 0; 250 } 251 252 USB_DETACH(umidi) 253 { 254 USB_DETACH_START(umidi, sc); 255 256 DPRINTFN(1,("umidi_detach\n")); 257 258 sc->sc_dying = 1; 259 detach_all_mididevs(sc, flags); 260 free_all_mididevs(sc); 261 free_all_jacks(sc); 262 free_all_endpoints(sc); 263 264 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 265 USBDEV(sc->sc_dev)); 266 267 return 0; 268 } 269 270 271 /* 272 * midi_if stuffs 273 */ 274 int 275 umidi_open(void *addr, 276 int flags, 277 void (*iintr)(void *, int), 278 void (*ointr)(void *), 279 void *arg) 280 { 281 struct umidi_mididev *mididev = addr; 282 struct umidi_softc *sc = mididev->sc; 283 284 DPRINTF(("umidi_open: sc=%p\n", sc)); 285 286 if (!sc) 287 return ENXIO; 288 if (mididev->opened) 289 return EBUSY; 290 if (sc->sc_dying) 291 return EIO; 292 293 mididev->opened = 1; 294 mididev->flags = flags; 295 if ((mididev->flags & FWRITE) && mididev->out_jack) 296 open_out_jack(mididev->out_jack, arg, ointr); 297 if ((mididev->flags & FREAD) && mididev->in_jack) { 298 open_in_jack(mididev->in_jack, arg, iintr); 299 } 300 301 return 0; 302 } 303 304 void 305 umidi_close(void *addr) 306 { 307 int s; 308 struct umidi_mididev *mididev = addr; 309 310 s = splusb(); 311 if ((mididev->flags & FWRITE) && mididev->out_jack) 312 close_out_jack(mididev->out_jack); 313 if ((mididev->flags & FREAD) && mididev->in_jack) 314 close_in_jack(mididev->in_jack); 315 mididev->opened = 0; 316 splx(s); 317 } 318 319 int 320 umidi_output(void *addr, int d) 321 { 322 struct umidi_mididev *mididev = addr; 323 324 if (!mididev->out_jack || !mididev->opened) 325 return EIO; 326 327 return out_jack_output(mididev->out_jack, d); 328 } 329 330 void 331 umidi_getinfo(void *addr, struct midi_info *mi) 332 { 333 struct umidi_mididev *mididev = addr; 334 /* struct umidi_softc *sc = mididev->sc; */ 335 336 mi->name = "USB MIDI I/F"; /* XXX: model name */ 337 mi->props = MIDI_PROP_OUT_INTR; 338 if (mididev->in_jack) 339 mi->props |= MIDI_PROP_CAN_INPUT; 340 } 341 342 343 /* 344 * each endpoint stuffs 345 */ 346 347 /* alloc/free pipe */ 348 static usbd_status 349 alloc_pipe(struct umidi_endpoint *ep) 350 { 351 struct umidi_softc *sc = ep->sc; 352 usbd_status err; 353 354 DPRINTF(("%s: alloc_pipe %p\n", USBDEVNAME(sc->sc_dev), ep)); 355 LIST_INIT(&ep->queue_head); 356 ep->xfer = usbd_alloc_xfer(sc->sc_udev); 357 if (ep->xfer == NULL) { 358 err = USBD_NOMEM; 359 goto quit; 360 } 361 ep->buffer = usbd_alloc_buffer(ep->xfer, UMIDI_PACKET_SIZE); 362 if (ep->buffer == NULL) { 363 usbd_free_xfer(ep->xfer); 364 err = USBD_NOMEM; 365 goto quit; 366 } 367 err = usbd_open_pipe(sc->sc_iface, ep->addr, 0, &ep->pipe); 368 if (err) 369 usbd_free_xfer(ep->xfer); 370 quit: 371 return err; 372 } 373 374 static void 375 free_pipe(struct umidi_endpoint *ep) 376 { 377 DPRINTF(("%s: free_pipe %p\n", USBDEVNAME(ep->sc->sc_dev), ep)); 378 usbd_abort_pipe(ep->pipe); 379 usbd_close_pipe(ep->pipe); 380 usbd_free_xfer(ep->xfer); 381 } 382 383 384 /* alloc/free the array of endpoint structures */ 385 386 static usbd_status alloc_all_endpoints_fixed_ep(struct umidi_softc *); 387 static usbd_status alloc_all_endpoints_yamaha(struct umidi_softc *); 388 static usbd_status alloc_all_endpoints_genuine(struct umidi_softc *); 389 390 static usbd_status 391 alloc_all_endpoints(struct umidi_softc *sc) 392 { 393 usbd_status err; 394 struct umidi_endpoint *ep; 395 int i; 396 397 if (UMQ_ISTYPE(sc, UMQ_TYPE_FIXED_EP)) { 398 err = alloc_all_endpoints_fixed_ep(sc); 399 } else if (UMQ_ISTYPE(sc, UMQ_TYPE_YAMAHA)) { 400 err = alloc_all_endpoints_yamaha(sc); 401 } else { 402 err = alloc_all_endpoints_genuine(sc); 403 } 404 if (err!=USBD_NORMAL_COMPLETION) 405 return err; 406 407 ep = sc->sc_endpoints; 408 for (i=sc->sc_out_num_endpoints+sc->sc_in_num_endpoints; i>0; i--) { 409 err = alloc_pipe(ep++); 410 if (err!=USBD_NORMAL_COMPLETION) { 411 for (; ep!=sc->sc_endpoints; ep--) 412 free_pipe(ep-1); 413 free(sc->sc_endpoints, M_USBDEV); 414 sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL; 415 break; 416 } 417 } 418 return err; 419 } 420 421 static void 422 free_all_endpoints(struct umidi_softc *sc) 423 { 424 int i; 425 for (i=0; i<sc->sc_in_num_endpoints+sc->sc_out_num_endpoints; i++) 426 free_pipe(&sc->sc_endpoints[i]); 427 if (sc->sc_endpoints != NULL) 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_interface_descriptor_t *interface_desc; 620 usb_config_descriptor_t *config_desc; 621 usb_descriptor_t *desc; 622 int num_ep; 623 size_t remain, descsize; 624 struct umidi_endpoint *p, *q, *lowest, *endep, tmpep; 625 int epaddr; 626 627 interface_desc = usbd_get_interface_descriptor(sc->sc_iface); 628 num_ep = interface_desc->bNumEndpoints; 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 config_desc = usbd_get_config_descriptor(sc->sc_udev); 640 desc = (usb_descriptor_t *) config_desc; 641 remain = (size_t)UGETW(config_desc->wTotalLength); 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 & FREAD) && 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 err != USBD_IN_PROGRESS) { 896 ep->num_open--; 897 } 898 } 899 900 return err; 901 } 902 903 static void 904 close_out_jack(struct umidi_jack *jack) 905 { 906 struct umidi_jack *tail; 907 int s; 908 909 if (jack->opened) { 910 s = splusb(); 911 LIST_FOREACH(tail, 912 &jack->endpoint->queue_head, 913 u.out.queue_entry) 914 if (tail == jack) { 915 LIST_REMOVE(jack, u.out.queue_entry); 916 break; 917 } 918 if (jack == jack->endpoint->queue_tail) { 919 /* find tail */ 920 LIST_FOREACH(tail, 921 &jack->endpoint->queue_head, 922 u.out.queue_entry) { 923 if (!LIST_NEXT(tail, u.out.queue_entry)) { 924 jack->endpoint->queue_tail = tail; 925 } 926 } 927 } 928 splx(s); 929 jack->opened = 0; 930 jack->endpoint->num_open--; 931 } 932 } 933 934 static void 935 close_in_jack(struct umidi_jack *jack) 936 { 937 if (jack->opened) { 938 jack->opened = 0; 939 if (--jack->endpoint->num_open == 0) { 940 usbd_abort_pipe(jack->endpoint->pipe); 941 } 942 } 943 } 944 945 static usbd_status 946 attach_mididev(struct umidi_softc *sc, struct umidi_mididev *mididev) 947 { 948 if (mididev->sc) 949 return USBD_IN_USE; 950 951 mididev->sc = sc; 952 953 mididev->mdev = midi_attach_mi(&umidi_hw_if, mididev, &sc->sc_dev); 954 955 return USBD_NORMAL_COMPLETION; 956 } 957 958 static usbd_status 959 detach_mididev(struct umidi_mididev *mididev, int flags) 960 { 961 if (!mididev->sc) 962 return USBD_NO_ADDR; 963 964 if (mididev->opened) { 965 umidi_close(mididev); 966 } 967 unbind_jacks_from_mididev(mididev); 968 969 if (mididev->mdev) 970 config_detach(mididev->mdev, flags); 971 972 mididev->sc = NULL; 973 974 return USBD_NORMAL_COMPLETION; 975 } 976 977 static usbd_status 978 deactivate_mididev(struct umidi_mididev *mididev) 979 { 980 if (mididev->out_jack) 981 mididev->out_jack->binded = 0; 982 if (mididev->in_jack) 983 mididev->in_jack->binded = 0; 984 config_deactivate(mididev->mdev); 985 986 return USBD_NORMAL_COMPLETION; 987 } 988 989 static usbd_status 990 alloc_all_mididevs(struct umidi_softc *sc, int nmidi) 991 { 992 sc->sc_num_mididevs = nmidi; 993 sc->sc_mididevs = malloc(sizeof(*sc->sc_mididevs)*nmidi, 994 M_USBDEV, M_WAITOK|M_ZERO); 995 if (!sc->sc_mididevs) 996 return USBD_NOMEM; 997 998 return USBD_NORMAL_COMPLETION; 999 } 1000 1001 static void 1002 free_all_mididevs(struct umidi_softc *sc) 1003 { 1004 sc->sc_num_mididevs = 0; 1005 if (sc->sc_mididevs) 1006 free(sc->sc_mididevs, M_USBDEV); 1007 } 1008 1009 static usbd_status 1010 attach_all_mididevs(struct umidi_softc *sc) 1011 { 1012 usbd_status err; 1013 int i; 1014 1015 if (sc->sc_mididevs) 1016 for (i=0; i<sc->sc_num_mididevs; i++) { 1017 err = attach_mididev(sc, &sc->sc_mididevs[i]); 1018 if (err!=USBD_NORMAL_COMPLETION) 1019 return err; 1020 } 1021 1022 return USBD_NORMAL_COMPLETION; 1023 } 1024 1025 static usbd_status 1026 detach_all_mididevs(struct umidi_softc *sc, int flags) 1027 { 1028 usbd_status err; 1029 int i; 1030 1031 if (sc->sc_mididevs) 1032 for (i=0; i<sc->sc_num_mididevs; i++) { 1033 err = detach_mididev(&sc->sc_mididevs[i], flags); 1034 if (err!=USBD_NORMAL_COMPLETION) 1035 return err; 1036 } 1037 1038 return USBD_NORMAL_COMPLETION; 1039 } 1040 1041 static usbd_status 1042 deactivate_all_mididevs(struct umidi_softc *sc) 1043 { 1044 usbd_status err; 1045 int i; 1046 1047 if (sc->sc_mididevs) 1048 for (i=0; i<sc->sc_num_mididevs; i++) { 1049 err = deactivate_mididev(&sc->sc_mididevs[i]); 1050 if (err!=USBD_NORMAL_COMPLETION) 1051 return err; 1052 } 1053 1054 return USBD_NORMAL_COMPLETION; 1055 } 1056 1057 #ifdef UMIDI_DEBUG 1058 static void 1059 dump_sc(struct umidi_softc *sc) 1060 { 1061 int i; 1062 1063 DPRINTFN(10, ("%s: dump_sc\n", USBDEVNAME(sc->sc_dev))); 1064 for (i=0; i<sc->sc_out_num_endpoints; i++) { 1065 DPRINTFN(10, ("\tout_ep(%p):\n", &sc->sc_out_ep[i])); 1066 dump_ep(&sc->sc_out_ep[i]); 1067 } 1068 for (i=0; i<sc->sc_in_num_endpoints; i++) { 1069 DPRINTFN(10, ("\tin_ep(%p):\n", &sc->sc_in_ep[i])); 1070 dump_ep(&sc->sc_in_ep[i]); 1071 } 1072 } 1073 1074 static void 1075 dump_ep(struct umidi_endpoint *ep) 1076 { 1077 int i; 1078 for (i=0; i<ep->num_jacks; i++) { 1079 DPRINTFN(10, ("\t\tjack(%p):\n", ep->jacks[i])); 1080 dump_jack(ep->jacks[i]); 1081 } 1082 } 1083 static void 1084 dump_jack(struct umidi_jack *jack) 1085 { 1086 DPRINTFN(10, ("\t\t\tep=%p\n", 1087 jack->endpoint)); 1088 } 1089 1090 #endif /* UMIDI_DEBUG */ 1091 1092 1093 1094 /* 1095 * MUX MIDI PACKET 1096 */ 1097 1098 static const int packet_length[16] = { 1099 /*0*/ -1, 1100 /*1*/ -1, 1101 /*2*/ 2, 1102 /*3*/ 3, 1103 /*4*/ 3, 1104 /*5*/ 1, 1105 /*6*/ 2, 1106 /*7*/ 3, 1107 /*8*/ 3, 1108 /*9*/ 3, 1109 /*A*/ 3, 1110 /*B*/ 3, 1111 /*C*/ 2, 1112 /*D*/ 2, 1113 /*E*/ 3, 1114 /*F*/ 1, 1115 }; 1116 1117 static const struct { 1118 int cin; 1119 packet_state_t next; 1120 } packet_0xFX[16] = { 1121 /*F0: SysEx */ { 0x04, PS_EXCL_1 }, 1122 /*F1: MTC */ { 0x02, PS_NORMAL_1OF2 }, 1123 /*F2: S.POS */ { 0x03, PS_NORMAL_1OF3 }, 1124 /*F3: S.SEL */ { 0x02, PS_NORMAL_1OF2 }, 1125 /*F4: UNDEF */ { 0x00, PS_INITIAL }, 1126 /*F5: UNDEF */ { 0x00, PS_INITIAL }, 1127 /*F6: Tune */ { 0x0F, PS_END }, 1128 /*F7: EofEx */ { 0x00, PS_INITIAL }, 1129 /*F8: Timing */ { 0x0F, PS_END }, 1130 /*F9: UNDEF */ { 0x00, PS_INITIAL }, 1131 /*FA: Start */ { 0x0F, PS_END }, 1132 /*FB: Cont */ { 0x0F, PS_END }, 1133 /*FC: Stop */ { 0x0F, PS_END }, 1134 /*FD: UNDEF */ { 0x00, PS_INITIAL }, 1135 /*FE: ActS */ { 0x0F, PS_END }, 1136 /*FF: Reset */ { 0x0F, PS_END }, 1137 }; 1138 1139 #define GET_CN(p) (((unsigned char)(p)>>4)&0x0F) 1140 #define GET_CIN(p) ((unsigned char)(p)&0x0F) 1141 #define MIX_CN_CIN(cn, cin) \ 1142 ((unsigned char)((((unsigned char)(cn)&0x0F)<<4)| \ 1143 ((unsigned char)(cin)&0x0F))) 1144 1145 static void 1146 init_packet(struct umidi_packet *packet) 1147 { 1148 memset(packet->buffer, 0, UMIDI_PACKET_SIZE); 1149 packet->state = PS_INITIAL; 1150 } 1151 1152 static usbd_status 1153 start_input_transfer(struct umidi_endpoint *ep) 1154 { 1155 usbd_setup_xfer(ep->xfer, ep->pipe, 1156 (usbd_private_handle)ep, 1157 ep->buffer, UMIDI_PACKET_SIZE, 1158 USBD_NO_COPY, USBD_NO_TIMEOUT, in_intr); 1159 return usbd_transfer(ep->xfer); 1160 } 1161 1162 static usbd_status 1163 start_output_transfer(struct umidi_endpoint *ep) 1164 { 1165 usbd_setup_xfer(ep->xfer, ep->pipe, 1166 (usbd_private_handle)ep, 1167 ep->buffer, UMIDI_PACKET_SIZE, 1168 USBD_NO_COPY, USBD_NO_TIMEOUT, out_intr); 1169 return usbd_transfer(ep->xfer); 1170 } 1171 1172 #ifdef UMIDI_DEBUG 1173 #define DPR_PACKET(dir, sc, p) \ 1174 if ((unsigned char)(p)->buffer[1]!=0xFE) \ 1175 DPRINTFN(500, \ 1176 ("%s: umidi packet(" #dir "): %02X %02X %02X %02X\n", \ 1177 USBDEVNAME(sc->sc_dev), \ 1178 (unsigned char)(p)->buffer[0], \ 1179 (unsigned char)(p)->buffer[1], \ 1180 (unsigned char)(p)->buffer[2], \ 1181 (unsigned char)(p)->buffer[3])); 1182 #else 1183 #define DPR_PACKET(dir, sc, p) 1184 #endif 1185 1186 static int 1187 out_jack_output(struct umidi_jack *out_jack, int d) 1188 { 1189 struct umidi_endpoint *ep = out_jack->endpoint; 1190 struct umidi_softc *sc = ep->sc; 1191 int error; 1192 int s; 1193 1194 if (sc->sc_dying) 1195 return EIO; 1196 1197 error = 0; 1198 if (out_jack->opened) { 1199 DPRINTFN(1000, ("umidi_output: ep=%p 0x%02x\n", ep, d)); 1200 out_build_packet(out_jack->cable_number, &out_jack->packet, d); 1201 switch (out_jack->packet.state) { 1202 case PS_EXCL_0: 1203 case PS_END: 1204 DPR_PACKET(out, sc, &out_jack->packet); 1205 s = splusb(); 1206 if (LIST_EMPTY(&ep->queue_head)) { 1207 memcpy(ep->buffer, 1208 out_jack->packet.buffer, 1209 UMIDI_PACKET_SIZE); 1210 start_output_transfer(ep); 1211 } 1212 if (LIST_EMPTY(&ep->queue_head)) 1213 LIST_INSERT_HEAD(&ep->queue_head, 1214 out_jack, u.out.queue_entry); 1215 else 1216 LIST_INSERT_AFTER(ep->queue_tail, 1217 out_jack, u.out.queue_entry); 1218 ep->queue_tail = out_jack; 1219 splx(s); 1220 break; 1221 default: 1222 error = EINPROGRESS; 1223 } 1224 } else 1225 error = ENODEV; 1226 1227 return error; 1228 } 1229 1230 static void 1231 in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1232 { 1233 int cn, len, i; 1234 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv; 1235 struct umidi_jack *jack; 1236 1237 if (ep->sc->sc_dying || !ep->num_open) 1238 return; 1239 1240 cn = GET_CN(ep->buffer[0]); 1241 len = packet_length[GET_CIN(ep->buffer[0])]; 1242 jack = ep->jacks[cn]; 1243 if (cn>=ep->num_jacks || !jack) { 1244 DPRINTF(("%s: stray umidi packet (in): %02X %02X %02X %02X\n", 1245 USBDEVNAME(ep->sc->sc_dev), 1246 (unsigned)ep->buffer[0], 1247 (unsigned)ep->buffer[1], 1248 (unsigned)ep->buffer[2], 1249 (unsigned)ep->buffer[3])); 1250 return; 1251 } 1252 if (!jack->binded || !jack->opened) 1253 return; 1254 DPR_PACKET(in, ep->sc, &jack->packet); 1255 if (jack->u.in.intr) { 1256 for (i=0; i<len; i++) { 1257 (*jack->u.in.intr)(jack->arg, ep->buffer[i+1]); 1258 } 1259 } 1260 1261 (void)start_input_transfer(ep); 1262 } 1263 1264 static void 1265 out_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1266 { 1267 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv; 1268 struct umidi_softc *sc = ep->sc; 1269 struct umidi_jack *jack; 1270 1271 if (sc->sc_dying || !ep->num_open) 1272 return; 1273 1274 jack = LIST_FIRST(&ep->queue_head); 1275 if (jack && jack->opened) { 1276 LIST_REMOVE(jack, u.out.queue_entry); 1277 if (!LIST_EMPTY(&ep->queue_head)) { 1278 memcpy(ep->buffer, 1279 LIST_FIRST(&ep->queue_head)->packet.buffer, 1280 UMIDI_PACKET_SIZE); 1281 (void)start_output_transfer(ep); 1282 } 1283 if (jack->u.out.intr) { 1284 (*jack->u.out.intr)(jack->arg); 1285 } 1286 } 1287 } 1288 1289 static void 1290 out_build_packet(int cable_number, struct umidi_packet *packet, uByte in) 1291 { 1292 int cin; 1293 uByte prev; 1294 1295 retry: 1296 switch (packet->state) { 1297 case PS_END: 1298 case PS_INITIAL: 1299 prev = packet->buffer[1]; 1300 memset(packet->buffer, 0, UMIDI_PACKET_SIZE); 1301 if (in<0x80) { 1302 if (prev>=0x80 && prev<0xf0) { 1303 /* running status */ 1304 out_build_packet(cable_number, packet, prev); 1305 goto retry; 1306 } 1307 /* ??? */ 1308 break; 1309 } 1310 if (in>=0xf0) { 1311 cin=packet_0xFX[in&0x0F].cin; 1312 packet->state=packet_0xFX[in&0x0F].next; 1313 } else { 1314 cin=(unsigned char)in>>4; 1315 switch (packet_length[cin]) { 1316 case 2: 1317 packet->state = PS_NORMAL_1OF2; 1318 break; 1319 case 3: 1320 packet->state = PS_NORMAL_1OF3; 1321 break; 1322 default: 1323 /* ??? */ 1324 packet->state = PS_INITIAL; 1325 } 1326 } 1327 packet->buffer[0] = MIX_CN_CIN(cable_number, cin); 1328 packet->buffer[1] = in; 1329 break; 1330 case PS_NORMAL_1OF3: 1331 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1332 packet->buffer[2] = in; 1333 packet->state = PS_NORMAL_2OF3; 1334 break; 1335 case PS_NORMAL_2OF3: 1336 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1337 packet->buffer[3] = in; 1338 packet->state = PS_END; 1339 break; 1340 case PS_NORMAL_1OF2: 1341 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1342 packet->buffer[2] = in; 1343 packet->state = PS_END; 1344 break; 1345 case PS_EXCL_0: 1346 memset(packet->buffer, 0, UMIDI_PACKET_SIZE); 1347 if (in==0xF7) { 1348 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x05); 1349 packet->buffer[1] = 0xF7; 1350 packet->state = PS_END; 1351 break; 1352 } 1353 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1354 packet->buffer[1] = in; 1355 packet->state = PS_EXCL_1; 1356 break; 1357 case PS_EXCL_1: 1358 if (in==0xF7) { 1359 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x06); 1360 packet->buffer[2] = 0xF7; 1361 packet->state = PS_END; 1362 break; 1363 } 1364 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1365 packet->buffer[2] = in; 1366 packet->state = PS_EXCL_2; 1367 break; 1368 case PS_EXCL_2: 1369 if (in==0xF7) { 1370 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x07); 1371 packet->buffer[3] = 0xF7; 1372 packet->state = PS_END; 1373 break; 1374 } 1375 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1376 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x04); 1377 packet->buffer[3] = in; 1378 packet->state = PS_EXCL_0; 1379 break; 1380 default: 1381 printf("umidi: ambiguous state.\n"); 1382 packet->state = PS_INITIAL; 1383 goto retry; 1384 } 1385 } 1386 1387