ALSA: 6fire: make buffers DMA-able (pcm)
authorTorsten Schenk <torsten.schenk@zoho.com>
Sun, 11 Aug 2013 09:11:19 +0000 (11:11 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 20 Aug 2013 15:43:04 +0000 (08:43 -0700)
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
sound/usb/6fire/pcm.h

index 074aaf7a36db46ee5071558be7b4e189621e5bab..25f9e61ad883cfcd4ce1f220a9f8b2ede0282257 100644 (file)
@@ -580,6 +580,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;
@@ -591,6 +618,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);
@@ -612,6 +646,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;
@@ -627,6 +662,7 @@ int usb6fire_pcm_init(struct sfire_chip *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_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;
 }
index 9b01133ee3fe9c22d3f51557430f011846e5bc8a..f5779d6182c638b02253af7bc9ab73dfed7e1916 100644 (file)
@@ -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;
 };