davinci: edma: provide ability to detect insufficient CC info data
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / media / video / videobuf-dma-contig.c
blob74730c624cfcba0809fb45069bf3e1854c963412
1 /*
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>
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>
24 #include <media/videobuf-dma-contig.h>
26 struct videobuf_dma_contig_memory {
27 u32 magic;
28 void *vaddr;
29 dma_addr_t dma_handle;
30 unsigned long size;
31 int is_userptr;
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(); \
41 static void
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);
49 map->count++;
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;
56 int i;
58 dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
59 map, map->count, vma->vm_start, vma->vm_end);
61 map->count--;
62 if (0 == map->count) {
63 struct videobuf_dma_contig_memory *mem;
65 dev_dbg(q->dev, "munmap %p q=%p\n", map, q);
66 mutex_lock(&q->vb_lock);
68 /* We need first to cancel streams, before unmapping */
69 if (q->streaming)
70 videobuf_queue_cancel(q);
72 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
73 if (NULL == q->bufs[i])
74 continue;
76 if (q->bufs[i]->map != map)
77 continue;
79 mem = q->bufs[i]->priv;
80 if (mem) {
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(q->dev, "buf[%d] freeing %p\n",
93 i, mem->vaddr);
95 dma_free_coherent(q->dev, mem->size,
96 mem->vaddr, mem->dma_handle);
97 mem->vaddr = NULL;
100 q->bufs[i]->map = NULL;
101 q->bufs[i]->baddr = 0;
104 kfree(map);
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)
123 mem->is_userptr = 0;
124 mem->dma_handle = 0;
125 mem->size = 0;
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;
145 unsigned int offset;
146 int ret;
148 offset = vb->baddr & ~PAGE_MASK;
149 mem->size = PAGE_ALIGN(vb->size + offset);
150 mem->is_userptr = 0;
151 ret = -EINVAL;
153 down_read(&mm->mmap_sem);
155 vma = find_vma(mm, vb->baddr);
156 if (!vma)
157 goto out_up;
159 if ((vb->baddr + mem->size) > vma->vm_end)
160 goto out_up;
162 pages_done = 0;
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);
168 if (ret)
169 break;
171 if (pages_done == 0)
172 mem->dma_handle = (this_pfn << PAGE_SHIFT) + offset;
173 else if (this_pfn != (prev_pfn + 1))
174 ret = -EFAULT;
176 if (ret)
177 break;
179 prev_pfn = this_pfn;
180 user_address += PAGE_SIZE;
181 pages_done++;
184 if (!ret)
185 mem->is_userptr = 1;
187 out_up:
188 up_read(&current->mm->mmap_sem);
190 return ret;
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);
199 if (vb) {
200 mem = vb->priv = ((char *)vb) + size;
201 mem->magic = MAGIC_DC_MEM;
204 return vb;
207 static void *__videobuf_to_vaddr(struct videobuf_buffer *buf)
209 struct videobuf_dma_contig_memory *mem = buf->priv;
211 BUG_ON(!mem);
212 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
214 return mem->vaddr;
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;
223 BUG_ON(!mem);
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() */
231 if (!mem->vaddr) {
232 dev_err(q->dev, "memory is not alloced/mmapped.\n");
233 return -EINVAL;
235 break;
236 case V4L2_MEMORY_USERPTR:
237 dev_dbg(q->dev, "%s memory method USERPTR\n", __func__);
239 /* handle pointer from user space */
240 if (vb->baddr)
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);
247 if (!mem->vaddr) {
248 dev_err(q->dev, "dma_alloc_coherent %ld failed\n",
249 mem->size);
250 return -ENOMEM;
253 dev_dbg(q->dev, "dma_alloc_coherent data is at %p (%ld)\n",
254 mem->vaddr, mem->size);
255 break;
256 case V4L2_MEMORY_OVERLAY:
257 default:
258 dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n",
259 __func__);
260 return -EINVAL;
263 return 0;
266 static int __videobuf_mmap_mapper(struct videobuf_queue *q,
267 struct videobuf_buffer *buf,
268 struct vm_area_struct *vma)
270 struct videobuf_dma_contig_memory *mem;
271 struct videobuf_mapping *map;
272 int retval;
273 unsigned long size;
275 dev_dbg(q->dev, "%s\n", __func__);
277 /* create mapping + update buffer list */
278 map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
279 if (!map)
280 return -ENOMEM;
282 buf->map = map;
283 map->start = vma->vm_start;
284 map->end = vma->vm_end;
285 map->q = q;
287 buf->baddr = vma->vm_start;
289 mem = buf->priv;
290 BUG_ON(!mem);
291 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
293 mem->size = PAGE_ALIGN(buf->bsize);
294 mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
295 &mem->dma_handle, GFP_KERNEL);
296 if (!mem->vaddr) {
297 dev_err(q->dev, "dma_alloc_coherent size %ld failed\n",
298 mem->size);
299 goto error;
301 dev_dbg(q->dev, "dma_alloc_coherent data is at addr %p (size %ld)\n",
302 mem->vaddr, mem->size);
304 /* Try to remap memory */
306 size = vma->vm_end - vma->vm_start;
307 size = (size < mem->size) ? size : mem->size;
309 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
310 retval = remap_pfn_range(vma, vma->vm_start,
311 mem->dma_handle >> PAGE_SHIFT,
312 size, vma->vm_page_prot);
313 if (retval) {
314 dev_err(q->dev, "mmap: remap failed with error %d. ", retval);
315 dma_free_coherent(q->dev, mem->size,
316 mem->vaddr, mem->dma_handle);
317 goto error;
320 vma->vm_ops = &videobuf_vm_ops;
321 vma->vm_flags |= VM_DONTEXPAND;
322 vma->vm_private_data = map;
324 dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
325 map, q, vma->vm_start, vma->vm_end,
326 (long int)buf->bsize,
327 vma->vm_pgoff, buf->i);
329 videobuf_vm_open(vma);
331 return 0;
333 error:
334 kfree(map);
335 return -ENOMEM;
338 static struct videobuf_qtype_ops qops = {
339 .magic = MAGIC_QTYPE_OPS,
341 .alloc = __videobuf_alloc,
342 .iolock = __videobuf_iolock,
343 .mmap_mapper = __videobuf_mmap_mapper,
344 .vaddr = __videobuf_to_vaddr,
347 void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
348 const struct videobuf_queue_ops *ops,
349 struct device *dev,
350 spinlock_t *irqlock,
351 enum v4l2_buf_type type,
352 enum v4l2_field field,
353 unsigned int msize,
354 void *priv)
356 videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
357 priv, &qops);
359 EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init);
361 dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf)
363 struct videobuf_dma_contig_memory *mem = buf->priv;
365 BUG_ON(!mem);
366 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
368 return mem->dma_handle;
370 EXPORT_SYMBOL_GPL(videobuf_to_dma_contig);
372 void videobuf_dma_contig_free(struct videobuf_queue *q,
373 struct videobuf_buffer *buf)
375 struct videobuf_dma_contig_memory *mem = buf->priv;
377 /* mmapped memory can't be freed here, otherwise mmapped region
378 would be released, while still needed. In this case, the memory
379 release should happen inside videobuf_vm_close().
380 So, it should free memory only if the memory were allocated for
381 read() operation.
383 if (buf->memory != V4L2_MEMORY_USERPTR)
384 return;
386 if (!mem)
387 return;
389 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
391 /* handle user space pointer case */
392 if (buf->baddr) {
393 videobuf_dma_contig_user_put(mem);
394 return;
397 /* read() method */
398 dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle);
399 mem->vaddr = NULL;
401 EXPORT_SYMBOL_GPL(videobuf_dma_contig_free);
403 MODULE_DESCRIPTION("helper module to manage video4linux dma contig buffers");
404 MODULE_AUTHOR("Magnus Damm");
405 MODULE_LICENSE("GPL");