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