| From 5ece263f1d93fba8d992e67e3ab8a71acf674db9 Mon Sep 17 00:00:00 2001 |
| From: Torsten Schenk <torsten.schenk@zoho.com> |
| Date: Sun, 11 Aug 2013 11:11:19 +0200 |
| Subject: ALSA: 6fire: make buffers DMA-able (pcm) |
| |
| From: Torsten Schenk <torsten.schenk@zoho.com> |
| |
| commit 5ece263f1d93fba8d992e67e3ab8a71acf674db9 upstream. |
| |
| Patch makes pcm buffers DMA-able by allocating each one separately. |
| |
| Signed-off-by: Torsten Schenk <torsten.schenk@zoho.com> |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| sound/usb/6fire/pcm.c | 41 ++++++++++++++++++++++++++++++++++++++++- |
| sound/usb/6fire/pcm.h | 2 +- |
| 2 files changed, 41 insertions(+), 2 deletions(-) |
| |
| --- a/sound/usb/6fire/pcm.c |
| +++ b/sound/usb/6fire/pcm.c |
| @@ -580,6 +580,33 @@ static void usb6fire_pcm_init_urb(struct |
| urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB; |
| } |
| |
| +static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt) |
| +{ |
| + int i; |
| + |
| + for (i = 0; i < PCM_N_URBS; i++) { |
| + rt->out_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB |
| + * PCM_MAX_PACKET_SIZE, GFP_KERNEL); |
| + if (!rt->out_urbs[i].buffer) |
| + return -ENOMEM; |
| + rt->in_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB |
| + * PCM_MAX_PACKET_SIZE, GFP_KERNEL); |
| + if (!rt->in_urbs[i].buffer) |
| + return -ENOMEM; |
| + } |
| + return 0; |
| +} |
| + |
| +static void usb6fire_pcm_buffers_destroy(struct pcm_runtime *rt) |
| +{ |
| + int i; |
| + |
| + for (i = 0; i < PCM_N_URBS; i++) { |
| + kfree(rt->out_urbs[i].buffer); |
| + kfree(rt->in_urbs[i].buffer); |
| + } |
| +} |
| + |
| int usb6fire_pcm_init(struct sfire_chip *chip) |
| { |
| int i; |
| @@ -591,6 +618,13 @@ int usb6fire_pcm_init(struct sfire_chip |
| if (!rt) |
| return -ENOMEM; |
| |
| + ret = usb6fire_pcm_buffers_init(rt); |
| + if (ret) { |
| + usb6fire_pcm_buffers_destroy(rt); |
| + kfree(rt); |
| + return ret; |
| + } |
| + |
| rt->chip = chip; |
| rt->stream_state = STREAM_DISABLED; |
| rt->rate = ARRAY_SIZE(rates); |
| @@ -612,6 +646,7 @@ int usb6fire_pcm_init(struct sfire_chip |
| |
| ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm); |
| if (ret < 0) { |
| + usb6fire_pcm_buffers_destroy(rt); |
| kfree(rt); |
| snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n"); |
| return ret; |
| @@ -627,6 +662,7 @@ int usb6fire_pcm_init(struct sfire_chip |
| snd_dma_continuous_data(GFP_KERNEL), |
| MAX_BUFSIZE, MAX_BUFSIZE); |
| if (ret) { |
| + usb6fire_pcm_buffers_destroy(rt); |
| kfree(rt); |
| snd_printk(KERN_ERR PREFIX |
| "error preallocating pcm buffers.\n"); |
| @@ -671,6 +707,9 @@ void usb6fire_pcm_abort(struct sfire_chi |
| |
| void usb6fire_pcm_destroy(struct sfire_chip *chip) |
| { |
| - kfree(chip->pcm); |
| + struct pcm_runtime *rt = chip->pcm; |
| + |
| + usb6fire_pcm_buffers_destroy(rt); |
| + kfree(rt); |
| chip->pcm = NULL; |
| } |
| --- a/sound/usb/6fire/pcm.h |
| +++ b/sound/usb/6fire/pcm.h |
| @@ -32,7 +32,7 @@ struct pcm_urb { |
| struct urb instance; |
| struct usb_iso_packet_descriptor packets[PCM_N_PACKETS_PER_URB]; |
| /* END DO NOT SEPARATE */ |
| - u8 buffer[PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE]; |
| + u8 *buffer; |
| |
| struct pcm_urb *peer; |
| }; |