Update of /cvsroot/alsa/alsa-kernel/usb
In directory usw-pr-cvs1:/tmp/cvs-serv18001

Modified Files:
        usbaudio.c usbaudio.h usbmidi.c usbquirks.h 
Log Message:
added the support for Yamaha and Midiman devices.



Index: usbaudio.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbaudio.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- usbaudio.c  4 Oct 2002 12:27:41 -0000       1.15
+++ usbaudio.c  4 Oct 2002 13:18:24 -0000       1.16
@@ -2079,7 +2079,7 @@
        snd_card_t *card;
        snd_usb_audio_t *chip;
 
-       if (quirk && ifnum != quirk->ifnum)
+       if (quirk && quirk->ifnum != QUIRK_ANY_INTERFACE && ifnum != quirk->ifnum)
                goto __err_val;
 
        if (usb_set_configuration(dev, config->bConfigurationValue) < 0) {

Index: usbaudio.h
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbaudio.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- usbaudio.h  26 Aug 2002 16:05:43 -0000      1.2
+++ usbaudio.h  4 Oct 2002 13:18:24 -0000       1.3
@@ -58,6 +58,8 @@
 #define EP_GENERAL                     0x01
 
 #define MS_GENERAL                     0x01
+#define MIDI_IN_JACK                   0x02
+#define MIDI_OUT_JACK                  0x03
 
 /* endpoint attributes */
 #define EP_ATTR_MASK                   0x0c
@@ -146,21 +148,33 @@
 /*
  * Information about devices with broken descriptors
  */
+#define QUIRK_ANY_INTERFACE -1
+
+#define QUIRK_MIDI_FIXED_ENDPOINT      0
+#define QUIRK_MIDI_YAMAHA              1
+#define QUIRK_MIDI_MIDIMAN             2
+
 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;
+       int16_t ifnum;
+       int16_t type;
+       const void *data;
+};
 
-       /* 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];
+/* data for QUIRK_MIDI_FIXED_ENDPOINT */
+struct snd_usb_midi_endpoint_info {
+       int16_t epnum;          /* ep number, -1 autodetect */
+       uint16_t out_cables;    /* bitmask */
+       uint16_t in_cables;     /* bitmask */
 };
+
+/* for QUIRK_MIDI_YAMAHA, data is NULL */
+
+/* for QUIRK_MIDI_MIDIMAN, data is the number of ports */
 
 /*
  * USB MIDI sequencer device data

Index: usbmidi.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbmidi.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- usbmidi.c   3 Oct 2002 10:33:09 -0000       1.5
+++ usbmidi.c   4 Oct 2002 13:18:24 -0000       1.6
@@ -4,6 +4,10 @@
  * Copyright (c) 2002 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:
@@ -120,6 +124,10 @@
 
 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.
  */
@@ -152,9 +160,6 @@
 static void snd_usbmidi_input_packet(snd_usb_midi_in_endpoint_t* ep,
                                     uint8_t packet[4])
 {
-       static const uint8_t cin_length[] = {
-               0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1
-       };
        int cable = packet[0] >> 4;
        usbmidi_in_port_t* port = &ep->ports[cable];
        snd_seq_event_t ev;
@@ -163,7 +168,7 @@
                return;
        memset(&ev, 0, sizeof(ev));
        if (snd_midi_event_encode(port->midi_event, &packet[1],
-                                 cin_length[packet[0] & 0x0f], &ev) > 0
+                                 snd_usbmidi_cin_length[packet[0] & 0x0f], &ev) > 0
            && ev.type != SNDRV_SEQ_EVENT_NONE) {
                ev.source.port = port->seq_port;
                ev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
@@ -199,6 +204,38 @@
        }
 }
 
