diff options
author | Pawel Osciak <p.osciak@samsung.com> | 2010-05-11 09:36:29 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-02 14:21:29 -0400 |
commit | a438d6da52b991b6896742a0f9aed80c2f82da87 (patch) | |
tree | 267bfe22e74ec98432a271424b76ee4c70d8652d /drivers/media | |
parent | 33c38283f03d8ea0358229fc03c1beebe67aed0e (diff) |
V4L/DVB: videobuf: rename videobuf_mmap_free and add sanity checks
This function is not specific to mmap, hence the rename.
Add a check whether we are not streaming or reading (for read mode that
uses the stream queue) before freeing anything.
Signed-off-by: Pawel Osciak <p.osciak@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/videobuf-core.c | 70 |
1 files changed, 42 insertions, 28 deletions
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index 4d5658387955..ce1595bef629 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c | |||
@@ -195,6 +195,45 @@ int videobuf_queue_is_busy(struct videobuf_queue *q) | |||
195 | } | 195 | } |
196 | EXPORT_SYMBOL_GPL(videobuf_queue_is_busy); | 196 | EXPORT_SYMBOL_GPL(videobuf_queue_is_busy); |
197 | 197 | ||
198 | /** | ||
199 | * __videobuf_free() - free all the buffers and their control structures | ||
200 | * | ||
201 | * This function can only be called if streaming/reading is off, i.e. no buffers | ||
202 | * are under control of the driver. | ||
203 | */ | ||
204 | /* Locking: Caller holds q->vb_lock */ | ||
205 | static int __videobuf_free(struct videobuf_queue *q) | ||
206 | { | ||
207 | int i; | ||
208 | |||
209 | dprintk(1, "%s\n", __func__); | ||
210 | if (!q) | ||
211 | return 0; | ||
212 | |||
213 | if (q->streaming || q->reading) { | ||
214 | dprintk(1, "Cannot free buffers when streaming or reading\n"); | ||
215 | return -EBUSY; | ||
216 | } | ||
217 | |||
218 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); | ||
219 | |||
220 | for (i = 0; i < VIDEO_MAX_FRAME; i++) | ||
221 | if (q->bufs[i] && q->bufs[i]->map) { | ||
222 | dprintk(1, "Cannot free mmapped buffers\n"); | ||
223 | return -EBUSY; | ||
224 | } | ||
225 | |||
226 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | ||
227 | if (NULL == q->bufs[i]) | ||
228 | continue; | ||
229 | q->ops->buf_release(q, q->bufs[i]); | ||
230 | kfree(q->bufs[i]); | ||
231 | q->bufs[i] = NULL; | ||
232 | } | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
198 | /* Locking: Caller holds q->vb_lock */ | 237 | /* Locking: Caller holds q->vb_lock */ |
199 | void videobuf_queue_cancel(struct videobuf_queue *q) | 238 | void videobuf_queue_cancel(struct videobuf_queue *q) |
200 | { | 239 | { |
@@ -308,36 +347,11 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, | |||
308 | b->sequence = vb->field_count >> 1; | 347 | b->sequence = vb->field_count >> 1; |
309 | } | 348 | } |
310 | 349 | ||
311 | /* Locking: Caller holds q->vb_lock */ | ||
312 | static int __videobuf_mmap_free(struct videobuf_queue *q) | ||
313 | { | ||
314 | int i; | ||
315 | |||
316 | if (!q) | ||
317 | return 0; | ||
318 | |||
319 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); | ||
320 | |||
321 | for (i = 0; i < VIDEO_MAX_FRAME; i++) | ||
322 | if (q->bufs[i] && q->bufs[i]->map) | ||
323 | return -EBUSY; | ||
324 | |||
325 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | ||
326 | if (NULL == q->bufs[i]) | ||
327 | continue; | ||
328 | q->ops->buf_release(q, q->bufs[i]); | ||
329 | kfree(q->bufs[i]); | ||
330 | q->bufs[i] = NULL; | ||
331 | } | ||
332 | |||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | int videobuf_mmap_free(struct videobuf_queue *q) | 350 | int videobuf_mmap_free(struct videobuf_queue *q) |
337 | { | 351 | { |
338 | int ret; | 352 | int ret; |
339 | mutex_lock(&q->vb_lock); | 353 | mutex_lock(&q->vb_lock); |
340 | ret = __videobuf_mmap_free(q); | 354 | ret = __videobuf_free(q); |
341 | mutex_unlock(&q->vb_lock); | 355 | mutex_unlock(&q->vb_lock); |
342 | return ret; | 356 | return ret; |
343 | } | 357 | } |
@@ -353,7 +367,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q, | |||
353 | 367 | ||
354 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); | 368 | MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); |
355 | 369 | ||
356 | err = __videobuf_mmap_free(q); | 370 | err = __videobuf_free(q); |
357 | if (0 != err) | 371 | if (0 != err) |
358 | return err; | 372 | return err; |
359 | 373 | ||
@@ -970,7 +984,7 @@ static void __videobuf_read_stop(struct videobuf_queue *q) | |||
970 | int i; | 984 | int i; |
971 | 985 | ||
972 | videobuf_queue_cancel(q); | 986 | videobuf_queue_cancel(q); |
973 | __videobuf_mmap_free(q); | 987 | __videobuf_free(q); |
974 | INIT_LIST_HEAD(&q->stream); | 988 | INIT_LIST_HEAD(&q->stream); |
975 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | 989 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { |
976 | if (NULL == q->bufs[i]) | 990 | if (NULL == q->bufs[i]) |