diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
new file mode 100644
index 0000000..5d32857
--- /dev/null
+++ b/sound/usb/usbmidi.c
@@ -0,0 +1,1564 @@
+/*
+ * usbmidi.c - ALSA USB MIDI driver
+ *
+ * Copyright (c) 2002-2005 Clemens Ladisch
+ * All rights reserved.
+ *
+ * Based on the OSS usb-midi driver by NAGANO Daisuke,
+ *          NetBSD's umidi driver by Takuya SHIOZAKI,
+ *          the "USB Device Class Definition for MIDI Devices" by Roland
+ *
+ * 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,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed and/or modified under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sound/driver.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <sound/core.h>
+#include <sound/minors.h>
+#include <sound/rawmidi.h>
+#include "usbaudio.h"
+
+
+/*
+ * define this to log all USB packets
+ */
+/* #define DUMP_PACKETS */
+
+
+MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
+MODULE_DESCRIPTION("USB Audio/MIDI helper module");
+MODULE_LICENSE("Dual BSD/GPL");
+
+
+struct usb_ms_header_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u8  bDescriptorSubtype;
+	__u8  bcdMSC[2];
+	__le16 wTotalLength;
+} __attribute__ ((packed));
+
+struct usb_ms_endpoint_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u8  bDescriptorSubtype;
+	__u8  bNumEmbMIDIJack;
+	__u8  baAssocJackID[0];
+} __attribute__ ((packed));
+
+typedef struct snd_usb_midi snd_usb_midi_t;
+typedef struct snd_usb_midi_endpoint snd_usb_midi_endpoint_t;
+typedef struct snd_usb_midi_out_endpoint snd_usb_midi_out_endpoint_t;
+typedef struct snd_usb_midi_in_endpoint snd_usb_midi_in_endpoint_t;
+typedef struct usbmidi_out_port usbmidi_out_port_t;
+typedef struct usbmidi_in_port usbmidi_in_port_t;
+
+struct usb_protocol_ops {
+	void (*input)(snd_usb_midi_in_endpoint_t*, uint8_t*, int);
+	void (*output)(snd_usb_midi_out_endpoint_t*);
+	void (*output_packet)(struct urb*, uint8_t, uint8_t, uint8_t, uint8_t);
+	void (*init_out_endpoint)(snd_usb_midi_out_endpoint_t*);
+	void (*finish_out_endpoint)(snd_usb_midi_out_endpoint_t*);
+};
+
+struct snd_usb_midi {
+	snd_usb_audio_t *chip;
+	struct usb_interface *iface;
+	const snd_usb_audio_quirk_t *quirk;
+	snd_rawmidi_t* rmidi;
+	struct usb_protocol_ops* usb_protocol_ops;
+	struct list_head list;
+
+	struct snd_usb_midi_endpoint {
+		snd_usb_midi_out_endpoint_t *out;
+		snd_usb_midi_in_endpoint_t *in;
+	} endpoints[MIDI_MAX_ENDPOINTS];
+	unsigned long input_triggered;
+};
+
+struct snd_usb_midi_out_endpoint {
+	snd_usb_midi_t* umidi;
+	struct urb* urb;
+	int urb_active;
+	int max_transfer;		/* size of urb buffer */
+	struct tasklet_struct tasklet;
+
+	spinlock_t buffer_lock;
+
+	struct usbmidi_out_port {
+		snd_usb_midi_out_endpoint_t* ep;
+		snd_rawmidi_substream_t* substream;
+		int active;
+		uint8_t cable;		/* cable number << 4 */
+		uint8_t state;
+#define STATE_UNKNOWN	0
+#define STATE_1PARAM	1
+#define STATE_2PARAM_1	2
+#define STATE_2PARAM_2	3
+#define STATE_SYSEX_0	4
+#define STATE_SYSEX_1	5
+#define STATE_SYSEX_2	6
+		uint8_t data[2];
+	} ports[0x10];
+	int current_port;
+};
+
+struct snd_usb_midi_in_endpoint {
+	snd_usb_midi_t* umidi;
+	struct urb* urb;
+	struct usbmidi_in_port {
+		snd_rawmidi_substream_t* substream;
+	} ports[0x10];
+	int seen_f5;
+	int current_port;
+};
+
+static void snd_usbmidi_do_output(snd_usb_midi_out_endpoint_t* ep);
+
+static const uint8_t snd_usbmidi_cin_length[] = {
+	0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1
+};
+
+/*
+ * Submits the URB, with error handling.
+ */
+static int snd_usbmidi_submit_urb(struct urb* urb, int flags)
+{
+	int err = usb_submit_urb(urb, flags);
+	if (err < 0 && err != -ENODEV)
+		snd_printk(KERN_ERR "usb_submit_urb: %d\n", err);
+	return err;
+}
+
+/*
+ * Error handling for URB completion functions.
+ */
+static int snd_usbmidi_urb_error(int status)
+{
+	if (status == -ENOENT)
+		return status; /* killed */
+	if (status == -EILSEQ ||
+	    status == -ECONNRESET ||
+	    status == -ETIMEDOUT)
+		return -ENODEV; /* device removed/shutdown */
+	snd_printk(KERN_ERR "urb status %d\n", status);
+	return 0; /* continue */
+}
+
+/*
+ * Receives a chunk of MIDI data.
+ */
+static void snd_usbmidi_input_data(snd_usb_midi_in_endpoint_t* ep, int portidx,
+				   uint8_t* data, int length)
+{
+	usbmidi_in_port_t* port = &ep->ports[portidx];
+
+	if (!port->substream) {
+		snd_printd("unexpected port %d!\n", portidx);
+		return;
+	}
+	if (!test_bit(port->substream->number, &ep->umidi->input_triggered))
+		return;
+	snd_rawmidi_receive(port->substream, data, length);
+}
+
+#ifdef DUMP_PACKETS
+static void dump_urb(const char *type, const u8 *data, int length)
+{
+	snd_printk(KERN_DEBUG "%s packet: [", type);
+	for (; length > 0; ++data, --length)
+		printk(" %02x", *data);
+	printk(" ]\n");
+}
+#else
+#define dump_urb(type, data, length) /* nothing */
+#endif
+
+/*
+ * Processes the data read from the device.
+ */
+static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs)
+{
+	snd_usb_midi_in_endpoint_t* ep = urb->context;
+
+	if (urb->status == 0) {
+		dump_urb("received", urb->transfer_buffer, urb->actual_length);
+		ep->umidi->usb_protocol_ops->input(ep, urb->transfer_buffer,
+						   urb->actual_length);
+	} else {
+		if (snd_usbmidi_urb_error(urb->status) < 0)
+			return;
+	}
+
+	if (usb_pipe_needs_resubmit(urb->pipe)) {
+		urb->dev = ep->umidi->chip->dev;
+		snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
+	}
+}
+
+static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs)
+{
+	snd_usb_midi_out_endpoint_t* ep = urb->context;
+
+	spin_lock(&ep->buffer_lock);
+	ep->urb_active = 0;
+	spin_unlock(&ep->buffer_lock);
+	if (urb->status < 0) {
+		if (snd_usbmidi_urb_error(urb->status) < 0)
+			return;
+	}
+	snd_usbmidi_do_output(ep);
+}
+
+/*
+ * This is called when some data should be transferred to the device
+ * (from one or more substreams).
+ */
+static void snd_usbmidi_do_output(snd_usb_midi_out_endpoint_t* ep)
+{
+	struct urb* urb = ep->urb;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ep->buffer_lock, flags);
+	if (ep->urb_active || ep->umidi->chip->shutdown) {
+		spin_unlock_irqrestore(&ep->buffer_lock, flags);
+		return;
+	}
+
+	urb->transfer_buffer_length = 0;
+	ep->umidi->usb_protocol_ops->output(ep);
+
+	if (urb->transfer_buffer_length > 0) {
+		dump_urb("sending", urb->transfer_buffer,
+			 urb->transfer_buffer_length);
+		urb->dev = ep->umidi->chip->dev;
+		ep->urb_active = snd_usbmidi_submit_urb(urb, GFP_ATOMIC) >= 0;
+	}
+	spin_unlock_irqrestore(&ep->buffer_lock, flags);
+}
+
+static void snd_usbmidi_out_tasklet(unsigned long data)
+{
+	snd_usb_midi_out_endpoint_t* ep = (snd_usb_midi_out_endpoint_t *) data;
+
+	snd_usbmidi_do_output(ep);
+}
+
+/* helper function to send static data that may not DMA-able */
+static int send_bulk_static_data(snd_usb_midi_out_endpoint_t* ep,
+				 const void *data, int len)
+{
+	int err;
+	void *buf = kmalloc(len, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	memcpy(buf, data, len);
+	dump_urb("sending", buf, len);
+	err = usb_bulk_msg(ep->umidi->chip->dev, ep->urb->pipe, buf, len,
+			   NULL, 250);
+	kfree(buf);
+	return err;
+}
+
+/*
+ * Standard USB MIDI protocol: see the spec.
+ * Midiman protocol: like the standard protocol, but the control byte is the
+ * fourth byte in each packet, and uses length instead of CIN.
+ */
+
+static void snd_usbmidi_standard_input(snd_usb_midi_in_endpoint_t* ep,
+				       uint8_t* buffer, int buffer_length)
+{
+	int i;
+
+	for (i = 0; i + 3 < buffer_length; i += 4)
+		if (buffer[i] != 0) {
+			int cable = buffer[i] >> 4;
+			int length = snd_usbmidi_cin_length[buffer[i] & 0x0f];
+			snd_usbmidi_input_data(ep, cable, &buffer[i + 1], length);
+		}
+}
+
+static void snd_usbmidi_midiman_input(snd_usb_midi_in_endpoint_t* ep,
+				      uint8_t* buffer, int buffer_length)
+{
+	int i;
+
+	for (i = 0; i + 3 < buffer_length; i += 4)
+		if (buffer[i + 3] != 0) {
+			int port = buffer[i + 3] >> 4;
+			int length = buffer[i + 3] & 3;
+			snd_usbmidi_input_data(ep, port, &buffer[i], length);
+		}
+}
+
+/*
+ * Adds one USB MIDI packet to the output buffer.
+ */
+static void snd_usbmidi_output_standard_packet(struct urb* urb, uint8_t p0,
+					       uint8_t p1, uint8_t p2, uint8_t p3)
+{
+
+	uint8_t* buf = (uint8_t*)urb->transfer_buffer + urb->transfer_buffer_length;
+	buf[0] = p0;
+	buf[1] = p1;
+	buf[2] = p2;
+	buf[3] = p3;
+	urb->transfer_buffer_length += 4;
+}
+
+/*
+ * Adds one Midiman packet to the output buffer.
+ */
+static void snd_usbmidi_output_midiman_packet(struct urb* urb, uint8_t p0,
+					      uint8_t p1, uint8_t p2, uint8_t p3)
+{
+
+	uint8_t* buf = (uint8_t*)urb->transfer_buffer + urb->transfer_buffer_length;
+	buf[0] = p1;
+	buf[1] = p2;
+	buf[2] = p3;
+	buf[3] = (p0 & 0xf0) | snd_usbmidi_cin_length[p0 & 0x0f];
+	urb->transfer_buffer_length += 4;
+}
+
+/*
+ * Converts MIDI commands to USB MIDI packets.
+ */
+static void snd_usbmidi_transmit_byte(usbmidi_out_port_t* port,
+				      uint8_t b, struct urb* urb)
+{
+	uint8_t p0 = port->cable;
+	void (*output_packet)(struct urb*, uint8_t, uint8_t, uint8_t, uint8_t) =
+		port->ep->umidi->usb_protocol_ops->output_packet;
+
+	if (b >= 0xf8) {
+		output_packet(urb, p0 | 0x0f, b, 0, 0);
+	} else if (b >= 0xf0) {
+		switch (b) {
+		case 0xf0:
+			port->data[0] = b;
+			port->state = STATE_SYSEX_1;
+			break;
+		case 0xf1:
+		case 0xf3:
+			port->data[0] = b;
+			port->state = STATE_1PARAM;
+			break;
+		case 0xf2:
+			port->data[0] = b;
+			port->state = STATE_2PARAM_1;
+			break;
+		case 0xf4:
+		case 0xf5:
+			port->state = STATE_UNKNOWN;
+			break;
+		case 0xf6:
+			output_packet(urb, p0 | 0x05, 0xf6, 0, 0);
+			port->state = STATE_UNKNOWN;
+			break;
+		case 0xf7:
+			switch (port->state) {
+			case STATE_SYSEX_0:
+				output_packet(urb, p0 | 0x05, 0xf7, 0, 0);
+				break;
+			case STATE_SYSEX_1:
+				output_packet(urb, p0 | 0x06, port->data[0], 0xf7, 0);
+				break;
+			case STATE_SYSEX_2:
+				output_packet(urb, p0 | 0x07, port->data[0], port->data[1], 0xf7);
+				break;
+			}
+			port->state = STATE_UNKNOWN;
+			break;
+		}
+	} else if (b >= 0x80) {
+		port->data[0] = b;
+		if (b >= 0xc0 && b <= 0xdf)
+			port->state = STATE_1PARAM;
+		else
+			port->state = STATE_2PARAM_1;
+	} else { /* b < 0x80 */
+		switch (port->state) {
+		case STATE_1PARAM:
+			if (port->data[0] < 0xf0) {
+				p0 |= port->data[0] >> 4;
+			} else {
+				p0 |= 0x02;
+				port->state = STATE_UNKNOWN;
+			}
+			output_packet(urb, p0, port->data[0], b, 0);
+			break;
+		case STATE_2PARAM_1:
+			port->data[1] = b;
+			port->state = STATE_2PARAM_2;
+			break;
+		case STATE_2PARAM_2:
+			if (port->data[0] < 0xf0) {
+				p0 |= port->data[0] >> 4;
+				port->state = STATE_2PARAM_1;
+			} else {
+				p0 |= 0x03;
+				port->state = STATE_UNKNOWN;
+			}
+			output_packet(urb, p0, port->data[0], port->data[1], b);
+			break;
+		case STATE_SYSEX_0:
+			port->data[0] = b;
+			port->state = STATE_SYSEX_1;
+			break;
+		case STATE_SYSEX_1:
+			port->data[1] = b;
+			port->state = STATE_SYSEX_2;
+			break;
+		case STATE_SYSEX_2:
+			output_packet(urb, p0 | 0x04, port->data[0], port->data[1], b);
+			port->state = STATE_SYSEX_0;
+			break;
+		}
+	}
+}
+
+static void snd_usbmidi_standard_output(snd_usb_midi_out_endpoint_t* ep)
+{
+	struct urb* urb = ep->urb;
+	int p;
+
+	/* FIXME: lower-numbered ports can starve higher-numbered ports */
+	for (p = 0; p < 0x10; ++p) {
+		usbmidi_out_port_t* port = &ep->ports[p];
+		if (!port->active)
+			continue;
+		while (urb->transfer_buffer_length + 3 < ep->max_transfer) {
+			uint8_t b;
+			if (snd_rawmidi_transmit(port->substream, &b, 1) != 1) {
+				port->active = 0;
+				break;
+			}
+			snd_usbmidi_transmit_byte(port, b, urb);
+		}
+	}
+}
+
+static struct usb_protocol_ops snd_usbmidi_standard_ops = {
+	.input = snd_usbmidi_standard_input,
+	.output = snd_usbmidi_standard_output,
+	.output_packet = snd_usbmidi_output_standard_packet,
+};
+
+static struct usb_protocol_ops snd_usbmidi_midiman_ops = {
+	.input = snd_usbmidi_midiman_input,
+	.output = snd_usbmidi_standard_output, 
+	.output_packet = snd_usbmidi_output_midiman_packet,
+};
+
+/*
+ * Novation USB MIDI protocol: number of data bytes is in the first byte
+ * (when receiving) (+1!) or in the second byte (when sending); data begins
+ * at the third byte.
+ */
+
+static void snd_usbmidi_novation_input(snd_usb_midi_in_endpoint_t* ep,
+				       uint8_t* buffer, int buffer_length)
+{
+	if (buffer_length < 2 || !buffer[0] || buffer_length < buffer[0] + 1)
+		return;
+	snd_usbmidi_input_data(ep, 0, &buffer[2], buffer[0] - 1);
+}
+
+static void snd_usbmidi_novation_output(snd_usb_midi_out_endpoint_t* ep)
+{
+	uint8_t* transfer_buffer;
+	int count;
+
+	if (!ep->ports[0].active)
+		return;
+	transfer_buffer = ep->urb->transfer_buffer;
+	count = snd_rawmidi_transmit(ep->ports[0].substream,
+				     &transfer_buffer[2],
+				     ep->max_transfer - 2);
+	if (count < 1) {
+		ep->ports[0].active = 0;
+		return;
+	}
+	transfer_buffer[0] = 0;
+	transfer_buffer[1] = count;
+	ep->urb->transfer_buffer_length = 2 + count;
+}
+
+static struct usb_protocol_ops snd_usbmidi_novation_ops = {
+	.input = snd_usbmidi_novation_input,
+	.output = snd_usbmidi_novation_output,
+};
+
+/*
+ * Mark of the Unicorn USB MIDI protocol: raw MIDI.
+ */
+
+static void snd_usbmidi_motu_input(snd_usb_midi_in_endpoint_t* ep,
+				   uint8_t* buffer, int buffer_length)
+{
+	snd_usbmidi_input_data(ep, 0, buffer, buffer_length);
+}
+
+static void snd_usbmidi_motu_output(snd_usb_midi_out_endpoint_t* ep)
+{
+	int count;
+
+	if (!ep->ports[0].active)
+		return;
+	count = snd_rawmidi_transmit(ep->ports[0].substream,
+				     ep->urb->transfer_buffer,
+				     ep->max_transfer);
+	if (count < 1) {
+		ep->ports[0].active = 0;
+		return;
+	}
+	ep->urb->transfer_buffer_length = count;
+}
+
+static struct usb_protocol_ops snd_usbmidi_motu_ops = {
+	.input = snd_usbmidi_motu_input,
+	.output = snd_usbmidi_motu_output,
+};
+
+/*
+ * Emagic USB MIDI protocol: raw MIDI with "F5 xx" port switching.
+ */
+
+static void snd_usbmidi_emagic_init_out(snd_usb_midi_out_endpoint_t* ep)
+{
+	static const u8 init_data[] = {
+		/* initialization magic: "get version" */
+		0xf0,
+		0x00, 0x20, 0x31,	/* Emagic */
+		0x64,			/* Unitor8 */
+		0x0b,			/* version number request */
+		0x00,			/* command version */
+		0x00,			/* EEPROM, box 0 */
+		0xf7
+	};
+	send_bulk_static_data(ep, init_data, sizeof(init_data));
+	/* while we're at it, pour on more magic */
+	send_bulk_static_data(ep, init_data, sizeof(init_data));
+}
+
+static void snd_usbmidi_emagic_finish_out(snd_usb_midi_out_endpoint_t* ep)
+{
+	static const u8 finish_data[] = {
+		/* switch to patch mode with last preset */
+		0xf0,
+		0x00, 0x20, 0x31,	/* Emagic */
+		0x64,			/* Unitor8 */
+		0x10,			/* patch switch command */
+		0x00,			/* command version */
+		0x7f,			/* to all boxes */
+		0x40,			/* last preset in EEPROM */
+		0xf7
+	};
+	send_bulk_static_data(ep, finish_data, sizeof(finish_data));
+}
+
+static void snd_usbmidi_emagic_input(snd_usb_midi_in_endpoint_t* ep,
+				     uint8_t* buffer, int buffer_length)
+{
+	/* ignore padding bytes at end of buffer */
+	while (buffer_length > 0 && buffer[buffer_length - 1] == 0xff)
+		--buffer_length;
+
+	/* handle F5 at end of last buffer */
+	if (ep->seen_f5)
+		goto switch_port;
+
+	while (buffer_length > 0) {
+		int i;
+
+		/* determine size of data until next F5 */
+		for (i = 0; i < buffer_length; ++i)
+			if (buffer[i] == 0xf5)
+				break;
+		snd_usbmidi_input_data(ep, ep->current_port, buffer, i);
+		buffer += i;
+		buffer_length -= i;
+
+		if (buffer_length <= 0)
+			break;
+		/* assert(buffer[0] == 0xf5); */
+		ep->seen_f5 = 1;
+		++buffer;
+		--buffer_length;
+
+	switch_port:
+		if (buffer_length <= 0)
+			break;
+		if (buffer[0] < 0x80) {
+			ep->current_port = (buffer[0] - 1) & 15;
+			++buffer;
+			--buffer_length;
+		}
+		ep->seen_f5 = 0;
+	}
+}
+
+static void snd_usbmidi_emagic_output(snd_usb_midi_out_endpoint_t* ep)
+{
+	int port0 = ep->current_port;
+	uint8_t* buf = ep->urb->transfer_buffer;
+	int buf_free = ep->max_transfer;
+	int length, i;
+
+	for (i = 0; i < 0x10; ++i) {
+		/* round-robin, starting at the last current port */
+		int portnum = (port0 + i) & 15;
+		usbmidi_out_port_t* port = &ep->ports[portnum];
+
+		if (!port->active)
+			continue;
+		if (snd_rawmidi_transmit_peek(port->substream, buf, 1) != 1) {
+			port->active = 0;
+			continue;
+		}
+
+		if (portnum != ep->current_port) {
+			if (buf_free < 2)
+				break;
+			ep->current_port = portnum;
+			buf[0] = 0xf5;
+			buf[1] = (portnum + 1) & 15;
+			buf += 2;
+			buf_free -= 2;
+		}
+
+		if (buf_free < 1)
+			break;
+		length = snd_rawmidi_transmit(port->substream, buf, buf_free);
+		if (length > 0) {
+			buf += length;
+			buf_free -= length;
+			if (buf_free < 1)
+				break;
+		}
+	}
+	ep->urb->transfer_buffer_length = ep->max_transfer - buf_free;
+}
+
+static struct usb_protocol_ops snd_usbmidi_emagic_ops = {
+	.input = snd_usbmidi_emagic_input,
+	.output = snd_usbmidi_emagic_output,
+	.init_out_endpoint = snd_usbmidi_emagic_init_out,
+	.finish_out_endpoint = snd_usbmidi_emagic_finish_out,
+};
+
+
+static int snd_usbmidi_output_open(snd_rawmidi_substream_t* substream)
+{
+	snd_usb_midi_t* umidi = substream->rmidi->private_data;
+	usbmidi_out_port_t* port = NULL;
+	int i, j;
+
+	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
+		if (umidi->endpoints[i].out)
+			for (j = 0; j < 0x10; ++j)
+				if (umidi->endpoints[i].out->ports[j].substream == substream) {
+					port = &umidi->endpoints[i].out->ports[j];
+					break;
+				}
+	if (!port) {
+		snd_BUG();
+		return -ENXIO;
+	}
+	substream->runtime->private_data = port;
+	port->state = STATE_UNKNOWN;
+	return 0;
+}
+
+static int snd_usbmidi_output_close(snd_rawmidi_substream_t* substream)
+{
+	return 0;
+}
+
+static void snd_usbmidi_output_trigger(snd_rawmidi_substream_t* substream, int up)
+{
+	usbmidi_out_port_t* port = (usbmidi_out_port_t*)substream->runtime->private_data;
+
+	port->active = up;
+	if (up) {
+		if (port->ep->umidi->chip->shutdown) {
+			/* gobble up remaining bytes to prevent wait in
+			 * snd_rawmidi_drain_output */
+			while (!snd_rawmidi_transmit_empty(substream))
+				snd_rawmidi_transmit_ack(substream, 1);
+			return;
+		}
+		tasklet_hi_schedule(&port->ep->tasklet);
+	}
+}
+
+static int snd_usbmidi_input_open(snd_rawmidi_substream_t* substream)
+{
+	return 0;
+}
+
+static int snd_usbmidi_input_close(snd_rawmidi_substream_t* substream)
+{
+	return 0;
+}
+
+static void snd_usbmidi_input_trigger(snd_rawmidi_substream_t* substream, int up)
+{
+	snd_usb_midi_t* umidi = substream->rmidi->private_data;
+
+	if (up)
+		set_bit(substream->number, &umidi->input_triggered);
+	else
+		clear_bit(substream->number, &umidi->input_triggered);
+}
+
+static snd_rawmidi_ops_t snd_usbmidi_output_ops = {
+	.open = snd_usbmidi_output_open,
+	.close = snd_usbmidi_output_close,
+	.trigger = snd_usbmidi_output_trigger,
+};
+
+static snd_rawmidi_ops_t snd_usbmidi_input_ops = {
+	.open = snd_usbmidi_input_open,
+	.close = snd_usbmidi_input_close,
+	.trigger = snd_usbmidi_input_trigger
+};
+
+/*
+ * Frees an input endpoint.
+ * May be called when ep hasn't been initialized completely.
+ */
+static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep)
+{
+	if (ep->urb) {
+		kfree(ep->urb->transfer_buffer);
+		usb_free_urb(ep->urb);
+	}
+	kfree(ep);
+}
+
+/*
+ * Creates an input endpoint.
+ */
+static int snd_usbmidi_in_endpoint_create(snd_usb_midi_t* umidi,
+					  snd_usb_midi_endpoint_info_t* ep_info,
+					  snd_usb_midi_endpoint_t* rep)
+{
+	snd_usb_midi_in_endpoint_t* ep;
+	void* buffer;
+	unsigned int pipe;
+	int length;
+
+	rep->in = NULL;
+	ep = kcalloc(1, sizeof(*ep), GFP_KERNEL);
+	if (!ep)
+		return -ENOMEM;
+	ep->umidi = umidi;
+
+	ep->urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!ep->urb) {
+		snd_usbmidi_in_endpoint_delete(ep);
+		return -ENOMEM;
+	}
+	if (ep_info->in_interval)
+		pipe = usb_rcvintpipe(umidi->chip->dev, ep_info->in_ep);
+	else
+		pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->in_ep);
+	length = usb_maxpacket(umidi->chip->dev, pipe, 0);
+	buffer = kmalloc(length, GFP_KERNEL);
+	if (!buffer) {
+		snd_usbmidi_in_endpoint_delete(ep);
+		return -ENOMEM;
+	}
+	if (ep_info->in_interval)
+		usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer, length,
+				 snd_usb_complete_callback(snd_usbmidi_in_urb_complete),
+				 ep, ep_info->in_interval);
+	else
+		usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, length,
+				  snd_usb_complete_callback(snd_usbmidi_in_urb_complete),
+				  ep);
+
+	rep->in = ep;
+	return 0;
+}
+
+static unsigned int snd_usbmidi_count_bits(unsigned int x)
+{
+	unsigned int bits = 0;
+
+	for (; x; x >>= 1)
+		bits += x & 1;
+	return bits;
+}
+
+/*
+ * Frees an output endpoint.
+ * May be called when ep hasn't been initialized completely.
+ */
+static void snd_usbmidi_out_endpoint_delete(snd_usb_midi_out_endpoint_t* ep)
+{
+	if (ep->tasklet.func)
+		tasklet_kill(&ep->tasklet);
+	if (ep->urb) {
+		kfree(ep->urb->transfer_buffer);
+		usb_free_urb(ep->urb);
+	}
+	kfree(ep);
+}
+
+/*
+ * Creates an output endpoint, and initializes output ports.
+ */
+static int snd_usbmidi_out_endpoint_create(snd_usb_midi_t* umidi,
+					   snd_usb_midi_endpoint_info_t* ep_info,
+			 		   snd_usb_midi_endpoint_t* rep)
+{
+	snd_usb_midi_out_endpoint_t* ep;
+	int i;
+	unsigned int pipe;
+	void* buffer;
+
+	rep->out = NULL;
+	ep = kcalloc(1, sizeof(*ep), GFP_KERNEL);
+	if (!ep)
+		return -ENOMEM;
+	ep->umidi = umidi;
+
+	ep->urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!ep->urb) {
+		snd_usbmidi_out_endpoint_delete(ep);
+		return -ENOMEM;
+	}
+	/* we never use interrupt output pipes */
+	pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep);
+	ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1);
+	buffer = kmalloc(ep->max_transfer, GFP_KERNEL);
+	if (!buffer) {
+		snd_usbmidi_out_endpoint_delete(ep);
+		return -ENOMEM;
+	}
+	usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer,
+			  ep->max_transfer,
+			  snd_usb_complete_callback(snd_usbmidi_out_urb_complete), ep);
+
+	spin_lock_init(&ep->buffer_lock);
+	tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep);
+
+	for (i = 0; i < 0x10; ++i)
+		if (ep_info->out_cables & (1 << i)) {
+			ep->ports[i].ep = ep;
+			ep->ports[i].cable = i << 4;
+		}
+
+	if (umidi->usb_protocol_ops->init_out_endpoint)
+		umidi->usb_protocol_ops->init_out_endpoint(ep);
+
+	rep->out = ep;
+	return 0;
+}
+
+/*
+ * Frees everything.
+ */
+static void snd_usbmidi_free(snd_usb_midi_t* umidi)
+{
+	int i;
+
+	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
+		snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i];
+		if (ep->out)
+			snd_usbmidi_out_endpoint_delete(ep->out);
+		if (ep->in)
+			snd_usbmidi_in_endpoint_delete(ep->in);
+	}
+	kfree(umidi);
+}
+
+/*
+ * Unlinks all URBs (must be done before the usb_device is deleted).
+ */
+void snd_usbmidi_disconnect(struct list_head* p, struct usb_driver *driver)
+{
+	snd_usb_midi_t* umidi;
+	int i;
+
+	umidi = list_entry(p, snd_usb_midi_t, list);
+	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
+		snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i];
+		if (ep->out && ep->out->urb) {
+			usb_kill_urb(ep->out->urb);
+			if (umidi->usb_protocol_ops->finish_out_endpoint)
+				umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
+		}
+		if (ep->in && ep->in->urb)
+			usb_kill_urb(ep->in->urb);
+	}
+}
+
+static void snd_usbmidi_rawmidi_free(snd_rawmidi_t* rmidi)
+{
+	snd_usb_midi_t* umidi = rmidi->private_data;
+	snd_usbmidi_free(umidi);
+}
+
+static snd_rawmidi_substream_t* snd_usbmidi_find_substream(snd_usb_midi_t* umidi,
+							   int stream, int number)
+{
+	struct list_head* list;
+
+	list_for_each(list, &umidi->rmidi->streams[stream].substreams) {
+		snd_rawmidi_substream_t* substream = list_entry(list, snd_rawmidi_substream_t, list);
+		if (substream->number == number)
+			return substream;
+	}
+	return NULL;
+}
+
+/*
+ * This list specifies names for ports that do not fit into the standard
+ * "(product) MIDI (n)" schema because they aren't external MIDI ports,
+ * such as internal control or synthesizer ports.
+ */
+static struct {
+	__u16 vendor;
+	__u16 product;
+	int port;
+	const char *name_format;
+} snd_usbmidi_port_names[] = {
+	/* Roland UA-100 */
+	{0x0582, 0x0000, 2, "%s Control"},
+	/* Roland SC-8850 */
+	{0x0582, 0x0003, 0, "%s Part A"},
+	{0x0582, 0x0003, 1, "%s Part B"},
+	{0x0582, 0x0003, 2, "%s Part C"},
+	{0x0582, 0x0003, 3, "%s Part D"},
+	{0x0582, 0x0003, 4, "%s MIDI 1"},
+	{0x0582, 0x0003, 5, "%s MIDI 2"},
+	/* Roland U-8 */
+	{0x0582, 0x0004, 0, "%s MIDI"},
+	{0x0582, 0x0004, 1, "%s Control"},
+	/* Roland SC-8820 */
+	{0x0582, 0x0007, 0, "%s Part A"},
+	{0x0582, 0x0007, 1, "%s Part B"},
+	{0x0582, 0x0007, 2, "%s MIDI"},
+	/* Roland SK-500 */
+	{0x0582, 0x000b, 0, "%s Part A"},
+	{0x0582, 0x000b, 1, "%s Part B"},
+	{0x0582, 0x000b, 2, "%s MIDI"},
+	/* Roland SC-D70 */
+	{0x0582, 0x000c, 0, "%s Part A"},
+	{0x0582, 0x000c, 1, "%s Part B"},
+	{0x0582, 0x000c, 2, "%s MIDI"},
+	/* Edirol UM-880 */
+	{0x0582, 0x0014, 8, "%s Control"},
+	/* Edirol SD-90 */
+	{0x0582, 0x0016, 0, "%s Part A"},
+	{0x0582, 0x0016, 1, "%s Part B"},
+	{0x0582, 0x0016, 2, "%s MIDI 1"},
+	{0x0582, 0x0016, 3, "%s MIDI 2"},
+	/* Edirol UM-550 */
+	{0x0582, 0x0023, 5, "%s Control"},
+	/* Edirol SD-20 */
+	{0x0582, 0x0027, 0, "%s Part A"},
+	{0x0582, 0x0027, 1, "%s Part B"},
+	{0x0582, 0x0027, 2, "%s MIDI"},
+	/* Edirol SD-80 */
+	{0x0582, 0x0029, 0, "%s Part A"},
+	{0x0582, 0x0029, 1, "%s Part B"},
+	{0x0582, 0x0029, 2, "%s MIDI 1"},
+	{0x0582, 0x0029, 3, "%s MIDI 2"},
+	/* Edirol UA-700 */
+	{0x0582, 0x002b, 0, "%s MIDI"},
+	{0x0582, 0x002b, 1, "%s Control"},
+	/* Roland VariOS */
+	{0x0582, 0x002f, 0, "%s MIDI"},
+	{0x0582, 0x002f, 1, "%s External MIDI"},
+	{0x0582, 0x002f, 2, "%s Sync"},
+	/* Edirol PCR */
+	{0x0582, 0x0033, 0, "%s MIDI"},
+	{0x0582, 0x0033, 1, "%s 1"},
+	{0x0582, 0x0033, 2, "%s 2"},
+	/* BOSS GS-10 */
+	{0x0582, 0x003b, 0, "%s MIDI"},
+	{0x0582, 0x003b, 1, "%s Control"},
+	/* Edirol UA-1000 */
+	{0x0582, 0x0044, 0, "%s MIDI"},
+	{0x0582, 0x0044, 1, "%s Control"},
+	/* Edirol UR-80 */
+	{0x0582, 0x0048, 0, "%s MIDI"},
+	{0x0582, 0x0048, 1, "%s 1"},
+	{0x0582, 0x0048, 2, "%s 2"},
+	/* Edirol PCR-A */
+	{0x0582, 0x004d, 0, "%s MIDI"},
+	{0x0582, 0x004d, 1, "%s 1"},
+	{0x0582, 0x004d, 2, "%s 2"},
+	/* M-Audio MidiSport 8x8 */
+	{0x0763, 0x1031, 8, "%s Control"},
+	{0x0763, 0x1033, 8, "%s Control"},
+	/* MOTU Fastlane */
+	{0x07fd, 0x0001, 0, "%s MIDI A"},
+	{0x07fd, 0x0001, 1, "%s MIDI B"},
+	/* Emagic Unitor8/AMT8/MT4 */
+	{0x086a, 0x0001, 8, "%s Broadcast"},
+	{0x086a, 0x0002, 8, "%s Broadcast"},
+	{0x086a, 0x0003, 4, "%s Broadcast"},
+};
+
+static void snd_usbmidi_init_substream(snd_usb_midi_t* umidi,
+				       int stream, int number,
+				       snd_rawmidi_substream_t** rsubstream)
+{
+	int i;
+	__u16 vendor, product;
+	const char *name_format;
+
+	snd_rawmidi_substream_t* substream = snd_usbmidi_find_substream(umidi, stream, number);
+	if (!substream) {
+		snd_printd(KERN_ERR "substream %d:%d not found\n", stream, number);
+		return;
+	}
+
+	/* TODO: read port name from jack descriptor */
+	name_format = "%s MIDI %d";
+	vendor = le16_to_cpu(umidi->chip->dev->descriptor.idVendor);
+	product = le16_to_cpu(umidi->chip->dev->descriptor.idProduct);
+	for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_names); ++i) {
+		if (snd_usbmidi_port_names[i].vendor == vendor &&
+		    snd_usbmidi_port_names[i].product == product &&
+		    snd_usbmidi_port_names[i].port == number) {
+			name_format = snd_usbmidi_port_names[i].name_format;
+			break;
+		}
+	}
+	snprintf(substream->name, sizeof(substream->name),
+		 name_format, umidi->chip->card->shortname, number + 1);
+
+	*rsubstream = substream;
+}
+
+/*
+ * Creates the endpoints and their ports.
+ */
+static int snd_usbmidi_create_endpoints(snd_usb_midi_t* umidi,
+					snd_usb_midi_endpoint_info_t* endpoints)
+{
+	int i, j, err;
+	int out_ports = 0, in_ports = 0;
+
+	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
+		if (endpoints[i].out_cables) {
+			err = snd_usbmidi_out_endpoint_create(umidi, &endpoints[i],
+							      &umidi->endpoints[i]);
+			if (err < 0)
+				return err;
+		}
+		if (endpoints[i].in_cables) {
+			err = snd_usbmidi_in_endpoint_create(umidi, &endpoints[i],
+							     &umidi->endpoints[i]);
+			if (err < 0)
+				return err;
+		}
+
+		for (j = 0; j < 0x10; ++j) {
+			if (endpoints[i].out_cables & (1 << j)) {
+				snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_OUTPUT, out_ports,
+							   &umidi->endpoints[i].out->ports[j].substream);
+				++out_ports;
+			}
+			if (endpoints[i].in_cables & (1 << j)) {
+				snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_INPUT, in_ports,
+							   &umidi->endpoints[i].in->ports[j].substream);
+				++in_ports;
+			}
+		}
+	}
+	snd_printdd(KERN_INFO "created %d output and %d input ports\n",
+		    out_ports, in_ports);
+	return 0;
+}
+
+/*
+ * Returns MIDIStreaming device capabilities.
+ */
+static int snd_usbmidi_get_ms_info(snd_usb_midi_t* umidi,
+			   	   snd_usb_midi_endpoint_info_t* endpoints)
+{
+	struct usb_interface* intf;
+	struct usb_host_interface *hostif;
+	struct usb_interface_descriptor* intfd;
+	struct usb_ms_header_descriptor* ms_header;
+	struct usb_host_endpoint *hostep;
+	struct usb_endpoint_descriptor* ep;
+	struct usb_ms_endpoint_descriptor* ms_ep;
+	int i, epidx;
+
+	intf = umidi->iface;
+	if (!intf)
+		return -ENXIO;
+	hostif = &intf->altsetting[0];
+	intfd = get_iface_desc(hostif);
+	ms_header = (struct usb_ms_header_descriptor*)hostif->extra;
+	if (hostif->extralen >= 7 &&
+	    ms_header->bLength >= 7 &&
+	    ms_header->bDescriptorType == USB_DT_CS_INTERFACE &&
+	    ms_header->bDescriptorSubtype == HEADER)
+		snd_printdd(KERN_INFO "MIDIStreaming version %02x.%02x\n",
+			    ms_header->bcdMSC[1], ms_header->bcdMSC[0]);
+	else
+		snd_printk(KERN_WARNING "MIDIStreaming interface descriptor not found\n");
+
+	epidx = 0;
+	for (i = 0; i < intfd->bNumEndpoints; ++i) {
+		hostep = &hostif->endpoint[i];
+		ep = get_ep_desc(hostep);
+		if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK &&
+		    (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
+			continue;
+		ms_ep = (struct usb_ms_endpoint_descriptor*)hostep->extra;
+		if (hostep->extralen < 4 ||
+		    ms_ep->bLength < 4 ||
+		    ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT ||
+		    ms_ep->bDescriptorSubtype != MS_GENERAL)
+			continue;
+		if ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
+			if (endpoints[epidx].out_ep) {
+				if (++epidx >= MIDI_MAX_ENDPOINTS) {
+					snd_printk(KERN_WARNING "too many endpoints\n");
+					break;
+				}
+			}
+			endpoints[epidx].out_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+			if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
+				endpoints[epidx].out_interval = ep->bInterval;
+			endpoints[epidx].out_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
+			snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n",
+				    ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);
+		} else {
+			if (endpoints[epidx].in_ep) {
+				if (++epidx >= MIDI_MAX_ENDPOINTS) {
+					snd_printk(KERN_WARNING "too many endpoints\n");
+					break;
+				}
+			}
+			endpoints[epidx].in_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+			if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
+				endpoints[epidx].in_interval = ep->bInterval;
+			endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
+			snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n",
+				    ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);
+		}
+	}
+	return 0;
+}
+
+/*
+ * On Roland devices, use the second alternate setting to be able to use
+ * the interrupt input endpoint.
+ */
+static void snd_usbmidi_switch_roland_altsetting(snd_usb_midi_t* umidi)
+{
+	struct usb_interface* intf;
+	struct usb_host_interface *hostif;
+	struct usb_interface_descriptor* intfd;
+
+	intf = umidi->iface;
+	if (!intf || intf->num_altsetting != 2)
+		return;
+
+	hostif = &intf->altsetting[1];
+	intfd = get_iface_desc(hostif);
+	if (intfd->bNumEndpoints != 2 ||
+	    (get_endpoint(hostif, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK ||
+	    (get_endpoint(hostif, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
+		return;
+
+	snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n",
+		    intfd->bAlternateSetting);
+	usb_set_interface(umidi->chip->dev, intfd->bInterfaceNumber,
+			  intfd->bAlternateSetting);
+}
+
+/*
+ * Try to find any usable endpoints in the interface.
+ */
+static int snd_usbmidi_detect_endpoints(snd_usb_midi_t* umidi,
+					snd_usb_midi_endpoint_info_t* endpoint,
+					int max_endpoints)
+{
+	struct usb_interface* intf;
+	struct usb_host_interface *hostif;
+	struct usb_interface_descriptor* intfd;
+	struct usb_endpoint_descriptor* epd;
+	int i, out_eps = 0, in_eps = 0;
+
+	if (le16_to_cpu(umidi->chip->dev->descriptor.idVendor) == 0x0582)
+		snd_usbmidi_switch_roland_altsetting(umidi);
+
+	intf = umidi->iface;
+	if (!intf || intf->num_altsetting < 1)
+		return -ENOENT;
+	hostif = intf->cur_altsetting;
+	intfd = get_iface_desc(hostif);
+
+	for (i = 0; i < intfd->bNumEndpoints; ++i) {
+		epd = get_endpoint(hostif, i);
+		if ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK &&
+		    (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
+			continue;
+		if (out_eps < max_endpoints &&
+		    (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
+			endpoint[out_eps].out_ep = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+			if ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
+				endpoint[out_eps].out_interval = epd->bInterval;
+			++out_eps;
+		}
+		if (in_eps < max_endpoints &&
+		    (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
+			endpoint[in_eps].in_ep = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+			if ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
+				endpoint[in_eps].in_interval = epd->bInterval;
+			++in_eps;
+		}
+	}
+	return (out_eps || in_eps) ? 0 : -ENOENT;
+}
+
+/*
+ * Detects the endpoints for one-port-per-endpoint protocols.
+ */
+static int snd_usbmidi_detect_per_port_endpoints(snd_usb_midi_t* umidi,
+						 snd_usb_midi_endpoint_info_t* endpoints)
+{
+	int err, i;
+	
+	err = snd_usbmidi_detect_endpoints(umidi, endpoints, MIDI_MAX_ENDPOINTS);
+	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
+		if (endpoints[i].out_ep)
+			endpoints[i].out_cables = 0x0001;
+		if (endpoints[i].in_ep)
+			endpoints[i].in_cables = 0x0001;
+	}
+	return err;
+}
+
+/*
+ * Detects the endpoints and ports of Yamaha devices.
+ */
+static int snd_usbmidi_detect_yamaha(snd_usb_midi_t* umidi,
+				     snd_usb_midi_endpoint_info_t* endpoint)
+{
+	struct usb_interface* intf;
+	struct usb_host_interface *hostif;
+	struct usb_interface_descriptor* intfd;
+	uint8_t* cs_desc;
+
+	intf = umidi->iface;
+	if (!intf)
+		return -ENOENT;
+	hostif = intf->altsetting;
+	intfd = get_iface_desc(hostif);
+	if (intfd->bNumEndpoints < 1)
+		return -ENOENT;
+
+	/*
+	 * For each port there is one MIDI_IN/OUT_JACK descriptor, not
+	 * necessarily with any useful contents.  So simply count 'em.
+	 */
+	for (cs_desc = hostif->extra;
+	     cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2;
+	     cs_desc += cs_desc[0]) {
+		if (cs_desc[1] == CS_AUDIO_INTERFACE) {
+			if (cs_desc[2] == MIDI_IN_JACK)
+				endpoint->in_cables = (endpoint->in_cables << 1) | 1;
+			else if (cs_desc[2] == MIDI_OUT_JACK)
+				endpoint->out_cables = (endpoint->out_cables << 1) | 1;
+		}
+	}
+	if (!endpoint->in_cables && !endpoint->out_cables)
+		return -ENOENT;
+
+	return snd_usbmidi_detect_endpoints(umidi, endpoint, 1);
+}
+
+/*
+ * Creates the endpoints and their ports for Midiman devices.
+ */
+static int snd_usbmidi_create_endpoints_midiman(snd_usb_midi_t* umidi,
+						snd_usb_midi_endpoint_info_t* endpoint)
+{
+	snd_usb_midi_endpoint_info_t ep_info;
+	struct usb_interface* intf;
+	struct usb_host_interface *hostif;
+	struct usb_interface_descriptor* intfd;
+	struct usb_endpoint_descriptor* epd;
+	int cable, err;
+
+	intf = umidi->iface;
+	if (!intf)
+		return -ENOENT;
+	hostif = intf->altsetting;
+	intfd = get_iface_desc(hostif);
+	/*
+	 * The various MidiSport devices have more or less random endpoint
+	 * numbers, so we have to identify the endpoints by their index in
+	 * the descriptor array, like the driver for that other OS does.
+	 *
+	 * There is one interrupt input endpoint for all input ports, one
+	 * bulk output endpoint for even-numbered ports, and one for odd-
+	 * numbered ports.  Both bulk output endpoints have corresponding
+	 * input bulk endpoints (at indices 1 and 3) which aren't used.
+	 */
+	if (intfd->bNumEndpoints < (endpoint->out_cables > 0x0001 ? 5 : 3)) {
+		snd_printdd(KERN_ERR "not enough endpoints\n");
+		return -ENOENT;
+	}
+
+	epd = get_endpoint(hostif, 0);
+	if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN ||
+	    (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
+		snd_printdd(KERN_ERR "endpoint[0] isn't interrupt\n");
+		return -ENXIO;
+	}
+	epd = get_endpoint(hostif, 2);
+	if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT ||
+	    (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) {
+		snd_printdd(KERN_ERR "endpoint[2] isn't bulk output\n");
+		return -ENXIO;
+	}
+	if (endpoint->out_cables > 0x0001) {
+		epd = get_endpoint(hostif, 4);
+		if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT ||
+		    (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) {
+			snd_printdd(KERN_ERR "endpoint[4] isn't bulk output\n");
+			return -ENXIO;
+		}
+	}
+
+	ep_info.out_ep = get_endpoint(hostif, 2)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+	ep_info.out_cables = endpoint->out_cables & 0x5555;
+	err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
+	if (err < 0)
+		return err;
+
+	ep_info.in_ep = get_endpoint(hostif, 0)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+	ep_info.in_interval = get_endpoint(hostif, 0)->bInterval;
+	ep_info.in_cables = endpoint->in_cables;
+	err = snd_usbmidi_in_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
+	if (err < 0)
+		return err;
+
+	if (endpoint->out_cables > 0x0001) {
+		ep_info.out_ep = get_endpoint(hostif, 4)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+		ep_info.out_cables = endpoint->out_cables & 0xaaaa;
+		err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[1]);
+		if (err < 0)
+			return err;
+	}
+
+	for (cable = 0; cable < 0x10; ++cable) {
+		if (endpoint->out_cables & (1 << cable))
+			snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_OUTPUT, cable,
+						   &umidi->endpoints[cable & 1].out->ports[cable].substream);
+		if (endpoint->in_cables & (1 << cable))
+			snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_INPUT, cable,
+						   &umidi->endpoints[0].in->ports[cable].substream);
+	}
+	return 0;
+}
+
+static int snd_usbmidi_create_rawmidi(snd_usb_midi_t* umidi,
+				      int out_ports, int in_ports)
+{
+	snd_rawmidi_t* rmidi;
+	int err;
+
+	err = snd_rawmidi_new(umidi->chip->card, "USB MIDI",
+			      umidi->chip->next_midi_device++,
+			      out_ports, in_ports, &rmidi);
+	if (err < 0)
+		return err;
+	strcpy(rmidi->name, umidi->chip->card->shortname);
+	rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
+			    SNDRV_RAWMIDI_INFO_INPUT |
+			    SNDRV_RAWMIDI_INFO_DUPLEX;
+	rmidi->private_data = umidi;
+	rmidi->private_free = snd_usbmidi_rawmidi_free;
+	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_usbmidi_output_ops);
+	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_usbmidi_input_ops);
+
+	umidi->rmidi = rmidi;
+	return 0;
+}
+
+/*
+ * Temporarily stop input.
+ */
+void snd_usbmidi_input_stop(struct list_head* p)
+{
+	snd_usb_midi_t* umidi;
+	int i;
+
+	umidi = list_entry(p, snd_usb_midi_t, list);
+	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
+		snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i];
+		if (ep->in)
+			usb_kill_urb(ep->in->urb);
+	}
+}
+
+static void snd_usbmidi_input_start_ep(snd_usb_midi_in_endpoint_t* ep)
+{
+	if (ep) {
+		struct urb* urb = ep->urb;
+		urb->dev = ep->umidi->chip->dev;
+		snd_usbmidi_submit_urb(urb, GFP_KERNEL);
+	}
+}
+
+/*
+ * Resume input after a call to snd_usbmidi_input_stop().
+ */
+void snd_usbmidi_input_start(struct list_head* p)
+{
+	snd_usb_midi_t* umidi;
+	int i;
+
+	umidi = list_entry(p, snd_usb_midi_t, list);
+	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
+		snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
+}
+
+/*
+ * Creates and registers everything needed for a MIDI streaming interface.
+ */
+int snd_usb_create_midi_interface(snd_usb_audio_t* chip,
+				  struct usb_interface* iface,
+				  const snd_usb_audio_quirk_t* quirk)
+{
+	snd_usb_midi_t* umidi;
+	snd_usb_midi_endpoint_info_t endpoints[MIDI_MAX_ENDPOINTS];
+	int out_ports, in_ports;
+	int i, err;
+
+	umidi = kcalloc(1, sizeof(*umidi), GFP_KERNEL);
+	if (!umidi)
+		return -ENOMEM;
+	umidi->chip = chip;
+	umidi->iface = iface;
+	umidi->quirk = quirk;
+	umidi->usb_protocol_ops = &snd_usbmidi_standard_ops;
+
+	/* detect the endpoint(s) to use */
+	memset(endpoints, 0, sizeof(endpoints));
+	if (!quirk) {
+		err = snd_usbmidi_get_ms_info(umidi, endpoints);
+	} else {
+		switch (quirk->type) {
+		case QUIRK_MIDI_FIXED_ENDPOINT:
+			memcpy(&endpoints[0], quirk->data,
+			       sizeof(snd_usb_midi_endpoint_info_t));
+			err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
+			break;
+		case QUIRK_MIDI_YAMAHA:
+			err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]);
+			break;
+		case QUIRK_MIDI_MIDIMAN:
+			umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops;
+			memcpy(&endpoints[0], quirk->data,
+			       sizeof(snd_usb_midi_endpoint_info_t));
+			err = 0;
+			break;
+		case QUIRK_MIDI_NOVATION:
+			umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
+			err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+			break;
+		case QUIRK_MIDI_MOTU:
+			umidi->usb_protocol_ops = &snd_usbmidi_motu_ops;
+			err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+			break;
+		case QUIRK_MIDI_EMAGIC:
+			umidi->usb_protocol_ops = &snd_usbmidi_emagic_ops;
+			memcpy(&endpoints[0], quirk->data,
+			       sizeof(snd_usb_midi_endpoint_info_t));
+			err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
+			break;
+		default:
+			snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
+			err = -ENXIO;
+			break;
+		}
+	}
+	if (err < 0) {
+		kfree(umidi);
+		return err;
+	}
+
+	/* create rawmidi device */
+	out_ports = 0;
+	in_ports = 0;
+	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
+		out_ports += snd_usbmidi_count_bits(endpoints[i].out_cables);
+		in_ports += snd_usbmidi_count_bits(endpoints[i].in_cables);
+	}
+	err = snd_usbmidi_create_rawmidi(umidi, out_ports, in_ports);
+	if (err < 0) {
+		kfree(umidi);
+		return err;
+	}
+
+	/* create endpoint/port structures */
+	if (quirk && quirk->type == QUIRK_MIDI_MIDIMAN)
+		err = snd_usbmidi_create_endpoints_midiman(umidi, &endpoints[0]);
+	else
+		err = snd_usbmidi_create_endpoints(umidi, endpoints);
+	if (err < 0) {
+		snd_usbmidi_free(umidi);
+		return err;
+	}
+
+	list_add(&umidi->list, &umidi->chip->midi_list);
+
+	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
+		snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
+	return 0;
+}
+
+EXPORT_SYMBOL(snd_usb_create_midi_interface);
+EXPORT_SYMBOL(snd_usbmidi_input_stop);
+EXPORT_SYMBOL(snd_usbmidi_input_start);
+EXPORT_SYMBOL(snd_usbmidi_disconnect);
