summaryrefslogtreecommitdiff
path: root/sys/dev/usb/umidi.c
diff options
context:
space:
mode:
authorNathan Binkert <nate@cvs.openbsd.org>2002-05-07 18:29:20 +0000
committerNathan Binkert <nate@cvs.openbsd.org>2002-05-07 18:29:20 +0000
commite3500453ce2b94b39af2ef626169742ebc17530c (patch)
treed3c1ce90d9ae11b43948c86e7276f9595b6ee08d /sys/dev/usb/umidi.c
parent98e3a0a3b6a5b0271467c9f199a555d22161f072 (diff)
Meant to commit only ulpt and committed everything. Most things weren't ready
Diffstat (limited to 'sys/dev/usb/umidi.c')
-rw-r--r--sys/dev/usb/umidi.c1374
1 files changed, 0 insertions, 1374 deletions
diff --git a/sys/dev/usb/umidi.c b/sys/dev/usb/umidi.c
deleted file mode 100644
index 09b8df082a8..00000000000
--- a/sys/dev/usb/umidi.c
+++ /dev/null
@@ -1,1374 +0,0 @@
-/* $OpenBSD: umidi.c,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: umidi.c,v 1.14 2002/03/08 17:24:06 kent Exp $ */
-/*
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Takuya SHIOZAKI (tshiozak@netbsd.org).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/device.h>
-#include <sys/ioctl.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/select.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/poll.h>
-#include <sys/lock.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include <dev/usb/usbdevs.h>
-#include <dev/usb/uaudioreg.h>
-#include <dev/usb/umidireg.h>
-#include <dev/usb/umidivar.h>
-#include <dev/usb/umidi_quirks.h>
-
-#include <dev/midi_if.h>
-
-#ifdef UMIDI_DEBUG
-#define DPRINTF(x) if (umididebug) printf x
-#define DPRINTFN(n,x) if (umididebug >= (n)) printf x
-int umididebug = 0;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-
-static int umidi_open(void *, int,
- void (*)(void *, int), void (*)(void *), void *);
-static void umidi_close(void *);
-static int umidi_output(void *, int);
-static void umidi_getinfo(void *, struct midi_info *);
-
-static usbd_status alloc_pipe(struct umidi_endpoint *);
-static void free_pipe(struct umidi_endpoint *);
-
-static usbd_status alloc_all_endpoints(struct umidi_softc *);
-static void free_all_endpoints(struct umidi_softc *);
-
-static usbd_status alloc_all_jacks(struct umidi_softc *);
-static void free_all_jacks(struct umidi_softc *);
-static usbd_status bind_jacks_to_mididev(struct umidi_softc *,
- struct umidi_jack *,
- struct umidi_jack *,
- struct umidi_mididev *);
-static void unbind_jacks_from_mididev(struct umidi_mididev *);
-static void unbind_all_jacks(struct umidi_softc *);
-static usbd_status assign_all_jacks_automatically(struct umidi_softc *);
-static usbd_status open_out_jack(struct umidi_jack *, void *,
- void (*)(void *));
-static usbd_status open_in_jack(struct umidi_jack *, void *,
- void (*)(void *, int));
-static void close_out_jack(struct umidi_jack *);
-static void close_in_jack(struct umidi_jack *);
-
-static usbd_status attach_mididev(struct umidi_softc *,
- struct umidi_mididev *);
-static usbd_status detach_mididev(struct umidi_mididev *, int);
-static usbd_status deactivate_mididev(struct umidi_mididev *);
-static usbd_status alloc_all_mididevs(struct umidi_softc *, int);
-static void free_all_mididevs(struct umidi_softc *);
-static usbd_status attach_all_mididevs(struct umidi_softc *);
-static usbd_status detach_all_mididevs(struct umidi_softc *, int);
-static usbd_status deactivate_all_mididevs(struct umidi_softc *);
-
-#ifdef UMIDI_DEBUG
-static void dump_sc(struct umidi_softc *);
-static void dump_ep(struct umidi_endpoint *);
-static void dump_jack(struct umidi_jack *);
-#endif
-
-static void init_packet(struct umidi_packet *);
-
-static usbd_status start_input_transfer(struct umidi_endpoint *);
-static usbd_status start_output_transfer(struct umidi_endpoint *);
-static int out_jack_output(struct umidi_jack *, int);
-static void in_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void out_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void out_build_packet(int, struct umidi_packet *, uByte);
-
-
-struct midi_hw_if umidi_hw_if = {
- umidi_open,
- umidi_close,
- umidi_output,
- umidi_getinfo,
- 0, /* ioctl */
-};
-
-USB_DECLARE_DRIVER(umidi);
-
-USB_MATCH(umidi)
-{
- USB_MATCH_START(umidi, uaa);
- usb_interface_descriptor_t *id;
-
- DPRINTFN(1,("umidi_match\n"));
-
- if (uaa->iface == NULL)
- return UMATCH_NONE;
-
- if (umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno))
- return UMATCH_IFACECLASS_IFACESUBCLASS;
-
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id!=NULL &&
- id->bInterfaceClass==UICLASS_AUDIO &&
- id->bInterfaceSubClass==UISUBCLASS_MIDISTREAM)
- return UMATCH_IFACECLASS_IFACESUBCLASS;
-
- return UMATCH_NONE;
-}
-
-USB_ATTACH(umidi)
-{
- usbd_status err;
- USB_ATTACH_START(umidi, sc, uaa);
- char devinfo[1024];
-
- DPRINTFN(1,("umidi_attach\n"));
-
- usbd_devinfo(uaa->device, 0, devinfo);
- printf("\n%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
-
- sc->sc_iface = uaa->iface;
- sc->sc_udev = uaa->device;
-
- sc->sc_quirk =
- umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno);
- printf("%s: ", USBDEVNAME(sc->sc_dev));
- umidi_print_quirk(sc->sc_quirk);
-
-
- err = alloc_all_endpoints(sc);
- if (err!=USBD_NORMAL_COMPLETION) {
- printf("%s: alloc_all_endpoints failed. (err=%d)\n",
- USBDEVNAME(sc->sc_dev), err);
- goto error;
- }
- err = alloc_all_jacks(sc);
- if (err!=USBD_NORMAL_COMPLETION) {
- free_all_endpoints(sc);
- printf("%s: alloc_all_jacks failed. (err=%d)\n",
- USBDEVNAME(sc->sc_dev), err);
- goto error;
- }
- printf("%s: out=%d, in=%d\n",
- USBDEVNAME(sc->sc_dev),
- sc->sc_out_num_jacks, sc->sc_in_num_jacks);
-
- err = assign_all_jacks_automatically(sc);
- if (err!=USBD_NORMAL_COMPLETION) {
- unbind_all_jacks(sc);
- free_all_jacks(sc);
- free_all_endpoints(sc);
- printf("%s: assign_all_jacks_automatically failed. (err=%d)\n",
- USBDEVNAME(sc->sc_dev), err);
- goto error;
- }
- err = attach_all_mididevs(sc);
- if (err!=USBD_NORMAL_COMPLETION) {
- free_all_jacks(sc);
- free_all_endpoints(sc);
- printf("%s: attach_all_mididevs failed. (err=%d)\n",
- USBDEVNAME(sc->sc_dev), err);
- }
-
-#ifdef UMIDI_DEBUG
- dump_sc(sc);
-#endif
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH,
- sc->sc_udev, USBDEV(sc->sc_dev));
-
- USB_ATTACH_SUCCESS_RETURN;
-error:
- printf("%s: disabled.\n", USBDEVNAME(sc->sc_dev));
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
-}
-
-int
-umidi_activate(device_ptr_t self, enum devact act)
-{
- struct umidi_softc *sc = (struct umidi_softc *)self;
-
- switch (act) {
- case DVACT_ACTIVATE:
- DPRINTFN(1,("umidi_activate (activate)\n"));
-
- return EOPNOTSUPP;
- break;
- case DVACT_DEACTIVATE:
- DPRINTFN(1,("umidi_activate (deactivate)\n"));
- sc->sc_dying = 1;
- deactivate_all_mididevs(sc);
- break;
- }
- return 0;
-}
-
-USB_DETACH(umidi)
-{
- USB_DETACH_START(umidi, sc);
-
- DPRINTFN(1,("umidi_detach\n"));
-
- sc->sc_dying = 1;
- detach_all_mididevs(sc, flags);
- free_all_mididevs(sc);
- free_all_jacks(sc);
- free_all_endpoints(sc);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
-
- return 0;
-}
-
-
-/*
- * midi_if stuffs
- */
-int
-umidi_open(void *addr,
- int flags,
- void (*iintr)(void *, int),
- void (*ointr)(void *),
- void *arg)
-{
- struct umidi_mididev *mididev = addr;
- struct umidi_softc *sc = mididev->sc;
-
- DPRINTF(("umidi_open: sc=%p\n", sc));
-
- if (!sc)
- return ENXIO;
- if (mididev->opened)
- return EBUSY;
- if (sc->sc_dying)
- return EIO;
-
- mididev->opened = 1;
- mididev->flags = flags;
- if ((mididev->flags & FWRITE) && mididev->out_jack)
- open_out_jack(mididev->out_jack, arg, ointr);
- if ((mididev->flags & FREAD) && mididev->in_jack) {
- open_in_jack(mididev->in_jack, arg, iintr);
- }
-
- return 0;
-}
-
-void
-umidi_close(void *addr)
-{
- int s;
- struct umidi_mididev *mididev = addr;
-
- s = splusb();
- if ((mididev->flags & FWRITE) && mididev->out_jack)
- close_out_jack(mididev->out_jack);
- if ((mididev->flags & FREAD) && mididev->in_jack)
- close_in_jack(mididev->in_jack);
- mididev->opened = 0;
- splx(s);
-}
-
-int
-umidi_output(void *addr, int d)
-{
- struct umidi_mididev *mididev = addr;
-
- if (!mididev->out_jack || !mididev->opened)
- return EIO;
-
- return out_jack_output(mididev->out_jack, d);
-}
-
-void
-umidi_getinfo(void *addr, struct midi_info *mi)
-{
- struct umidi_mididev *mididev = addr;
-/* struct umidi_softc *sc = mididev->sc; */
-
- mi->name = "USB MIDI I/F"; /* XXX: model name */
- mi->props = MIDI_PROP_OUT_INTR;
- if (mididev->in_jack)
- mi->props |= MIDI_PROP_CAN_INPUT;
-}
-
-
-/*
- * each endpoint stuffs
- */
-
-/* alloc/free pipe */
-static usbd_status
-alloc_pipe(struct umidi_endpoint *ep)
-{
- struct umidi_softc *sc = ep->sc;
- usbd_status err;
-
- DPRINTF(("%s: alloc_pipe %p\n", USBDEVNAME(sc->sc_dev), ep));
- LIST_INIT(&ep->queue_head);
- ep->xfer = usbd_alloc_xfer(sc->sc_udev);
- if (ep->xfer == NULL) {
- err = USBD_NOMEM;
- goto quit;
- }
- ep->buffer = usbd_alloc_buffer(ep->xfer, UMIDI_PACKET_SIZE);
- if (ep->buffer == NULL) {
- usbd_free_xfer(ep->xfer);
- err = USBD_NOMEM;
- goto quit;
- }
- err = usbd_open_pipe(sc->sc_iface, ep->addr, 0, &ep->pipe);
- if (err)
- usbd_free_xfer(ep->xfer);
-quit:
- return err;
-}
-
-static void
-free_pipe(struct umidi_endpoint *ep)
-{
- DPRINTF(("%s: free_pipe %p\n", USBDEVNAME(ep->sc->sc_dev), ep));
- usbd_abort_pipe(ep->pipe);
- usbd_close_pipe(ep->pipe);
- usbd_free_xfer(ep->xfer);
-}
-
-
-/* alloc/free the array of endpoint structures */
-
-static usbd_status alloc_all_endpoints_fixed_ep(struct umidi_softc *);
-static usbd_status alloc_all_endpoints_yamaha(struct umidi_softc *);
-static usbd_status alloc_all_endpoints_genuine(struct umidi_softc *);
-
-static usbd_status
-alloc_all_endpoints(struct umidi_softc *sc)
-{
- usbd_status err;
- struct umidi_endpoint *ep;
- int i;
-
- if (UMQ_ISTYPE(sc, UMQ_TYPE_FIXED_EP)) {
- err = alloc_all_endpoints_fixed_ep(sc);
- } else if (UMQ_ISTYPE(sc, UMQ_TYPE_YAMAHA)) {
- err = alloc_all_endpoints_yamaha(sc);
- } else {
- err = alloc_all_endpoints_genuine(sc);
- }
- if (err!=USBD_NORMAL_COMPLETION)
- return err;
-
- ep = sc->sc_endpoints;
- for (i=sc->sc_out_num_endpoints+sc->sc_in_num_endpoints; i>0; i--) {
- err = alloc_pipe(ep++);
- if (err!=USBD_NORMAL_COMPLETION) {
- for (; ep!=sc->sc_endpoints; ep--)
- free_pipe(ep-1);
- free(sc->sc_endpoints, M_USBDEV);
- sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL;
- break;
- }
- }
- return err;
-}
-
-static void
-free_all_endpoints(struct umidi_softc *sc)
-{
- int i;
- for (i=0; i<sc->sc_in_num_endpoints+sc->sc_out_num_endpoints; i++)
- free_pipe(&sc->sc_endpoints[i]);
- if (sc->sc_endpoints != NULL)
- free(sc->sc_endpoints, M_USBDEV);
- sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL;
-}
-
-static usbd_status
-alloc_all_endpoints_fixed_ep(struct umidi_softc *sc)
-{
- usbd_status err;
- struct umq_fixed_ep_desc *fp;
- struct umidi_endpoint *ep;
- usb_endpoint_descriptor_t *epd;
- int i;
-
- fp = umidi_get_quirk_data_from_type(sc->sc_quirk,
- UMQ_TYPE_FIXED_EP);
- sc->sc_out_num_jacks = 0;
- sc->sc_in_num_jacks = 0;
- sc->sc_out_num_endpoints = fp->num_out_ep;
- sc->sc_in_num_endpoints = fp->num_in_ep;
- sc->sc_endpoints = malloc(sizeof(*sc->sc_out_ep)*
- (sc->sc_out_num_endpoints+
- sc->sc_in_num_endpoints),
- M_USBDEV, M_WAITOK);
- if (!sc->sc_endpoints) {
- return USBD_NOMEM;
- }
- sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL;
- sc->sc_in_ep =
- sc->sc_in_num_endpoints ?
- sc->sc_endpoints+sc->sc_out_num_endpoints : NULL;
-
- ep = &sc->sc_out_ep[0];
- for (i=0; i<sc->sc_out_num_endpoints; i++) {
- epd = usbd_interface2endpoint_descriptor(
- sc->sc_iface,
- fp->out_ep[i].ep);
- if (!epd) {
- printf("%s: cannot get endpoint descriptor(out:%d)\n",
- USBDEVNAME(sc->sc_dev), fp->out_ep[i].ep);
- err = USBD_INVAL;
- goto error;
- }
- if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK ||
- UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_OUT) {
- printf("%s: illegal endpoint(out:%d)\n",
- USBDEVNAME(sc->sc_dev), fp->out_ep[i].ep);
- err = USBD_INVAL;
- goto error;
- }
- ep->sc = sc;
- ep->addr = epd->bEndpointAddress;
- ep->num_jacks = fp->out_ep[i].num_jacks;
- sc->sc_out_num_jacks += fp->out_ep[i].num_jacks;
- ep->num_open = 0;
- memset(ep->jacks, 0, sizeof(ep->jacks));
- LIST_INIT(&ep->queue_head);
- ep++;
- }
- ep = &sc->sc_in_ep[0];
- for (i=0; i<sc->sc_in_num_endpoints; i++) {
- epd = usbd_interface2endpoint_descriptor(
- sc->sc_iface,
- fp->in_ep[i].ep);
- if (!epd) {
- printf("%s: cannot get endpoint descriptor(in:%d)\n",
- USBDEVNAME(sc->sc_dev), fp->in_ep[i].ep);
- err = USBD_INVAL;
- goto error;
- }
- if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK ||
- UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_IN) {
- printf("%s: illegal endpoint(in:%d)\n",
- USBDEVNAME(sc->sc_dev), fp->in_ep[i].ep);
- err = USBD_INVAL;
- goto error;
- }
- ep->sc = sc;
- ep->addr = epd->bEndpointAddress;
- ep->num_jacks = fp->in_ep[i].num_jacks;
- sc->sc_in_num_jacks += fp->in_ep[i].num_jacks;
- ep->num_open = 0;
- memset(ep->jacks, 0, sizeof(ep->jacks));
- ep++;
- }
-
- return USBD_NORMAL_COMPLETION;
-error:
- free(sc->sc_endpoints, M_USBDEV);
- sc->sc_endpoints = NULL;
- return err;
-}
-
-static usbd_status
-alloc_all_endpoints_yamaha(struct umidi_softc *sc)
-{
- /* This driver currently supports max 1in/1out bulk endpoints */
- usb_descriptor_t *desc;
- usb_endpoint_descriptor_t *epd;
- int out_addr, in_addr, i;
- int dir;
- size_t remain, descsize;
-
- sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0;
- out_addr = in_addr = 0;
-
- /* detect endpoints */
- desc = TO_D(usbd_get_interface_descriptor(sc->sc_iface));
- for (i=(int)TO_IFD(desc)->bNumEndpoints-1; i>=0; i--) {
- epd = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
- if (UE_GET_XFERTYPE(epd->bmAttributes) == UE_BULK) {
- dir = UE_GET_DIR(epd->bEndpointAddress);
- if (dir==UE_DIR_OUT && !out_addr)
- out_addr = epd->bEndpointAddress;
- else if (dir==UE_DIR_IN && !in_addr)
- in_addr = epd->bEndpointAddress;
- }
- }
- desc = NEXT_D(desc);
-
- /* count jacks */
- if (!(desc->bDescriptorType==UDESC_CS_INTERFACE &&
- desc->bDescriptorSubtype==UMIDI_MS_HEADER))
- return USBD_INVAL;
- remain = (size_t)UGETW(TO_CSIFD(desc)->wTotalLength) -
- (size_t)desc->bLength;
- desc = NEXT_D(desc);
-
- while (remain>=sizeof(usb_descriptor_t)) {
- descsize = desc->bLength;
- if (descsize>remain || descsize==0)
- break;
- if (desc->bDescriptorType==UDESC_CS_INTERFACE &&
- remain>=UMIDI_JACK_DESCRIPTOR_SIZE) {
- if (desc->bDescriptorSubtype==UMIDI_OUT_JACK)
- sc->sc_out_num_jacks++;
- else if (desc->bDescriptorSubtype==UMIDI_IN_JACK)
- sc->sc_in_num_jacks++;
- }
- desc = NEXT_D(desc);
- remain-=descsize;
- }
-
- /* validate some parameters */
- if (sc->sc_out_num_jacks>UMIDI_MAX_EPJACKS)
- sc->sc_out_num_jacks = UMIDI_MAX_EPJACKS;
- if (sc->sc_in_num_jacks>UMIDI_MAX_EPJACKS)
- sc->sc_in_num_jacks = UMIDI_MAX_EPJACKS;
- if (sc->sc_out_num_jacks && out_addr) {
- sc->sc_out_num_endpoints = 1;
- } else {
- sc->sc_out_num_endpoints = 0;
- sc->sc_out_num_jacks = 0;
- }
- if (sc->sc_in_num_jacks && in_addr) {
- sc->sc_in_num_endpoints = 1;
- } else {
- sc->sc_in_num_endpoints = 0;
- sc->sc_in_num_jacks = 0;
- }
- sc->sc_endpoints = malloc(sizeof(struct umidi_endpoint)*
- (sc->sc_out_num_endpoints+
- sc->sc_in_num_endpoints),
- M_USBDEV, M_WAITOK);
- if (!sc->sc_endpoints)
- return USBD_NOMEM;
- if (sc->sc_out_num_endpoints) {
- sc->sc_out_ep = sc->sc_endpoints;
- sc->sc_out_ep->sc = sc;
- sc->sc_out_ep->addr = out_addr;
- sc->sc_out_ep->num_jacks = sc->sc_out_num_jacks;
- sc->sc_out_ep->num_open = 0;
- memset(sc->sc_out_ep->jacks, 0, sizeof(sc->sc_out_ep->jacks));
- } else
- sc->sc_out_ep = NULL;
-
- if (sc->sc_in_num_endpoints) {
- sc->sc_in_ep = sc->sc_endpoints+sc->sc_out_num_endpoints;
- sc->sc_in_ep->sc = sc;
- sc->sc_in_ep->addr = in_addr;
- sc->sc_in_ep->num_jacks = sc->sc_in_num_jacks;
- sc->sc_in_ep->num_open = 0;
- memset(sc->sc_in_ep->jacks, 0, sizeof(sc->sc_in_ep->jacks));
- } else
- sc->sc_in_ep = NULL;
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-alloc_all_endpoints_genuine(struct umidi_softc *sc)
-{
- usb_descriptor_t *desc;
- int num_ep;
- size_t remain, descsize;
- struct umidi_endpoint *p, *q, *lowest, *endep, tmpep;
- int epaddr;
-
- desc = TO_D(usbd_get_interface_descriptor(sc->sc_iface));
- num_ep = TO_IFD(desc)->bNumEndpoints;
- desc = NEXT_D(desc); /* ifd -> csifd */
- remain = ((size_t)UGETW(TO_CSIFD(desc)->wTotalLength) -
- (size_t)desc->bLength);
- desc = NEXT_D(desc);
-
- sc->sc_endpoints = p = malloc(sizeof(struct umidi_endpoint)*num_ep,
- M_USBDEV, M_WAITOK);
- if (!p)
- return USBD_NOMEM;
-
- sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0;
- sc->sc_out_num_endpoints = sc->sc_in_num_endpoints = 0;
- epaddr = -1;
-
- /* get the list of endpoints for midi stream */
- while (remain>=sizeof(usb_descriptor_t)) {
- descsize = desc->bLength;
- if (descsize>remain || descsize==0)
- break;
- if (desc->bDescriptorType==UDESC_ENDPOINT &&
- remain>=USB_ENDPOINT_DESCRIPTOR_SIZE &&
- UE_GET_XFERTYPE(TO_EPD(desc)->bmAttributes) == UE_BULK) {
- epaddr = TO_EPD(desc)->bEndpointAddress;
- } else if (desc->bDescriptorType==UDESC_CS_ENDPOINT &&
- remain>=UMIDI_CS_ENDPOINT_DESCRIPTOR_SIZE &&
- epaddr!=-1) {
- if (num_ep>0) {
- num_ep--;
- p->sc = sc;
- p->addr = epaddr;
- p->num_jacks = TO_CSEPD(desc)->bNumEmbMIDIJack;
- if (UE_GET_DIR(epaddr)==UE_DIR_OUT) {
- sc->sc_out_num_endpoints++;
- sc->sc_out_num_jacks += p->num_jacks;
- } else {
- sc->sc_in_num_endpoints++;
- sc->sc_in_num_jacks += p->num_jacks;
- }
- p++;
- }
- } else
- epaddr = -1;
- desc = NEXT_D(desc);
- remain-=descsize;
- }
-
- /* sort endpoints */
- num_ep = sc->sc_out_num_endpoints + sc->sc_in_num_endpoints;
- p = sc->sc_endpoints;
- endep = p + num_ep;
- while (p<endep) {
- lowest = p;
- for (q=p+1; q<endep; q++) {
- if ((UE_GET_DIR(lowest->addr)==UE_DIR_IN &&
- UE_GET_DIR(q->addr)==UE_DIR_OUT) ||
- ((UE_GET_DIR(lowest->addr)==
- UE_GET_DIR(q->addr)) &&
- (UE_GET_ADDR(lowest->addr)>
- UE_GET_ADDR(q->addr))))
- lowest = q;
- }
- if (lowest != p) {
- memcpy((void *)&tmpep, (void *)p, sizeof(tmpep));
- memcpy((void *)p, (void *)lowest, sizeof(tmpep));
- memcpy((void *)lowest, (void *)&tmpep, sizeof(tmpep));
- }
- p->num_open = 0;
- p++;
- }
-
- sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL;
- sc->sc_in_ep =
- sc->sc_in_num_endpoints ?
- sc->sc_endpoints+sc->sc_out_num_endpoints : NULL;
-
- return USBD_NORMAL_COMPLETION;
-}
-
-
-/*
- * jack stuffs
- */
-
-static usbd_status
-alloc_all_jacks(struct umidi_softc *sc)
-{
- int i, j;
- struct umidi_endpoint *ep;
- struct umidi_jack *jack, **rjack;
-
- /* allocate/initialize structures */
- sc->sc_jacks =
- malloc(sizeof(*sc->sc_out_jacks)*(sc->sc_in_num_jacks+
- sc->sc_out_num_jacks),
- M_USBDEV, M_WAITOK);
- if (!sc->sc_jacks)
- return USBD_NOMEM;
- sc->sc_out_jacks =
- sc->sc_out_num_jacks ? sc->sc_jacks : NULL;
- sc->sc_in_jacks =
- sc->sc_in_num_jacks ? sc->sc_jacks+sc->sc_out_num_jacks : NULL;
-
- jack = &sc->sc_out_jacks[0];
- for (i=0; i<sc->sc_out_num_jacks; i++) {
- jack->opened = 0;
- jack->binded = 0;
- jack->arg = NULL;
- jack->u.out.intr = NULL;
- jack->cable_number = i;
- jack++;
- }
- jack = &sc->sc_in_jacks[0];
- for (i=0; i<sc->sc_in_num_jacks; i++) {
- jack->opened = 0;
- jack->binded = 0;
- jack->arg = NULL;
- jack->u.in.intr = NULL;
- jack->cable_number = i;
- jack++;
- }
-
- /* assign each jacks to each endpoints */
- jack = &sc->sc_out_jacks[0];
- ep = &sc->sc_out_ep[0];
- for (i=0; i<sc->sc_out_num_endpoints; i++) {
- rjack = &ep->jacks[0];
- for (j=0; j<ep->num_jacks; j++) {
- *rjack = jack;
- jack->endpoint = ep;
- jack++;
- rjack++;
- }
- ep++;
- }
- jack = &sc->sc_in_jacks[0];
- ep = &sc->sc_in_ep[0];
- for (i=0; i<sc->sc_in_num_endpoints; i++) {
- rjack = &ep->jacks[0];
- for (j=0; j<ep->num_jacks; j++) {
- *rjack = jack;
- jack->endpoint = ep;
- jack++;
- rjack++;
- }
- ep++;
- }
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static void
-free_all_jacks(struct umidi_softc *sc)
-{
- int s;
-
- s = splaudio();
- if (sc->sc_out_jacks) {
- free(sc->sc_jacks, M_USBDEV);
- sc->sc_jacks = sc->sc_in_jacks = sc->sc_out_jacks = NULL;
- }
- splx(s);
-}
-
-static usbd_status
-bind_jacks_to_mididev(struct umidi_softc *sc,
- struct umidi_jack *out_jack,
- struct umidi_jack *in_jack,
- struct umidi_mididev *mididev)
-{
- if ((out_jack && out_jack->binded) || (in_jack && in_jack->binded))
- return USBD_IN_USE;
- if (mididev->out_jack || mididev->in_jack)
- return USBD_IN_USE;
-
- if (out_jack)
- out_jack->binded = 1;
- if (in_jack)
- in_jack->binded = 1;
- mididev->in_jack = in_jack;
- mididev->out_jack = out_jack;
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static void
-unbind_jacks_from_mididev(struct umidi_mididev *mididev)
-{
- if ((mididev->flags&FWRITE) && mididev->out_jack)
- close_out_jack(mididev->out_jack);
- if ((mididev->flags&FWRITE) && mididev->in_jack)
- close_in_jack(mididev->in_jack);
-
- if (mididev->out_jack)
- mididev->out_jack->binded = 0;
- if (mididev->in_jack)
- mididev->in_jack->binded = 0;
- mididev->out_jack = mididev->in_jack = NULL;
-}
-
-static void
-unbind_all_jacks(struct umidi_softc *sc)
-{
- int i;
-
- if (sc->sc_mididevs)
- for (i=0; i<sc->sc_num_mididevs; i++) {
- unbind_jacks_from_mididev(&sc->sc_mididevs[i]);
- }
-}
-
-static usbd_status
-assign_all_jacks_automatically(struct umidi_softc *sc)
-{
- usbd_status err;
- int i;
- struct umidi_jack *out, *in;
-
- err =
- alloc_all_mididevs(sc,
- max(sc->sc_out_num_jacks, sc->sc_in_num_jacks));
- if (err!=USBD_NORMAL_COMPLETION)
- return err;
-
- for (i=0; i<sc->sc_num_mididevs; i++) {
- out = (i<sc->sc_out_num_jacks) ? &sc->sc_out_jacks[i]:NULL;
- in = (i<sc->sc_in_num_jacks) ? &sc->sc_in_jacks[i]:NULL;
- err = bind_jacks_to_mididev(sc, out, in, &sc->sc_mididevs[i]);
- if (err!=USBD_NORMAL_COMPLETION) {
- free_all_mididevs(sc);
- return err;
- }
- }
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-open_out_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *))
-{
- struct umidi_endpoint *ep = jack->endpoint;
-
- if (jack->opened)
- return USBD_IN_USE;
-
- jack->arg = arg;
- jack->u.out.intr = intr;
- init_packet(&jack->packet);
- jack->opened = 1;
- ep->num_open++;
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-open_in_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *, int))
-{
- usbd_status err = USBD_NORMAL_COMPLETION;
- struct umidi_endpoint *ep = jack->endpoint;
-
- if (jack->opened)
- return USBD_IN_USE;
-
- jack->arg = arg;
- jack->u.in.intr = intr;
- jack->opened = 1;
- if (ep->num_open++==0 && UE_GET_DIR(ep->addr)==UE_DIR_IN) {
- err = start_input_transfer(ep);
- if (err!=USBD_NORMAL_COMPLETION) {
- ep->num_open--;
- }
- }
-
- return err;
-}
-
-static void
-close_out_jack(struct umidi_jack *jack)
-{
- struct umidi_jack *tail;
- int s;
-
- if (jack->opened) {
- s = splusb();
- LIST_REMOVE(jack, u.out.queue_entry);
- if (jack==jack->endpoint->queue_tail) {
- /* find tail */
- LIST_FOREACH(tail,
- &jack->endpoint->queue_head,
- u.out.queue_entry) {
- if (!LIST_NEXT(tail, u.out.queue_entry)) {
- jack->endpoint->queue_tail = tail;
- }
- }
- }
- splx(s);
- jack->opened = 0;
- jack->endpoint->num_open--;
- }
-}
-
-static void
-close_in_jack(struct umidi_jack *jack)
-{
- if (jack->opened) {
- jack->opened = 0;
- jack->endpoint->num_open--;
- }
-}
-
-static usbd_status
-attach_mididev(struct umidi_softc *sc, struct umidi_mididev *mididev)
-{
- if (mididev->sc)
- return USBD_IN_USE;
-
- mididev->sc = sc;
-
- mididev->mdev = midi_attach_mi(&umidi_hw_if, mididev, &sc->sc_dev);
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-detach_mididev(struct umidi_mididev *mididev, int flags)
-{
- if (!mididev->sc)
- return USBD_NO_ADDR;
-
- if (mididev->opened) {
- umidi_close(mididev);
- }
- unbind_jacks_from_mididev(mididev);
-
- if (mididev->mdev)
- config_detach(mididev->mdev, flags);
-
- mididev->sc = NULL;
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-deactivate_mididev(struct umidi_mididev *mididev)
-{
- if (mididev->out_jack)
- mididev->out_jack->binded = 0;
- if (mididev->in_jack)
- mididev->in_jack->binded = 0;
- config_deactivate(mididev->mdev);
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-alloc_all_mididevs(struct umidi_softc *sc, int nmidi)
-{
- sc->sc_num_mididevs = nmidi;
- sc->sc_mididevs = malloc(sizeof(*sc->sc_mididevs)*nmidi,
- M_USBDEV, M_WAITOK|M_ZERO);
- if (!sc->sc_mididevs)
- return USBD_NOMEM;
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static void
-free_all_mididevs(struct umidi_softc *sc)
-{
- sc->sc_num_mididevs = 0;
- if (sc->sc_mididevs)
- free(sc->sc_mididevs, M_USBDEV);
-}
-
-static usbd_status
-attach_all_mididevs(struct umidi_softc *sc)
-{
- usbd_status err;
- int i;
-
- if (sc->sc_mididevs)
- for (i=0; i<sc->sc_num_mididevs; i++) {
- err = attach_mididev(sc, &sc->sc_mididevs[i]);
- if (err!=USBD_NORMAL_COMPLETION)
- return err;
- }
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-detach_all_mididevs(struct umidi_softc *sc, int flags)
-{
- usbd_status err;
- int i;
-
- if (sc->sc_mididevs)
- for (i=0; i<sc->sc_num_mididevs; i++) {
- err = detach_mididev(&sc->sc_mididevs[i], flags);
- if (err!=USBD_NORMAL_COMPLETION)
- return err;
- }
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-deactivate_all_mididevs(struct umidi_softc *sc)
-{
- usbd_status err;
- int i;
-
- if (sc->sc_mididevs)
- for (i=0; i<sc->sc_num_mididevs; i++) {
- err = deactivate_mididev(&sc->sc_mididevs[i]);
- if (err!=USBD_NORMAL_COMPLETION)
- return err;
- }
-
- return USBD_NORMAL_COMPLETION;
-}
-
-#ifdef UMIDI_DEBUG
-static void
-dump_sc(struct umidi_softc *sc)
-{
- int i;
-
- DPRINTFN(10, ("%s: dump_sc\n", USBDEVNAME(sc->sc_dev)));
- for (i=0; i<sc->sc_out_num_endpoints; i++) {
- DPRINTFN(10, ("\tout_ep(%p):\n", &sc->sc_out_ep[i]));
- dump_ep(&sc->sc_out_ep[i]);
- }
- for (i=0; i<sc->sc_in_num_endpoints; i++) {
- DPRINTFN(10, ("\tin_ep(%p):\n", &sc->sc_in_ep[i]));
- dump_ep(&sc->sc_in_ep[i]);
- }
-}
-
-static void
-dump_ep(struct umidi_endpoint *ep)
-{
- int i;
- for (i=0; i<ep->num_jacks; i++) {
- DPRINTFN(10, ("\t\tjack(%p):\n", ep->jacks[i]));
- dump_jack(ep->jacks[i]);
- }
-}
-static void
-dump_jack(struct umidi_jack *jack)
-{
- DPRINTFN(10, ("\t\t\tep=%p, mididev=%p\n",
- jack->endpoint, jack->mididev));
-}
-
-#endif /* UMIDI_DEBUG */
-
-
-
-/*
- * MUX MIDI PACKET
- */
-
-static const int packet_length[16] = {
- /*0*/ -1,
- /*1*/ -1,
- /*2*/ 2,
- /*3*/ 3,
- /*4*/ 3,
- /*5*/ 1,
- /*6*/ 2,
- /*7*/ 3,
- /*8*/ 3,
- /*9*/ 3,
- /*A*/ 3,
- /*B*/ 3,
- /*C*/ 2,
- /*D*/ 2,
- /*E*/ 3,
- /*F*/ 1,
-};
-
-static const struct {
- int cin;
- packet_state_t next;
-} packet_0xFX[16] = {
- /*F0: SysEx */ { 0x04, PS_EXCL_1 },
- /*F1: MTC */ { 0x02, PS_NORMAL_1OF2 },
- /*F2: S.POS */ { 0x03, PS_NORMAL_1OF3 },
- /*F3: S.SEL */ { 0x02, PS_NORMAL_1OF2 },
- /*F4: UNDEF */ { 0x00, PS_INITIAL },
- /*F5: UNDEF */ { 0x00, PS_INITIAL },
- /*F6: Tune */ { 0x0F, PS_END },
- /*F7: EofEx */ { 0x00, PS_INITIAL },
- /*F8: Timing */ { 0x0F, PS_END },
- /*F9: UNDEF */ { 0x00, PS_INITIAL },
- /*FA: Start */ { 0x0F, PS_END },
- /*FB: Cont */ { 0x0F, PS_END },
- /*FC: Stop */ { 0x0F, PS_END },
- /*FD: UNDEF */ { 0x00, PS_INITIAL },
- /*FE: ActS */ { 0x0F, PS_END },
- /*FF: Reset */ { 0x0F, PS_END },
-};
-
-#define GET_CN(p) (((unsigned char)(p)>>4)&0x0F)
-#define GET_CIN(p) ((unsigned char)(p)&0x0F)
-#define MIX_CN_CIN(cn, cin) \
- ((unsigned char)((((unsigned char)(cn)&0x0F)<<4)| \
- ((unsigned char)(cin)&0x0F)))
-
-static void
-init_packet(struct umidi_packet *packet)
-{
- memset(packet->buffer, 0, UMIDI_PACKET_SIZE);
- packet->state = PS_INITIAL;
-}
-
-static usbd_status
-start_input_transfer(struct umidi_endpoint *ep)
-{
- usbd_setup_xfer(ep->xfer, ep->pipe,
- (usbd_private_handle)ep,
- ep->buffer, UMIDI_PACKET_SIZE,
- USBD_NO_COPY, USBD_NO_TIMEOUT, in_intr);
- return usbd_transfer(ep->xfer);
-}
-
-static usbd_status
-start_output_transfer(struct umidi_endpoint *ep)
-{
- usbd_setup_xfer(ep->xfer, ep->pipe,
- (usbd_private_handle)ep,
- ep->buffer, UMIDI_PACKET_SIZE,
- USBD_NO_COPY, USBD_NO_TIMEOUT, out_intr);
- return usbd_transfer(ep->xfer);
-}
-
-#ifdef UMIDI_DEBUG
-#define DPR_PACKET(dir, sc, p) \
-if ((unsigned char)(p)->buffer[1]!=0xFE) \
- DPRINTFN(500, \
- ("%s: umidi packet(" #dir "): %02X %02X %02X %02X\n", \
- USBDEVNAME(sc->sc_dev), \
- (unsigned char)(p)->buffer[0], \
- (unsigned char)(p)->buffer[1], \
- (unsigned char)(p)->buffer[2], \
- (unsigned char)(p)->buffer[3]));
-#else
-#define DPR_PACKET(dir, sc, p)
-#endif
-
-static int
-out_jack_output(struct umidi_jack *out_jack, int d)
-{
- struct umidi_endpoint *ep = out_jack->endpoint;
- struct umidi_softc *sc = ep->sc;
- int error;
- int s;
-
- if (sc->sc_dying)
- return EIO;
-
- error = 0;
- if (out_jack->opened) {
- DPRINTFN(1000, ("umidi_output: ep=%p 0x%02x\n", ep, d));
- out_build_packet(out_jack->cable_number, &out_jack->packet, d);
- switch (out_jack->packet.state) {
- case PS_EXCL_0:
- case PS_END:
- DPR_PACKET(out, sc, &out_jack->packet);
- s = splusb();
- if (LIST_EMPTY(&ep->queue_head)) {
- memcpy(ep->buffer,
- out_jack->packet.buffer,
- UMIDI_PACKET_SIZE);
- start_output_transfer(ep);
- }
- if (LIST_EMPTY(&ep->queue_head))
- LIST_INSERT_HEAD(&ep->queue_head,
- out_jack, u.out.queue_entry);
- else
- LIST_INSERT_AFTER(ep->queue_tail,
- out_jack, u.out.queue_entry);
- ep->queue_tail = out_jack;
- splx(s);
- break;
- default:
- error = EINPROGRESS;
- }
- } else
- error = ENODEV;
-
- return error;
-}
-
-static void
-in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- int cn, len, i;
- struct umidi_endpoint *ep = (struct umidi_endpoint *)priv;
- struct umidi_jack *jack;
-
- if (ep->sc->sc_dying || !ep->num_open)
- return;
-
- cn = GET_CN(ep->buffer[0]);
- len = packet_length[GET_CIN(ep->buffer[0])];
- jack = ep->jacks[cn];
- if (cn>=ep->num_jacks || !jack) {
- DPRINTF(("%s: stray umidi packet (in): %02X %02X %02X %02X\n",
- USBDEVNAME(ep->sc->sc_dev),
- (unsigned)ep->buffer[0],
- (unsigned)ep->buffer[1],
- (unsigned)ep->buffer[2],
- (unsigned)ep->buffer[3]));
- return;
- }
- if (!jack->binded || !jack->opened)
- return;
- DPR_PACKET(in, ep->sc, &jack->buffer);
- if (jack->u.in.intr) {
- for (i=0; i<len; i++) {
- (*jack->u.in.intr)(jack->arg, ep->buffer[i+1]);
- }
- }
-
- (void)start_input_transfer(ep);
-}
-
-static void
-out_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct umidi_endpoint *ep = (struct umidi_endpoint *)priv;
- struct umidi_softc *sc = ep->sc;
- struct umidi_jack *jack;
-
- if (sc->sc_dying || !ep->num_open)
- return;
-
- jack = LIST_FIRST(&ep->queue_head);
- if (jack && jack->opened) {
- LIST_REMOVE(jack, u.out.queue_entry);
- if (!LIST_EMPTY(&ep->queue_head)) {
- memcpy(ep->buffer,
- LIST_FIRST(&ep->queue_head)->packet.buffer,
- UMIDI_PACKET_SIZE);
- (void)start_output_transfer(ep);
- }
- if (jack->u.out.intr) {
- (*jack->u.out.intr)(jack->arg);
- }
- }
-}
-
-static void
-out_build_packet(int cable_number, struct umidi_packet *packet, uByte in)
-{
- int cin;
- uByte prev;
-
-retry:
- switch (packet->state) {
- case PS_END:
- case PS_INITIAL:
- prev = packet->buffer[1];
- memset(packet->buffer, 0, UMIDI_PACKET_SIZE);
- if (in<0x80) {
- if (prev>=0x80 && prev<0xf0) {
- /* running status */
- out_build_packet(cable_number, packet, prev);
- goto retry;
- }
- /* ??? */
- break;
- }
- if (in>=0xf0) {
- cin=packet_0xFX[in&0x0F].cin;
- packet->state=packet_0xFX[in&0x0F].next;
- } else {
- cin=(unsigned char)in>>4;
- switch (packet_length[cin]) {
- case 2:
- packet->state = PS_NORMAL_1OF2;
- break;
- case 3:
- packet->state = PS_NORMAL_1OF3;
- break;
- default:
- /* ??? */
- packet->state = PS_INITIAL;
- }
- }
- packet->buffer[0] = MIX_CN_CIN(cable_number, cin);
- packet->buffer[1] = in;
- break;
- case PS_NORMAL_1OF3:
- if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
- packet->buffer[2] = in;
- packet->state = PS_NORMAL_2OF3;
- break;
- case PS_NORMAL_2OF3:
- if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
- packet->buffer[3] = in;
- packet->state = PS_END;
- break;
- case PS_NORMAL_1OF2:
- if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
- packet->buffer[2] = in;
- packet->state = PS_END;
- break;
- case PS_EXCL_0:
- memset(packet->buffer, 0, UMIDI_PACKET_SIZE);
- if (in==0xF7) {
- packet->buffer[0] = MIX_CN_CIN(cable_number, 0x05);
- packet->buffer[1] = 0xF7;
- packet->state = PS_END;
- break;
- }
- if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
- packet->buffer[1] = in;
- packet->state = PS_EXCL_1;
- break;
- case PS_EXCL_1:
- if (in==0xF7) {
- packet->buffer[0] = MIX_CN_CIN(cable_number, 0x06);
- packet->buffer[2] = 0xF7;
- packet->state = PS_END;
- break;
- }
- if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
- packet->buffer[2] = in;
- packet->state = PS_EXCL_2;
- break;
- case PS_EXCL_2:
- if (in==0xF7) {
- packet->buffer[0] = MIX_CN_CIN(cable_number, 0x07);
- packet->buffer[3] = 0xF7;
- packet->state = PS_END;
- break;
- }
- if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
- packet->buffer[0] = MIX_CN_CIN(cable_number, 0x04);
- packet->buffer[3] = in;
- packet->state = PS_EXCL_0;
- break;
- default:
- printf("umidi: ambiguous state.\n");
- packet->state = PS_INITIAL;
- goto retry;
- }
-}
-