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 <asm/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 * Return: Zero if successful, or a negative error code on failure. 92 */ 93 int 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 */ 113 int 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 124 EXPORT_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 */ 132 static 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 */ 144 static 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 */ 156 static 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 198 static 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 */ 231 static 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 */ 258 int 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 267 EXPORT_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 */ 282 int 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 296 EXPORT_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 */ 308 struct 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 318 EXPORT_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 */ 332 int 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 374 EXPORT_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 */ 384 int 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 402 EXPORT_SYMBOL(snd_pcm_lib_free_pages); 403 404 int _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 } 423 EXPORT_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 */ 432 int 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 } 443 EXPORT_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 */ 455 struct 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 } 460 EXPORT_SYMBOL(snd_pcm_lib_get_vmalloc_page); 461