ALSA: Make snd_sgbuf_get_{ptr|addr}() available for non-SG cases
[sfrench/cifs-2.6.git] / sound / core / sgbuf.c
index d0f00356fc115a32db23bc8475f08a6aad178c47..0a418503ec412c61e22da5ac31ddac96e6e436a4 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 #include <sound/memalloc.h>
 
 
@@ -136,3 +137,29 @@ void *snd_malloc_sgbuf_pages(struct device *device,
        snd_free_sgbuf_pages(dmab); /* free the table */
        return NULL;
 }
+
+/*
+ * compute the max chunk size with continuous pages on sg-buffer
+ */
+unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
+                                     unsigned int ofs, unsigned int size)
+{
+       struct snd_sg_buf *sg = dmab->private_data;
+       unsigned int start, end, pg;
+
+       start = ofs >> PAGE_SHIFT;
+       end = (ofs + size - 1) >> PAGE_SHIFT;
+       /* check page continuity */
+       pg = sg->table[start].addr >> PAGE_SHIFT;
+       for (;;) {
+               start++;
+               if (start > end)
+                       break;
+               pg++;
+               if ((sg->table[start].addr >> PAGE_SHIFT) != pg)
+                       return (start << PAGE_SHIFT) - ofs;
+       }
+       /* ok, all on continuous pages */
+       return size;
+}
+EXPORT_SYMBOL(snd_sgbuf_get_chunk_size);