+/*
+ * Converts the data read from a Midiman device to standard USB MIDI packets.
+ */
+static void snd_usbmidi_in_midiman_complete(struct urb* urb)
+{
+       if (urb->status == 0) {
+               uint8_t* buffer = (uint8_t*)urb->transfer_buffer;
+               int i;
+
+               for (i = 0; i + 4 <= urb->actual_length; i += 4) {
+                       if (buffer[i + 3] != 0) {
+                               /*
+                                * snd_usbmidi_input_packet() doesn't check the
+                                * contents of the message, so we simply use
+                                * some random CIN with the desired length.
+                                */
+                               static const uint8_t cin[4] = {
+                                       0x0, 0xf, 0x2, 0x3
+                               };
+                               uint8_t ctl = buffer[i + 3];
+                               buffer[i + 3] = buffer[i + 2];
+                               buffer[i + 2] = buffer[i + 1];
+                               buffer[i + 1] = buffer[i + 0];
+                               buffer[i + 0] = (ctl & 0xf0) | cin[ctl & 3];
+                       } else {
+                               buffer[i + 0] = 0;
+                       }
+               }
+       }
+       snd_usbmidi_in_urb_complete(urb);
+}
+
 static void snd_usbmidi_out_urb_complete(struct urb* urb)
 {
        snd_usb_midi_out_endpoint_t* ep = snd_magic_cast(snd_usb_midi_out_endpoint_t, 
urb->context, return);
@@ -214,6 +251,23 @@
 }
 
 /*
+ * Converts standard USB MIDI packets to what Midman devices expect.
+ */
+static void snd_usbmidi_convert_to_midiman(struct urb* urb)
+{
+       uint8_t* buffer = (uint8_t*)urb->transfer_buffer;
+       int i;
+
+       for (i = 0; i + 4 <= urb->transfer_buffer_length; i += 4) {
+               uint8_t cin = buffer[i];
+               buffer[i + 0] = buffer[i + 1];
+               buffer[i + 1] = buffer[i + 2];
+               buffer[i + 2] = buffer[i + 3];
+               buffer[i + 3] = (cin & 0xf0) | snd_usbmidi_cin_length[cin & 0x0f];
+       }
+}
+
+/*
  * This is called when some data should be transferred to the device
  * (after the reception of one or more sequencer events, or after completion
  * of the previous transfer). ep->buffer_lock must be held.
@@ -255,6 +309,9 @@
        }
 
        if (len > 0) {
+               if (ep->umidi->quirk && ep->umidi->quirk->type == QUIRK_MIDI_MIDIMAN)
+                       snd_usbmidi_convert_to_midiman(ep->urb);
+
                ep->urb->dev = ep->umidi->chip->dev;
                snd_usbmidi_submit_urb(ep->urb, GFP_ATOMIC);
        }
@@ -528,6 +585,14 @@
        return &intfd->endpoint[1];
 }
 
+static usb_endpoint_descriptor_t* snd_usbmidi_get_midiman_int_epd(snd_usb_midi_t* 
+umidi)
+{
+       usb_interface_t* intf = local_usb_ifnum_to_if(umidi->chip->dev, umidi->ifnum);
+       if (!intf)
+               return NULL;
+       return &intf->altsetting[0].endpoint[0];
+}
+
 /*
  * Creates an input endpoint, and initalizes input ports.
  * ALSA ports are created later.
@@ -551,7 +616,10 @@
        for (i = 0; i < 0x10; ++i)
                ep->ports[i].seq_port = -1;
 
-       int_epd = snd_usbmidi_get_int_epd(umidi, ep_info->epnum);
+       if (umidi->quirk && umidi->quirk->type == QUIRK_MIDI_MIDIMAN)
+               int_epd = snd_usbmidi_get_midiman_int_epd(umidi);
+       else
+               int_epd = snd_usbmidi_get_int_epd(umidi, ep_info->epnum);
 
        ep->urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!ep->urb) {
@@ -697,72 +765,106 @@
 }
 
 /*
+ * Creates a sequencer port for an input/output cable pair.
+ */
+static int snd_usbmidi_create_port(snd_usb_midi_t* umidi,
+                                  snd_usb_midi_out_endpoint_t* out_ep,
+                                  snd_usb_midi_in_endpoint_t* in_ep,
+                                  int cable, int port_idx)
+{
+       int cap, type, port;
+       snd_seq_port_callback_t port_callback;
+       char port_name[48];
+
+       cap = 0;
+       memset(&port_callback, 0, sizeof(port_callback));
+       port_callback.owner = THIS_MODULE;
+       if (out_ep) {
+               port_callback.event_input = snd_usbmidi_event_input;
+               port_callback.private_data = &out_ep->ports[cable];
+               cap |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
+       }
+       if (in_ep) {
+               cap |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ;
+       }
+       if (out_ep && in_ep) {
+               cap |= SNDRV_SEQ_PORT_CAP_DUPLEX;
+       }
+       /* TODO: read type bits from element descriptor */
+       type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC;
+       /* TODO: read port name from jack descriptor */
+       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);
+       if (port < 0) {
+               snd_printk(KERN_ERR "cannot create port (error code %d)\n", port);
+               return port;
+       }
+       if (in_ep)
+               in_ep->ports[cable].seq_port = port;
+       return port;
+}
+
+/*
+ * Creates a virmidi port emulating rawmidi for the sequencer port.
+ */
+static int snd_usbmidi_create_virmidi(snd_usb_midi_t* umidi, int port,
+                                     int port_idx, snd_rawmidi_t** rrmidi)
+{
+       snd_rawmidi_t *rmidi;
+       snd_virmidi_dev_t *rdev;
+       int err;
+
+       *rrmidi = NULL;
+       err = snd_virmidi_new(umidi->chip->card, port_idx, &rmidi);
+       if (err < 0)
+               return err;
+       sprintf(rmidi->name, "%s MIDI %d", umidi->chip->card->shortname, port_idx);
+       rdev = snd_magic_cast(snd_virmidi_dev_t, rmidi->private_data, return -ENXIO);
+       rdev->seq_mode = SNDRV_VIRMIDI_SEQ_ATTACH;
+       rdev->client = umidi->seq_client;
+       rdev->port = port;
+       err = snd_device_register(umidi->chip->card, rmidi);
+       if (err < 0) {
+               snd_device_free(umidi->chip->card, rmidi);
+               return err;
+       }
+       *rrmidi = rmidi;
+       return 0;
+}
+
+/*
  * After input and output endpoints have been initialized, create
  * 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(snd_usb_midi_t* umidi, int ep, int* 
port_idx,
+static int snd_usbmidi_create_endpoint_ports(snd_usb_midi_t* umidi,
+                                            snd_usb_midi_endpoint_t* endpoint,
+                                            int* port_idx,
                                             snd_usb_midi_endpoint_info_t* ep_info)
 {
-       int c, err;
-       int cap, type, port;
-       int out, in;
-       snd_seq_port_callback_t port_callback;
-       char port_name[48];
+       int cable;
 
-       for (c = 0; c < 0x10; ++c) {
-               out = ep_info->out_cables & (1 << c);
-               in = ep_info->in_cables & (1 << c);
+       for (cable = 0; cable < 0x10; ++cable) {
+               int port, err;
+               int out = ep_info->out_cables & (1 << cable);
+               int in = ep_info->in_cables & (1 << cable);
                if (!(in || out))
                        continue;
-               cap = 0;
-               memset(&port_callback, 0, sizeof(port_callback));
-               port_callback.owner = THIS_MODULE;
-               if (out) {
-                       port_callback.event_input = snd_usbmidi_event_input;
-                       port_callback.private_data = 
&umidi->endpoints[ep].out->ports[c];
-                       cap |= SNDRV_SEQ_PORT_CAP_WRITE |
-                               SNDRV_SEQ_PORT_CAP_SUBS_WRITE;  
-               }
-               if (in) {
-                       cap |= SNDRV_SEQ_PORT_CAP_READ |
-                               SNDRV_SEQ_PORT_CAP_SUBS_READ;
-               }
-               if (out && in) {
-                       cap |= SNDRV_SEQ_PORT_CAP_DUPLEX;
-               }
-               /* TODO: read type bits from element descriptor */
-               type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC;
-               /* TODO: read port name from jack descriptor */
-               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);
-               if (port < 0) {
-                       snd_printk(KERN_ERR "cannot create port (error code %d)\n", 
port);
+
+               port = snd_usbmidi_create_port(umidi,
+                                              out ? endpoint->out : NULL,
+                                              in ? endpoint->in : NULL,
+                                              cable, *port_idx);
+               if (port < 0)
                        return port;
-               }
-               if (in)
-                       umidi->endpoints[ep].in->ports[c].seq_port = port;
 
                if (*port_idx < SNDRV_MINOR_RAWMIDIS) {
-                       snd_rawmidi_t *rmidi;
-                       snd_virmidi_dev_t *rdev;
-                       err = snd_virmidi_new(umidi->chip->card, *port_idx, &rmidi);
+                       err = snd_usbmidi_create_virmidi(umidi, port, *port_idx,
+                                                        &endpoint->rmidi[cable]);
                        if (err < 0)
                                return err;
-                       rdev = snd_magic_cast(snd_virmidi_dev_t, rmidi->private_data, 
return -ENXIO);
-                       strcpy(rmidi->name, port_name);
-                       rdev->seq_mode = SNDRV_VIRMIDI_SEQ_ATTACH;
-                       rdev->client = umidi->seq_client;
-                       rdev->port = port;
-                       err = snd_device_register(umidi->chip->card, rmidi);
-                       if (err < 0) {
-                               snd_device_free(umidi->chip->card, rmidi);
-                               return err;
-                       }
-                       umidi->endpoints[ep].rmidi[c] = rmidi;
                }
                ++*port_idx;
        }
