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);
75 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
76 if (NULL == q->bufs[i])
79 if (q->bufs[i]->map != map)
82 mem = q->bufs[i]->priv;
84 /* This callback is called only if kernel has
85 allocated memory and this memory is mmapped.
86 In this case, memory should be freed,
87 in order to do memory unmap.
89 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
94 q->bufs[i]->map = NULL;
95 q->bufs[i]->baddr = 0;
97 mutex_unlock(&q->vb_lock);
103 static struct vm_operations_struct videobuf_vm_ops =
105 .open = videobuf_vm_open,
106 .close = videobuf_vm_close,
109 /* ---------------------------------------------------------------------
110 * vmalloc handlers for the generic methods
113 /* Allocated area consists on 3 parts:
115 struct <driver>_buffer (cx88_buffer, saa7134_buf, ...)
116 struct videobuf_dma_sg_memory
119 static void *__videobuf_alloc(size_t size)
121 struct videobuf_vmalloc_memory *mem;
122 struct videobuf_buffer *vb;
124 vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
126 mem = vb->priv = ((char *)vb)+size;
127 mem->magic=MAGIC_VMAL_MEM;
129 dprintk(1,"%s: allocated at %p(%ld+%ld) & %p(%ld)\n",
130 __func__,vb,(long)sizeof(*vb),(long)size-sizeof(*vb),
131 mem,(long)sizeof(*mem));
136 static int __videobuf_iolock (struct videobuf_queue* q,
137 struct videobuf_buffer *vb,
138 struct v4l2_framebuffer *fbuf)
140 struct videobuf_vmalloc_memory *mem = vb->priv;
144 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
146 switch (vb->memory) {
147 case V4L2_MEMORY_MMAP:
148 dprintk(1, "%s memory method MMAP\n", __func__);
150 /* All handling should be done by __videobuf_mmap_mapper() */
152 printk(KERN_ERR "memory is not alloced/mmapped.\n");
156 case V4L2_MEMORY_USERPTR:
158 int pages = PAGE_ALIGN(vb->size);
160 dprintk(1, "%s memory method USERPTR\n", __func__);
164 printk(KERN_ERR "USERPTR is currently not supported\n");
169 /* The only USERPTR currently supported is the one needed for
173 mem->vmalloc = vmalloc_user(pages);
175 printk(KERN_ERR "vmalloc (%d pages) failed\n", pages);
178 dprintk(1, "vmalloc is at addr %p (%d pages)\n",
179 mem->vmalloc, pages);
183 /* Kernel userptr is used also by read() method. In this case,
184 there's no need to remap, since data will be copied to user
189 /* FIXME: to properly support USERPTR, remap should occur.
190 The code bellow won't work, since mem->vma = NULL
192 /* Try to remap memory */
193 rc = remap_vmalloc_range(mem->vma, (void *)vb->baddr, 0);
195 printk(KERN_ERR "mmap: remap failed with error %d. ", rc);
202 case V4L2_MEMORY_OVERLAY:
204 dprintk(1, "%s memory method OVERLAY/unknown\n", __func__);
206 /* Currently, doesn't support V4L2_MEMORY_OVERLAY */
207 printk(KERN_ERR "Memory method currently unsupported.\n");
214 static int __videobuf_sync(struct videobuf_queue *q,
215 struct videobuf_buffer *buf)
220 static int __videobuf_mmap_free(struct videobuf_queue *q)
224 dprintk(1, "%s\n", __func__);
225 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
235 static int __videobuf_mmap_mapper(struct videobuf_queue *q,
236 struct vm_area_struct *vma)
238 struct videobuf_vmalloc_memory *mem;
239 struct videobuf_mapping *map;
242 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
244 dprintk(1, "%s\n", __func__);
245 if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
248 /* look for first buffer to map */
249 for (first = 0; first < VIDEO_MAX_FRAME; first++) {
250 if (NULL == q->bufs[first])
253 if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
255 if (q->bufs[first]->boff == offset)
258 if (VIDEO_MAX_FRAME == first) {
259 dprintk(1,"mmap app bug: offset invalid [offset=0x%lx]\n",
260 (vma->vm_pgoff << PAGE_SHIFT));
264 /* create mapping + update buffer list */
265 map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
269 q->bufs[first]->map = map;
270 map->start = vma->vm_start;
271 map->end = vma->vm_end;
274 q->bufs[first]->baddr = vma->vm_start;
276 mem = q->bufs[first]->priv;
278 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
280 pages = PAGE_ALIGN(vma->vm_end - vma->vm_start);
281 mem->vmalloc = vmalloc_user(pages);
283 printk(KERN_ERR "vmalloc (%d pages) failed\n", pages);
286 dprintk(1, "vmalloc is at addr %p (%d pages)\n",
287 mem->vmalloc, pages);
289 /* Try to remap memory */
290 retval = remap_vmalloc_range(vma, mem->vmalloc, 0);
292 printk(KERN_ERR "mmap: remap failed with error %d. ", retval);
297 vma->vm_ops = &videobuf_vm_ops;
298 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
299 vma->vm_private_data = map;
301 dprintk(1,"mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
302 map, q, vma->vm_start, vma->vm_end,
303 (long int) q->bufs[first]->bsize,
304 vma->vm_pgoff, first);
306 videobuf_vm_open(vma);
316 static int __videobuf_copy_to_user ( struct videobuf_queue *q,
317 char __user *data, size_t count,
320 struct videobuf_vmalloc_memory *mem=q->read_buf->priv;
322 MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
324 BUG_ON (!mem->vmalloc);
326 /* copy to userspace */
327 if (count > q->read_buf->size - q->read_off)
328 count = q->read_buf->size - q->read_off;
330 if (copy_to_user(data, mem->vmalloc+q->read_off, count))
336 static int __videobuf_copy_stream ( struct videobuf_queue *q,
337 char __user *data, size_t count, size_t pos,
338 int vbihack, int nonblocking )
341 struct videobuf_vmalloc_memory *mem=q->read_buf->priv;
343 MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
346 /* dirty, undocumented hack -- pass the frame counter
347 * within the last four bytes of each vbi data block.
348 * We need that one to maintain backward compatibility
349 * to all vbi decoding software out there ... */
350 fc = (unsigned int*)mem->vmalloc;
351 fc += (q->read_buf->size>>2) -1;
352 *fc = q->read_buf->field_count >> 1;
353 dprintk(1,"vbihack: %d\n",*fc);
356 /* copy stuff using the common method */
357 count = __videobuf_copy_to_user (q,data,count,nonblocking);
359 if ( (count==-EFAULT) && (0 == pos) )
365 static struct videobuf_qtype_ops qops = {
366 .magic = MAGIC_QTYPE_OPS,
368 .alloc = __videobuf_alloc,
369 .iolock = __videobuf_iolock,
370 .sync = __videobuf_sync,
371 .mmap_free = __videobuf_mmap_free,
372 .mmap_mapper = __videobuf_mmap_mapper,
373 .video_copy_to_user = __videobuf_copy_to_user,
374 .copy_stream = __videobuf_copy_stream,
377 void videobuf_queue_vmalloc_init(struct videobuf_queue* q,
378 struct videobuf_queue_ops *ops,
381 enum v4l2_buf_type type,
382 enum v4l2_field field,
386 videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
390 EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init);
392 void *videobuf_to_vmalloc (struct videobuf_buffer *buf)
394 struct videobuf_vmalloc_memory *mem=buf->priv;
396 MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
400 EXPORT_SYMBOL_GPL(videobuf_to_vmalloc);
402 void videobuf_vmalloc_free (struct videobuf_buffer *buf)
404 struct videobuf_vmalloc_memory *mem = buf->priv;
406 /* mmapped memory can't be freed here, otherwise mmapped region
407 would be released, while still needed. In this case, the memory
408 release should happen inside videobuf_vm_close().
409 So, it should free memory only if the memory were allocated for
412 if ((buf->memory != V4L2_MEMORY_USERPTR) || (buf->baddr == 0))
418 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
425 EXPORT_SYMBOL_GPL(videobuf_vmalloc_free);