22 #include <linux/module.h>
24 #include <linux/sched.h>
25 #include <linux/slab.h>
33 #include <asm/pgtable.h>
37 #define MAGIC_DMABUF 0x19721112
38 #define MAGIC_SG_MEM 0x17890714
40 #define MAGIC_CHECK(is, should) \
41 if (unlikely((is) != (should))) { \
42 printk(KERN_ERR "magic mismatch: %x (expected %x)\n", \
54 #define dprintk(level, fmt, arg...) \
56 printk(KERN_DEBUG "vbuf-sg: " fmt , ## arg)
65 static struct scatterlist *videobuf_vmalloc_to_sg(
unsigned char *virt,
72 sglist =
vzalloc(nr_pages *
sizeof(*sglist));
76 for (i = 0; i < nr_pages; i++, virt +=
PAGE_SIZE) {
81 sg_set_page(&sglist[i], pg,
PAGE_SIZE, 0);
101 if (
NULL == pages[0])
103 sglist =
vmalloc(nr_pages *
sizeof(*sglist));
108 if (PageHighMem(pages[0]))
111 sg_set_page(&sglist[0], pages[0],
114 for (i = 1; i < nr_pages; i++) {
115 if (
NULL == pages[i])
117 if (PageHighMem(pages[i]))
119 sg_set_page(&sglist[i], pages[i],
min_t(
size_t,
PAGE_SIZE, size), 0);
125 dprintk(2,
"sgl: oops - no page\n");
130 dprintk(2,
"sgl: oops - highmem page\n");
150 memset(dma, 0,
sizeof(*dma));
182 dprintk(1,
"init user [0x%lx+0x%lx => %d pages]\n",
191 dma->
nr_pages = (err >= 0) ? err : 0;
193 return err < 0 ? err : -
EINVAL;
199 unsigned long data,
unsigned long size)
204 ret = videobuf_dma_init_user_locked(dma, direction, data, size);
214 dprintk(1,
"init kernel [%d pages]\n", nr_pages);
219 dprintk(1,
"vmalloc_32(%d pages) failed\n", nr_pages);
223 dprintk(1,
"vmalloc is at addr 0x%08lx, size=%d\n",
224 (
unsigned long)dma->
vaddr,
237 dprintk(1,
"init overlay [%d pages @ bus 0x%lx]\n",
238 nr_pages, (
unsigned long)addr);
275 dprintk(1,
"scatterlist is NULL\n");
281 if (0 == dma->
sglen) {
283 "%s: videobuf_map_sg failed\n", __func__);
342 dprintk(2,
"vm_open %p [count=%d,vma=%08lx-%08lx]\n", map,
355 dprintk(2,
"vm_close %p [count=%d,vma=%08lx-%08lx]\n", map,
359 if (0 == map->
count) {
360 dprintk(1,
"munmap %p q=%p\n", map, q);
361 videobuf_queue_lock(q);
365 mem = q->
bufs[
i]->priv;
371 if (q->
bufs[i]->map != map)
374 q->
bufs[
i]->baddr = 0;
375 q->
ops->buf_release(q, q->
bufs[i]);
377 videobuf_queue_unlock(q);
389 static int videobuf_vm_fault(
struct vm_area_struct *vma,
struct vm_fault *vmf)
393 dprintk(3,
"fault: fault @ %08lx [vma %08lx-%08lx]\n",
394 (
unsigned long)vmf->virtual_address,
406 static const struct vm_operations_struct videobuf_vm_ops = {
407 .open = videobuf_vm_open,
408 .close = videobuf_vm_close,
409 .fault = videobuf_vm_fault,
427 vb = kzalloc(size +
sizeof(*mem),
GFP_KERNEL);
431 mem = vb->
priv = ((
char *)vb) +
size;
436 dprintk(1,
"%s: allocated at %p(%ld+%ld) & %p(%ld)\n",
437 __func__, vb, (
long)
sizeof(*vb), (
long)size -
sizeof(*vb),
438 mem, (
long)
sizeof(*mem));
450 return mem->
dma.vaddr;
467 if (0 == vb->
baddr) {
488 err = videobuf_dma_init_user_locked(&mem->
dma,
531 mem->
dma.sglen, mem->
dma.direction);
542 unsigned int first, last, size = 0,
i;
552 if (buf == q->
bufs[first]) {
560 dprintk(1,
"mmap app bug: offset invalid [offset=0x%lx]\n",
574 for (i = first; i <= last; i++) {
584 vma->
vm_ops = &videobuf_vm_ops;
585 vma->
vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
588 dprintk(1,
"mmap %p: q=%p %08lx-%08lx pgoff %08lx bufs %d-%d\n",
599 .alloc_vb = __videobuf_alloc_vb,
600 .iolock = __videobuf_iolock,
601 .sync = __videobuf_sync,
602 .mmap_mapper = __videobuf_mmap_mapper,
603 .vaddr = __videobuf_to_vaddr,
630 priv, &sg_ops, ext_lock);