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 v3 1/6] ALSA: xen-front: Introduce Xen para-virtualized sound frontend driver
Date: Mon, 14 May 2018 09:27:37 +0300 [thread overview]
Message-ID: <20180514062742.25879-2-andr2000@gmail.com> (raw)
In-Reply-To: <20180514062742.25879-1-andr2000@gmail.com>
From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Introduce skeleton of the para-virtualized Xen sound
frontend driver.
Initial handling for Xen bus states: implement
Xen bus state machine for the frontend driver according to
the state diagram and recovery flow from sound para-virtualized
protocol: xen/interface/io/sndif.h.
Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
---
sound/Kconfig | 2 +
sound/Makefile | 2 +-
sound/xen/Kconfig | 10 ++
sound/xen/Makefile | 5 +
sound/xen/xen_snd_front.c | 196 ++++++++++++++++++++++++++++++++++++++
sound/xen/xen_snd_front.h | 18 ++++
6 files changed, 232 insertions(+), 1 deletion(-)
create mode 100644 sound/xen/Kconfig
create mode 100644 sound/xen/Makefile
create mode 100644 sound/xen/xen_snd_front.c
create mode 100644 sound/xen/xen_snd_front.h
diff --git a/sound/Kconfig b/sound/Kconfig
index 6833db9002ec..1140e9988fc5 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -96,6 +96,8 @@ source "sound/x86/Kconfig"
source "sound/synth/Kconfig"
+source "sound/xen/Kconfig"
+
endif # SND
endif # !UML
diff --git a/sound/Makefile b/sound/Makefile
index 99d8c31262c8..797ecdcd35e2 100644
--- a/sound/Makefile
+++ b/sound/Makefile
@@ -5,7 +5,7 @@
obj-$(CONFIG_SOUND) += soundcore.o
obj-$(CONFIG_DMASOUND) += oss/dmasound/
obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \
- firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/
+ firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/ xen/
obj-$(CONFIG_SND_AOA) += aoa/
# This one must be compilable even if sound is configured out
diff --git a/sound/xen/Kconfig b/sound/xen/Kconfig
new file mode 100644
index 000000000000..4f1fceea82d2
--- /dev/null
+++ b/sound/xen/Kconfig
@@ -0,0 +1,10 @@
+# ALSA Xen drivers
+
+config SND_XEN_FRONTEND
+ tristate "Xen para-virtualized sound frontend driver"
+ depends on XEN
+ select SND_PCM
+ select XEN_XENBUS_FRONTEND
+ help
+ Choose this option if you want to enable a para-virtualized
+ frontend sound driver for Xen guest OSes.
diff --git a/sound/xen/Makefile b/sound/xen/Makefile
new file mode 100644
index 000000000000..4507ef3c27fd
--- /dev/null
+++ b/sound/xen/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0 OR MIT
+
+snd_xen_front-objs := xen_snd_front.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
new file mode 100644
index 000000000000..bbbe2767b565
--- /dev/null
+++ b/sound/xen/xen_snd_front.c
@@ -0,0 +1,196 @@
+// 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 <linux/delay.h>
+#include <linux/module.h>
+
+#include <xen/platform_pci.h>
+#include <xen/xen.h>
+#include <xen/xenbus.h>
+
+#include <xen/interface/io/sndif.h>
+
+#include "xen_snd_front.h"
+
+static void xen_snd_drv_fini(struct xen_snd_front_info *front_info)
+{
+}
+
+static int sndback_initwait(struct xen_snd_front_info *front_info)
+{
+ return 0;
+}
+
+static int sndback_connect(struct xen_snd_front_info *front_info)
+{
+ return 0;
+}
+
+static void sndback_disconnect(struct xen_snd_front_info *front_info)
+{
+ xen_snd_drv_fini(front_info);
+ xenbus_switch_state(front_info->xb_dev, XenbusStateInitialising);
+}
+
+static void sndback_changed(struct xenbus_device *xb_dev,
+ enum xenbus_state backend_state)
+{
+ struct xen_snd_front_info *front_info = dev_get_drvdata(&xb_dev->dev);
+ int ret;
+
+ dev_dbg(&xb_dev->dev, "Backend state is %s, front is %s\n",
+ xenbus_strstate(backend_state),
+ xenbus_strstate(xb_dev->state));
+
+ switch (backend_state) {
+ case XenbusStateReconfiguring:
+ /* fall through */
+ case XenbusStateReconfigured:
+ /* fall through */
+ case XenbusStateInitialised:
+ /* fall through */
+ break;
+
+ case XenbusStateInitialising:
+ /* Recovering after backend unexpected closure. */
+ sndback_disconnect(front_info);
+ break;
+
+ case XenbusStateInitWait:
+ /* Recovering after backend unexpected closure. */
+ sndback_disconnect(front_info);
+
+ ret = sndback_initwait(front_info);
+ if (ret < 0)
+ xenbus_dev_fatal(xb_dev, ret, "initializing frontend");
+ else
+ xenbus_switch_state(xb_dev, XenbusStateInitialised);
+ break;
+
+ case XenbusStateConnected:
+ if (xb_dev->state != XenbusStateInitialised)
+ break;
+
+ ret = sndback_connect(front_info);
+ if (ret < 0)
+ xenbus_dev_fatal(xb_dev, ret, "initializing frontend");
+ else
+ xenbus_switch_state(xb_dev, XenbusStateConnected);
+ break;
+
+ case XenbusStateClosing:
+ /*
+ * In this state backend starts freeing resources,
+ * so let it go into closed state first, so we can also
+ * remove ours.
+ */
+ break;
+
+ case XenbusStateUnknown:
+ /* fall through */
+ case XenbusStateClosed:
+ if (xb_dev->state == XenbusStateClosed)
+ break;
+
+ sndback_disconnect(front_info);
+ break;
+ }
+}
+
+static int xen_drv_probe(struct xenbus_device *xb_dev,
+ const struct xenbus_device_id *id)
+{
+ struct xen_snd_front_info *front_info;
+
+ front_info = devm_kzalloc(&xb_dev->dev,
+ sizeof(*front_info), GFP_KERNEL);
+ if (!front_info)
+ return -ENOMEM;
+
+ front_info->xb_dev = xb_dev;
+ dev_set_drvdata(&xb_dev->dev, front_info);
+
+ return xenbus_switch_state(xb_dev, XenbusStateInitialising);
+}
+
+static int xen_drv_remove(struct xenbus_device *dev)
+{
+ struct xen_snd_front_info *front_info = dev_get_drvdata(&dev->dev);
+ int to = 100;
+
+ xenbus_switch_state(dev, XenbusStateClosing);
+
+ /*
+ * On driver removal it is disconnected from XenBus,
+ * so no backend state change events come via .otherend_changed
+ * callback. This prevents us from exiting gracefully, e.g.
+ * signaling the backend to free event channels, waiting for its
+ * state to change to XenbusStateClosed and cleaning at our end.
+ * Normally when front driver removed backend will finally go into
+ * XenbusStateInitWait state.
+ *
+ * Workaround: read backend's state manually and wait with time-out.
+ */
+ while ((xenbus_read_unsigned(front_info->xb_dev->otherend, "state",
+ XenbusStateUnknown) != XenbusStateInitWait) &&
+ to--)
+ msleep(10);
+
+ if (!to) {
+ unsigned int state;
+
+ state = xenbus_read_unsigned(front_info->xb_dev->otherend,
+ "state", XenbusStateUnknown);
+ pr_err("Backend state is %s while removing driver\n",
+ xenbus_strstate(state));
+ }
+
+ xen_snd_drv_fini(front_info);
+ xenbus_frontend_closed(dev);
+ return 0;
+}
+
+static const struct xenbus_device_id xen_drv_ids[] = {
+ { XENSND_DRIVER_NAME },
+ { "" }
+};
+
+static struct xenbus_driver xen_driver = {
+ .ids = xen_drv_ids,
+ .probe = xen_drv_probe,
+ .remove = xen_drv_remove,
+ .otherend_changed = sndback_changed,
+};
+
+static int __init xen_drv_init(void)
+{
+ if (!xen_domain())
+ return -ENODEV;
+
+ if (!xen_has_pv_devices())
+ return -ENODEV;
+
+ pr_info("Initialising Xen " XENSND_DRIVER_NAME " frontend driver\n");
+ return xenbus_register_frontend(&xen_driver);
+}
+
+static void __exit xen_drv_fini(void)
+{
+ pr_info("Unregistering Xen " XENSND_DRIVER_NAME " frontend driver\n");
+ xenbus_unregister_driver(&xen_driver);
+}
+
+module_init(xen_drv_init);
+module_exit(xen_drv_fini);
+
+MODULE_DESCRIPTION("Xen virtual sound device frontend");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("xen:" XENSND_DRIVER_NAME);
+MODULE_SUPPORTED_DEVICE("{{ALSA,Virtual soundcard}}");
diff --git a/sound/xen/xen_snd_front.h b/sound/xen/xen_snd_front.h
new file mode 100644
index 000000000000..4ae204b23d32
--- /dev/null
+++ b/sound/xen/xen_snd_front.h
@@ -0,0 +1,18 @@
+/* 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_H
+#define __XEN_SND_FRONT_H
+
+struct xen_snd_front_info {
+ struct xenbus_device *xb_dev;
+};
+
+#endif /* __XEN_SND_FRONT_H */
--
2.17.0
next prev parent reply other threads:[~2018-05-14 6:27 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-14 6:27 [PATCH v3 0/6] ALSA: xen-front: Add Xen para-virtualized frontend driver Oleksandr Andrushchenko
2018-05-14 6:27 ` Oleksandr Andrushchenko [this message]
2018-05-14 6:27 ` [PATCH v3 2/6] ALSA: xen-front: Read sound driver configuration from Xen store Oleksandr Andrushchenko
2018-05-14 6:27 ` [PATCH v3 3/6] ALSA: xen-front: Implement Xen event channel handling Oleksandr Andrushchenko
2018-05-14 6:27 ` [PATCH v3 4/6] ALSA: xen-front: Implement handling of shared buffers Oleksandr Andrushchenko
2018-05-14 20:28 ` Takashi Iwai
2018-05-15 5:46 ` Oleksandr Andrushchenko
2018-05-15 6:01 ` Takashi Iwai
2018-05-15 6:02 ` Oleksandr Andrushchenko
2018-05-17 6:26 ` Takashi Iwai
2018-05-17 6:33 ` Oleksandr Andrushchenko
2018-05-21 20:26 ` Takashi Iwai
2018-05-22 5:25 ` Oleksandr Andrushchenko
2018-05-14 6:27 ` [PATCH v3 5/6] ALSA: xen-front: Implement ALSA virtual sound driver Oleksandr Andrushchenko
2018-05-23 4:00 ` Takashi Sakamoto
2018-05-23 6:14 ` Oleksandr Andrushchenko
2018-05-14 6:27 ` [PATCH v3 6/6] MAINTAINERS: Add ALSA: xen-front: maintainer entry Oleksandr Andrushchenko
2018-05-14 15:52 ` [alsa-devel] [PATCH v3 0/6] ALSA: xen-front: Add Xen para-virtualized frontend driver Takashi Iwai
2018-05-14 16:08 ` 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=20180514062742.25879-2-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).