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