[PATCH v3 1/6] ALSA: xen-front: Introduce Xen para-virtualized sound frontend driver

2018-05-14 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

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 
Reviewed-by: Juergen Gross 
---
 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 ..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 ..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 ..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 
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+
+#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(_dev->dev);
+   int ret;
+
+   dev_dbg(_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)
+   

[PATCH v3 1/6] ALSA: xen-front: Introduce Xen para-virtualized sound frontend driver

2018-05-14 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

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 
Reviewed-by: Juergen Gross 
---
 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 ..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 ..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 ..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 
+ */
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+
+#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(_dev->dev);
+   int ret;
+
+   dev_dbg(_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
+