All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleksandr Andrushchenko <andr2000@gmail.com>
To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org,
	alsa-devel@alsa-project.org, jgross@suse.com,
	boris.ostrovsky@oracle.com, konrad.wilk@oracle.com,
	perex@perex.cz, tiwai@suse.com
Cc: andr2000@gmail.com,
	Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Subject: [PATCH v2 3/5] ALSA: xen-front: Implement Xen event channel handling
Date: Mon, 16 Apr 2018 09:24:51 +0300	[thread overview]
Message-ID: <20180416062453.24743-4-andr2000@gmail.com> (raw)
In-Reply-To: <20180416062453.24743-1-andr2000@gmail.com>

From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>

Handle Xen event channels:
  - create for all configured streams and publish
    corresponding ring references and event channels in Xen store,
    so backend can connect
  - implement event channels interrupt handlers
  - create and destroy event channels with respect to Xen bus state

Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
---
 sound/xen/Makefile                |   3 +-
 sound/xen/xen_snd_front.c         |  10 +-
 sound/xen/xen_snd_front.h         |   7 +
 sound/xen/xen_snd_front_evtchnl.c | 474 ++++++++++++++++++++++++++++++++++++++
 sound/xen/xen_snd_front_evtchnl.h |  92 ++++++++
 5 files changed, 584 insertions(+), 2 deletions(-)
 create mode 100644 sound/xen/xen_snd_front_evtchnl.c
 create mode 100644 sound/xen/xen_snd_front_evtchnl.h

diff --git a/sound/xen/Makefile b/sound/xen/Makefile
index 06705bef61fa..03c669984000 100644
--- a/sound/xen/Makefile
+++ b/sound/xen/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0 OR MIT
 
 snd_xen_front-objs := xen_snd_front.o \
-		      xen_snd_front_cfg.o
+		      xen_snd_front_cfg.o \
+		      xen_snd_front_evtchnl.o
 
 obj-$(CONFIG_SND_XEN_FRONTEND) += snd_xen_front.o
diff --git a/sound/xen/xen_snd_front.c b/sound/xen/xen_snd_front.c
index 65d2494a9d14..eb46bf4070f9 100644
--- a/sound/xen/xen_snd_front.c
+++ b/sound/xen/xen_snd_front.c
@@ -18,9 +18,11 @@
 #include <xen/interface/io/sndif.h>
 
 #include "xen_snd_front.h"
+#include "xen_snd_front_evtchnl.h"
 
 static void xen_snd_drv_fini(struct xen_snd_front_info *front_info)
 {
+	xen_snd_front_evtchnl_free_all(front_info);
 }
 
 static int sndback_initwait(struct xen_snd_front_info *front_info)
@@ -32,7 +34,12 @@ static int sndback_initwait(struct xen_snd_front_info *front_info)
 	if (ret < 0)
 		return ret;
 
-	return 0;
+	/* create event channels for all streams and publish */
+	ret = xen_snd_front_evtchnl_create_all(front_info, num_streams);
+	if (ret < 0)
+		return ret;
+
+	return xen_snd_front_evtchnl_publish_all(front_info);
 }
 
 static int sndback_connect(struct xen_snd_front_info *front_info)
