[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/5] libxl: add PV sound device
From: Oleksandr Grytsov <oleksandr_grytsov@xxxxxxxx> Add PV sound device described in sndif.h Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@xxxxxxxx> --- 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 | 307 +++++++++++++++++++++++++++++++++++ 7 files changed, 389 insertions(+), 1 deletion(-) create mode 100644 tools/libxl/libxl_vsnd.c diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile index 49b2c63..2d52435 100644 --- a/tools/libxl/Makefile +++ b/tools/libxl/Makefile @@ -138,7 +138,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \ libxl_dom_suspend.o libxl_dom_save.o libxl_usb.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_9pfs.o libxl_domain.o libxl_vdispl.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 7d853ca..7200d49 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -1913,6 +1913,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 0ef54d2..f813114 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -1449,6 +1449,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 8b71517..6b403dc 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -3575,6 +3575,7 @@ extern const struct libxl_device_type libxl__usbdev_devtype; 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__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 756e120..fb3e5e8 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -793,6 +793,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", uint32), + ("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), @@ -807,6 +870,7 @@ libxl_domain_config = Struct("domain_config", [ ("vtpms", Array(libxl_device_vtpm, "num_vtpms")), ("p9s", Array(libxl_device_p9, "num_p9s")), ("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 673a6d5..7898dae 100644 --- a/tools/libxl/libxl_types_internal.idl +++ b/tools/libxl/libxl_types_internal.idl @@ -27,6 +27,7 @@ libxl__device_kind = Enumeration("device_kind", [ (10, "QUSB"), (11, "9PFS"), (12, "VDISPL"), + (13, "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 0000000..26885f9 --- /dev/null +++ b/tools/libxl/libxl_vsnd.c @@ -0,0 +1,307 @@ +/* + * 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) return rc; + + return libxl__backendpath_parse_domid(gc, be_path, &vsnd->backend_domid); +} + +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) { + return len; + } + + 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]); + } + + 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) { + return len; + } + + 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])); + } + + 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) return rc; + } + } + + 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) return rc; + } + } + + if (params->channels_min) { + rc = flexarray_append_pair(front, + GCSPRINTF("%s"XENSND_FIELD_CHANNELS_MIN, path), + GCSPRINTF("%u", params->channels_min)); + if (rc) return rc; + } + + if (params->channels_max) { + rc = flexarray_append_pair(front, + GCSPRINTF("%s"XENSND_FIELD_CHANNELS_MAX, path), + GCSPRINTF("%u", params->channels_max)); + if (rc) return rc; + } + + if (params->buffer_size) { + rc = flexarray_append_pair(front, + GCSPRINTF("%s"XENSND_FIELD_BUFFER_SIZE, path), + GCSPRINTF("%u", params->buffer_size)); + if (rc) return rc; + } + + return 0; +} + +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), + GCSPRINTF("%u", streams[i].id)); + if (rc) return rc; + + 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) return rc; + } + + rc = libxl__set_params_vsnd(gc, GCSPRINTF("%s%d/", path, i), + &streams[i].params, front); + if (rc) return rc; + } + + return 0; +} + +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) return rc; + } + + char *path = GCSPRINTF("%d/", i); + + rc = libxl__set_params_vsnd(gc, path, &pcms[i].params, front); + if (rc) return rc; + + rc = libxl__set_streams_vsnd(gc, path, pcms[i].streams, + pcms[i].num_vsnd_streams, front); + if (rc) return rc; + } + + return 0; +} + +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) return rc; + } + + if (vsnd->short_name) { + rc = flexarray_append_pair(front, XENSND_FIELD_VCARD_SHORT_NAME, + vsnd->short_name); + if (rc) return rc; + } + + rc = libxl__set_params_vsnd(gc, "", &vsnd->params, front); + if (rc) return rc; + + rc = libxl__set_pcms_vsnd(gc, vsnd->pcms, vsnd->num_vsnd_pcms, front); + if (rc) return rc; + + return 0; +} + +LIBXL_DEFINE_DEVICE_ADD(vsnd) +static LIBXL_DEFINE_DEVICES_ADD(vsnd) +LIBXL_DEFINE_DEVICE_REMOVE(vsnd) +static LIBXL_DEFINE_UPDATE_DEVID(vsnd, "vsnd") + +DEFINE_DEVICE_TYPE_STRUCT(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.7.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |