// SPDX-License-Identifier: GPL-2.0 OR MIT

/*
 * Xen para-virtual sound device
 *
 * Copyright (C) 2016-2018 EPAM Systems Inc.
 *
 * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
 */

#include <xen/events.h>
#include <xen/grant_table.h>
#include <xen/xen.h>
#include <xen/xenbus.h>

#include "xen_snd_front.h"
#include "xen_snd_front_alsa.h"
#include "xen_snd_front_cfg.h"
#include "xen_snd_front_evtchnl.h"

static irqreturn_t evtchnl_interrupt_req(int irq, void *dev_id)
{
	struct xen_snd_front_evtchnl *channel = dev_id;
	struct xen_snd_front_info *front_info = channel->front_info;
	struct xensnd_resp *resp;
	RING_IDX i, rp;

	if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED))
		return IRQ_HANDLED;

	mutex_lock(&channel->ring_io_lock);

again:
	rp = channel->u.req.ring.sring->rsp_prod;
	/* Ensure we see queued responses up to rp. */
	rmb();

	/*
	 * Assume that the backend is trusted to always write sane values
	 * to the ring counters, so no overflow checks on frontend side
	 * are required.
	 */
	for (i = channel->u.req.ring.rsp_cons; i != rp; i++) {
		resp = RING_GET_RESPONSE(&channel->u.req.ring, i);
		if (resp->id != channel->evt_id)
			continue;
		switch (resp->operation) {
		case XENSND_OP_OPEN:
		case XENSND_OP_CLOSE:
		case XENSND_OP_READ:
		case XENSND_OP_WRITE:
		case XENSND_OP_TRIGGER:
			channel->u.req.resp_status = resp->status;
			complete(&channel->u.req.completion);
			break;
		case XENSND_OP_HW_PARAM_QUERY:
			channel->u.req.resp_status = resp->status;
			channel->u.req.resp.hw_param =
					resp->resp.hw_param;
			complete(&channel->u.req.completion);
			break;

		default:
			dev_err(&front_info->xb_dev->dev,
				"Operation %d is not supported\n",
				resp->operation);
			break;
		}
	}

	channel->u.req.ring.rsp_cons = i;
	if (i != channel->u.req.ring.req_prod_pvt) {
		int more_to_do;

		RING_FINAL_CHECK_FOR_RESPONSES(&channel->u.req.ring,
					       more_to_do);
		if (more_to_do)
			goto again;
	} else {
		channel->u.req.ring.sring->rsp_event = i + 1;
	}

	mutex_unlock(&channel->ring_io_lock);
	return IRQ_HANDLED;
}

static irqreturn_t evtchnl_interrupt_evt(int irq, void *dev_id)
{
	struct xen_snd_front_evtchnl *channel = dev_id;
	struct xensnd_event_page *page = channel->u.evt.page;
	u32 cons, prod;

	if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED))
		return IRQ_HANDLED;

	mutex_lock(&channel->ring_io_lock);

	prod = page->in_prod;
	/* Ensure we see ring contents up to prod. */
	virt_rmb();
	if (prod == page->in_cons)
		goto out;

	/*
	 * Assume that the backend is trusted to always write sane values
	 * to the ring counters, so no overflow checks on frontend side
	 * are required.
	 */
	for (cons = page->in_cons; cons != prod; cons++) {
		struct xensnd_evt *event;

		event = &XENSND_IN_RING_REF(page, cons);
		if (unlikely(event->id != channel->evt_id++))
			continue;

		switch (event->type) {
		case XENSND_EVT_CUR_POS:
			xen_snd_front_alsa_handle_cur_pos(channel,
							  event->op.cur_pos.position);
			break;
		}
	}

	page->in_cons = cons;
	/* Ensure ring contents. */
	virt_wmb();

out:
	mutex_unlock(&channel->ring_io_lock);
	return IRQ_HANDLED;
}