@@ -122,6 +129,7 @@ static int xen_drv_probe(struct xenbus_device *xb_dev,
 		return -ENOMEM;
 
 	front_info->xb_dev = xb_dev;
+	spin_lock_init(&front_info->io_lock);
 	dev_set_drvdata(&xb_dev->dev, front_info);
 
 	return xenbus_switch_state(xb_dev, XenbusStateInitialising);
diff --git a/sound/xen/xen_snd_front.h b/sound/xen/xen_snd_front.h
index b52226cb30bc..9c2ffbb4e4b8 100644
--- a/sound/xen/xen_snd_front.h
+++ b/sound/xen/xen_snd_front.h
@@ -13,9 +13,16 @@
 
 #include "xen_snd_front_cfg.h"
 
+struct xen_snd_front_evtchnl_pair;
+
 struct xen_snd_front_info {
 	struct xenbus_device *xb_dev;
 
+	/* serializer for backend IO: request/response */
+	spinlock_t io_lock;
+	int num_evt_pairs;
+	struct xen_snd_front_evtchnl_pair *evt_pairs;
+
 	struct xen_front_cfg_card cfg;
 };
 
diff --git a/sound/xen/xen_snd_front_evtchnl.c b/sound/xen/xen_snd_front_evtchnl.c
new file mode 100644
index 000000000000..9ece39f938f8
--- /dev/null
+++ b/sound/xen/xen_snd_front_evtchnl.c
@@ -0,0 +1,474 @@
+// 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_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;
+	unsigned long flags;
+
+	if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED))
+		return IRQ_HANDLED;
+
+	spin_lock_irqsave(&front_info->io_lock, flags);
+
+again:
+	rp = channel->u.req.ring.sring->rsp_prod;
+	/* ensure we see queued responses up to rp */
+	rmb();
+
+	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:
+			/* fall through */
+		case XENSND_OP_CLOSE:
+			/* fall through */
+		case XENSND_OP_READ:
+			/* fall through */
+		case XENSND_OP_WRITE:
+			/* fall through */
+		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;
+	}
+
+	spin_unlock_irqrestore(&front_info->io_lock, flags);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t evtchnl_interrupt_evt(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_event_page *page = channel->u.evt.page;
+	u32 cons, prod;
+	unsigned long flags;
+
+	if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED))
+		return IRQ_HANDLED;
+
+	spin_lock_irqsave(&front_info->io_lock, flags);
+
+	prod = page->in_prod;
+	/* ensure we see ring contents up to prod */
+	virt_rmb();
+	if (prod == page->in_cons)
+		goto out;
+
+	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:
+			/* do nothing at the moment */
+			break;
+		}
+	}
+
+	page->in_cons = cons;
+	/* ensure ring contents */
+	virt_wmb();
+
+out:
+	spin_unlock_irqrestore(&front_info->io_lock, flags);
+	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);
+
+	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_NOIO | __GFP_HIGH);
+	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;
+	}
+
+	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;
+			free_page(page);
+			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) {
+			free_page(page);
+			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:
+	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;
+			}
+		}
+	}
+	if (ret < 0)
+		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;
+
+	evt_pair->req.state = state;
+	evt_pair->evt.state = state;
+}
+
+void xen_snd_front_evtchnl_pair_clear(struct xen_snd_front_evtchnl_pair *evt_pair)
+{
+	evt_pair->req.evt_next_id = 0;
+	evt_pair->evt.evt_next_id = 0;
+}
+
diff --git a/sound/xen/xen_snd_front_evtchnl.h b/sound/xen/xen_snd_front_evtchnl.h
new file mode 100644
index 000000000000..c4921f469347
--- /dev/null
+++ b/sound/xen/xen_snd_front_evtchnl.h
@@ -0,0 +1,92 @@
+/* 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>
+ */
+
+#ifndef __XEN_SND_FRONT_EVTCHNL_H
+#define __XEN_SND_FRONT_EVTCHNL_H
+
+#include <xen/interface/io/sndif.h>
+
+struct xen_snd_front_info;
+
+#ifndef GRANT_INVALID_REF
+/*
+ * FIXME: usage of grant reference 0 as invalid grant reference:
+ * grant reference 0 is valid, but never exposed to a PV driver,
+ * because of the fact it is already in use/reserved by the PV console.
+ */
+#define GRANT_INVALID_REF	0
+#endif
+
+/* timeout in ms to wait for backend to respond */
+#define VSND_WAIT_BACK_MS	3000
+
+enum xen_snd_front_evtchnl_state {
+	EVTCHNL_STATE_DISCONNECTED,
+	EVTCHNL_STATE_CONNECTED,
+};
+
+enum xen_snd_front_evtchnl_type {
+	EVTCHNL_TYPE_REQ,
+	EVTCHNL_TYPE_EVT,
+};
+
+struct xen_snd_front_evtchnl {
+	struct xen_snd_front_info *front_info;
+	int gref;
+	int port;
+	int irq;
+	int index;
+	/* state of the event channel */
+	enum xen_snd_front_evtchnl_state state;
+	enum xen_snd_front_evtchnl_type type;
+	/* either response id or incoming event id */
+	u16 evt_id;
+	/* next request id or next expected event id */
+	u16 evt_next_id;
+	union {
+		struct {
+			struct xen_sndif_front_ring ring;
+			struct completion completion;
+			/* latest response status */
+			int resp_status;
+			/* serializer for backend IO: request/response */
+			struct mutex req_io_lock;
+			union {
+				struct xensnd_query_hw_param hw_param;
+			} resp;
+		} req;
+		struct {
+			struct xensnd_event_page *page;
+			/* this is needed to handle XENSND_EVT_CUR_POS event */
+			struct snd_pcm_substream *substream;
+		} evt;
+	} u;
+};
+
+struct xen_snd_front_evtchnl_pair {
+	struct xen_snd_front_evtchnl req;
+	struct xen_snd_front_evtchnl evt;
+};
+
+int xen_snd_front_evtchnl_create_all(struct xen_snd_front_info *front_info,
+				     int num_streams);
+
+void xen_snd_front_evtchnl_free_all(struct xen_snd_front_info *front_info);
+
+int xen_snd_front_evtchnl_publish_all(struct xen_snd_front_info *front_info);
+
+void xen_snd_front_evtchnl_flush(struct xen_snd_front_evtchnl *evtchnl);
+
+void xen_snd_front_evtchnl_pair_set_connected(struct xen_snd_front_evtchnl_pair *evt_pair,
+					      bool is_connected);
+
+void xen_snd_front_evtchnl_pair_clear(struct xen_snd_front_evtchnl_pair *evt_pair);
+
+#endif /* __XEN_SND_FRONT_EVTCHNL_H */
-- 
2.16.2

  parent reply	other threads:[~2018-04-16  6:24 UTC|newest]

