diff options
author | Torsten Schenk <torsten.schenk@zoho.com> | 2013-08-11 05:11:19 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-20 11:43:04 -0400 |
commit | e6c1227df6c1fc67cd70d808429a7ad924d3b154 (patch) | |
tree | 08d117f17bd741c191e6158c031d368187bf51a7 /sound | |
parent | 5c75cd55f7fff95ddc45cfb32cca1b65bb2b1caf (diff) |
ALSA: 6fire: make buffers DMA-able (pcm)
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>
Diffstat (limited to 'sound')
-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 074aaf7a36db..25f9e61ad883 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c | |||
@@ -580,6 +580,33 @@ static void usb6fire_pcm_init_urb(struct pcm_urb *urb, | |||
580 | urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB; | 580 | urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB; |
581 | } | 581 | } |
582 | 582 | ||
583 | static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt) | ||
584 | { | ||
585 | int i; | ||
586 | |||
587 | for (i = 0; i < PCM_N_URBS; i++) { | ||
588 | rt->out_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB | ||
589 | * PCM_MAX_PACKET_SIZE, GFP_KERNEL); | ||
590 | if (!rt->out_urbs[i].buffer) | ||
591 | return -ENOMEM; | ||
592 | rt->in_urbs[i].buffer = kzalloc(PCM_N_PACKETS_PER_URB | ||
593 | * PCM_MAX_PACKET_SIZE, GFP_KERNEL); | ||
594 | if (!rt->in_urbs[i].buffer) | ||
595 | return -ENOMEM; | ||
596 | } | ||
597 | return 0; | ||
598 | } | ||
599 | |||
600 | static void usb6fire_pcm_buffers_destroy(struct pcm_runtime *rt) | ||
601 | { | ||
602 | int i; | ||
603 | |||
604 | for (i = 0; i < PCM_N_URBS; i++) { | ||
605 | kfree(rt->out_urbs[i].buffer); | ||
606 | kfree(rt->in_urbs[i].buffer); | ||
607 | } | ||
608 | } | ||
609 | |||
583 | int usb6fire_pcm_init(struct sfire_chip *chip) | 610 | int usb6fire_pcm_init(struct sfire_chip *chip) |
584 | { | 611 | { |
585 | int i; | 612 | int i; |
@@ -591,6 +618,13 @@ int usb6fire_pcm_init(struct sfire_chip *chip) | |||
591 | if (!rt) | 618 | if (!rt) |
592 | return -ENOMEM; | 619 | return -ENOMEM; |
593 | 620 | ||
621 | ret = usb6fire_pcm_buffers_init(rt); | ||
622 | if (ret) { | ||
623 | usb6fire_pcm_buffers_destroy(rt); | ||
624 | kfree(rt); | ||
625 | return ret; | ||
626 | } | ||
627 | |||
594 | rt->chip = chip; | 628 | rt->chip = chip; |
595 | rt->stream_state = STREAM_DISABLED; | 629 | rt->stream_state = STREAM_DISABLED; |
596 | rt->rate = ARRAY_SIZE(rates); | 630 | rt->rate = ARRAY_SIZE(rates); |
@@ -612,6 +646,7 @@ int usb6fire_pcm_init(struct sfire_chip *chip) | |||
612 | 646 | ||
613 | ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm); | 647 | ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm); |
614 | if (ret < 0) { | 648 | if (ret < 0) { |
649 | usb6fire_pcm_buffers_destroy(rt); | ||
615 | kfree(rt); | 650 | kfree(rt); |
616 | snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n"); | 651 | snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n"); |
617 | return ret; | 652 | return ret; |
@@ -627,6 +662,7 @@ int usb6fire_pcm_init(struct sfire_chip *chip) | |||
627 | snd_dma_continuous_data(GFP_KERNEL), | 662 | snd_dma_continuous_data(GFP_KERNEL), |
628 | MAX_BUFSIZE, MAX_BUFSIZE); | 663 | MAX_BUFSIZE, MAX_BUFSIZE); |
629 | if (ret) { | 664 | if (ret) { |
665 | usb6fire_pcm_buffers_destroy(rt); | ||
630 | kfree(rt); | 666 | kfree(rt); |
631 | snd_printk(KERN_ERR PREFIX | 667 | snd_printk(KERN_ERR PREFIX |
632 | "error preallocating pcm buffers.\n"); | 668 | "error preallocating pcm buffers.\n"); |
@@ -671,6 +707,9 @@ void usb6fire_pcm_abort(struct sfire_chip *chip) | |||
671 | 707 | ||
672 | void usb6fire_pcm_destroy(struct sfire_chip *chip) | 708 | void usb6fire_pcm_destroy(struct sfire_chip *chip) |
673 | { | 709 | { |
674 | kfree(chip->pcm); | 710 | struct pcm_runtime *rt = chip->pcm; |
711 | |||
712 | usb6fire_pcm_buffers_destroy(rt); | ||
713 | kfree(rt); | ||
675 | chip->pcm = NULL; | 714 | chip->pcm = NULL; |
676 | } | 715 | } |
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 { | |||
32 | struct urb instance; | 32 | struct urb instance; |
33 | struct usb_iso_packet_descriptor packets[PCM_N_PACKETS_PER_URB]; | 33 | struct usb_iso_packet_descriptor packets[PCM_N_PACKETS_PER_URB]; |
34 | /* END DO NOT SEPARATE */ | 34 | /* END DO NOT SEPARATE */ |
35 | u8 buffer[PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE]; | 35 | u8 *buffer; |
36 | 36 | ||
37 | struct pcm_urb *peer; | 37 | struct pcm_urb *peer; |
38 | }; | 38 | }; |