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