Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: 6fire: fix DMA issues with URB transfer_buffer usage

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.

Cc: stable@vger.kernel.org
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Tested-by: Torsten Schenk <torsten.schenk@zoho.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Jussi Kivilinna and committed by
Takashi Iwai
ddb6b5a9 697aebab

+34 -6
+33 -5
sound/usb/6fire/comm.c
··· 110 110 static int usb6fire_comm_write8(struct comm_runtime *rt, u8 request, 111 111 u8 reg, u8 value) 112 112 { 113 - u8 buffer[13]; /* 13: maximum length of message */ 113 + u8 *buffer; 114 + int ret; 115 + 116 + /* 13: maximum length of message */ 117 + buffer = kmalloc(13, GFP_KERNEL); 118 + if (!buffer) 119 + return -ENOMEM; 114 120 115 121 usb6fire_comm_init_buffer(buffer, 0x00, request, reg, value, 0x00); 116 - return usb6fire_comm_send_buffer(buffer, rt->chip->dev); 122 + ret = usb6fire_comm_send_buffer(buffer, rt->chip->dev); 123 + 124 + kfree(buffer); 125 + return ret; 117 126 } 118 127 119 128 static int usb6fire_comm_write16(struct comm_runtime *rt, u8 request, 120 129 u8 reg, u8 vl, u8 vh) 121 130 { 122 - u8 buffer[13]; /* 13: maximum length of message */ 131 + u8 *buffer; 132 + int ret; 133 + 134 + /* 13: maximum length of message */ 135 + buffer = kmalloc(13, GFP_KERNEL); 136 + if (!buffer) 137 + return -ENOMEM; 123 138 124 139 usb6fire_comm_init_buffer(buffer, 0x00, request, reg, vl, vh); 125 - return usb6fire_comm_send_buffer(buffer, rt->chip->dev); 140 + ret = usb6fire_comm_send_buffer(buffer, rt->chip->dev); 141 + 142 + kfree(buffer); 143 + return ret; 126 144 } 127 145 128 146 int usb6fire_comm_init(struct sfire_chip *chip) ··· 152 134 153 135 if (!rt) 154 136 return -ENOMEM; 137 + 138 + rt->receiver_buffer = kzalloc(COMM_RECEIVER_BUFSIZE, GFP_KERNEL); 139 + if (!rt->receiver_buffer) { 140 + kfree(rt); 141 + return -ENOMEM; 142 + } 155 143 156 144 urb = &rt->receiver; 157 145 rt->serial = 1; ··· 177 153 urb->interval = 1; 178 154 ret = usb_submit_urb(urb, GFP_KERNEL); 179 155 if (ret < 0) { 156 + kfree(rt->receiver_buffer); 180 157 kfree(rt); 181 158 snd_printk(KERN_ERR PREFIX "cannot create comm data receiver."); 182 159 return ret; ··· 196 171 197 172 void usb6fire_comm_destroy(struct sfire_chip *chip) 198 173 { 199 - kfree(chip->comm); 174 + struct comm_runtime *rt = chip->comm; 175 + 176 + kfree(rt->receiver_buffer); 177 + kfree(rt); 200 178 chip->comm = NULL; 201 179 }
+1 -1
sound/usb/6fire/comm.h
··· 24 24 struct sfire_chip *chip; 25 25 26 26 struct urb receiver; 27 - u8 receiver_buffer[COMM_RECEIVER_BUFSIZE]; 27 + u8 *receiver_buffer; 28 28 29 29 u8 serial; /* urb serial */ 30 30