Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
videobuf-dma-contig.c
Go to the documentation of this file.
1 /*
2  * helper functions for physically contiguous capture buffers
3  *
4  * The functions support hardware lacking scatter gather support
5  * (i.e. the buffers must be linear in physical memory)
6  *
7  * Copyright (c) 2008 Magnus Damm
8  *
9  * Based on videobuf-vmalloc.c,
10  * (c) 2007 Mauro Carvalho Chehab, <[email protected]>
11  *
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
15  */
16 
17 #include <linux/init.h>
18 #include <linux/module.h>
19 #include <linux/mm.h>
20 #include <linux/pagemap.h>
21 #include <linux/dma-mapping.h>
22 #include <linux/sched.h>
23 #include <linux/slab.h>
25 
28  void *vaddr;
30  bool cached;
31  unsigned long size;
32 };
33 
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)); \
38  BUG(); \
39  }
40 
41 static int __videobuf_dc_alloc(struct device *dev,
43  unsigned long size, gfp_t flags)
44 {
45  mem->size = size;
46  if (mem->cached) {
47  mem->vaddr = alloc_pages_exact(mem->size, flags | GFP_DMA);
48  if (mem->vaddr) {
49  int err;
50 
51  mem->dma_handle = dma_map_single(dev, mem->vaddr,
52  mem->size,
54  err = dma_mapping_error(dev, mem->dma_handle);
55  if (err) {
56  dev_err(dev, "dma_map_single failed\n");
57 
58  free_pages_exact(mem->vaddr, mem->size);
59  mem->vaddr = NULL;
60  return err;
61  }
62  }
63  } else
64  mem->vaddr = dma_alloc_coherent(dev, mem->size,
65  &mem->dma_handle, flags);
66 
67  if (!mem->vaddr) {
68  dev_err(dev, "memory alloc size %ld failed\n", mem->size);
69  return -ENOMEM;
70  }
71 
72  dev_dbg(dev, "dma mapped data is at %p (%ld)\n", mem->vaddr, mem->size);
73 
74  return 0;
75 }
76 
77 static void __videobuf_dc_free(struct device *dev,
79 {
80  if (mem->cached) {
81  if (!mem->vaddr)
82  return;
83  dma_unmap_single(dev, mem->dma_handle, mem->size,
85  free_pages_exact(mem->vaddr, mem->size);
86  } else
87  dma_free_coherent(dev, mem->size, mem->vaddr, mem->dma_handle);
88 
89  mem->vaddr = NULL;
90 }
91 
92 static void videobuf_vm_open(struct vm_area_struct *vma)
93 {
94  struct videobuf_mapping *map = vma->vm_private_data;
95 
96  dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
97  map, map->count, vma->vm_start, vma->vm_end);
98 
99  map->count++;
100 }
101 
102 static void videobuf_vm_close(struct vm_area_struct *vma)
103 {
104  struct videobuf_mapping *map = vma->vm_private_data;
105  struct videobuf_queue *q = map->q;
106  int i;
107 
108  dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
109  map, map->count, vma->vm_start, vma->vm_end);
110 
111  map->count--;
112  if (0 == map->count) {
114 
115  dev_dbg(q->dev, "munmap %p q=%p\n", map, q);
116  videobuf_queue_lock(q);
117 
118  /* We need first to cancel streams, before unmapping */
119  if (q->streaming)
121 
122  for (i = 0; i < VIDEO_MAX_FRAME; i++) {
123  if (NULL == q->bufs[i])
124  continue;
125 
126  if (q->bufs[i]->map != map)
127  continue;
128 
129  mem = q->bufs[i]->priv;
130  if (mem) {
131  /* This callback is called only if kernel has
132  allocated memory and this memory is mmapped.
133  In this case, memory should be freed,
134  in order to do memory unmap.
135  */
136 
138 
139  /* vfree is not atomic - can't be
140  called with IRQ's disabled
141  */
142  dev_dbg(q->dev, "buf[%d] freeing %p\n",
143  i, mem->vaddr);
144 
145  __videobuf_dc_free(q->dev, mem);
146  mem->vaddr = NULL;
147  }
148 
149  q->bufs[i]->map = NULL;
150  q->bufs[i]->baddr = 0;
151  }
152 
153  kfree(map);
154 
155  videobuf_queue_unlock(q);
156  }
157 }
158 
159 static const struct vm_operations_struct videobuf_vm_ops = {
160  .open = videobuf_vm_open,
161  .close = videobuf_vm_close,
162 };
163 
170 static void videobuf_dma_contig_user_put(struct videobuf_dma_contig_memory *mem)
171 {
172  mem->dma_handle = 0;
173  mem->size = 0;
174 }
175 
186 static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
187  struct videobuf_buffer *vb)
188 {
189  struct mm_struct *mm = current->mm;
190  struct vm_area_struct *vma;
191  unsigned long prev_pfn, this_pfn;
192  unsigned long pages_done, user_address;
193  unsigned int offset;
194  int ret;
195 
196  offset = vb->baddr & ~PAGE_MASK;
197  mem->size = PAGE_ALIGN(vb->size + offset);
198  ret = -EINVAL;
199 
200  down_read(&mm->mmap_sem);
201 
202  vma = find_vma(mm, vb->baddr);
203  if (!vma)
204  goto out_up;
205 
206  if ((vb->baddr + mem->size) > vma->vm_end)
207  goto out_up;
208 
209  pages_done = 0;
210  prev_pfn = 0; /* kill warning */
211  user_address = vb->baddr;
212 
213  while (pages_done < (mem->size >> PAGE_SHIFT)) {
214  ret = follow_pfn(vma, user_address, &this_pfn);
215  if (ret)
216  break;
217 
218  if (pages_done == 0)
219  mem->dma_handle = (this_pfn << PAGE_SHIFT) + offset;
220  else if (this_pfn != (prev_pfn + 1))
221  ret = -EFAULT;
222 
223  if (ret)
224  break;
225 
226  prev_pfn = this_pfn;
227  user_address += PAGE_SIZE;
228  pages_done++;
229  }
230 
231 out_up:
232  up_read(&current->mm->mmap_sem);
233 
234  return ret;
235 }
236 
237 static struct videobuf_buffer *__videobuf_alloc_vb(size_t size, bool cached)
238 {
240  struct videobuf_buffer *vb;
241 
242  vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
243  if (vb) {
244  vb->priv = ((char *)vb) + size;
245  mem = vb->priv;
246  mem->magic = MAGIC_DC_MEM;
247  mem->cached = cached;
248  }
249 
250  return vb;
251 }
252 
253 static struct videobuf_buffer *__videobuf_alloc_uncached(size_t size)
254 {
255  return __videobuf_alloc_vb(size, false);
256 }
257 
258 static struct videobuf_buffer *__videobuf_alloc_cached(size_t size)
259 {
260  return __videobuf_alloc_vb(size, true);
261 }
262 
263 static void *__videobuf_to_vaddr(struct videobuf_buffer *buf)
264 {
265  struct videobuf_dma_contig_memory *mem = buf->priv;
266 
267  BUG_ON(!mem);
269 
270  return mem->vaddr;
271 }
272 
273 static int __videobuf_iolock(struct videobuf_queue *q,
274  struct videobuf_buffer *vb,
275  struct v4l2_framebuffer *fbuf)
276 {
277  struct videobuf_dma_contig_memory *mem = vb->priv;
278 
279  BUG_ON(!mem);
281 
282  switch (vb->memory) {
283  case V4L2_MEMORY_MMAP:
284  dev_dbg(q->dev, "%s memory method MMAP\n", __func__);
285 
286  /* All handling should be done by __videobuf_mmap_mapper() */
287  if (!mem->vaddr) {
288  dev_err(q->dev, "memory is not alloced/mmapped.\n");
289  return -EINVAL;
290  }
291  break;
292  case V4L2_MEMORY_USERPTR:
293  dev_dbg(q->dev, "%s memory method USERPTR\n", __func__);
294 
295  /* handle pointer from user space */
296  if (vb->baddr)
297  return videobuf_dma_contig_user_get(mem, vb);
298 
299  /* allocate memory for the read() method */
300  if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(vb->size),
301  GFP_KERNEL))
302  return -ENOMEM;
303  break;
304  case V4L2_MEMORY_OVERLAY:
305  default:
306  dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n", __func__);
307  return -EINVAL;
308  }
309 
310  return 0;
311 }
312 
313 static int __videobuf_sync(struct videobuf_queue *q,
314  struct videobuf_buffer *buf)
315 {
316  struct videobuf_dma_contig_memory *mem = buf->priv;
317  BUG_ON(!mem);
319 
322 
323  return 0;
324 }
325 
326 static int __videobuf_mmap_mapper(struct videobuf_queue *q,
327  struct videobuf_buffer *buf,
328  struct vm_area_struct *vma)
329 {
331  struct videobuf_mapping *map;
332  int retval;
333  unsigned long size;
334  unsigned long pos, start = vma->vm_start;
335  struct page *page;
336 
337  dev_dbg(q->dev, "%s\n", __func__);
338 
339  /* create mapping + update buffer list */
340  map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
341  if (!map)
342  return -ENOMEM;
343 
344  buf->map = map;
345  map->q = q;
346 
347  buf->baddr = vma->vm_start;
348 
349  mem = buf->priv;
350  BUG_ON(!mem);
352 
353  if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(buf->bsize),
355  goto error;
356 
357  /* Try to remap memory */
358 
359  size = vma->vm_end - vma->vm_start;
360  size = (size < mem->size) ? size : mem->size;
361 
362  if (!mem->cached) {
364  retval = remap_pfn_range(vma, vma->vm_start,
365  mem->dma_handle >> PAGE_SHIFT,
366  size, vma->vm_page_prot);
367  if (retval) {
368  dev_err(q->dev, "mmap: remap failed with error %d. ",
369  retval);
370  dma_free_coherent(q->dev, mem->size,
371  mem->vaddr, mem->dma_handle);
372  goto error;
373  }
374  } else {
375  pos = (unsigned long)mem->vaddr;
376 
377  while (size > 0) {
378  page = virt_to_page((void *)pos);
379  if (NULL == page) {
380  dev_err(q->dev, "mmap: virt_to_page failed\n");
381  __videobuf_dc_free(q->dev, mem);
382  goto error;
383  }
384  retval = vm_insert_page(vma, start, page);
385  if (retval) {
386  dev_err(q->dev, "mmap: insert failed with error %d\n",
387  retval);
388  __videobuf_dc_free(q->dev, mem);
389  goto error;
390  }
391  start += PAGE_SIZE;
392  pos += PAGE_SIZE;
393 
394  if (size > PAGE_SIZE)
395  size -= PAGE_SIZE;
396  else
397  size = 0;
398  }
399  }
400 
401  vma->vm_ops = &videobuf_vm_ops;
402  vma->vm_flags |= VM_DONTEXPAND;
403  vma->vm_private_data = map;
404 
405  dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
406  map, q, vma->vm_start, vma->vm_end,
407  (long int)buf->bsize, vma->vm_pgoff, buf->i);
408 
409  videobuf_vm_open(vma);
410 
411  return 0;
412 
413 error:
414  kfree(map);
415  return -ENOMEM;
416 }
417 
418 static struct videobuf_qtype_ops qops = {
419  .magic = MAGIC_QTYPE_OPS,
420  .alloc_vb = __videobuf_alloc_uncached,
421  .iolock = __videobuf_iolock,
422  .mmap_mapper = __videobuf_mmap_mapper,
423  .vaddr = __videobuf_to_vaddr,
424 };
425 
426 static struct videobuf_qtype_ops qops_cached = {
427  .magic = MAGIC_QTYPE_OPS,
428  .alloc_vb = __videobuf_alloc_cached,
429  .iolock = __videobuf_iolock,
430  .sync = __videobuf_sync,
431  .mmap_mapper = __videobuf_mmap_mapper,
432  .vaddr = __videobuf_to_vaddr,
433 };
434 
436  const struct videobuf_queue_ops *ops,
437  struct device *dev,
438  spinlock_t *irqlock,
439  enum v4l2_buf_type type,
440  enum v4l2_field field,
441  unsigned int msize,
442  void *priv,
443  struct mutex *ext_lock)
444 {
445  videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
446  priv, &qops, ext_lock);
447 }
449 
451  const struct videobuf_queue_ops *ops,
452  struct device *dev,
453  spinlock_t *irqlock,
454  enum v4l2_buf_type type,
455  enum v4l2_field field,
456  unsigned int msize,
457  void *priv, struct mutex *ext_lock)
458 {
459  videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
460  priv, &qops_cached, ext_lock);
461 }
463 
465 {
466  struct videobuf_dma_contig_memory *mem = buf->priv;
467 
468  BUG_ON(!mem);
470 
471  return mem->dma_handle;
472 }
474 
476  struct videobuf_buffer *buf)
477 {
478  struct videobuf_dma_contig_memory *mem = buf->priv;
479 
480  /* mmapped memory can't be freed here, otherwise mmapped region
481  would be released, while still needed. In this case, the memory
482  release should happen inside videobuf_vm_close().
483  So, it should free memory only if the memory were allocated for
484  read() operation.
485  */
486  if (buf->memory != V4L2_MEMORY_USERPTR)
487  return;
488 
489  if (!mem)
490  return;
491 
493 
494  /* handle user space pointer case */
495  if (buf->baddr) {
496  videobuf_dma_contig_user_put(mem);
497  return;
498  }
499 
500  /* read() method */
501  if (mem->vaddr) {
502  __videobuf_dc_free(q->dev, mem);
503  mem->vaddr = NULL;
504  }
505 }
507 
508 MODULE_DESCRIPTION("helper module to manage video4linux dma contig buffers");
509 MODULE_AUTHOR("Magnus Damm");
510 MODULE_LICENSE("GPL");