1 /* $NetBSD: umidi.c,v 1.6 2001/04/07 22:01:34 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_jacks+sc->sc_in_num_jacks; 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_jacks+sc->sc_out_num_jacks; 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 int out_ep, in_ep, out_addr, in_addr; 522 size_t remain, descsize; 523 524 /* count jacks */ 525 desc = TO_D(usbd_get_interface_descriptor(sc->sc_iface)); 526 desc = NEXT_D(desc); /* ifd -> csifd */ 527 remain = ((size_t)UGETW(TO_CSIFD(desc)->wTotalLength) - 528 (size_t)desc->bLength); 529 desc = NEXT_D(desc); 530 531 sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0; 532 out_ep = in_ep = -1; 533 534 while (remain>=sizeof(usb_descriptor_t)) { 535 descsize = desc->bLength; 536 if (descsize>remain || descsize==0) 537 break; 538 if (desc->bDescriptorType==UDESC_CS_INTERFACE && 539 remain>=UMIDI_JACK_DESCRIPTOR_SIZE) { 540 if (desc->bDescriptorSubtype==UMIDI_OUT_JACK) 541 sc->sc_out_num_jacks++; 542 else if (desc->bDescriptorSubtype==UMIDI_IN_JACK) 543 sc->sc_in_num_jacks++; 544 } else if (desc->bDescriptorType==UDESC_ENDPOINT && 545 remain>=USB_ENDPOINT_DESCRIPTOR_SIZE && 546 (UE_GET_XFERTYPE(TO_EPD(desc)->bmAttributes) 547 == UE_BULK)) { 548 if ((UE_GET_DIR(TO_EPD(desc)->bEndpointAddress) 549 ==UE_DIR_OUT) && 550 out_addr==-1) 551 out_addr = TO_EPD(desc)->bEndpointAddress; 552 else if ((UE_GET_DIR(TO_EPD(desc)->bEndpointAddress) 553 ==UE_DIR_IN) && 554 in_addr==-1) 555 in_addr = TO_EPD(desc)->bEndpointAddress; 556 } 557 558 desc = NEXT_D(desc); 559 remain-=descsize; 560 } 561 562 /* validate some parameter */ 563 if (sc->sc_out_num_jacks>UMIDI_MAX_EPJACKS) 564 sc->sc_out_num_jacks = UMIDI_MAX_EPJACKS; 565 if (sc->sc_in_num_jacks>UMIDI_MAX_EPJACKS) 566 sc->sc_in_num_jacks = UMIDI_MAX_EPJACKS; 567 if (sc->sc_out_num_jacks && out_addr!=-1) { 568 sc->sc_out_num_endpoints = 1; 569 } else { 570 sc->sc_out_num_endpoints = 0; 571 sc->sc_out_num_jacks = 0; 572 } 573 if (sc->sc_in_num_jacks && in_addr!=-1) { 574 sc->sc_in_num_endpoints = 1; 575 } else { 576 sc->sc_in_num_endpoints = 0; 577 sc->sc_in_num_jacks = 0; 578 } 579 sc->sc_endpoints = malloc(sizeof(struct umidi_endpoint)* 580 (sc->sc_out_num_endpoints+ 581 sc->sc_in_num_endpoints), 582 M_USBDEV, M_WAITOK); 583 if (!sc->sc_endpoints) 584 return USBD_NOMEM; 585 if (sc->sc_out_num_endpoints) { 586 sc->sc_out_ep = sc->sc_endpoints; 587 sc->sc_out_ep->sc = sc; 588 sc->sc_out_ep->addr = out_addr; 589 sc->sc_out_ep->num_jacks = sc->sc_out_num_jacks; 590 sc->sc_out_ep->num_open = 0; 591 memset(sc->sc_out_ep->jacks, 0, sizeof(sc->sc_out_ep->jacks)); 592 } else 593 sc->sc_out_ep = NULL; 594 595 if (sc->sc_in_num_endpoints) { 596 sc->sc_in_ep = sc->sc_endpoints+sc->sc_out_num_endpoints; 597 sc->sc_in_ep->sc = sc; 598 sc->sc_in_ep->addr = in_addr; 599 sc->sc_in_ep->num_jacks = sc->sc_in_num_jacks; 600 sc->sc_in_ep->num_open = 0; 601 memset(sc->sc_in_ep->jacks, 0, sizeof(sc->sc_in_ep->jacks)); 602 } else 603 sc->sc_in_ep = NULL; 604 605 return USBD_NORMAL_COMPLETION; 606 } 607 608 static usbd_status 609 alloc_all_endpoints_genuine(struct umidi_softc *sc) 610 { 611 usb_descriptor_t *desc; 612 int num_ep, i; 613 size_t remain, descsize; 614 struct umidi_endpoint *p, *q, *lowest, *endep, tmpep; 615 int epaddr; 616 617 desc = TO_D(usbd_get_interface_descriptor(sc->sc_iface)); 618 num_ep = TO_IFD(desc)->bNumEndpoints; 619 desc = NEXT_D(desc); /* ifd -> csifd */ 620 remain = ((size_t)UGETW(TO_CSIFD(desc)->wTotalLength) - 621 (size_t)desc->bLength); 622 desc = NEXT_D(desc); 623 624 sc->sc_endpoints = p = malloc(sizeof(struct umidi_endpoint)*num_ep, 625 M_USBDEV, M_WAITOK); 626 if (!p) 627 return USBD_NOMEM; 628 629 sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0; 630 sc->sc_out_num_endpoints = sc->sc_in_num_endpoints = 0; 631 epaddr = -1; 632 633 /* get the list of endpoints for midi stream */ 634 while (remain>=sizeof(usb_descriptor_t)) { 635 descsize = desc->bLength; 636 if (descsize>remain || descsize==0) 637 break; 638 if (desc->bDescriptorType==UDESC_ENDPOINT && 639 remain>=USB_ENDPOINT_DESCRIPTOR_SIZE && 640 UE_GET_XFERTYPE(TO_EPD(desc)->bmAttributes) == UE_BULK) { 641 epaddr = TO_EPD(desc)->bEndpointAddress; 642 } else if (desc->bDescriptorType==UDESC_CS_ENDPOINT && 643 remain>=UMIDI_CS_ENDPOINT_DESCRIPTOR_SIZE && 644 epaddr!=-1) { 645 num_ep--; 646 if (num_ep>0) { 647 p->sc = sc; 648 p->addr = epaddr; 649 p->num_jacks = TO_CSEPD(desc)->bNumEmbMIDIJack; 650 if (UE_GET_DIR(epaddr)==UE_DIR_OUT) { 651 sc->sc_out_num_endpoints++; 652 sc->sc_out_num_jacks += p->num_jacks; 653 } else { 654 sc->sc_in_num_endpoints++; 655 sc->sc_in_num_jacks += p->num_jacks; 656 } 657 p++; 658 } 659 } else 660 epaddr = -1; 661 desc = NEXT_D(desc); 662 remain-=descsize; 663 } 664 665 /* sort endpoints */ 666 num_ep = sc->sc_out_num_endpoints + sc->sc_in_num_endpoints; 667 p = sc->sc_endpoints; 668 endep = p + num_ep; 669 while (p<endep) { 670 lowest = p; 671 for (q=p+1; q<endep; q++) { 672 if ((UE_GET_DIR(lowest->addr)==UE_DIR_IN && 673 UE_GET_DIR(q->addr)==UE_DIR_OUT) || 674 ((UE_GET_DIR(lowest->addr)== 675 UE_GET_DIR(q->addr)) && 676 (UE_GET_ADDR(lowest->addr)> 677 UE_GET_ADDR(q->addr)))) 678 lowest = q; 679 } 680 if (lowest != p) { 681 memcpy((void *)&tmpep, (void *)p, sizeof(tmpep)); 682 memcpy((void *)p, (void *)lowest, sizeof(tmpep)); 683 memcpy((void *)lowest, (void *)&tmpep, sizeof(tmpep)); 684 } 685 } 686 687 sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL; 688 sc->sc_in_ep = 689 sc->sc_in_num_endpoints ? 690 sc->sc_endpoints+sc->sc_out_num_endpoints : NULL; 691 sc->sc_endpoints[i].num_open = 0; 692 693 return USBD_NORMAL_COMPLETION; 694 } 695 696 697 /* 698 * jack stuffs 699 */ 700 701 static usbd_status 702 alloc_all_jacks(struct umidi_softc *sc) 703 { 704 int i, j; 705 struct umidi_endpoint *ep; 706 struct umidi_jack *jack, **rjack; 707 708 /* allocate/initialize structures */ 709 sc->sc_jacks = 710 malloc(sizeof(*sc->sc_out_jacks)*(sc->sc_in_num_jacks+ 711 sc->sc_out_num_jacks), 712 M_USBDEV, M_WAITOK); 713 if (!sc->sc_jacks) 714 return USBD_NOMEM; 715 sc->sc_out_jacks = 716 sc->sc_out_num_jacks ? sc->sc_jacks : NULL; 717 sc->sc_in_jacks = 718 sc->sc_in_num_jacks ? sc->sc_jacks+sc->sc_out_num_jacks : NULL; 719 720 jack = &sc->sc_out_jacks[0]; 721 for (i=0; i<sc->sc_out_num_jacks; i++) { 722 jack->opened = 0; 723 jack->binded = 0; 724 jack->arg = NULL; 725 jack->u.out.intr = NULL; 726 jack->cable_number = i; 727 jack++; 728 } 729 jack = &sc->sc_in_jacks[0]; 730 for (i=0; i<sc->sc_in_num_jacks; i++) { 731 jack->opened = 0; 732 jack->binded = 0; 733 jack->arg = NULL; 734 jack->u.in.intr = NULL; 735 jack->cable_number = i; 736 jack++; 737 } 738 739 /* assign each jacks to each endpoints */ 740 jack = &sc->sc_out_jacks[0]; 741 ep = &sc->sc_out_ep[0]; 742 for (i=0; i<sc->sc_out_num_endpoints; i++) { 743 rjack = &ep->jacks[0]; 744 for (j=0; j<ep->num_jacks; j++) { 745 *rjack = jack; 746 jack->endpoint = ep; 747 jack++; 748 rjack++; 749 } 750 ep++; 751 } 752 jack = &sc->sc_in_jacks[0]; 753 ep = &sc->sc_in_ep[0]; 754 for (i=0; i<sc->sc_in_num_endpoints; i++) { 755 rjack = &ep->jacks[0]; 756 for (j=0; j<ep->num_jacks; j++) { 757 *rjack = jack; 758 jack->endpoint = ep; 759 jack++; 760 rjack++; 761 } 762 ep++; 763 } 764 765 return USBD_NORMAL_COMPLETION; 766 } 767 768 static void 769 free_all_jacks(struct umidi_softc *sc) 770 { 771 int s; 772 773 s = splaudio(); 774 if (sc->sc_out_jacks) { 775 free(sc->sc_jacks, M_USBDEV); 776 sc->sc_jacks = sc->sc_in_jacks = sc->sc_out_jacks = NULL; 777 } 778 splx(s); 779 } 780 781 static usbd_status 782 bind_jacks_to_mididev(struct umidi_softc *sc, 783 struct umidi_jack *out_jack, 784 struct umidi_jack *in_jack, 785 struct umidi_mididev *mididev) 786 { 787 if (out_jack->binded || in_jack->binded) 788 return USBD_IN_USE; 789 if (mididev->out_jack || mididev->in_jack) 790 return USBD_IN_USE; 791 792 if (out_jack) 793 out_jack->binded = 1; 794 if (in_jack) 795 in_jack->binded = 1; 796 mididev->in_jack = in_jack; 797 mididev->out_jack = out_jack; 798 799 return USBD_NORMAL_COMPLETION; 800 } 801 802 static void 803 unbind_jacks_from_mididev(struct umidi_mididev *mididev) 804 { 805 if ((mididev->flags&FWRITE) && mididev->out_jack) 806 close_out_jack(mididev->out_jack); 807 if ((mididev->flags&FWRITE) && mididev->in_jack) 808 close_in_jack(mididev->in_jack); 809 810 if (mididev->out_jack) 811 mididev->out_jack->binded = 0; 812 if (mididev->in_jack) 813 mididev->in_jack->binded = 0; 814 mididev->out_jack = mididev->in_jack = NULL; 815 } 816 817 static void 818 unbind_all_jacks(struct umidi_softc *sc) 819 { 820 int i; 821 822 if (sc->sc_mididevs) 823 for (i=0; i<sc->sc_num_mididevs; i++) { 824 unbind_jacks_from_mididev(&sc->sc_mididevs[i]); 825 } 826 } 827 828 static usbd_status 829 assign_all_jacks_automatically(struct umidi_softc *sc) 830 { 831 usbd_status err; 832 int i; 833 struct umidi_jack *out, *in; 834 835 err = 836 alloc_all_mididevs(sc, 837 max(sc->sc_out_num_jacks, sc->sc_in_num_jacks)); 838 if (err!=USBD_NORMAL_COMPLETION) 839 return err; 840 841 for (i=0; i<sc->sc_num_mididevs; i++) { 842 out = (i<sc->sc_out_num_jacks) ? &sc->sc_out_jacks[i]:NULL; 843 in = (i<sc->sc_in_num_jacks) ? &sc->sc_in_jacks[i]:NULL; 844 err = bind_jacks_to_mididev(sc, out, in, &sc->sc_mididevs[i]); 845 if (err!=USBD_NORMAL_COMPLETION) { 846 free_all_mididevs(sc); 847 return err; 848 } 849 } 850 851 return USBD_NORMAL_COMPLETION; 852 } 853 854 static usbd_status 855 open_out_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *)) 856 { 857 struct umidi_endpoint *ep = jack->endpoint; 858 859 if (jack->opened) 860 return USBD_IN_USE; 861 862 jack->arg = arg; 863 jack->u.out.intr = intr; 864 init_packet(&jack->packet); 865 jack->opened = 1; 866 ep->num_open++; 867 868 return USBD_NORMAL_COMPLETION; 869 } 870 871 static usbd_status 872 open_in_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *, int)) 873 { 874 usbd_status err = USBD_NORMAL_COMPLETION; 875 struct umidi_endpoint *ep = jack->endpoint; 876 877 if (jack->opened) 878 return USBD_IN_USE; 879 880 jack->arg = arg; 881 jack->u.in.intr = intr; 882 jack->opened = 1; 883 if (ep->num_open++==0 && UE_GET_DIR(ep->addr)==UE_DIR_IN) { 884 err = start_input_transfer(ep); 885 if (err!=USBD_NORMAL_COMPLETION) { 886 ep->num_open--; 887 } 888 } 889 890 return err; 891 } 892 893 static void 894 close_out_jack(struct umidi_jack *jack) 895 { 896 struct umidi_jack *tail; 897 int s; 898 899 if (jack->opened) { 900 s = splusb(); 901 LIST_REMOVE(jack, u.out.queue_entry); 902 if (jack==jack->endpoint->queue_tail) { 903 /* find tail */ 904 LIST_FOREACH(tail, 905 &jack->endpoint->queue_head, 906 u.out.queue_entry) { 907 if (!LIST_NEXT(tail, u.out.queue_entry)) { 908 jack->endpoint->queue_tail = tail; 909 } 910 } 911 } 912 splx(s); 913 jack->opened = 0; 914 jack->endpoint->num_open--; 915 } 916 } 917 918 static void 919 close_in_jack(struct umidi_jack *jack) 920 { 921 if (jack->opened) { 922 jack->opened = 0; 923 jack->endpoint->num_open--; 924 } 925 } 926 927 static usbd_status 928 attach_mididev(struct umidi_softc *sc, struct umidi_mididev *mididev) 929 { 930 if (mididev->sc) 931 return USBD_IN_USE; 932 933 mididev->sc = sc; 934 935 mididev->mdev = midi_attach_mi(&umidi_hw_if, mididev, &sc->sc_dev); 936 937 return USBD_NORMAL_COMPLETION; 938 } 939 940 static usbd_status 941 detach_mididev(struct umidi_mididev *mididev, int flags) 942 { 943 if (!mididev->sc) 944 return USBD_NO_ADDR; 945 946 if (mididev->opened) { 947 umidi_close(mididev); 948 } 949 unbind_jacks_from_mididev(mididev); 950 951 if (mididev->mdev) 952 config_detach(mididev->mdev, flags); 953 954 mididev->sc = NULL; 955 956 return USBD_NORMAL_COMPLETION; 957 } 958 959 static usbd_status 960 deactivate_mididev(struct umidi_mididev *mididev) 961 { 962 if (mididev->out_jack) 963 mididev->out_jack->binded = 0; 964 if (mididev->in_jack) 965 mididev->in_jack->binded = 0; 966 config_deactivate(mididev->mdev); 967 968 return USBD_NORMAL_COMPLETION; 969 } 970 971 static usbd_status 972 alloc_all_mididevs(struct umidi_softc *sc, int nmidi) 973 { 974 sc->sc_num_mididevs = nmidi; 975 sc->sc_mididevs = malloc(sizeof(*sc->sc_mididevs)*nmidi, 976 M_USBDEV, M_WAITOK); 977 memset(sc->sc_mididevs, 0, sizeof(*sc->sc_mididevs)*nmidi); 978 if (!sc->sc_mididevs) 979 return USBD_NOMEM; 980 981 return USBD_NORMAL_COMPLETION; 982 } 983 984 static void 985 free_all_mididevs(struct umidi_softc *sc) 986 { 987 sc->sc_num_mididevs = 0; 988 if (sc->sc_mididevs) 989 free(sc->sc_mididevs, M_USBDEV); 990 } 991 992 static usbd_status 993 attach_all_mididevs(struct umidi_softc *sc) 994 { 995 usbd_status err; 996 int i; 997 998 if (sc->sc_mididevs) 999 for (i=0; i<sc->sc_num_mididevs; i++) { 1000 err = attach_mididev(sc, &sc->sc_mididevs[i]); 1001 if (err!=USBD_NORMAL_COMPLETION) 1002 return err; 1003 } 1004 1005 return USBD_NORMAL_COMPLETION; 1006 } 1007 1008 static usbd_status 1009 detach_all_mididevs(struct umidi_softc *sc, int flags) 1010 { 1011 usbd_status err; 1012 int i; 1013 1014 if (sc->sc_mididevs) 1015 for (i=0; i<sc->sc_num_mididevs; i++) { 1016 err = detach_mididev(&sc->sc_mididevs[i], flags); 1017 if (err!=USBD_NORMAL_COMPLETION) 1018 return err; 1019 } 1020 1021 return USBD_NORMAL_COMPLETION; 1022 } 1023 1024 static usbd_status 1025 deactivate_all_mididevs(struct umidi_softc *sc) 1026 { 1027 usbd_status err; 1028 int i; 1029 1030 if (sc->sc_mididevs) 1031 for (i=0; i<sc->sc_num_mididevs; i++) { 1032 err = deactivate_mididev(&sc->sc_mididevs[i]); 1033 if (err!=USBD_NORMAL_COMPLETION) 1034 return err; 1035 } 1036 1037 return USBD_NORMAL_COMPLETION; 1038 } 1039 1040 #ifdef UMIDI_DEBUG 1041 static void 1042 dump_sc(struct umidi_softc *sc) 1043 { 1044 int i; 1045 1046 DPRINTFN(10, ("%s: dump_sc\n", USBDEVNAME(sc->sc_dev))); 1047 for (i=0; i<sc->sc_out_num_endpoints; i++) { 1048 DPRINTFN(10, ("\tout_ep(%p):\n", &sc->sc_out_ep[i])); 1049 dump_ep(&sc->sc_out_ep[i]); 1050 } 1051 for (i=0; i<sc->sc_in_num_endpoints; i++) { 1052 DPRINTFN(10, ("\tin_ep(%p):\n", &sc->sc_in_ep[i])); 1053 dump_ep(&sc->sc_in_ep[i]); 1054 } 1055 } 1056 1057 static void 1058 dump_ep(struct umidi_endpoint *ep) 1059 { 1060 int i; 1061 for (i=0; i<ep->num_jacks; i++) { 1062 DPRINTFN(10, ("\t\tjack(%p):\n", ep->jacks[i])); 1063 dump_jack(ep->jacks[i]); 1064 } 1065 } 1066 static void 1067 dump_jack(struct umidi_jack *jack) 1068 { 1069 DPRINTFN(10, ("\t\t\tep=%p, mididev=%p\n", 1070 jack->endpoint, jack->mididev)); 1071 } 1072 1073 #endif /* UMIDI_DEBUG */ 1074 1075 1076 1077 /* 1078 * MUX MIDI PACKET 1079 */ 1080 1081 static const int packet_length[16] = { 1082 /*0*/ -1, 1083 /*1*/ -1, 1084 /*2*/ 2, 1085 /*3*/ 3, 1086 /*4*/ 3, 1087 /*5*/ 1, 1088 /*6*/ 2, 1089 /*7*/ 3, 1090 /*8*/ 3, 1091 /*9*/ 3, 1092 /*A*/ 3, 1093 /*B*/ 3, 1094 /*C*/ 2, 1095 /*D*/ 2, 1096 /*E*/ 3, 1097 /*F*/ 1, 1098 }; 1099 1100 static const struct { 1101 int cin; 1102 packet_state_t next; 1103 } packet_0xFX[16] = { 1104 /*F0: SysEx */ { 0x04, PS_EXCL_1 }, 1105 /*F1: MTC */ { 0x02, PS_NORMAL_1OF2 }, 1106 /*F2: S.POS */ { 0x03, PS_NORMAL_1OF3 }, 1107 /*F3: S.SEL */ { 0x02, PS_NORMAL_1OF2 }, 1108 /*F4: UNDEF */ { 0x00, PS_INITIAL }, 1109 /*F5: UNDEF */ { 0x00, PS_INITIAL }, 1110 /*F6: Tune */ { 0x0F, PS_END }, 1111 /*F7: EofEx */ { 0x00, PS_INITIAL }, 1112 /*F8: Timing */ { 0x0F, PS_END }, 1113 /*F9: UNDEF */ { 0x00, PS_INITIAL }, 1114 /*FA: Start */ { 0x0F, PS_END }, 1115 /*FB: Cont */ { 0x0F, PS_END }, 1116 /*FC: Stop */ { 0x0F, PS_END }, 1117 /*FD: UNDEF */ { 0x00, PS_INITIAL }, 1118 /*FE: ActS */ { 0x0F, PS_END }, 1119 /*FF: Reset */ { 0x0F, PS_END }, 1120 }; 1121 1122 #define GET_CN(p) (((unsigned char)(p)>>4)&0x0F) 1123 #define GET_CIN(p) ((unsigned char)(p)&0x0F) 1124 #define MIX_CN_CIN(cn, cin) \ 1125 ((unsigned char)((((unsigned char)(cn)&0x0F)<<4)| \ 1126 ((unsigned char)(cin)&0x0F))) 1127 1128 static void 1129 init_packet(struct umidi_packet *packet) 1130 { 1131 memset(packet->buffer, 0, UMIDI_PACKET_SIZE); 1132 packet->state = PS_INITIAL; 1133 } 1134 1135 static usbd_status 1136 start_input_transfer(struct umidi_endpoint *ep) 1137 { 1138 usbd_setup_xfer(ep->xfer, ep->pipe, 1139 (usbd_private_handle)ep, 1140 ep->buffer, UMIDI_PACKET_SIZE, 1141 0, USBD_NO_TIMEOUT, in_intr); 1142 return usbd_transfer(ep->xfer); 1143 } 1144 1145 static usbd_status 1146 start_output_transfer(struct umidi_endpoint *ep) 1147 { 1148 usbd_setup_xfer(ep->xfer, ep->pipe, 1149 (usbd_private_handle)ep, 1150 ep->buffer, UMIDI_PACKET_SIZE, 1151 0, USBD_NO_TIMEOUT, out_intr); 1152 return usbd_transfer(ep->xfer); 1153 } 1154 1155 #ifdef UMIDI_DEBUG 1156 #define DPR_PACKET(dir, sc, p) \ 1157 if ((unsigned char)(p)->buffer[1]!=0xFE) \ 1158 DPRINTFN(500, \ 1159 ("%s: umidi packet(" #dir "): %02X %02X %02X %02X\n", \ 1160 USBDEVNAME(sc->sc_dev), \ 1161 (unsigned char)(p)->buffer[0], \ 1162 (unsigned char)(p)->buffer[1], \ 1163 (unsigned char)(p)->buffer[2], \ 1164 (unsigned char)(p)->buffer[3])); 1165 #else 1166 #define DPR_PACKET(dir, sc, p) 1167 #endif 1168 1169 static int 1170 out_jack_output(struct umidi_jack *out_jack, int d) 1171 { 1172 struct umidi_endpoint *ep = out_jack->endpoint; 1173 struct umidi_softc *sc = ep->sc; 1174 int error; 1175 int s; 1176 1177 if (sc->sc_dying) 1178 return EIO; 1179 1180 error = 0; 1181 if (out_jack->opened) { 1182 DPRINTFN(1000, ("umidi_output: ep=%p 0x%02x\n", ep, d)); 1183 out_build_packet(out_jack->cable_number, &out_jack->packet, d); 1184 switch (out_jack->packet.state) { 1185 case PS_EXCL_0: 1186 case PS_END: 1187 DPR_PACKET(out, sc, &out_jack->packet); 1188 s = splusb(); 1189 if (LIST_EMPTY(&ep->queue_head)) { 1190 memcpy(ep->buffer, 1191 out_jack->packet.buffer, 1192 UMIDI_PACKET_SIZE); 1193 start_output_transfer(ep); 1194 } 1195 if (LIST_EMPTY(&ep->queue_head)) 1196 LIST_INSERT_HEAD(&ep->queue_head, 1197 out_jack, u.out.queue_entry); 1198 else 1199 LIST_INSERT_AFTER(ep->queue_tail, 1200 out_jack, u.out.queue_entry); 1201 ep->queue_tail = out_jack; 1202 splx(s); 1203 break; 1204 default: 1205 error = EINPROGRESS; 1206 } 1207 } else 1208 error = ENODEV; 1209 1210 return error; 1211 } 1212 1213 static void 1214 in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1215 { 1216 int cn, len, i; 1217 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv; 1218 struct umidi_jack *jack; 1219 1220 if (ep->sc->sc_dying || !ep->num_open) 1221 return; 1222 1223 cn = GET_CN(ep->buffer[0]); 1224 len = packet_length[GET_CIN(ep->buffer[0])]; 1225 jack = ep->jacks[cn]; 1226 if (cn>=ep->num_jacks || !jack) { 1227 DPRINTF(("%s: stray umidi packet (in): %02X %02X %02X %02X\n", 1228 USBDEVNAME(ep->sc->sc_dev), 1229 (unsigned)ep->buffer[0], 1230 (unsigned)ep->buffer[1], 1231 (unsigned)ep->buffer[2], 1232 (unsigned)ep->buffer[3])); 1233 return; 1234 } 1235 if (!jack->binded || !jack->opened) 1236 return; 1237 DPR_PACKET(in, ep->sc, &jack->buffer); 1238 if (jack->u.in.intr) { 1239 for (i=0; i<len; i++) { 1240 (*jack->u.in.intr)(jack->arg, ep->buffer[i+1]); 1241 } 1242 } 1243 1244 (void)start_input_transfer(ep); 1245 } 1246 1247 static void 1248 out_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1249 { 1250 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv; 1251 struct umidi_softc *sc = ep->sc; 1252 struct umidi_jack *jack; 1253 1254 if (sc->sc_dying || !ep->num_open) 1255 return; 1256 1257 jack = LIST_FIRST(&ep->queue_head); 1258 if (jack && jack->opened) { 1259 LIST_REMOVE(jack, u.out.queue_entry); 1260 if (!LIST_EMPTY(&ep->queue_head)) { 1261 memcpy(ep->buffer, 1262 LIST_FIRST(&ep->queue_head)->packet.buffer, 1263 UMIDI_PACKET_SIZE); 1264 (void)start_output_transfer(ep); 1265 } 1266 if (jack->u.out.intr) { 1267 (*jack->u.out.intr)(jack->arg); 1268 } 1269 } 1270 } 1271 1272 static void 1273 out_build_packet(int cable_number, struct umidi_packet *packet, uByte in) 1274 { 1275 int cin; 1276 uByte prev; 1277 1278 retry: 1279 switch (packet->state) { 1280 case PS_END: 1281 case PS_INITIAL: 1282 prev = packet->buffer[1]; 1283 memset(packet->buffer, 0, UMIDI_PACKET_SIZE); 1284 if (in<0x80) { 1285 if (prev>=0x80 && prev<0xf0) { 1286 /* running status */ 1287 out_build_packet(cable_number, packet, prev); 1288 goto retry; 1289 } 1290 /* ??? */ 1291 break; 1292 } 1293 if (in>=0xf0) { 1294 cin=packet_0xFX[in&0x0F].cin; 1295 packet->state=packet_0xFX[in&0x0F].next; 1296 } else { 1297 cin=(unsigned char)in>>4; 1298 switch (packet_length[cin]) { 1299 case 2: 1300 packet->state = PS_NORMAL_1OF2; 1301 break; 1302 case 3: 1303 packet->state = PS_NORMAL_1OF3; 1304 break; 1305 default: 1306 /* ??? */ 1307 packet->state = PS_INITIAL; 1308 } 1309 } 1310 packet->buffer[0] = MIX_CN_CIN(cable_number, cin); 1311 packet->buffer[1] = in; 1312 break; 1313 case PS_NORMAL_1OF3: 1314 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1315 packet->buffer[2] = in; 1316 packet->state = PS_NORMAL_2OF3; 1317 break; 1318 case PS_NORMAL_2OF3: 1319 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1320 packet->buffer[3] = in; 1321 packet->state = PS_END; 1322 break; 1323 case PS_NORMAL_1OF2: 1324 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1325 packet->buffer[2] = in; 1326 packet->state = PS_END; 1327 break; 1328 case PS_EXCL_0: 1329 memset(packet->buffer, 0, UMIDI_PACKET_SIZE); 1330 if (in==0xF7) { 1331 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x05); 1332 packet->buffer[1] = 0xF7; 1333 packet->state = PS_END; 1334 break; 1335 } 1336 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1337 packet->buffer[1] = in; 1338 packet->state = PS_EXCL_1; 1339 break; 1340 case PS_EXCL_1: 1341 if (in==0xF7) { 1342 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x06); 1343 packet->buffer[2] = 0xF7; 1344 packet->state = PS_END; 1345 break; 1346 } 1347 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1348 packet->buffer[2] = in; 1349 packet->state = PS_EXCL_2; 1350 break; 1351 case PS_EXCL_2: 1352 if (in==0xF7) { 1353 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x07); 1354 packet->buffer[3] = 0xF7; 1355 packet->state = PS_END; 1356 break; 1357 } 1358 if (in>=0x80) { /* ??? */ packet->state = PS_END; break; } 1359 packet->buffer[0] = MIX_CN_CIN(cable_number, 0x04); 1360 packet->buffer[3] = in; 1361 packet->state = PS_EXCL_0; 1362 break; 1363 default: 1364 printf("umidi: ambiguous state.\n"); 1365 packet->state = PS_INITIAL; 1366 goto retry; 1367 } 1368 } 1369 1370