[PATCH RESEND1 11/12] ALSA: vsnd: Implement communication with backend

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Implement frontend to backend communication according to
the para-virtualized sound protocol: xen/interface/io/sndif.h.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 302 +++---
 1 file changed, 288 insertions(+), 14 deletions(-)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 7275e9cb38c0..8bfec43ef03a 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -38,6 +38,8 @@
  * because of the fact it is already in use/reserved by the PV console.
  */
 #define GRANT_INVALID_REF  0
+/* timeout in ms to wait for backend to respond */
+#define VSND_WAIT_BACK_MS  3000
 /* maximum number of supported streams */
 #define VSND_MAX_STREAM8
 
@@ -151,10 +153,12 @@ struct xdrv_info {
struct sdev_card_plat_data cfg_plat_data;
 };
 
+static inline void xdrv_evtchnl_flush(struct xdrv_evtchnl_info *channel);
 static inline void sh_buf_clear(struct sh_buf_info *buf);
 static void sh_buf_free(struct sh_buf_info *buf);
 static int sh_buf_alloc(struct xenbus_device *xb_dev, struct sh_buf_info *buf,
unsigned int buffer_size);
+static grant_ref_t sh_buf_get_dir_start(struct sh_buf_info *buf);
 
 static struct sdev_pcm_stream_info *sdrv_stream_get(
struct snd_pcm_substream *substream)
@@ -314,6 +318,234 @@ static void sdrv_copy_pcm_hw(struct snd_pcm_hardware *dst,
}
 }
 
+struct ALSA_SNDIF_SAMPLE_FORMAT {
+   uint8_t sndif;
+   snd_pcm_format_t alsa;
+};
+
+static struct ALSA_SNDIF_SAMPLE_FORMAT alsa_sndif_formats[] = {
+   {
+   .sndif = XENSND_PCM_FORMAT_U8,
+   .alsa = SNDRV_PCM_FORMAT_U8
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S8,
+   .alsa = SNDRV_PCM_FORMAT_S8
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U16_LE,
+   .alsa = SNDRV_PCM_FORMAT_U16_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U16_BE,
+   .alsa = SNDRV_PCM_FORMAT_U16_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S16_LE,
+   .alsa = SNDRV_PCM_FORMAT_S16_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S16_BE,
+   .alsa = SNDRV_PCM_FORMAT_S16_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U24_LE,
+   .alsa = SNDRV_PCM_FORMAT_U24_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U24_BE,
+   .alsa = SNDRV_PCM_FORMAT_U24_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S24_LE,
+   .alsa = SNDRV_PCM_FORMAT_S24_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S24_BE,
+   .alsa = SNDRV_PCM_FORMAT_S24_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U32_LE,
+   .alsa = SNDRV_PCM_FORMAT_U32_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U32_BE,
+   .alsa = SNDRV_PCM_FORMAT_U32_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S32_LE,
+   .alsa = SNDRV_PCM_FORMAT_S32_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S32_BE,
+   .alsa = SNDRV_PCM_FORMAT_S32_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_A_LAW,
+   .alsa = SNDRV_PCM_FORMAT_A_LAW
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_MU_LAW,
+   .alsa = SNDRV_PCM_FORMAT_MU_LAW
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F32_LE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F32_BE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F64_LE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT64_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F64_BE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT64_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE,
+   .alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE,
+   .alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IMA_ADPCM,
+   .alsa = SNDRV_PCM_FORMAT_IMA_ADPCM
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_MPEG,
+   .alsa = SNDRV_PCM_FORMAT_MPEG
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_GSM,
+   .alsa = SNDRV_PCM_FORMAT_GSM
+   },
+};
+
+static int alsa_to_sndif_format(snd_pcm_format_t format)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(alsa_sndif_formats); i++)
+   if (alsa_sndif_formats[i].alsa == format)
+   return alsa_sndif_formats[i].sndif;
+ 

[PATCH RESEND1 11/12] ALSA: vsnd: Implement communication with backend

2017-08-07 Thread Oleksandr Andrushchenko
From: Oleksandr Andrushchenko 

Implement frontend to backend communication according to
the para-virtualized sound protocol: xen/interface/io/sndif.h.

