tree 6eef6e6915e459f959a596fa37b6c2f87b55f863
parent daa150ef7d437d17973210f47a1c58623415df94
author Clemens Ladisch <[EMAIL PROTECTED]> Mon, 15 Aug 2005 08:34:16 +0200
committer Jaroslav Kysela <[EMAIL PROTECTED]> Tue, 30 Aug 2005 08:45:53 +0200

[ALSA] usb-audio: use usb_buffer_alloc/free

USB generic driver
Use the USB buffer allocation functions to avoid repeated DMA mappings
of our buffers, which are re-used quite a lot.

Signed-off-by: Clemens Ladisch <[EMAIL PROTECTED]>

 sound/usb/usbaudio.c |   52 ++++++++++++++++++++++++++++++++-------------------
 sound/usb/usbmidi.c  |   17 ++++++++++++----
 2 files changed, 46 insertions(+), 23 deletions(-)

diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -127,6 +127,7 @@ struct audioformat {
 
 struct snd_urb_ctx {
        struct urb *urb;
+       unsigned int buffer_size;       /* size of data buffer, if data URB */
        snd_usb_substream_t *subs;
        int index;      /* index for urb array */
        int packets;    /* number of packets per urb */
@@ -176,7 +177,8 @@ struct snd_usb_substream {
        unsigned int nurbs;                     /* # urbs */
        snd_urb_ctx_t dataurb[MAX_URBS];        /* data urb table */
        snd_urb_ctx_t syncurb[SYNC_URBS];       /* sync urb table */
-       char syncbuf[SYNC_URBS * 4];    /* sync buffer; it's so small - let's 
get static */
+       char *syncbuf;                          /* sync buffer for all sync 
URBs */
+       dma_addr_t sync_dma;                    /* DMA address of syncbuf */
 
        u64 formats;                    /* format bitmasks (all or'ed) */
        unsigned int num_formats;               /* number of supported audio 
formats (list) */
@@ -855,7 +857,10 @@ static int snd_usb_pcm_trigger(snd_pcm_s
 static void release_urb_ctx(snd_urb_ctx_t *u)
 {
        if (u->urb) {
-               kfree(u->urb->transfer_buffer);
+               if (u->buffer_size)
+                       usb_buffer_free(u->subs->dev, u->buffer_size,
+                                       u->urb->transfer_buffer,
+                                       u->urb->transfer_dma);
                usb_free_urb(u->urb);
                u->urb = NULL;
        }
@@ -876,6 +881,9 @@ static void release_substream_urbs(snd_u
                release_urb_ctx(&subs->dataurb[i]);
        for (i = 0; i < SYNC_URBS; i++)
                release_urb_ctx(&subs->syncurb[i]);
+       usb_buffer_free(subs->dev, SYNC_URBS * 4,
+                       subs->syncbuf, subs->sync_dma);
+       subs->syncbuf = NULL;
        subs->nurbs = 0;
 }
 
@@ -986,21 +994,19 @@ static int init_substream_urbs(snd_usb_s
                u->index = i;
                u->subs = subs;
                u->packets = npacks[i];
+               u->buffer_size = maxsize * u->packets;
                if (subs->fmt_type == USB_FORMAT_TYPE_II)
                        u->packets++; /* for transfer delimiter */
                u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
-               if (! u->urb) {
-                       release_substream_urbs(subs, 0);
-                       return -ENOMEM;
-               }
-               u->urb->transfer_buffer = kmalloc(maxsize * u->packets,
-                                                 GFP_KERNEL);
-               if (! u->urb->transfer_buffer) {
-                       release_substream_urbs(subs, 0);
-                       return -ENOMEM;
-               }
+               if (! u->urb)
+                       goto out_of_memory;
+               u->urb->transfer_buffer =
+                       usb_buffer_alloc(subs->dev, u->buffer_size, GFP_KERNEL,
+                                        &u->urb->transfer_dma);
+               if (! u->urb->transfer_buffer)
+                       goto out_of_memory;
                u->urb->pipe = subs->datapipe;
-               u->urb->transfer_flags = URB_ISO_ASAP;
+               u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
                u->urb->interval = 1 << subs->datainterval;
                u->urb->context = u;
                u->urb->complete = snd_usb_complete_callback(snd_complete_urb);
@@ -1008,20 +1014,24 @@ static int init_substream_urbs(snd_usb_s
 
        if (subs->syncpipe) {
                /* allocate and initialize sync urbs */
+               subs->syncbuf = usb_buffer_alloc(subs->dev, SYNC_URBS * 4,
+                                                GFP_KERNEL, &subs->sync_dma);
+               if (! subs->syncbuf)
+                       goto out_of_memory;
                for (i = 0; i < SYNC_URBS; i++) {
                        snd_urb_ctx_t *u = &subs->syncurb[i];
                        u->index = i;
                        u->subs = subs;
                        u->packets = 1;
                        u->urb = usb_alloc_urb(1, GFP_KERNEL);
-                       if (! u->urb) {
-                               release_substream_urbs(subs, 0);
-                               return -ENOMEM;
-                       }
+                       if (! u->urb)
+                               goto out_of_memory;
                        u->urb->transfer_buffer = subs->syncbuf + i * 4;
+                       u->urb->transfer_dma = subs->sync_dma + i * 4;
                        u->urb->transfer_buffer_length = 4;
                        u->urb->pipe = subs->syncpipe;
-                       u->urb->transfer_flags = URB_ISO_ASAP;
+                       u->urb->transfer_flags = URB_ISO_ASAP |
+                                                URB_NO_TRANSFER_DMA_MAP;
                        u->urb->number_of_packets = 1;
                        u->urb->interval = 1 << subs->syncinterval;
                        u->urb->context = u;
@@ -1029,6 +1039,10 @@ static int init_substream_urbs(snd_usb_s
                }
        }
        return 0;
+
+out_of_memory:
+       release_substream_urbs(subs, 0);
+       return -ENOMEM;
 }
 
 
@@ -2036,7 +2050,7 @@ static void init_substream(snd_usb_strea
                subs->ops = audio_urb_ops_high_speed[stream];
        snd_pcm_lib_preallocate_pages(as->pcm->streams[stream].substream,
                                      SNDRV_DMA_TYPE_CONTINUOUS,
-                                     snd_dma_continuous_data(GFP_KERNEL),
+                                     snd_dma_continuous_data(GFP_NOIO),
                                      64 * 1024, 128 * 1024);
        snd_pcm_set_ops(as->pcm, stream,
                        stream == SNDRV_PCM_STREAM_PLAYBACK ?
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -765,7 +765,10 @@ static snd_rawmidi_ops_t snd_usbmidi_inp
 static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep)
 {
        if (ep->urb) {
-               kfree(ep->urb->transfer_buffer);
+               usb_buffer_free(ep->umidi->chip->dev,
+                               ep->urb->transfer_buffer_length,
+                               ep->urb->transfer_buffer,
+                               ep->urb->transfer_dma);
                usb_free_urb(ep->urb);
        }
        kfree(ep);
@@ -799,7 +802,8 @@ static int snd_usbmidi_in_endpoint_creat
        else
                pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->in_ep);
        length = usb_maxpacket(umidi->chip->dev, pipe, 0);
-       buffer = kmalloc(length, GFP_KERNEL);
+       buffer = usb_buffer_alloc(umidi->chip->dev, length, GFP_KERNEL,
+                                 &ep->urb->transfer_dma);
        if (!buffer) {
                snd_usbmidi_in_endpoint_delete(ep);
                return -ENOMEM;
@@ -812,6 +816,7 @@ static int snd_usbmidi_in_endpoint_creat
                usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, 
length,
                                  
snd_usb_complete_callback(snd_usbmidi_in_urb_complete),
                                  ep);
+       ep->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
 
        rep->in = ep;
        return 0;
@@ -835,7 +840,9 @@ static void snd_usbmidi_out_endpoint_del
        if (ep->tasklet.func)
                tasklet_kill(&ep->tasklet);
        if (ep->urb) {
-               kfree(ep->urb->transfer_buffer);
+               usb_buffer_free(ep->umidi->chip->dev, ep->max_transfer,
+                               ep->urb->transfer_buffer,
+                               ep->urb->transfer_dma);
                usb_free_urb(ep->urb);
        }
        kfree(ep);
@@ -867,7 +874,8 @@ static int snd_usbmidi_out_endpoint_crea
        /* we never use interrupt output pipes */
        pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep);
        ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1);
-       buffer = kmalloc(ep->max_transfer, GFP_KERNEL);
+       buffer = usb_buffer_alloc(umidi->chip->dev, ep->max_transfer,
+                                 GFP_KERNEL, &ep->urb->transfer_dma);
        if (!buffer) {
                snd_usbmidi_out_endpoint_delete(ep);
                return -ENOMEM;
@@ -875,6 +883,7 @@ static int snd_usbmidi_out_endpoint_crea
        usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer,
                          ep->max_transfer,
                          
snd_usb_complete_callback(snd_usbmidi_out_urb_complete), ep);
+       ep->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
 
        spin_lock_init(&ep->buffer_lock);
        tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to