diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-10 05:33:03 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-25 16:04:46 -0500 |
commit | d05051c82e0e8ff748e9c9a06a061bda3ad656e5 (patch) | |
tree | 8c16254c217b301b60519136bc12618de3894a2e | |
parent | c6243d9c3de82e46467c88898db45ca14b6843a0 (diff) |
V4L/DVB (6997): Replace a very dirty hack on videobuf for a clean wait_event
In order to videobuf_iolock to work, mmap_mapper should be called first.
Otherwise, an OOPS is generated.
On some cases, .mmap file handler used to took some time to be called. On those
situations, mmap_mmapper() were called after iolock.
This patch properly waits for mmap_mapper to be called, otherwise generating an
error.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | drivers/media/video/videobuf-core.c | 15 | ||||
-rw-r--r-- | include/media/videobuf-core.h | 2 |
2 files changed, 13 insertions, 4 deletions
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index 43fe3f78c8df..c3adbd686ffe 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c | |||
@@ -98,13 +98,15 @@ int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
98 | MAGIC_CHECK(vb->magic, MAGIC_BUFFER); | 98 | MAGIC_CHECK(vb->magic, MAGIC_BUFFER); |
99 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); | 99 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); |
100 | 100 | ||
101 | /* FIXME: This is required to avoid OOPS on some cases, | 101 | /* This is required to avoid OOPS on some cases, |
102 | since mmap_mapper() method should be called before _iolock. | 102 | since mmap_mapper() method should be called before _iolock. |
103 | On some cases, the mmap_mapper() is called only after scheduling. | 103 | On some cases, the mmap_mapper() is called only after scheduling. |
104 | |||
105 | However, this way is just too dirty! Better to wait for some event. | ||
106 | */ | 104 | */ |
107 | schedule_timeout(HZ); | 105 | wait_event_timeout(vb->done, q->is_mmapped, msecs_to_jiffies(100)); |
106 | if (!q->is_mmapped) { | ||
107 | printk(KERN_ERR "Error: mmap_mapper() never called!\n"); | ||
108 | return -EINVAL; | ||
109 | } | ||
108 | 110 | ||
109 | return CALL(q, iolock, q, vb, fbuf); | 111 | return CALL(q, iolock, q, vb, fbuf); |
110 | } | 112 | } |
@@ -300,7 +302,11 @@ static int __videobuf_mmap_free(struct videobuf_queue *q) | |||
300 | 302 | ||
301 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); | 303 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); |
302 | 304 | ||
305 | |||
303 | rc = CALL(q, mmap_free, q); | 306 | rc = CALL(q, mmap_free, q); |
307 | |||
308 | q->is_mmapped = 0; | ||
309 | |||
304 | if (rc < 0) | 310 | if (rc < 0) |
305 | return rc; | 311 | return rc; |
306 | 312 | ||
@@ -1022,6 +1028,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, | |||
1022 | 1028 | ||
1023 | mutex_lock(&q->lock); | 1029 | mutex_lock(&q->lock); |
1024 | retval = CALL(q, mmap_mapper, q, vma); | 1030 | retval = CALL(q, mmap_mapper, q, vma); |
1031 | q->is_mmapped = 1; | ||
1025 | mutex_unlock(&q->lock); | 1032 | mutex_unlock(&q->lock); |
1026 | 1033 | ||
1027 | return retval; | 1034 | return retval; |
diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h index 7aa7a7b64c1b..97f14d469595 100644 --- a/include/media/videobuf-core.h +++ b/include/media/videobuf-core.h | |||
@@ -164,6 +164,8 @@ struct videobuf_queue { | |||
164 | 164 | ||
165 | unsigned int streaming:1; | 165 | unsigned int streaming:1; |
166 | unsigned int reading:1; | 166 | unsigned int reading:1; |
167 | unsigned int is_mmapped:1; | ||
168 | |||
167 | /* capture via mmap() + ioctl(QBUF/DQBUF) */ | 169 | /* capture via mmap() + ioctl(QBUF/DQBUF) */ |
168 | struct list_head stream; | 170 | struct list_head stream; |
169 | 171 | ||