[alsa-devel] [PATCH] 6fire: fix DMA issues with URB transfer_buffer usage

Takashi Iwai tiwai at suse.de
Wed Aug 7 14:43:43 CEST 2013


At Tue, 06 Aug 2013 14:53:24 +0300,
Jussi Kivilinna wrote:
> 
> Patch fixes 6fire not to use stack as URB transfer_buffer. URB buffers need to
> be DMA-able, which stack is not. Furthermore, transfer_buffer should not be
> allocated as part of larger device structure because DMA coherency issues and
> patch fixes this issue too.
> 
> Patch is only compile tested.

The changes look OK, but I'd like to let it checked with a real
hardware before putting to stable kernel.

Torsten, could you check this?


thanks,

Takashi

> 
> Cc: stable at vger.kernel.org
> Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
> ---
>  sound/usb/6fire/comm.c |   38 +++++++++++++++++++++++++++++++++-----
>  sound/usb/6fire/comm.h |    2 +-
>  2 files changed, 34 insertions(+), 6 deletions(-)
> 
> diff --git a/sound/usb/6fire/comm.c b/sound/usb/6fire/comm.c
> index 9e6e3ff..23452ee 100644
> --- a/sound/usb/6fire/comm.c
> +++ b/sound/usb/6fire/comm.c
> @@ -110,19 +110,37 @@ static int usb6fire_comm_send_buffer(u8 *buffer, struct usb_device *dev)
>  static int usb6fire_comm_write8(struct comm_runtime *rt, u8 request,
>  		u8 reg, u8 value)
>  {
> -	u8 buffer[13]; /* 13: maximum length of message */
> +	u8 *buffer;
> +	int ret;
> +
> +	/* 13: maximum length of message */
> +	buffer = kmalloc(13, GFP_KERNEL);
> +	if (!buffer)
> +		return -ENOMEM;
>  
>  	usb6fire_comm_init_buffer(buffer, 0x00, request, reg, value, 0x00);
> -	return usb6fire_comm_send_buffer(buffer, rt->chip->dev);
> +	ret = usb6fire_comm_send_buffer(buffer, rt->chip->dev);
> +
> +	kfree(buffer);
> +	return ret;
>  }
>  
>  static int usb6fire_comm_write16(struct comm_runtime *rt, u8 request,
>  		u8 reg, u8 vl, u8 vh)
>  {
> -	u8 buffer[13]; /* 13: maximum length of message */
> +	u8 *buffer;
> +	int ret;
> +
> +	/* 13: maximum length of message */
> +	buffer = kmalloc(13, GFP_KERNEL);
> +	if (!buffer)
> +		return -ENOMEM;
>  
>  	usb6fire_comm_init_buffer(buffer, 0x00, request, reg, vl, vh);
> -	return usb6fire_comm_send_buffer(buffer, rt->chip->dev);
> +	ret = usb6fire_comm_send_buffer(buffer, rt->chip->dev);
> +
> +	kfree(buffer);
> +	return ret;
>  }
>  
>  int usb6fire_comm_init(struct sfire_chip *chip)
> @@ -135,6 +153,12 @@ int usb6fire_comm_init(struct sfire_chip *chip)
>  	if (!rt)
>  		return -ENOMEM;
>  
> +	rt->receiver_buffer = kzalloc(COMM_RECEIVER_BUFSIZE, GFP_KERNEL);
> +	if (!rt->receiver_buffer) {
> +		kfree(rt);
> +		return -ENOMEM;
> +	}
> +
>  	urb = &rt->receiver;
>  	rt->serial = 1;
>  	rt->chip = chip;
> @@ -153,6 +177,7 @@ int usb6fire_comm_init(struct sfire_chip *chip)
>  	urb->interval = 1;
>  	ret = usb_submit_urb(urb, GFP_KERNEL);
>  	if (ret < 0) {
> +		kfree(rt->receiver_buffer);
>  		kfree(rt);
>  		snd_printk(KERN_ERR PREFIX "cannot create comm data receiver.");
>  		return ret;
> @@ -171,6 +196,9 @@ void usb6fire_comm_abort(struct sfire_chip *chip)
>  
>  void usb6fire_comm_destroy(struct sfire_chip *chip)
>  {
> -	kfree(chip->comm);
> +	struct comm_runtime *rt = chip->comm;
> +
> +	kfree(rt->receiver_buffer);
> +	kfree(rt);
>  	chip->comm = NULL;
>  }
> diff --git a/sound/usb/6fire/comm.h b/sound/usb/6fire/comm.h
> index 6a0840b..780d5ed 100644
> --- a/sound/usb/6fire/comm.h
> +++ b/sound/usb/6fire/comm.h
> @@ -24,7 +24,7 @@ struct comm_runtime {
>  	struct sfire_chip *chip;
>  
>  	struct urb receiver;
> -	u8 receiver_buffer[COMM_RECEIVER_BUFSIZE];
> +	u8 *receiver_buffer;
>  
>  	u8 serial; /* urb serial */
>  
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 


More information about the Alsa-devel mailing list