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 34static int preallocate_dma = 1; 35module_param(preallocate_dma, int, 0444); 36MODULE_PARM_DESC(preallocate_dma, "Preallocate DMA memory when the PCM devices are initialized."); 37 38static int maximum_substreams = 4; 39module_param(maximum_substreams, int, 0444); 40MODULE_PARM_DESC(maximum_substreams, "Maximum substreams with preallocated DMA memory."); 41 42static 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 */ 51static 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 */ 77static 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 * Return: Zero if successful, or a negative error code on failure. 92 */ 93int snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream) 94{ 95 snd_pcm_lib_preallocate_dma_free(substream); 96#ifdef CONFIG_SND_VERBOSE_PROCFS 97 snd_info_free_entry(substream->proc_prealloc_max_entry); 98 substream->proc_prealloc_max_entry = NULL; 99 snd_info_free_entry(substream->proc_prealloc_entry); 100 substream->proc_prealloc_entry = NULL; 101#endif 102 return 0; 103} 104 105/** 106 * snd_pcm_lib_preallocate_free_for_all - release all pre-allocated buffers on the pcm 107 * @pcm: the pcm instance 108 * 109 * Releases all the pre-allocated buffers on the given pcm. 110 * 111 * Return: Zero if successful, or a negative error code on failure. 112 */ 113int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm) 114{ 115 struct snd_pcm_substream *substream; 116 int stream; 117 118 for (stream = 0; stream < 2; stream++) 119 for (substream = pcm->streams[stream].substream; substream; substream = substream->next) 120 snd_pcm_lib_preallocate_free(substream); 121 return 0; 122} 123 124EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all); 125 126#ifdef CONFIG_SND_VERBOSE_PROCFS 127/* 128 * read callback for prealloc proc file 129 * 130 * prints the current allocated size in kB. 131 */ 132static void snd_pcm_lib_preallocate_proc_read(struct snd_info_entry *entry, 133 struct snd_info_buffer *buffer) 134{ 135 struct snd_pcm_substream *substream = entry->private_data; 136 snd_iprintf(buffer, "%lu\n", (unsigned long) substream->dma_buffer.bytes / 1024); 137} 138 139/* 140 * read callback for prealloc_max proc file 141 * 142 * prints the maximum allowed size in kB. 143 */ 144static void snd_pcm_lib_preallocate_max_proc_read(struct snd_info_entry *entry, 145 struct snd_info_buffer *buffer) 146{ 147 struct snd_pcm_substream *substream = entry->private_data; 148 snd_iprintf(buffer, "%lu\n", (unsigned long) substream->dma_max / 1024); 149} 150 151/* 152 * write callback for prealloc proc file 153 * 154 * accepts the preallocation size in kB. 155 */ 156static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry, 157 struct snd_info_buffer *buffer) 158{ 159 struct snd_pcm_substream *substream = entry->private_data; 160 char line[64], str[64]; 161 size_t size; 162 struct snd_dma_buffer new_dmab; 163 164 if (substream->runtime) { 165 buffer->error = -EBUSY; 166 return; 167 } 168 if (!snd_info_get_line(buffer, line, sizeof(line))) { 169 snd_info_get_str(str, line, sizeof(str)); 170 size = simple_strtoul(str, NULL, 10) * 1024; 171 if ((size != 0 && size < 8192) || size > substream->dma_max) { 172 buffer->error = -EINVAL; 173 return; 174 } 175 if (substream->dma_buffer.bytes == size) 176 return; 177 memset(&new_dmab, 0, sizeof(new_dmab)); 178 new_dmab.dev = substream->dma_buffer.dev; 179 if (size > 0) { 180 if (snd_dma_alloc_pages(substream->dma_buffer.dev.type, 181 substream->dma_buffer.dev.dev, 182 size, &new_dmab) < 0) { 183 buffer->error = -ENOMEM; 184 return; 185 } 186 substream->buffer_bytes_max = size; 187 } else { 188 substream->buffer_bytes_max = UINT_MAX; 189 } 190 if (substream->dma_buffer.area) 191 snd_dma_free_pages(&substream->dma_buffer); 192 substream->dma_buffer = new_dmab; 193 } else { 194 buffer->error = -EINVAL; 195 } 196} 197 198static inline void preallocate_info_init(struct snd_pcm_substream *substream) 199{ 200 struct snd_info_entry *entry; 201 202 if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) { 203 entry->c.text.read = snd_pcm_lib_preallocate_proc_read; 204 entry->c.text.write = snd_pcm_lib_preallocate_proc_write; 205 entry->mode |= S_IWUSR; 206 entry->private_data = substream; 207 if (snd_info_register(entry) < 0) { 208 snd_info_free_entry(entry); 209 entry = NULL; 210 } 211 } 212 substream->proc_prealloc_entry = entry; 213 if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc_max", substream->proc_root)) != NULL) { 214 entry->c.text.read = snd_pcm_lib_preallocate_max_proc_read; 215 entry->private_data = substream; 216 if (snd_info_register(entry) < 0) { 217 snd_info_free_entry(entry); 218 entry = NULL; 219 } 220 } 221 substream->proc_prealloc_max_entry = entry; 222} 223 224#else /* !CONFIG_SND_VERBOSE_PROCFS */ 225#define preallocate_info_init(s) 226#endif /* CONFIG_SND_VERBOSE_PROCFS */ 227 228/* 229 * pre-allocate the buffer and create a proc file for the substream 230 */ 231static int snd_pcm_lib_preallocate_pages1(struct snd_pcm_substream *substream, 232 size_t size, size_t max) 233{ 234 235 if (size > 0 && preallocate_dma && substream->number < maximum_substreams) 236 preallocate_pcm_pages(substream, size); 237 238 if (substream->dma_buffer.bytes > 0) 239 substream->buffer_bytes_max = substream->dma_buffer.bytes; 240 substream->dma_max = max; 241 preallocate_info_init(substream); 242 return 0; 243} 244 245 246/** 247 * snd_pcm_lib_preallocate_pages - pre-allocation for the given DMA type 248 * @substream: the pcm substream instance 249 * @type: DMA type (SNDRV_DMA_TYPE_*) 250 * @data: DMA type dependent data 251 * @size: the requested pre-allocation size in bytes 252 * @max: the max. allowed pre-allocation size 253 * 254 * Do pre-allocation for the given DMA buffer type. 255 * 256 * Return: Zero if successful, or a negative error code on failure. 257 */ 258int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream, 259 int type, struct device *data, 260 size_t size, size_t max) 261{ 262 substream->dma_buffer.dev.type = type; 263 substream->dma_buffer.dev.dev = data; 264 return snd_pcm_lib_preallocate_pages1(substream, size, max); 265} 266 267EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages); 268 269/** 270 * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continuous memory type (all substreams) 271 * @pcm: the pcm instance 272 * @type: DMA type (SNDRV_DMA_TYPE_*) 273 * @data: DMA type dependent data 274 * @size: the requested pre-allocation size in bytes 275 * @max: the max. allowed pre-allocation size 276 * 277 * Do pre-allocation to all substreams of the given pcm for the 278 * specified DMA type. 279 * 280 * Return: Zero if successful, or a negative error code on failure. 281 */ 282int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm, 283 int type, void *data, 284 size_t size, size_t max) 285{ 286 struct snd_pcm_substream *substream; 287 int stream, err; 288 289 for (stream = 0; stream < 2; stream++) 290 for (substream = pcm->streams[stream].substream; substream; substream = substream->next) 291 if ((err = snd_pcm_lib_preallocate_pages(substream, type, data, size, max)) < 0) 292 return err; 293 return 0; 294} 295 296EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all); 297 298#ifdef CONFIG_SND_DMA_SGBUF 299/** 300 * snd_pcm_sgbuf_ops_page - get the page struct at the given offset 301 * @substream: the pcm substream instance 302 * @offset: the buffer offset 303 * 304 * Used as the page callback of PCM ops. 305 * 306 * Return: The page struct at the given buffer offset. %NULL on failure. 307 */ 308struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset) 309{ 310 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); 311 312 unsigned int idx = offset >> PAGE_SHIFT; 313 if (idx >= (unsigned int)sgbuf->pages) 314 return NULL; 315 return sgbuf->page_table[idx]; 316} 317 318EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page); 319#endif /* CONFIG_SND_DMA_SGBUF */ 320 321/** 322 * snd_pcm_lib_malloc_pages - allocate the DMA buffer 323 * @substream: the substream to allocate the DMA buffer to 324 * @size: the requested buffer size in bytes 325 * 326 * Allocates the DMA buffer on the BUS type given earlier to 327 * snd_pcm_lib_preallocate_xxx_pages(). 328 * 329 * Return: 1 if the buffer is changed, 0 if not changed, or a negative 330 * code on failure. 331 */ 332int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size) 333{ 334 struct snd_pcm_runtime *runtime; 335 struct snd_dma_buffer *dmab = NULL; 336 337 if (PCM_RUNTIME_CHECK(substream)) 338 return -EINVAL; 339 if (snd_BUG_ON(substream->dma_buffer.dev.type == 340 SNDRV_DMA_TYPE_UNKNOWN)) 341 return -EINVAL; 342 runtime = substream->runtime; 343 344 if (runtime->dma_buffer_p) { 345 /* perphaps, we might free the large DMA memory region 346 to save some space here, but the actual solution 347 costs us less time */ 348 if (runtime->dma_buffer_p->bytes >= size) { 349 runtime->dma_bytes = size; 350 return 0; /* ok, do not change */ 351 } 352 snd_pcm_lib_free_pages(substream); 353 } 354 if (substream->dma_buffer.area != NULL && 355 substream->dma_buffer.bytes >= size) { 356 dmab = &substream->dma_buffer; /* use the pre-allocated buffer */ 357 } else { 358 dmab = kzalloc(sizeof(*dmab), GFP_KERNEL); 359 if (! dmab) 360 return -ENOMEM; 361 dmab->dev = substream->dma_buffer.dev; 362 if (snd_dma_alloc_pages(substream->dma_buffer.dev.type, 363 substream->dma_buffer.dev.dev, 364 size, dmab) < 0) { 365 kfree(dmab); 366 return -ENOMEM; 367 } 368 } 369 snd_pcm_set_runtime_buffer(substream, dmab); 370 runtime->dma_bytes = size; 371 return 1; /* area was changed */ 372} 373 374EXPORT_SYMBOL(snd_pcm_lib_malloc_pages); 375 376/** 377 * snd_pcm_lib_free_pages - release the allocated DMA buffer. 378 * @substream: the substream to release the DMA buffer 379 * 380 * Releases the DMA buffer allocated via snd_pcm_lib_malloc_pages(). 381 * 382 * Return: Zero if successful, or a negative error code on failure. 383 */ 384int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream) 385{ 386 struct snd_pcm_runtime *runtime; 387 388 if (PCM_RUNTIME_CHECK(substream)) 389 return -EINVAL; 390 runtime = substream->runtime; 391 if (runtime->dma_area == NULL) 392 return 0; 393 if (runtime->dma_buffer_p != &substream->dma_buffer) { 394 /* it's a newly allocated buffer. release it now. */ 395 snd_dma_free_pages(runtime->dma_buffer_p); 396 kfree(runtime->dma_buffer_p); 397 } 398 snd_pcm_set_runtime_buffer(substream, NULL); 399 return 0; 400} 401 402EXPORT_SYMBOL(snd_pcm_lib_free_pages); 403 404int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream, 405 size_t size, gfp_t gfp_flags) 406{ 407 struct snd_pcm_runtime *runtime; 408 409 if (PCM_RUNTIME_CHECK(substream)) 410 return -EINVAL; 411 runtime = substream->runtime; 412 if (runtime->dma_area) { 413 if (runtime->dma_bytes >= size) 414 return 0; /* already large enough */ 415 vfree(runtime->dma_area); 416 } 417 runtime->dma_area = __vmalloc(size, gfp_flags, PAGE_KERNEL); 418 if (!runtime->dma_area) 419 return -ENOMEM; 420 runtime->dma_bytes = size; 421 return 1; 422} 423EXPORT_SYMBOL(_snd_pcm_lib_alloc_vmalloc_buffer); 424 425/** 426 * snd_pcm_lib_free_vmalloc_buffer - free vmalloc buffer 427 * @substream: the substream with a buffer allocated by 428 * snd_pcm_lib_alloc_vmalloc_buffer() 429 * 430 * Return: Zero if successful, or a negative error code on failure. 431 */ 432int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream) 433{ 434 struct snd_pcm_runtime *runtime; 435 436 if (PCM_RUNTIME_CHECK(substream)) 437 return -EINVAL; 438 runtime = substream->runtime; 439 vfree(runtime->dma_area); 440 runtime->dma_area = NULL; 441 return 0; 442} 443EXPORT_SYMBOL(snd_pcm_lib_free_vmalloc_buffer); 444 445/** 446 * snd_pcm_lib_get_vmalloc_page - map vmalloc buffer offset to page struct 447 * @substream: the substream with a buffer allocated by 448 * snd_pcm_lib_alloc_vmalloc_buffer() 449 * @offset: offset in the buffer 450 * 451 * This function is to be used as the page callback in the PCM ops. 452 * 453 * Return: The page struct, or %NULL on failure. 454 */ 455struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, 456 unsigned long offset) 457{ 458 return vmalloc_to_page(substream->runtime->dma_area + offset); 459} 460EXPORT_SYMBOL(snd_pcm_lib_get_vmalloc_page); 461