diff options
author | Torsten Schenk <torsten.schenk@zoho.com> | 2013-08-11 13:11:19 +0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-08-12 13:42:28 +0400 |
commit | 5ece263f1d93fba8d992e67e3ab8a71acf674db9 (patch) | |
tree | 038670213da0df88ac884a8e48bbbd90eb1bb330 /sound/usb/6fire | |
parent | db8a38e5063a4daf61252e65d47ab3495c705f4c (diff) | |
download | linux-5ece263f1d93fba8d992e67e3ab8a71acf674db9.tar.xz |
ALSA: 6fire: make buffers DMA-able (pcm)
Patch makes pcm buffers DMA-able by allocating each one separately.
Signed-off-by: Torsten Schenk <torsten.schenk@zoho.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/6fire')
-rw-r--r-- | sound/usb/6fire/pcm.c | 41 | ||||
-rw-r--r-- | sound/usb/6fire/pcm.h | 2 |
2 files changed, 41 insertions, 2 deletions
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index 3d2551cc10f2..b5eb97fdc842 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c @@ -582,6 +582,33 @@ static void usb6fire_pcm_init_urb(struct pcm_urb *urb, 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; @@ -593,6 +620,13 @@ int usb6fire_pcm_init(struct sfire_chip *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); @@ -614,6 +648,7 @@ int usb6fire_pcm_init(struct sfire_chip *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; @@ -625,6 +660,7 @@ int usb6fire_pcm_init(struct sfire_chip *chip) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_ops); if (ret) { + usb6fire_pcm_buffers_destroy(rt); kfree(rt); snd_printk(KERN_ERR PREFIX "error preallocating pcm buffers.\n"); @@ -669,6 +705,9 @@ void usb6fire_pcm_abort(struct sfire_chip *chip) 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; } diff --git a/sound/usb/6fire/pcm.h b/sound/usb/6fire/pcm.h index 9b01133ee3fe..f5779d6182c6 100644 --- 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; }; |