Signed-off-by: Oleksandr Andrushchenko 
---
 sound/drivers/xen-front.c | 302 +++---
 1 file changed, 288 insertions(+), 14 deletions(-)

diff --git a/sound/drivers/xen-front.c b/sound/drivers/xen-front.c
index 7275e9cb38c0..8bfec43ef03a 100644
--- a/sound/drivers/xen-front.c
+++ b/sound/drivers/xen-front.c
@@ -38,6 +38,8 @@
  * because of the fact it is already in use/reserved by the PV console.
  */
 #define GRANT_INVALID_REF  0
+/* timeout in ms to wait for backend to respond */
+#define VSND_WAIT_BACK_MS  3000
 /* maximum number of supported streams */
 #define VSND_MAX_STREAM8
 
@@ -151,10 +153,12 @@ struct xdrv_info {
struct sdev_card_plat_data cfg_plat_data;
 };
 
+static inline void xdrv_evtchnl_flush(struct xdrv_evtchnl_info *channel);
 static inline void sh_buf_clear(struct sh_buf_info *buf);
 static void sh_buf_free(struct sh_buf_info *buf);
 static int sh_buf_alloc(struct xenbus_device *xb_dev, struct sh_buf_info *buf,
unsigned int buffer_size);
+static grant_ref_t sh_buf_get_dir_start(struct sh_buf_info *buf);
 
 static struct sdev_pcm_stream_info *sdrv_stream_get(
struct snd_pcm_substream *substream)
@@ -314,6 +318,234 @@ static void sdrv_copy_pcm_hw(struct snd_pcm_hardware *dst,
}
 }
 
+struct ALSA_SNDIF_SAMPLE_FORMAT {
+   uint8_t sndif;
+   snd_pcm_format_t alsa;
+};
+
+static struct ALSA_SNDIF_SAMPLE_FORMAT alsa_sndif_formats[] = {
+   {
+   .sndif = XENSND_PCM_FORMAT_U8,
+   .alsa = SNDRV_PCM_FORMAT_U8
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S8,
+   .alsa = SNDRV_PCM_FORMAT_S8
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U16_LE,
+   .alsa = SNDRV_PCM_FORMAT_U16_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U16_BE,
+   .alsa = SNDRV_PCM_FORMAT_U16_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S16_LE,
+   .alsa = SNDRV_PCM_FORMAT_S16_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S16_BE,
+   .alsa = SNDRV_PCM_FORMAT_S16_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U24_LE,
+   .alsa = SNDRV_PCM_FORMAT_U24_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U24_BE,
+   .alsa = SNDRV_PCM_FORMAT_U24_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S24_LE,
+   .alsa = SNDRV_PCM_FORMAT_S24_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S24_BE,
+   .alsa = SNDRV_PCM_FORMAT_S24_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U32_LE,
+   .alsa = SNDRV_PCM_FORMAT_U32_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_U32_BE,
+   .alsa = SNDRV_PCM_FORMAT_U32_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S32_LE,
+   .alsa = SNDRV_PCM_FORMAT_S32_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_S32_BE,
+   .alsa = SNDRV_PCM_FORMAT_S32_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_A_LAW,
+   .alsa = SNDRV_PCM_FORMAT_A_LAW
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_MU_LAW,
+   .alsa = SNDRV_PCM_FORMAT_MU_LAW
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F32_LE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F32_BE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F64_LE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT64_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_F64_BE,
+   .alsa = SNDRV_PCM_FORMAT_FLOAT64_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE,
+   .alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE,
+   .alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_IMA_ADPCM,
+   .alsa = SNDRV_PCM_FORMAT_IMA_ADPCM
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_MPEG,
+   .alsa = SNDRV_PCM_FORMAT_MPEG
+   },
+   {
+   .sndif = XENSND_PCM_FORMAT_GSM,
+   .alsa = SNDRV_PCM_FORMAT_GSM
+   },
+};
+
+static int alsa_to_sndif_format(snd_pcm_format_t format)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(alsa_sndif_formats); i++)
+   if (alsa_sndif_formats[i].alsa == format)
+   return alsa_sndif_formats[i].sndif;
+   return -EINVAL;
+}
+
+static void sdrv_stream_clear(struct