xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/5] libxl: add PV sound device
@ 2018-05-18 14:38 Oleksandr Grytsov
  2018-05-18 14:38 ` [PATCH v2 1/5] " Oleksandr Grytsov
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Oleksandr Grytsov @ 2018-05-18 14:38 UTC (permalink / raw)
  To: xen-devel; +Cc: ian.jackson, wei.liu2, Oleksandr Grytsov

From: Oleksandr Grytsov <oleksandr_grytsov@epam.com>

This patch set adds PV sound device support to xl.cfg and xl.
See sndif.h for protocol implementation details.


Changes since initial:
 * rebase to current staging
 * use libxl__realloc instead of realloc

Oleksandr Grytsov (5):
  libxl: add PV sound device
  libxl: add vsnd list and info
  xl: add PV sound condif parser
  xl: add vsnd CLI commands
  docs: add PV sound device config

 docs/man/xl.cfg.pod.5.in             | 149 ++++++
 docs/man/xl.pod.1.in                 |  30 ++
 tools/libxl/Makefile                 |   2 +-
 tools/libxl/libxl.h                  |  24 +
 tools/libxl/libxl_create.c           |   1 +
 tools/libxl/libxl_internal.h         |   1 +
 tools/libxl/libxl_types.idl          |  83 ++++
 tools/libxl/libxl_types_internal.idl |   1 +
 tools/libxl/libxl_utils.h            |   3 +
 tools/libxl/libxl_vsnd.c             | 699 +++++++++++++++++++++++++++
 tools/xl/Makefile                    |   2 +-
 tools/xl/xl.h                        |   3 +
 tools/xl/xl_cmdtable.c               |  15 +
 tools/xl/xl_parse.c                  | 246 ++++++++++
 tools/xl/xl_parse.h                  |   1 +
 tools/xl/xl_vsnd.c                   | 203 ++++++++
 16 files changed, 1461 insertions(+), 2 deletions(-)
 create mode 100644 tools/libxl/libxl_vsnd.c
 create mode 100644 tools/xl/xl_vsnd.c

-- 
2.17.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/5] libxl: add PV sound device
  2018-05-18 14:38 [PATCH v2 0/5] libxl: add PV sound device Oleksandr Grytsov
@ 2018-05-18 14:38 ` Oleksandr Grytsov
  2018-05-18 14:38 ` [PATCH v2 2/5] libxl: add vsnd list and info Oleksandr Grytsov
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Oleksandr Grytsov @ 2018-05-18 14:38 UTC (permalink / raw)
  To: xen-devel; +Cc: ian.jackson, wei.liu2, Oleksandr Grytsov

From: Oleksandr Grytsov <oleksandr_grytsov@epam.com>

Add PV sound device described in sndif.h

Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxl/Makefile                 |   2 +-
 tools/libxl/libxl.h                  |  14 ++
 tools/libxl/libxl_create.c           |   1 +
 tools/libxl/libxl_internal.h         |   1 +
 tools/libxl/libxl_types.idl          |  64 ++++++
 tools/libxl/libxl_types_internal.idl |   1 +
 tools/libxl/libxl_vsnd.c             | 331 +++++++++++++++++++++++++++
 7 files changed, 413 insertions(+), 1 deletion(-)
 create mode 100644 tools/libxl/libxl_vsnd.c

diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index 035e66e22e..d60743d38b 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -140,7 +140,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
 			libxl_vtpm.o libxl_nic.o libxl_disk.o libxl_console.o \
 			libxl_cpupool.o libxl_mem.o libxl_sched.o libxl_tmem.o \
 			libxl_9pfs.o libxl_domain.o libxl_vdispl.o \
-                        libxl_pvcalls.o $(LIBXL_OBJS-y)
+			libxl_pvcalls.o libxl_vsnd.o $(LIBXL_OBJS-y)
 LIBXL_OBJS += libxl_genid.o
 LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
 
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index a09d069358..a312166b48 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -2000,6 +2000,20 @@ int libxl_device_vdispl_getinfo(libxl_ctx *ctx, uint32_t domid,
                                 libxl_vdisplinfo *vdisplinfo)
                                 LIBXL_EXTERNAL_CALLERS_ONLY;
 
+/* Virtual sounds */
+int libxl_device_vsnd_add(libxl_ctx *ctx, uint32_t domid,
+                          libxl_device_vsnd *vsnd,
+                          const libxl_asyncop_how *ao_how)
+                          LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_vsnd_remove(libxl_ctx *ctx, uint32_t domid,
+                             libxl_device_vsnd *vsnd,
+                             const libxl_asyncop_how *ao_how)
+                             LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_vsnd_destroy(libxl_ctx *ctx, uint32_t domid,
+                              libxl_device_vsnd *vsnd,
+                              const libxl_asyncop_how *ao_how)
+                              LIBXL_EXTERNAL_CALLERS_ONLY;
+
 /* Keyboard */
 int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb,
                          const libxl_asyncop_how *ao_how)
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index b5e27a7766..7d46824eac 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -1501,6 +1501,7 @@ const struct libxl_device_type *device_type_tbl[] = {
     &libxl__pcidev_devtype,
     &libxl__dtdev_devtype,
     &libxl__vdispl_devtype,
+    &libxl__vsnd_devtype,
     NULL
 };
 
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index c582894589..17ac2083f6 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3653,6 +3653,7 @@ extern const struct libxl_device_type libxl__pcidev_devtype;
 extern const struct libxl_device_type libxl__vdispl_devtype;
 extern const struct libxl_device_type libxl__p9_devtype;
 extern const struct libxl_device_type libxl__pvcallsif_devtype;
+extern const struct libxl_device_type libxl__vsnd_devtype;
 
 extern const struct libxl_device_type *device_type_tbl[];
 
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 01ec1d1afa..ad978fb413 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -822,6 +822,69 @@ libxl_device_vdispl = Struct("device_vdispl", [
     ("connectors", Array(libxl_connector_param, "num_connectors"))
     ])
 
+libxl_vsnd_pcm_format = Enumeration("vsnd_pcm_format", [
+    (1,  "S8"),
+    (2,  "U8"),
+    (3,  "S16_LE"),
+    (4,  "S16_BE"),
+    (5,  "U16_LE"),
+    (6,  "U16_BE"),
+    (7,  "S24_LE"),
+    (8,  "S24_BE"),
+    (9,  "U24_LE"),
+    (10, "U24_BE"),
+    (11, "S32_LE"),
+    (12, "S32_BE"),
+    (13, "U32_LE"),
+    (14, "U32_BE"),
+    (15, "F32_LE"),
+    (16, "F32_BE"),
+    (17, "F64_LE"),
+    (18, "F64_BE"),
+    (19, "IEC958_SUBFRAME_LE"),
+    (20, "IEC958_SUBFRAME_BE"),
+    (21, "MU_LAW"),
+    (22, "A_LAW"),
+    (23, "IMA_ADPCM"),
+    (24, "MPEG"),
+    (25, "GSM")
+    ])
+
+libxl_vsnd_params = Struct("vsnd_params", [
+    ("sample_rates", Array(uint32, "num_sample_rates")),
+    ("sample_formats", Array(libxl_vsnd_pcm_format, "num_sample_formats")),
+    ("channels_min", uint32),
+    ("channels_max", uint32),
+    ("buffer_size", uint32)
+    ])
+
+libxl_vsnd_stream_type = Enumeration("vsnd_stream_type", [
+    (1, "P"),
+    (2, "C")
+    ])
+
+libxl_vsnd_stream = Struct("vsnd_stream", [
+    ("id", string),
+    ("type", libxl_vsnd_stream_type),
+    ("params", libxl_vsnd_params)
+    ])
+
+libxl_vsnd_pcm = Struct("vsnd_pcm", [
+    ("name", string),
+    ("params", libxl_vsnd_params),
+    ("streams", Array(libxl_vsnd_stream, "num_vsnd_streams"))
+    ])
+
+libxl_device_vsnd = Struct("device_vsnd", [
+    ("backend_domid", libxl_domid),
+    ("backend_domname", string),
+    ("devid", libxl_devid),
+    ("short_name", string),
+    ("long_name", string),
+    ("params", libxl_vsnd_params),
+    ("pcms", Array(libxl_vsnd_pcm, "num_vsnd_pcms"))
+    ])
+
 libxl_domain_config = Struct("domain_config", [
     ("c_info", libxl_domain_create_info),
     ("b_info", libxl_domain_build_info),
@@ -837,6 +900,7 @@ libxl_domain_config = Struct("domain_config", [
     ("p9s", Array(libxl_device_p9, "num_p9s")),
     ("pvcallsifs", Array(libxl_device_pvcallsif, "num_pvcallsifs")),
     ("vdispls", Array(libxl_device_vdispl, "num_vdispls")),
+    ("vsnds", Array(libxl_device_vsnd, "num_vsnds")),
     # a channel manifests as a console with a name,
     # see docs/misc/channels.txt
     ("channels", Array(libxl_device_channel, "num_channels")),
diff --git a/tools/libxl/libxl_types_internal.idl b/tools/libxl/libxl_types_internal.idl
index f2ff01718d..37402e49cb 100644
--- a/tools/libxl/libxl_types_internal.idl
+++ b/tools/libxl/libxl_types_internal.idl
@@ -29,6 +29,7 @@ libxl__device_kind = Enumeration("device_kind", [
     (12, "VDISPL"),
     (13, "VUART"),
     (14, "PVCALLS"),
+    (15, "VSND"),
     ])
 
 libxl__console_backend = Enumeration("console_backend", [
diff --git a/tools/libxl/libxl_vsnd.c b/tools/libxl/libxl_vsnd.c
new file mode 100644
index 0000000000..1e19217811
--- /dev/null
+++ b/tools/libxl/libxl_vsnd.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2016 EPAM Systems Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include "libxl_internal.h"
+#include <xen/io/sndif.h>
+
+static int libxl__device_vsnd_setdefault(libxl__gc *gc, uint32_t domid,
+                                         libxl_device_vsnd *vsnd,
+                                         bool hotplug)
+{
+    return libxl__resolve_domid(gc, vsnd->backend_domname,
+                                &vsnd->backend_domid);
+}
+
+static int libxl__device_from_vsnd(libxl__gc *gc, uint32_t domid,
+                                   libxl_device_vsnd *vsnd,
+                                   libxl__device *device)
+{
+   device->backend_devid   = vsnd->devid;
+   device->backend_domid   = vsnd->backend_domid;
+   device->backend_kind    = LIBXL__DEVICE_KIND_VSND;
+   device->devid           = vsnd->devid;
+   device->domid           = domid;
+   device->kind            = LIBXL__DEVICE_KIND_VSND;
+
+   return 0;
+}
+
+static int libxl__vsnd_from_xenstore(libxl__gc *gc, const char *libxl_path,
+                                     libxl_devid devid,
+                                     libxl_device_vsnd *vsnd)
+{
+    const char *be_path;
+    int rc;
+
+    vsnd->devid = devid;
+    rc = libxl__xs_read_mandatory(gc, XBT_NULL,
+                                  GCSPRINTF("%s/backend", libxl_path),
+                                  &be_path);
+    if (rc) goto out;
+
+    rc = libxl__backendpath_parse_domid(gc, be_path, &vsnd->backend_domid);
+    if (rc) goto out;
+
+    rc = 0;
+
+out:
+
+    return rc;
+}
+
+static void libxl__update_config_vsnd(libxl__gc *gc,
+                                      libxl_device_vsnd *dst,
+                                      libxl_device_vsnd *src)
+{
+    dst->devid = src->devid;
+}
+
+static int libxl_device_vsnd_compare(libxl_device_vsnd *d1,
+                                     libxl_device_vsnd *d2)
+{
+    return COMPARE_DEVID(d1, d2);
+}
+
+static void libxl__device_vsnd_add(libxl__egc *egc, uint32_t domid,
+                                   libxl_device_vsnd *vsnd,
+                                   libxl__ao_device *aodev)
+{
+    libxl__device_add_async(egc, domid, &libxl__vsnd_devtype, vsnd, aodev);
+}
+
+static unsigned int libxl__rates_to_str_vsnd(char *str, uint32_t *sample_rates,
+                                             int num_sample_rates)
+{
+    unsigned int len;
+    int i;
+
+    len = 0;
+
+    if (num_sample_rates == 0) goto out;
+
+    for (i = 0; i < num_sample_rates - 1; i++) {
+        if (str) {
+            len += sprintf(&str[len], "%u,", sample_rates[i]);
+        } else {
+            len += snprintf(NULL, 0, "%u,", sample_rates[i]);
+        }
+    }
+
+    if (str) {
+        len += sprintf(&str[len], "%u", sample_rates[i]);
+    } else {
+        len += snprintf(NULL, 0, "%u", sample_rates[i]);
+    }
+
+out:
+
+    return len;
+}
+
+static unsigned int libxl__formats_to_str_vsnd(char *str,
+                                               libxl_vsnd_pcm_format *sample_formats,
+                                               int num_sample_formats)
+{
+    unsigned int len;
+    int i;
+
+    len = 0;
+
+    if (num_sample_formats == 0) goto out;
+
+    for (i = 0; i < num_sample_formats - 1; i++) {
+        if (str) {
+            len += sprintf(&str[len], "%s,",
+                           libxl_vsnd_pcm_format_to_string(sample_formats[i]));
+        } else {
+            len += snprintf(NULL, 0, "%s,",
+                            libxl_vsnd_pcm_format_to_string(sample_formats[i]));
+        }
+    }
+
+    if (str) {
+        len += sprintf(&str[len], "%s",
+                       libxl_vsnd_pcm_format_to_string(sample_formats[i]));
+    } else {
+        len += snprintf(NULL, 0, "%s",
+                        libxl_vsnd_pcm_format_to_string(sample_formats[i]));
+    }
+
+out:
+
+    return len;
+}
+
+static int libxl__set_params_vsnd(libxl__gc *gc, char *path,
+                                  libxl_vsnd_params *params, flexarray_t *front)
+{
+    char *buffer;
+    int len;
+    int rc;
+
+    if (params->sample_rates) {
+        /* calculate required string size */
+        len = libxl__rates_to_str_vsnd(NULL, params->sample_rates,
+                                       params->num_sample_rates);
+
+        if (len) {
+            buffer = libxl__malloc(gc, len + 1);
+
+            libxl__rates_to_str_vsnd(buffer, params->sample_rates,
+                                     params->num_sample_rates);
+            rc = flexarray_append_pair(front,
+                                       GCSPRINTF("%s"XENSND_FIELD_SAMPLE_RATES,
+                                                 path), buffer);
+            if (rc) goto out;
+        }
+    }
+
+    if (params->sample_formats) {
+        /* calculate required string size */
+        len = libxl__formats_to_str_vsnd(NULL, params->sample_formats,
+                                         params->num_sample_formats);
+
+        if (len) {
+            buffer = libxl__malloc(gc, len + 1);
+
+            libxl__formats_to_str_vsnd(buffer, params->sample_formats,
+                                     params->num_sample_formats);
+            rc = flexarray_append_pair(front,
+                                       GCSPRINTF("%s"XENSND_FIELD_SAMPLE_FORMATS,
+                                                 path), buffer);
+            if (rc) goto out;
+        }
+    }
+
+    if (params->channels_min) {
+        rc = flexarray_append_pair(front,
+                                   GCSPRINTF("%s"XENSND_FIELD_CHANNELS_MIN, path),
+                                   GCSPRINTF("%u", params->channels_min));
+        if (rc) goto out;
+    }
+
+    if (params->channels_max) {
+        rc = flexarray_append_pair(front,
+                                   GCSPRINTF("%s"XENSND_FIELD_CHANNELS_MAX, path),
+                                   GCSPRINTF("%u", params->channels_max));
+        if (rc) goto out;
+    }
+
+    if (params->buffer_size) {
+        rc = flexarray_append_pair(front,
+                                   GCSPRINTF("%s"XENSND_FIELD_BUFFER_SIZE, path),
+                                   GCSPRINTF("%u", params->buffer_size));
+        if (rc) goto out;
+    }
+
+    rc = 0;
+
+out:
+
+    return rc;
+}
+
+static int libxl__set_streams_vsnd(libxl__gc *gc, char *path,
+                                   libxl_vsnd_stream *streams,
+                                   int num_streams, flexarray_t *front)
+{
+    int i;
+    int rc;
+
+    for (i = 0; i < num_streams; i++) {
+        rc = flexarray_append_pair(front,
+                 GCSPRINTF("%s%d/"XENSND_FIELD_STREAM_UNIQUE_ID, path, i),
+                 streams[i].id);
+        if (rc) goto out;
+
+        const char *type = libxl_vsnd_stream_type_to_string(streams[i].type);
+
+        if (type) {
+            rc = flexarray_append_pair(front,
+                     GCSPRINTF("%s%d/"XENSND_FIELD_TYPE, path, i),
+                     (char *)type);
+            if (rc) goto out;
+        }
+
+        rc = libxl__set_params_vsnd(gc, GCSPRINTF("%s%d/", path, i),
+                                    &streams[i].params, front);
+        if (rc) goto out;
+    }
+
+    rc = 0;
+
+out:
+
+    return rc;
+}
+
+static int libxl__set_pcms_vsnd(libxl__gc *gc, libxl_vsnd_pcm *pcms,
+                                int num_pcms, flexarray_t *front)
+{
+    int i;
+    int rc;
+
+    for (i = 0; i < num_pcms; i++) {
+        if (pcms[i].name) {
+            rc = flexarray_append_pair(front,
+                                       GCSPRINTF("%d/"XENSND_FIELD_DEVICE_NAME, i),
+                                       pcms[i].name);
+            if (rc) goto out;
+        }
+
+        char *path = GCSPRINTF("%d/", i);
+
+        rc = libxl__set_params_vsnd(gc, path, &pcms[i].params, front);
+        if (rc) goto out;
+
+        rc = libxl__set_streams_vsnd(gc, path, pcms[i].streams,
+                                     pcms[i].num_vsnd_streams, front);
+        if (rc) goto out;
+    }
+
+    rc = 0;
+
+out:
+
+    return rc;
+}
+
+static int libxl__set_xenstore_vsnd(libxl__gc *gc, uint32_t domid,
+                                    libxl_device_vsnd *vsnd,
+                                    flexarray_t *back, flexarray_t *front,
+                                    flexarray_t *ro_front)
+{
+    int rc;
+
+    if (vsnd->long_name) {
+        rc = flexarray_append_pair(front, XENSND_FIELD_VCARD_LONG_NAME,
+                                   vsnd->long_name);
+        if (rc) goto out;
+    }
+
+    if (vsnd->short_name) {
+        rc = flexarray_append_pair(front, XENSND_FIELD_VCARD_SHORT_NAME,
+                                   vsnd->short_name);
+        if (rc) goto out;
+    }
+
+    rc = libxl__set_params_vsnd(gc, "", &vsnd->params, front);
+    if (rc) goto out;
+
+    rc = libxl__set_pcms_vsnd(gc, vsnd->pcms, vsnd->num_vsnd_pcms, front);
+    if (rc) goto out;
+
+    rc = 0;
+
+out:
+
+    return rc;
+}
+
+static LIBXL_DEFINE_UPDATE_DEVID(vsnd)
+static LIBXL_DEFINE_DEVICES_ADD(vsnd)
+
+LIBXL_DEFINE_DEVICE_ADD(vsnd)
+LIBXL_DEFINE_DEVICE_REMOVE(vsnd)
+
+DEFINE_DEVICE_TYPE_STRUCT(vsnd, VSND,
+    .update_config = (device_update_config_fn_t) libxl__update_config_vsnd,
+    .from_xenstore = (device_from_xenstore_fn_t) libxl__vsnd_from_xenstore,
+    .set_xenstore_config = (device_set_xenstore_config_fn_t)
+                           libxl__set_xenstore_vsnd
+);
+
+/*
+ * Local variables:
+ * mode: C
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.17.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/5] libxl: add vsnd list and info
  2018-05-18 14:38 [PATCH v2 0/5] libxl: add PV sound device Oleksandr Grytsov
  2018-05-18 14:38 ` [PATCH v2 1/5] " Oleksandr Grytsov
