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>
This commit is contained in:
Pawel Osciak 2010-05-11 10:36:29 -03:00 committed by Mauro Carvalho Chehab
parent 33c38283f0
commit a438d6da52

View file

@ -195,6 +195,45 @@ int videobuf_queue_is_busy(struct videobuf_queue *q)
}
EXPORT_SYMBOL_GPL(videobuf_queue_is_busy);
/**
* __videobuf_free() - free all the buffers and their control structures
*
* This function can only be called if streaming/reading is off, i.e. no buffers
* are under control of the driver.
*/
/* Locking: Caller holds q->vb_lock */
static int __videobuf_free(struct videobuf_queue *q)
{
int i;
dprintk(1, "%s\n", __func__);
if (!q)
return 0;
if (q->streaming || q->reading) {
dprintk(1, "Cannot free buffers when streaming or reading\n");
return -EBUSY;
}
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
for (i = 0; i < VIDEO_MAX_FRAME; i++)
if (q->bufs[i] && q->bufs[i]->map) {
dprintk(1, "Cannot free mmapped buffers\n");
return -EBUSY;
}
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
if (NULL == q->bufs[i])
continue;
q->ops->buf_release(q, q->bufs[i]);
kfree(q->bufs[i]);
q->bufs[i] = NULL;
}
return 0;
}
/* Locking: Caller holds q->vb_lock */
void videobuf_queue_cancel(struct videobuf_queue *q)
{
@ -308,36 +347,11 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
b->sequence = vb->field_count >> 1;
}
/* Locking: Caller holds q->vb_lock */
static int __videobuf_mmap_free(struct videobuf_queue *q)
{
int i;
if (!q)
return 0;
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
for (i = 0; i < VIDEO_MAX_FRAME; i++)
if (q->bufs[i] && q->bufs[i]->map)
return -EBUSY;
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
if (NULL == q->bufs[i])
continue;
q->ops->buf_release(q, q->bufs[i]);
kfree(q->bufs[i]);
q->bufs[i] = NULL;
}
return 0;
}
int videobuf_mmap_free(struct videobuf_queue *q)
{
int ret;
mutex_lock(&q->vb_lock);
ret = __videobuf_mmap_free(q);
ret = __videobuf_free(q);
mutex_unlock(&q->vb_lock);
return ret;
}
@ -353,7 +367,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q,
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
err = __videobuf_mmap_free(q);
err = __videobuf_free(q);
if (0 != err)
return err;
@ -970,7 +984,7 @@ static void __videobuf_read_stop(struct videobuf_queue *q)
int i;
videobuf_queue_cancel(q);
__videobuf_mmap_free(q);
__videobuf_free(q);
INIT_LIST_HEAD(&q->stream);
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
if (NULL == q->bufs[i])