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