@ 2018-05-18 14:38 ` Oleksandr Grytsov
  2018-05-22 11:37   ` Wei Liu
  2018-05-18 14:38 ` [PATCH v2 3/5] xl: add PV sound condif parser Oleksandr Grytsov
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: Oleksandr Grytsov @ 2018-05-18 14:38 UTC (permalink / raw)
  To: xen-devel; +Cc: ian.jackson, wei.liu2, Oleksandr Grytsov

From: Oleksandr Grytsov <oleksandr_grytsov@epam.com>

Add getting vsnd list amd info API

Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
---
 tools/libxl/libxl.h         |  10 +
 tools/libxl/libxl_types.idl |  19 ++
 tools/libxl/libxl_utils.h   |   3 +
 tools/libxl/libxl_vsnd.c    | 374 +++++++++++++++++++++++++++++++++++-
 4 files changed, 403 insertions(+), 3 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index a312166b48..bfc788594c 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -2014,6 +2014,16 @@ int libxl_device_vsnd_destroy(libxl_ctx *ctx, uint32_t domid,
                               const libxl_asyncop_how *ao_how)
                               LIBXL_EXTERNAL_CALLERS_ONLY;
 
+libxl_device_vsnd *libxl_device_vsnd_list(libxl_ctx *ctx,
+                                          uint32_t domid, int *num)
+                                          LIBXL_EXTERNAL_CALLERS_ONLY;
+void libxl_device_vsnd_list_free(libxl_device_vsnd* list, int num)
+                                 LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_vsnd_getinfo(libxl_ctx *ctx, uint32_t domid,
+                              libxl_device_vsnd *vsnd,
+                              libxl_vsndinfo *vsndlinfo)
+                              LIBXL_EXTERNAL_CALLERS_ONLY;
+
 /* Keyboard */
 int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb,
                          const libxl_asyncop_how *ao_how)
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index ad978fb413..d959127dc2 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -1019,6 +1019,25 @@ libxl_vdisplinfo = Struct("vdisplinfo", [
     ("connectors", Array(libxl_connectorinfo, "num_connectors"))
     ], dir=DIR_OUT)
 
+libxl_streaminfo = Struct("streaminfo", [
+    ("req_evtch", integer),
+    ("req_rref", integer)
+    ])
+
+libxl_pcminfo = Struct("pcminfo", [
+    ("streams", Array(libxl_streaminfo, "num_vsnd_streams"))
+    ])
+
+libxl_vsndinfo = Struct("vsndinfo", [
+    ("backend", string),
+    ("backend_id", uint32),
+    ("frontend", string),
+    ("frontend_id", uint32),
+    ("devid", libxl_devid),
+    ("state", integer),
+    ("pcms", Array(libxl_pcminfo, "num_vsnd_pcms"))
+    ])
+
 # NUMA node characteristics: size and free are how much memory it has, and how
 # much of it is free, respectively. dists is an array of distances from this
 # node to each other node.
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index 9e743dc598..5455752c6e 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -82,6 +82,9 @@ int libxl_devid_to_device_usbctrl(libxl_ctx *ctx, uint32_t domid,
 int libxl_devid_to_device_vdispl(libxl_ctx *ctx, uint32_t domid,
                                  int devid, libxl_device_vdispl *vdispl);
 
+int libxl_devid_to_device_vsnd(libxl_ctx *ctx, uint32_t domid,
+                               int devid, libxl_device_vsnd *vsnd);
+
 int libxl_ctrlport_to_device_usbdev(libxl_ctx *ctx, uint32_t domid,
                                     int ctrl, int port,
                                     libxl_device_usbdev *usbdev);
diff --git a/tools/libxl/libxl_vsnd.c b/tools/libxl/libxl_vsnd.c
index 1e19217811..b188eb2fb3 100644
--- a/tools/libxl/libxl_vsnd.c
+++ b/tools/libxl/libxl_vsnd.c
@@ -37,22 +37,247 @@ static int libxl__device_from_vsnd(libxl__gc *gc, uint32_t domid,
    return 0;
 }
 
+static int libxl__sample_rates_from_string(libxl__gc *gc, const char *str,
+                                           libxl_vsnd_params *params)
+{
+    char *tmp = libxl__strdup(gc, str);
+
+    params->num_sample_rates = 0;
+    params->sample_rates = NULL;
+
+    char *p = strtok(tmp, " ,");
+
+    while (p != NULL) {
+        params->sample_rates = libxl__realloc(NOGC, params->sample_rates,
+                                              sizeof(*params->sample_rates) *
+                                              (params->num_sample_rates + 1));
+        params->sample_rates[params->num_sample_rates++] = strtoul(p, NULL, 0);
+        p = strtok(NULL, " ,");
+    }
+
+    return 0;
+}
+
+static int libxl__sample_formats_from_string(libxl__gc *gc, const char *str,
+                                             libxl_vsnd_params *params)
+{
+    int rc;
+    char *tmp = libxl__strdup(gc, str);
+
+    params->num_sample_formats = 0;
+    params->sample_formats = NULL;
+
+    char *p = strtok(tmp, " ,");
+
+    while (p != NULL) {
+        params->sample_formats = libxl__realloc(NOGC, params->sample_formats,
+                                                sizeof(*params->sample_formats) *
+                                                (params->num_sample_formats + 1));
+
+        libxl_vsnd_pcm_format format;
+
+        rc = libxl_vsnd_pcm_format_from_string(p, &format);
+        if (rc) goto out;
+
+        params->sample_formats[params->num_sample_formats++] = format;
+        p = strtok(NULL, " ,");
+    }
+
+    rc = 0;
+
+out:
+
+    return rc;
+}
+
+static int libxl__params_from_xenstore(libxl__gc *gc, const char *path,
+                                       libxl_vsnd_params *params)
+{
+    const char *tmp;
+    int rc;
+
+    rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                GCSPRINTF("%s/"XENSND_FIELD_SAMPLE_RATES,
+                                          path), &tmp);
+    if (rc) goto out;
+
+    if (tmp) {
+        rc = libxl__sample_rates_from_string(gc, tmp, params);
+        if (rc) goto out;
+    }
+
+    rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                GCSPRINTF("%s/"XENSND_FIELD_SAMPLE_FORMATS,
+                                          path), &tmp);
+    if (rc) goto out;
+
+    if (tmp) {
+        rc = libxl__sample_formats_from_string(gc, tmp, params);
+        if (rc) goto out;
+    }
+
+    rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                 GCSPRINTF("%s/"XENSND_FIELD_CHANNELS_MIN,
+                                           path), &tmp);
+    if (rc) goto out;
+
+    if (tmp) {
+        params->channels_min = strtoul(tmp, NULL, 0);
+    }
+
+    rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                 GCSPRINTF("%s/"XENSND_FIELD_CHANNELS_MAX,
+                                           path), &tmp);
+    if (rc) goto out;
+
+    if (tmp) {
+        params->channels_max = strtoul(tmp, NULL, 0);
+    }
+
+    rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                 GCSPRINTF("%s/"XENSND_FIELD_BUFFER_SIZE,
+                                           path), &tmp);
+    if (rc) goto out;
+
+    if (tmp) {
+        params->buffer_size = strtoul(tmp, NULL, 0);
+    }
+
+    rc = 0;
+
+out:
+
+    return rc;
+}
+
+static int libxl__stream_from_xenstore(libxl__gc *gc, const char *path,
+                                       libxl_vsnd_stream *stream)
+{
+    const char *tmp;
+    int rc;
+
+    stream->id = xs_read(CTX->xsh, XBT_NULL,
+                         GCSPRINTF("%s/"XENSND_FIELD_STREAM_UNIQUE_ID,
+                         path), NULL);
+
+    rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                GCSPRINTF("%s/"XENSND_FIELD_TYPE,
+                                          path), &tmp);
+    if (rc) goto out;
+
+    if (tmp) {
+        libxl_vsnd_stream_type type;
+
+        rc = libxl_vsnd_stream_type_from_string(tmp, &type);
+        if (rc) goto out;
+
+        stream->type = type;
+    }
+
+    rc = libxl__params_from_xenstore(gc, path, &stream->params);
+    if (rc) goto out;
+
+    rc = 0;
+
+out:
+
+    return rc;
+}
+
+static int libxl__pcm_from_xenstore(libxl__gc *gc, const char *path,
+                                    libxl_vsnd_pcm *pcm)
+{
+    const char *tmp;
+    int rc;
+
+    pcm->name = xs_read(CTX->xsh, XBT_NULL,
+                        GCSPRINTF("%s/"XENSND_FIELD_DEVICE_NAME, path), NULL);
+
+    rc = libxl__params_from_xenstore(gc, path, &pcm->params);
+
+    pcm->streams = NULL;
+    pcm->num_vsnd_streams = 0;
+
+    do {
+        char *stream_path = GCSPRINTF("%s/%d", path, pcm->num_vsnd_streams);
+
+        rc = libxl__xs_read_checked(gc, XBT_NULL, stream_path, &tmp);
+        if (rc) goto out;
+
+        if (tmp) {
+            pcm->streams = libxl__realloc(NOGC, pcm->streams,
+                                          sizeof(*pcm->streams) *
+                                          (++pcm->num_vsnd_streams));
+
+            libxl_vsnd_stream_init(&pcm->streams[pcm->num_vsnd_streams - 1]);
+
+            rc = libxl__stream_from_xenstore(gc, stream_path,
+                                             &pcm->streams[pcm->num_vsnd_streams
+                                             - 1]);
+            if (rc) goto out;
+        }
+    } while (tmp);
+
+    rc = 0;
+
+out:
+
+    return rc;
+}
+
 static int libxl__vsnd_from_xenstore(libxl__gc *gc, const char *libxl_path,
                                      libxl_devid devid,
                                      libxl_device_vsnd *vsnd)
 {
-    const char *be_path;
+    const char *tmp;
+    const char *fe_path;
     int rc;
 
     vsnd->devid = devid;
     rc = libxl__xs_read_mandatory(gc, XBT_NULL,
                                   GCSPRINTF("%s/backend", libxl_path),
-                                  &be_path);
+                                  &tmp);
+    if (rc) goto out;
+
+    rc = libxl__backendpath_parse_domid(gc, tmp, &vsnd->backend_domid);
     if (rc) goto out;
 
-    rc = libxl__backendpath_parse_domid(gc, be_path, &vsnd->backend_domid);
+    rc = libxl__xs_read_mandatory(gc, XBT_NULL,
+                                  GCSPRINTF("%s/frontend", libxl_path),
+                                  &fe_path);
     if (rc) goto out;
 
+    vsnd->short_name = xs_read(CTX->xsh, XBT_NULL,
+                               GCSPRINTF("%s/"XENSND_FIELD_VCARD_SHORT_NAME,
+                               fe_path), NULL);
+
+    vsnd->long_name = xs_read(CTX->xsh, XBT_NULL,
+                              GCSPRINTF("%s/"XENSND_FIELD_VCARD_LONG_NAME,
+                              fe_path), NULL);
+
+    rc = libxl__params_from_xenstore(gc, fe_path, &vsnd->params);
+
+    vsnd->pcms = NULL;
+    vsnd->num_vsnd_pcms = 0;
+
+    do {
+        char *pcm_path = GCSPRINTF("%s/%d", fe_path, vsnd->num_vsnd_pcms);
+
+        rc = libxl__xs_read_checked(gc, XBT_NULL, pcm_path, &tmp);
+        if (rc) goto out;
+
+        if (tmp) {
+            vsnd->pcms = libxl__realloc(NOGC, vsnd->pcms, sizeof(*vsnd->pcms) *
+                                        (++vsnd->num_vsnd_pcms));
+
+            libxl_vsnd_pcm_init(&vsnd->pcms[vsnd->num_vsnd_pcms - 1]);
+
+            rc = libxl__pcm_from_xenstore(gc, pcm_path,
+                                          &vsnd->pcms[vsnd->num_vsnd_pcms - 1]);
+            if (rc) goto out;
+        }
+    } while (tmp);
+
     rc = 0;
 
 out:
@@ -309,11 +534,154 @@ out:
     return rc;
 }
 
+static int libxl__device_stream_getinfo(libxl__gc *gc, const char *path,
+                                        libxl_vsnd_pcm* pcm,
+                                        libxl_pcminfo *info)
+{
+    const char *tmp;
+    int i;
+    int rc;
+
+    info->num_vsnd_streams = pcm->num_vsnd_streams;
+    info->streams = malloc(sizeof(*info->streams) * info->num_vsnd_streams);
+
+    for (i = 0; i < info->num_vsnd_streams; i++)
+    {
+        libxl_streaminfo_init(&info->streams[i]);
+
+        rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                    GCSPRINTF("%s/%d/"XENSND_FIELD_RING_REF,
+                                    path, i), &tmp);
+        if (rc) goto out;
+
+        info->streams[i].req_rref = tmp ? strtoul(tmp, NULL, 10) : -1;
+
+        rc = libxl__xs_read_checked(gc, XBT_NULL,
+                                    GCSPRINTF("%s/%d/"XENSND_FIELD_EVT_CHNL,
+                                    path, i), &tmp);
+        if (rc) goto out;
+
+        info->streams[i].req_evtch = tmp ? strtoul(tmp, NULL, 10) : -1;
+    }
+
+    rc = 0;
+
+out:
+
+    return rc;
+}
+
+static int libxl__device_pcm_getinfo(libxl__gc *gc, const char *path,
+                                     libxl_device_vsnd *vsnd,
+                                     libxl_vsndinfo *info)
+{
+    int i;
+    int rc;
+
+    info->num_vsnd_pcms = vsnd->num_vsnd_pcms;
+    info->pcms = malloc(sizeof(*info->pcms) * info->num_vsnd_pcms);
+
+    for (i = 0; i < info->num_vsnd_pcms; i++)
+    {
+        libxl_pcminfo_init(&info->pcms[i]);
+
+        rc = libxl__device_stream_getinfo(gc, GCSPRINTF("%s/%d", path, i),
+                                          &vsnd->pcms[i], &info->pcms[i]);
+        if (rc) goto out;
+    }
+
+    rc = 0;
+
+out:
+
+
+
+    return rc;
+}
+
+int libxl_device_vsnd_getinfo(libxl_ctx *ctx, uint32_t domid,
+                              libxl_device_vsnd *vsnd,
+                              libxl_vsndinfo *info)
+{
+    GC_INIT(ctx);
+    char *libxl_path, *dompath, *devpath;
+    const char *val;
+    int rc;
+
+    libxl_vsndinfo_init(info);
+    dompath = libxl__xs_get_dompath(gc, domid);
+    info->devid = vsnd->devid;
+
+    devpath = libxl__domain_device_frontend_path(gc, domid, info->devid,
+                                                 LIBXL__DEVICE_KIND_VSND);
+    libxl_path = libxl__domain_device_libxl_path(gc, domid, info->devid,
+                                                 LIBXL__DEVICE_KIND_VSND);
+
+    info->backend = xs_read(ctx->xsh, XBT_NULL,
+                            GCSPRINTF("%s/backend", libxl_path), NULL);
+
+    rc = libxl__backendpath_parse_domid(gc, info->backend, &info->backend_id);
+    if (rc) goto out;
+
+    val = xs_read(ctx->xsh, XBT_NULL, GCSPRINTF("%s/state", devpath), NULL);
+
+    info->state = val ? strtoul(val, NULL, 10) : -1;
+
+    info->frontend = xs_read(ctx->xsh, XBT_NULL,
+                             GCSPRINTF("%s/frontend", libxl_path), NULL);
+
+    info->frontend_id = domid;
+
+    rc = libxl__device_pcm_getinfo(gc, devpath, vsnd, info);
+    if (rc) goto out;
+
+    rc = 0;
+
+out:
+     GC_FREE;
+     return rc;
+}
+
+int libxl_devid_to_device_vsnd(libxl_ctx *ctx, uint32_t domid,
+                               int devid, libxl_device_vsnd *vsnd)
+{
+    GC_INIT(ctx);
+
+    libxl_device_vsnd *vsnds = NULL;
+    int n, i;
+    int rc;
+
+    libxl_device_vsnd_init(vsnd);
+
+    vsnds = libxl__device_list(gc, &libxl__vsnd_devtype, domid, &n);
+
+    if (!vsnds) { rc = ERROR_NOTFOUND; goto out; }
+
+    for (i = 0; i < n; ++i) {
+        if (devid == vsnds[i].devid) {
+            libxl_device_vsnd_copy(ctx, vsnd, &vsnds[i]);
+            rc = 0;
+            goto out;
+        }
+    }
+
+    rc = ERROR_NOTFOUND;
+
+out:
+
+    if (vsnds)
+        libxl__device_list_free(&libxl__vsnd_devtype, vsnds, n);
+
+    GC_FREE;
+    return rc;
+}
+
 static LIBXL_DEFINE_UPDATE_DEVID(vsnd)
 static LIBXL_DEFINE_DEVICES_ADD(vsnd)
 
 LIBXL_DEFINE_DEVICE_ADD(vsnd)
 LIBXL_DEFINE_DEVICE_REMOVE(vsnd)
+LIBXL_DEFINE_DEVICE_LIST(vsnd)
 
 DEFINE_DEVICE_TYPE_STRUCT(vsnd, VSND,
     .update_config = (device_update_config_fn_t) libxl__update_config_vsnd,
-- 
2.17.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 3/5] xl: add PV sound condif parser
  2018-05-18 14:38 [PATCH v2 0/5] libxl: add PV sound device Oleksandr Grytsov
  2018-05-18 14:38 ` [PATCH v2 1/5] " Oleksandr Grytsov
  2018-05-18 14:38 ` [PATCH v2 2/5] libxl: add vsnd list and info Oleksandr Grytsov
@ 2018-05-18 14:38 ` Oleksandr Grytsov
  2018-05-18 14:38 ` [PATCH v2 4/5] xl: add vsnd CLI commands Oleksandr Grytsov
  2018-05-18 14:38 ` [PATCH v2 5/5] docs: add PV sound device config Oleksandr Grytsov
  4 siblings, 0 replies; 7+ messages in thread