@@ -792,8 +894,8 @@
                        if (err < 0)
                                return err;
                }
-               err = snd_usbmidi_create_endpoint_ports(umidi, i, &port_idx,
-                                                       &endpoints[i]);
+               err = snd_usbmidi_create_endpoint_ports(umidi, &umidi->endpoints[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",
@@ -817,8 +919,6 @@
        usb_ms_endpoint_descriptor_t* ms_ep;
        int i, epidx;
 
-       memset(endpoints, 0, sizeof(*endpoints) * MIDI_MAX_ENDPOINTS);
-
        intf = local_usb_ifnum_to_if(umidi->chip->dev, umidi->ifnum);
        if (!intf)
                return -ENXIO;
@@ -891,6 +991,120 @@
 }
 
 /*
+ * 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)
+{
+       usb_interface_t* intf;
+       usb_interface_descriptor_t* intfd;
+       uint8_t* cs_desc;
+
+       intf = local_usb_ifnum_to_if(umidi->chip->dev, umidi->ifnum);
+       if (!intf)
+               return -ENOENT;
+       intfd = intf->altsetting;
+       if (intfd->bNumEndpoints < 1)
+               return -ENOENT;
+
+       for (cs_desc = intfd->extra;
+            cs_desc < intfd->extra + intfd->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;
+
+       endpoint->epnum = -1;
+       return snd_usbmidi_detect_endpoint(umidi, endpoint);
+}
+
+/*
+ * Creates the endpoints and their ports for Midiman devices.
+ */
+static int snd_usbmidi_create_endpoints_midiman(snd_usb_midi_t* umidi, int ports)
+{
+       snd_usb_midi_endpoint_info_t ep_info;
+       usb_interface_t* intf;
+       usb_interface_descriptor_t* intfd;
+       usb_endpoint_descriptor_t* epd;
+       int cable, err;
+
+       intf = local_usb_ifnum_to_if(umidi->chip->dev, umidi->ifnum);
+       if (!intf)
+               return -ENOENT;
+       intfd = intf->altsetting;
+       if (intfd->bNumEndpoints < (ports > 1 ? 5 : 3)) {
+               snd_printdd(KERN_ERR "not enough endpoints\n");
+               return -ENOENT;
+       }
+
+       epd = &intfd->endpoint[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 = &intfd->endpoint[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 (ports > 1) {
+               epd = &intfd->endpoint[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.epnum = intfd->endpoint[2].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+       ep_info.out_cables = 0x5555 & ((1 << ports) - 1);
+       err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
+       if (err < 0)
+               return err;
+
+       ep_info.epnum = intfd->endpoint[0].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+       ep_info.in_cables = (1 << ports) - 1;
+       err = snd_usbmidi_in_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
+       if (err < 0)
+               return err;
+       umidi->endpoints[0].in->urb->complete = snd_usbmidi_in_midiman_complete;
+
+       if (ports > 1) {
+               ep_info.epnum = intfd->endpoint[4].bEndpointAddress & 
+USB_ENDPOINT_NUMBER_MASK;
+               ep_info.out_cables = 0xaaaa & ((1 << ports) - 1);
+               err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, 
+&umidi->endpoints[1]);
+               if (err < 0)
+                       return err;
+       }
+
+       for (cable = 0; cable < ports; ++cable) {
+               int port = snd_usbmidi_create_port(umidi,
+                                                  umidi->endpoints[cable & 1].out,
+                                                  umidi->endpoints[0].in,
+                                                  cable, cable);
+               if (port < 0)
+                       return port;
+
+               if (cable < SNDRV_MINOR_RAWMIDIS) {
+                       int err = snd_usbmidi_create_virmidi(umidi, port, cable,
+                                                            
+&umidi->endpoints[0].rmidi[cable]);
+                       if (err < 0)
+                               return err;
+               }
+       }
+       return 0;
+}
+
+/*
  * Initialize the sequencer device.
  */
 static int snd_usbmidi_seq_device_new(snd_seq_device_t* seq_device)
@@ -912,6 +1126,7 @@
        if (umidi->seq_client < 0)
                return umidi->seq_client;
 
+       /* set the client name */
        memset(&client_info, 0, sizeof(client_info));
        client_info.client = umidi->seq_client;
        client_info.type = KERNEL_CLIENT;
@@ -935,17 +1150,37 @@
                                  SNDRV_SEQ_IOCTL_SET_CLIENT_INFO,
                                  &client_info);
 
-       if (umidi->quirk) {
-               memcpy(endpoints, umidi->quirk->endpoints, sizeof(endpoints));
-               err = snd_usbmidi_detect_endpoint(umidi, &endpoints[0]);
-       } else {
+       /* detect the endpoint(s) to use */
+       memset(endpoints, 0, sizeof(endpoints));
+       if (!umidi->quirk) {
                err = snd_usbmidi_get_ms_info(umidi, endpoints);
+       } else {
+               switch (umidi->quirk->type) {
+               case QUIRK_MIDI_FIXED_ENDPOINT:
+                       memcpy(&endpoints[0], umidi->quirk->data,
+                              sizeof(snd_usb_midi_endpoint_info_t));
+                       err = snd_usbmidi_detect_endpoint(umidi, &endpoints[0]);
+                       break;
+               case QUIRK_MIDI_YAMAHA:
+                       err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]);
+                       break;
+               case QUIRK_MIDI_MIDIMAN:
+                       err = 0;
+                       break;
+               default:
+                       snd_printd(KERN_ERR "invalid quirk type %d\n", 
+umidi->quirk->type);
+                       err = -ENXIO;
+                       break;
+               }
        }
-       if (err < 0) {
-               snd_usbmidi_seq_device_delete(seq_device);
-               return err;
+
+       /* create ports */
+       if (err >= 0) {
+               if (umidi->quirk && umidi->quirk->type == QUIRK_MIDI_MIDIMAN)
+                       err = snd_usbmidi_create_endpoints_midiman(umidi, 
+(int)umidi->quirk->data);
+               else
+                       err = snd_usbmidi_create_endpoints(umidi, endpoints);
        }
-       err = snd_usbmidi_create_endpoints(umidi, endpoints);
        if (err < 0) {
                snd_usbmidi_seq_device_delete(seq_device);
                return err;

Index: usbquirks.h
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbquirks.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- usbquirks.h 26 Aug 2002 16:05:43 -0000      1.1
+++ usbquirks.h 4 Oct 2002 13:18:24 -0000       1.2
@@ -26,45 +26,143 @@
  * In a perfect world, this file would be empty.
  */
 
+#define USB_DEVICE_VENDOR_SPEC(vend, prod) \
+       .match_flags = USB_DEVICE_ID_MATCH_VENDOR | \
+                      USB_DEVICE_ID_MATCH_PRODUCT | \
+                      USB_DEVICE_ID_MATCH_INT_CLASS, \
+       .idVendor = vend, \
+       .idProduct = prod, \
+       .bInterfaceClass = USB_CLASS_VENDOR_SPEC
+
 #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
 
+/* Yamaha devices */
 {
-       /* from NetBSD's umidi driver */
-       USB_DEVICE(0x0499, 0x1000), /* Yamaha UX256 */
+       USB_DEVICE_VENDOR_SPEC(0x0499, 0x1000),
        .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
-               .ifnum = 0,
-               .endpoints = {
-                       {
-                               .epnum = -1,
-                               .out_cables = 0xffff,
-                               .in_cables  = 0x00ff
-                       }
-               }
+               .vendor_name = "Yamaha",
+               .product_name = "UX256",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_YAMAHA
        }
 },
 {
-       /* from Nagano Daisuke's usb-midi driver */
-       USB_DEVICE(0x0499, 0x1001), /* Yamaha MU1000 */
+       USB_DEVICE_VENDOR_SPEC(0x0499, 0x1001),
        .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
-               .ifnum = 0,
-               .endpoints = {
-                       {
-                               .epnum = 1,
-                               .out_cables = 0x000f,
-                               .in_cables  = 0x0001
-                       }
-               }
+               .vendor_name = "Yamaha",
+               .product_name = "MU1000",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_YAMAHA
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0499, 0x1002),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Yamaha",
+               .product_name = "MU2000",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_YAMAHA
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0499, 0x1003),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Yamaha",
+               .product_name = "MU500",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_YAMAHA
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0499, 0x1004),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Yamaha",
+               .product_name = "UW500",
+               .ifnum = 3,
+               .type = QUIRK_MIDI_YAMAHA
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0499, 0x1005),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Yamaha",
+               .product_name = "MOTIF6",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_YAMAHA
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0499, 0x1006),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Yamaha",
+               .product_name = "MOTIF7",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_YAMAHA
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0499, 0x1007),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Yamaha",
+               .product_name = "MOTIF8",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_YAMAHA
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0499, 0x1008),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Yamaha",
+               .product_name = "UX96",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_YAMAHA
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0499, 0x1009),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Yamaha",
+               .product_name = "UX16",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_YAMAHA
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0499, 0x100a),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Yamaha",
+               .product_name = "EOS BX",
+               .ifnum = 3,
+               .type = QUIRK_MIDI_YAMAHA
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0499, 0x100e),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Yamaha",
+               .product_name = "S08",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_YAMAHA
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0499, 0x100f),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Yamaha",
+               .product_name = "CLP-150",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_YAMAHA
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0499, 0x1010),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "Yamaha",
+               .product_name = "CLP-170",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_YAMAHA
        }
 },
