aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/videobuf-core.c20
-rw-r--r--drivers/media/video/videobuf-dma-contig.c34
-rw-r--r--drivers/media/video/videobuf-dma-sg.c69
-rw-r--r--drivers/media/video/videobuf-vmalloc.c33
-rw-r--r--include/media/videobuf-core.h3
5 files changed, 67 insertions, 92 deletions
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index f1dfcff44e1b..dc2f6a8c0225 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -1123,15 +1123,29 @@ EXPORT_SYMBOL_GPL(videobuf_poll_stream);
1123 1123
1124int videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma) 1124int videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma)
1125{ 1125{
1126 int retval; 1126 int rc = -EINVAL;
1127 int i;
1127 1128
1128 MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); 1129 MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
1129 1130
1131 if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) {
1132 dprintk(1, "mmap appl bug: PROT_WRITE and MAP_SHARED are required\n");
1133 return -EINVAL;
1134 }
1135
1130 mutex_lock(&q->vb_lock); 1136 mutex_lock(&q->vb_lock);
1131 retval = CALL(q, mmap_mapper, q, vma); 1137 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1138 struct videobuf_buffer *buf = q->bufs[i];
1139
1140 if (buf && buf->memory == V4L2_MEMORY_MMAP &&
1141 buf->boff == (vma->vm_pgoff << PAGE_SHIFT)) {
1142 rc = CALL(q, mmap_mapper, q, buf, vma);
1143 break;
1144 }
1145 }
1132 mutex_unlock(&q->vb_lock); 1146 mutex_unlock(&q->vb_lock);
1133 1147
1134 return retval; 1148 return rc;
1135} 1149}
1136EXPORT_SYMBOL_GPL(videobuf_mmap_mapper); 1150EXPORT_SYMBOL_GPL(videobuf_mmap_mapper);
1137 1151
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index 0a0ff85140b7..055ce8439ce6 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -264,51 +264,33 @@ static int __videobuf_iolock(struct videobuf_queue *q,
264} 264}
265 265
266static int __videobuf_mmap_mapper(struct videobuf_queue *q, 266static int __videobuf_mmap_mapper(struct videobuf_queue *q,
267 struct videobuf_buffer *buf,
267 struct vm_area_struct *vma) 268 struct vm_area_struct *vma)
268{ 269{
269 struct videobuf_dma_contig_memory *mem; 270 struct videobuf_dma_contig_memory *mem;
270 struct videobuf_mapping *map; 271 struct videobuf_mapping *map;
271 unsigned int first;
272 int retval; 272 int retval;
273 unsigned long size, offset = vma->vm_pgoff << PAGE_SHIFT; 273 unsigned long size;
274 274
275 dev_dbg(q->dev, "%s\n", __func__); 275 dev_dbg(q->dev, "%s\n", __func__);
276 if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
277 return -EINVAL;
278
279 /* look for first buffer to map */
280 for (first = 0; first < VIDEO_MAX_FRAME; first++) {
281 if (!q->bufs[first])
282 continue;
283
284 if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
285 continue;
286 if (q->bufs[first]->boff == offset)
287 break;
288 }
289 if (VIDEO_MAX_FRAME == first) {
290 dev_dbg(q->dev, "invalid user space offset [offset=0x%lx]\n",
291 offset);
292 return -EINVAL;
293 }
294 276
295 /* create mapping + update buffer list */ 277 /* create mapping + update buffer list */
296 map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL); 278 map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
297 if (!map) 279 if (!map)
298 return -ENOMEM; 280 return -ENOMEM;
299 281
300 q->bufs[first]->map = map; 282 buf->map = map;
301 map->start = vma->vm_start; 283 map->start = vma->vm_start;
302 map->end = vma->vm_end; 284 map->end = vma->vm_end;
303 map->q = q; 285 map->q = q;
304 286
305 q->bufs[first]->baddr = vma->vm_start; 287 buf->baddr = vma->vm_start;
306 288
307 mem = q->bufs[first]->priv; 289 mem = buf->priv;
308 BUG_ON(!mem); 290 BUG_ON(!mem);
309 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); 291 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
310 292
311 mem->size = PAGE_ALIGN(q->bufs[first]->bsize); 293 mem->size = PAGE_ALIGN(buf->bsize);
312 mem->vaddr = dma_alloc_coherent(q->dev, mem->size, 294 mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
313 &mem->dma_handle, GFP_KERNEL); 295 &mem->dma_handle, GFP_KERNEL);
314 if (!mem->vaddr) { 296 if (!mem->vaddr) {
@@ -341,8 +323,8 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
341 323
342 dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n", 324 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, 325 map, q, vma->vm_start, vma->vm_end,
344 (long int) q->bufs[first]->bsize, 326 (long int)buf->bsize,
345 vma->vm_pgoff, first); 327 vma->vm_pgoff, buf->i);
346 328
347 videobuf_vm_open(vma); 329 videobuf_vm_open(vma);
348 330
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 5c55bd392ea3..1a7f3d3d2f99 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -549,22 +549,15 @@ static int __videobuf_sync(struct videobuf_queue *q,
549} 549}
550 550
551static int __videobuf_mmap_mapper(struct videobuf_queue *q, 551static int __videobuf_mmap_mapper(struct videobuf_queue *q,
552 struct vm_area_struct *vma) 552 struct videobuf_buffer *buf,
553 struct vm_area_struct *vma)
553{ 554{
554 struct videobuf_dma_sg_memory *mem; 555 struct videobuf_dma_sg_memory *mem = buf->priv;
555 struct videobuf_mapping *map; 556 struct videobuf_mapping *map;
556 unsigned int first, last, size, i; 557 unsigned int first, last, size, i;
557 int retval; 558 int retval;
558 559
559 retval = -EINVAL; 560 retval = -EINVAL;
560 if (!(vma->vm_flags & VM_WRITE)) {
561 dprintk(1, "mmap app bug: PROT_WRITE please\n");
562 goto done;
563 }
564 if (!(vma->vm_flags & VM_SHARED)) {
565 dprintk(1, "mmap app bug: MAP_SHARED please\n");
566 goto done;
567 }
568 561
569 /* This function maintains backwards compatibility with V4L1 and will 562 /* This function maintains backwards compatibility with V4L1 and will
570 * map more than one buffer if the vma length is equal to the combined 563 * map more than one buffer if the vma length is equal to the combined
@@ -574,44 +567,48 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
574 * TODO: Allow drivers to specify if they support this mode 567 * TODO: Allow drivers to specify if they support this mode
575 */ 568 */
576 569
570 BUG_ON(!mem);
571 MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
572
577 /* look for first buffer to map */ 573 /* look for first buffer to map */
578 for (first = 0; first < VIDEO_MAX_FRAME; first++) { 574 for (first = 0; first < VIDEO_MAX_FRAME; first++) {
579 if (NULL == q->bufs[first]) 575 if (buf == q->bufs[first]) {
580 continue; 576 size = PAGE_ALIGN(q->bufs[first]->bsize);
581 mem = q->bufs[first]->priv;
582 BUG_ON(!mem);
583 MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
584
585 if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
586 continue;
587 if (q->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT))
588 break; 577 break;
578 }
589 } 579 }
580
581 /* paranoia, should never happen since buf is always valid. */
590 if (VIDEO_MAX_FRAME == first) { 582 if (VIDEO_MAX_FRAME == first) {
591 dprintk(1, "mmap app bug: offset invalid [offset=0x%lx]\n", 583 dprintk(1, "mmap app bug: offset invalid [offset=0x%lx]\n",
592 (vma->vm_pgoff << PAGE_SHIFT)); 584 (vma->vm_pgoff << PAGE_SHIFT));
593 goto done; 585 goto done;
594 } 586 }
595 587
596 /* look for last buffer to map */ 588 last = first;
597 for (size = 0, last = first; last < VIDEO_MAX_FRAME; last++) { 589#ifdef CONFIG_VIDEO_V4L1_COMPAT
598 if (NULL == q->bufs[last]) 590 if (size != (vma->vm_end - vma->vm_start)) {
599 continue; 591 /* look for last buffer to map */
600 if (V4L2_MEMORY_MMAP != q->bufs[last]->memory) 592 for (last = first + 1; last < VIDEO_MAX_FRAME; last++) {
601 continue; 593 if (NULL == q->bufs[last])
602 if (q->bufs[last]->map) { 594 continue;
603 retval = -EBUSY; 595 if (V4L2_MEMORY_MMAP != q->bufs[last]->memory)
596 continue;
597 if (q->bufs[last]->map) {
598 retval = -EBUSY;
599 goto done;
600 }
601 size += PAGE_ALIGN(q->bufs[last]->bsize);
602 if (size == (vma->vm_end - vma->vm_start))
603 break;
604 }
605 if (VIDEO_MAX_FRAME == last) {
606 dprintk(1, "mmap app bug: size invalid [size=0x%lx]\n",
607 (vma->vm_end - vma->vm_start));
604 goto done; 608 goto done;
605 } 609 }
606 size += PAGE_ALIGN(q->bufs[last]->bsize);
607 if (size == (vma->vm_end - vma->vm_start))
608 break;
609 }
610 if (VIDEO_MAX_FRAME == last) {
611 dprintk(1, "mmap app bug: size invalid [size=0x%lx]\n",
612 (vma->vm_end - vma->vm_start));
613 goto done;
614 } 610 }
611#endif
615 612
616 /* create mapping + update buffer list */ 613 /* create mapping + update buffer list */
617 retval = -ENOMEM; 614 retval = -ENOMEM;
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index ad655839827b..f8b5b5635113 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -236,47 +236,28 @@ static int __videobuf_sync(struct videobuf_queue *q,
236} 236}
237 237
238static int __videobuf_mmap_mapper(struct videobuf_queue *q, 238static int __videobuf_mmap_mapper(struct videobuf_queue *q,
239 struct vm_area_struct *vma) 239 struct videobuf_buffer *buf,
240 struct vm_area_struct *vma)
240{ 241{
241 struct videobuf_vmalloc_memory *mem; 242 struct videobuf_vmalloc_memory *mem;
242 struct videobuf_mapping *map; 243 struct videobuf_mapping *map;
243 unsigned int first;
244 int retval, pages; 244 int retval, pages;
245 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
246 245
247 dprintk(1, "%s\n", __func__); 246 dprintk(1, "%s\n", __func__);
248 if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
249 return -EINVAL;
250
251 /* look for first buffer to map */
252 for (first = 0; first < VIDEO_MAX_FRAME; first++) {
253 if (NULL == q->bufs[first])
254 continue;
255
256 if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
257 continue;
258 if (q->bufs[first]->boff == offset)
259 break;
260 }
261 if (VIDEO_MAX_FRAME == first) {
262 dprintk(1, "mmap app bug: offset invalid [offset=0x%lx]\n",
263 (vma->vm_pgoff << PAGE_SHIFT));
264 return -EINVAL;
265 }
266 247
267 /* create mapping + update buffer list */ 248 /* create mapping + update buffer list */
268 map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL); 249 map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
269 if (NULL == map) 250 if (NULL == map)
270 return -ENOMEM; 251 return -ENOMEM;
271 252
272 q->bufs[first]->map = map; 253 buf->map = map;
273 map->start = vma->vm_start; 254 map->start = vma->vm_start;
274 map->end = vma->vm_end; 255 map->end = vma->vm_end;
275 map->q = q; 256 map->q = q;
276 257
277 q->bufs[first]->baddr = vma->vm_start; 258 buf->baddr = vma->vm_start;
278 259
279 mem = q->bufs[first]->priv; 260 mem = buf->priv;
280 BUG_ON(!mem); 261 BUG_ON(!mem);
281 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); 262 MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
282 263
@@ -302,8 +283,8 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
302 283
303 dprintk(1, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n", 284 dprintk(1, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
304 map, q, vma->vm_start, vma->vm_end, 285 map, q, vma->vm_start, vma->vm_end,
305 (long int) q->bufs[first]->bsize, 286 (long int)buf->bsize,
306 vma->vm_pgoff, first); 287 vma->vm_pgoff, buf->i);
307 288
308 videobuf_vm_open(vma); 289 videobuf_vm_open(vma);
309 290
diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h
index 821a530f4957..f91a736c133d 100644
--- a/include/media/videobuf-core.h
+++ b/include/media/videobuf-core.h
@@ -135,7 +135,8 @@ struct videobuf_qtype_ops {
135 int (*sync) (struct videobuf_queue *q, 135 int (*sync) (struct videobuf_queue *q,
136 struct videobuf_buffer *buf); 136 struct videobuf_buffer *buf);
137 int (*mmap_mapper) (struct videobuf_queue *q, 137 int (*mmap_mapper) (struct videobuf_queue *q,
138 struct vm_area_struct *vma); 138 struct videobuf_buffer *buf,
139 struct vm_area_struct *vma);
139}; 140};
140 141
141struct videobuf_queue { 142struct videobuf_queue {