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