// SPDX-License-Identifier: GPL-2.0+
/* Driver for virtio video device.
 *
 * Copyright 2019 OpenSynergy GmbH.
 *
 * Based on drivers/gpu/drm/virtio/virtgpu_vq.c
 * Copyright (C) 2015 Red Hat, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "virtio_video.h"

#define MAX_INLINE_CMD_SIZE   298
#define MAX_INLINE_RESP_SIZE  298
#define VBUFFER_SIZE          (sizeof(struct virtio_video_vbuffer) \
			       + MAX_INLINE_CMD_SIZE		   \
			       + MAX_INLINE_RESP_SIZE)

void virtio_video_resource_id_get(struct virtio_video *vv, uint32_t *id)
{
	int handle;

	idr_preload(GFP_KERNEL);
	spin_lock(&vv->resource_idr_lock);
	handle = idr_alloc(&vv->resource_idr, NULL, 1, 0, GFP_NOWAIT);
	spin_unlock(&vv->resource_idr_lock);
	idr_preload_end();
	*id = handle;
}

void virtio_video_resource_id_put(struct virtio_video *vv, uint32_t id)
{
	spin_lock(&vv->resource_idr_lock);
	idr_remove(&vv->resource_idr, id);
	spin_unlock(&vv->resource_idr_lock);
}

void virtio_video_stream_id_get(struct virtio_video *vv,
				struct virtio_video_stream *stream,
				uint32_t *id)
{
	int handle;

	idr_preload(GFP_KERNEL);
	spin_lock(&vv->stream_idr_lock);
	handle = idr_alloc(&vv->stream_idr, stream, 1, 0, 0);
	spin_unlock(&vv->stream_idr_lock);
	idr_preload_end();
	*id = handle;
}

void virtio_video_stream_id_put(struct virtio_video *vv, uint32_t id)
{
	spin_lock(&vv->stream_idr_lock);
	idr_remove(&vv->stream_idr, id);
	spin_unlock(&vv->stream_idr_lock);
}

void virtio_video_cmd_ack(struct virtqueue *vq)
{
	struct virtio_video *vv = vq->vdev->priv;

	schedule_work(&vv->commandq.dequeue_work);
}

void virtio_video_event_ack(struct virtqueue *vq)
{
	struct virtio_video *vv = vq->vdev->priv;

	schedule_work(&vv->eventq.dequeue_work);
}

static struct virtio_video_vbuffer *
virtio_video_get_vbuf(struct virtio_video *vv, int size,
		      int resp_size, void *resp_buf,
		      virtio_video_resp_cb resp_cb)
{
	struct virtio_video_vbuffer *vbuf;

	vbuf = kmem_cache_alloc(vv->vbufs, GFP_KERNEL);
	if (!vbuf)
		return ERR_PTR(-ENOMEM);
	memset(vbuf, 0, VBUFFER_SIZE);

	BUG_ON(size > MAX_INLINE_CMD_SIZE);
	vbuf->buf = (void *)vbuf + sizeof(*vbuf);
	vbuf->size = size;

	vbuf->resp_cb = resp_cb;
	vbuf->resp_size = resp_size;
	if (resp_size <= MAX_INLINE_RESP_SIZE && !resp_buf)
		vbuf->resp_buf = (void *)vbuf->buf + size;
	else
		vbuf->resp_buf = resp_buf;
	BUG_ON(!vbuf->resp_buf);

	return vbuf;
}

static void free_vbuf(struct virtio_video *vv,
		      struct virtio_video_vbuffer *vbuf)
{
	if (!vbuf->resp_cb &&
	    vbuf->resp_size > MAX_INLINE_RESP_SIZE)
		kfree(vbuf->resp_buf);
	kfree(vbuf->data_buf);
	kmem_cache_free(vv->vbufs, vbuf);
}

static void reclaim_vbufs(struct virtqueue *vq, struct list_head *reclaim_list)
{
	struct virtio_video_vbuffer *vbuf;
	unsigned int len;
	struct virtio_video *vv = vq->vdev->priv;
	int freed = 0;

	while ((vbuf = virtqueue_get_buf(vq, &len))) {
		list_add_tail(&vbuf->list, reclaim_list);
		freed++;
	}
	if (freed == 0)
		v4l2_dbg(1, vv->debug, &vv->v4l2_dev,
			 "zero vbufs reclaimed\n");
}

static void detach_vbufs(struct virtqueue *vq, struct list_head *detach_list)
{
	struct virtio_video_vbuffer *vbuf;

	while ((vbuf = virtqueue_detach_unused_buf(vq)) != NULL)
		list_add_tail(&vbuf->list, detach_list);
}

static void virtio_video_deatch_vbufs(struct virtio_video *vv)
{
	struct list_head detach_list;
	struct virtio_video_vbuffer *entry, *tmp;

	INIT_LIST_HEAD(&detach_list);

	detach_vbufs(vv->eventq.vq, &detach_list);
	detach_vbufs(vv->commandq.vq, &detach_list);

	if (list_empty(&detach_list))
		return;

	list_for_each_entry_safe(entry, tmp, &detach_list, list) {
		list_del(&entry->list);
		free_vbuf(vv, entry);
	}
}

int virtio_video_alloc_vbufs(struct virtio_video *vv)
{
	vv->vbufs =
		kmem_cache_create("virtio-video-vbufs", VBUFFER_SIZE,
				  __alignof__(struct virtio_video_vbuffer), 0,
				  NULL);
	if (!vv->vbufs)
		return -ENOMEM;

	return 0;
}

void virtio_video_free_vbufs(struct virtio_video *vv)
{
	virtio_video_deatch_vbufs(vv);
	kmem_cache_destroy(vv->vbufs);
	vv->vbufs = NULL;
}

static void *virtio_video_alloc_req(struct virtio_video *vv,
				    struct virtio_video_vbuffer **vbuffer_p,
				    int size)
{
	struct virtio_video_vbuffer *vbuf;

	vbuf = virtio_video_get_vbuf(vv, size,
				     sizeof(struct virtio_video_cmd_hdr),
				     NULL, NULL);
	if (IS_ERR(vbuf)) {
		*vbuffer_p = NULL;
		return ERR_CAST(vbuf);
	}
	*vbuffer_p = vbuf;

	return vbuf->buf;
}

static void *
virtio_video_alloc_req_resp(struct virtio_video *vv,
			    virtio_video_resp_cb cb,
			    struct virtio_video_vbuffer **vbuffer_p,
			    int req_size, int resp_size,
			    void *resp_buf)
{
	struct virtio_video_vbuffer *vbuf;

	vbuf = virtio_video_get_vbuf(vv, req_size, resp_size, resp_buf, cb);
	if (IS_ERR(vbuf)) {
		*vbuffer_p = NULL;
		return ERR_CAST(vbuf);
	}
	*vbuffer_p = vbuf;

	return vbuf->buf;
}

void virtio_video_dequeue_cmd_func(struct work_struct *work)
{
	struct virtio_video *vv =
		container_of(work, struct virtio_video,
			     commandq.dequeue_work);
	struct list_head reclaim_list;
	struct virtio_video_vbuffer *entry, *tmp;
	struct virtio_video_cmd_hdr *resp;

	INIT_LIST_HEAD(&reclaim_list);
	spin_lock(&vv->commandq.qlock);
	do {
		virtqueue_disable_cb(vv->commandq.vq);
		reclaim_vbufs(vv->commandq.vq, &reclaim_list);

	} while (!virtqueue_enable_cb(vv->commandq.vq));
	spin_unlock(&vv->commandq.qlock);

	list_for_each_entry_safe(entry, tmp, &reclaim_list, list) {
		resp = (struct virtio_video_cmd_hdr *)entry->resp_buf;
		if (resp->type >=
		    cpu_to_le32(VIRTIO_VIDEO_RESP_ERR_INVALID_OPERATION))
			v4l2_dbg(1, vv->debug, &vv->v4l2_dev,
				 "response 0x%x\n", le32_to_cpu(resp->type));
		if (entry->resp_cb)
			entry->resp_cb(vv, entry);

		list_del(&entry->list);
		free_vbuf(vv, entry);
	}
	wake_up(&vv->commandq.ack_queue);
}

void virtio_video_dequeue_event_func(struct work_struct *work)
{
	struct virtio_video *vv =
		container_of(work, struct virtio_video,
			     eventq.dequeue_work);
	struct list_head reclaim_list;
	struct virtio_video_vbuffer *entry, *tmp;

	INIT_LIST_HEAD(&reclaim_list);
	spin_lock(&vv->eventq.qlock);
	do {
		virtqueue_disable_cb(vv->eventq.vq);
		reclaim_vbufs(vv->eventq.vq, &reclaim_list);

	} while (!virtqueue_enable_cb(vv->eventq.vq));
	spin_unlock(&vv->eventq.qlock);

	list_for_each_entry_safe(entry, tmp, &reclaim_list, list) {
		entry->resp_cb(vv, entry);
		list_del(&entry->list);
	}
	wake_up(&vv->eventq.ack_queue);
}

static int
virtio_video_queue_cmd_buffer_locked(struct virtio_video *vv,
				      struct virtio_video_vbuffer *vbuf)
{
	struct virtqueue *vq = vv->commandq.vq;
	struct scatterlist *sgs[3], vreq, vout, vresp;
	int outcnt = 0, incnt = 0;
	int ret;

	if (!vv->vq_ready)
		return -ENODEV;

	sg_init_one(&vreq, vbuf->buf, vbuf->size);
	sgs[outcnt + incnt] = &vreq;
	outcnt++;

	if (vbuf->data_size) {
		sg_init_one(&vout, vbuf->data_buf, vbuf->data_size);
		sgs[outcnt + incnt] = &vout;
		outcnt++;
	}

	if (vbuf->resp_size) {
		sg_init_one(&vresp, vbuf->resp_buf, vbuf->resp_size);
		sgs[outcnt + incnt] = &vresp;
		incnt++;
	}

retry:
	ret = virtqueue_add_sgs(vq, sgs, outcnt, incnt, vbuf, GFP_ATOMIC);
	if (ret == -ENOSPC) {
		spin_unlock(&vv->commandq.qlock);
		wait_event(vv->commandq.ack_queue, vq->num_free);
		spin_lock(&vv->commandq.qlock);
		goto retry;
	} else {
		virtqueue_kick(vq);
	}

	return ret;
}

static int virtio_video_queue_cmd_buffer(struct virtio_video *vv,
					  struct virtio_video_vbuffer *vbuf)
{
	int ret;

	spin_lock(&vv->commandq.qlock);
	ret = virtio_video_queue_cmd_buffer_locked(vv, vbuf);
	spin_unlock(&vv->commandq.qlock);

	return ret;
}

static int virtio_video_queue_event_buffer(struct virtio_video *vv,
					   struct virtio_video_vbuffer *vbuf)
{
	int ret;
	struct scatterlist vresp;
	struct virtqueue *vq = vv->eventq.vq;

	spin_lock(&vv->eventq.qlock);
	sg_init_one(&vresp, vbuf->resp_buf, vbuf->resp_size);
	ret = virtqueue_add_inbuf(vq, &vresp, 1, vbuf, GFP_ATOMIC);
	spin_unlock(&vv->eventq.qlock);
	if (ret)
		return ret;

	virtqueue_kick(vq);

	return 0;
}

static void virtio_video_event_cb(struct virtio_video *vv,
				  struct virtio_video_vbuffer *vbuf)
{
	int ret;
	struct virtio_video_stream *stream;
	struct virtio_video_event *event =
		(struct virtio_video_event *)vbuf->resp_buf;
	struct vb2_queue *src_vq;
	struct vb2_queue *dst_vq;
	uint32_t stream_id, event_type;

	stream_id = le32_to_cpu(event->stream_id);
	event_type = le32_to_cpu(event->event_type);

	stream = idr_find(&vv->stream_idr, stream_id);
	if (!stream) {
		v4l2_warn(&vv->v4l2_dev, "no stream %u found for event\n",
			  stream_id);
		return;
	}

	switch (event_type) {
	case VIRTIO_VIDEO_EVENT_DECODER_RESOLUTION_CHANGED:
		virtio_video_cmd_get_params(vv, stream,
					   VIRTIO_VIDEO_QUEUE_TYPE_OUTPUT);
		virtio_video_queue_res_chg_event(stream);
		if (stream->state == STREAM_STATE_INIT) {
			stream->state = STREAM_STATE_METADATA;
			wake_up(&vv->wq);
		}
		break;
	case VIRTIO_VIDEO_EVENT_ERROR:
		v4l2_err(&vv->v4l2_dev, "error on stream %d\n", stream_id);
		src_vq = v4l2_m2m_get_vq(stream->fh.m2m_ctx,
					 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
		dst_vq = v4l2_m2m_get_vq(stream->fh.m2m_ctx,
					 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
		vb2_queue_error(src_vq);
		vb2_queue_error(dst_vq);
		break;
	default:
		v4l2_warn(&vv->v4l2_dev, "unknown event %d on %d\n",
			  event_type, stream_id);
		break;
	}

	memset(vbuf->resp_buf, 0, vbuf->resp_size);
	ret = virtio_video_queue_event_buffer(vv, vbuf);
	if (ret)
		v4l2_warn(&vv->v4l2_dev, "queue event buffer failed\n");
}

int virtio_video_alloc_events(struct virtio_video *vv, size_t num)
{
	int ret;
	size_t i;
	struct virtio_video_vbuffer *vbuf;

	for (i = 0; i < num; i++) {
		vbuf = virtio_video_get_vbuf(vv, 0,
					     sizeof(struct virtio_video_event),
					     NULL, virtio_video_event_cb);
		if (IS_ERR(vbuf))
			return PTR_ERR(vbuf);

		ret = virtio_video_queue_event_buffer(vv, vbuf);
		if (ret)
			return ret;
	}

	return 0;
}

int virtio_video_cmd_stream_create(struct virtio_video *vv, uint32_t stream_id,
				   enum virtio_video_format format,
				   const char *tag)
{
	struct virtio_video_stream_create *req_p;
	struct virtio_video_vbuffer *vbuf;
	int resource_type;

	switch (vv->res_type) {
	case RESOURCE_TYPE_GUEST_PAGES:
		resource_type = VIRTIO_VIDEO_MEM_TYPE_GUEST_PAGES;
		break;
	case RESOURCE_TYPE_VIRTIO_OBJECT:
		resource_type = VIRTIO_VIDEO_MEM_TYPE_VIRTIO_OBJECT;
		break;
	default:
		return -EINVAL;
	}

	req_p = virtio_video_alloc_req(vv, &vbuf, sizeof(*req_p));
	if (IS_ERR(req_p))
		return PTR_ERR(req_p);

	req_p->hdr.type = cpu_to_le32(VIRTIO_VIDEO_CMD_STREAM_CREATE);
	req_p->hdr.stream_id = cpu_to_le32(stream_id);
	req_p->coded_format = cpu_to_le32(format);
	req_p->in_mem_type = cpu_to_le32(resource_type);
	req_p->out_mem_type = cpu_to_le32(resource_type);

	strncpy(req_p->tag, tag, sizeof(req_p->tag) - 1);
	req_p->tag[sizeof(req_p->tag) - 1] = 0;

	return virtio_video_queue_cmd_buffer(vv, vbuf);
}

int virtio_video_cmd_stream_destroy(struct virtio_video *vv, uint32_t stream_id)
{
	struct virtio_video_stream_destroy *req_p;
	struct virtio_video_vbuffer *vbuf;

	req_p = virtio_video_alloc_req(vv, &vbuf, sizeof(*req_p));
	if (IS_ERR(req_p))
		return PTR_ERR(req_p);

	req_p->hdr.type = cpu_to_le32(VIRTIO_VIDEO_CMD_STREAM_DESTROY);
	req_p->hdr.stream_id = cpu_to_le32(stream_id);

	return virtio_video_queue_cmd_buffer(vv, vbuf);
}

int virtio_video_cmd_stream_drain(struct virtio_video *vv, uint32_t stream_id)
{
	struct virtio_video_stream_drain *req_p;
	struct virtio_video_vbuffer *vbuf;

	req_p = virtio_video_alloc_req(vv, &vbuf, sizeof(*req_p));
	if (IS_ERR(req_p))
		return PTR_ERR(req_p);

	req_p->hdr.type = cpu_to_le32(VIRTIO_VIDEO_CMD_STREAM_DRAIN);
	req_p->hdr.stream_id = cpu_to_le32(stream_id);

	return virtio_video_queue_cmd_buffer(vv, vbuf);
}

static void virtio_video_cmd_resource_create_core(
	struct virtio_video *vv, struct virtio_video_resource_create *req_p,
	uint32_t stream_id, uint32_t resource_id, uint32_t queue_type,
	unsigned int num_planes)
{
	req_p->hdr.type = cpu_to_le32(VIRTIO_VIDEO_CMD_RESOURCE_CREATE);
	req_p->hdr.stream_id = cpu_to_le32(stream_id);
	req_p->resource_id = cpu_to_le32(resource_id);
	req_p->queue_type = cpu_to_le32(queue_type);
	req_p->num_planes = cpu_to_le32(num_planes);
}

int virtio_video_cmd_resource_create_page(
	struct virtio_video *vv, uint32_t stream_id, uint32_t resource_id,
	uint32_t queue_type, unsigned int num_planes, unsigned int *num_entries,
	struct virtio_video_mem_entry *ents)
{
	struct virtio_video_resource_create *req_p;
	struct virtio_video_vbuffer *vbuf;
	unsigned int nents = 0;
	int i;

	req_p = virtio_video_alloc_req(vv, &vbuf, sizeof(*req_p));
	if (IS_ERR(req_p))
		return PTR_ERR(req_p);

	virtio_video_cmd_resource_create_core(vv, req_p, stream_id, resource_id,
					      queue_type, num_planes);

	for (i = 0; i < num_planes; i++) {
		nents += num_entries[i];
		req_p->num_entries[i] = cpu_to_le32(num_entries[i]);
	}

	vbuf->data_buf = ents;
	vbuf->data_size = sizeof(*ents) * nents;

	return virtio_video_queue_cmd_buffer(vv, vbuf);
}

int virtio_video_cmd_resource_create_object(
	struct virtio_video *vv, uint32_t stream_id, uint32_t resource_id,
	uint32_t queue_type, unsigned int num_planes, struct vb2_plane *planes,
	struct virtio_video_object_entry *ents)
{
	struct virtio_video_resource_create *req_p;
	struct virtio_video_vbuffer *vbuf;
	int i;

	req_p = virtio_video_alloc_req(vv, &vbuf, sizeof(*req_p));
	if (IS_ERR(req_p))
		return PTR_ERR(req_p);

	virtio_video_cmd_resource_create_core(vv, req_p, stream_id, resource_id,
					      queue_type, num_planes);

	req_p->planes_layout =
		cpu_to_le32(VIRTIO_VIDEO_PLANES_LAYOUT_SINGLE_BUFFER);
	for (i = 0; i < num_planes; i++)
		req_p->plane_offsets[i] = planes[i].data_offset;

	vbuf->data_buf = ents;
	vbuf->data_size = sizeof(*ents);

	return virtio_video_queue_cmd_buffer(vv, vbuf);
}

static void
virtio_video_cmd_resource_destroy_all_cb(struct virtio_video *vv,
					 struct virtio_video_vbuffer *vbuf)
{
	struct virtio_video_stream *stream = vbuf->priv;
	struct virtio_video_resource_destroy_all *req_p =
		(struct virtio_video_resource_destroy_all *)vbuf->buf;

	switch (le32_to_cpu(req_p->queue_type)) {
	case VIRTIO_VIDEO_QUEUE_TYPE_INPUT:
		stream->src_destroyed = true;
		break;
	case VIRTIO_VIDEO_QUEUE_TYPE_OUTPUT:
		stream->dst_destroyed = true;
		break;
	default:
		v4l2_err(&vv->v4l2_dev, "invalid queue type: %u\n",
			 req_p->queue_type);
		return;
	}

	wake_up(&vv->wq);
}

int virtio_video_cmd_resource_destroy_all(struct virtio_video *vv,
					  struct virtio_video_stream *stream,
					  enum virtio_video_queue_type qtype)
{
	struct virtio_video_resource_destroy_all *req_p;
	struct virtio_video_vbuffer *vbuf;

	req_p = virtio_video_alloc_req_resp
		(vv, &virtio_video_cmd_resource_destroy_all_cb,
		 &vbuf, sizeof(*req_p),
		 sizeof(struct virtio_video_cmd_hdr), NULL);
	if (IS_ERR(req_p))
		return PTR_ERR(req_p);

	req_p->hdr.type = cpu_to_le32(VIRTIO_VIDEO_CMD_RESOURCE_DESTROY_ALL);
	req_p->hdr.stream_id = cpu_to_le32(stream->stream_id);
	req_p->queue_type = cpu_to_le32(qtype);

	vbuf->priv = stream;

	return virtio_video_queue_cmd_buffer(vv, vbuf);
}

static void
virtio_video_cmd_resource_queue_cb(struct virtio_video *vv,
				   struct virtio_video_vbuffer *vbuf)
{
	uint32_t flags, bytesused;
	uint64_t timestamp;
	struct virtio_video_buffer *virtio_vb = vbuf->priv;
	struct virtio_video_resource_queue_resp *resp =
		(struct virtio_video_resource_queue_resp *)vbuf->resp_buf;

	flags = le32_to_cpu(resp->flags);
	bytesused = le32_to_cpu(resp->size);
	timestamp = le64_to_cpu(resp->timestamp);

	virtio_video_buf_done(virtio_vb, flags, timestamp, bytesused);
}

int virtio_video_cmd_resource_queue(struct virtio_video *vv, uint32_t stream_id,
				    struct virtio_video_buffer *virtio_vb,
				    uint32_t data_size[],
				    uint8_t num_data_size, uint32_t queue_type)
{
	uint8_t i;
	struct virtio_video_resource_queue *req_p;
	struct virtio_video_resource_queue_resp *resp_p;
	struct virtio_video_vbuffer *vbuf;
	size_t resp_size = sizeof(struct virtio_video_resource_queue_resp);

	req_p = virtio_video_alloc_req_resp(vv,
					    &virtio_video_cmd_resource_queue_cb,
					    &vbuf, sizeof(*req_p), resp_size,
					    NULL);
	if (IS_ERR(req_p))
		return PTR_ERR(req_p);

	req_p->hdr.type = cpu_to_le32(VIRTIO_VIDEO_CMD_RESOURCE_QUEUE);
	req_p->hdr.stream_id = cpu_to_le32(stream_id);
	req_p->queue_type = cpu_to_le32(queue_type);
	req_p->resource_id = cpu_to_le32(virtio_vb->resource_id);
	req_p->num_data_sizes = num_data_size;
	req_p->timestamp =
		cpu_to_le64(virtio_vb->v4l2_m2m_vb.vb.vb2_buf.timestamp);

	for (i = 0; i < num_data_size; ++i)
		req_p->data_sizes[i] = cpu_to_le32(data_size[i]);

	resp_p = (struct virtio_video_resource_queue_resp *)vbuf->resp_buf;
	memset(resp_p, 0, sizeof(*resp_p));

	vbuf->priv = virtio_vb;

	return virtio_video_queue_cmd_buffer(vv, vbuf);
}

static void
virtio_video_cmd_queue_clear_cb(struct virtio_video *vv,
				struct virtio_video_vbuffer *vbuf)
{
	struct virtio_video_stream *stream = vbuf->priv;
	struct virtio_video_queue_clear *req_p =
		(struct virtio_video_queue_clear *)vbuf->buf;

	if (le32_to_cpu(req_p->queue_type) == VIRTIO_VIDEO_QUEUE_TYPE_INPUT)
		stream->src_cleared = true;
	else
		stream->dst_cleared = true;

	wake_up(&vv->wq);
}

int virtio_video_cmd_queue_clear(struct virtio_video *vv,
				 struct virtio_video_stream *stream,
				 uint32_t queue_type)
{
	struct virtio_video_queue_clear *req_p;
	struct virtio_video_vbuffer *vbuf;

	req_p = virtio_video_alloc_req_resp
		(vv, &virtio_video_cmd_queue_clear_cb,
		 &vbuf, sizeof(*req_p),
		 sizeof(struct virtio_video_cmd_hdr), NULL);
	if (IS_ERR(req_p))
		return PTR_ERR(req_p);

	req_p->hdr.type = cpu_to_le32(VIRTIO_VIDEO_CMD_QUEUE_CLEAR);
	req_p->hdr.stream_id = cpu_to_le32(stream->stream_id);
	req_p->queue_type = cpu_to_le32(queue_type);

	vbuf->priv = stream;

	return virtio_video_queue_cmd_buffer(vv, vbuf);
}

static void
virtio_video_query_caps_cb(struct virtio_video *vv,
			   struct virtio_video_vbuffer *vbuf)
{
	bool *got_resp_p = vbuf->priv;
	*got_resp_p = true;
	wake_up(&vv->wq);
}

int virtio_video_query_capability(struct virtio_video *vv, void *resp_buf,
				  size_t resp_size, uint32_t queue_type)
{
	struct virtio_video_query_capability *req_p = NULL;
	struct virtio_video_vbuffer *vbuf = NULL;

	if (!vv || !resp_buf)
		return -1;

	req_p = virtio_video_alloc_req_resp(vv, &virtio_video_query_caps_cb,
					    &vbuf, sizeof(*req_p), resp_size,
					    resp_buf);
	if (IS_ERR(req_p))
		return -1;

	req_p->hdr.type = cpu_to_le32(VIRTIO_VIDEO_CMD_QUERY_CAPABILITY);
	req_p->queue_type = cpu_to_le32(queue_type);

	vbuf->priv = &vv->got_caps;

	return virtio_video_queue_cmd_buffer(vv, vbuf);
}

int virtio_video_query_control_level(struct virtio_video *vv, void *resp_buf,
				     size_t resp_size, uint32_t format)
{
	struct virtio_video_query_control *req_p = NULL;
	struct virtio_video_query_control_level *ctrl_l = NULL;
	struct virtio_video_vbuffer *vbuf = NULL;
	uint32_t req_size = 0;

	if (!vv || !resp_buf)
		return -1;

	req_size = sizeof(struct virtio_video_query_control) +
		sizeof(struct virtio_video_query_control_level);

	req_p = virtio_video_alloc_req_resp(vv, &virtio_video_query_caps_cb,
					    &vbuf, req_size, resp_size,
					    resp_buf);
	if (IS_ERR(req_p))
		return -1;

	req_p->hdr.type = cpu_to_le32(VIRTIO_VIDEO_CMD_QUERY_CONTROL);
	req_p->control = cpu_to_le32(VIRTIO_VIDEO_CONTROL_LEVEL);
	ctrl_l = (void *)((char *)req_p +
			  sizeof(struct virtio_video_query_control));
	ctrl_l->format = cpu_to_le32(format);

	vbuf->priv = &vv->got_control;

	return virtio_video_queue_cmd_buffer(vv, vbuf);
}

int virtio_video_query_control_profile(struct virtio_video *vv, void *resp_buf,
				       size_t resp_size, uint32_t format)
{
	struct virtio_video_query_control *req_p = NULL;
	struct virtio_video_query_control_profile *ctrl_p = NULL;
	struct virtio_video_vbuffer *vbuf = NULL;
	uint32_t req_size = 0;

	if (!vv || !resp_buf)
		return -1;

	req_size = sizeof(struct virtio_video_query_control) +
		sizeof(struct virtio_video_query_control_profile);

	req_p = virtio_video_alloc_req_resp(vv, &virtio_video_query_caps_cb,
					    &vbuf, req_size, resp_size,
					    resp_buf);
	if (IS_ERR(req_p))
		return -1;

	req_p->hdr.type = cpu_to_le32(VIRTIO_VIDEO_CMD_QUERY_CONTROL);
	req_p->control = cpu_to_le32(VIRTIO_VIDEO_CONTROL_PROFILE);
	ctrl_p = (void *)((char *)req_p +
			  sizeof(struct virtio_video_query_control));
	ctrl_p->format = cpu_to_le32(format);

	vbuf->priv = &vv->got_control;

	return virtio_video_queue_cmd_buffer(vv, vbuf);
}

static void
virtio_video_cmd_get_params_cb(struct virtio_video *vv,
			       struct virtio_video_vbuffer *vbuf)
{
	int i;
	struct virtio_video_get_params_resp *resp =
		(struct virtio_video_get_params_resp *)vbuf->resp_buf;
	struct virtio_video_params *params = &resp->params;
	struct virtio_video_stream *stream = vbuf->priv;
	enum virtio_video_queue_type queue_type;
	struct video_format_info *format_info = NULL;

	queue_type = le32_to_cpu(params->queue_type);
	if (queue_type == VIRTIO_VIDEO_QUEUE_TYPE_INPUT)
		format_info = &stream->in_info;
	else
		format_info = &stream->out_info;

	if (!format_info)
		return;

	format_info->frame_rate = le32_to_cpu(params->frame_rate);
	format_info->frame_width = le32_to_cpu(params->frame_width);
	format_info->frame_height = le32_to_cpu(params->frame_height);
	format_info->min_buffers = le32_to_cpu(params->min_buffers);
	format_info->max_buffers = le32_to_cpu(params->max_buffers);
	format_info->fourcc_format =
		virtio_video_format_to_v4l2(le32_to_cpu(params->format));

	format_info->crop.top = le32_to_cpu(params->crop.top);
	format_info->crop.left = le32_to_cpu(params->crop.left);
	format_info->crop.width = le32_to_cpu(params->crop.width);
	format_info->crop.height = le32_to_cpu(params->crop.height);

	format_info->num_planes = le32_to_cpu(params->num_planes);
	for (i = 0; i < le32_to_cpu(params->num_planes); i++) {
		struct virtio_video_plane_format *plane_formats =
						 &params->plane_formats[i];
		struct video_plane_format *plane_format =
						 &format_info->plane_format[i];

		plane_format->plane_size =
				 le32_to_cpu(plane_formats->plane_size);
		plane_format->stride = le32_to_cpu(plane_formats->stride);
	}

	format_info->is_updated = true;
	wake_up(&vv->wq);
}

int virtio_video_cmd_get_params(struct virtio_video *vv,
			       struct virtio_video_stream *stream,
			       uint32_t queue_type)
{
	int ret;
	struct virtio_video_get_params *req_p = NULL;
	struct virtio_video_vbuffer *vbuf = NULL;
	struct virtio_video_get_params_resp *resp_p;
	struct video_format_info *format_info = NULL;
	size_t resp_size = sizeof(struct virtio_video_get_params_resp);

	if (!vv || !stream)
		return -1;

	req_p = virtio_video_alloc_req_resp(vv,
					&virtio_video_cmd_get_params_cb,
					&vbuf, sizeof(*req_p), resp_size,
					NULL);

	if (IS_ERR(req_p))
		return PTR_ERR(req_p);

	req_p->hdr.type = cpu_to_le32(VIRTIO_VIDEO_CMD_GET_PARAMS);
	req_p->hdr.stream_id = cpu_to_le32(stream->stream_id);
	req_p->queue_type = cpu_to_le32(queue_type);

	resp_p = (struct virtio_video_get_params_resp *)vbuf->resp_buf;
	memset(resp_p, 0, sizeof(*resp_p));

	if (req_p->queue_type == VIRTIO_VIDEO_QUEUE_TYPE_INPUT)
		format_info = &stream->in_info;
	else
		format_info = &stream->out_info;

	format_info->is_updated = false;

	vbuf->priv = stream;
	ret = virtio_video_queue_cmd_buffer(vv, vbuf);
	if (ret)
		return ret;

	ret = wait_event_timeout(vv->wq,
				 format_info->is_updated, 5 * HZ);
	if (ret == 0) {
		v4l2_err(&vv->v4l2_dev, "timed out waiting for get_params\n");
		return -1;
	}
	return 0;
}

int
virtio_video_cmd_set_params(struct virtio_video *vv,
			    struct virtio_video_stream *stream,
			    struct video_format_info *format_info,
			    uint32_t queue_type)
{
	int i;
	struct virtio_video_set_params *req_p;
	struct virtio_video_vbuffer *vbuf;

	req_p = virtio_video_alloc_req(vv, &vbuf, sizeof(*req_p));
	if (IS_ERR(req_p))
		return PTR_ERR(req_p);

	req_p->hdr.type = cpu_to_le32(VIRTIO_VIDEO_CMD_SET_PARAMS);
	req_p->hdr.stream_id = cpu_to_le32(stream->stream_id);
	req_p->params.queue_type = cpu_to_le32(queue_type);
	req_p->params.frame_rate = cpu_to_le32(format_info->frame_rate);
	req_p->params.frame_width = cpu_to_le32(format_info->frame_width);
	req_p->params.frame_height = cpu_to_le32(format_info->frame_height);
	req_p->params.format = virtio_video_v4l2_format_to_virtio(
				 cpu_to_le32(format_info->fourcc_format));
	req_p->params.min_buffers = cpu_to_le32(format_info->min_buffers);
	req_p->params.max_buffers = cpu_to_le32(format_info->max_buffers);
	req_p->params.num_planes = cpu_to_le32(format_info->num_planes);

	for (i = 0; i < format_info->num_planes; i++) {
		struct virtio_video_plane_format *plane_formats =
			&req_p->params.plane_formats[i];
		struct video_plane_format *plane_format =
			&format_info->plane_format[i];
		plane_formats->plane_size =
				 cpu_to_le32(plane_format->plane_size);
		plane_formats->stride = cpu_to_le32(plane_format->stride);
	}

	return virtio_video_queue_cmd_buffer(vv, vbuf);
}

static void
virtio_video_cmd_get_ctrl_profile_cb(struct virtio_video *vv,
				     struct virtio_video_vbuffer *vbuf)
{
	struct virtio_video_get_control_resp *resp =
		(struct virtio_video_get_control_resp *)vbuf->resp_buf;
	struct virtio_video_control_val_profile *resp_p = NULL;
	struct virtio_video_stream *stream = vbuf->priv;
	struct video_control_info *control = &stream->control;

	if (!control)
		return;

	resp_p = (void *)((char *) resp +
			  sizeof(struct virtio_video_get_control_resp));

	control->profile = le32_to_cpu(resp_p->profile);
	control->is_updated = true;
	wake_up(&vv->wq);
}

static void
virtio_video_cmd_get_ctrl_level_cb(struct virtio_video *vv,
				   struct virtio_video_vbuffer *vbuf)
{
	struct virtio_video_get_control_resp *resp =
		(struct virtio_video_get_control_resp *)vbuf->resp_buf;
	struct virtio_video_control_val_level *resp_p = NULL;
	struct virtio_video_stream *stream = vbuf->priv;
	struct video_control_info *control = &stream->control;

	if (!control)
		return;

	resp_p = (void *)((char *)resp +
			  sizeof(struct virtio_video_get_control_resp));

	control->level = le32_to_cpu(resp_p->level);
	control->is_updated = true;
	wake_up(&vv->wq);
}

static void
virtio_video_cmd_get_ctrl_bitrate_cb(struct virtio_video *vv,
				     struct virtio_video_vbuffer *vbuf)
{
	struct virtio_video_get_control_resp *resp =
		(struct virtio_video_get_control_resp *)vbuf->resp_buf;
	struct virtio_video_control_val_bitrate *resp_p = NULL;
	struct virtio_video_stream *stream = vbuf->priv;
	struct video_control_info *control = &stream->control;

	if (!control)
		return;

	resp_p = (void *)((char *) resp +
			  sizeof(struct virtio_video_get_control_resp));

	control->bitrate = le32_to_cpu(resp_p->bitrate);
	control->is_updated = true;
	wake_up(&vv->wq);
}

int virtio_video_cmd_get_control(struct virtio_video *vv,
				 struct virtio_video_stream *stream,
				 uint32_t virtio_ctrl)
{
	int ret = 0;
	struct virtio_video_get_control *req_p = NULL;
	struct virtio_video_get_control_resp *resp_p = NULL;
	struct virtio_video_vbuffer *vbuf = NULL;
	size_t resp_size = sizeof(struct virtio_video_get_control_resp);
	virtio_video_resp_cb cb;

	if (!vv)
		return -1;

	switch (virtio_ctrl) {
	case VIRTIO_VIDEO_CONTROL_PROFILE:
		resp_size += sizeof(struct virtio_video_control_val_profile);
		cb = &virtio_video_cmd_get_ctrl_profile_cb;
		break;
	case VIRTIO_VIDEO_CONTROL_LEVEL:
		resp_size += sizeof(struct virtio_video_control_val_level);
		cb = &virtio_video_cmd_get_ctrl_level_cb;
		break;
	case VIRTIO_VIDEO_CONTROL_BITRATE:
		resp_size += sizeof(struct virtio_video_control_val_bitrate);
		cb = &virtio_video_cmd_get_ctrl_bitrate_cb;
		break;
	default:
		return -1;
	}

	req_p = virtio_video_alloc_req_resp(vv, cb, &vbuf,
					    sizeof(*req_p), resp_size, NULL);
	if (IS_ERR(req_p))
		return PTR_ERR(req_p);

	req_p->hdr.type = cpu_to_le32(VIRTIO_VIDEO_CMD_GET_CONTROL);
	req_p->hdr.stream_id = cpu_to_le32(stream->stream_id);
	req_p->control = cpu_to_le32(virtio_ctrl);

	resp_p = (struct virtio_video_get_control_resp *)vbuf->resp_buf;
	memset(resp_p, 0, resp_size);

	stream->control.is_updated = false;

	vbuf->priv = stream;
	ret = virtio_video_queue_cmd_buffer(vv, vbuf);
	if (ret)
		return ret;

	ret = wait_event_timeout(vv->wq, stream->control.is_updated, 5 * HZ);
	if (ret == 0) {
		v4l2_err(&vv->v4l2_dev, "timed out waiting for get_params\n");
		return -1;
	}
	return 0;
}

int virtio_video_cmd_set_control(struct virtio_video *vv, uint32_t stream_id,
				 uint32_t control, uint32_t value)
{
	struct virtio_video_set_control *req_p = NULL;
	struct virtio_video_vbuffer *vbuf = NULL;
	struct virtio_video_control_val_level *ctrl_l = NULL;
	struct virtio_video_control_val_profile *ctrl_p = NULL;
	struct virtio_video_control_val_bitrate *ctrl_b = NULL;
	size_t size;

	if (!vv || value == 0)
		return -EINVAL;

	switch (control) {
	case VIRTIO_VIDEO_CONTROL_PROFILE:
		size = sizeof(struct virtio_video_control_val_profile);
		break;
	case VIRTIO_VIDEO_CONTROL_LEVEL:
		size = sizeof(struct virtio_video_control_val_level);
		break;
	case VIRTIO_VIDEO_CONTROL_BITRATE:
		size = sizeof(struct virtio_video_control_val_bitrate);
		break;
	case VIRTIO_VIDEO_CONTROL_FORCE_KEYFRAME:
		size = 0;
		break;
	default:
		return -1;
	}

	req_p = virtio_video_alloc_req(vv, &vbuf, size + sizeof(*req_p));
	if (IS_ERR(req_p))
		return PTR_ERR(req_p);

	req_p->hdr.type = cpu_to_le32(VIRTIO_VIDEO_CMD_SET_CONTROL);
	req_p->hdr.stream_id = cpu_to_le32(stream_id);
	req_p->control = cpu_to_le32(control);

	switch (control) {
	case VIRTIO_VIDEO_CONTROL_PROFILE:
		ctrl_p = (void *)((char *)req_p +
				  sizeof(struct virtio_video_set_control));
		ctrl_p->profile = cpu_to_le32(value);
		break;
	case VIRTIO_VIDEO_CONTROL_LEVEL:
		ctrl_l = (void *)((char *)req_p +
				 sizeof(struct virtio_video_set_control));
		ctrl_l->level = cpu_to_le32(value);
		break;
	case VIRTIO_VIDEO_CONTROL_BITRATE:
		ctrl_b = (void *)((char *)req_p +
				 sizeof(struct virtio_video_set_control));
		ctrl_b->bitrate = cpu_to_le32(value);
		break;
	case VIRTIO_VIDEO_CONTROL_FORCE_KEYFRAME:
		// Button controls have no value.
		break;
	}

	return virtio_video_queue_cmd_buffer(vv, vbuf);
}