void xen_snd_front_evtchnl_flush(struct xen_snd_front_evtchnl *channel)
{
	int notify;

	channel->u.req.ring.req_prod_pvt++;
	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&channel->u.req.ring, notify);
	if (notify)
		notify_remote_via_irq(channel->irq);
}

static void evtchnl_free(struct xen_snd_front_info *front_info,
			 struct xen_snd_front_evtchnl *channel)
{
	unsigned long page = 0;

	if (channel->type == EVTCHNL_TYPE_REQ)
		page = (unsigned long)channel->u.req.ring.sring;
	else if (channel->type == EVTCHNL_TYPE_EVT)
		page = (unsigned long)channel->u.evt.page;

	if (!page)
		return;

	channel->state = EVTCHNL_STATE_DISCONNECTED;
	if (channel->type == EVTCHNL_TYPE_REQ) {
		/* Release all who still waits for response if any. */
		channel->u.req.resp_status = -EIO;
		complete_all(&channel->u.req.completion);
	}

	if (channel->irq)
		unbind_from_irqhandler(channel->irq, channel);

	if (channel->port)
		xenbus_free_evtchn(front_info->xb_dev, channel->port);

	/* End access and free the page. */
	if (channel->gref != GRANT_INVALID_REF)
		gnttab_end_foreign_access(channel->gref, 0, page);
	else
		free_page(page);

	memset(channel, 0, sizeof(*channel));
}

void xen_snd_front_evtchnl_free_all(struct xen_snd_front_info *front_info)
{
	int i;

	if (!front_info->evt_pairs)
		return;

	for (i = 0; i < front_info->num_evt_pairs; i++) {
		evtchnl_free(front_info, &front_info->evt_pairs[i].req);
		evtchnl_free(front_info, &front_info->evt_pairs[i].evt);
	}

	kfree(front_info->evt_pairs);
	front_info->evt_pairs = NULL;
}

static int evtchnl_alloc(struct xen_snd_front_info *front_info, int index,
			 struct xen_snd_front_evtchnl *channel,
			 enum xen_snd_front_evtchnl_type type)
{
	struct xenbus_device *xb_dev = front_info->xb_dev;
	unsigned long page;
	grant_ref_t gref;
	irq_handler_t handler;
	char *handler_name = NULL;
	int ret;

	memset(channel, 0, sizeof(*channel));
	channel->type = type;
	channel->index = index;
	channel->front_info = front_info;
	channel->state = EVTCHNL_STATE_DISCONNECTED;
	channel->gref = GRANT_INVALID_REF;
	page = get_zeroed_page(GFP_KERNEL);
	if (!page) {
		ret = -ENOMEM;
		goto fail;
	}

	handler_name = kasprintf(GFP_KERNEL, "%s-%s", XENSND_DRIVER_NAME,
				 type == EVTCHNL_TYPE_REQ ?
				 XENSND_FIELD_RING_REF :
				 XENSND_FIELD_EVT_RING_REF);
	if (!handler_name) {
		ret = -ENOMEM;
		goto fail;
	}

	mutex_init(&channel->ring_io_lock);

	if (type == EVTCHNL_TYPE_REQ) {
		struct xen_sndif_sring *sring = (struct xen_sndif_sring *)page;

		init_completion(&channel->u.req.completion);
		mutex_init(&channel->u.req.req_io_lock);
		SHARED_RING_INIT(sring);
		FRONT_RING_INIT(&channel->u.req.ring, sring, XEN_PAGE_SIZE);

		ret = xenbus_grant_ring(xb_dev, sring, 1, &gref);
		if (ret < 0) {
			channel->u.req.ring.sring = NULL;
			goto fail;
		}

		handler = evtchnl_interrupt_req;
	} else {
		ret = gnttab_grant_foreign_access(xb_dev->otherend_id,
						  virt_to_gfn((void *)page), 0);
		if (ret < 0)
			goto fail;

		channel->u.evt.page = (struct xensnd_event_page *)page;
		gref = ret;
		handler = evtchnl_interrupt_evt;
	}