From: Oleksandr Grytsov @ 2018-05-18 14:38 UTC (permalink / raw)
  To: xen-devel; +Cc: ian.jackson, wei.liu2, Oleksandr Grytsov

From: Oleksandr Grytsov <oleksandr_grytsov@epam.com>

Add config parser for virtual sound devices

Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
---
 tools/xl/xl_parse.c | 246 ++++++++++++++++++++++++++++++++++++++++++++
 tools/xl/xl_parse.h |   1 +
 2 files changed, 247 insertions(+)

diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index e6c54483e0..b9e8e1f997 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -851,6 +851,250 @@ out:
     return rc;
 }
 
+static int parse_vsnd_params(libxl_vsnd_params *params, char *token)
+{
+    char *oparg;
+    int i;
+
+    if (MATCH_OPTION("sample-rates", token, oparg)) {
+        libxl_string_list rates = NULL;
+
+        split_string_into_string_list(oparg, ";", &rates);
+
+        params->num_sample_rates = libxl_string_list_length(&rates);
+        params->sample_rates = calloc(params->num_sample_rates,
+                                      sizeof(*params->sample_rates));
+
+        for (i = 0; i < params->num_sample_rates; i++) {
+            params->sample_rates[i] = strtoul(rates[i], NULL, 0);
+        }
+
+        libxl_string_list_dispose(&rates);
+    } else if (MATCH_OPTION("sample-formats", token, oparg)) {
+        libxl_string_list formats = NULL;
+
+        split_string_into_string_list(oparg, ";", &formats);
+
+        params->num_sample_formats = libxl_string_list_length(&formats);
+        params->sample_formats = calloc(params->num_sample_formats,
+                                        sizeof(*params->sample_formats));
+
+        for (i = 0; i < params->num_sample_formats; i++) {
+            libxl_vsnd_pcm_format format;
+
+            if (libxl_vsnd_pcm_format_from_string(formats[i], &format)) {
+                fprintf(stderr, "Invalid pcm format: %s\n", formats[i]);
+                exit(EXIT_FAILURE);
+            }
+
+            params->sample_formats[i] = format;
+        }
+
+        libxl_string_list_dispose(&formats);
+    } else if (MATCH_OPTION("channels-min", token, oparg)) {
+        params->channels_min = strtoul(oparg, NULL, 0);
+    } else if (MATCH_OPTION("channels-max", token, oparg)) {
+        params->channels_max = strtoul(oparg, NULL, 0);
+    } else if (MATCH_OPTION("buffer-size", token, oparg)) {
+        params->buffer_size = strtoul(oparg, NULL, 0);
+    } else {
+        return 1;
+    }
+
+    return 0;
+}
+
+static int parse_vsnd_pcm_stream(libxl_device_vsnd *vsnd, char *param)
+{
+    if (vsnd->num_vsnd_pcms == 0) {
+        fprintf(stderr, "No vsnd pcm device\n");
+        return -1;
+    }
+
+    libxl_vsnd_pcm *pcm = &vsnd->pcms[vsnd->num_vsnd_pcms - 1];
+
+    if (pcm->num_vsnd_streams == 0) {
+        fprintf(stderr, "No vsnd stream\n");
+        return -1;
+    }
+
+    libxl_vsnd_stream *stream = &pcm->streams[pcm->num_vsnd_streams - 1];
+
+    if (parse_vsnd_params(&stream->params, param)) {
+        char *oparg;
+
+        if (MATCH_OPTION("id", param, oparg)) {
+            stream->id = strdup(oparg);
+        } else if (MATCH_OPTION("type", param, oparg)) {
+
+            if (libxl_vsnd_stream_type_from_string(oparg, &stream->type)) {
+                fprintf(stderr, "Invalid stream type: %s\n", oparg);
+                return -1;
+            }
+        } else {
+            fprintf(stderr, "Invalid parameter: %s\n", param);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+static int parse_vsnd_pcm_param(libxl_device_vsnd *vsnd, char *param)
+{
+    if (vsnd->num_vsnd_pcms == 0) {
+        fprintf(stderr, "No pcm device\n");
+        return -1;
+    }
+
+    libxl_vsnd_pcm *pcm = &vsnd->pcms[vsnd->num_vsnd_pcms - 1];
+
+    if (parse_vsnd_params(&pcm->params, param)) {
+        char *oparg;
+
+        if (MATCH_OPTION("name", param, oparg)) {
+            pcm->name = strdup(oparg);
+        } else {
+            fprintf(stderr, "Invalid parameter: %s\n", param);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+static int parse_vsnd_card_param(libxl_device_vsnd *vsnd, char *param)
+{
+    if (parse_vsnd_params(&vsnd->params, param)) {
+        char *oparg;
+
+        if (MATCH_OPTION("backend", param, oparg)) {
+            vsnd->backend_domname = strdup(oparg);
+        } else if (MATCH_OPTION("short-name", param, oparg)) {
+            vsnd->short_name = strdup(oparg);
+        } else if (MATCH_OPTION("long-name", param, oparg)) {
+            vsnd->long_name = strdup(oparg);
+        } else {
+            fprintf(stderr, "Invalid parameter: %s\n", param);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+static int parse_vsnd_create_item(libxl_device_vsnd *vsnd, const char *key)
+{
+    if (strcasecmp(key, "card") == 0) {
+
+    } else if (strcasecmp(key, "pcm") == 0) {
+        ARRAY_EXTEND_INIT_NODEVID(vsnd->pcms, vsnd->num_vsnd_pcms,
+                                  libxl_vsnd_pcm_init);
+    } else if (strcasecmp(key, "stream") == 0) {
+        if (vsnd->num_vsnd_pcms == 0) {
+            ARRAY_EXTEND_INIT_NODEVID(vsnd->pcms, vsnd->num_vsnd_pcms,
+                                      libxl_vsnd_pcm_init);
+        }
+
+        libxl_vsnd_pcm *pcm =  &vsnd->pcms[vsnd->num_vsnd_pcms - 1];
+
+        ARRAY_EXTEND_INIT_NODEVID(pcm->streams, pcm->num_vsnd_streams,
+                                  libxl_vsnd_stream_init);
+    } else {
+        fprintf(stderr, "Invalid key: %s\n", key);
+        return -1;
+    }
+
+    return 0;
+}
+
+int parse_vsnd_item(libxl_device_vsnd *vsnd, const char *spec)
+{
+    char *buf = strdup(spec);
+    char *token = strtok(buf, ",");
+    char *key = NULL;
+    int ret;
+
+    while (token) {
+        while (*token == ' ') token++;
+
+        if (!key) {
+            key = token;
+            ret = parse_vsnd_create_item(vsnd, key);
+            if (ret) goto out;
+        } else {
+            if (strcasecmp(key, "card") == 0) {
+                ret = parse_vsnd_card_param(vsnd, token);
+                if (ret) goto out;
+            } else if (strcasecmp(key, "pcm") == 0) {
+                ret = parse_vsnd_pcm_param(vsnd, token);
+                if (ret) goto out;
+            } else if (strcasecmp(key, "stream") == 0) {
+                ret = parse_vsnd_pcm_stream(vsnd, token);
+                if (ret) goto out;
+            }
+        }
+        token = strtok (NULL, ",");
+    }
+
+    ret = 0;
+
+out:
+    free(buf);
+    return ret;
+}
+
+static void parse_vsnd_card_config(const XLU_Config *config,
+                                   XLU_ConfigValue *card_value,
+                                   libxl_domain_config *d_config)
+{
+    int ret;
+    XLU_ConfigList *card_list;
+    libxl_device_vsnd *vsnd;
+    const char *card_item;
+    int item = 0;
+
+    ret = xlu_cfg_value_get_list(config, card_value,  &card_list, 0);
+
+    if (ret) {
+        fprintf(stderr, "Failed to get vsnd card list: %s\n", strerror(ret));
+        goto out;
+    }
+
+    vsnd = ARRAY_EXTEND_INIT(d_config->vsnds,
+                             d_config->num_vsnds,
+                             libxl_device_vsnd_init);
+
+    while ((card_item = xlu_cfg_get_listitem(card_list, item++)) != NULL) {
+        ret = parse_vsnd_item(vsnd, card_item);
+        if (ret) goto out;
+    }
+
+    ret = 0;
+
+out:
+
+    if (ret) exit(EXIT_FAILURE);
+}
+
+static void parse_vsnd_config(const XLU_Config *config,
+                              libxl_domain_config *d_config)
+{
+    XLU_ConfigList *vsnds;
+
+    if (!xlu_cfg_get_list(config, "vsnd", &vsnds, 0, 0)) {
+        XLU_ConfigValue *card_value;
+
+        d_config->num_vsnds = 0;
+        d_config->vsnds = NULL;
+
+        while ((card_value = xlu_cfg_get_listitem2(vsnds, d_config->num_vsnds))
+               != NULL) {
+            parse_vsnd_card_config(config, card_value, d_config);
+        }
+    }
+}
+
 void parse_config_data(const char *config_source,
                        const char *config_data,
                        int config_len,
@@ -1726,6 +1970,8 @@ void parse_config_data(const char *config_source,
         }
     }
 
+    parse_vsnd_config(config, d_config);
+
     if (!xlu_cfg_get_list (config, "channel", &channels, 0, 0)) {
         d_config->num_channels = 0;
         d_config->channels = NULL;
diff --git a/tools/xl/xl_parse.h b/tools/xl/xl_parse.h
index cc459fb43f..9a948ea4f7 100644
--- a/tools/xl/xl_parse.h
+++ b/tools/xl/xl_parse.h
@@ -34,6 +34,7 @@ int parse_usbdev_config(libxl_device_usbdev *usbdev, char *token);
 int parse_cpurange(const char *cpu, libxl_bitmap *cpumap);
 int parse_nic_config(libxl_device_nic *nic, XLU_Config **config, char *token);
 int parse_vdispl_config(libxl_device_vdispl *vdispl, char *token);
+int parse_vsnd_item(libxl_device_vsnd *vsnd, const char *spec);
 
 int match_option_size(const char *prefix, size_t len,
                       char *arg, char **argopt);
-- 
2.17.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 4/5] xl: add vsnd CLI commands
  2018-05-18 14:38 [PATCH v2 0/5] libxl: add PV sound device Oleksandr Grytsov
                   ` (2 preceding siblings ...)
  2018-05-18 14:38 ` [PATCH v2 3/5] xl: add PV sound condif parser Oleksandr Grytsov
@ 2018-05-18 14:38 ` Oleksandr Grytsov
  2018-05-18 14:38 ` [PATCH v2 5/5] docs: add PV sound device config Oleksandr Grytsov
  4 siblings, 0 replies; 7+ messages in thread
From: Oleksandr Grytsov @ 2018-05-18 14:38 UTC (permalink / raw)
  To: xen-devel; +Cc: ian.jackson, wei.liu2, Oleksandr Grytsov

From: Oleksandr Grytsov <oleksandr_grytsov@epam.com>

Add CLI commands to attach, detach and list virtual sound devices

Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
---
 tools/xl/Makefile      |   2 +-
 tools/xl/xl.h          |   3 +
 tools/xl/xl_cmdtable.c |  15 +++
 tools/xl/xl_vsnd.c     | 203 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 222 insertions(+), 1 deletion(-)
 create mode 100644 tools/xl/xl_vsnd.c

diff --git a/tools/xl/Makefile b/tools/xl/Makefile
index a5117ab3fb..66bdbdef13 100644
--- a/tools/xl/Makefile
+++ b/tools/xl/Makefile
@@ -22,7 +22,7 @@ XL_OBJS += xl_vtpm.o xl_block.o xl_nic.o xl_usb.o
 XL_OBJS += xl_sched.o xl_pci.o xl_vcpu.o xl_cdrom.o xl_mem.o
 XL_OBJS += xl_info.o xl_console.o xl_misc.o
 XL_OBJS += xl_vmcontrol.o xl_saverestore.o xl_migrate.o
-XL_OBJS += xl_vdispl.o
+XL_OBJS += xl_vdispl.o xl_vsnd.o
 
 $(XL_OBJS): CFLAGS += $(CFLAGS_libxentoollog)
 $(XL_OBJS): CFLAGS += $(CFLAGS_XL)
diff --git a/tools/xl/xl.h b/tools/xl/xl.h
index 4e784ff402..a6b85f6db2 100644
--- a/tools/xl/xl.h
+++ b/tools/xl/xl.h
@@ -170,6 +170,9 @@ int main_vtpmdetach(int argc, char **argv);
 int main_vdisplattach(int argc, char **argv);
 int main_vdispllist(int argc, char **argv);
 int main_vdispldetach(int argc, char **argv);
+int main_vsndattach(int argc, char **argv);
+int main_vsndlist(int argc, char **argv);
+int main_vsnddetach(int argc, char **argv);
 int main_usbctrl_attach(int argc, char **argv);
 int main_usbctrl_detach(int argc, char **argv);
 int main_usbdev_attach(int argc, char **argv);
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index bf2ced8140..10426a2ffd 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -399,6 +399,21 @@ struct cmd_spec cmd_table[] = {
       "Destroy a domain's virtual display device",
       "<Domain> <DevId>",
     },
+    { "vsnd-attach",
+      &main_vsndattach, 1, 1,
+      "Create a new virtual sound device",
+      "<Domain> <vsnd-spec-component(s)>...",
+    },
+    { "vsnd-list",
+      &main_vsndlist, 0, 0,
+      "List virtual display devices for a domain",
+      "<Domain(s)>",
+    },
+    { "vsnd-detach",
+      &main_vsnddetach, 0, 1,
+      "Destroy a domain's virtual sound device",
+      "<Domain> <DevId>",
+    },
     { "uptime",
       &main_uptime, 0, 0,
       "Print uptime for all/some domains",
diff --git a/tools/xl/xl_vsnd.c b/tools/xl/xl_vsnd.c
new file mode 100644
index 0000000000..41ee0ba5fe
--- /dev/null
+++ b/tools/xl/xl_vsnd.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2016 EPAM Systems Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include <stdlib.h>
+
+#include <libxl.h>
+#include <libxl_utils.h>
+#include <libxlutil.h>
+
+#include "xl.h"
+#include "xl_utils.h"
+#include "xl_parse.h"
+
+int main_vsndattach(int argc, char **argv)
+{
+    int opt;
+    int rc;
+    uint32_t domid;
+    libxl_device_vsnd vsnd;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vsnd-attach", 2) {
+        /* No options */
+    }
+
+    libxl_device_vsnd_init(&vsnd);
+    domid = find_domain(argv[optind++]);
+
+    for (argv += optind, argc -= optind; argc > 0; ++argv, --argc) {
+        rc = parse_vsnd_item(&vsnd, *argv);
+        if (rc) goto out;
+    }
+
+    if (dryrun_only) {
+        char *json = libxl_device_vsnd_to_json(ctx, &vsnd);
+        printf("vsnd: %s\n", json);
+        free(json);
+        goto out;
+    }
+
+    if (libxl_device_vsnd_add(ctx, domid, &vsnd, 0)) {
+        fprintf(stderr, "libxl_device_vsnd_add failed.\n");
+        rc = ERROR_FAIL; goto out;
+    }
+
+    rc = 0;
+
+out:
+    libxl_device_vsnd_dispose(&vsnd);
+    return rc;
+}
+
+static void print_params(libxl_vsnd_params *params)
+{
+    int i;
+
+    if (params->channels_min) {
+        printf(", channels-min: %u", params->channels_min);
+    }
+
+    if (params->channels_max) {
+        printf(", channels-max: %u", params->channels_max);
+    }
+
+    if (params->buffer_size) {
+        printf(", buffer-size: %u", params->buffer_size);
+    }
+
+    if (params->num_sample_rates) {
+        printf(", sample-rates: ");
+        for (i = 0; i < params->num_sample_rates - 1; i++) {
+            printf("%u;", params->sample_rates[i]);
+        }
+        printf("%u", params->sample_rates[i]);
+    }
+
+    if (params->num_sample_formats) {
+        printf(", sample-formats: ");
+        for (i = 0; i < params->num_sample_formats - 1; i++) {
+            printf("%s;", libxl_vsnd_pcm_format_to_string(params->sample_formats[i]));
+        }
+        printf("%s", libxl_vsnd_pcm_format_to_string(params->sample_formats[i]));
+    }
+
+    printf("\n");
+}
+
+int main_vsndlist(int argc, char **argv)
+{
+   int opt;
+   int i, j, k, n;
+   libxl_device_vsnd *vsnds;
+   libxl_vsndinfo vsndinfo;
+
+   SWITCH_FOREACH_OPT(opt, "", NULL, "vsnd-list", 1) {
+       /* No options */
+   }
+
+   for (argv += optind, argc -= optind; argc > 0; --argc, ++argv) {
+       uint32_t domid;
+
+       if (libxl_domain_qualifier_to_domid(ctx, *argv, &domid) < 0) {
+           fprintf(stderr, "%s is an invalid domain identifier\n", *argv);
+           continue;
+       }
+
+       vsnds = libxl_device_vsnd_list(ctx, domid, &n);
+
+       if (!vsnds) continue;
+
+       for (i = 0; i < n; i++) {
+           libxl_vsndinfo_init(&vsndinfo);
+           if (libxl_device_vsnd_getinfo(ctx, domid, &vsnds[i],
+                                         &vsndinfo) == 0) {
+               printf("\ndevid: %d, be-domid: %d, handle: %d, state: %d, "
+                      "be-path: %s, fe-path: %s\n",
+                      vsndinfo.devid, vsndinfo.backend_id,
+                      vsndinfo.frontend_id, vsndinfo.state,
+                      vsndinfo.backend, vsndinfo.frontend);
+
+               printf("short-name: \"%s\", long-name: \"%s\"",
+                      vsnds[i].short_name, vsnds[i].long_name);
+               print_params(&vsnds[i].params);
+
+               for (j = 0; j < vsndinfo.num_vsnd_pcms; j++) {
+                   libxl_vsnd_pcm *pcm = &vsnds[i].pcms[j];
+
+                   printf("\tpcm: %d, name: \"%s\"", j, pcm->name);
+                   print_params(&pcm->params);
+
+                   for(k = 0; k < vsnds[i].pcms[j].num_vsnd_streams; k++) {
+                       libxl_vsnd_stream *stream = &vsnds[i].pcms[j].streams[k];
+                       libxl_streaminfo *info = &vsndinfo.pcms[j].streams[k];
+
+                       printf("\t\tstream: %d, id: \"%s\", type: %s",
+                              k, stream->id,
+                              libxl_vsnd_stream_type_to_string(stream->type));
+                       print_params(&stream->params);
+                       printf("\t\t\tevent-channel: %d, ring-ref: %d\n",
+                              info->req_evtch, info->req_rref);
+                   }
+               }
+           }
+           libxl_vsndinfo_dispose(&vsndinfo);
+       }
+       libxl_device_vsnd_list_free(vsnds, n);
+   }
+   return 0;
+}
+
+int main_vsnddetach(int argc, char **argv)
+{
+    uint32_t domid, devid;
+    int opt, rc;
+    libxl_device_vsnd vsnd;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vsnd-detach", 2) {
+        /* No options */
+    }
+
+    domid = find_domain(argv[optind++]);
+    devid = atoi(argv[optind++]);
+
+    libxl_device_vsnd_init(&vsnd);
+
+    if (libxl_devid_to_device_vsnd(ctx, domid, devid, &vsnd)) {
+        fprintf(stderr, "Error: Device %d not connected.\n", devid);
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    rc = libxl_device_vsnd_remove(ctx, domid, &vsnd, 0);
+    if (rc) {
+        fprintf(stderr, "libxl_device_vsnd_remove failed.\n");
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    rc = 0;
+
+out:
+    libxl_device_vsnd_dispose(&vsnd);
+    return rc;
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.17.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 5/5] docs: add PV sound device config
  2018-05-18 14:38 [PATCH v2 0/5] libxl: add PV sound device Oleksandr Grytsov
                   ` (3 preceding siblings ...)
  2018-05-18 14:38 ` [PATCH v2 4/5] xl: add vsnd CLI commands Oleksandr Grytsov
@ 2018-05-18 14:38 ` Oleksandr Grytsov
  4 siblings, 0 replies; 7+ messages in thread
From: Oleksandr Grytsov @ 2018-05-18 14:38 UTC (permalink / raw)
  To: xen-devel; +Cc: ian.jackson, wei.liu2, Oleksandr Grytsov

From: Oleksandr Grytsov <oleksandr_grytsov@epam.com>

Update documentation with virtual sound device

Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
---
 docs/man/xl.cfg.pod.5.in | 149 +++++++++++++++++++++++++++++++++++++++
 docs/man/xl.pod.1.in     |  30 ++++++++
 2 files changed, 179 insertions(+)

diff --git a/docs/man/xl.cfg.pod.5.in b/docs/man/xl.cfg.pod.5.in
index 47d88243b1..f96bd1b9ad 100644
--- a/docs/man/xl.cfg.pod.5.in
+++ b/docs/man/xl.cfg.pod.5.in
@@ -1414,6 +1414,155 @@ we may break backward compatibility.
 
 =back
 
+=item B<vsnd=[ VCARD_SPEC, VCARD_SPEC, ... ]>
+
+Specifies the virtual sound cards to be provided to the guest.
+Each B<VCARD_SPEC> is a list, which has a form of
+"[VSND_ITEM_SPEC, VSND_ITEM_SPEC, ... ]" (without the quotes).
+The virtual sound card has hierarchical structure.
+Every card has a set of PCM devices and streams, each could be individually
+configured.
+
+B<VSND_ITEM_SPEC> describes individual item parameters.
+B<VSND_ITEM_SPEC> is a string of comma separated item parameters
+headed by item identifier. Each item parameter is C<KEY=VALUE> pair:
+
+=over 4
+
+"identifier, param = value, ...".
+
+=back
+
+Identifier shall be one of following values: "CARD", "PCM", "STREAM".
+The child item treated as belonging to the previously defined parent item.
+
+All parameters are optional.
+
+There are group of parameters which are common for all items.
+This group can be defined at higher level of the hierarchy and be fully or
+partially re-used by the underlying layers. These parameters are:
+
+=over 4
+
+* number of channels (min/max)
+
+* supported sample rates
+
+* supported sample formats
+
+=back
+
+E.g. one can define these values for the whole card, device or stream.
+Every underlying layer in turn can re-define some or all of them to better
+fit its needs. For example, card may define number of channels to be
+in [1; 8] range, and some particular stream may be limited to [1; 2] only.
+The rule is that the underlying layer must be a subset of the upper layer
+range.
+
+I<COMMON parameters:>
+
+=over 4
+
+=over 4
+
+=item B<sample-rates=RATES>
+
+List of integer values separated by semicolon: sample-rates=8000;22050;44100
+
+=item B<sample-formats=FORMATS>
+
+List of string values separated by semicolon: sample-formats=s16_le;s8;u32_be
+
+Supported formats: s8, u8, s16_le, s16_be, u16_le, u16_be, s24_le, s24_be,
+u24_le, u24_be, s32_le, s32_be, u32_le, u32_be, float_le, float_be,
+float64_le, float64_be, iec958_subframe_le, iec958_subframe_be,
+mu_law, a_law, ima_adpcm, mpeg, gsm
+
+=item B<channels-min=NUMBER>
+
+The minimum amount of channels.
+
+=item B<channels-max=NUMBER>
+
+The maximum amount of channels.
+
+=item B<buffer-size=NUMBER>
+
+The maximum size in octets of the buffer to allocate per stream.
+
+=back
+
+=back
+
+I<CARD specification:>
+
+=over 4
+
+=over 4
+
+=item B<backend=domain-id>
+
+Specify the backend domain name or id, defaults to dom0.
+
+=item B<short-name=STRING>
+
+Short name of the virtual sound card.
+
+=item B<long-name=STRING>
+
+Long name of the virtual sound card.
+
+=back
+
+=back
+
+I<PCM specification:>
+
+=over 4
+
+=over 4
+
+=item B<name=STRING>
+
+Name of the PCM sound device within the virtual sound card.
+
+=back
+
+=back
+
+I<STREAM specification:>
+
+=over 4
+
+=over 4
+
+=item B<id=STRING>
+
+Unique stream identifier.
+
+=item B<type=TYPE>
+
+Stream type: "p" - playback stream, "c" - capture stream.
+
+=back
+
+=back
+
+I<EXAMPLE:>
+
+    vsnd = [
+        ['CARD, short-name=Main, sample-formats=s16_le;s8;u32_be',
+            'PCM, name=Main',
+                'STREAM, id=0, type=p',
+                'STREAM, id=1, type=c, channels-max=2'
+        ],
+        ['CARD, short-name=Second',
+            'PCM, name=Second, buffer-size=1024',
+                'STREAM, id=2, type=p',
+                'STREAM, id=3, type=c'
+        ]
+    ]
+
 =back
 
 =head2 Paravirtualised (PV) Guest Specific Options
diff --git a/docs/man/xl.pod.1.in b/docs/man/xl.pod.1.in
index 48da2052cc..90423bf3df 100644
--- a/docs/man/xl.pod.1.in
+++ b/docs/man/xl.pod.1.in
@@ -1492,6 +1492,36 @@ List virtual displays for a domain.
 
 =back
 
+=head2 VSND DEVICES
+
+=over 4
+
+=item B<vsnd-attach> I<domain-id> I<vsnd-item> I<vsnd-item> ...
+
+Creates a new vsnd device in the domain specified by I<domain-id>.
+I<vsnd-item>'s describe the vsnd device to attach, using the same format as the
+B<VSND_ITEM_SPEC> string in the domain config file. See L<xl.cfg> for
+more information.
+
+B<EXAMPLE>
+
+=over 4
+
+xl vsnd-attach DomU 'CARD, short-name=Main, sample-formats=s16_le;s8;u32_be'
+'PCM, name=Main' 'STREAM, id=0, type=p' 'STREAM, id=1, type=c, channels-max=2'
+
+=back
+
+=item B<vsnd-detach> I<domain-id> I<dev-id>
+
+Removes the vsnd device specified by I<dev-id> from the domain specified by I<domain-id>.
+
+=item B<vsnd-list> I<domain-id>
+
+List vsnd devices for a domain.
+
+=back
+
 =head1 PCI PASS-THROUGH
 
 =over 4
-- 
2.17.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/5] libxl: add vsnd list and info
  2018-05-18 14:38 ` [PATCH v2 2/5] libxl: add vsnd list and info Oleksandr Grytsov
@ 2018-05-22 11:37   ` Wei Liu
  0 siblings, 0 replies; 7+ messages in thread
From: Wei Liu @ 2018-05-22 11:37 UTC (permalink / raw)
  To: Oleksandr Grytsov; +Cc: xen-devel, wei.liu2, ian.jackson, Oleksandr Grytsov

On Fri, May 18, 2018 at 05:38:27PM +0300, Oleksandr Grytsov wrote:
> From: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
> 
> Add getting vsnd list amd info API

amd -> and here.

> 
[...]
>  
> +static int libxl__device_stream_getinfo(libxl__gc *gc, const char *path,
> +                                        libxl_vsnd_pcm* pcm,
> +                                        libxl_pcminfo *info)
> +{
> +    const char *tmp;
> +    int i;
> +    int rc;
> +
> +    info->num_vsnd_streams = pcm->num_vsnd_streams;
> +    info->streams = malloc(sizeof(*info->streams) * info->num_vsnd_streams);
> +

No checking for NULL?

In fact you should use libxl__malloc(NOGC,...).


> +    for (i = 0; i < info->num_vsnd_streams; i++)
> +    {
> +        libxl_streaminfo_init(&info->streams[i]);
> +
> +        rc = libxl__xs_read_checked(gc, XBT_NULL,
> +                                    GCSPRINTF("%s/%d/"XENSND_FIELD_RING_REF,
> +                                    path, i), &tmp);
> +        if (rc) goto out;
> +
> +        info->streams[i].req_rref = tmp ? strtoul(tmp, NULL, 10) : -1;
> +
> +        rc = libxl__xs_read_checked(gc, XBT_NULL,
> +                                    GCSPRINTF("%s/%d/"XENSND_FIELD_EVT_CHNL,
> +                                    path, i), &tmp);
> +        if (rc) goto out;
> +
> +        info->streams[i].req_evtch = tmp ? strtoul(tmp, NULL, 10) : -1;
> +    }
> +
> +    rc = 0;
> +
> +out:
> +
> +    return rc;
> +}
> +
> +static int libxl__device_pcm_getinfo(libxl__gc *gc, const char *path,
> +                                     libxl_device_vsnd *vsnd,
> +                                     libxl_vsndinfo *info)
> +{
> +    int i;
> +    int rc;
> +
> +    info->num_vsnd_pcms = vsnd->num_vsnd_pcms;
> +    info->pcms = malloc(sizeof(*info->pcms) * info->num_vsnd_pcms);
> +
> +    for (i = 0; i < info->num_vsnd_pcms; i++)
> +    {
> +        libxl_pcminfo_init(&info->pcms[i]);
> +
> +        rc = libxl__device_stream_getinfo(gc, GCSPRINTF("%s/%d", path, i),
> +                                          &vsnd->pcms[i], &info->pcms[i]);
> +        if (rc) goto out;
> +    }
> +
> +    rc = 0;
> +
> +out:
> +

Too many blank lines here.

In fact you can leave no blank like at all after the out label, here and
other places.

Wei.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-05-22 11:37 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-05-18 14:38 [PATCH v2 0/5] libxl: add PV sound device Oleksandr Grytsov
2018-05-18 14:38 ` [PATCH v2 1/5] " Oleksandr Grytsov
2018-05-18 14:38 ` [PATCH v2 2/5] libxl: add vsnd list and info Oleksandr Grytsov
2018-05-22 11:37   ` Wei Liu
2018-05-18 14:38 ` [PATCH v2 3/5] xl: add PV sound condif parser Oleksandr Grytsov
2018-05-18 14:38 ` [PATCH v2 4/5] xl: add vsnd CLI commands Oleksandr Grytsov
2018-05-18 14:38 ` [PATCH v2 5/5] docs: add PV sound device config Oleksandr Grytsov

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).