Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/usb initial commit of USB midi driver.



details:   https://anonhg.NetBSD.org/src/rev/6fe32f7a72e1
branches:  trunk
changeset: 503080:6fe32f7a72e1
user:      tshiozak <tshiozak%NetBSD.org@localhost>
date:      Tue Jan 30 23:26:47 2001 +0000

description:
initial commit of USB midi driver.
  - I tested only ROLAND UM-1 and YAMAHA UX256.
    These are not conforming to USB-MIDI spec, however these are
    similar to USB-MIDI.
  - Since I've not yet seen the "genuine" USB-MIDI device,
    I cannot test such devices although I wrote the codes for it.
TODO:
  - clean up the codes.
  - umidi(4) manpage.
  - /dev/rmidi? is working well, but /dev/music seems not working correctly.

diffstat:

 sys/dev/usb/files.usb      |     8 +-
 sys/dev/usb/umidi.c        |  1279 ++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/usb/umidi_quirks.c |   198 ++++++
 sys/dev/usb/umidi_quirks.h |   118 ++++
 sys/dev/usb/umidireg.h     |    78 ++
 sys/dev/usb/umidivar.h     |   135 ++++
 6 files changed, 1815 insertions(+), 1 deletions(-)

diffs (truncated from 1850 to 300 lines):

diff -r 1c950d303776 -r 6fe32f7a72e1 sys/dev/usb/files.usb
--- a/sys/dev/usb/files.usb     Tue Jan 30 23:02:18 2001 +0000
+++ b/sys/dev/usb/files.usb     Tue Jan 30 23:26:47 2001 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.usb,v 1.26 2001/01/23 01:24:10 ichiro Exp $
+#      $NetBSD: files.usb,v 1.27 2001/01/30 23:26:47 tshiozak Exp $
 #
 # Config file and device description for machine-independent USB code.
 # Included by ports that need it.  Ports that use it must provide
@@ -36,6 +36,12 @@
 attach uaudio at uhub
 file   dev/usb/uaudio.c                uaudio
 
+# MIDI devices
+device umidi: midibus
+attach umidi at uhub
+file   dev/usb/umidi.c                 umidi
+file   dev/usb/umidi_quirks.c          umidi
+
 # Modem and com serial port
 device ucom
 attach ucom at ucombus
diff -r 1c950d303776 -r 6fe32f7a72e1 sys/dev/usb/umidi.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/usb/umidi.c       Tue Jan 30 23:26:47 2001 +0000
@@ -0,0 +1,1279 @@
+/*     $NetBSD: umidi.c,v 1.1 2001/01/30 23:26:47 tshiozak 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@localhost).
+ *
+ * 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 enable_an_endpoint(struct umidi_endpoint *);
+static void disable_an_endpoint(struct umidi_endpoint *, int);
+
+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 usbd_status unbind_jacks_from_mididev(struct umidi_mididev *);
+static usbd_status unbind_all_jacks(struct umidi_softc *);
+static usbd_status assign_all_jacks_automatically(struct umidi_softc *);
+static usbd_status open_jack(struct umidi_jack *);
+static void close_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 void in_packet_to_mididev(struct umidi_endpoint *, uByte *);
+static usbd_status start_input_transfer(struct umidi_endpoint *);
+static usbd_status start_output_transfer(struct umidi_endpoint *);
+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);
+int umidi_activate __P((device_ptr_t, enum devact));
+int umidi_detach __P((device_ptr_t, int));
+
+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);
+       unbind_all_jacks(sc);
+       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;
+}
+
+
+int
+umidi_open(void *addr,
+          int flags,
+          void (*iintr)__P((void *, int)),
+          void (*ointr)__P((void *)),
+          void *arg)
+{
+        struct umidi_mididev *mididev = addr;
+        struct umidi_softc *sc = mididev->sc;



Home | Main Index | Thread Index | Old Index