	channel->gref = gref;

	ret = xenbus_alloc_evtchn(xb_dev, &channel->port);
	if (ret < 0)
		goto fail;

	ret = bind_evtchn_to_irq(channel->port);
	if (ret < 0) {
		dev_err(&xb_dev->dev,
			"Failed to bind IRQ for domid %d port %d: %d\n",
			front_info->xb_dev->otherend_id, channel->port, ret);
		goto fail;
	}

	channel->irq = ret;

	ret = request_threaded_irq(channel->irq, NULL, handler,
				   IRQF_ONESHOT, handler_name, channel);
	if (ret < 0) {
		dev_err(&xb_dev->dev, "Failed to request IRQ %d: %d\n",
			channel->irq, ret);
		goto fail;
	}

	kfree(handler_name);
	return 0;

fail:
	if (page)
		free_page(page);
	kfree(handler_name);
	dev_err(&xb_dev->dev, "Failed to allocate ring: %d\n", ret);
	return ret;
}

int xen_snd_front_evtchnl_create_all(struct xen_snd_front_info *front_info,
				     int num_streams)
{
	struct xen_front_cfg_card *cfg = &front_info->cfg;
	struct device *dev = &front_info->xb_dev->dev;
	int d, ret = 0;

	front_info->evt_pairs =
			kcalloc(num_streams,
				sizeof(struct xen_snd_front_evtchnl_pair),
				GFP_KERNEL);
	if (!front_info->evt_pairs)
		return -ENOMEM;

	/* Iterate over devices and their streams and create event channels. */
	for (d = 0; d < cfg->num_pcm_instances; d++) {
		struct xen_front_cfg_pcm_instance *pcm_instance;
		int s, index;

		pcm_instance = &cfg->pcm_instances[d];

		for (s = 0; s < pcm_instance->num_streams_pb; s++) {
			index = pcm_instance->streams_pb[s].index;

			ret = evtchnl_alloc(front_info, index,
					    &front_info->evt_pairs[index].req,
					    EVTCHNL_TYPE_REQ);
			if (ret < 0) {
				dev_err(dev, "Error allocating control channel\n");
				goto fail;
			}

			ret = evtchnl_alloc(front_info, index,
					    &front_info->evt_pairs[index].evt,
					    EVTCHNL_TYPE_EVT);
			if (ret < 0) {
				dev_err(dev, "Error allocating in-event channel\n");
				goto fail;
			}
		}

		for (s = 0; s < pcm_instance->num_streams_cap; s++) {
			index = pcm_instance->streams_cap[s].index;

			ret = evtchnl_alloc(front_info, index,
					    &front_info->evt_pairs[index].req,
					    EVTCHNL_TYPE_REQ);
			if (ret < 0) {
				dev_err(dev, "Error allocating control channel\n");
				goto fail;
			}

			ret = evtchnl_alloc(front_info, index,
					    &front_info->evt_pairs[index].evt,
					    EVTCHNL_TYPE_EVT);
			if (ret < 0) {
				dev_err(dev, "Error allocating in-event channel\n");
				goto fail;
			}
		}
	}

	front_info->num_evt_pairs = num_streams;
	return 0;

fail:
	xen_snd_front_evtchnl_free_all(front_info);
	return ret;
}

static int evtchnl_publish(struct xenbus_transaction xbt,
			   struct xen_snd_front_evtchnl *channel,
			   const char *path, const char *node_ring,
			   const char *node_chnl)
{
	struct xenbus_device *xb_dev = channel->front_info->xb_dev;
	int ret;

	/* Write control channel ring reference. */
	ret = xenbus_printf(xbt, path, node_ring, "%u", channel->gref);
	if (ret < 0) {
		dev_err(&xb_dev->dev, "Error writing ring-ref: %d\n", ret);
		return ret;
	}

	/* Write event channel ring reference. */
	ret = xenbus_printf(xbt, path, node_chnl, "%u", channel->port);
	if (ret < 0) {
		dev_err(&xb_dev->dev, "Error writing event channel: %d\n", ret);
		return ret;
	}

	return 0;
}