-/*
- * 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
@@ -79,259 +177,316 @@
  * class-specific descriptors.
  */
 {
-       USB_DEVICE(0x0582, 0x0000),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x0007,
+                       .in_cables  = 0x0007
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x0002),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x000f,
+                       .in_cables  = 0x000f
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x0003),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x003f,
+                       .in_cables  = 0x003f
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x0004),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x0003,
+                       .in_cables  = 0x0003
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x0005),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x0003,
+                       .in_cables  = 0x0003
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x0007),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x0013,
+                       .in_cables  = 0x0013
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x0008),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x0001,
+                       .in_cables  = 0x0001
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x0009),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x0001,
+                       .in_cables  = 0x0001
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x000b),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x0013,
+                       .in_cables  = 0x0013
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x000c),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x0007,
+                       .in_cables  = 0x0007
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x0012),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x0001,
+                       .in_cables  = 0x0001
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x0014),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x01ff,
+                       .in_cables  = 0x01ff
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x0016),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x000f,
+                       .in_cables  = 0x000f
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x0023),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x003f,
+                       .in_cables  = 0x003f
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x0027),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x0003,
+                       .in_cables  = 0x0007
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x0029),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x000f,
+                       .in_cables  = 0x000f
                }
        }
 },
 {
-       USB_DEVICE(0x0582, 0x002b),
+       USB_DEVICE_VENDOR_SPEC(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
-                       }
+               .type = QUIRK_MIDI_FIXED_ENDPOINT,
+               .data = & (const snd_usb_midi_endpoint_info_t) {
+                       .epnum = -1,
+                       .out_cables = 0x0003,
+                       .in_cables  = 0x0003
                }
        }
 },
 
