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 <linux/slab.h>
24 #include <media/videobuf-dma-contig.h>
26 struct videobuf_dma_contig_memory {
29 dma_addr_t dma_handle;
34 #define MAGIC_DC_MEM 0x0733ac61
35 #define MAGIC_CHECK(is, should) \
36 if (unlikely((is) != (should))) { \
37 pr_err("magic mismatch: %x expected %x\n", (is), (should)); \
42 videobuf_vm_open(struct vm_area_struct *vma)
44 struct videobuf_mapping *map = vma->vm_private_data;
46 dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
47 map, map->count, vma->vm_start, vma->vm_end);
52 static void videobuf_vm_close(struct vm_area_struct *vma)
54 struct videobuf_mapping *map = vma->vm_private_data;
55 struct videobuf_queue *q = map->q;
58 dev_dbg(map->q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
59 map, map->count, vma->vm_start, vma->vm_end);
62 if (0 == map->count) {
63 struct videobuf_dma_contig_memory *mem;
65 dev_dbg(map->q->dev, "munmap %p q=%p\n", map, q);
66 mutex_lock(&q->vb_lock);
68 /* We need first to cancel streams, before unmapping */
70 videobuf_queue_cancel(q);
72 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
73 if (NULL == q->bufs[i])
76 if (q->bufs[i]->map != map)
79 mem = q->bufs[i]->priv;
81 /* This callback is called only if kernel has
82 allocated memory and this memory is mmapped.
83 In this case, memory should be freed,
84 in order to do memory unmap.
87 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
89 /* vfree is not atomic - can't be
90 called with IRQ's disabled
92 dev_dbg(map->q->dev, "buf[%d] freeing %p\n",
95 dma_free_coherent(q->dev, mem->size,
96 mem->vaddr, mem->dma_handle);
100 q->bufs[i]->map = NULL;
101 q->bufs[i]->baddr = 0;
106 mutex_unlock(&q->vb_lock);
110 static const struct vm_operations_struct videobuf_vm_ops = {
111 .open = videobuf_vm_open,
112 .close = videobuf_vm_close,
116 * videobuf_dma_contig_user_put() - reset pointer to user space buffer
117 * @mem: per-buffer private videobuf-dma-contig data
119 * This function resets the user space pointer
121 static void videobuf_dma_contig_user_put(struct videobuf_dma_contig_memory *mem)
129 * videobuf_dma_contig_user_get() - setup user space memory pointer
130 * @mem: per-buffer private videobuf-dma-contig data
131 * @vb: video buffer to map
133 * This function validates and sets up a pointer to user space memory.
134 * Only physically contiguous pfn-mapped memory is accepted.
136 * Returns 0 if successful.
138 static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
139 struct videobuf_buffer *vb)
141 struct mm_struct *mm = current->mm;
142 struct vm_area_struct *vma;
143 unsigned long prev_pfn, this_pfn;
144 unsigned long pages_done, user_address;
148 offset = vb->baddr & ~PAGE_MASK;
149 mem->size = PAGE_ALIGN(vb->size + offset);
153 down_read(&mm->mmap_sem);
155 vma = find_vma(mm, vb->baddr);
159 if ((vb->baddr + mem->size) > vma->vm_end)
163 prev_pfn = 0; /* kill warning */
164 user_address = vb->baddr;
166 while (pages_done < (mem->size >> PAGE_SHIFT)) {
167 ret = follow_pfn(vma, user_address, &this_pfn);
172 mem->dma_handle = (this_pfn << PAGE_SHIFT) + offset;
173 else if (this_pfn != (prev_pfn + 1))
180 user_address += PAGE_SIZE;
188 up_read(¤t->mm->mmap_sem);
193 static struct videobuf_buffer *__videobuf_alloc(size_t size)
195 struct videobuf_dma_contig_memory *mem;
196 struct videobuf_buffer *vb;
198 vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
200 mem = vb->priv = ((char *)vb) + size;
201 mem->magic = MAGIC_DC_MEM;
207 static void *__videobuf_to_vmalloc(struct videobuf_buffer *buf)
209 struct videobuf_dma_contig_memory *mem = buf->priv;
212 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
217 static int __videobuf_iolock(struct videobuf_queue *q,
218 struct videobuf_buffer *vb,
219 struct v4l2_framebuffer *fbuf)
221 struct videobuf_dma_contig_memory *mem = vb->priv;
224 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
226 switch (vb->memory) {
227 case V4L2_MEMORY_MMAP:
228 dev_dbg(q->dev, "%s memory method MMAP\n", __func__);
230 /* All handling should be done by __videobuf_mmap_mapper() */
232 dev_err(q->dev, "memory is not alloced/mmapped.\n");
236 case V4L2_MEMORY_USERPTR:
237 dev_dbg(q->dev, "%s memory method USERPTR\n", __func__);
239 /* handle pointer from user space */
241 return videobuf_dma_contig_user_get(mem, vb);
243 /* allocate memory for the read() method */
244 mem->size = PAGE_ALIGN(vb->size);
245 mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
246 &mem->dma_handle, GFP_KERNEL);
248 dev_err(q->dev, "dma_alloc_coherent %ld failed\n",
253 dev_dbg(q->dev, "dma_alloc_coherent data is at %p (%ld)\n",
254 mem->vaddr, mem->size);
256 case V4L2_MEMORY_OVERLAY:
258 dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n",
266 static int __videobuf_mmap_mapper(struct videobuf_queue *q,
267 struct vm_area_struct *vma)
269 struct videobuf_dma_contig_memory *mem;
270 struct videobuf_mapping *map;
273 unsigned long size, offset = vma->vm_pgoff << PAGE_SHIFT;
275 dev_dbg(q->dev, "%s\n", __func__);
276 if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
279 /* look for first buffer to map */
280 for (first = 0; first < VIDEO_MAX_FRAME; first++) {
284 if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
286 if (q->bufs[first]->boff == offset)
289 if (VIDEO_MAX_FRAME == first) {
290 dev_dbg(q->dev, "invalid user space offset [offset=0x%lx]\n",
295 /* create mapping + update buffer list */
296 map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
300 q->bufs[first]->map = map;
301 map->start = vma->vm_start;
302 map->end = vma->vm_end;
305 q->bufs[first]->baddr = vma->vm_start;
307 mem = q->bufs[first]->priv;
309 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
311 mem->size = PAGE_ALIGN(q->bufs[first]->bsize);
312 mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
313 &mem->dma_handle, GFP_KERNEL);
315 dev_err(q->dev, "dma_alloc_coherent size %ld failed\n",
319 dev_dbg(q->dev, "dma_alloc_coherent data is at addr %p (size %ld)\n",
320 mem->vaddr, mem->size);
322 /* Try to remap memory */
324 size = vma->vm_end - vma->vm_start;
325 size = (size < mem->size) ? size : mem->size;
327 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
328 retval = remap_pfn_range(vma, vma->vm_start,
329 mem->dma_handle >> PAGE_SHIFT,
330 size, vma->vm_page_prot);
332 dev_err(q->dev, "mmap: remap failed with error %d. ", retval);
333 dma_free_coherent(q->dev, mem->size,
334 mem->vaddr, mem->dma_handle);
338 vma->vm_ops = &videobuf_vm_ops;
339 vma->vm_flags |= VM_DONTEXPAND;
340 vma->vm_private_data = map;
342 dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
343 map, q, vma->vm_start, vma->vm_end,
344 (long int) q->bufs[first]->bsize,
345 vma->vm_pgoff, first);
347 videobuf_vm_open(vma);
356 static int __videobuf_copy_to_user(struct videobuf_queue *q,
357 char __user *data, size_t count,
360 struct videobuf_dma_contig_memory *mem = q->read_buf->priv;
364 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
367 /* copy to userspace */
368 if (count > q->read_buf->size - q->read_off)
369 count = q->read_buf->size - q->read_off;
373 if (copy_to_user(data, vaddr + q->read_off, count))
379 static int __videobuf_copy_stream(struct videobuf_queue *q,
380 char __user *data, size_t count, size_t pos,
381 int vbihack, int nonblocking)
384 struct videobuf_dma_contig_memory *mem = q->read_buf->priv;
387 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
390 /* dirty, undocumented hack -- pass the frame counter
391 * within the last four bytes of each vbi data block.
392 * We need that one to maintain backward compatibility
393 * to all vbi decoding software out there ... */
394 fc = (unsigned int *)mem->vaddr;
395 fc += (q->read_buf->size >> 2) - 1;
396 *fc = q->read_buf->field_count >> 1;
397 dev_dbg(q->dev, "vbihack: %d\n", *fc);
400 /* copy stuff using the common method */
401 count = __videobuf_copy_to_user(q, data, count, nonblocking);
403 if ((count == -EFAULT) && (pos == 0))
409 static struct videobuf_qtype_ops qops = {
410 .magic = MAGIC_QTYPE_OPS,
412 .alloc = __videobuf_alloc,
413 .iolock = __videobuf_iolock,
414 .mmap_mapper = __videobuf_mmap_mapper,
415 .video_copy_to_user = __videobuf_copy_to_user,
416 .copy_stream = __videobuf_copy_stream,
417 .vmalloc = __videobuf_to_vmalloc,
420 void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
421 const struct videobuf_queue_ops *ops,
424 enum v4l2_buf_type type,
425 enum v4l2_field field,
429 videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
432 EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init);
434 dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf)
436 struct videobuf_dma_contig_memory *mem = buf->priv;
439 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
441 return mem->dma_handle;
443 EXPORT_SYMBOL_GPL(videobuf_to_dma_contig);
445 void videobuf_dma_contig_free(struct videobuf_queue *q,
446 struct videobuf_buffer *buf)
448 struct videobuf_dma_contig_memory *mem = buf->priv;
450 /* mmapped memory can't be freed here, otherwise mmapped region
451 would be released, while still needed. In this case, the memory
452 release should happen inside videobuf_vm_close().
453 So, it should free memory only if the memory were allocated for
456 if (buf->memory != V4L2_MEMORY_USERPTR)
462 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
464 /* handle user space pointer case */
466 videobuf_dma_contig_user_put(mem);
471 dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle);
474 EXPORT_SYMBOL_GPL(videobuf_dma_contig_free);
476 MODULE_DESCRIPTION("helper module to manage video4linux dma contig buffers");
477 MODULE_AUTHOR("Magnus Damm");
478 MODULE_LICENSE("GPL");