int xen_snd_front_evtchnl_publish_all(struct xen_snd_front_info *front_info)
{
	struct xen_front_cfg_card *cfg = &front_info->cfg;
	struct xenbus_transaction xbt;
	int ret, d;

again:
	ret = xenbus_transaction_start(&xbt);
	if (ret < 0) {
		xenbus_dev_fatal(front_info->xb_dev, ret,
				 "starting transaction");
		return ret;
	}

	for (d = 0; d < cfg->num_pcm_instances; d++) {
		struct xen_front_cfg_pcm_instance *pcm_instance;
		int s, index;

		pcm_instance = &cfg->pcm_instances[d];

		for (s = 0; s < pcm_instance->num_streams_pb; s++) {
			index = pcm_instance->streams_pb[s].index;

			ret = evtchnl_publish(xbt,
					      &front_info->evt_pairs[index].req,
					      pcm_instance->streams_pb[s].xenstore_path,
					      XENSND_FIELD_RING_REF,
					      XENSND_FIELD_EVT_CHNL);
			if (ret < 0)
				goto fail;

			ret = evtchnl_publish(xbt,
					      &front_info->evt_pairs[index].evt,
					      pcm_instance->streams_pb[s].xenstore_path,
					      XENSND_FIELD_EVT_RING_REF,
					      XENSND_FIELD_EVT_EVT_CHNL);
			if (ret < 0)
				goto fail;
		}

		for (s = 0; s < pcm_instance->num_streams_cap; s++) {
			index = pcm_instance->streams_cap[s].index;

			ret = evtchnl_publish(xbt,
					      &front_info->evt_pairs[index].req,
					      pcm_instance->streams_cap[s].xenstore_path,
					      XENSND_FIELD_RING_REF,
					      XENSND_FIELD_EVT_CHNL);
			if (ret < 0)
				goto fail;

			ret = evtchnl_publish(xbt,
					      &front_info->evt_pairs[index].evt,
					      pcm_instance->streams_cap[s].xenstore_path,
					      XENSND_FIELD_EVT_RING_REF,
					      XENSND_FIELD_EVT_EVT_CHNL);
			if (ret < 0)
				goto fail;
		}
	}
	ret = xenbus_transaction_end(xbt, 0);
	if (ret < 0) {
		if (ret == -EAGAIN)
			goto again;

		xenbus_dev_fatal(front_info->xb_dev, ret,
				 "completing transaction");
		goto fail_to_end;
	}
	return 0;
fail:
	xenbus_transaction_end(xbt, 1);
fail_to_end:
	xenbus_dev_fatal(front_info->xb_dev, ret, "writing XenStore");
	return ret;
}

void xen_snd_front_evtchnl_pair_set_connected(struct xen_snd_front_evtchnl_pair *evt_pair,
					      bool is_connected)
{
	enum xen_snd_front_evtchnl_state state;

	if (is_connected)
		state = EVTCHNL_STATE_CONNECTED;
	else
		state = EVTCHNL_STATE_DISCONNECTED;

	mutex_lock(&evt_pair->req.ring_io_lock);
	evt_pair->req.state = state;
	mutex_unlock(&evt_pair->req.ring_io_lock);

	mutex_lock(&evt_pair->evt.ring_io_lock);
	evt_pair->evt.state = state;
	mutex_unlock(&evt_pair->evt.ring_io_lock);
}

void xen_snd_front_evtchnl_pair_clear(struct xen_snd_front_evtchnl_pair *evt_pair)
{
	mutex_lock(&evt_pair->req.ring_io_lock);
	evt_pair->req.evt_next_id = 0;
	mutex_unlock(&evt_pair->req.ring_io_lock);

	mutex_lock(&evt_pair->evt.ring_io_lock);
	evt_pair->evt.evt_next_id = 0;
	mutex_unlock(&evt_pair->evt.ring_io_lock);
}

