Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ece263f authored by Torsten Schenk's avatar Torsten Schenk Committed by Takashi Iwai
Browse files

ALSA: 6fire: make buffers DMA-able (pcm)



Patch makes pcm buffers DMA-able by allocating each one separately.

Signed-off-by: default avatarTorsten Schenk <torsten.schenk@zoho.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent db8a38e5
Loading
Loading
Loading
Loading
+40 −1
Original line number Original line Diff line number Diff line
@@ -582,6 +582,33 @@ static void usb6fire_pcm_init_urb(struct pcm_urb *urb,
	urb->instance.number_of_packets = PCM_N_PACKETS_PER_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 usb6fire_pcm_init(struct sfire_chip *chip)
{
{
	int i;
	int i;
@@ -593,6 +620,13 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
	if (!rt)
	if (!rt)
		return -ENOMEM;
		return -ENOMEM;


	ret = usb6fire_pcm_buffers_init(rt);
	if (ret) {
		usb6fire_pcm_buffers_destroy(rt);
		kfree(rt);
		return ret;
	}

	rt->chip = chip;
	rt->chip = chip;
	rt->stream_state = STREAM_DISABLED;
	rt->stream_state = STREAM_DISABLED;
	rt->rate = ARRAY_SIZE(rates);
	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);
	ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm);
	if (ret < 0) {
	if (ret < 0) {
		usb6fire_pcm_buffers_destroy(rt);
		kfree(rt);
		kfree(rt);
		snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n");
		snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n");
		return ret;
		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);
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_ops);


	if (ret) {
	if (ret) {
		usb6fire_pcm_buffers_destroy(rt);
		kfree(rt);
		kfree(rt);
		snd_printk(KERN_ERR PREFIX
		snd_printk(KERN_ERR PREFIX
				"error preallocating pcm buffers.\n");
				"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)
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;
	chip->pcm = NULL;
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -32,7 +32,7 @@ struct pcm_urb {
	struct urb instance;
	struct urb instance;
	struct usb_iso_packet_descriptor packets[PCM_N_PACKETS_PER_URB];
	struct usb_iso_packet_descriptor packets[PCM_N_PACKETS_PER_URB];
	/* END DO NOT SEPARATE */
	/* END DO NOT SEPARATE */
	u8 buffer[PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE];
	u8 *buffer;


	struct pcm_urb *peer;
	struct pcm_urb *peer;
};
};