diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2010-03-28 08:09:05 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-19 11:57:54 -0400 |
commit | 0b62b73778554cd47480ea465f0b255cc63b4336 (patch) | |
tree | 880c3c5fc9b9ba75c65902da9dc77e8c97d3967d | |
parent | 37111039c9521c751ce0597c129fe6d45ba72818 (diff) |
V4L/DVB: v4l videobuf: add videobuf_buffer *buf as argument to mmap_mapper
mmap_mapper should operate on a buffer, not on a complete queue. So let
the videobuf-core find the correct buffer instead of duplicating that
code in each mmap_mapper implementation.
The dma-sg implementation has backwards compatibility code for handling
the V4L1_COMPAT layer. This code is now under the v4L1_COMPAT config option.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/videobuf-core.c | 20 | ||||
-rw-r--r-- | drivers/media/video/videobuf-dma-contig.c | 34 | ||||
-rw-r--r-- | drivers/media/video/videobuf-dma-sg.c | 69 | ||||
-rw-r--r-- | drivers/media/video/videobuf-vmalloc.c | 33 | ||||
-rw-r--r-- | include/media/videobuf-core.h | 3 |
5 files changed, 67 insertions, 92 deletions
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index f1dfcff44e1..dc2f6a8c022 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 | ||
1124 | int videobuf_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma) | 1124 | int 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 | } |
1136 | EXPORT_SYMBOL_GPL(videobuf_mmap_mapper); | 1150 | EXPORT_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 0a0ff85140b..055ce8439ce 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 | ||
266 | static int __videobuf_mmap_mapper(struct videobuf_queue *q, | 266 | static 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 5c55bd392ea..1a7f3d3d2f9 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 | ||
551 | static int __videobuf_mmap_mapper(struct videobuf_queue *q, | 551 | static 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 ad655839827..f8b5b563511 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 | ||
238 | static int __videobuf_mmap_mapper(struct videobuf_queue *q, | 238 | static 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 821a530f495..f91a736c133 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 | ||
141 | struct videobuf_queue { | 142 | struct videobuf_queue { |