Index: acore/seq/Makefile
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/acore/seq/Makefile,v
retrieving revision 1.2
diff -u -r1.2 Makefile
--- acore/seq/Makefile  3 Jul 2002 08:29:29 -0000       1.2
+++ acore/seq/Makefile  26 Aug 2002 13:54:22 -0000
@@ -3,7 +3,9 @@
 include $(TOPDIR)/toplevel.config
 include $(TOPDIR)/Makefile.conf
 
-obj-$(CONFIG_SND_USB_MIDI) += snd-seq-virmidi.o snd-seq.o snd-seq-device.o 
snd-seq-midi-event.o
+ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
+obj-$(CONFIG_SND_USB_AUDIO) += snd-seq-virmidi.o snd-seq.o snd-seq-device.o 
+snd-seq-midi-event.o
+endif
 
 TOPDIR = $(MAINSRCDIR)
 include $(TOPDIR)/alsa-kernel/core/seq/Makefile




Index: include/sndmagic.h
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/include/sndmagic.h,v
retrieving revision 1.10
diff -u -r1.10 sndmagic.h
--- include/sndmagic.h  16 Aug 2002 11:12:45 -0000      1.10
+++ include/sndmagic.h  26 Aug 2002 13:59:02 -0000
@@ -140,9 +140,9 @@
 #define snd_usb_audio_t_magic                  0xa15a3e01
 #define usb_mixer_elem_info_t_magic            0xa15a3e02
 #define snd_usb_stream_t_magic                 0xa15a3e03
-#define usbmidi_t_magic                                0xa15a3f01
-#define usbmidi_out_endpoint_t_magic           0xa15a3f02
-#define usbmidi_in_endpoint_t_magic            0xa15a3f03
+#define snd_usb_midi_t_magic                   0xa15a3f01
+#define snd_usb_midi_out_endpoint_t_magic      0xa15a3f02
+#define snd_usb_midi_in_endpoint_t_magic       0xa15a3f03
 
 
 #else
Index: scripts/Modules.dep
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/scripts/Modules.dep,v
retrieving revision 1.16
diff -u -r1.16 Modules.dep
--- scripts/Modules.dep 14 Aug 2002 17:21:36 -0000      1.16
+++ scripts/Modules.dep 26 Aug 2002 13:59:02 -0000
@@ -203,4 +203,4 @@
 
 %dir linux/sound/usb
 |snd-usb-audio snd-pcm
-|snd-usb-midi @if_sequencer snd-seq-device snd-seq-midi-event
+snd-usb-midi @if_sequencer snd-seq-device snd-seq-midi-event
Index: usb/Config.help
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/Config.help,v
retrieving revision 1.1
diff -u -r1.1 Config.help
--- usb/Config.help     14 Aug 2002 17:22:18 -0000      1.1
+++ usb/Config.help     26 Aug 2002 13:59:02 -0000
@@ -1,5 +1,2 @@
 CONFIG_SND_USB_AUDIO
   Say 'Y' or 'M' to include support for USB audio devices.
-
-CONFIG_SND_USB_MIDI
-  Say 'Y' or 'M' to include support for MIDI devices connected via USB.
Index: usb/Config.in
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/Config.in,v
retrieving revision 1.1
diff -u -r1.1 Config.in
--- usb/Config.in       14 Aug 2002 17:22:18 -0000      1.1
+++ usb/Config.in       26 Aug 2002 13:59:02 -0000
@@ -4,6 +4,5 @@
 comment 'ALSA USB devices'
 
 dep_tristate 'USB Audio driver' CONFIG_SND_USB_AUDIO $CONFIG_SND
-dep_tristate 'USB MIDI driver' CONFIG_SND_USB_MIDI $CONFIG_SND $CONFIG_SND_SEQUENCER
 
 endmenu
Index: usb/Makefile
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/Makefile,v
retrieving revision 1.1
diff -u -r1.1 Makefile
--- usb/Makefile        14 Aug 2002 17:22:18 -0000      1.1
+++ usb/Makefile        26 Aug 2002 13:59:02 -0000
@@ -3,10 +3,14 @@
 #
 
 snd-usb-audio-objs := usbaudio.o usbmixer.o
+ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
 snd-usb-midi-objs := usbmidi.o
+endif
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o
-obj-$(CONFIG_SND_USB_MIDI) += snd-usb-midi.o
+ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
+obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-midi.o
+endif
 
 include $(TOPDIR)/Rules.make
Index: usb/usbaudio.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbaudio.c,v
retrieving revision 1.2
diff -u -r1.2 usbaudio.c
--- usb/usbaudio.c      15 Aug 2002 12:13:10 -0000      1.2
+++ usb/usbaudio.c      26 Aug 2002 13:59:02 -0000
@@ -36,6 +36,7 @@
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/pcm.h>
+#include <sound/seq_device.h>
 #define SNDRV_GET_ID
 #include <sound/initval.h>
 
@@ -1234,6 +1235,7 @@
 static void usb_audio_disconnect(struct usb_device *dev, void *ptr);
 
 static struct usb_device_id usb_audio_ids [] = {
+#include "usbquirks.h"
     { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | 
USB_DEVICE_ID_MATCH_INT_SUBCLASS),
       .bInterfaceClass = USB_CLASS_AUDIO,
       .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL },
@@ -1716,11 +1718,14 @@
 
 
 /*
- * parse audio control descriptor and create pcm streams
+ * parse audio control descriptor and create pcm/midi streams
  */
 
-static int snd_usb_create_pcm(snd_usb_audio_t *chip, int ctrlif,
-                             unsigned char *buffer, int buflen)
+static int snd_usb_create_midi_interface(snd_usb_audio_t *chip, int ifnum,
+                                        const snd_usb_audio_quirk_t *quirk);
+
+static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif,
+                                 unsigned char *buffer, int buflen)
 {
        struct usb_device *dev = chip->dev;
        struct usb_config_descriptor *config;
@@ -1752,6 +1757,15 @@
                        continue;
                }
                iface = &config->interface[j];
+               if (iface->altsetting[0].bInterfaceClass == USB_CLASS_AUDIO &&
+                   iface->altsetting[0].bInterfaceSubClass == 
+USB_SUBCLASS_MIDI_STREAMING) {
+                       if (snd_usb_create_midi_interface(chip, j, NULL) < 0) {
+                               snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer 
+device\n", dev->devnum, ctrlif, j);
+                               continue;
+                       }
+                       usb_driver_claim_interface(&usb_audio_driver, iface, (void 
+*)-1);
+                       continue;
+               }
                if (iface->altsetting[0].bInterfaceClass != USB_CLASS_AUDIO ||
                    iface->altsetting[0].bInterfaceSubClass != 
USB_SUBCLASS_AUDIO_STREAMING) {
                        snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported 
interface %d\n", dev->devnum, ctrlif, j,
iface->altsetting[0].bInterfaceClass);
@@ -1808,6 +1822,37 @@
        return 0;
 }
 
+static int snd_usb_create_midi_interface(snd_usb_audio_t *chip, int ifnum,
+                                        const snd_usb_audio_quirk_t *quirk)
+{
+#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+       snd_seq_device_t *seq_device;
+       snd_usb_midi_t *umidi;
+       int err;
+
+       err = snd_seq_device_new(chip->card, chip->next_seq_device,
+                                SNDRV_SEQ_DEV_ID_USBMIDI,
+                                sizeof(snd_usb_midi_t), &seq_device);
+       if (err < 0)
+               return err;
+       chip->next_seq_device++;
+       strcpy(seq_device->name, chip->card->shortname);
+       umidi = (snd_usb_midi_t *)SNDRV_SEQ_DEVICE_ARGPTR(seq_device);
+       umidi->chip = chip;
+       umidi->ifnum = ifnum;
+       umidi->quirk = quirk;
+       umidi->seq_client = -1;
+#endif
+       return 0;
+}
+
+static inline int snd_usb_create_quirk(snd_usb_audio_t *chip, int ifnum,
+                                      const snd_usb_audio_quirk_t *quirk)
+{
+       /* in the future, there may be quirks for PCM devices */
+       return snd_usb_create_midi_interface(chip, ifnum, quirk);
+}
+
 
 /*
  * free the chip instance
@@ -1835,7 +1880,9 @@
 /*
  * create a chip instance and set its names.
  */
-static int snd_usb_audio_create(snd_card_t *card, struct usb_device *dev, 
snd_usb_audio_t **rchip)
+static int snd_usb_audio_create(snd_card_t *card, struct usb_device *dev,
+                               const snd_usb_audio_quirk_t *quirk,
+                               snd_usb_audio_t **rchip)
 {
        snd_usb_audio_t *chip;
        int err, len;
@@ -1858,18 +1905,50 @@
        }
 
        strcpy(card->driver, "USB-Audio");
