aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/pcm_memory.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-07-30 09:13:33 -0400
committerJaroslav Kysela <perex@perex.cz>2008-08-25 03:57:38 -0400
commit51e9f2e665bf2b6a01be275d64c336d942c59a66 (patch)
tree75b79c23288a820eea6959e79060e3e4fb9d0eae /sound/core/pcm_memory.c
parent4e184f8fc06411f35fdcf4b9bc6187c857bf7214 (diff)
ALSA: Allocate larger pages in sgbuf
Most hardwares have limited buffer-descriptor table length. This also restricts the max buffer size of the sound driver. For example, snd-hda-intel has 1MB buffer size limit, and this is because it can have at most 256 BDL entries. For supporting larger buffers, we need to allocate larger pages even for sg-buffers. This patch changes the sgbuf allocation code to try to allocate larger pages first. At each head of the allocated pages, the number of allocated pages is stored in the lowest bits of the corresponding entry of the table addr field. This change isn't visible as long as the driver uses snd_sgbuf_get_addr() helper. Also, the patch adds a new function, snd_pcm_sgbuf_get_chunk_size(). This returns the size of the chunk on continuous pages starting at the given position offset. If the chunk reaches to a non-continuous page, it returns the size to the boundary. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/core/pcm_memory.c')
-rw-r--r--sound/core/pcm_memory.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index 859b1185e69a..a6d42808828c 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -324,6 +324,32 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne
324 324
325EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page); 325EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
326 326
327/*
328 * compute the max chunk size with continuous pages on sg-buffer
329 */
330unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
331 unsigned int ofs, unsigned int size)
332{
333 struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
334 unsigned int start, end, pg;
335
336 start = ofs >> PAGE_SHIFT;
337 end = (ofs + size - 1) >> PAGE_SHIFT;
338 /* check page continuity */
339 pg = sg->table[start].addr >> PAGE_SHIFT;
340 for (;;) {
341 start++;
342 if (start > end)
343 break;
344 pg++;
345 if ((sg->table[start].addr >> PAGE_SHIFT) != pg)
346 return (start << PAGE_SHIFT) - ofs;
347 }
348 /* ok, all on continuous pages */
349 return size;
350}
351EXPORT_SYMBOL(snd_pcm_sgbuf_get_chunk_size);
352
327/** 353/**
328 * snd_pcm_lib_malloc_pages - allocate the DMA buffer 354 * snd_pcm_lib_malloc_pages - allocate the DMA buffer
329 * @substream: the substream to allocate the DMA buffer to 355 * @substream: the substream to allocate the DMA buffer to