2 * helper functions for vmalloc video4linux capture buffers
4 * The functions expect the hardware being able to scatter gatter
5 * (i.e. the buffers are not linear in physical memory, but fragmented
6 * into PAGE_SIZE chunks). They also assume the driver does not need
7 * to touch the video data.
9 * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2
16 #include <linux/init.h>
17 #include <linux/module.h>
18 #include <linux/moduleparam.h>
19 #include <linux/slab.h>
20 #include <linux/interrupt.h>
22 #include <linux/pci.h>
23 #include <linux/vmalloc.h>
24 #include <linux/pagemap.h>
26 #include <asm/pgtable.h>
28 #include <media/videobuf-vmalloc.h>
30 #define MAGIC_DMABUF 0x17760309
31 #define MAGIC_VMAL_MEM 0x18221223
33 #define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \
34 { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); }
37 module_param(debug
, int, 0644);
39 MODULE_DESCRIPTION("helper module to manage video4linux vmalloc buffers");
40 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
41 MODULE_LICENSE("GPL");
43 #define dprintk(level, fmt, arg...) if (debug >= level) \
44 printk(KERN_DEBUG "vbuf-vmalloc: " fmt , ## arg)
47 /***************************************************************************/
50 videobuf_vm_open(struct vm_area_struct
*vma
)
52 struct videobuf_mapping
*map
= vma
->vm_private_data
;
54 dprintk(2,"vm_open %p [count=%u,vma=%08lx-%08lx]\n",map
,
55 map
->count
,vma
->vm_start
,vma
->vm_end
);
60 static void videobuf_vm_close(struct vm_area_struct
*vma
)
62 struct videobuf_mapping
*map
= vma
->vm_private_data
;
63 struct videobuf_queue
*q
= map
->q
;
66 dprintk(2,"vm_close %p [count=%u,vma=%08lx-%08lx]\n", map
,
67 map
->count
, vma
->vm_start
, vma
->vm_end
);
70 if (0 == map
->count
) {
71 struct videobuf_vmalloc_memory
*mem
;
73 dprintk(1, "munmap %p q=%p\n", map
, q
);
74 mutex_lock(&q
->vb_lock
);
76 /* We need first to cancel streams, before unmapping */
78 videobuf_queue_cancel(q
);
80 for (i
= 0; i
< VIDEO_MAX_FRAME
; i
++) {
81 if (NULL
== q
->bufs
[i
])
84 if (q
->bufs
[i
]->map
!= map
)
87 mem
= q
->bufs
[i
]->priv
;
89 /* This callback is called only if kernel has
90 allocated memory and this memory is mmapped.
91 In this case, memory should be freed,
92 in order to do memory unmap.
95 MAGIC_CHECK(mem
->magic
, MAGIC_VMAL_MEM
);
97 /* vfree is not atomic - can't be
98 called with IRQ's disabled
100 dprintk(1, "%s: buf[%d] freeing (%p)\n",
101 __func__
, i
, mem
->vmalloc
);
107 q
->bufs
[i
]->map
= NULL
;
108 q
->bufs
[i
]->baddr
= 0;
113 mutex_unlock(&q
->vb_lock
);
119 static struct vm_operations_struct videobuf_vm_ops
=
121 .open
= videobuf_vm_open
,
122 .close
= videobuf_vm_close
,
125 /* ---------------------------------------------------------------------
126 * vmalloc handlers for the generic methods
129 /* Allocated area consists on 3 parts:
131 struct <driver>_buffer (cx88_buffer, saa7134_buf, ...)
132 struct videobuf_dma_sg_memory
135 static void *__videobuf_alloc(size_t size
)
137 struct videobuf_vmalloc_memory
*mem
;
138 struct videobuf_buffer
*vb
;
140 vb
= kzalloc(size
+sizeof(*mem
),GFP_KERNEL
);
142 mem
= vb
->priv
= ((char *)vb
)+size
;
143 mem
->magic
=MAGIC_VMAL_MEM
;
145 dprintk(1,"%s: allocated at %p(%ld+%ld) & %p(%ld)\n",
146 __func__
,vb
,(long)sizeof(*vb
),(long)size
-sizeof(*vb
),
147 mem
,(long)sizeof(*mem
));
152 static int __videobuf_iolock (struct videobuf_queue
* q
,
153 struct videobuf_buffer
*vb
,
154 struct v4l2_framebuffer
*fbuf
)
156 struct videobuf_vmalloc_memory
*mem
= vb
->priv
;
161 MAGIC_CHECK(mem
->magic
, MAGIC_VMAL_MEM
);
163 switch (vb
->memory
) {
164 case V4L2_MEMORY_MMAP
:
165 dprintk(1, "%s memory method MMAP\n", __func__
);
167 /* All handling should be done by __videobuf_mmap_mapper() */
169 printk(KERN_ERR
"memory is not alloced/mmapped.\n");
173 case V4L2_MEMORY_USERPTR
:
174 pages
= PAGE_ALIGN(vb
->size
);
176 dprintk(1, "%s memory method USERPTR\n", __func__
);
180 printk(KERN_ERR
"USERPTR is currently not supported\n");
185 /* The only USERPTR currently supported is the one needed for
189 mem
->vmalloc
= vmalloc_user(pages
);
191 printk(KERN_ERR
"vmalloc (%d pages) failed\n", pages
);
194 dprintk(1, "vmalloc is at addr %p (%d pages)\n",
195 mem
->vmalloc
, pages
);
199 /* Kernel userptr is used also by read() method. In this case,
200 there's no need to remap, since data will be copied to user
205 /* FIXME: to properly support USERPTR, remap should occur.
206 The code bellow won't work, since mem->vma = NULL
208 /* Try to remap memory */
209 rc
= remap_vmalloc_range(mem
->vma
, (void *)vb
->baddr
, 0);
211 printk(KERN_ERR
"mmap: remap failed with error %d. ", rc
);
217 case V4L2_MEMORY_OVERLAY
:
219 dprintk(1, "%s memory method OVERLAY/unknown\n", __func__
);
221 /* Currently, doesn't support V4L2_MEMORY_OVERLAY */
222 printk(KERN_ERR
"Memory method currently unsupported.\n");
229 static int __videobuf_sync(struct videobuf_queue
*q
,
230 struct videobuf_buffer
*buf
)
235 static int __videobuf_mmap_free(struct videobuf_queue
*q
)
239 dprintk(1, "%s\n", __func__
);
240 for (i
= 0; i
< VIDEO_MAX_FRAME
; i
++) {
250 static int __videobuf_mmap_mapper(struct videobuf_queue
*q
,
251 struct vm_area_struct
*vma
)
253 struct videobuf_vmalloc_memory
*mem
;
254 struct videobuf_mapping
*map
;
257 unsigned long offset
= vma
->vm_pgoff
<< PAGE_SHIFT
;
259 dprintk(1, "%s\n", __func__
);
260 if (!(vma
->vm_flags
& VM_WRITE
) || !(vma
->vm_flags
& VM_SHARED
))
263 /* look for first buffer to map */
264 for (first
= 0; first
< VIDEO_MAX_FRAME
; first
++) {
265 if (NULL
== q
->bufs
[first
])
268 if (V4L2_MEMORY_MMAP
!= q
->bufs
[first
]->memory
)
270 if (q
->bufs
[first
]->boff
== offset
)
273 if (VIDEO_MAX_FRAME
== first
) {
274 dprintk(1,"mmap app bug: offset invalid [offset=0x%lx]\n",
275 (vma
->vm_pgoff
<< PAGE_SHIFT
));
279 /* create mapping + update buffer list */
280 map
= kzalloc(sizeof(struct videobuf_mapping
), GFP_KERNEL
);
284 q
->bufs
[first
]->map
= map
;
285 map
->start
= vma
->vm_start
;
286 map
->end
= vma
->vm_end
;
289 q
->bufs
[first
]->baddr
= vma
->vm_start
;
291 mem
= q
->bufs
[first
]->priv
;
293 MAGIC_CHECK(mem
->magic
, MAGIC_VMAL_MEM
);
295 pages
= PAGE_ALIGN(vma
->vm_end
- vma
->vm_start
);
296 mem
->vmalloc
= vmalloc_user(pages
);
298 printk(KERN_ERR
"vmalloc (%d pages) failed\n", pages
);
301 dprintk(1, "vmalloc is at addr %p (%d pages)\n",
302 mem
->vmalloc
, pages
);
304 /* Try to remap memory */
305 retval
= remap_vmalloc_range(vma
, mem
->vmalloc
, 0);
307 printk(KERN_ERR
"mmap: remap failed with error %d. ", retval
);
312 vma
->vm_ops
= &videobuf_vm_ops
;
313 vma
->vm_flags
|= VM_DONTEXPAND
| VM_RESERVED
;
314 vma
->vm_private_data
= map
;
316 dprintk(1,"mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
317 map
, q
, vma
->vm_start
, vma
->vm_end
,
318 (long int) q
->bufs
[first
]->bsize
,
319 vma
->vm_pgoff
, first
);
321 videobuf_vm_open(vma
);
331 static int __videobuf_copy_to_user ( struct videobuf_queue
*q
,
332 char __user
*data
, size_t count
,
335 struct videobuf_vmalloc_memory
*mem
=q
->read_buf
->priv
;
337 MAGIC_CHECK(mem
->magic
,MAGIC_VMAL_MEM
);
339 BUG_ON (!mem
->vmalloc
);
341 /* copy to userspace */
342 if (count
> q
->read_buf
->size
- q
->read_off
)
343 count
= q
->read_buf
->size
- q
->read_off
;
345 if (copy_to_user(data
, mem
->vmalloc
+q
->read_off
, count
))
351 static int __videobuf_copy_stream ( struct videobuf_queue
*q
,
352 char __user
*data
, size_t count
, size_t pos
,
353 int vbihack
, int nonblocking
)
356 struct videobuf_vmalloc_memory
*mem
=q
->read_buf
->priv
;
358 MAGIC_CHECK(mem
->magic
,MAGIC_VMAL_MEM
);
361 /* dirty, undocumented hack -- pass the frame counter
362 * within the last four bytes of each vbi data block.
363 * We need that one to maintain backward compatibility
364 * to all vbi decoding software out there ... */
365 fc
= (unsigned int*)mem
->vmalloc
;
366 fc
+= (q
->read_buf
->size
>>2) -1;
367 *fc
= q
->read_buf
->field_count
>> 1;
368 dprintk(1,"vbihack: %d\n",*fc
);
371 /* copy stuff using the common method */
372 count
= __videobuf_copy_to_user (q
,data
,count
,nonblocking
);
374 if ( (count
==-EFAULT
) && (0 == pos
) )
380 static struct videobuf_qtype_ops qops
= {
381 .magic
= MAGIC_QTYPE_OPS
,
383 .alloc
= __videobuf_alloc
,
384 .iolock
= __videobuf_iolock
,
385 .sync
= __videobuf_sync
,
386 .mmap_free
= __videobuf_mmap_free
,
387 .mmap_mapper
= __videobuf_mmap_mapper
,
388 .video_copy_to_user
= __videobuf_copy_to_user
,
389 .copy_stream
= __videobuf_copy_stream
,
390 .vmalloc
= videobuf_to_vmalloc
,
393 void videobuf_queue_vmalloc_init(struct videobuf_queue
* q
,
394 struct videobuf_queue_ops
*ops
,
397 enum v4l2_buf_type type
,
398 enum v4l2_field field
,
402 videobuf_queue_core_init(q
, ops
, dev
, irqlock
, type
, field
, msize
,
406 EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init
);
408 void *videobuf_to_vmalloc (struct videobuf_buffer
*buf
)
410 struct videobuf_vmalloc_memory
*mem
=buf
->priv
;
412 MAGIC_CHECK(mem
->magic
,MAGIC_VMAL_MEM
);
416 EXPORT_SYMBOL_GPL(videobuf_to_vmalloc
);
418 void videobuf_vmalloc_free (struct videobuf_buffer
*buf
)
420 struct videobuf_vmalloc_memory
*mem
= buf
->priv
;
422 /* mmapped memory can't be freed here, otherwise mmapped region
423 would be released, while still needed. In this case, the memory
424 release should happen inside videobuf_vm_close().
425 So, it should free memory only if the memory were allocated for
428 if ((buf
->memory
!= V4L2_MEMORY_USERPTR
) || (buf
->baddr
== 0))
434 MAGIC_CHECK(mem
->magic
, MAGIC_VMAL_MEM
);
441 EXPORT_SYMBOL_GPL(videobuf_vmalloc_free
);