+/* Midiman/M-Audio devices */
+{
+       USB_DEVICE_VENDOR_SPEC(0x0763, 0x1002),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "M-Audio",
+               .product_name = "MidiSport 2x2",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_MIDIMAN,
+               .data = (void*) 2
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0763, 0x1011),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "M-Audio",
+               .product_name = "MidiSport 1x1",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_MIDIMAN,
+               .data = (void*) 1
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0763, 0x1015),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "M-Audio",
+               .product_name = "Keystation",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_MIDIMAN,
+               .data = (void*) 1
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0763, 0x1021),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "M-Audio",
+               .product_name = "MidiSport 4x4",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_MIDIMAN,
+               .data = (void*) 4
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0763, 0x1033),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "M-Audio",
+               .product_name = "MidiSport 8x8",
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_MIDI_MIDIMAN,
+               .data = (void*) 9
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0763, 0x2001),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "M-Audio",
+               .product_name = "Quattro",
+               .ifnum = 9,
+               .type = QUIRK_MIDI_MIDIMAN,
+               .data = (void*) 1
+       }
+},
+{
+       USB_DEVICE_VENDOR_SPEC(0x0763, 0x2003),
+       .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+               .vendor_name = "M-Audio",
+               .product_name = "AudioPhile",
+               .ifnum = 9,
+               .type = QUIRK_MIDI_MIDIMAN,
+               .data = (void*) 1
+       }
+},
+
 #endif /* CONFIG_SND_SEQUENCER(_MODULE) */
+
+#undef USB_DEVICE_VENDOR_SPEC



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to