1 /* $NetBSD: umidi.c,v 1.9 2001/09/29 22:00:47 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 395 if (UMQ_ISTYPE(sc, UMQ_TYPE_FIXED_EP)) { 396 err = alloc_all_endpoints_fixed_ep(sc); 397 } else if (UMQ_ISTYPE(sc, UMQ_TYPE_YAMAHA)) { 398 err = alloc_all_endpoints_yamaha(sc); 399 } else { 400 err = alloc_all_endpoints_genuine(sc); 401 } 402 if (err!=USBD_NORMAL_COMPLETION) 403 return err; 404 405 ep = sc->sc_endpoints; 406 for (i=sc->sc_out_num_endpoints+sc->sc_in_num_endpoints; i>0; i--) { 407 err = alloc_pipe(ep++); 408 if (err!=USBD_NORMAL_COMPLETION) { 409 for (; ep!=sc->sc_endpoints; ep--) 410 free_pipe(ep-1); 411 free(sc->sc_endpoints, M_USBDEV); 412 sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL; 413 break; 414 } 415 } 416 return err; 417 } 418 419 static void 420 free_all_endpoints(struct umidi_softc *sc) 421 { 422 int i; 423 for (i=0; i<sc->sc_in_num_endpoints+sc->sc_out_num_endpoints; i++) 424 free_pipe(&sc->sc_endpoints[i]); 425 free(sc->sc_endpoints, M_USBDEV); 426 sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL; 427 } 428 429 static usbd_status 430 alloc_all_endpoints_fixed_ep(struct umidi_softc *sc) 431 { 432 usbd_status err; 433 struct umq_fixed_ep_desc *fp; 434 struct umidi_endpoint *ep; 435 usb_endpoint_descriptor_t *epd; 436 int i; 437 438 fp = umidi_get_quirk_data_from_type(sc->sc_quirk, 439 UMQ_TYPE_FIXED_EP); 440 sc->sc_out_num_jacks = 0; 441 sc->sc_in_num_jacks = 0; 442 sc->sc_out_num_endpoints = fp->num_out_ep; 443 sc->sc_in_num_endpoints = fp->num_in_ep; 444 sc->sc_endpoints = malloc(sizeof(*sc->sc_out_ep)* 445 (sc->sc_out_num_endpoints+ 446 sc->sc_in_num_endpoints), 447 M_USBDEV, M_WAITOK); 448 if (!sc->sc_endpoints) { 449 return USBD_NOMEM; 450 } 451 sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL; 452 sc->sc_in_ep = 453 sc->sc_in_num_endpoints ? 454 sc->sc_endpoints+sc->sc_out_num_endpoints : NULL; 455 456 ep = &sc->sc_out_ep[0]; 457 for (i=0; i<sc->sc_out_num_endpoints; i++) { 458 epd = usbd_interface2endpoint_descriptor( 459 sc->sc_iface, 460 fp->out_ep[i].ep); 461 if (!epd) { 462 printf("%s: cannot get endpoint descriptor(out:%d)\n", 463 USBDEVNAME(sc->sc_dev), fp->out_ep[i].ep); 464 err = USBD_INVAL; 465 goto error; 466 } 467 if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK || 468 UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_OUT) { 469 printf("%s: illegal endpoint(out:%d)\n", 470 USBDEVNAME(sc->sc_dev), fp->out_ep[i].ep); 471 err = USBD_INVAL; 472 goto error; 473 } 474 ep->sc = sc; 475 ep->addr = epd->bEndpointAddress; 476 ep->num_jacks = fp->out_ep[i].num_jacks; 477 sc->sc_out_num_jacks += fp->out_ep[i].num_jacks; 478 ep->num_open = 0; 479 memset(ep->jacks, 0, sizeof(ep->jacks)); 480 LIST_INIT(&ep->queue_head); 481 ep++; 482 } 483 ep = &sc->sc_in_ep[0]; 484 for (i=0; i<sc->sc_in_num_endpoints; i++) { 485 epd = usbd_interface2endpoint_descriptor( 486 sc->sc_iface, 487 fp->in_ep[i].ep); 488 if (!epd) { 489 printf("%s: cannot get endpoint descriptor(in:%d)\n", 490 USBDEVNAME(sc->sc_dev), fp->in_ep[i].ep); 491 err = USBD_INVAL; 492 goto error; 493 } 494 if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK || 495 UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_IN) { 496 printf("%s: illegal endpoint(in:%d)\n", 497 USBDEVNAME(sc->sc_dev), fp->in_ep[i].ep); 498 err = USBD_INVAL; 499 goto error; 500 } 501 ep->sc = sc; 502 ep->addr = epd->bEndpointAddress; 503 ep->num_jacks = fp->in_ep[i].num_jacks; 504 sc->sc_in_num_jacks += fp->in_ep[i].num_jacks; 505 ep->num_open = 0; 506 memset(ep->jacks, 0, sizeof(ep->jacks)); 507 ep++; 508 } 509 510 return USBD_NORMAL_COMPLETION; 511 error: 512 free(sc->sc_endpoints, M_USBDEV); 513 sc->sc_endpoints = NULL; 514 return err; 515 } 516 517 static usbd_status 518 alloc_all_endpoints_yamaha(struct umidi_softc *sc) 519 { 520 /* This driver currently supports max 1in/1out bulk endpoints */ 521 usb_descriptor_t *desc; 522 usb_endpoint_descriptor_t *epd; 523 int out_addr, in_addr, i; 524 int dir; 525 size_t remain, descsize; 526 527 sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0; 528 out_addr = in_addr = 0; 529 530 /* detect endpoints */ 531 desc = TO_D(usbd_get_interface_descriptor(sc->sc_iface)); 532 for (i=(int)TO_IFD(desc)->bNumEndpoints-1; i>=0; i--) { 533 epd = usbd_interface2endpoint_descriptor(sc->sc_iface, i); 534 if (UE_GET_XFERTYPE(epd->bmAttributes) == UE_BULK) { 535 dir = UE_GET_DIR(epd->bEndpointAddress); 536 if (dir==UE_DIR_OUT && !out_addr) 537 out_addr = epd->bEndpointAddress; 538 else if (dir==UE_DIR_IN && !in_addr) 539 in_addr = epd->bEndpointAddress; 540 } 541 } 542 desc = NEXT_D(desc); 543 544 /* count jacks */ 545 if (!(desc->bDescriptorType==UDESC_CS_INTERFACE && 546 desc->bDescriptorSubtype==UMIDI_MS_HEADER)) 547 return USBD_INVAL; 548 remain = (size_t)UGETW(TO_CSIFD(desc)->wTotalLength) - 549 (size_t)desc->bLength; 550 desc = NEXT_D(desc); 551 552 while (remain>=sizeof(usb_descriptor_t)) { 553 descsize = desc->bLength; 554 if (descsize>remain || descsize==0) 555 break; 556 if (desc->bDescriptorType==UDESC_CS_INTERFACE && 557 remain>=UMIDI_JACK_DESCRIPTOR_SIZE) { 558 if (desc->bDescriptorSubtype==UMIDI_OUT_JACK) 559 sc->sc_out_num_jacks++; 560 else if (desc->bDescriptorSubtype==UMIDI_IN_JACK) 561 sc->sc_in_num_jacks++; 562 } 563 desc = NEXT_D(desc); 564 remain-=descsize; 565 } 566 567 /* validate some parameters */ 568 if (sc->sc_out_num_jacks>UMIDI_MAX_EPJACKS) 569 sc->sc_out_num_jacks = UMIDI_MAX_EPJACKS; 570 if (sc->sc_in_num_jacks>UMIDI_MAX_EPJACKS) 571 sc->sc_in_num_jacks = UMIDI_MAX_EPJACKS; 572 if (sc->sc_out_num_jacks && out_addr) { 573 sc->sc_out_num_endpoints = 1; 574 } else { 575 sc->sc_out_num_endpoints = 0; 576 sc->sc_out_num_jacks = 0; 577 } 578 if (sc->sc_in_num_jacks && in_addr) { 579 sc->sc_in_num_endpoints = 1; 580 } else { 581 sc->sc_in_num_endpoints = 0; 582 sc->sc_in_num_jacks = 0; 583 } 584 sc->sc_endpoints = malloc(sizeof(struct umidi_endpoint)* 585 (sc->sc_out_num_endpoints+ 586 sc->sc_in_num_endpoints), 587 M_USBDEV, M_WAITOK); 588 if (!sc->sc_endpoints) 589 return USBD_NOMEM; 590 if (sc->sc_out_num_endpoints) { 591 sc->sc_out_ep = sc->sc_endpoints; 592 sc->sc_out_ep->sc = sc; 593 sc->sc_out_ep->addr = out_addr; 594 sc->sc_out_ep->num_jacks = sc->sc_out_num_jacks; 595 sc->sc_out_ep->num_open = 0; 596 memset(sc->sc_out_ep->jacks, 0, sizeof(sc->sc_out_ep->jacks)); 597 } else 598 sc->sc_out_ep = NULL; 599 600 if (sc->sc_in_num_endpoints) { 601 sc->sc_in_ep = sc->sc_endpoints+sc->sc_out_num_endpoints; 602 sc->sc_in_ep->sc = sc; 603 sc->sc_in_ep->addr = in_addr; 604 sc->sc_in_ep->num_jacks = sc->sc_in_num_jacks; 605 sc->sc_in_ep->num_open = 0; 606 memset(sc->sc_in_ep->jacks, 0, sizeof(sc->sc_in_ep->jacks)); 607 } else 608 sc->sc_in_ep = NULL; 609 610 return USBD_NORMAL_COMPLETION; 611 } 612 613 static usbd_status 614 alloc_all_endpoints_genuine(struct umidi_softc *sc) 615 { 616 usb_descriptor_t *desc; 617 int num_ep; 618 size_t remain, descsize; 619 struct umidi_endpoint *p, *q, *lowest, *endep, tmpep; 620 int epaddr; 621 622 desc = TO_D(usbd_get_interface_descriptor(sc->sc_iface)); 623 num_ep = TO_IFD(desc)->bNumEndpoints; 624 desc = NEXT_D(desc); /* ifd -> csifd */ 625 remain = ((size_t)UGETW(TO_CSIFD(desc)->wTotalLength) - 626 (size_t)desc->bLength); 627 desc = NEXT_D(desc); 628 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 while (remain>=sizeof(usb_descriptor_t)) { 640 descsize = desc->bLength; 641 if (descsize>remain || descsize==0) 642 break; 643 if (desc->bDescriptorType==UDESC_ENDPOINT && 644 remain>=USB_ENDPOINT_DESCRIPTOR_SIZE && 645 UE_GET_XFERTYPE(TO_EPD(desc)->bmAttributes) == UE_BULK) { 646 epaddr = TO_EPD(desc)->bEndpointAddress; 647 } else if (desc->bDescriptorType==UDESC_CS_ENDPOINT && 648 remain>=UMIDI_CS_ENDPOINT_DESCRIPTOR_SIZE && 649 epaddr!=-1) { 650 if (num_ep>0) { 651 num_ep--; 652 p->sc = sc; 653 p->addr = epaddr; 654 p->num_jacks = TO_CSEPD(desc)->bNumEmbMIDIJack; 655 if (UE_GET_DIR(epaddr)==UE_DIR_OUT) { 656 sc->sc_out_num_endpoints++; 657 sc->sc_out_num_jacks += p->num_jacks; 658 } else { 659 sc->sc_in_num_endpoints++; 660 sc->sc_in_num_jacks += p->num_jacks; 661 } 662 p++; 663 } 664 } else 665 epaddr = -1; 666 desc = NEXT_D(desc); 667 remain-=descsize; 668 } 669 670 /* sort endpoints */ 671 num_ep = sc->sc_out_num_endpoints + sc->sc_in_num_endpoints; 672 p = sc->sc_endpoints; 673 endep = p + num_ep; 674 while (p<endep) { 675 lowest = p; 676 for (q=p+1; q<endep; q++) { 677 if ((UE_GET_DIR(lowest->addr)==UE_DIR_IN && 678 UE_GET_DIR(q->addr)==UE_DIR_OUT) || 679 ((UE_GET_DIR(lowest->addr)== 680 UE_GET_DIR(q->addr)) && 681 (UE_GET_ADDR(lowest->addr)> 682 UE_GET_ADDR(q->addr)))) 683 lowest = q; 684 } 685 if (lowest != p) { 686 memcpy((void *)&tmpep, (void *)p, sizeof(tmpep)); 687 memcpy((void *)p, (void *)lowest, sizeof(tmpep)); 688 memcpy((void *)lowest, (void *)&tmpep, sizeof(tmpep)); 689 } 690 p->num_open = 0; 691 p++; 692 } 693 694 sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL; 695 sc->sc_in_ep = 696 sc->sc_in_num_endpoints ? 697 sc->sc_endpoints+sc->sc_out_num_endpoints : NULL; 698 699 return USBD_NORMAL_COMPLETION; 700 } 701 702 703 /* 704 * jack stuffs 705 */ 706 707 static usbd_status 708 alloc_all_jacks(struct umidi_softc *sc) 709 { 710 int i, j; 711 struct umidi_endpoint *ep; 712 struct umidi_jack *jack, **rjack; 713 714 /* allocate/initialize structures */ 715 sc->sc_jacks = 716 malloc(sizeof(*sc->sc_out_jacks)*(sc->sc_in_num_jacks+ 717 sc->sc_out_num_jacks), 718 M_USBDEV, M_WAITOK); 719 if (!sc->sc_jacks) 720 return USBD_NOMEM; 721 sc->sc_out_jacks = 722 sc->sc_out_num_jacks ? sc->sc_jacks : NULL; 723 sc->sc_in_jacks = 724 sc->sc_in_num_jacks ? sc->sc_jacks+sc->sc_out_num_jacks : NULL; 725 726 jack = &sc->sc_out_jacks[0]; 727 for (i=0; i<sc->sc_out_num_jacks; i++) { 728 jack->opened = 0; 729 jack->binded = 0; 730 jack->arg = NULL; 731 jack->u.out.intr = NULL; 732 jack->cable_number = i; 733 jack++; 734 } 735 jack = &sc->sc_in_jacks[0]; 736 for (i=0; i<sc->sc_in_num_jacks; i++) { 737 jack->opened = 0; 738 jack->binded = 0; 739 jack->arg = NULL; 740 jack->u.in.intr = NULL; 741 jack->cable_number = i; 742 jack++; 743 } 744 745 /* assign each jacks to each endpoints */ 746 jack = &sc->sc_out_jacks[0]; 747 ep = &sc->sc_out_ep[0]; 748 for (i=0; i<sc->sc_out_num_endpoints; i++) { 749 rjack = &ep->jacks[0]; 750 for (j=0; j<ep->num_jacks; j++) { 751 *rjack = jack; 752 jack->endpoint = ep; 753 jack++; 754 rjack++; 755 } 756 ep++; 757 } 758 jack = &sc->sc_in_jacks[0]; 759 ep = &sc->sc_in_ep[0]; 760 for (i=0; i<sc->sc_in_num_endpoints; i++) { 761 rjack = &ep->jacks[0]; 762 for (j=0; j<ep->num_jacks; j++) { 763 *rjack = jack; 764 jack->endpoint = ep; 765 jack++; 766 rjack++; 767 } 768 ep++; 769 } 770 771 return USBD_NORMAL_COMPLETION; 772 } 773 774 static void 775 free_all_jacks(struct umidi_softc *sc) 776 { 777 int s; 778 779 s = splaudio(); 780 if (sc->sc_out_jacks) { 781 free(sc->sc_jacks, M_USBDEV); 782 sc->sc_jacks = sc->sc_in_jacks = sc->sc_out_jacks = NULL; 783 } 784 splx(s); 785 } 786 787 static usbd_status 788 bind_jacks_to_mididev(struct umidi_softc *sc, 789 struct umidi_jack *out_jack, 790 struct umidi_jack *in_jack, 791 struct umidi_mididev *mididev) 792 { 793 if ((out_jack && out_jack->binded) || (in_jack && in_jack->binded)) 794 return USBD_IN_USE; 795 if (mididev->out_jack || mididev->in_jack) 796 return USBD_IN_USE; 797 798 if (out_jack) 799 out_jack->binded = 1; 800 if (in_jack) 801 in_jack->binded = 1; 802 mididev->in_jack = in_jack; 803 mididev->out_jack = out_jack; 804 805 return USBD_NORMAL_COMPLETION; 806 } 807 808 static void 809 unbind_jacks_from_mididev(struct umidi_mididev *mididev) 810 { 811 if ((mididev->flags&FWRITE) && mididev->out_jack) 812 close_out_jack(mididev->out_jack); 813 if ((mididev->flags&FWRITE) && mididev->in_jack) 814 close_in_jack(mididev->in_jack); 815 816 if (mididev->out_jack) 817 mididev->out_jack->binded = 0; 818 if (mididev->in_jack) 819 mididev->in_jack->binded = 0; 820 mididev->out_jack = mididev->in_jack = NULL; 821 } 822 823 static void 824 unbind_all_jacks(struct umidi_softc *sc) 825 { 826 int i; 827 828 if (sc->sc_mididevs) 829 for (i=0; i<sc->sc_num_mididevs; i++) { 830 unbind_jacks_from_mididev(&sc->sc_mididevs[i]); 831 } 832 } 833 834 static usbd_status 835 assign_all_jacks_automatically(struct umidi_softc *sc) 836 { 837 usbd_status err; 838 int i; 839 struct umidi_jack *out, *in; 840 841 err = 842 alloc_all_mididevs(sc, 843 max(sc->sc_out_num_jacks, sc->sc_in_num_jacks)); 844 if (err!=USBD_NORMAL_COMPLETION) 845 return err; 846 847 for (i=0; i<sc->sc_num_mididevs; i++) { 848 out = (i<sc->sc_out_num_jacks) ? &sc->sc_out_jacks[i]:NULL; 849 in = (i<sc->sc_in_num_jacks) ? &sc->sc_in_jacks[i]:NULL; 850 err = bind_jacks_to_mididev(sc, out, in, &sc->sc_mididevs[i]); 851 if (err!=USBD_NORMAL_COMPLETION) { 852 free_all_mididevs(sc); 853 return err; 854 } 855 } 856 857 return USBD_NORMAL_COMPLETION; 858 } 859 860 static usbd_status 861 open_out_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *)) 862 { 863 struct umidi_endpoint *ep = jack->endpoint; 864 865 if (jack->opened) 866 return USBD_IN_USE; 867 868 jack->arg = arg; 869 jack->u.out.intr = intr; 870 init_packet(&jack->packet); 871 jack->opened = 1; 872 ep->num_open++; 873 874 return USBD_NORMAL_COMPLETION; 875 } 876 877 static usbd_status 878 open_in_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *, int)) 879 { 880 usbd_status err = USBD_NORMAL_COMPLETION; 881 struct umidi_endpoint *ep = jack->endpoint; 882 883 if (jack->opened) 884 return USBD_IN_USE; 885 886 jack->arg = arg; 887 jack->u.in.intr = intr; 888 jack->opened = 1; 889 if (ep->num_open++==0 && UE_GET_DIR(ep->addr)==UE_DIR_IN) { 890 err = start_input_transfer(ep); 891 if (err!=USBD_NORMAL_COMPLETION) { 892 ep->num_open--; 893 } 894 } 895 896 return err; 897 } 898 899 static void 900 close_out_jack(struct umidi_jack *jack) 901 { 902 struct umidi_jack *tail; 903 int s; 904 905 if (jack->opened) { 906 s = splusb(); 907 LIST_REMOVE(jack, u.out.queue_entry); 908 if (jack==jack->endpoint->queue_tail) { 909 /* find tail */ 910 LIST_FOREACH(tail, 911 &jack->endpoint->queue_head, 912 u.out.queue_entry) { 913 if (!LIST_NEXT(tail, u.out.queue_entry)) { 914 jack->endpoint->queue_tail = tail; 915 } 916 } 917 } 918 splx(s); 919 jack->opened = 0; 920 jack->endpoint->num_open--; 921 } 922 } 923 924 static void 925 close_in_jack(struct umidi_jack *jack) 926 { 927 if (jack->opened) { 928 jack->opened = 0; 929 jack->endpoint->num_open--; 930 } 931 } 932 933 static usbd_status 934 attach_mididev(struct umidi_softc *sc, struct umidi_mididev *mididev) 935 { 936 if (mididev->sc) 937 return USBD_IN_USE; 938 939 mididev->sc = sc; 940 941 mididev->mdev = midi_attach_mi(&umidi_hw_if, mididev, &sc->sc_dev); 942 943 return USBD_NORMAL_COMPLETION; 944 } 945 946 static usbd_status 947 detach_mididev(struct umidi_mididev *mididev, int flags) 948 { 949 if (!mididev->sc) 950 return USBD_NO_ADDR; 951 952 if (mididev->opened) { 953 umidi_close(mididev); 954 } 955 unbind_jacks_from_mididev(mididev); 956 957 if (mididev->mdev) 958 config_detach(mididev->mdev, flags); 959 960 mididev->sc = NULL; 961 962 return USBD_NORMAL_COMPLETION; 963 } 964 965 static usbd_status 966 deactivate_mididev(struct umidi_mididev *mididev) 967 { 968 if (mididev->out_jack) 969 mididev->out_jack->binded = 0; 970 if (mididev->in_jack) 971 mididev->in_jack->binded = 0; 972 config_deactivate(mididev->mdev); 973 974 return USBD_NORMAL_COMPLETION; 975 } 976 977 static usbd_status 978 alloc_all_mididevs(struct umidi_softc *sc, int nmidi) 979 { 980 sc->sc_num_mididevs = nmidi; 981 sc->sc_mididevs = malloc(sizeof(*sc->sc_mididevs)*nmidi, 982 M_USBDEV, M_WAITOK); 983 memset(sc->sc_mididevs, 0, sizeof(*sc->sc_mididevs)*nmidi); 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 0, 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 0, 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