1 /* 2 * Digital Audio (PCM) abstract layer 3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 4 * 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 */ 21 22 #include <linux/io.h> 23 #include <linux/time.h> 24 #include <linux/init.h> 25 #include <linux/slab.h> 26 #include <linux/moduleparam.h> 27 #include <linux/vmalloc.h> 28 #include <linux/export.h> 29 #include <sound/core.h> 30 #include <sound/pcm.h> 31 #include <sound/info.h> 32 #include <sound/initval.h> 33 34 static int preallocate_dma = 1; 35 module_param(preallocate_dma, int, 0444); 36 MODULE_PARM_DESC(preallocate_dma, "Preallocate DMA memory when the PCM devices are initialized."); 37 38 static int maximum_substreams = 4; 39 module_param(maximum_substreams, int, 0444); 40 MODULE_PARM_DESC(maximum_substreams, "Maximum substreams with preallocated DMA memory."); 41 42 static const size_t snd_minimum_buffer = 16384; 43 44 45 /* 46 * try to allocate as the large pages as possible. 47 * stores the resultant memory size in *res_size. 48 * 49 * the minimum size is snd_minimum_buffer. it should be power of 2. 50 */ 51 static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t size) 52 { 53 struct snd_dma_buffer *dmab = &substream->dma_buffer; 54 size_t orig_size = size; 55 int err; 56 57 do { 58 if ((err = snd_dma_alloc_pages(dmab->dev.type, dmab->dev.dev, 59 size, dmab)) < 0) { 60 if (err != -ENOMEM) 61 return err; /* fatal error */ 62 } else 63 return 0; 64 size >>= 1; 65 } while (size >= snd_minimum_buffer); 66 dmab->bytes = 0; /* tell error */ 67 pr_warn("ALSA pcmC%dD%d%c,%d:%s: cannot preallocate for size %zu\n", 68 substream->pcm->card->number, substream->pcm->device, 69 substream->stream ? 'c' : 'p', substream->number, 70 substream->pcm->name, orig_size); 71 return 0; 72 } 73 74 /* 75 * release the preallocated buffer if not yet done. 76 */ 77 static void snd_pcm_lib_preallocate_dma_free(struct snd_pcm_substream *substream) 78 { 79 if (substream->dma_buffer.area == NULL) 80 return; 81 snd_dma_free_pages(&substream->dma_buffer); 82 substream->dma_buffer.area = NULL; 83 } 84 85 /** 86 * snd_pcm_lib_preallocate_free - release the preallocated buffer of the specified substream. 87 * @substream: the pcm substream instance 88 * 89 * Releases the pre-allocated buffer of the given substream. 90 */ 91 void snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream) 92 { 93 snd_pcm_lib_preallocate_dma_free(substream); 94 } 95 96 /** 97 * snd_pcm_lib_preallocate_free_for_all - release all pre-allocated buffers on the pcm 98 * @pcm: the pcm instance 99 * 100 * Releases all the pre-allocated buffers on the given pcm. 101 */ 102 void snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm) 103 { 104 struct snd_pcm_substream *substream; 105 int stream; 106 107 for (stream = 0; stream < 2; stream++) 108 for (substream = pcm->streams[stream].substream; substream; substream = substream->next) 109 snd_pcm_lib_preallocate_free(substream); 110 } 111 EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all); 112 113 #ifdef CONFIG_SND_VERBOSE_PROCFS 114 /* 115 * read callback for prealloc proc file 116 * 117 * prints the current allocated size in kB. 118 */ 119 static void snd_pcm_lib_preallocate_proc_read(struct snd_info_entry *entry, 120 struct snd_info_buffer *buffer) 121 { 122 struct snd_pcm_substream *substream = entry->private_data; 123 snd_iprintf(buffer, "%lu\n", (unsigned long) substream->dma_buffer.bytes / 1024); 124 } 125 126 /* 127 * read callback for prealloc_max proc file 128 * 129 * prints the maximum allowed size in kB. 130 */ 131 static void snd_pcm_lib_preallocate_max_proc_read(struct snd_info_entry *entry, 132 struct snd_info_buffer *buffer) 133 { 134 struct snd_pcm_substream *substream = entry->private_data; 135 snd_iprintf(buffer, "%lu\n", (unsigned long) substream->dma_max / 1024); 136 } 137 138 /* 139 * write callback for prealloc proc file 140 * 141 * accepts the preallocation size in kB. 142 */ 143 static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry, 144 struct snd_info_buffer *buffer) 145 { 146 struct snd_pcm_substream *substream = entry->private_data; 147 char line[64], str[64]; 148 size_t size; 149 struct snd_dma_buffer new_dmab; 150 151 if (substream->runtime) { 152 buffer->error = -EBUSY; 153 return; 154 } 155 if (!snd_info_get_line(buffer, line, sizeof(line))) { 156 snd_info_get_str(str, line, sizeof(str)); 157 size = simple_strtoul(str, NULL, 10) * 1024; 158 if ((size != 0 && size < 8192) || size > substream->dma_max) { 159 buffer->error = -EINVAL; 160 return; 161 } 162 if (substream->dma_buffer.bytes == size) 163 return; 164 memset(&new_dmab, 0, sizeof(new_dmab)); 165 new_dmab.dev = substream->dma_buffer.dev; 166 if (size > 0) { 167 if (snd_dma_alloc_pages(substream->dma_buffer.dev.type, 168 substream->dma_buffer.dev.dev, 169 size, &new_dmab) < 0) { 170 buffer->error = -ENOMEM; 171 return; 172 } 173 substream->buffer_bytes_max = size; 174 } else { 175 substream->buffer_bytes_max = UINT_MAX; 176 } 177 if (substream->dma_buffer.area) 178 snd_dma_free_pages(&substream->dma_buffer); 179 substream->dma_buffer = new_dmab; 180 } else { 181 buffer->error = -EINVAL; 182 } 183 } 184 185 static inline void preallocate_info_init(struct snd_pcm_substream *substream) 186 { 187 struct snd_info_entry *entry; 188 189 entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", 190 substream->proc_root); 191 if (entry) { 192 snd_info_set_text_ops(entry, substream, 193 snd_pcm_lib_preallocate_proc_read); 194 entry->c.text.write = snd_pcm_lib_preallocate_proc_write; 195 entry->mode |= 0200; 196 } 197 entry = snd_info_create_card_entry(substream->pcm->card, "prealloc_max", 198 substream->proc_root); 199 if (entry) 200 snd_info_set_text_ops(entry, substream, 201 snd_pcm_lib_preallocate_max_proc_read); 202 } 203 204 #else /* !CONFIG_SND_VERBOSE_PROCFS */ 205 #define preallocate_info_init(s) 206 #endif /* CONFIG_SND_VERBOSE_PROCFS */ 207 208 /* 209 * pre-allocate the buffer and create a proc file for the substream 210 */ 211 static void snd_pcm_lib_preallocate_pages1(struct snd_pcm_substream *substream, 212 size_t size, size_t max) 213 { 214 215 if (size > 0 && preallocate_dma && substream->number < maximum_substreams) 216 preallocate_pcm_pages(substream, size); 217 218 if (substream->dma_buffer.bytes > 0) 219 substream->buffer_bytes_max = substream->dma_buffer.bytes; 220 substream->dma_max = max; 221 preallocate_info_init(substream); 222 } 223 224 225 /** 226 * snd_pcm_lib_preallocate_pages - pre-allocation for the given DMA type 227 * @substream: the pcm substream instance 228 * @type: DMA type (SNDRV_DMA_TYPE_*) 229 * @data: DMA type dependent data 230 * @size: the requested pre-allocation size in bytes 231 * @max: the max. allowed pre-allocation size 232 * 233 * Do pre-allocation for the given DMA buffer type. 234 */ 235 void snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream, 236 int type, struct device *data, 237 size_t size, size_t max) 238 { 239 substream->dma_buffer.dev.type = type; 240 substream->dma_buffer.dev.dev = data; 241 snd_pcm_lib_preallocate_pages1(substream, size, max); 242 } 243 EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages); 244 245 /** 246 * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continuous memory type (all substreams) 247 * @pcm: the pcm instance 248 * @type: DMA type (SNDRV_DMA_TYPE_*) 249 * @data: DMA type dependent data 250 * @size: the requested pre-allocation size in bytes 251 * @max: the max. allowed pre-allocation size 252 * 253 * Do pre-allocation to all substreams of the given pcm for the 254 * specified DMA type. 255 */ 256 void snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm, 257 int type, void *data, 258 size_t size, size_t max) 259 { 260 struct snd_pcm_substream *substream; 261 int stream; 262 263 for (stream = 0; stream < 2; stream++) 264 for (substream = pcm->streams[stream].substream; substream; substream = substream->next) 265 snd_pcm_lib_preallocate_pages(substream, type, data, size, max); 266 } 267 EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all); 268 269 #ifdef CONFIG_SND_DMA_SGBUF 270 /** 271 * snd_pcm_sgbuf_ops_page - get the page struct at the given offset 272 * @substream: the pcm substream instance 273 * @offset: the buffer offset 274 * 275 * Used as the page callback of PCM ops. 276 * 277 * Return: The page struct at the given buffer offset. %NULL on failure. 278 */ 279 struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset) 280 { 281 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); 282 283 unsigned int idx = offset >> PAGE_SHIFT; 284 if (idx >= (unsigned int)sgbuf->pages) 285 return NULL; 286 return sgbuf->page_table[idx]; 287 } 288 EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page); 289 #endif /* CONFIG_SND_DMA_SGBUF */ 290 291 /** 292 * snd_pcm_lib_malloc_pages - allocate the DMA buffer 293 * @substream: the substream to allocate the DMA buffer to 294 * @size: the requested buffer size in bytes 295 * 296 * Allocates the DMA buffer on the BUS type given earlier to 297 * snd_pcm_lib_preallocate_xxx_pages(). 298 * 299 * Return: 1 if the buffer is changed, 0 if not changed, or a negative 300 * code on failure. 301 */ 302 int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size) 303 { 304 struct snd_pcm_runtime *runtime; 305 struct snd_dma_buffer *dmab = NULL; 306 307 if (PCM_RUNTIME_CHECK(substream)) 308 return -EINVAL; 309 if (snd_BUG_ON(substream->dma_buffer.dev.type == 310 SNDRV_DMA_TYPE_UNKNOWN)) 311 return -EINVAL; 312 runtime = substream->runtime; 313 314 if (runtime->dma_buffer_p) { 315 /* perphaps, we might free the large DMA memory region 316 to save some space here, but the actual solution 317 costs us less time */ 318 if (runtime->dma_buffer_p->bytes >= size) { 319 runtime->dma_bytes = size; 320 return 0; /* ok, do not change */ 321 } 322 snd_pcm_lib_free_pages(substream); 323 } 324 if (substream->dma_buffer.area != NULL && 325 substream->dma_buffer.bytes >= size) { 326 dmab = &substream->dma_buffer; /* use the pre-allocated buffer */ 327 } else { 328 dmab = kzalloc(sizeof(*dmab), GFP_KERNEL); 329 if (! dmab) 330 return -ENOMEM; 331 dmab->dev = substream->dma_buffer.dev; 332 if (snd_dma_alloc_pages(substream->dma_buffer.dev.type, 333 substream->dma_buffer.dev.dev, 334 size, dmab) < 0) { 335 kfree(dmab); 336 return -ENOMEM; 337 } 338 } 339 snd_pcm_set_runtime_buffer(substream, dmab); 340 runtime->dma_bytes = size; 341 return 1; /* area was changed */ 342 } 343 EXPORT_SYMBOL(snd_pcm_lib_malloc_pages); 344 345 /** 346 * snd_pcm_lib_free_pages - release the allocated DMA buffer. 347 * @substream: the substream to release the DMA buffer 348 * 349 * Releases the DMA buffer allocated via snd_pcm_lib_malloc_pages(). 350 * 351 * Return: Zero if successful, or a negative error code on failure. 352 */ 353 int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream) 354 { 355 struct snd_pcm_runtime *runtime; 356 357 if (PCM_RUNTIME_CHECK(substream)) 358 return -EINVAL; 359 runtime = substream->runtime; 360 if (runtime->dma_area == NULL) 361 return 0; 362 if (runtime->dma_buffer_p != &substream->dma_buffer) { 363 /* it's a newly allocated buffer. release it now. */ 364 snd_dma_free_pages(runtime->dma_buffer_p); 365 kfree(runtime->dma_buffer_p); 366 } 367 snd_pcm_set_runtime_buffer(substream, NULL); 368 return 0; 369 } 370 EXPORT_SYMBOL(snd_pcm_lib_free_pages); 371 372 int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream, 373 size_t size, gfp_t gfp_flags) 374 { 375 struct snd_pcm_runtime *runtime; 376 377 if (PCM_RUNTIME_CHECK(substream)) 378 return -EINVAL; 379 runtime = substream->runtime; 380 if (runtime->dma_area) { 381 if (runtime->dma_bytes >= size) 382 return 0; /* already large enough */ 383 vfree(runtime->dma_area); 384 } 385 runtime->dma_area = __vmalloc(size, gfp_flags, PAGE_KERNEL); 386 if (!runtime->dma_area) 387 return -ENOMEM; 388 runtime->dma_bytes = size; 389 return 1; 390 } 391 EXPORT_SYMBOL(_snd_pcm_lib_alloc_vmalloc_buffer); 392 393 /** 394 * snd_pcm_lib_free_vmalloc_buffer - free vmalloc buffer 395 * @substream: the substream with a buffer allocated by 396 * snd_pcm_lib_alloc_vmalloc_buffer() 397 * 398 * Return: Zero if successful, or a negative error code on failure. 399 */ 400 int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream) 401 { 402 struct snd_pcm_runtime *runtime; 403 404 if (PCM_RUNTIME_CHECK(substream)) 405 return -EINVAL; 406 runtime = substream->runtime; 407 vfree(runtime->dma_area); 408 runtime->dma_area = NULL; 409 return 0; 410 } 411 EXPORT_SYMBOL(snd_pcm_lib_free_vmalloc_buffer); 412 413 /** 414 * snd_pcm_lib_get_vmalloc_page - map vmalloc buffer offset to page struct 415 * @substream: the substream with a buffer allocated by 416 * snd_pcm_lib_alloc_vmalloc_buffer() 417 * @offset: offset in the buffer 418 * 419 * This function is to be used as the page callback in the PCM ops. 420 * 421 * Return: The page struct, or %NULL on failure. 422 */ 423 struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, 424 unsigned long offset) 425 { 426 return vmalloc_to_page(substream->runtime->dma_area + offset); 427 } 428 EXPORT_SYMBOL(snd_pcm_lib_get_vmalloc_page); 429