diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2005-08-15 02:34:16 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2005-08-30 02:45:53 -0400 |
commit | 55851f734d7af7e5362d43b60331c95c32a3b027 (patch) | |
tree | 6eef6e6915e459f959a596fa37b6c2f87b55f863 /sound/usb | |
parent | daa150ef7d437d17973210f47a1c58623415df94 (diff) |
[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 <clemens@ladisch.de>
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/usbaudio.c | 52 | ||||
-rw-r--r-- | sound/usb/usbmidi.c | 17 |
2 files changed, 46 insertions, 23 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 8d4a085f642a..13ff66b0a532 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -127,6 +127,7 @@ struct audioformat { | |||
127 | 127 | ||
128 | struct snd_urb_ctx { | 128 | struct snd_urb_ctx { |
129 | struct urb *urb; | 129 | struct urb *urb; |
130 | unsigned int buffer_size; /* size of data buffer, if data URB */ | ||
130 | snd_usb_substream_t *subs; | 131 | snd_usb_substream_t *subs; |
131 | int index; /* index for urb array */ | 132 | int index; /* index for urb array */ |
132 | int packets; /* number of packets per urb */ | 133 | int packets; /* number of packets per urb */ |
@@ -176,7 +177,8 @@ struct snd_usb_substream { | |||
176 | unsigned int nurbs; /* # urbs */ | 177 | unsigned int nurbs; /* # urbs */ |
177 | snd_urb_ctx_t dataurb[MAX_URBS]; /* data urb table */ | 178 | snd_urb_ctx_t dataurb[MAX_URBS]; /* data urb table */ |
178 | snd_urb_ctx_t syncurb[SYNC_URBS]; /* sync urb table */ | 179 | snd_urb_ctx_t syncurb[SYNC_URBS]; /* sync urb table */ |
179 | char syncbuf[SYNC_URBS * 4]; /* sync buffer; it's so small - let's get static */ | 180 | char *syncbuf; /* sync buffer for all sync URBs */ |
181 | dma_addr_t sync_dma; /* DMA address of syncbuf */ | ||
180 | 182 | ||
181 | u64 formats; /* format bitmasks (all or'ed) */ | 183 | u64 formats; /* format bitmasks (all or'ed) */ |
182 | unsigned int num_formats; /* number of supported audio formats (list) */ | 184 | unsigned int num_formats; /* number of supported audio formats (list) */ |
@@ -855,7 +857,10 @@ static int snd_usb_pcm_trigger(snd_pcm_substream_t *substream, int cmd) | |||
855 | static void release_urb_ctx(snd_urb_ctx_t *u) | 857 | static void release_urb_ctx(snd_urb_ctx_t *u) |
856 | { | 858 | { |
857 | if (u->urb) { | 859 | if (u->urb) { |
858 | kfree(u->urb->transfer_buffer); | 860 | if (u->buffer_size) |
861 | usb_buffer_free(u->subs->dev, u->buffer_size, | ||
862 | u->urb->transfer_buffer, | ||
863 | u->urb->transfer_dma); | ||
859 | usb_free_urb(u->urb); | 864 | usb_free_urb(u->urb); |
860 | u->urb = NULL; | 865 | u->urb = NULL; |
861 | } | 866 | } |
@@ -876,6 +881,9 @@ static void release_substream_urbs(snd_usb_substream_t *subs, int force) | |||
876 | release_urb_ctx(&subs->dataurb[i]); | 881 | release_urb_ctx(&subs->dataurb[i]); |
877 | for (i = 0; i < SYNC_URBS; i++) | 882 | for (i = 0; i < SYNC_URBS; i++) |
878 | release_urb_ctx(&subs->syncurb[i]); | 883 | release_urb_ctx(&subs->syncurb[i]); |
884 | usb_buffer_free(subs->dev, SYNC_URBS * 4, | ||
885 | subs->syncbuf, subs->sync_dma); | ||
886 | subs->syncbuf = NULL; | ||
879 | subs->nurbs = 0; | 887 | subs->nurbs = 0; |
880 | } | 888 | } |
881 | 889 | ||
@@ -986,21 +994,19 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by | |||
986 | u->index = i; | 994 | u->index = i; |
987 | u->subs = subs; | 995 | u->subs = subs; |
988 | u->packets = npacks[i]; | 996 | u->packets = npacks[i]; |
997 | u->buffer_size = maxsize * u->packets; | ||
989 | if (subs->fmt_type == USB_FORMAT_TYPE_II) | 998 | if (subs->fmt_type == USB_FORMAT_TYPE_II) |
990 | u->packets++; /* for transfer delimiter */ | 999 | u->packets++; /* for transfer delimiter */ |
991 | u->urb = usb_alloc_urb(u->packets, GFP_KERNEL); | 1000 | u->urb = usb_alloc_urb(u->packets, GFP_KERNEL); |
992 | if (! u->urb) { | 1001 | if (! u->urb) |
993 | release_substream_urbs(subs, 0); | 1002 | goto out_of_memory; |
994 | return -ENOMEM; | 1003 | u->urb->transfer_buffer = |
995 | } | 1004 | usb_buffer_alloc(subs->dev, u->buffer_size, GFP_KERNEL, |
996 | u->urb->transfer_buffer = kmalloc(maxsize * u->packets, | 1005 | &u->urb->transfer_dma); |
997 | GFP_KERNEL); | 1006 | if (! u->urb->transfer_buffer) |
998 | if (! u->urb->transfer_buffer) { | 1007 | goto out_of_memory; |
999 | release_substream_urbs(subs, 0); | ||
1000 | return -ENOMEM; | ||
1001 | } | ||
1002 | u->urb->pipe = subs->datapipe; | 1008 | u->urb->pipe = subs->datapipe; |
1003 | u->urb->transfer_flags = URB_ISO_ASAP; | 1009 | u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; |
1004 | u->urb->interval = 1 << subs->datainterval; | 1010 | u->urb->interval = 1 << subs->datainterval; |
1005 | u->urb->context = u; | 1011 | u->urb->context = u; |
1006 | u->urb->complete = snd_usb_complete_callback(snd_complete_urb); | 1012 | u->urb->complete = snd_usb_complete_callback(snd_complete_urb); |
@@ -1008,20 +1014,24 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by | |||
1008 | 1014 | ||
1009 | if (subs->syncpipe) { | 1015 | if (subs->syncpipe) { |
1010 | /* allocate and initialize sync urbs */ | 1016 | /* allocate and initialize sync urbs */ |
1017 | subs->syncbuf = usb_buffer_alloc(subs->dev, SYNC_URBS * 4, | ||
1018 | GFP_KERNEL, &subs->sync_dma); | ||
1019 | if (! subs->syncbuf) | ||
1020 | goto out_of_memory; | ||
1011 | for (i = 0; i < SYNC_URBS; i++) { | 1021 | for (i = 0; i < SYNC_URBS; i++) { |
1012 | snd_urb_ctx_t *u = &subs->syncurb[i]; | 1022 | snd_urb_ctx_t *u = &subs->syncurb[i]; |
1013 | u->index = i; | 1023 | u->index = i; |
1014 | u->subs = subs; | 1024 | u->subs = subs; |
1015 | u->packets = 1; | 1025 | u->packets = 1; |
1016 | u->urb = usb_alloc_urb(1, GFP_KERNEL); | 1026 | u->urb = usb_alloc_urb(1, GFP_KERNEL); |
1017 | if (! u->urb) { | 1027 | if (! u->urb) |
1018 | release_substream_urbs(subs, 0); | 1028 | goto out_of_memory; |
1019 | return -ENOMEM; | ||
1020 | } | ||
1021 | u->urb->transfer_buffer = subs->syncbuf + i * 4; | 1029 | u->urb->transfer_buffer = subs->syncbuf + i * 4; |
1030 | u->urb->transfer_dma = subs->sync_dma + i * 4; | ||
1022 | u->urb->transfer_buffer_length = 4; | 1031 | u->urb->transfer_buffer_length = 4; |
1023 | u->urb->pipe = subs->syncpipe; | 1032 | u->urb->pipe = subs->syncpipe; |
1024 | u->urb->transfer_flags = URB_ISO_ASAP; | 1033 | u->urb->transfer_flags = URB_ISO_ASAP | |
1034 | URB_NO_TRANSFER_DMA_MAP; | ||
1025 | u->urb->number_of_packets = 1; | 1035 | u->urb->number_of_packets = 1; |
1026 | u->urb->interval = 1 << subs->syncinterval; | 1036 | u->urb->interval = 1 << subs->syncinterval; |
1027 | u->urb->context = u; | 1037 | u->urb->context = u; |
@@ -1029,6 +1039,10 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by | |||
1029 | } | 1039 | } |
1030 | } | 1040 | } |
1031 | return 0; | 1041 | return 0; |
1042 | |||
1043 | out_of_memory: | ||
1044 | release_substream_urbs(subs, 0); | ||
1045 | return -ENOMEM; | ||
1032 | } | 1046 | } |
1033 | 1047 | ||
1034 | 1048 | ||
@@ -2036,7 +2050,7 @@ static void init_substream(snd_usb_stream_t *as, int stream, struct audioformat | |||
2036 | subs->ops = audio_urb_ops_high_speed[stream]; | 2050 | subs->ops = audio_urb_ops_high_speed[stream]; |
2037 | snd_pcm_lib_preallocate_pages(as->pcm->streams[stream].substream, | 2051 | snd_pcm_lib_preallocate_pages(as->pcm->streams[stream].substream, |
2038 | SNDRV_DMA_TYPE_CONTINUOUS, | 2052 | SNDRV_DMA_TYPE_CONTINUOUS, |
2039 | snd_dma_continuous_data(GFP_KERNEL), | 2053 | snd_dma_continuous_data(GFP_NOIO), |
2040 | 64 * 1024, 128 * 1024); | 2054 | 64 * 1024, 128 * 1024); |
2041 | snd_pcm_set_ops(as->pcm, stream, | 2055 | snd_pcm_set_ops(as->pcm, stream, |
2042 | stream == SNDRV_PCM_STREAM_PLAYBACK ? | 2056 | stream == SNDRV_PCM_STREAM_PLAYBACK ? |
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 5778a9b725ec..d0d895df5375 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c | |||
@@ -765,7 +765,10 @@ static snd_rawmidi_ops_t snd_usbmidi_input_ops = { | |||
765 | static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep) | 765 | static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep) |
766 | { | 766 | { |
767 | if (ep->urb) { | 767 | if (ep->urb) { |
768 | kfree(ep->urb->transfer_buffer); | 768 | usb_buffer_free(ep->umidi->chip->dev, |
769 | ep->urb->transfer_buffer_length, | ||
770 | ep->urb->transfer_buffer, | ||
771 | ep->urb->transfer_dma); | ||
769 | usb_free_urb(ep->urb); | 772 | usb_free_urb(ep->urb); |
770 | } | 773 | } |
771 | kfree(ep); | 774 | kfree(ep); |
@@ -799,7 +802,8 @@ static int snd_usbmidi_in_endpoint_create(snd_usb_midi_t* umidi, | |||
799 | else | 802 | else |
800 | pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->in_ep); | 803 | pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->in_ep); |
801 | length = usb_maxpacket(umidi->chip->dev, pipe, 0); | 804 | length = usb_maxpacket(umidi->chip->dev, pipe, 0); |
802 | buffer = kmalloc(length, GFP_KERNEL); | 805 | buffer = usb_buffer_alloc(umidi->chip->dev, length, GFP_KERNEL, |
806 | &ep->urb->transfer_dma); | ||
803 | if (!buffer) { | 807 | if (!buffer) { |
804 | snd_usbmidi_in_endpoint_delete(ep); | 808 | snd_usbmidi_in_endpoint_delete(ep); |
805 | return -ENOMEM; | 809 | return -ENOMEM; |
@@ -812,6 +816,7 @@ static int snd_usbmidi_in_endpoint_create(snd_usb_midi_t* umidi, | |||
812 | usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, length, | 816 | usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, length, |
813 | snd_usb_complete_callback(snd_usbmidi_in_urb_complete), | 817 | snd_usb_complete_callback(snd_usbmidi_in_urb_complete), |
814 | ep); | 818 | ep); |
819 | ep->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; | ||
815 | 820 | ||
816 | rep->in = ep; | 821 | rep->in = ep; |
817 | return 0; | 822 | return 0; |
@@ -835,7 +840,9 @@ static void snd_usbmidi_out_endpoint_delete(snd_usb_midi_out_endpoint_t* ep) | |||
835 | if (ep->tasklet.func) | 840 | if (ep->tasklet.func) |
836 | tasklet_kill(&ep->tasklet); | 841 | tasklet_kill(&ep->tasklet); |
837 | if (ep->urb) { | 842 | if (ep->urb) { |
838 | kfree(ep->urb->transfer_buffer); | 843 | usb_buffer_free(ep->umidi->chip->dev, ep->max_transfer, |
844 | ep->urb->transfer_buffer, | ||
845 | ep->urb->transfer_dma); | ||
839 | usb_free_urb(ep->urb); | 846 | usb_free_urb(ep->urb); |
840 | } | 847 | } |
841 | kfree(ep); | 848 | kfree(ep); |
@@ -867,7 +874,8 @@ static int snd_usbmidi_out_endpoint_create(snd_usb_midi_t* umidi, | |||
867 | /* we never use interrupt output pipes */ | 874 | /* we never use interrupt output pipes */ |
868 | pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); | 875 | pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); |
869 | ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); | 876 | ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); |
870 | buffer = kmalloc(ep->max_transfer, GFP_KERNEL); | 877 | buffer = usb_buffer_alloc(umidi->chip->dev, ep->max_transfer, |
878 | GFP_KERNEL, &ep->urb->transfer_dma); | ||
871 | if (!buffer) { | 879 | if (!buffer) { |
872 | snd_usbmidi_out_endpoint_delete(ep); | 880 | snd_usbmidi_out_endpoint_delete(ep); |
873 | return -ENOMEM; | 881 | return -ENOMEM; |
@@ -875,6 +883,7 @@ static int snd_usbmidi_out_endpoint_create(snd_usb_midi_t* umidi, | |||
875 | usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, | 883 | usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, |
876 | ep->max_transfer, | 884 | ep->max_transfer, |
877 | snd_usb_complete_callback(snd_usbmidi_out_urb_complete), ep); | 885 | snd_usb_complete_callback(snd_usbmidi_out_urb_complete), ep); |
886 | ep->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; | ||
878 | 887 | ||
879 | spin_lock_init(&ep->buffer_lock); | 888 | spin_lock_init(&ep->buffer_lock); |
880 | tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep); | 889 | tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep); |