Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a438d6da authored by Pawel Osciak's avatar Pawel Osciak Committed by Mauro Carvalho Chehab
Browse files

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: default avatarPawel Osciak <p.osciak@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 33c38283
Loading
Loading
Loading
Loading
+42 −28
Original line number Diff line number Diff line
@@ -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])