]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - sound/usb/usbmidi.c
USB: rename usb_buffer_alloc() and usb_buffer_free() users
[linux-2.6.git] / sound / usb / usbmidi.c
index 6e89b8368d9ae2bcb315dd74fb28026cec25af99..61b2d8fd0331d917793a85ef3ac63dfd91837dfc 100644 (file)
@@ -46,6 +46,8 @@
 #include <linux/timer.h>
 #include <linux/usb.h>
 #include <linux/wait.h>
+#include <linux/usb/audio.h>
+
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/rawmidi.h>
@@ -984,6 +986,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
        DEFINE_WAIT(wait);
        long timeout = msecs_to_jiffies(50);
 
+       if (ep->umidi->disconnected)
+               return;
        /*
         * The substream buffer is empty, but some data might still be in the
         * currently active URBs, so we have to wait for those to complete.
@@ -1043,8 +1047,8 @@ static struct snd_rawmidi_ops snd_usbmidi_input_ops = {
 static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb,
                                unsigned int buffer_length)
 {
-       usb_buffer_free(umidi->dev, buffer_length,
-                       urb->transfer_buffer, urb->transfer_dma);
+       usb_free_coherent(umidi->dev, buffer_length,
+                         urb->transfer_buffer, urb->transfer_dma);
        usb_free_urb(urb);
 }
 
@@ -1095,8 +1099,8 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
                pipe = usb_rcvbulkpipe(umidi->dev, ep_info->in_ep);
        length = usb_maxpacket(umidi->dev, pipe, 0);
        for (i = 0; i < INPUT_URBS; ++i) {
-               buffer = usb_buffer_alloc(umidi->dev, length, GFP_KERNEL,
-                                         &ep->urbs[i]->transfer_dma);
+               buffer = usb_alloc_coherent(umidi->dev, length, GFP_KERNEL,
+                                           &ep->urbs[i]->transfer_dma);
                if (!buffer) {
                        snd_usbmidi_in_endpoint_delete(ep);
                        return -ENOMEM;
@@ -1121,14 +1125,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
  * Frees an output endpoint.
  * May be called when ep hasn't been initialized completely.
  */
-static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep)
+static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep)
 {
        unsigned int i;
 
        for (i = 0; i < OUTPUT_URBS; ++i)
-               if (ep->urbs[i].urb)
+               if (ep->urbs[i].urb) {
                        free_urb_and_buffer(ep->umidi, ep->urbs[i].urb,
                                            ep->max_transfer);
+                       ep->urbs[i].urb = NULL;
+               }
+}
+
+static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep)
+{
+       snd_usbmidi_out_endpoint_clear(ep);
        kfree(ep);
 }
 
@@ -1162,14 +1173,26 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
                pipe = usb_sndintpipe(umidi->dev, ep_info->out_ep);
        else
                pipe = usb_sndbulkpipe(umidi->dev, ep_info->out_ep);
-       if (umidi->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */
-               ep->max_transfer = 4;
-       else
+       switch (umidi->usb_id) {
+       default:
                ep->max_transfer = usb_maxpacket(umidi->dev, pipe, 1);
+               break;
+               /*
+                * Various chips declare a packet size larger than 4 bytes, but
+                * do not actually work with larger packets:
+                */
+       case USB_ID(0x0a92, 0x1020): /* ESI M4U */
+       case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */
+       case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */
+       case USB_ID(0x15ca, 0x1806): /* Textech USB Midi Cable */
+       case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */
+               ep->max_transfer = 4;
+               break;
+       }
        for (i = 0; i < OUTPUT_URBS; ++i) {
-               buffer = usb_buffer_alloc(umidi->dev,
-                                         ep->max_transfer, GFP_KERNEL,
-                                         &ep->urbs[i].urb->transfer_dma);
+               buffer = usb_alloc_coherent(umidi->dev,
+                                           ep->max_transfer, GFP_KERNEL,
+                                           &ep->urbs[i].urb->transfer_dma);
                if (!buffer) {
                        snd_usbmidi_out_endpoint_delete(ep);
                        return -ENOMEM;
@@ -1248,15 +1271,18 @@ void snd_usbmidi_disconnect(struct list_head* p)
                                usb_kill_urb(ep->out->urbs[j].urb);
                        if (umidi->usb_protocol_ops->finish_out_endpoint)
                                umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
+                       ep->out->active_urbs = 0;
+                       if (ep->out->drain_urbs) {
+                               ep->out->drain_urbs = 0;
+                               wake_up(&ep->out->drain_wait);
+                       }
                }
                if (ep->in)
                        for (j = 0; j < INPUT_URBS; ++j)
                                usb_kill_urb(ep->in->urbs[j]);
                /* free endpoints here; later call can result in Oops */
-               if (ep->out) {
-                       snd_usbmidi_out_endpoint_delete(ep->out);
-                       ep->out = NULL;
-               }
+               if (ep->out)
+                       snd_usbmidi_out_endpoint_clear(ep->out);
                if (ep->in) {
                        snd_usbmidi_in_endpoint_delete(ep->in);
                        ep->in = NULL;
@@ -1407,6 +1433,12 @@ static struct port_info {
        EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"),
        EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"),
        EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"),
+       /* Access Music Virus TI */
+       EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"),
+       PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0,
+               SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
+               SNDRV_SEQ_PORT_TYPE_HARDWARE |
+               SNDRV_SEQ_PORT_TYPE_SYNTHESIZER),
 };
 
 static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number)
@@ -1522,7 +1554,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
        if (hostif->extralen >= 7 &&
            ms_header->bLength >= 7 &&
            ms_header->bDescriptorType == USB_DT_CS_INTERFACE &&
-           ms_header->bDescriptorSubtype == HEADER)
+           ms_header->bDescriptorSubtype == UAC_HEADER)
                snd_printdd(KERN_INFO "MIDIStreaming version %02x.%02x\n",
                            ms_header->bcdMSC[1], ms_header->bcdMSC[0]);
        else
@@ -1538,7 +1570,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
                if (hostep->extralen < 4 ||
                    ms_ep->bLength < 4 ||
                    ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT ||
-                   ms_ep->bDescriptorSubtype != MS_GENERAL)
+                   ms_ep->bDescriptorSubtype != UAC_MS_GENERAL)
                        continue;
                if (usb_endpoint_dir_out(ep)) {
                        if (endpoints[epidx].out_ep) {
@@ -1750,9 +1782,9 @@ static int snd_usbmidi_detect_yamaha(struct snd_usb_midi* umidi,
             cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2;
             cs_desc += cs_desc[0]) {
                if (cs_desc[1] == USB_DT_CS_INTERFACE) {
-                       if (cs_desc[2] == MIDI_IN_JACK)
+                       if (cs_desc[2] == UAC_MIDI_IN_JACK)
                                endpoint->in_cables = (endpoint->in_cables << 1) | 1;
-                       else if (cs_desc[2] == MIDI_OUT_JACK)
+                       else if (cs_desc[2] == UAC_MIDI_OUT_JACK)
                                endpoint->out_cables = (endpoint->out_cables << 1) | 1;
                }
        }