Thread overview: 91+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-16  6:24 [PATCH v2 0/5] ALSA: xen-front: Add Xen para-virtualized frontend driver Oleksandr Andrushchenko
2018-04-16  6:24 ` [PATCH v2 1/5] ALSA: xen-front: Introduce Xen para-virtualized sound " Oleksandr Andrushchenko
2018-04-16  6:24 ` Oleksandr Andrushchenko
2018-04-16 12:25   ` Juergen Gross
2018-04-16 12:25   ` Juergen Gross
2018-04-17  8:24     ` Oleksandr Andrushchenko
2018-04-17  8:24     ` Oleksandr Andrushchenko
2018-04-24 13:55   ` Takashi Iwai
2018-04-24 13:55   ` Takashi Iwai
2018-04-24 13:55     ` Takashi Iwai
2018-04-24 13:59     ` Oleksandr Andrushchenko
2018-04-24 13:59       ` Oleksandr Andrushchenko
2018-04-24 13:59     ` Oleksandr Andrushchenko
2018-04-16  6:24 ` [PATCH v2 2/5] ALSA: xen-front: Read sound driver configuration from Xen store Oleksandr Andrushchenko
2018-04-16  6:24 ` Oleksandr Andrushchenko
2018-04-16 12:55   ` Juergen Gross
2018-04-16 12:55   ` Juergen Gross
2018-04-17  8:42     ` Oleksandr Andrushchenko
2018-04-17 11:08       ` Juergen Gross
2018-04-17 11:08       ` Juergen Gross
2018-04-17  8:42     ` Oleksandr Andrushchenko
2018-04-16  6:24 ` Oleksandr Andrushchenko [this message]
2018-04-16 13:12   ` [PATCH v2 3/5] ALSA: xen-front: Implement Xen event channel handling Juergen Gross
2018-04-16 13:12   ` Juergen Gross
2018-04-17  8:58     ` Oleksandr Andrushchenko
2018-04-17  8:58     ` Oleksandr Andrushchenko
2018-04-17 11:14       ` Juergen Gross
2018-04-17 11:21         ` Oleksandr Andrushchenko
2018-04-17 11:21         ` Oleksandr Andrushchenko
2018-04-17 11:14       ` Juergen Gross
2018-04-16 13:53   ` kbuild test robot
2018-04-16 13:53   ` kbuild test robot
2018-04-16 13:53     ` kbuild test robot
2018-04-24 14:20   ` Takashi Iwai
2018-04-24 14:20     ` Takashi Iwai
2018-04-24 14:29     ` Oleksandr Andrushchenko
2018-04-24 14:29     ` Oleksandr Andrushchenko
2018-04-24 14:35       ` Takashi Iwai
2018-04-24 14:35         ` Takashi Iwai
2018-04-24 14:58         ` Oleksandr Andrushchenko
2018-04-24 14:58           ` Oleksandr Andrushchenko
2018-04-24 15:02           ` Takashi Iwai
2018-04-24 16:23             ` Oleksandr Andrushchenko
2018-04-24 16:23             ` Oleksandr Andrushchenko
2018-04-24 16:23               ` Oleksandr Andrushchenko
2018-04-25  8:26               ` Oleksandr Andrushchenko
2018-04-25  8:26               ` Oleksandr Andrushchenko
2018-04-25  8:26                 ` Oleksandr Andrushchenko
2018-04-25  9:02                 ` Takashi Iwai
2018-04-25  9:02                   ` Takashi Iwai
2018-04-25  9:04                   ` Oleksandr Andrushchenko
2018-04-25  9:04                     ` Oleksandr Andrushchenko
2018-04-25  9:04                   ` Oleksandr Andrushchenko
2018-04-25  9:02                 ` Takashi Iwai
2018-04-24 15:02           ` Takashi Iwai
2018-04-24 14:58         ` Oleksandr Andrushchenko
2018-04-24 14:35       ` Takashi Iwai
2018-04-24 14:20   ` Takashi Iwai
2018-04-16  6:24 ` Oleksandr Andrushchenko
2018-04-16  6:24 ` [PATCH v2 4/5] ALSA: xen-front: Implement handling of shared buffers Oleksandr Andrushchenko
2018-04-16  6:24 ` Oleksandr Andrushchenko
2018-04-16 13:39   ` Juergen Gross
2018-04-17  9:22     ` Oleksandr Andrushchenko
2018-04-17  9:22     ` Oleksandr Andrushchenko
2018-04-17 11:15       ` Juergen Gross
2018-04-17 11:15       ` Juergen Gross
2018-04-16 13:39   ` Juergen Gross
2018-04-16  6:24 ` [PATCH v2 5/5] ALSA: xen-front: Implement ALSA virtual sound driver Oleksandr Andrushchenko
2018-04-16  6:24 ` Oleksandr Andrushchenko
2018-04-16 14:09   ` Juergen Gross
2018-04-16 14:09   ` Juergen Gross
2018-04-17 11:32     ` Oleksandr Andrushchenko
2018-04-17 11:32     ` Oleksandr Andrushchenko
2018-04-17 12:26       ` Oleksandr Andrushchenko
2018-04-17 12:26       ` Oleksandr Andrushchenko
2018-04-17 12:32         ` Juergen Gross
2018-04-17 12:34           ` Oleksandr Andrushchenko
2018-04-17 12:34           ` Oleksandr Andrushchenko
2018-04-17 12:34             ` Oleksandr Andrushchenko
2018-04-17 12:32         ` Juergen Gross
2018-04-16 14:59   ` kbuild test robot
2018-04-16 14:59     ` kbuild test robot
2018-04-16 14:59   ` kbuild test robot
2018-04-17 12:42 ` [PATCH v2 0/5] ALSA: xen-front: Add Xen para-virtualized frontend driver Oleksandr Andrushchenko
2018-04-17 12:42 ` Oleksandr Andrushchenko
2018-04-18 15:15 ` Oleksandr Andrushchenko
2018-04-18 15:15 ` Oleksandr Andrushchenko
2018-04-23  6:34   ` Oleksandr Andrushchenko
2018-04-23  6:34   ` Oleksandr Andrushchenko
2018-05-02  7:59 ` Oleksandr Andrushchenko
2018-05-02  7:59 ` Oleksandr Andrushchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180416062453.24743-4-andr2000@gmail.com \
    --to=andr2000@gmail.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=boris.ostrovsky@oracle.com \
    --cc=jgross@suse.com \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oleksandr_andrushchenko@epam.com \
    --cc=perex@perex.cz \
    --cc=tiwai@suse.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.