-       strcpy(card->shortname, "USB Audio Driver");
+
+       /* retrieve the device string as shortname */
+       if (dev->descriptor.iProduct)
+               len = usb_string(dev, dev->descriptor.iProduct,
+                                card->shortname, sizeof(card->shortname));
+       else
+               len = 0;
+       if (len <= 0) {
+               if (quirk && quirk->product_name) {
+                       strncpy(card->shortname, quirk->product_name, 
+sizeof(card->shortname) - 1);
+                       card->shortname[sizeof(card->shortname) - 1] = '\0';
+               } else {
+                       sprintf(card->shortname, "USB Device %#04x:%#04x",
+                               dev->descriptor.idVendor, dev->descriptor.idProduct);
+               }
+       }
 
        /* retrieve the vendor and device strings as longname */
-       len = usb_string(dev, 1, card->longname, sizeof(card->longname) - 1);
-       if (len <= 0)
+       if (dev->descriptor.iManufacturer)
+               len = usb_string(dev, dev->descriptor.iManufacturer,
+                                card->longname, sizeof(card->longname) - 1);
+       else
                len = 0;
-       else {
+       if (len <= 0) {
+               if (quirk && quirk->vendor_name) {
+                       strncpy(card->longname, quirk->vendor_name, 
+sizeof(card->longname) - 2);
+                       card->longname[sizeof(card->longname) - 2] = '\0';
+                       len = strlen(card->longname);
+               } else {
+                       len = 0;
+               }
+       }
+       if (len > 0) {
                card->longname[len] = ' ';
                len++;
        }
-       card->longname[len] = 0;
-       usb_string(dev, 2, card->longname + len, sizeof(card->longname) - len);
+       card->longname[len] = '\0';
+       if ((!dev->descriptor.iProduct
+            || usb_string(dev, dev->descriptor.iProduct,
+                          card->longname + len, sizeof(card->longname) - len) <= 0)
+           && quirk && quirk->product_name) {
+               strncpy(card->longname + len, quirk->product_name, 
+sizeof(card->longname) - len - 1);
+               card->longname[sizeof(card->longname) - 1] = '\0';
+       }
 
        *rchip = chip;
        return 0;
@@ -1926,12 +2005,16 @@
                             const struct usb_device_id *id)
 {
        struct usb_config_descriptor *config = dev->actconfig;  
+       const snd_usb_audio_quirk_t *quirk = (const snd_usb_audio_quirk_t 
+*)id->driver_info;
        unsigned char *buffer;
        unsigned int index;
        int i, buflen;
        snd_card_t *card;
        snd_usb_audio_t *chip;
 
+       if (quirk && ifnum != quirk->ifnum)
+               return NULL;
+
        if (usb_set_configuration(dev, config->bConfigurationValue) < 0) {
                snd_printk(KERN_ERR "cannot set configuration (value 0x%x)\n", 
config->bConfigurationValue);
                return NULL;
@@ -1966,7 +2049,7 @@
                                        snd_printk(KERN_ERR "cannot create a card 
instance %d\n", i);
                                        goto __error;
                                }
-                               if (snd_usb_audio_create(card, dev, &chip) < 0) {
+                               if (snd_usb_audio_create(card, dev, quirk, &chip) < 0) 
+{
                                        snd_card_free(card);
                                        goto __error;
                                }
@@ -1980,10 +2063,15 @@
                }
        }
 
-       if (snd_usb_create_pcm(chip, ifnum, buffer, buflen) < 0)
-               goto __error;
-       if (snd_usb_create_mixer(chip, ifnum, buffer, buflen) < 0)
-               goto __error;
+       if (!quirk) {
+               if (snd_usb_create_streams(chip, ifnum, buffer, buflen) < 0)
+                       goto __error;
+               if (snd_usb_create_mixer(chip, ifnum, buffer, buflen) < 0)
+                       goto __error;
+       } else {
+               if (snd_usb_create_quirk(chip, ifnum, quirk) < 0)
+                       goto __error;
+       }
 
        /* we are allowed to call snd_card_register() many times */
        if (snd_card_register(chip->card) < 0) {
Index: usb/usbaudio.h
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbaudio.h,v
retrieving revision 1.1
diff -u -r1.1 usbaudio.h
--- usb/usbaudio.h      14 Aug 2002 17:22:18 -0000      1.1
+++ usb/usbaudio.h      26 Aug 2002 13:59:02 -0000
@@ -27,6 +27,7 @@
 
 #define USB_SUBCLASS_AUDIO_CONTROL     0x01
 #define USB_SUBCLASS_AUDIO_STREAMING   0x02
+#define USB_SUBCLASS_MIDI_STREAMING    0x03
 
 #define USB_DT_CS_DEVICE                0x21
 #define USB_DT_CS_CONFIG                0x22
@@ -56,6 +57,8 @@
 
 #define EP_GENERAL                     0x01
 
+#define MS_GENERAL                     0x01
+
 /* endpoint attributes */
 #define EP_ATTR_MASK                   0x0c
 #define EP_ATTR_ASYNC                  0x04
@@ -115,6 +118,11 @@
 #define USB_AUDIO_FORMAT_IEC1937_MPEG2_LAYER23_LS      0x2006
 
 
+/* maximum number of endpoints per interface */
+#define MIDI_MAX_ENDPOINTS 2
+
+#define SNDRV_SEQ_DEV_ID_USBMIDI "usb-midi"
+
 /*
  */
 
@@ -130,7 +138,52 @@
        struct list_head pcm_list;      /* list of pcm streams */
        int pcm_devs;
 
+#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+       int next_seq_device;
+#endif
 };  
+
+/*
+ * Information about devices with broken descriptors
+ */
+typedef struct snd_usb_audio_quirk snd_usb_audio_quirk_t;
+typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t;
+
+struct snd_usb_audio_quirk {
+       const char *vendor_name;
+       const char *product_name;
+       int ifnum;
+
+       /* MIDI specific */
+       struct snd_usb_midi_endpoint_info {
+               int16_t epnum;          /* ep number, -1 autodetect */
+               uint16_t out_cables;    /* bitmask */
+               uint16_t in_cables;     /* bitmask */
+       } endpoints[MIDI_MAX_ENDPOINTS];
+};
+
+/*
+ * USB MIDI sequencer device data
+ */
+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;
+
+struct snd_usb_midi {
+       /* filled by usbaudio.c */
+       snd_usb_audio_t *chip;
+       int ifnum;
+       const snd_usb_audio_quirk_t *quirk;
+
+       /* used internally in usbmidi.c */
+       int seq_client;
+       struct snd_usb_midi_endpoint {
+               snd_usb_midi_out_endpoint_t *out;
+               snd_usb_midi_in_endpoint_t *in;
+               snd_rawmidi_t *rmidi[0x10];
+       } endpoints[MIDI_MAX_ENDPOINTS];
+};
 
 
 /*
Index: usb/usbmidi.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbmidi.c,v
retrieving revision 1.3
diff -u -r1.3 usbmidi.c
--- usb/usbmidi.c       19 Aug 2002 16:19:03 -0000      1.3
+++ usb/usbmidi.c       26 Aug 2002 13:59:02 -0000
@@ -40,7 +40,6 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/usb.h>
-#include <asm/semaphore.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/asequencer.h>
@@ -48,59 +47,13 @@
 #include <sound/seq_kernel.h>
 #include <sound/seq_virmidi.h>
 #include <sound/seq_midi_event.h>
-#define SNDRV_GET_ID
 #include <sound/initval.h>
+#include "usbaudio.h"
 
 MODULE_AUTHOR("Clemens Ladisch <[EMAIL PROTECTED]>");
 MODULE_DESCRIPTION("USB MIDI");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_CLASSES("{sound}");
-MODULE_DEVICES("{{Generic,USB MIDI},"
-               "{Roland/EDIROL,PC-300},"
-               "{Roland/EDIROL,SC-8820},"
-               "{Roland/EDIROL,SC-8850},"
-               "{Roland/EDIROL,SC-D70},"
-               "{Roland/EDIROL,SD-20},"
-               "{Roland/EDIROL,SD-80},"
-               "{Roland/EDIROL,SD-90},"
-               "{Roland/EDIROL,SK-500},"
-               "{Roland/EDIROL,U-8},"
-               "{Roland/EDIROL,UA-100(G)},"
-               "{Roland/EDIROL,UA-700},"
-               "{Roland/EDIROL,UM-1(S)},"
-               "{Roland/EDIROL,UM-2(E)},"
-               "{Roland/EDIROL,UM-4},"
-               "{Roland/EDIROL,UM-550},"
-               "{Roland/EDIROL,UM-880},"
-               "{Roland/EDIROL,XV-5050},"
-               "{Yamaha,MU1000},"
-               "{Yamaha,UX256}}");
-
-static int snd_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
-static char* snd_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
-static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int snd_vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Vendor id of 
this card */
-static int snd_pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Product id of 
this card */
-static int snd_int_transfer[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* Use 
interrupt transfers for this card */
-
-MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
-MODULE_PARM_DESC(snd_index, "Index value for USB MIDI.");
-MODULE_PARM_SYNTAX(snd_index, SNDRV_INDEX_DESC);
-MODULE_PARM(snd_id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
-MODULE_PARM_DESC(snd_id, "ID string for USB MIDI.");
-MODULE_PARM_SYNTAX(snd_id, SNDRV_ID_DESC);
-MODULE_PARM(snd_enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
-MODULE_PARM_DESC(snd_enable, "Enable USB MIDI.");
-MODULE_PARM_SYNTAX(snd_enable, SNDRV_ENABLE_DESC);
-MODULE_PARM(snd_vid, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
-MODULE_PARM_DESC(snd_vid, "USB Vendor ID for USB MIDI.");
-MODULE_PARM_SYNTAX(snd_vid, SNDRV_ENABLED ",allows:{{-1,0xffff}},base:16");
-MODULE_PARM(snd_pid, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
-MODULE_PARM_DESC(snd_pid, "USB Product ID for USB MIDI.");
-MODULE_PARM_SYNTAX(snd_pid, SNDRV_ENABLED ",allows:{{-1,0xffff}},base:16");
-MODULE_PARM(snd_int_transfer, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
-MODULE_PARM_DESC(snd_int_transfer, "Use interrupt transfers for USB MIDI input.");
-MODULE_PARM_SYNTAX(snd_int_transfer, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC 
",skill:advanced");
 
 /* size of the per-endpoint output buffer, must be a multiple of 4 */
 #define OUTPUT_BUFFER_SIZE 0x400
@@ -108,26 +61,6 @@
 /* max. size of incoming sysex messages */
 #define INPUT_BUFFER_SIZE 0x200
 
-#define MAX_ENDPOINTS 2
-
-#define SNDRV_SEQ_DEV_ID_USBMIDI "usb-midi"
-
-#ifndef USB_SUBCLASS_MIDISTREAMING
-#define USB_SUBCLASS_MIDISTREAMING 3
-#endif
-
-#ifndef USB_DT_CS_INTERFACE
-#define USB_DT_CS_INTERFACE (USB_TYPE_CLASS | USB_DT_INTERFACE)
-#define USB_DT_CS_ENDPOINT (USB_TYPE_CLASS | USB_DT_ENDPOINT)
-#endif
-
-#ifndef USB_DST_MS_HEADER
-#define USB_DST_MS_HEADER 0x01
-#define USB_DST_MS_GENERAL 0x01
-#define USB_DST_MS_HEADER_SIZE 7
-#define USB_DST_MS_GENERAL_SIZE 4
-#endif
-
 typedef struct usb_driver usb_driver_t;
 typedef struct usb_device usb_device_t;
 typedef struct usb_device_id usb_device_id_t;
@@ -153,47 +86,11 @@
        __u8  baAssocJackID[0];
 } __attribute__ ((packed));
 
-typedef struct usbmidi usbmidi_t;
-typedef struct usbmidi_device_info usbmidi_device_info_t;
-typedef struct usbmidi_endpoint_info usbmidi_endpoint_info_t;
-typedef struct usbmidi_endpoint usbmidi_endpoint_t;
-typedef struct usbmidi_out_endpoint usbmidi_out_endpoint_t;
 typedef struct usbmidi_out_port usbmidi_out_port_t;
-typedef struct usbmidi_in_endpoint usbmidi_in_endpoint_t;
 typedef struct usbmidi_in_port usbmidi_in_port_t;
 
-/*
- * Describes the capabilities of a USB MIDI device.
- * This structure is filled after parsing the USB descriptors,
- * or is supplied explicitly for broken devices.
- */
-struct usbmidi_device_info {
-       char vendor[32];                /* vendor name */
-       char product[32];               /* device name */
-       int16_t ifnum;                  /* interface number */
-       struct usbmidi_endpoint_info {
-               int16_t epnum;          /* endpoint number,
-                                          -1: autodetect (first ep only) */
-               uint16_t out_cables;    /* bitmask */
-               uint16_t in_cables;     /* bitmask */
-       } endpoints[MAX_ENDPOINTS];
-};
-
-struct usbmidi {
-       snd_card_t* card;
-       usb_device_t* usb_device;
-       int dev;
-       int seq_client;
-       usbmidi_device_info_t device_info;
-       struct usbmidi_endpoint {
-               usbmidi_out_endpoint_t* out;
-               usbmidi_in_endpoint_t* in;
-               snd_rawmidi_t* rmidi[0x10];
-       } endpoints[MAX_ENDPOINTS];
-};
-
-struct usbmidi_out_endpoint {
-       usbmidi_t* umidi;
+struct snd_usb_midi_out_endpoint {
+       snd_usb_midi_t* umidi;
        struct urb* urb;
        int max_transfer;               /* size of urb buffer */
        struct tasklet_struct tasklet;
@@ -204,16 +101,16 @@
        spinlock_t buffer_lock;
 
        struct usbmidi_out_port {
-               usbmidi_out_endpoint_t* ep;
+               snd_usb_midi_out_endpoint_t* ep;
                uint8_t cable;          /* cable number << 4 */
                uint8_t sysex_len;
                uint8_t sysex[2];
        } ports[0x10];
 };
 
-struct usbmidi_in_endpoint {
-       usbmidi_t* umidi;
-       usbmidi_endpoint_t* ep;
+struct snd_usb_midi_in_endpoint {
+       snd_usb_midi_t* umidi;
+       snd_usb_midi_endpoint_t* ep;
        struct urb* urb;
        struct usbmidi_in_port {
                int seq_port;
@@ -221,10 +118,7 @@
        } ports[0x10];
 };
 
-static int snd_usbmidi_card_used[SNDRV_CARDS];
-static DECLARE_MUTEX(snd_usbmidi_open_mutex);
-
-static void snd_usbmidi_do_output(usbmidi_out_endpoint_t* ep);
+static void snd_usbmidi_do_output(snd_usb_midi_out_endpoint_t* ep);
 
 /*
  * Submits the URB, with error handling.
@@ -255,7 +149,7 @@
 /*
  * Converts a USB MIDI packet into an ALSA sequencer event.
  */
-static void snd_usbmidi_input_packet(usbmidi_in_endpoint_t* ep,
+static void snd_usbmidi_input_packet(snd_usb_midi_in_endpoint_t* ep,
                                     uint8_t packet[4])
 {
        static const uint8_t cin_length[] = {
@@ -285,7 +179,7 @@
  */
 static void snd_usbmidi_in_urb_complete(struct urb* urb)
 {
-       usbmidi_in_endpoint_t* ep = snd_magic_cast(usbmidi_in_endpoint_t, 
urb->context, return);
+       snd_usb_midi_in_endpoint_t* ep = snd_magic_cast(snd_usb_midi_in_endpoint_t, 
+urb->context, return);
 
        if (urb->status == 0) {
                uint8_t* buffer = (uint8_t*)ep->urb->transfer_buffer;
@@ -300,14 +194,14 @@
        }
 
        if (!usb_pipeint(urb->pipe)) {
-               urb->dev = ep->umidi->usb_device;
+               urb->dev = ep->umidi->chip->dev;
                snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
        }
 }
 
 static void snd_usbmidi_out_urb_complete(struct urb* urb)
 {
-       usbmidi_out_endpoint_t* ep = snd_magic_cast(usbmidi_out_endpoint_t, 
urb->context, return);
+       snd_usb_midi_out_endpoint_t* ep = snd_magic_cast(snd_usb_midi_out_endpoint_t, 
+urb->context, return);
        unsigned long flags;
 
        if (urb->status < 0) {
@@ -324,7 +218,7 @@
  * (after the reception of one or more sequencer events, or after completion
  * of the previous transfer). ep->buffer_lock must be held.
  */
-static void snd_usbmidi_do_output(usbmidi_out_endpoint_t* ep)
+static void snd_usbmidi_do_output(snd_usb_midi_out_endpoint_t* ep)
 {
        int len;
        uint8_t* buffer;
@@ -361,14 +255,14 @@
        }
 
        if (len > 0) {
-               ep->urb->dev = ep->umidi->usb_device;
+               ep->urb->dev = ep->umidi->chip->dev;
                snd_usbmidi_submit_urb(ep->urb, GFP_ATOMIC);
        }
 }
 
 static void snd_usbmidi_out_tasklet(unsigned long data)
 {
-       usbmidi_out_endpoint_t* ep = snd_magic_cast(usbmidi_out_endpoint_t, 
(void*)data, return);
+       snd_usb_midi_out_endpoint_t* ep = snd_magic_cast(snd_usb_midi_out_endpoint_t, 
+(void*)data, return);
        unsigned long flags;
        
        spin_lock_irqsave(&ep->buffer_lock, flags);
@@ -382,7 +276,7 @@
 static void output_packet(usbmidi_out_port_t* port,
                          uint8_t p0, uint8_t p1, uint8_t p2, uint8_t p3)
 {
-       usbmidi_out_endpoint_t* ep = port->ep;
+       snd_usb_midi_out_endpoint_t* ep = port->ep;
        unsigned long flags;
 
        spin_lock_irqsave(&ep->buffer_lock, flags);
@@ -568,7 +462,7 @@
  * Frees an input endpoint.
  * May be called when ep hasn't been initialized completely.
  */
-static void snd_usbmidi_in_endpoint_delete(usbmidi_in_endpoint_t* ep)
+static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep)
 {
        int i;
 
@@ -586,53 +480,54 @@
 }
 
 /*
- * Searches for an alternate setting in which the endpoint uses interrupt
+ * For Roland devices, use the alternate setting which uses interrupt
  * transfers for input.
  */
-static int snd_usbmidi_get_int_ep(usbmidi_t* umidi, uint8_t epnum,
-                                 usb_endpoint_descriptor_t** descriptor)
+static usb_endpoint_descriptor_t* snd_usbmidi_get_int_epd(snd_usb_midi_t* umidi,
+                                                         uint8_t epnum)
 {
        usb_interface_t* intf;
-       int i, j;
+       usb_interface_descriptor_t* intfd;
 
-       *descriptor = NULL;
-       intf = usb_ifnum_to_if(umidi->usb_device, umidi->device_info.ifnum);
-       if (!intf)
-               return -ENXIO;
-       for (i = 0; i < intf->num_altsetting; ++i) {
-               usb_interface_descriptor_t* intfd = &intf->altsetting[i];
-               for (j = 0; j < intfd->bNumEndpoints; ++j) {
-                       usb_endpoint_descriptor_t* epd = &intfd->endpoint[j];
-                       if ((epd->bEndpointAddress & (USB_ENDPOINT_NUMBER_MASK | 
USB_ENDPOINT_DIR_MASK)) == (epnum | USB_DIR_IN) &&
-                           (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == 
USB_ENDPOINT_XFER_INT) {
-                               usb_set_interface(umidi->usb_device,
-                                                 intfd->bInterfaceNumber,
-                                                 intfd->bAlternateSetting);
-                               *descriptor = &intfd->endpoint[j];
-                               return 0;
-                       }
-               }
-       }
-       return -ENXIO;
+       if (umidi->chip->dev->descriptor.idVendor != 0x0582)
+               return NULL;
+       intf = usb_ifnum_to_if(umidi->chip->dev, umidi->ifnum);
+       if (!intf || intf->num_altsetting != 2)
+               return NULL;
+
+       intfd = &intf->altsetting[0];
+       if (intfd->bNumEndpoints != 2 ||
+           (intfd->endpoint[0].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 
+USB_ENDPOINT_XFER_BULK ||
+           (intfd->endpoint[1].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 
+USB_ENDPOINT_XFER_BULK)
+               return NULL;
+
+       intfd = &intf->altsetting[1];
+       if (intfd->bNumEndpoints != 2 ||
+           (intfd->endpoint[0].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 
+USB_ENDPOINT_XFER_BULK ||
+           (intfd->endpoint[1].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 
+USB_ENDPOINT_XFER_INT)
+               return NULL;
+
+       usb_set_interface(umidi->chip->dev, intfd->bInterfaceNumber,
+                         intfd->bAlternateSetting);
+       return &intfd->endpoint[1];
 }
 
 /*
  * Creates an input endpoint, and initalizes input ports.
  * ALSA ports are created later.
  */
-static int snd_usbmidi_in_endpoint_create(usbmidi_t* umidi,
-                                         usbmidi_endpoint_info_t* ep_info,
-                                         usbmidi_endpoint_t* rep)
+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)
 {
-       usbmidi_in_endpoint_t* ep;
-       int do_int_transfer;
-       usb_endpoint_descriptor_t* epd;
+       snd_usb_midi_in_endpoint_t* ep;
+       usb_endpoint_descriptor_t* int_epd;
        void* buffer;
        unsigned int pipe;
        int length, i, err;
 
        rep->in = NULL;
-       ep = snd_magic_kcalloc(usbmidi_in_endpoint_t, 0, GFP_KERNEL);
+       ep = snd_magic_kcalloc(snd_usb_midi_in_endpoint_t, 0, GFP_KERNEL);
        if (!ep)
                return -ENOMEM;
        ep->umidi = umidi;
@@ -640,34 +535,28 @@
        for (i = 0; i < 0x10; ++i)
                ep->ports[i].seq_port = -1;
 
-       do_int_transfer = snd_int_transfer[umidi->dev];
-       if (do_int_transfer) {
-               if (snd_usbmidi_get_int_ep(umidi, ep_info->epnum, &epd) < 0) {
-                       printk(KERN_WARNING "snd-usb-midi: interrupt endpoint not 
found\n");
-                       do_int_transfer = 0;
-               }
-       }
+       int_epd = snd_usbmidi_get_int_epd(umidi, ep_info->epnum);
 
        ep->urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!ep->urb) {
                snd_usbmidi_in_endpoint_delete(ep);
                return -ENOMEM;
        }
-       if (do_int_transfer)
-               pipe = usb_rcvintpipe(umidi->usb_device, ep_info->epnum);
+       if (int_epd)
+               pipe = usb_rcvintpipe(umidi->chip->dev, ep_info->epnum);
        else
-               pipe = usb_rcvbulkpipe(umidi->usb_device, ep_info->epnum);
-       length = usb_maxpacket(umidi->usb_device, pipe, 0);
+               pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->epnum);
+       length = usb_maxpacket(umidi->chip->dev, pipe, 0);
        buffer = kmalloc(length, GFP_KERNEL);
        if (!buffer) {
                snd_usbmidi_in_endpoint_delete(ep);
                return -ENOMEM;
        }
-       if (do_int_transfer)
-               FILL_INT_URB(ep->urb, umidi->usb_device, pipe, buffer, length,
-                            snd_usbmidi_in_urb_complete, ep, epd->bInterval);
+       if (int_epd)
+               FILL_INT_URB(ep->urb, umidi->chip->dev, pipe, buffer, length,
+                            snd_usbmidi_in_urb_complete, ep, int_epd->bInterval);
        else
-               FILL_BULK_URB(ep->urb, umidi->usb_device, pipe, buffer, length,
+               FILL_BULK_URB(ep->urb, umidi->chip->dev, pipe, buffer, length,
                              snd_usbmidi_in_urb_complete, ep);
 
        for (i = 0; i < 0x10; ++i)
@@ -697,7 +586,7 @@
  * Frees an output endpoint.
  * May be called when ep hasn't been initialized completely.
  */
-static void snd_usbmidi_out_endpoint_delete(usbmidi_out_endpoint_t* ep)
+static void snd_usbmidi_out_endpoint_delete(snd_usb_midi_out_endpoint_t* ep)
 {
        if (ep->tasklet.func)
                tasklet_kill(&ep->tasklet);
@@ -715,17 +604,17 @@
  * Creates an output endpoint, and initializes output ports.
  * ALSA ports are created later.
  */
-static int snd_usbmidi_out_endpoint_create(usbmidi_t* umidi,
-                                          usbmidi_endpoint_info_t* ep_info,
-                                          usbmidi_endpoint_t* rep)
+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)
 {
-       usbmidi_out_endpoint_t* ep;
+       snd_usb_midi_out_endpoint_t* ep;
        int i;
        unsigned int pipe;
        void* buffer;
 
        rep->out = NULL;
-       ep = snd_magic_kcalloc(usbmidi_out_endpoint_t, 0, GFP_KERNEL);
+       ep = snd_magic_kcalloc(snd_usb_midi_out_endpoint_t, 0, GFP_KERNEL);
        if (!ep)
                return -ENOMEM;
        ep->umidi = umidi;
@@ -735,14 +624,14 @@
                snd_usbmidi_out_endpoint_delete(ep);
                return -ENOMEM;
        }
-       pipe = usb_sndbulkpipe(umidi->usb_device, ep_info->epnum);
-       ep->max_transfer = usb_maxpacket(umidi->usb_device, pipe, 1) & ~3;
+       pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->epnum);
+       ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1) & ~3;
        buffer = kmalloc(ep->max_transfer, GFP_KERNEL);
        if (!buffer) {
                snd_usbmidi_out_endpoint_delete(ep);
                return -ENOMEM;
        }
-       FILL_BULK_URB(ep->urb, umidi->usb_device, pipe, buffer,
+       FILL_BULK_URB(ep->urb, umidi->chip->dev, pipe, buffer,
                      ep->max_transfer, snd_usbmidi_out_urb_complete, ep);
 
        spin_lock_init(&ep->buffer_lock);
@@ -763,17 +652,17 @@
  */
 static int snd_usbmidi_seq_device_delete(snd_seq_device_t* seq_device)
 {
-       usbmidi_t* umidi;
+       snd_usb_midi_t* umidi;
        int i, j;
 
-       umidi = (usbmidi_t*)SNDRV_SEQ_DEVICE_ARGPTR(seq_device);
+       umidi = (snd_usb_midi_t*)SNDRV_SEQ_DEVICE_ARGPTR(seq_device);
 
        if (umidi->seq_client >= 0) {
                snd_seq_delete_kernel_client(umidi->seq_client);
                umidi->seq_client = -1;
        }
-       for (i = 0; i < MAX_ENDPOINTS; ++i) {
-               usbmidi_endpoint_t* ep = &umidi->endpoints[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);
                        ep->out = NULL;
@@ -784,7 +673,7 @@
                }
                for (j = 0; j < 0x10; ++j)
                        if (ep->rmidi[j]) {
-                               snd_device_free(umidi->card, ep->rmidi[j]);
+                               snd_device_free(umidi->chip->card, ep->rmidi[j]);
                                ep->rmidi[j] = NULL;
                        }
        }
@@ -796,10 +685,9 @@
  * the ALSA port for each input/output port pair in the endpoint.
  * *port_idx is the port number, which must be unique over all endpoints.
  */
-static int snd_usbmidi_create_endpoint_ports(usbmidi_t* umidi, int ep,
-                                            int* port_idx)
+static int snd_usbmidi_create_endpoint_ports(snd_usb_midi_t* umidi, int ep, int* 
+port_idx,
+                                            snd_usb_midi_endpoint_info_t* ep_info)
 {
-       usbmidi_endpoint_info_t* ep_info = &umidi->device_info.endpoints[ep];
        int c, err;
        int cap, type, port;
        int out, in;
@@ -830,8 +718,8 @@
                /* TODO: read type bits from element descriptor */
                type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC;
                /* TODO: read port name from jack descriptor */
-               sprintf(port_name, "%s Port %d",
-                       umidi->device_info.product, *port_idx);
+               snprintf(port_name, sizeof(port_name), "%s Port %d",
+                        umidi->chip->card->shortname, *port_idx);
                port = snd_seq_event_port_attach(umidi->seq_client,
                                                 &port_callback,
                                                 cap, type, port_name);
@@ -845,7 +733,7 @@
                if (*port_idx < SNDRV_MINOR_RAWMIDIS) {
                        snd_rawmidi_t *rmidi;
                        snd_virmidi_dev_t *rdev;
-                       err = snd_virmidi_new(umidi->card, *port_idx, &rmidi);
+                       err = snd_virmidi_new(umidi->chip->card, *port_idx, &rmidi);
                        if (err < 0)
                                return err;
                        rdev = snd_magic_cast(snd_virmidi_dev_t, rmidi->private_data, 
return -ENXIO);
@@ -853,9 +741,9 @@
                        rdev->seq_mode = SNDRV_VIRMIDI_SEQ_ATTACH;
                        rdev->client = umidi->seq_client;
                        rdev->port = port;
-                       err = snd_device_register(umidi->card, rmidi);
+                       err = snd_device_register(umidi->chip->card, rmidi);
                        if (err < 0) {
-                               snd_device_free(umidi->card, rmidi);
+                               snd_device_free(umidi->chip->card, rmidi);
                                return err;
                        }
                        umidi->endpoints[ep].rmidi[c] = rmidi;
@@ -866,219 +754,45 @@
 }
 
 /*
- * Create the endpoints and their ports.
+ * Creates the endpoints and their ports.
  */
-static int snd_usbmidi_create_endpoints(usbmidi_t* umidi)
+static int snd_usbmidi_create_endpoints(snd_usb_midi_t* umidi,
+                                       snd_usb_midi_endpoint_info_t* endpoints)
 {
        int i, err, port_idx = 0;
 
-       for (i = 0; i < MAX_ENDPOINTS; ++i) {
-               usbmidi_endpoint_info_t* ep_info = &umidi->device_info.endpoints[i];
-
-               if (!ep_info->epnum)
+       for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
+               if (!endpoints[i].epnum)
                        continue;
-               if (ep_info->out_cables) {
-                       err = snd_usbmidi_out_endpoint_create(umidi, ep_info,
+               if (endpoints[i].out_cables) {
+                       err = snd_usbmidi_out_endpoint_create(umidi, &endpoints[i],
                                                              &umidi->endpoints[i]);
                        if (err < 0)
                                return err;
                }
-               if (ep_info->in_cables) {
-                       err = snd_usbmidi_in_endpoint_create(umidi, ep_info,
+               if (endpoints[i].in_cables) {
+                       err = snd_usbmidi_in_endpoint_create(umidi, &endpoints[i],
                                                             &umidi->endpoints[i]);
                        if (err < 0)
                                return err;
                }
-               err = snd_usbmidi_create_endpoint_ports(umidi, i, &port_idx);
+               err = snd_usbmidi_create_endpoint_ports(umidi, i, &port_idx,
+                                                       &endpoints[i]);
                if (err < 0)
                        return err;
                printk(KERN_INFO "snd-usb-midi: endpoint %d: created %d output and %d 
input ports\n",
-                      ep_info->epnum,
-                      snd_usbmidi_count_bits(ep_info->out_cables),
-                      snd_usbmidi_count_bits(ep_info->in_cables));
+                      endpoints[i].epnum,
+                      snd_usbmidi_count_bits(endpoints[i].out_cables),
+                      snd_usbmidi_count_bits(endpoints[i].in_cables));
        }
        return 0;
 }
 
 /*
- * Initialize the sequencer device.
- */
-static int snd_usbmidi_seq_device_new(snd_seq_device_t* seq_device)
-{
-       usbmidi_t* umidi;
-       snd_seq_client_callback_t client_callback;
-       snd_seq_client_info_t client_info;
-       int i, err;
-
-       umidi = (usbmidi_t*)SNDRV_SEQ_DEVICE_ARGPTR(seq_device);
-
-       memset(&client_callback, 0, sizeof(client_callback));
-       client_callback.allow_output = 1;
-       client_callback.allow_input = 1;
-       umidi->seq_client = snd_seq_create_kernel_client(umidi->card, 0,
-                                                        &client_callback);
-       if (umidi->seq_client < 0)
-               return umidi->seq_client;
-
-       memset(&client_info, 0, sizeof(client_info));
-       client_info.client = umidi->seq_client;
-       client_info.type = KERNEL_CLIENT;
-       sprintf(client_info.name, "%s %s",
-               umidi->device_info.vendor, umidi->device_info.product);
-       snd_seq_kernel_client_ctl(umidi->seq_client,
-                                 SNDRV_SEQ_IOCTL_SET_CLIENT_INFO,
-                                 &client_info);
-
-       err = snd_usbmidi_create_endpoints(umidi);
-       if (err < 0) {
-               snd_usbmidi_seq_device_delete(seq_device);
-               return err;
-       }
-
-       for (i = 0; i < MAX_ENDPOINTS; ++i)
-               if (umidi->endpoints[i].in)
-                       snd_usbmidi_submit_urb(umidi->endpoints[i].in->urb,
-                                              GFP_KERNEL);
-       return 0;
-}
-
-static int snd_usbmidi_card_create(usb_device_t* usb_device,
-                                  usbmidi_device_info_t* device_info,
-                                  snd_card_t** rcard)
-{
-       snd_card_t* card;
-       snd_seq_device_t* seq_device;
-       usbmidi_t* umidi;
-       int dev, err;
-
-       if (rcard)
-               *rcard = NULL;
-
-       down(&snd_usbmidi_open_mutex);
-
-       for (dev = 0; dev < SNDRV_CARDS; ++dev) {
-               if (snd_enable[dev] && !snd_usbmidi_card_used[dev] &&
-                   (snd_vid[dev] == -1 || 
-                    snd_vid[dev] == usb_device->descriptor.idVendor) &&
-                   (snd_pid[dev] == -1 ||
-                    snd_pid[dev] == usb_device->descriptor.idProduct))
-                       break;
-       }
-       if (dev >= SNDRV_CARDS) {
-               up(&snd_usbmidi_open_mutex);
-               return -ENOENT;
-       }
-
-       card = snd_card_new(snd_index[dev], snd_id[dev], THIS_MODULE, 0);
-       if (!card) {
-               up(&snd_usbmidi_open_mutex);
-               return -ENOMEM;
-       }
-       strcpy(card->driver, "USB MIDI");
-       snprintf(card->shortname, sizeof(card->shortname), "%s %s",
-                device_info->vendor, device_info->product);
-       snprintf(card->longname, sizeof(card->longname), "%s %s at %03d/%03d if %d",
-                device_info->vendor, device_info->product,
-                usb_device->bus->busnum, usb_device->devnum,
-                device_info->ifnum);
-       card->private_data = (void*)dev;
-
-       err = snd_seq_device_new(card, 0, SNDRV_SEQ_DEV_ID_USBMIDI,
-                                sizeof(usbmidi_t), &seq_device);
-       if (err < 0) {
-               snd_card_free(card);
-               up(&snd_usbmidi_open_mutex);
-               return err;
-       }
-       strcpy(seq_device->name, card->shortname);
-       umidi = (usbmidi_t*)SNDRV_SEQ_DEVICE_ARGPTR(seq_device);
-       umidi->card = card;
-       umidi->usb_device = usb_device;
-       umidi->dev = dev;
-       umidi->seq_client = -1;
-       umidi->device_info = *device_info;
-
-       err = snd_card_register(card);
-       if (err < 0) {
-               snd_card_free(card);
-               up(&snd_usbmidi_open_mutex);
-               return err;
-       }
-       snd_usbmidi_card_used[dev] = 1;
-       up(&snd_usbmidi_open_mutex);
-       if (rcard)
-               *rcard = card;
-       return 0;
-}
-
-/*
- * If the first endpoint isn't specified, use the first endpoint in the
- * first alternate setting of the interface.
- */
-static int snd_usbmidi_detect_endpoint(usb_device_t* usb_device, 
-                                      usbmidi_device_info_t* device_info)
-{
-       usb_interface_t* intf;
-       usb_interface_descriptor_t* intfd;
-       usb_endpoint_descriptor_t* epd;
-
-       if (device_info->endpoints[0].epnum == -1) {
-               intf = usb_ifnum_to_if(usb_device, device_info->ifnum);
-               if (!intf || intf->num_altsetting < 1)
-                       return -ENOENT;
-               intfd = intf->altsetting;
-               if (intfd->bNumEndpoints < 1)
-                       return -ENOENT;
-               epd = intfd->endpoint;
-               device_info->endpoints[0].epnum = epd->bEndpointAddress & 
USB_ENDPOINT_NUMBER_MASK;
-       }
-       return 0;
-}
-
-/*
- * Searches for the alternate setting with the greatest number of bulk transfer
- * endpoints.
- */
-static usb_interface_descriptor_t* snd_usbmidi_get_altsetting(usb_device_t* 
usb_device,
-                                                             usb_interface_t* intf)
-{
-       int i, best = -1;
-       int best_out = 0, best_in = 0;
-       usb_interface_descriptor_t* intfd;
-
-       if (intf->num_altsetting == 1)
-               return &intf->altsetting[0];
-       for (i = 0; i < intf->num_altsetting; ++i) {
-               int out = 0, in = 0, j;
-               for (j = 0; j < intf->altsetting[i].bNumEndpoints; ++j) {
-                       usb_endpoint_descriptor_t* ep = 
&intf->altsetting[i].endpoint[j];
-                       if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == 
USB_ENDPOINT_XFER_BULK) {
-                               if (ep->bEndpointAddress & USB_DIR_IN)
-                                       ++in;
-                               else
-                                       ++out;
-                       }
-               }
-               if ((out >= best_out && in >= best_in) &&
-                   (out > best_out || in > best_in)) {
-                       best_out = out;
-                       best_in = in;
-                       best = i;
-               }
-       }
-       if (best < 0)
-               return NULL;
-       intfd = &intf->altsetting[best];
-       usb_set_interface(usb_device, intfd->bInterfaceNumber, 
intfd->bAlternateSetting);
-       return intfd;
-}
-
-/*
- * Returns MIDIStreaming device capabilities in device_info.
+ * Returns MIDIStreaming device capabilities.
  */
-static int snd_usbmidi_get_ms_info(usb_device_t* usb_device,
-                                  unsigned int ifnum,
-                                  usbmidi_device_info_t* device_info)
+static int snd_usbmidi_get_ms_info(snd_usb_midi_t* umidi,
+                                  snd_usb_midi_endpoint_info_t* endpoints)
 {
        usb_interface_t* intf;
        usb_interface_descriptor_t* intfd;
@@ -1087,34 +801,17 @@
        usb_ms_endpoint_descriptor_t* ms_ep;
        int i, epidx;
 
-       memset(device_info, 0, sizeof(*device_info));
+       memset(endpoints, 0, sizeof(*endpoints) * MIDI_MAX_ENDPOINTS);
 
-       if (usb_device->descriptor.iManufacturer == 0 ||
-           usb_string(usb_device, usb_device->descriptor.iManufacturer,
-                      device_info->vendor, sizeof(device_info->vendor)) < 0)
-               sprintf(device_info->vendor, "Unknown Vendor %x", 
usb_device->descriptor.idVendor);
-       if (usb_device->descriptor.iProduct == 0 ||
-           usb_string(usb_device, usb_device->descriptor.iProduct,
-                      device_info->product, sizeof(device_info->product)) < 0)
-               sprintf(device_info->product, "Unknown Device %x", 
usb_device->descriptor.idProduct);
-
-       intf = usb_ifnum_to_if(usb_device, ifnum);
+       intf = usb_ifnum_to_if(umidi->chip->dev, umidi->ifnum);
        if (!intf)
                return -ENXIO;
-       device_info->ifnum = ifnum;
-       printk(KERN_INFO "snd-usb-midi: using interface %d\n",
-              intf->altsetting[0].bInterfaceNumber);
-
-       intfd = snd_usbmidi_get_altsetting(usb_device, intf);
-       if (!intfd) {
-               printk(KERN_ERR "snd-usb-midi: could not determine altsetting\n");
-               return -ENXIO;
-       }
+       intfd = &intf->altsetting[0];
        ms_header = (usb_ms_header_descriptor_t*)intfd->extra;
-       if (intfd->extralen >= USB_DST_MS_HEADER_SIZE &&
-           ms_header->bLength >= USB_DST_MS_HEADER_SIZE &&
+       if (intfd->extralen >= 7 &&
+           ms_header->bLength >= 7 &&
            ms_header->bDescriptorType == USB_DT_CS_INTERFACE &&
-           ms_header->bDescriptorSubtype == USB_DST_MS_HEADER)
+           ms_header->bDescriptorSubtype == HEADER)
                printk(KERN_INFO "snd-usb-midi: MIDIStreaming version %02x.%02x\n",
                       ms_header->bcdMSC[1], ms_header->bcdMSC[0]);
        else
@@ -1126,242 +823,124 @@
                if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 
USB_ENDPOINT_XFER_BULK)
                        continue;
                ms_ep = (usb_ms_endpoint_descriptor_t*)ep->extra;
-               if (ep->extralen < USB_DST_MS_GENERAL_SIZE ||
-                   ms_ep->bLength < USB_DST_MS_GENERAL_SIZE ||
+               if (ep->extralen < 4 ||
+                   ms_ep->bLength < 4 ||
                    ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT ||
-                   ms_ep->bDescriptorSubtype != USB_DST_MS_GENERAL)
+                   ms_ep->bDescriptorSubtype != MS_GENERAL)
                        continue;
-               if (device_info->endpoints[epidx].epnum != 0 &&
-                   device_info->endpoints[epidx].epnum != (ep->bEndpointAddress & 
USB_ENDPOINT_NUMBER_MASK)) {
+               if (endpoints[epidx].epnum != 0 &&
+                   endpoints[epidx].epnum != (ep->bEndpointAddress & 
+USB_ENDPOINT_NUMBER_MASK)) {
                        ++epidx;
-                       if (epidx >= MAX_ENDPOINTS) {
+                       if (epidx >= MIDI_MAX_ENDPOINTS) {
                                printk(KERN_WARNING "snd-usb-midi: too many 
endpoints\n");
                                break;
                        }
                }
-               device_info->endpoints[epidx].epnum = ep->bEndpointAddress & 
USB_ENDPOINT_NUMBER_MASK;
+               endpoints[epidx].epnum = ep->bEndpointAddress & 
+USB_ENDPOINT_NUMBER_MASK;
                if (ep->bEndpointAddress & USB_DIR_IN) {
-                       device_info->endpoints[epidx].in_cables = (1 << 
ms_ep->bNumEmbMIDIJack) - 1;
+                       endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
                } else {
-                       device_info->endpoints[epidx].out_cables = (1 << 
ms_ep->bNumEmbMIDIJack) - 1;
+                       endpoints[epidx].out_cables = (1 << ms_ep->bNumEmbMIDIJack) - 
+1;
                }
                printk(KERN_INFO "snd-usb-midi: detected %d %s jack(s) on endpoint 
%d\n",
                       ms_ep->bNumEmbMIDIJack,
                       ep->bEndpointAddress & USB_DIR_IN ? "input" : "output",
-                      device_info->endpoints[epidx].epnum);
-       }
-       return 0;
-}
-
-/*
- * Returns device capabilities, either explicitly supplied or from the
- * class-specific descriptors.
- */
-static int snd_usbmidi_get_device_info(usb_device_t* usb_device,
-                                      unsigned int ifnum,
-                                      const usb_device_id_t* usb_device_id,
-                                      usbmidi_device_info_t* device_info)
-{
-       if (usb_device_id->driver_info) {
-               usbmidi_device_info_t* id_info = 
(usbmidi_device_info_t*)usb_device_id->driver_info;
-               if (ifnum != id_info->ifnum)
-                       return -ENXIO;
-               *device_info = *id_info;
-               if (snd_usbmidi_detect_endpoint(usb_device, device_info) < 0)
-                       return -ENXIO;
-       } else {
-               if (snd_usbmidi_get_ms_info(usb_device, ifnum, device_info) < 0)
-                       return -ENXIO;
+                      endpoints[epidx].epnum);
        }
        return 0;
 }
 
 /*
- * Probes for a supported device.
+ * If the first endpoint isn't specified, use the first endpoint in the
+ * first alternate setting of the interface.
  */
-static void* snd_usbmidi_usb_probe(usb_device_t* device,
-                                  unsigned int ifnum,
-                                  const usb_device_id_t* device_id)
+static int snd_usbmidi_detect_endpoint(snd_usb_midi_t* umidi, 
+                                      snd_usb_midi_endpoint_info_t* endpoint)
 {
-       usbmidi_device_info_t device_info;
-       snd_card_t* card = NULL;
-       int err;
+       usb_interface_t* intf;
+       usb_interface_descriptor_t* intfd;
+       usb_endpoint_descriptor_t* epd;
 
-       if (snd_usbmidi_get_device_info(device, ifnum, device_id,
-                                       &device_info) == 0) {
-               printk(KERN_INFO "snd-usb-midi: detected %s %s\n",
-                      device_info.vendor, device_info.product);
-               err = snd_usbmidi_card_create(device, &device_info, &card);
-               if (err < 0)
-                       snd_printk(KERN_ERR "cannot create card (error code %d)\n", 
err);
+       if (endpoint->epnum == -1) {
+               intf = usb_ifnum_to_if(umidi->chip->dev, umidi->ifnum);
+               if (!intf || intf->num_altsetting < 1)
+                       return -ENOENT;
+               intfd = intf->altsetting;
+               if (intfd->bNumEndpoints < 1)
+                       return -ENOENT;
+               epd = intfd->endpoint;
+               endpoint->epnum = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
        }
-       return card;
+       return 0;
 }
 
 /*
- * Frees the device.
+ * Initialize the sequencer device.
  */
-static void snd_usbmidi_usb_disconnect(usb_device_t* usb_device, void* ptr)
+static int snd_usbmidi_seq_device_new(snd_seq_device_t* seq_device)
 {
-       snd_card_t* card = (snd_card_t*)ptr;
-       int dev = (int)card->private_data;
+       snd_usb_midi_t* umidi;
+       usb_device_t* dev;
+       snd_seq_client_callback_t client_callback;
+       snd_seq_client_info_t client_info;
+       snd_usb_midi_endpoint_info_t endpoints[MIDI_MAX_ENDPOINTS];
+       int i, err;
 
-       snd_card_free(card);
-       down(&snd_usbmidi_open_mutex);
-       snd_usbmidi_card_used[dev] = 0;
-       up(&snd_usbmidi_open_mutex);
-}
+       umidi = (snd_usb_midi_t*)SNDRV_SEQ_DEVICE_ARGPTR(seq_device);
 
-/*
- * Information about devices with broken descriptors.
- */
-
-static usbmidi_device_info_t snd_usbmidi_yamaha_ux256_info = {
-       /* from NetBSD's umidi driver */
-       .vendor = "Yamaha", .product = "UX256",
-       .ifnum = 0,
-       .endpoints = {{ -1, 0xffff, 0x00ff }}
-};
-static usbmidi_device_info_t snd_usbmidi_yamaha_mu1000_info = {
-       /* from Nagano Daisuke's usb-midi driver */
-       .vendor = "Yamaha", .product = "MU1000",
-       .ifnum = 0,
-       .endpoints = {{ 1, 0x000f, 0x0001 }}
-};
-/*
- * There ain't no such thing as a standard-compliant Roland device.
- * Apparently, Roland decided not to risk to have wrong entries in the USB
- * descriptors. The consequence is that class-specific descriptors are
- * conspicuous by their absence.
- *
- * And now you may guess which company was responsible for writing the
- * USB Device Class Definition for MIDI Devices.
- */
-static usbmidi_device_info_t snd_usbmidi_roland_ua100_info = {
-       .vendor = "Roland", .product = "UA-100",
-       .ifnum = 2,
-       .endpoints = {{ -1, 0x0007, 0x0007 }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_um4_info = {
-       .vendor = "EDIROL", .product = "UM-4",
-       .ifnum = 2,
-       .endpoints = {{ -1, 0x000f, 0x000f }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_sc8850_info = {
-       .vendor = "Roland", .product = "SC-8850",
-       .ifnum = 2,
-       .endpoints = {{ -1, 0x003f, 0x003f }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_u8_info = {
-       .vendor = "Roland", .product = "U-8",
-       .ifnum = 2,
-       .endpoints = {{ -1, 0x0003, 0x0003 }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_um2_info = {
-       .vendor = "EDIROL", .product = "UM-2",
-       .ifnum = 2,
-       .endpoints = {{ -1, 0x0003, 0x0003 }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_sc8820_info = {
-       .vendor = "Roland", .product = "SC-8820",
-       .ifnum = 2,
-       .endpoints = {{ -1, 0x0013, 0x0013 }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_pc300_info = {
-       .vendor = "Roland", .product = "PC-300",
-       .ifnum = 2,
-       .endpoints = {{ -1, 0x0001, 0x0001 }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_um1_info = {
-       .vendor = "EDIROL", .product = "UM-1",
-       .ifnum = 2,
-       .endpoints = {{ -1, 0x0001, 0x0001 }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_sk500_info = {
-       .vendor = "Roland", .product = "SK-500",
-       .ifnum = 2,
-       .endpoints = {{ -1, 0x0013, 0x0013 }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_scd70_info = {
-       .vendor = "Roland", .product = "SC-D70",
-       .ifnum = 2,
-       .endpoints = {{ -1, 0x0007, 0x0007 }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_xv5050_info = {
-       .vendor = "Roland", .product = "XV-5050",
-       .ifnum = 0,
-       .endpoints = {{ -1, 0x0001, 0x0001 }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_um880_info = {
-       .vendor = "EDIROL", .product = "UM-880",
-       .ifnum = 0,
-       .endpoints = {{ -1, 0x01ff, 0x01ff }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_sd90_info = {
-       .vendor = "EDIROL", .product = "SD-90",
-       .ifnum = 2,
-       .endpoints = {{ -1, 0x000f, 0x000f }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_um550_info = {
-       .vendor = "EDIROL", .product = "UM-550",
-       .ifnum = 0,
-       .endpoints = {{ -1, 0x003f, 0x003f }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_sd20_info = {
-       .vendor = "EDIROL", .product = "SD-20",
-       .ifnum = 0,
-       .endpoints = {{ -1, 0x0003, 0x0007 }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_sd80_info = {
-       .vendor = "EDIROL", .product = "SD-80",
-       .ifnum = 0,
-       .endpoints = {{ -1, 0x000f, 0x000f }}
-};
-static usbmidi_device_info_t snd_usbmidi_roland_ua700_info = {
-       .vendor = "EDIROL", .product = "UA-700",
-       .ifnum = 3,
-       .endpoints = {{ -1, 0x0003, 0x0003 }}
-};
+       memset(&client_callback, 0, sizeof(client_callback));
+       client_callback.allow_output = 1;
+       client_callback.allow_input = 1;
+       umidi->seq_client = snd_seq_create_kernel_client(umidi->chip->card, 0,
+                                                        &client_callback);
+       if (umidi->seq_client < 0)
+               return umidi->seq_client;
 
-#define USBMIDI_NONCOMPLIANT_DEVICE(vid, pid, name) \
-               USB_DEVICE(vid, pid), \
-               driver_info: (unsigned long)&snd_usbmidi_##name##_info
-static usb_device_id_t snd_usbmidi_usb_id_table[] = {
-       { match_flags: USB_DEVICE_ID_MATCH_INT_CLASS |
-                      USB_DEVICE_ID_MATCH_INT_SUBCLASS,
-         bInterfaceClass: USB_CLASS_AUDIO,
-         bInterfaceSubClass: USB_SUBCLASS_MIDISTREAMING },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0499, 0x1000, yamaha_ux256) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0499, 0x1001, yamaha_mu1000) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x0000, roland_ua100) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x0002, roland_um4) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x0003, roland_sc8850) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x0004, roland_u8) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x0005, roland_um2) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x0007, roland_sc8820) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x0008, roland_pc300) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x0009, roland_um1) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x000b, roland_sk500) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x000c, roland_scd70) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x0012, roland_xv5050) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x0014, roland_um880) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x0016, roland_sd90) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x0023, roland_um550) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x0027, roland_sd20) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x0029, roland_sd80) },
-       { USBMIDI_NONCOMPLIANT_DEVICE(0x0582, 0x002b, roland_ua700) },
-       { /* terminator */ }
-};
+       memset(&client_info, 0, sizeof(client_info));
+       client_info.client = umidi->seq_client;
+       client_info.type = KERNEL_CLIENT;
+       dev = umidi->chip->dev;
+       if (dev->descriptor.iProduct)
+               err = usb_string(dev, dev->descriptor.iProduct,
+                                client_info.name, sizeof(client_info.name));
+       else
+               err = 0;
+       if (err <= 0) {
+               if (umidi->quirk && umidi->quirk->product_name) {
+                       strncpy(client_info.name, umidi->quirk->product_name,
+                               sizeof(client_info.name) - 1);
+                       client_info.name[sizeof(client_info.name) - 1] = '\0';
+               } else {
+                       sprintf(client_info.name, "USB Device %#04x:%#04x",
+                               dev->descriptor.idVendor, dev->descriptor.idProduct);
+               }
+       }
+       snd_seq_kernel_client_ctl(umidi->seq_client,
+                                 SNDRV_SEQ_IOCTL_SET_CLIENT_INFO,
+                                 &client_info);
 
-MODULE_DEVICE_TABLE(usb, snd_usbmidi_usb_id_table);
+       if (umidi->quirk) {
+               memcpy(endpoints, umidi->quirk->endpoints, sizeof(endpoints));
+               err = snd_usbmidi_detect_endpoint(umidi, &endpoints[0]);
+       } else {
+               err = snd_usbmidi_get_ms_info(umidi, endpoints);
+       }
+       if (err < 0) {
+               snd_usbmidi_seq_device_delete(seq_device);
+               return err;
+       }
+       err = snd_usbmidi_create_endpoints(umidi, endpoints);
+       if (err < 0) {
+               snd_usbmidi_seq_device_delete(seq_device);
+               return err;
+       }
 
-static usb_driver_t snd_usbmidi_usb_driver = {
-       .name = "snd-usb-midi",
-       .probe = snd_usbmidi_usb_probe,
-       .disconnect = snd_usbmidi_usb_disconnect,
-       .id_table = snd_usbmidi_usb_id_table,
-       .driver_list = LIST_HEAD_INIT(snd_usbmidi_usb_driver.driver_list)
-};
+       for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
+               if (umidi->endpoints[i].in)
+                       snd_usbmidi_submit_urb(umidi->endpoints[i].in->urb,
+                                              GFP_KERNEL);
+       return 0;
+}
 
 static int __init snd_usbmidi_module_init(void)
 {
@@ -1369,51 +948,15 @@
                snd_usbmidi_seq_device_new,
                snd_usbmidi_seq_device_delete
        };
-       int err;
 
-       err = snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_USBMIDI, &ops,
-                                            sizeof(usbmidi_t));
-       if (err < 0)
-               return err;
-       err = usb_register(&snd_usbmidi_usb_driver);
-       if (err < 0) {
-               snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_USBMIDI);
-               return err;
-       }
-       return 0;
+       return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_USBMIDI, &ops,
+                                             sizeof(snd_usb_midi_t));
 }
 
 static void __exit snd_usbmidi_module_exit(void)
 {
-       usb_deregister(&snd_usbmidi_usb_driver);
        snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_USBMIDI);
 }
 
 module_init(snd_usbmidi_module_init)
 module_exit(snd_usbmidi_module_exit)
-
-#ifndef MODULE
-
-/*
- * format is snd-usb-midi=snd_enable,snd_index,snd_id,
- *                        snd_vid,snd_pid,snd_int_transfer
- */
-static int __init snd_usbmidi_module_setup(char* str)
-{
-       static unsigned __initdata nr_dev = 0;
-
-       if (nr_dev >= SNDRV_CARDS)
-               return 0;
-       (void)(get_option(&str, &snd_enable[nr_dev]) == 2 &&
-              get_option(&str, &snd_index[nr_dev]) == 2 &&
-              get_id(&str, &snd_id[nr_dev]) == 2 &&
-              get_option(&str, &snd_vid[nr_dev]) == 2 &&
-              get_option(&str, &snd_pid[nr_dev]) == 2 &&
-              get_option(&str, &snd_int_transfer[nr_dev]) == 2);
-       ++nr_dev;
-       return 1;
-}
-
-__setup("snd-usb-midi=", snd_usbmidi_module_setup);
-
-#endif /* !MODULE */
diff -uP /dev/null usb/usbquirks.h
--- /dev/null   Thu Jan  1 01:00:00 1970
+++ usb/usbquirks.h     Mon Aug 26 15:48:15 2002
@@ -0,0 +1,337 @@
+/*
+ * ALSA USB Audio Driver
+ *
+ * Copyright (c) 2002 by Takashi Iwai <[EMAIL PROTECTED]>,
+ *                       Clemens Ladisch <[EMAIL PROTECTED]>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it 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 program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+/*
+ * The contents of this file are part of the driver's id_table.
+ *
+ * In a perfect world, this file would be empty.
+ */
+
+#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+
+{
+       /* from NetBSD's umidi driver */
+       USB_DEVICE(0x0499, 0x1000), /* Yamaha UX256 */
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .ifnum = 0,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0xffff,
+                               .in_cables  = 0x00ff
+                       }
+               }
+       }
+},
+{
+       /* from Nagano Daisuke's usb-midi driver */
+       USB_DEVICE(0x0499, 0x1001), /* Yamaha MU1000 */
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .ifnum = 0,
+               .endpoints = {
+                       {
+                               .epnum = 1,
+                               .out_cables = 0x000f,
+                               .in_cables  = 0x0001
+                       }
+               }
+       }
+},
+/*
+ * I don't know whether the following Yamaha devices need entries or not:
+ * 0x1002 MU2000   0x1008 UX96
+ * 0x1003 MU500    0x1009 UX16
+ * 0x1004 UW500    0x100e S08
+ * 0x1005 MOTIF6   0x100f CLP-150
+ * 0x1006 MOTIF7   0x1010 CLP-170
+ * 0x1007 MOTIF8
+ */
+
+/*
+ * Once upon a time people thought, "Wouldn't it be nice if there was a
+ * standard for USB MIDI devices, so that device drivers would not be forced
+ * to know about the quirks of specific devices?"  So Roland went ahead and
+ * wrote the USB Device Class Definition for MIDI Devices, and the USB-IF
+ * endorsed it, and now everybody designing USB MIDI devices does so in
+ * agreement with this standard (or at least tries to).
+ *
+ * And if you prefer a happy end, you can imagine that Roland devices set a
+ * good example. Instead of being completely fucked up due to the lack of
+ * class-specific descriptors.
+ */
+{
+       USB_DEVICE(0x0582, 0x0000),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Roland",
+               .product_name = "UA-100",
+               .ifnum = 2,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x0007,
+                               .in_cables  = 0x0007
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x0002),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "EDIROL",
+               .product_name = "UM-4",
+               .ifnum = 2,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x000f,
+                               .in_cables  = 0x000f
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x0003),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Roland",
+               .product_name = "SC-8850",
+               .ifnum = 2,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x003f,
+                               .in_cables  = 0x003f
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x0004),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Roland",
+               .product_name = "U-8",
+               .ifnum = 2,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x0003,
+                               .in_cables  = 0x0003
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x0005),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "EDIROL",
+               .product_name = "UM-2",
+               .ifnum = 2,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x0003,
+                               .in_cables  = 0x0003
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x0007),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Roland",
+               .product_name = "SC-8820",
+               .ifnum = 2,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x0013,
+                               .in_cables  = 0x0013
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x0008),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Roland",
+               .product_name = "PC-300",
+               .ifnum = 2,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x0001,
+                               .in_cables  = 0x0001
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x0009),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "EDIROL",
+               .product_name = "UM-1",
+               .ifnum = 2,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x0001,
+                               .in_cables  = 0x0001
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x000b),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Roland",
+               .product_name = "SK-500",
+               .ifnum = 2,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x0013,
+                               .in_cables  = 0x0013
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x000c),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Roland",
+               .product_name = "SC-D70",
+               .ifnum = 2,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x0007,
+                               .in_cables  = 0x0007
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x0012),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Roland",
+               .product_name = "XV-5050",
+               .ifnum = 0,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x0001,
+                               .in_cables  = 0x0001
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x0014),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "EDIROL",
+               .product_name = "UM-880",
+               .ifnum = 0,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x01ff,
+                               .in_cables  = 0x01ff
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x0016),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "EDIROL",
+               .product_name = "SD-90",
+               .ifnum = 2,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x000f,
+                               .in_cables  = 0x000f
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x0023),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "EDIROL",
+               .product_name = "UM-550",
+               .ifnum = 0,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x003f,
+                               .in_cables  = 0x003f
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x0027),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "EDIROL",
+               .product_name = "SD-20",
+               .ifnum = 0,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x0003,
+                               .in_cables  = 0x0007
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x0029),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "EDIROL",
+               .product_name = "SD-80",
+               .ifnum = 0,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x000f,
+                               .in_cables  = 0x000f
+                       }
+               }
+       }
+},
+{
+       USB_DEVICE(0x0582, 0x002b),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "EDIROL",
+               .product_name = "UA-700",
+               .ifnum = 3,
+               .endpoints = {
+                       {
+                               .epnum = -1,
+                               .out_cables = 0x0003,
+                               .in_cables  = 0x0003
+                       }
+               }
+       }
+},
+
+#endif /* CONFIG_SND_SEQUENCER(_MODULE) */


-------------------------------------------------------
This sf.net email is sponsored by: OSDN - Tired of that same old
cell phone?  Get a new here for FREE!
https://www.inphonic.com/r.asp?r=sourceforge1&refcode1=vs3390
_______________________________________________
Alsa-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-devel

Reply via email to