2 * helper functions for physically contiguous capture buffers
4 * The functions support hardware lacking scatter gather support
5 * (i.e. the buffers must be linear in physical memory)
7 * Copyright (c) 2008 Magnus Damm
9 * Based on videobuf-vmalloc.c,
10 * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2
17 #include <linux/init.h>
18 #include <linux/module.h>
20 #include <linux/pagemap.h>
21 #include <linux/dma-mapping.h>
22 #include <linux/sched.h>
23 #include <media/videobuf-dma-contig.h>
25 struct videobuf_dma_contig_memory
{
28 dma_addr_t dma_handle
;
33 #define MAGIC_DC_MEM 0x0733ac61
34 #define MAGIC_CHECK(is, should) \
35 if (unlikely((is) != (should))) { \
36 pr_err("magic mismatch: %x expected %x\n", (is), (should)); \
41 videobuf_vm_open(struct vm_area_struct
*vma
)
43 struct videobuf_mapping
*map
= vma
->vm_private_data
;
45 dev_dbg(map
->q
->dev
, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
46 map
, map
->count
, vma
->vm_start
, vma
->vm_end
);
51 static void videobuf_vm_close(struct vm_area_struct
*vma
)
53 struct videobuf_mapping
*map
= vma
->vm_private_data
;
54 struct videobuf_queue
*q
= map
->q
;
57 dev_dbg(map
->q
->dev
, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
58 map
, map
->count
, vma
->vm_start
, vma
->vm_end
);
61 if (0 == map
->count
) {
62 struct videobuf_dma_contig_memory
*mem
;
64 dev_dbg(map
->q
->dev
, "munmap %p q=%p\n", map
, q
);
65 mutex_lock(&q
->vb_lock
);
67 /* We need first to cancel streams, before unmapping */
69 videobuf_queue_cancel(q
);
71 for (i
= 0; i
< VIDEO_MAX_FRAME
; i
++) {
72 if (NULL
== q
->bufs
[i
])
75 if (q
->bufs
[i
]->map
!= map
)
78 mem
= q
->bufs
[i
]->priv
;
80 /* This callback is called only if kernel has
81 allocated memory and this memory is mmapped.
82 In this case, memory should be freed,
83 in order to do memory unmap.
86 MAGIC_CHECK(mem
->magic
, MAGIC_DC_MEM
);
88 /* vfree is not atomic - can't be
89 called with IRQ's disabled
91 dev_dbg(map
->q
->dev
, "buf[%d] freeing %p\n",
94 dma_free_coherent(q
->dev
, mem
->size
,
95 mem
->vaddr
, mem
->dma_handle
);
99 q
->bufs
[i
]->map
= NULL
;
100 q
->bufs
[i
]->baddr
= 0;
105 mutex_unlock(&q
->vb_lock
);
109 static const struct vm_operations_struct videobuf_vm_ops
= {
110 .open
= videobuf_vm_open
,
111 .close
= videobuf_vm_close
,
115 * videobuf_dma_contig_user_put() - reset pointer to user space buffer
116 * @mem: per-buffer private videobuf-dma-contig data
118 * This function resets the user space pointer
120 static void videobuf_dma_contig_user_put(struct videobuf_dma_contig_memory
*mem
)
128 * videobuf_dma_contig_user_get() - setup user space memory pointer
129 * @mem: per-buffer private videobuf-dma-contig data
130 * @vb: video buffer to map
132 * This function validates and sets up a pointer to user space memory.
133 * Only physically contiguous pfn-mapped memory is accepted.
135 * Returns 0 if successful.
137 static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory
*mem
,
138 struct videobuf_buffer
*vb
)
140 struct mm_struct
*mm
= current
->mm
;
141 struct vm_area_struct
*vma
;
142 unsigned long prev_pfn
, this_pfn
;
143 unsigned long pages_done
, user_address
;
147 offset
= vb
->baddr
& ~PAGE_MASK
;
148 mem
->size
= PAGE_ALIGN(vb
->size
+ offset
);
152 down_read(&mm
->mmap_sem
);
154 vma
= find_vma(mm
, vb
->baddr
);
158 if ((vb
->baddr
+ mem
->size
) > vma
->vm_end
)
162 prev_pfn
= 0; /* kill warning */
163 user_address
= vb
->baddr
;
165 while (pages_done
< (mem
->size
>> PAGE_SHIFT
)) {
166 ret
= follow_pfn(vma
, user_address
, &this_pfn
);
171 mem
->dma_handle
= (this_pfn
<< PAGE_SHIFT
) + offset
;
172 else if (this_pfn
!= (prev_pfn
+ 1))
179 user_address
+= PAGE_SIZE
;
187 up_read(¤t
->mm
->mmap_sem
);
192 static void *__videobuf_alloc(size_t size
)
194 struct videobuf_dma_contig_memory
*mem
;
195 struct videobuf_buffer
*vb
;
197 vb
= kzalloc(size
+ sizeof(*mem
), GFP_KERNEL
);
199 mem
= vb
->priv
= ((char *)vb
) + size
;
200 mem
->magic
= MAGIC_DC_MEM
;
206 static void *__videobuf_to_vmalloc(struct videobuf_buffer
*buf
)
208 struct videobuf_dma_contig_memory
*mem
= buf
->priv
;
211 MAGIC_CHECK(mem
->magic
, MAGIC_DC_MEM
);
216 static int __videobuf_iolock(struct videobuf_queue
*q
,
217 struct videobuf_buffer
*vb
,
218 struct v4l2_framebuffer
*fbuf
)
220 struct videobuf_dma_contig_memory
*mem
= vb
->priv
;
223 MAGIC_CHECK(mem
->magic
, MAGIC_DC_MEM
);
225 switch (vb
->memory
) {
226 case V4L2_MEMORY_MMAP
:
227 dev_dbg(q
->dev
, "%s memory method MMAP\n", __func__
);
229 /* All handling should be done by __videobuf_mmap_mapper() */
231 dev_err(q
->dev
, "memory is not alloced/mmapped.\n");
235 case V4L2_MEMORY_USERPTR
:
236 dev_dbg(q
->dev
, "%s memory method USERPTR\n", __func__
);
238 /* handle pointer from user space */
240 return videobuf_dma_contig_user_get(mem
, vb
);
242 /* allocate memory for the read() method */
243 mem
->size
= PAGE_ALIGN(vb
->size
);
244 mem
->vaddr
= dma_alloc_coherent(q
->dev
, mem
->size
,
245 &mem
->dma_handle
, GFP_KERNEL
);
247 dev_err(q
->dev
, "dma_alloc_coherent %ld failed\n",
252 dev_dbg(q
->dev
, "dma_alloc_coherent data is at %p (%ld)\n",
253 mem
->vaddr
, mem
->size
);
255 case V4L2_MEMORY_OVERLAY
:
257 dev_dbg(q
->dev
, "%s memory method OVERLAY/unknown\n",
265 static int __videobuf_mmap_free(struct videobuf_queue
*q
)
269 dev_dbg(q
->dev
, "%s\n", __func__
);
270 for (i
= 0; i
< VIDEO_MAX_FRAME
; i
++) {
271 if (q
->bufs
[i
] && q
->bufs
[i
]->map
)
278 static int __videobuf_mmap_mapper(struct videobuf_queue
*q
,
279 struct vm_area_struct
*vma
)
281 struct videobuf_dma_contig_memory
*mem
;
282 struct videobuf_mapping
*map
;
285 unsigned long size
, offset
= vma
->vm_pgoff
<< PAGE_SHIFT
;
287 dev_dbg(q
->dev
, "%s\n", __func__
);
288 if (!(vma
->vm_flags
& VM_WRITE
) || !(vma
->vm_flags
& VM_SHARED
))
291 /* look for first buffer to map */
292 for (first
= 0; first
< VIDEO_MAX_FRAME
; first
++) {
296 if (V4L2_MEMORY_MMAP
!= q
->bufs
[first
]->memory
)
298 if (q
->bufs
[first
]->boff
== offset
)
301 if (VIDEO_MAX_FRAME
== first
) {
302 dev_dbg(q
->dev
, "invalid user space offset [offset=0x%lx]\n",
307 /* create mapping + update buffer list */
308 map
= kzalloc(sizeof(struct videobuf_mapping
), GFP_KERNEL
);
312 q
->bufs
[first
]->map
= map
;
313 map
->start
= vma
->vm_start
;
314 map
->end
= vma
->vm_end
;
317 q
->bufs
[first
]->baddr
= vma
->vm_start
;
319 mem
= q
->bufs
[first
]->priv
;
321 MAGIC_CHECK(mem
->magic
, MAGIC_DC_MEM
);
323 mem
->size
= PAGE_ALIGN(q
->bufs
[first
]->bsize
);
324 mem
->vaddr
= dma_alloc_coherent(q
->dev
, mem
->size
,
325 &mem
->dma_handle
, GFP_KERNEL
);
327 dev_err(q
->dev
, "dma_alloc_coherent size %ld failed\n",
331 dev_dbg(q
->dev
, "dma_alloc_coherent data is at addr %p (size %ld)\n",
332 mem
->vaddr
, mem
->size
);
334 /* Try to remap memory */
336 size
= vma
->vm_end
- vma
->vm_start
;
337 size
= (size
< mem
->size
) ? size
: mem
->size
;
339 vma
->vm_page_prot
= pgprot_noncached(vma
->vm_page_prot
);
340 retval
= remap_pfn_range(vma
, vma
->vm_start
,
341 mem
->dma_handle
>> PAGE_SHIFT
,
342 size
, vma
->vm_page_prot
);
344 dev_err(q
->dev
, "mmap: remap failed with error %d. ", retval
);
345 dma_free_coherent(q
->dev
, mem
->size
,
346 mem
->vaddr
, mem
->dma_handle
);
350 vma
->vm_ops
= &videobuf_vm_ops
;
351 vma
->vm_flags
|= VM_DONTEXPAND
;
352 vma
->vm_private_data
= map
;
354 dev_dbg(q
->dev
, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
355 map
, q
, vma
->vm_start
, vma
->vm_end
,
356 (long int) q
->bufs
[first
]->bsize
,
357 vma
->vm_pgoff
, first
);
359 videobuf_vm_open(vma
);
368 static int __videobuf_copy_to_user(struct videobuf_queue
*q
,
369 char __user
*data
, size_t count
,
372 struct videobuf_dma_contig_memory
*mem
= q
->read_buf
->priv
;
376 MAGIC_CHECK(mem
->magic
, MAGIC_DC_MEM
);
379 /* copy to userspace */
380 if (count
> q
->read_buf
->size
- q
->read_off
)
381 count
= q
->read_buf
->size
- q
->read_off
;
385 if (copy_to_user(data
, vaddr
+ q
->read_off
, count
))
391 static int __videobuf_copy_stream(struct videobuf_queue
*q
,
392 char __user
*data
, size_t count
, size_t pos
,
393 int vbihack
, int nonblocking
)
396 struct videobuf_dma_contig_memory
*mem
= q
->read_buf
->priv
;
399 MAGIC_CHECK(mem
->magic
, MAGIC_DC_MEM
);
402 /* dirty, undocumented hack -- pass the frame counter
403 * within the last four bytes of each vbi data block.
404 * We need that one to maintain backward compatibility
405 * to all vbi decoding software out there ... */
406 fc
= (unsigned int *)mem
->vaddr
;
407 fc
+= (q
->read_buf
->size
>> 2) - 1;
408 *fc
= q
->read_buf
->field_count
>> 1;
409 dev_dbg(q
->dev
, "vbihack: %d\n", *fc
);
412 /* copy stuff using the common method */
413 count
= __videobuf_copy_to_user(q
, data
, count
, nonblocking
);
415 if ((count
== -EFAULT
) && (pos
== 0))
421 static struct videobuf_qtype_ops qops
= {
422 .magic
= MAGIC_QTYPE_OPS
,
424 .alloc
= __videobuf_alloc
,
425 .iolock
= __videobuf_iolock
,
426 .mmap_free
= __videobuf_mmap_free
,
427 .mmap_mapper
= __videobuf_mmap_mapper
,
428 .video_copy_to_user
= __videobuf_copy_to_user
,
429 .copy_stream
= __videobuf_copy_stream
,
430 .vmalloc
= __videobuf_to_vmalloc
,
433 void videobuf_queue_dma_contig_init(struct videobuf_queue
*q
,
434 const struct videobuf_queue_ops
*ops
,
437 enum v4l2_buf_type type
,
438 enum v4l2_field field
,
442 videobuf_queue_core_init(q
, ops
, dev
, irqlock
, type
, field
, msize
,
445 EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init
);
447 dma_addr_t
videobuf_to_dma_contig(struct videobuf_buffer
*buf
)
449 struct videobuf_dma_contig_memory
*mem
= buf
->priv
;
452 MAGIC_CHECK(mem
->magic
, MAGIC_DC_MEM
);
454 return mem
->dma_handle
;
456 EXPORT_SYMBOL_GPL(videobuf_to_dma_contig
);
458 void videobuf_dma_contig_free(struct videobuf_queue
*q
,
459 struct videobuf_buffer
*buf
)
461 struct videobuf_dma_contig_memory
*mem
= buf
->priv
;
463 /* mmapped memory can't be freed here, otherwise mmapped region
464 would be released, while still needed. In this case, the memory
465 release should happen inside videobuf_vm_close().
466 So, it should free memory only if the memory were allocated for
469 if (buf
->memory
!= V4L2_MEMORY_USERPTR
)
475 MAGIC_CHECK(mem
->magic
, MAGIC_DC_MEM
);
477 /* handle user space pointer case */
479 videobuf_dma_contig_user_put(mem
);
484 dma_free_coherent(q
->dev
, mem
->size
, mem
->vaddr
, mem
->dma_handle
);
487 EXPORT_SYMBOL_GPL(videobuf_dma_contig_free
);
489 MODULE_DESCRIPTION("helper module to manage video4linux dma contig buffers");
490 MODULE_AUTHOR("Magnus Damm");
491 MODULE_LICENSE("GPL");