From patchwork Thu Jul 20 12:57:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manos Pitsidianakis X-Patchwork-Id: 13320466 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8036CEB64DA for ; Thu, 20 Jul 2023 12:58:34 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qMTEK-0004zU-4L; Thu, 20 Jul 2023 08:58:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qMTEH-0004zF-Rq for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:01 -0400 Received: from mail-wr1-x42b.google.com ([2a00:1450:4864:20::42b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qMTEE-00047Y-9J for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:00 -0400 Received: by mail-wr1-x42b.google.com with SMTP id ffacd0b85a97d-31438512cafso672378f8f.2 for ; Thu, 20 Jul 2023 05:57:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689857876; x=1690462676; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RgUg0zrDS1rOnZRHzZ1CpNDRNZkYU8arTNOhghXsoRA=; b=fSF3jVgkNEUdtFCntCNS7B+lj7A/xGSsGdRZ/i8a3eBpkixNVY4MQjArXamBmj/v/T Sc2yBoPIPFcm6wZcnoi5raxDOlsLRbfY/xv5b+bVRD6ZrpKfrEa6Kiql0tK97hco+cxN /eQFlXQ696P5cV8MeRBkhHqV1CE0jNlnZdx4mp2PRrBp45avckCzIh+pj4gwoG3pMEfa 5T3nHZBFxUE+gtuhkWCsAGTMHNeXwoR0CGLUl3Nagd/24SJs0e5zsmyU/r/2zSFdwNWN zgMoAfN5Aam4ERnC4OrVOHIqW09OWN2stlpWteTOHaOapoTpG+qy9MncnQ7Gi/50b0g8 1IZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689857876; x=1690462676; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RgUg0zrDS1rOnZRHzZ1CpNDRNZkYU8arTNOhghXsoRA=; b=XGAKGz9+NU8WTge/OixOu+aBmZvbWAFscT5VWdlIRipzI1AY73VuYX0/7yzEdxerkV KRivvnH963/P3kGcUucdYUXwXJgiqjafDuYb3RuehcNZTXAliIUwa1aZFnM8M/ZmtmWX vBHzpaRTZGPdwUfSTDN+p5XcDP+WWulHf174gFzqCNzEps0YnlSZgHRD1WmWgTEiXBvU QTIZcfLwxdN4e6kBPYoRCcM+mdqsAS+CJEwPWrNkAk6uqAlCyBsoDlJO3g9f2gCnnqPL OzAm4RBdJV9w0wwl84FLMd1woxuKq9N6IiALrQ2RI5JKH7oTH2ZQBcAc+H3UEkUq+VZP 6hbw== X-Gm-Message-State: ABy/qLayICZVSadF7HfpF1rVGUaAsJY7IxE7n+rd96B/iHWWPXMrl2nA EfGdbgfkxLzqLIXVSO8KHvz5TMXlhIeTT7+9iH+hjJsh X-Google-Smtp-Source: APBJJlFVp4POylcZzaB5B+2bnh6qv7wEc2TFD93KKI63QSoNJvQbIwZTn4AHb6pXcAOEWN4v2z7T7A== X-Received: by 2002:adf:db46:0:b0:30f:ce4f:5675 with SMTP id f6-20020adfdb46000000b0030fce4f5675mr2269972wrj.59.1689857876584; Thu, 20 Jul 2023 05:57:56 -0700 (PDT) Received: from localhost.localdomain (adsl-41.37.6.162.tellas.gr. [37.6.162.41]) by smtp.gmail.com with ESMTPSA id o2-20020a5d4742000000b003063a92bbf5sm1294816wrs.70.2023.07.20.05.57.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Jul 2023 05:57:56 -0700 (PDT) From: Emmanouil Pitsidianakis To: qemu-devel@nongnu.org Cc: Emmanouil Pitsidianakis , "Igor Skalkin" , "Anton Yakovlev" , "Paolo Bonzini" , "Gerd Hoffmann" , "Michael S. Tsirkin" , "Marcel Apfelbaum" , =?utf-8?q?Daniel_P=2E_Berr?= =?utf-8?q?ang=C3=A9?= , "Eduardo Habkost" , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Volker_R=C3=BCmelin?= , =?utf-8?b?S8WRdsOh?= =?utf-8?b?Z8OzLCBab2x0w6Fu?= , "Alex Bennee" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH v4 01/12] Add virtio-sound device stub Date: Thu, 20 Jul 2023 15:57:02 +0300 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42b; envelope-from=manos.pitsidianakis@linaro.org; helo=mail-wr1-x42b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add a new VIRTIO device for the virtio sound device id. Functionality will be added in the following commits. Signed-off-by: Emmanouil Pitsidianakis --- MAINTAINERS | 6 + hw/virtio/Kconfig | 5 + hw/virtio/meson.build | 1 + hw/virtio/trace-events | 9 ++ hw/virtio/virtio-snd.c | 230 +++++++++++++++++++++++++++++++++ include/hw/virtio/virtio-snd.h | 79 +++++++++++ 6 files changed, 330 insertions(+) create mode 100644 hw/virtio/virtio-snd.c create mode 100644 include/hw/virtio/virtio-snd.h diff --git a/MAINTAINERS b/MAINTAINERS index 12e59b6b27..2bed60f9c1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2245,6 +2245,12 @@ F: hw/virtio/virtio-mem-pci.h F: hw/virtio/virtio-mem-pci.c F: include/hw/virtio/virtio-mem.h +virtio-snd +M: Manos Pitsidianakis +S: Supported +F: hw/virtio/virtio-snd*.c +F: include/hw/virtio/virtio-snd.h + nvme M: Keith Busch M: Klaus Jensen diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig index 92c9cf6c96..d6f20657b3 100644 --- a/hw/virtio/Kconfig +++ b/hw/virtio/Kconfig @@ -17,6 +17,11 @@ config VIRTIO_PCI depends on PCI select VIRTIO +config VIRTIO_SND + bool + default y + depends on VIRTIO + config VIRTIO_MMIO bool select VIRTIO diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build index 13e7c6c272..120d4bfa0a 100644 --- a/hw/virtio/meson.build +++ b/hw/virtio/meson.build @@ -31,6 +31,7 @@ specific_virtio_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: files('vhost-vsock.c specific_virtio_ss.add(when: 'CONFIG_VHOST_USER_VSOCK', if_true: files('vhost-user-vsock.c')) specific_virtio_ss.add(when: 'CONFIG_VIRTIO_RNG', if_true: files('virtio-rng.c')) specific_virtio_ss.add(when: 'CONFIG_VIRTIO_MEM', if_true: files('virtio-mem.c')) +specific_virtio_ss.add(when: 'CONFIG_VIRTIO_SND', if_true: files('virtio-snd.c')) specific_virtio_ss.add(when: 'CONFIG_VHOST_USER_I2C', if_true: files('vhost-user-i2c.c')) specific_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c')) specific_virtio_ss.add(when: 'CONFIG_VHOST_USER_GPIO', if_true: files('vhost-user-gpio.c')) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 7109cf1a3b..3ed7da35f2 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -154,3 +154,12 @@ virtio_pmem_flush_done(int type) "fsync return=%d" virtio_gpio_start(void) "start" virtio_gpio_stop(void) "stop" virtio_gpio_set_status(uint8_t status) "0x%x" + +#virtio-snd.c +virtio_snd_get_config(void *vdev, uint32_t jacks, uint32_t streams, uint32_t chmaps) "snd %p: get_config jacks=%"PRIu32" streams=%"PRIu32" chmaps=%"PRIu32"" +virtio_snd_set_config(void *vdev, uint32_t jacks, uint32_t new_jacks, uint32_t streams, uint32_t new_streams, uint32_t chmaps, uint32_t new_chmaps) "snd %p: set_config jacks from %"PRIu32"->%"PRIu32", streams from %"PRIu32"->%"PRIu32", chmaps from %"PRIu32"->%"PRIu32 +virtio_snd_get_features(void *vdev, uint64_t features) "snd %p: get_features 0x%"PRIx64 +virtio_snd_vm_state_running(void) "vm state running" +virtio_snd_vm_state_stopped(void) "vm state stopped" +virtio_snd_realize(void *snd) "snd %p: realize" +virtio_snd_unrealize(void *snd) "snd %p: unrealize" diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c new file mode 100644 index 0000000000..e3f2156e5e --- /dev/null +++ b/hw/virtio/virtio-snd.c @@ -0,0 +1,230 @@ +/* + * VIRTIO Sound Device conforming to + * + * "Virtual I/O Device (VIRTIO) Version 1.2 + * Committee Specification Draft 01 + * 09 May 2022" + * + * + * + * Copyright (c) 2023 Emmanouil Pitsidianakis + * Copyright (C) 2019 OpenSynergy GmbH + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * (at your option) any later version. See the COPYING file in the + * top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/iov.h" +#include "qemu/log.h" +#include "include/qemu/lockable.h" +#include "sysemu/runstate.h" +#include "trace.h" +#include "qapi/error.h" +#include "hw/virtio/virtio-snd.h" + +#define VIRTIO_SOUND_VM_VERSION 1 +#define VIRTIO_SOUND_JACK_DEFAULT 0 +#define VIRTIO_SOUND_STREAM_DEFAULT 1 +#define VIRTIO_SOUND_CHMAP_DEFAULT 0 +#define VIRTIO_SOUND_HDA_FN_NID 0 + +static const VMStateDescription vmstate_virtio_snd_device = { + .name = TYPE_VIRTIO_SND, + .version_id = VIRTIO_SOUND_VM_VERSION, + .minimum_version_id = VIRTIO_SOUND_VM_VERSION, +}; + +static const VMStateDescription vmstate_virtio_snd = { + .name = "virtio-sound", + .minimum_version_id = VIRTIO_SOUND_VM_VERSION, + .version_id = VIRTIO_SOUND_VM_VERSION, + .fields = (VMStateField[]) { + VMSTATE_VIRTIO_DEVICE, + VMSTATE_END_OF_LIST() + }, +}; + +static Property virtio_snd_properties[] = { + DEFINE_AUDIO_PROPERTIES(VirtIOSound, card), + DEFINE_PROP_UINT32("jacks", VirtIOSound, snd_conf.jacks, + VIRTIO_SOUND_JACK_DEFAULT), + DEFINE_PROP_UINT32("streams", VirtIOSound, snd_conf.streams, + VIRTIO_SOUND_STREAM_DEFAULT), + DEFINE_PROP_UINT32("chmaps", VirtIOSound, snd_conf.chmaps, + VIRTIO_SOUND_CHMAP_DEFAULT), + DEFINE_PROP_END_OF_LIST(), +}; + +static void +virtio_snd_get_config(VirtIODevice *vdev, uint8_t *config) +{ + VirtIOSound *s = VIRTIO_SND(vdev); + trace_virtio_snd_get_config(vdev, + s->snd_conf.jacks, + s->snd_conf.streams, + s->snd_conf.chmaps); + + memcpy(config, &s->snd_conf, sizeof(s->snd_conf)); +} + +static void +virtio_snd_set_config(VirtIODevice *vdev, const uint8_t *config) +{ + VirtIOSound *s = VIRTIO_SND(vdev); + const virtio_snd_config *sndconfig = + (const virtio_snd_config *)config; + + + trace_virtio_snd_set_config(vdev, + s->snd_conf.jacks, + sndconfig->jacks, + s->snd_conf.streams, + sndconfig->streams, + s->snd_conf.chmaps, + sndconfig->chmaps); + + memcpy(&s->snd_conf, sndconfig, sizeof(s->snd_conf)); +} + +/* + * Queue handler stub. + * + * @vdev: VirtIOSound device + * @vq: virtqueue + */ +static void virtio_snd_handle_queue(VirtIODevice *vdev, VirtQueue *vq) {} + +static uint64_t get_features(VirtIODevice *vdev, uint64_t features, + Error **errp) +{ + /* + * virtio-v1.2-csd01, 5.14.3, + * Feature Bits + * None currently defined. + */ + trace_virtio_snd_get_features(vdev, features); + return features | 1UL << VIRTIO_F_VERSION_1 | 1UL << VIRTIO_F_IN_ORDER; +} + +static void virtio_snd_common_realize(DeviceState *dev, + VirtIOHandleOutput ctrl, + VirtIOHandleOutput evt, + VirtIOHandleOutput txq, + VirtIOHandleOutput rxq, + Error **errp) +{ + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOSound *vsnd = VIRTIO_SND(dev); + + virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config)); + + /* set number of jacks and streams */ + if (vsnd->snd_conf.jacks > 8) { + error_setg(errp, + "Invalid number of jacks: %"PRIu32, + vsnd->snd_conf.jacks); + return; + } + if (vsnd->snd_conf.streams < 1 || vsnd->snd_conf.streams > 10) { + error_setg(errp, + "Invalid number of streams: %"PRIu32, + vsnd->snd_conf.streams); + return; + } + + if (vsnd->snd_conf.chmaps > VIRTIO_SND_CHMAP_MAX_SIZE) { + error_setg(errp, + "Invalid number of channel maps: %"PRIu32, + vsnd->snd_conf.chmaps); + return; + } + + AUD_register_card("virtio-sound", &vsnd->card); + + vsnd->queues[VIRTIO_SND_VQ_CONTROL] = virtio_add_queue(vdev, 64, ctrl); + vsnd->queues[VIRTIO_SND_VQ_EVENT] = virtio_add_queue(vdev, 64, evt); + vsnd->queues[VIRTIO_SND_VQ_TX] = virtio_add_queue(vdev, 64, txq); + vsnd->queues[VIRTIO_SND_VQ_RX] = virtio_add_queue(vdev, 64, rxq); +} + +static void +virtio_snd_vm_state_change(void *, bool running, RunState) +{ + if (running) { + trace_virtio_snd_vm_state_running(); + } else { + trace_virtio_snd_vm_state_stopped(); + } +} + +static void virtio_snd_realize(DeviceState *dev, Error **errp) +{ + VirtIOSound *vsnd = VIRTIO_SND(dev); + Error *err = NULL; + + vsnd->vmstate = + qemu_add_vm_change_state_handler(virtio_snd_vm_state_change, vsnd); + + trace_virtio_snd_realize(vsnd); + + virtio_snd_common_realize(dev, + virtio_snd_handle_queue, + virtio_snd_handle_queue, + virtio_snd_handle_queue, + virtio_snd_handle_queue, + &err); + if (err != NULL) { + error_propagate(errp, err); + return; + } +} + +static void virtio_snd_unrealize(DeviceState *dev) +{ + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOSound *vsnd = VIRTIO_SND(dev); + + qemu_del_vm_change_state_handler(vsnd->vmstate); + virtio_del_queue(vdev, 0); + + trace_virtio_snd_unrealize(vsnd); + + AUD_remove_card(&vsnd->card); + virtio_cleanup(vdev); +} + + +static void virtio_snd_reset(VirtIODevice *vdev) {} + +static void virtio_snd_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); + + + set_bit(DEVICE_CATEGORY_SOUND, dc->categories); + device_class_set_props(dc, virtio_snd_properties); + + dc->vmsd = &vmstate_virtio_snd; + vdc->vmsd = &vmstate_virtio_snd_device; + vdc->realize = virtio_snd_realize; + vdc->unrealize = virtio_snd_unrealize; + vdc->get_config = virtio_snd_get_config; + vdc->set_config = virtio_snd_set_config; + vdc->get_features = get_features; + vdc->reset = virtio_snd_reset; + vdc->legacy_features = 0; +} + +static const TypeInfo virtio_snd_types[] = { + { + .name = TYPE_VIRTIO_SND, + .parent = TYPE_VIRTIO_DEVICE, + .instance_size = sizeof(VirtIOSound), + .class_init = virtio_snd_class_init, + } +}; + +DEFINE_TYPES(virtio_snd_types) diff --git a/include/hw/virtio/virtio-snd.h b/include/hw/virtio/virtio-snd.h new file mode 100644 index 0000000000..074b66c018 --- /dev/null +++ b/include/hw/virtio/virtio-snd.h @@ -0,0 +1,79 @@ +/* + * VIRTIO Sound Device conforming to + * + * "Virtual I/O Device (VIRTIO) Version 1.2 + * Committee Specification Draft 01 + * 09 May 2022" + * + * Copyright (c) 2023 Emmanouil Pitsidianakis + * Copyright (C) 2019 OpenSynergy GmbH + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * (at your option) any later version. See the COPYING file in the + * top-level directory. + */ + +#ifndef QEMU_VIRTIO_SOUND_H +#define QEMU_VIRTIO_SOUND_H + +#include "hw/virtio/virtio.h" +#include "audio/audio.h" +#include "standard-headers/linux/virtio_ids.h" +#include "standard-headers/linux/virtio_snd.h" + +#define TYPE_VIRTIO_SND "virtio-sound-device" +#define VIRTIO_SND(obj) \ + OBJECT_CHECK(VirtIOSound, (obj), TYPE_VIRTIO_SND) + +/* CONFIGURATION SPACE */ + +typedef struct virtio_snd_config virtio_snd_config; + +/* COMMON DEFINITIONS */ + +/* common header for request/response*/ +typedef struct virtio_snd_hdr virtio_snd_hdr; + +/* event notification */ +typedef struct virtio_snd_event virtio_snd_event; + +/* common control request to query an item information */ +typedef struct virtio_snd_query_info virtio_snd_query_info; + +/* JACK CONTROL MESSAGES */ + +typedef struct virtio_snd_jack_hdr virtio_snd_jack_hdr; + +/* jack information structure */ +typedef struct virtio_snd_jack_info virtio_snd_jack_info; + +/* jack remapping control request */ +typedef struct virtio_snd_jack_remap virtio_snd_jack_remap; + +typedef struct virtio_snd_jack virtio_snd_jack; + +/* + * PCM CONTROL MESSAGES + */ +typedef struct virtio_snd_pcm_hdr virtio_snd_pcm_hdr; + +/* PCM stream info structure */ +typedef struct virtio_snd_pcm_info virtio_snd_pcm_info; + +/* set PCM stream params */ +typedef struct virtio_snd_pcm_set_params virtio_snd_pcm_set_params; + +/* I/O request header */ +typedef struct virtio_snd_pcm_xfer virtio_snd_pcm_xfer; + +/* I/O request status */ +typedef struct virtio_snd_pcm_status virtio_snd_pcm_status; + +typedef struct VirtIOSound { + VirtIODevice parent_obj; + VirtQueue *queues[VIRTIO_SND_VQ_MAX]; + QEMUSoundCard card; + VMChangeStateEntry *vmstate; + virtio_snd_config snd_conf; +} VirtIOSound; +#endif From patchwork Thu Jul 20 12:57:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manos Pitsidianakis X-Patchwork-Id: 13320476 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 79818EB64DC for ; Thu, 20 Jul 2023 12:59:39 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qMTEW-0005CN-PV; Thu, 20 Jul 2023 08:58:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qMTER-000564-B1 for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:12 -0400 Received: from mail-wr1-x434.google.com ([2a00:1450:4864:20::434]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qMTEP-0004Fa-3f for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:10 -0400 Received: by mail-wr1-x434.google.com with SMTP id ffacd0b85a97d-3163eb69487so1259514f8f.1 for ; Thu, 20 Jul 2023 05:58:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689857885; x=1690462685; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TK1fciw7LUKtOLqmUperb6ROHdP0V6/TZkVSUmHfwKY=; b=UcX9JmOWu8UnEI27Dj+ozy7pWAtLUnWd6C7yEpYx+ZZxuQ7jboo2iuS+Fy8fQJxOSa 0tL1D8Fzms9naZ0Iiqf4W88aVMiKI7Gs1AJR5YiXMytS3Mq02OG04gxl1VTy+Ae+t0gy 9FuwJYxpb51KUT8WjP3+VoPfUr6XjREP/XIE+WpEACpKNFHAbnbXVd+OoRGFGHITI1J9 V00CzEG40BxStrteqsXoGEYYhPQTJ4ngiWKOnShqhko/2iN7nNElRv2lM56HksStm56v omfZ+e9xlzwlwCY3T5IV3mE5065i2aPbebaKbd5z4VVz+J4kR7lgM1MDE1IwOrWCDkBn 32vQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689857885; x=1690462685; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TK1fciw7LUKtOLqmUperb6ROHdP0V6/TZkVSUmHfwKY=; b=Jee+jfM/BpVk4stYao5ffhdSBhY7hVsuwfojEwF+qWAhWvwlRB0kULd2faCI6RRPGt EIUFgUZ4T3PXaHVjbgGxgAsQo2AVbZQjLVWATNzJIefJ/PgooglM3DMXVQTFxDlsTF0Z xfFxFhGSRdhoWg3oKER+L0+wNSbew1ZHX/OzVq+0xMKQIxA/KJJivsXn+avsRSL8XMbo buP3AU79olWxngUrUOhYAVMR3gXggPsKRuDvNidqTQdm2oYUcOZpTEGgo7Wj0JFMHLad aR2bZyAQs96/nbyXaGr2ZiDKvJMI9yXI8k+YKTmPTEiCyAyz+n709Ozbs5KSYCImbyyT KHMA== X-Gm-Message-State: ABy/qLbsleLBiiIMUKFrjCH3ShRh4XULnFosOuWz1Ti+Sf0qhnUKRV8C j0CTO0KzHzdVK6pZqCMXi6zzJ8010VXxdFgA/czdjDdo X-Google-Smtp-Source: APBJJlFwC6fxJuLYvtfDn6W9UCMHI33zUoO37RgQGBlgaoXBXSlzPdumWCCJnDH01h9K5d9nUX09rw== X-Received: by 2002:a5d:54c9:0:b0:313:f38d:555f with SMTP id x9-20020a5d54c9000000b00313f38d555fmr2229487wrv.24.1689857885584; Thu, 20 Jul 2023 05:58:05 -0700 (PDT) Received: from localhost.localdomain (adsl-41.37.6.162.tellas.gr. [37.6.162.41]) by smtp.gmail.com with ESMTPSA id o2-20020a5d4742000000b003063a92bbf5sm1294816wrs.70.2023.07.20.05.58.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Jul 2023 05:58:05 -0700 (PDT) From: Emmanouil Pitsidianakis To: qemu-devel@nongnu.org Cc: Emmanouil Pitsidianakis , "Igor Skalkin" , "Anton Yakovlev" , "Paolo Bonzini" , "Gerd Hoffmann" , "Michael S. Tsirkin" , "Marcel Apfelbaum" , =?utf-8?q?Daniel_P=2E_Berr?= =?utf-8?q?ang=C3=A9?= , "Eduardo Habkost" , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Volker_R=C3=BCmelin?= , =?utf-8?b?S8WRdsOh?= =?utf-8?b?Z8OzLCBab2x0w6Fu?= , "Alex Bennee" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH v4 02/12] Add virtio-sound-pci device Date: Thu, 20 Jul 2023 15:57:03 +0300 Message-Id: <5cde5472ea0aab0894022d24b86cf1815a4880ed.1689857559.git.manos.pitsidianakis@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::434; envelope-from=manos.pitsidianakis@linaro.org; helo=mail-wr1-x434.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This patch adds a PCI wrapper device for the virtio-sound device. It is necessary to instantiate a virtio-snd device in a guest. All sound logic will be added to the virtio-snd device in the following commits. To add this device with a guest, you'll need a >=5.13 kernel compiled with CONFIG_SND_VIRTIO=y, which at the time of writing most distros have off by default. Use with following flags in the invocation: -device virtio-sound-pci,disable-legacy=on And an audio backend listed with `-audio driver=help` that works on your host machine, e.g.: Pulseaudio: -audio driver=pa,model=virtio-sound or -audio driver=pa,model=virtio-sound,server=/run/user/1000/pulse/native sdl: -audio driver=sdl,model=virtio-sound coreaudio (macos/darwin): -audio driver=coreaudio,model=virtio-sound etc. Signed-off-by: Emmanouil Pitsidianakis --- hw/virtio/meson.build | 1 + hw/virtio/virtio-snd-pci.c | 91 ++++++++++++++++++++++++++++++++++++++ include/hw/pci/pci.h | 1 + softmmu/qdev-monitor.c | 1 + 4 files changed, 94 insertions(+) create mode 100644 hw/virtio/virtio-snd-pci.c diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build index 120d4bfa0a..5e5a83a4ee 100644 --- a/hw/virtio/meson.build +++ b/hw/virtio/meson.build @@ -63,6 +63,7 @@ virtio_pci_ss.add(when: 'CONFIG_VIRTIO_SERIAL', if_true: files('virtio-serial-pc virtio_pci_ss.add(when: 'CONFIG_VIRTIO_PMEM', if_true: files('virtio-pmem-pci.c')) virtio_pci_ss.add(when: 'CONFIG_VIRTIO_IOMMU', if_true: files('virtio-iommu-pci.c')) virtio_pci_ss.add(when: 'CONFIG_VIRTIO_MEM', if_true: files('virtio-mem-pci.c')) +virtio_pci_ss.add(when: 'CONFIG_VIRTIO_SND', if_true: files('virtio-snd-pci.c')) virtio_pci_ss.add(when: 'CONFIG_VHOST_VDPA_DEV', if_true: files('vdpa-dev-pci.c')) virtio_pci_ss.add(when: 'CONFIG_VIRTIO_MD', if_true: files('virtio-md-pci.c')) diff --git a/hw/virtio/virtio-snd-pci.c b/hw/virtio/virtio-snd-pci.c new file mode 100644 index 0000000000..53070b85f6 --- /dev/null +++ b/hw/virtio/virtio-snd-pci.c @@ -0,0 +1,91 @@ +/* + * VIRTIO Sound Device PCI Bindings + * + * Copyright (c) 2023 Emmanouil Pitsidianakis + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * (at your option) any later version. See the COPYING file in the + * top-level directory. + */ + +#include "qemu/osdep.h" +#include "hw/audio/soundhw.h" +#include "hw/virtio/virtio-pci.h" +#include "hw/virtio/virtio-snd.h" + +typedef struct VirtIOSoundPCI VirtIOSoundPCI; + +/* + * virtio-snd-pci: This extends VirtioPCIProxy. + */ +#define TYPE_VIRTIO_SND_PCI "virtio-sound-pci-base" +DECLARE_INSTANCE_CHECKER(VirtIOSoundPCI, VIRTIO_SOUND_PCI, + TYPE_VIRTIO_SND_PCI) + +struct VirtIOSoundPCI { + VirtIOPCIProxy parent; + VirtIOSound vdev; +}; + +static Property virtio_snd_pci_properties[] = { + DEFINE_PROP_END_OF_LIST(), +}; + +static const char *audiodev_id; + +static int virtio_snd_init_pci(PCIBus *init_bus, const char *audiodev) +{ + audiodev_id = audiodev; + return 0; +} + +static void virtio_snd_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) +{ + VirtIOSoundPCI *dev = VIRTIO_SOUND_PCI(vpci_dev); + DeviceState *vdev = DEVICE(&dev->vdev); + + qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus), errp); + qdev_prop_set_string(vdev, "audiodev", audiodev_id); + object_property_set_bool(OBJECT(vdev), "realized", true, errp); +} + +static void virtio_snd_pci_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VirtioPCIClass *vpciklass = VIRTIO_PCI_CLASS(klass); + PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass); + + vpciklass->realize = virtio_snd_pci_realize; + set_bit(DEVICE_CATEGORY_SOUND, dc->categories); + + pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; + pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_SND; + pcidev_k->revision = VIRTIO_PCI_ABI_VERSION; + pcidev_k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO; + device_class_set_props(dc, virtio_snd_pci_properties); +} + +static void virtio_snd_pci_instance_init(Object *obj) +{ + VirtIOSoundPCI *dev = VIRTIO_SOUND_PCI(obj); + + virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), + TYPE_VIRTIO_SND); +} + +static const VirtioPCIDeviceTypeInfo virtio_snd_pci_info = { + .base_name = TYPE_VIRTIO_SND_PCI, + .generic_name = "virtio-sound-pci", + .instance_size = sizeof(VirtIOSoundPCI), + .instance_init = virtio_snd_pci_instance_init, + .class_init = virtio_snd_pci_class_init, +}; + +static void virtio_snd_pci_register(void) +{ + virtio_pci_types_register(&virtio_snd_pci_info); + pci_register_soundhw("virtio-sound", "Virtio Sound Device", + virtio_snd_init_pci); +} + +type_init(virtio_snd_pci_register); diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index abdc1ef103..3cd5712035 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -85,6 +85,7 @@ extern bool pci_available; #define PCI_DEVICE_ID_VIRTIO_RNG 0x1005 #define PCI_DEVICE_ID_VIRTIO_9P 0x1009 #define PCI_DEVICE_ID_VIRTIO_VSOCK 0x1012 +#define PCI_DEVICE_ID_VIRTIO_SND 0x1019 /* * modern virtio-pci devices get their id assigned automatically, diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c index 74f4e41338..2e9835ad88 100644 --- a/softmmu/qdev-monitor.c +++ b/softmmu/qdev-monitor.c @@ -108,6 +108,7 @@ static const QDevAlias qdev_alias_table[] = { { "virtio-serial-device", "virtio-serial", QEMU_ARCH_VIRTIO_MMIO }, { "virtio-serial-ccw", "virtio-serial", QEMU_ARCH_VIRTIO_CCW }, { "virtio-serial-pci", "virtio-serial", QEMU_ARCH_VIRTIO_PCI}, + { "virtio-sound-pci", "virtio-sound", QEMU_ARCH_VIRTIO_PCI}, { "virtio-tablet-device", "virtio-tablet", QEMU_ARCH_VIRTIO_MMIO }, { "virtio-tablet-ccw", "virtio-tablet", QEMU_ARCH_VIRTIO_CCW }, { "virtio-tablet-pci", "virtio-tablet", QEMU_ARCH_VIRTIO_PCI }, From patchwork Thu Jul 20 12:57:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manos Pitsidianakis X-Patchwork-Id: 13320477 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DCB01EB64DA for ; Thu, 20 Jul 2023 12:59:41 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qMTEc-0005LE-1Q; Thu, 20 Jul 2023 08:58:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qMTET-000582-AW for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:14 -0400 Received: from mail-wr1-x42f.google.com ([2a00:1450:4864:20::42f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qMTER-0004GI-5E for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:13 -0400 Received: by mail-wr1-x42f.google.com with SMTP id ffacd0b85a97d-3143ccb0f75so674499f8f.0 for ; Thu, 20 Jul 2023 05:58:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689857889; x=1690462689; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wRq79tbTfRZSTrDdggOXNYK1qEYuy2BAv3Lz1PCks3g=; b=GvfSFVmIzceTx5RT4njgZ0ODKXhTkPBxlssJBe4oeraFpGB09v322bEfKxF+laXrpQ MCyJMYKnlUvhlZB71pCZzgLR3jmJA5AeC2w03P/6R0FLUigMtY3707Mnj1y0YCaoXGHz 04hwgjMLFDsgNbIB9Fija5wyecUW4z3zbeHLmxs5gMJ8IGOBFANjsP7va6b3JZv3bx/x I5CgMRjxxgK1C857/1y1dyOQIK+egnFoWPE7/QkJQ2nRSMmqAAEblZ62OsiCoeBictfj KfF3JEAlM7/PB29wn4MnVmxpEzkwC66jsX6t+D7tiZs8Ov2H6/Z/jJJhpSqwV8ckY5vS dv0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689857889; x=1690462689; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wRq79tbTfRZSTrDdggOXNYK1qEYuy2BAv3Lz1PCks3g=; b=TMZfgsZdNxdIuUAH7Uk5brXu+Apw0yShid7oOYy1uaG8ZFQvEiaBedOMDDHRb/2mve UiMVAwPKYZ1AHHTV3CYup1HVKDqhn72c+lzMquDdcnxWrKQTSr1M4SJmn+1Lhb1iarEX SN2fqRXwAZ4g5fdx/SVz/rE0HfTmH2mneG5++VDjDNsts95G8LCJYrd6qXJhbuZ2M/mO DofIvSPc4j6PrdBOx1vyOqS1syb1ZIHHtwapCxaDQspkMuZF8bKwMYtblUqRo5SUnbI0 eCqmsWWVFqT6AdLLfPL453AzQXapRUVVNx5KntJOvfQlm1ZzJSyw2FlHs8WMgTKa0zNc GBeA== X-Gm-Message-State: ABy/qLaqBoyaA3tprtf7gU5Wx7YMOmgYb7WFeTRkCDyPjVG+mSGLzbSP 164JuOjoKxYfXbeTk0iXZIRmR1M4HbhyqQDXVjoV7b7g X-Google-Smtp-Source: APBJJlEpKuUHyO0m4RaMJRVB+saw9IVCFn87IyuvA9BDhrVIDRXLBuLVfzxcXCnIxQxpgsfUCw0dtw== X-Received: by 2002:a5d:62cf:0:b0:311:19a2:e7f8 with SMTP id o15-20020a5d62cf000000b0031119a2e7f8mr2359867wrv.1.1689857889404; Thu, 20 Jul 2023 05:58:09 -0700 (PDT) Received: from localhost.localdomain (adsl-41.37.6.162.tellas.gr. [37.6.162.41]) by smtp.gmail.com with ESMTPSA id o2-20020a5d4742000000b003063a92bbf5sm1294816wrs.70.2023.07.20.05.58.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Jul 2023 05:58:08 -0700 (PDT) From: Emmanouil Pitsidianakis To: qemu-devel@nongnu.org Cc: Emmanouil Pitsidianakis , "Igor Skalkin" , "Anton Yakovlev" , "Paolo Bonzini" , "Gerd Hoffmann" , "Michael S. Tsirkin" , "Marcel Apfelbaum" , =?utf-8?q?Daniel_P=2E_Berr?= =?utf-8?q?ang=C3=A9?= , "Eduardo Habkost" , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Volker_R=C3=BCmelin?= , =?utf-8?b?S8WRdsOh?= =?utf-8?b?Z8OzLCBab2x0w6Fu?= , "Alex Bennee" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH v4 03/12] virtio-sound: handle control messages and streams Date: Thu, 20 Jul 2023 15:57:04 +0300 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42f; envelope-from=manos.pitsidianakis@linaro.org; helo=mail-wr1-x42f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Receive guest requests in the control (CTRL) queue of the virtio sound device and reply with a NOT SUPPORTED error to all control commands. The receiving handler is virtio_snd_handle_ctrl(). It stores all control messages in the queue in the device's command queue. Then it calls virtio_snd_process_cmdq() to handle each message. The handler is process_cmd() which replies with VIRTIO_SND_S_NOT_SUPP. Signed-off-by: Emmanouil Pitsidianakis --- hw/virtio/trace-events | 4 + hw/virtio/virtio-snd.c | 222 +++++++++++++++++++++++++++++++-- include/hw/virtio/virtio-snd.h | 71 ++++++++++- 3 files changed, 287 insertions(+), 10 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 3ed7da35f2..8a223e36e9 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -163,3 +163,7 @@ virtio_snd_vm_state_running(void) "vm state running" virtio_snd_vm_state_stopped(void) "vm state stopped" virtio_snd_realize(void *snd) "snd %p: realize" virtio_snd_unrealize(void *snd) "snd %p: unrealize" +virtio_snd_handle_ctrl(void *vdev, void *vq) "snd %p: handle ctrl event for queue %p" +virtio_snd_handle_code(uint32_t val, const char *code) "ctrl code msg val = %"PRIu32" == %s" +virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called" +virtio_snd_handle_event(void) "event queue callback called" diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c index e3f2156e5e..5a0c2c7594 100644 --- a/hw/virtio/virtio-snd.c +++ b/hw/virtio/virtio-snd.c @@ -30,6 +30,29 @@ #define VIRTIO_SOUND_CHMAP_DEFAULT 0 #define VIRTIO_SOUND_HDA_FN_NID 0 +static const char *print_code(uint32_t code) +{ + #define CASE(CODE) \ + case VIRTIO_SND_R_##CODE: \ + return "VIRTIO_SND_R_"#CODE + + switch (code) { + CASE(JACK_INFO); + CASE(JACK_REMAP); + CASE(PCM_INFO); + CASE(PCM_SET_PARAMS); + CASE(PCM_PREPARE); + CASE(PCM_RELEASE); + CASE(PCM_START); + CASE(PCM_STOP); + CASE(CHMAP_INFO); + default: + return "invalid code"; + } + + #undef CASE +}; + static const VMStateDescription vmstate_virtio_snd_device = { .name = TYPE_VIRTIO_SND, .version_id = VIRTIO_SOUND_VM_VERSION, @@ -89,12 +112,148 @@ virtio_snd_set_config(VirtIODevice *vdev, const uint8_t *config) } /* - * Queue handler stub. + * The actual processing done in virtio_snd_process_cmdq(). + * + * @s: VirtIOSound device + * @cmd: control command request + */ +static inline void +process_cmd(VirtIOSound *s, virtio_snd_ctrl_command *cmd) +{ + size_t sz = iov_to_buf(cmd->elem->out_sg, + cmd->elem->out_num, + 0, + &cmd->ctrl, + sizeof(cmd->ctrl)); + if (sz != sizeof(cmd->ctrl)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: virtio-snd command size incorrect %zu vs \ + %zu\n", __func__, sz, sizeof(cmd->ctrl)); + return; + } + + trace_virtio_snd_handle_code(cmd->ctrl.code, + print_code(cmd->ctrl.code)); + + switch (cmd->ctrl.code) { + case VIRTIO_SND_R_JACK_INFO: + case VIRTIO_SND_R_JACK_REMAP: + qemu_log_mask(LOG_UNIMP, + "virtio_snd: jack functionality is unimplemented."); + cmd->resp.code = VIRTIO_SND_S_NOT_SUPP; + break; + case VIRTIO_SND_R_PCM_INFO: + case VIRTIO_SND_R_PCM_SET_PARAMS: + case VIRTIO_SND_R_PCM_PREPARE: + case VIRTIO_SND_R_PCM_START: + case VIRTIO_SND_R_PCM_STOP: + case VIRTIO_SND_R_PCM_RELEASE: + cmd->resp.code = VIRTIO_SND_S_NOT_SUPP; + break; + case VIRTIO_SND_R_CHMAP_INFO: + qemu_log_mask(LOG_UNIMP, + "virtio_snd: chmap info functionality is unimplemented."); + trace_virtio_snd_handle_chmap_info(); + cmd->resp.code = VIRTIO_SND_S_NOT_SUPP; + break; + default: + /* error */ + error_report("virtio snd header not recognized: %"PRIu32, + cmd->ctrl.code); + cmd->resp.code = VIRTIO_SND_S_BAD_MSG; + } + + iov_from_buf(cmd->elem->in_sg, + cmd->elem->in_num, + 0, + &cmd->resp, + sizeof(cmd->resp)); + virtqueue_push(cmd->vq, cmd->elem, sizeof(cmd->elem)); + virtio_notify(VIRTIO_DEVICE(s), cmd->vq); +} + +/* + * Consume all elements in command queue. + * + * @s: VirtIOSound device + */ +static void virtio_snd_process_cmdq(VirtIOSound *s) +{ + virtio_snd_ctrl_command *cmd; + + if (unlikely(qatomic_read(&s->processing_cmdq))) { + return; + } + + WITH_QEMU_LOCK_GUARD(&s->cmdq_mutex) { + qatomic_set(&s->processing_cmdq, true); + while (!QTAILQ_EMPTY(&s->cmdq)) { + cmd = QTAILQ_FIRST(&s->cmdq); + + /* process command */ + process_cmd(s, cmd); + + QTAILQ_REMOVE(&s->cmdq, cmd, next); + + g_free(cmd); + } + qatomic_set(&s->processing_cmdq, false); + } +} + +/* + * The control message handler. Pops an element from the control virtqueue, + * and stores them to VirtIOSound's cmdq queue and finally calls + * virtio_snd_process_cmdq() for processing. + * + * @vdev: VirtIOSound device + * @vq: Control virtqueue + */ +static void virtio_snd_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) +{ + VirtIOSound *s = VIRTIO_SND(vdev); + VirtQueueElement *elem; + virtio_snd_ctrl_command *cmd; + + trace_virtio_snd_handle_ctrl(vdev, vq); + + if (!virtio_queue_ready(vq)) { + return; + } + + elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); + while (elem) { + cmd = g_new0(virtio_snd_ctrl_command, 1); + cmd->elem = elem; + cmd->vq = vq; + cmd->resp.code = VIRTIO_SND_S_OK; + QTAILQ_INSERT_TAIL(&s->cmdq, cmd, next); + elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); + } + + virtio_snd_process_cmdq(s); +} + +/* + * The event virtqueue handler. + * Not implemented yet. + * + * @vdev: VirtIOSound device + * @vq: event vq + */ +static void virtio_snd_handle_event(VirtIODevice *vdev, VirtQueue *vq) +{ + qemu_log_mask(LOG_UNIMP, "virtio_snd: event queue is unimplemented."); + trace_virtio_snd_handle_event(); +} + +/* + * Stub buffer virtqueue handler. * * @vdev: VirtIOSound device * @vq: virtqueue */ -static void virtio_snd_handle_queue(VirtIODevice *vdev, VirtQueue *vq) {} +static void virtio_snd_handle_xfer(VirtIODevice *vdev, VirtQueue *vq) {} static uint64_t get_features(VirtIODevice *vdev, uint64_t features, Error **errp) @@ -108,6 +267,20 @@ static uint64_t get_features(VirtIODevice *vdev, uint64_t features, return features | 1UL << VIRTIO_F_VERSION_1 | 1UL << VIRTIO_F_IN_ORDER; } +static void virtio_snd_set_pcm(VirtIOSound *snd) +{ + VirtIOSoundPCM *pcm; + + pcm = g_new0(VirtIOSoundPCM, 1); + pcm->snd = snd; + + pcm->streams = g_new0(VirtIOSoundPCMStream *, snd->snd_conf.streams); + pcm->pcm_params = g_new0(VirtIOSoundPCMParams *, snd->snd_conf.streams); + pcm->jacks = g_new0(virtio_snd_jack *, snd->snd_conf.jacks); + + snd->pcm = pcm; +} + static void virtio_snd_common_realize(DeviceState *dev, VirtIOHandleOutput ctrl, VirtIOHandleOutput evt, @@ -118,6 +291,8 @@ static void virtio_snd_common_realize(DeviceState *dev, VirtIODevice *vdev = VIRTIO_DEVICE(dev); VirtIOSound *vsnd = VIRTIO_SND(dev); + virtio_snd_set_pcm(vsnd); + virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config)); /* set number of jacks and streams */ @@ -147,6 +322,8 @@ static void virtio_snd_common_realize(DeviceState *dev, vsnd->queues[VIRTIO_SND_VQ_EVENT] = virtio_add_queue(vdev, 64, evt); vsnd->queues[VIRTIO_SND_VQ_TX] = virtio_add_queue(vdev, 64, txq); vsnd->queues[VIRTIO_SND_VQ_RX] = virtio_add_queue(vdev, 64, rxq); + qemu_mutex_init(&vsnd->cmdq_mutex); + QTAILQ_INIT(&vsnd->cmdq); } static void @@ -164,39 +341,68 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp) VirtIOSound *vsnd = VIRTIO_SND(dev); Error *err = NULL; + vsnd->pcm = NULL; vsnd->vmstate = qemu_add_vm_change_state_handler(virtio_snd_vm_state_change, vsnd); trace_virtio_snd_realize(vsnd); virtio_snd_common_realize(dev, - virtio_snd_handle_queue, - virtio_snd_handle_queue, - virtio_snd_handle_queue, - virtio_snd_handle_queue, + virtio_snd_handle_ctrl, + virtio_snd_handle_event, + virtio_snd_handle_xfer, + virtio_snd_handle_xfer, &err); if (err != NULL) { error_propagate(errp, err); - return; } } +/* + * Close the sound card. + * + * @stream: VirtIOSoundPCMStream *stream + */ +static void virtio_snd_pcm_close(VirtIOSoundPCMStream *stream) +{ + virtio_snd_process_cmdq(stream->s); +} + static void virtio_snd_unrealize(DeviceState *dev) { VirtIODevice *vdev = VIRTIO_DEVICE(dev); VirtIOSound *vsnd = VIRTIO_SND(dev); + VirtIOSoundPCMStream *stream; qemu_del_vm_change_state_handler(vsnd->vmstate); virtio_del_queue(vdev, 0); trace_virtio_snd_unrealize(vsnd); + for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) { + stream = vsnd->pcm->streams[i]; + virtio_snd_pcm_close(stream); + g_free(stream); + } AUD_remove_card(&vsnd->card); + g_free(vsnd->pcm); virtio_cleanup(vdev); } -static void virtio_snd_reset(VirtIODevice *vdev) {} +static void virtio_snd_reset(VirtIODevice *vdev) +{ + VirtIOSound *s = VIRTIO_SND(vdev); + virtio_snd_ctrl_command *cmd; + + WITH_QEMU_LOCK_GUARD(&s->cmdq_mutex) { + while (!QTAILQ_EMPTY(&s->cmdq)) { + cmd = QTAILQ_FIRST(&s->cmdq); + QTAILQ_REMOVE(&s->cmdq, cmd, next); + g_free(cmd); + } + } +} static void virtio_snd_class_init(ObjectClass *klass, void *data) { diff --git a/include/hw/virtio/virtio-snd.h b/include/hw/virtio/virtio-snd.h index 074b66c018..1a9835841d 100644 --- a/include/hw/virtio/virtio-snd.h +++ b/include/hw/virtio/virtio-snd.h @@ -69,11 +69,78 @@ typedef struct virtio_snd_pcm_xfer virtio_snd_pcm_xfer; /* I/O request status */ typedef struct virtio_snd_pcm_status virtio_snd_pcm_status; -typedef struct VirtIOSound { +/* device structs */ + +typedef struct VirtIOSound VirtIOSound; + +typedef struct VirtIOSoundPCMStream VirtIOSoundPCMStream; + +typedef struct virtio_snd_ctrl_command virtio_snd_ctrl_command; + +typedef struct VirtIOSoundPCMParams VirtIOSoundPCMParams; + +typedef struct VirtIOSoundPCM VirtIOSoundPCM; + +/* Stream params */ +struct VirtIOSoundPCMParams { + uint32_t features; + uint32_t buffer_bytes; /* size of hardware buffer in bytes */ + uint32_t period_bytes; /* size of hardware period in bytes */ + uint8_t channels; + uint8_t format; + uint8_t rate; +}; + +struct VirtIOSoundPCM { + VirtIOSound *snd; + VirtIOSoundPCMParams **pcm_params; + VirtIOSoundPCMStream **streams; + virtio_snd_jack **jacks; +}; + +struct VirtIOSoundPCMStream { + VirtIOSoundPCM *pcm; + virtio_snd_pcm_info info; + uint32_t id; + uint32_t buffer_bytes; + uint32_t period_bytes; + /* channel position values (VIRTIO_SND_CHMAP_XXX) */ + uint8_t positions[VIRTIO_SND_CHMAP_MAX_SIZE]; + VirtIOSound *s; + uint32_t features; /* 1 << VIRTIO_SND_PCM_F_XXX */ + uint64_t formats; /* 1 << VIRTIO_SND_PCM_FMT_XXX */ + uint64_t rates; /* 1 << VIRTIO_SND_PCM_RATE_XXX */ + uint8_t direction; + uint8_t channels_min; + uint8_t channels_max; + bool flushing; + audsettings as; + audsettings desired_as; + union { + SWVoiceIn *in; + SWVoiceOut *out; + } voice; + QemuMutex queue_mutex; + QSIMPLEQ_HEAD(, VirtIOSoundPCMBlock) queue; +}; + +struct VirtIOSound { VirtIODevice parent_obj; VirtQueue *queues[VIRTIO_SND_VQ_MAX]; + VirtIOSoundPCM *pcm; QEMUSoundCard card; VMChangeStateEntry *vmstate; virtio_snd_config snd_conf; -} VirtIOSound; + QemuMutex cmdq_mutex; + QTAILQ_HEAD(, virtio_snd_ctrl_command) cmdq; + bool processing_cmdq; +}; + +struct virtio_snd_ctrl_command { + VirtQueueElement *elem; + VirtQueue *vq; + virtio_snd_hdr ctrl; + virtio_snd_hdr resp; + QTAILQ_ENTRY(virtio_snd_ctrl_command) next; +}; #endif From patchwork Thu Jul 20 12:57:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manos Pitsidianakis X-Patchwork-Id: 13320469 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3D8E4EB64DA for ; Thu, 20 Jul 2023 12:58:53 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qMTEd-0005PL-K3; Thu, 20 Jul 2023 08:58:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qMTEY-0005DX-3D for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:18 -0400 Received: from mail-wr1-x430.google.com ([2a00:1450:4864:20::430]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qMTEV-0004Hu-Fb for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:17 -0400 Received: by mail-wr1-x430.google.com with SMTP id ffacd0b85a97d-3142970df44so626527f8f.3 for ; Thu, 20 Jul 2023 05:58:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689857892; x=1690462692; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=tjl/1n+mQgCku0rCqPi039Kzl5u/s+/8eKT/XrYc3Zc=; b=DxopRcGq9NI30L8l/aUxzYEj38oZEfSWuQwkj3w8hjcubAT+pLJMraNTEhtLTkXGUN e60ubIgbDs+C15ekXinWQpiLNt4kMrMlx7vrY1yi/XOaLakgHnlMpdxLyw/hv1+EjyIy rj49j6zHnbr0nvWnZymhAp2SD4x6VZIZc+3Iunwm7h+1YHep1hGgW/V8apZlzTWRn8iP P7N3/rFzyARPByoM//kK3cNbQsx42FarT+2NKQIFc9ys8FyvveEW+xz/wVtkcAv6xav5 69QfuGTnVbF+OBJpSxIUqylgm6EhSvluxaH2B2DvoIF5s34CvdIievIzGOY08fkfQ/q2 U6ag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689857892; x=1690462692; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tjl/1n+mQgCku0rCqPi039Kzl5u/s+/8eKT/XrYc3Zc=; b=TGqaJMhOPWx05kBEO4QKU6m1RgTQtYz1K0U6QaeNPdNHDv1BjvCTEep9cMVHizcuaA juIbY02SiruGjwxkztoEPh6J4EyYqD3/diPTobNx2QYNbBex+XF4llVIKylSHvSuVdHu K6xCafTbcTXb+Qt9FqT3QI21qF7Lf8aNMUIsJTWuTK65Ll38iIa83+oVP2GRQVfF3uJs P/Ig+figyOrEivJPcNyA17jGIohm4I8xGe6gjnB8vUZoeplzyelgbKkWXLSTVA5zWZz9 3jG3w1k0b/KGC5ZMR7BMYryfIQglX7fOH6edFOL4XE5jiOQ+D5X7lwcpE+yUlHkccsfK kzZQ== X-Gm-Message-State: ABy/qLZjABgmZ+DrZUvLac8akk+3rBZ32ow89XNkgzaxadedcG598/mN 7kswvZfJ781dNYki9OGSpA8kxwjzRyTHS5O2qkDmZAoi X-Google-Smtp-Source: APBJJlGfy+u22b9q+dVS6bLIsFStdLufMVzZG48oCBlFDQgzDELrhrmOIe3UvYjST8eg9t1AvtRg0g== X-Received: by 2002:adf:f6c6:0:b0:314:6057:66b8 with SMTP id y6-20020adff6c6000000b00314605766b8mr2012977wrp.59.1689857892653; Thu, 20 Jul 2023 05:58:12 -0700 (PDT) Received: from localhost.localdomain (adsl-41.37.6.162.tellas.gr. [37.6.162.41]) by smtp.gmail.com with ESMTPSA id o2-20020a5d4742000000b003063a92bbf5sm1294816wrs.70.2023.07.20.05.58.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Jul 2023 05:58:12 -0700 (PDT) From: Emmanouil Pitsidianakis To: qemu-devel@nongnu.org Cc: Emmanouil Pitsidianakis , "Igor Skalkin" , "Anton Yakovlev" , "Paolo Bonzini" , "Gerd Hoffmann" , "Michael S. Tsirkin" , "Marcel Apfelbaum" , =?utf-8?q?Daniel_P=2E_Berr?= =?utf-8?q?ang=C3=A9?= , "Eduardo Habkost" , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Volker_R=C3=BCmelin?= , =?utf-8?b?S8WRdsOh?= =?utf-8?b?Z8OzLCBab2x0w6Fu?= , "Alex Bennee" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH v4 04/12] virtio-sound: set PCM stream parameters Date: Thu, 20 Jul 2023 15:57:05 +0300 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::430; envelope-from=manos.pitsidianakis@linaro.org; helo=mail-wr1-x430.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This commit sets the virtio-snd device's default PCM parameters in virtio_snd_pcm_set_params_impl(). The same function will be used to set parameters from the guest with VIRTIO_SND_R_PCM_SET_PARAMS in a follow-up commit. PCM parameters describe the sound card parameters that the guest's kernel sees as an ALSA device. Signed-off-by: Emmanouil Pitsidianakis --- hw/virtio/virtio-snd.c | 109 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c index 5a0c2c7594..62d9bf557c 100644 --- a/hw/virtio/virtio-snd.c +++ b/hw/virtio/virtio-snd.c @@ -30,6 +30,29 @@ #define VIRTIO_SOUND_CHMAP_DEFAULT 0 #define VIRTIO_SOUND_HDA_FN_NID 0 +static uint32_t supported_formats = BIT(VIRTIO_SND_PCM_FMT_S8) + | BIT(VIRTIO_SND_PCM_FMT_U8) + | BIT(VIRTIO_SND_PCM_FMT_S16) + | BIT(VIRTIO_SND_PCM_FMT_U16) + | BIT(VIRTIO_SND_PCM_FMT_S32) + | BIT(VIRTIO_SND_PCM_FMT_U32) + | BIT(VIRTIO_SND_PCM_FMT_FLOAT); + +static uint32_t supported_rates = BIT(VIRTIO_SND_PCM_RATE_5512) + | BIT(VIRTIO_SND_PCM_RATE_8000) + | BIT(VIRTIO_SND_PCM_RATE_11025) + | BIT(VIRTIO_SND_PCM_RATE_16000) + | BIT(VIRTIO_SND_PCM_RATE_22050) + | BIT(VIRTIO_SND_PCM_RATE_32000) + | BIT(VIRTIO_SND_PCM_RATE_44100) + | BIT(VIRTIO_SND_PCM_RATE_48000) + | BIT(VIRTIO_SND_PCM_RATE_64000) + | BIT(VIRTIO_SND_PCM_RATE_88200) + | BIT(VIRTIO_SND_PCM_RATE_96000) + | BIT(VIRTIO_SND_PCM_RATE_176400) + | BIT(VIRTIO_SND_PCM_RATE_192000) + | BIT(VIRTIO_SND_PCM_RATE_384000); + static const char *print_code(uint32_t code) { #define CASE(CODE) \ @@ -111,6 +134,72 @@ virtio_snd_set_config(VirtIODevice *vdev, const uint8_t *config) memcpy(&s->snd_conf, sndconfig, sizeof(s->snd_conf)); } +/* + * Get params for a specific stream. + * + * @s: VirtIOSound device + * @stream_id: stream id + */ +static VirtIOSoundPCMParams *virtio_snd_pcm_get_params(VirtIOSound *s, + uint32_t stream_id) +{ + return stream_id >= s->snd_conf.streams ? NULL + : s->pcm->pcm_params[stream_id]; +} + +/* + * Set the given stream params. + * Called by both virtio_snd_handle_pcm_set_params and during device + * initialization. + * Returns the response status code. (VIRTIO_SND_S_*). + * + * @s: VirtIOSound device + * @params: The PCM params as defined in the virtio specification + */ +static +uint32_t virtio_snd_pcm_set_params_impl(VirtIOSound *s, + virtio_snd_pcm_set_params *params) +{ + VirtIOSoundPCMParams *st_params; + uint32_t stream_id = params->hdr.stream_id; + + if (stream_id > s->snd_conf.streams || !(s->pcm->pcm_params)) { + virtio_error(VIRTIO_DEVICE(s), "Streams have not been initialized.\n"); + return VIRTIO_SND_S_BAD_MSG; + } + + if (!s->pcm->pcm_params[stream_id]) { + s->pcm->pcm_params[stream_id] = g_new0(VirtIOSoundPCMParams, 1); + } + st_params = virtio_snd_pcm_get_params(s, stream_id); + + st_params->features = params->features; + st_params->buffer_bytes = params->buffer_bytes; + st_params->period_bytes = params->period_bytes; + + if (params->channels < 1 || params->channels > AUDIO_MAX_CHANNELS) { + error_report("Number of channels is not supported."); + return VIRTIO_SND_S_NOT_SUPP; + } + st_params->channels = params->channels; + + if (!(supported_formats & BIT(params->format))) { + error_report("Stream format is not supported."); + return VIRTIO_SND_S_NOT_SUPP; + } + st_params->format = params->format; + + if (!(supported_rates & BIT(params->rate))) { + error_report("Stream rate is not supported."); + return VIRTIO_SND_S_NOT_SUPP; + } + st_params->rate = params->rate; + st_params->period_bytes = params->period_bytes; + st_params->buffer_bytes = params->buffer_bytes; + + return VIRTIO_SND_S_OK; +} + /* * The actual processing done in virtio_snd_process_cmdq(). * @@ -290,6 +379,8 @@ static void virtio_snd_common_realize(DeviceState *dev, { VirtIODevice *vdev = VIRTIO_DEVICE(dev); VirtIOSound *vsnd = VIRTIO_SND(dev); + virtio_snd_pcm_set_params default_params; + uint32_t status; virtio_snd_set_pcm(vsnd); @@ -318,12 +409,30 @@ static void virtio_snd_common_realize(DeviceState *dev, AUD_register_card("virtio-sound", &vsnd->card); + /* set default params for all streams */ + default_params.features = 0; + default_params.buffer_bytes = 8192; + default_params.period_bytes = 4096; + default_params.channels = 2; + default_params.format = VIRTIO_SND_PCM_FMT_S16; + default_params.rate = VIRTIO_SND_PCM_RATE_44100; vsnd->queues[VIRTIO_SND_VQ_CONTROL] = virtio_add_queue(vdev, 64, ctrl); vsnd->queues[VIRTIO_SND_VQ_EVENT] = virtio_add_queue(vdev, 64, evt); vsnd->queues[VIRTIO_SND_VQ_TX] = virtio_add_queue(vdev, 64, txq); vsnd->queues[VIRTIO_SND_VQ_RX] = virtio_add_queue(vdev, 64, rxq); qemu_mutex_init(&vsnd->cmdq_mutex); QTAILQ_INIT(&vsnd->cmdq); + + for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) { + default_params.hdr.stream_id = i; + status = virtio_snd_pcm_set_params_impl(vsnd, &default_params); + if (status != VIRTIO_SND_S_OK) { + error_setg(errp, + "Can't initalize stream params, device responded with %s.", + print_code(status)); + return; + } + } } static void From patchwork Thu Jul 20 12:57:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manos Pitsidianakis X-Patchwork-Id: 13320470 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 11203EB64DA for ; Thu, 20 Jul 2023 12:59:04 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qMTEe-0005S8-3y; Thu, 20 Jul 2023 08:58:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qMTEa-0005IV-7p for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:20 -0400 Received: from mail-wr1-x432.google.com ([2a00:1450:4864:20::432]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qMTEX-0004Mv-SP for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:19 -0400 Received: by mail-wr1-x432.google.com with SMTP id ffacd0b85a97d-3172144c084so664318f8f.1 for ; Thu, 20 Jul 2023 05:58:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689857896; x=1690462696; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=iZuVw3BQUrnbNc2JtnQAnYlXBBxw+U/MPRXh9Zf7n8E=; b=e3IATNBd18tyw1lEYqOE/CStucugW8RsYOjuj6wzHfH/w4YvHge9OCsC7Dtv1/MPD0 ZufphZPIva79bVxvg0ajuCZY6R51c3TiEo6XX45nvM1wrkHs9wufZXLpqYz3QOnjBtCU XAJY+RKhrw8zibyAPfTJgdl+V58VVmcdsqhkSIYjgqD0gk1uJlCwmkTiUn6DlU6i77ML Cj6smM1koKcksE7RLrt8l+YyfBi9yUpkdFWwTKdIY1md8iI+3iQ17bqJH68b94vs5PnQ Q21QVyQFZaIshOxN2Jv4QgB9neBbNL9FNwBKw0bJVWj4dwA56lw4wzpswUYrn1eh9AzD yTtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689857896; x=1690462696; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=iZuVw3BQUrnbNc2JtnQAnYlXBBxw+U/MPRXh9Zf7n8E=; b=YE7JGUt2Ata7HK4maYfGOBxgJ4quM98jsKMVogmcaDoBKbUkuO68h2yhfloLKZBP0v iswiJO3YnSmMDyMdZsFtDg8gtH7VBOUyhrwRb4c88/SneGJhgsRy185GjinKXHCL18oV i2F1n3RZ8m0yDfzyYI246gTmz6Fu8I/I2IkgvdB1BSpMy6Q4AQu5Et8Z+9q2b13AkoZF j3nyb2PYvGO8shd54KHoKlrPqnzbJcmi1zEAe5Dz7Z5lE7ipSKtJgHcCuVMMQX21dHeO IcvdFYDgb2JaudogokaNhPdgdXU/yYkANc6En4AU7A7nuKJaXk8o2H8Zx9BuqtwgFX9H st5Q== X-Gm-Message-State: ABy/qLb3RaD1JWaTj/uc0ZtYrN7IvGbNC0nIT7g3FOQ6L3Z3mr2OuE1K gF2MAKSOvVpXB45/TdRoiGcAPhCQ/JPefJIE0tSehLM5 X-Google-Smtp-Source: APBJJlGfaIa1syxQPhKZwGDPmtoozGkpdXB4IRCbAQe0E7BScGXEhLZbSRhunOqtmZ3DGQ+MjBcr1w== X-Received: by 2002:adf:f004:0:b0:314:41e8:107d with SMTP id j4-20020adff004000000b0031441e8107dmr2385099wro.47.1689857895817; Thu, 20 Jul 2023 05:58:15 -0700 (PDT) Received: from localhost.localdomain (adsl-41.37.6.162.tellas.gr. [37.6.162.41]) by smtp.gmail.com with ESMTPSA id o2-20020a5d4742000000b003063a92bbf5sm1294816wrs.70.2023.07.20.05.58.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Jul 2023 05:58:15 -0700 (PDT) From: Emmanouil Pitsidianakis To: qemu-devel@nongnu.org Cc: Emmanouil Pitsidianakis , "Igor Skalkin" , "Anton Yakovlev" , "Paolo Bonzini" , "Gerd Hoffmann" , "Michael S. Tsirkin" , "Marcel Apfelbaum" , =?utf-8?q?Daniel_P=2E_Berr?= =?utf-8?q?ang=C3=A9?= , "Eduardo Habkost" , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Volker_R=C3=BCmelin?= , =?utf-8?b?S8WRdsOh?= =?utf-8?b?Z8OzLCBab2x0w6Fu?= , "Alex Bennee" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH v4 05/12] virtio-sound: prepare PCM streams Date: Thu, 20 Jul 2023 15:57:06 +0300 Message-Id: <68a13c43854d00efd62e43f3525a555ff83794bf.1689857559.git.manos.pitsidianakis@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::432; envelope-from=manos.pitsidianakis@linaro.org; helo=mail-wr1-x432.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org After setting PCM parameters, instantiate ("prepare") each stream in virtio_snd_pcm_prepare_impl(). Signed-off-by: Emmanouil Pitsidianakis --- hw/virtio/virtio-snd.c | 133 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c index 62d9bf557c..ca09c937c7 100644 --- a/hw/virtio/virtio-snd.c +++ b/hw/virtio/virtio-snd.c @@ -200,6 +200,132 @@ uint32_t virtio_snd_pcm_set_params_impl(VirtIOSound *s, return VIRTIO_SND_S_OK; } +/* + * Get a QEMU Audiosystem compatible format value from a VIRTIO_SND_PCM_FMT_* + */ +static AudioFormat virtio_snd_get_qemu_format(uint32_t format) +{ + #define CASE(FMT) \ + case VIRTIO_SND_PCM_FMT_##FMT: \ + return AUDIO_FORMAT_##FMT; + + switch (format) { + CASE(U8) + CASE(S8) + CASE(U16) + CASE(S16) + CASE(U32) + CASE(S32) + case VIRTIO_SND_PCM_FMT_FLOAT: + return AUDIO_FORMAT_F32; + default: + g_assert_not_reached(); + } + + #undef CASE +} + +/* + * Get a QEMU Audiosystem compatible frequency value from a + * VIRTIO_SND_PCM_RATE_* + */ +static uint32_t virtio_snd_get_qemu_freq(uint32_t rate) +{ + #define CASE(RATE) \ + case VIRTIO_SND_PCM_RATE_##RATE: \ + return RATE; + + switch (rate) { + CASE(5512) + CASE(8000) + CASE(11025) + CASE(16000) + CASE(22050) + CASE(32000) + CASE(44100) + CASE(48000) + CASE(64000) + CASE(88200) + CASE(96000) + CASE(176400) + CASE(192000) + CASE(384000) + default: + g_assert_not_reached(); + } + + #undef CASE +} + +/* + * Get QEMU Audiosystem compatible audsettings from virtio based pcm stream + * params. + */ +static void virtio_snd_get_qemu_audsettings(audsettings *as, + VirtIOSoundPCMParams *params) +{ + as->nchannels = MIN(AUDIO_MAX_CHANNELS, params->channels); + as->fmt = virtio_snd_get_qemu_format(params->format); + as->freq = virtio_snd_get_qemu_freq(params->rate); + as->endianness = AUDIO_HOST_ENDIANNESS; +} + +/* + * Prepares a VirtIOSound card stream. + * Returns the response status code. (VIRTIO_SND_S_*). + * + * @s: VirtIOSound device + * @stream_id: stream id + */ +static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound *s, uint32_t stream_id) +{ + audsettings as; + VirtIOSoundPCMParams *params; + VirtIOSoundPCMStream *stream; + + if (!s->pcm->streams || + !s->pcm->pcm_params || + !s->pcm->pcm_params[stream_id]) { + return VIRTIO_SND_S_BAD_MSG; + } + + params = virtio_snd_pcm_get_params(s, stream_id); + if (!params) { + return VIRTIO_SND_S_BAD_MSG; + } + + virtio_snd_get_qemu_audsettings(&as, params); + + stream = g_new0(VirtIOSoundPCMStream, 1); + + stream->id = stream_id; + stream->pcm = s->pcm; + stream->direction = stream_id < s->snd_conf.streams / 2 + + (s->snd_conf.streams & 1) ? VIRTIO_SND_D_OUTPUT : VIRTIO_SND_D_INPUT; + stream->info.hdr.hda_fn_nid = VIRTIO_SOUND_HDA_FN_NID; + stream->features = 0; + stream->channels_min = 1; + stream->channels_max = as.nchannels; + stream->formats = supported_formats; + stream->rates = supported_rates; + stream->s = s; + + stream->buffer_bytes = params->buffer_bytes; + stream->period_bytes = params->period_bytes; + + stream->positions[0] = VIRTIO_SND_CHMAP_FL; + stream->positions[1] = VIRTIO_SND_CHMAP_FR; + + stream->as = as; + stream->desired_as = stream->as; + qemu_mutex_init(&stream->queue_mutex); + QSIMPLEQ_INIT(&stream->queue); + + s->pcm->streams[stream_id] = stream; + + return VIRTIO_SND_S_OK; +} + /* * The actual processing done in virtio_snd_process_cmdq(). * @@ -432,6 +558,13 @@ static void virtio_snd_common_realize(DeviceState *dev, print_code(status)); return; } + status = virtio_snd_pcm_prepare_impl(vsnd, i); + if (status != VIRTIO_SND_S_OK) { + error_setg(errp, + "Can't prepare streams, device responded with %s.", + print_code(status)); + return; + } } } From patchwork Thu Jul 20 12:57:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manos Pitsidianakis X-Patchwork-Id: 13320467 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4E2BEEB64DC for ; Thu, 20 Jul 2023 12:58:40 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qMTEh-0005ZU-UN; Thu, 20 Jul 2023 08:58:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qMTEf-0005Wz-Ov for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:25 -0400 Received: from mail-wr1-x432.google.com ([2a00:1450:4864:20::432]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qMTEc-0004PF-1P for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:24 -0400 Received: by mail-wr1-x432.google.com with SMTP id ffacd0b85a97d-316f9abf204so687140f8f.1 for ; Thu, 20 Jul 2023 05:58:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689857899; x=1690462699; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=tuGgcT++OoIvPxS0IRVKWB7nwGsKLlUzuYUWBanzCic=; b=IjEc8nyzsfhsUew4jBl7TQ53CToFYe2bGgdfwo9AIdw/fO3HsiEjgdFGFrBl4BRO// +W12eRoUJoRB81AZ1cgVTEIKzcQPdKIP4ZzXkcLkK9US/JR9i6ye7KDm0+eliJat20Vs V8DRbj9he+SE1RdX+4wNphY+hoESot4XtXNe28diTCz5oZCE1PudafVa62ZsaLOsU9ve gh6mAebEsURkRhZfvB3q4rcSsopPTXXE0du/v4TOPf4jB3Nrptzy418xpuDI1SE4k6O4 AH8AsFafwHpusNHrs/eUecvrHHVvBZqNlk9YvMYnmWjOUrPPuR3rdYVQBm/sb32gXoJT XV5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689857899; x=1690462699; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tuGgcT++OoIvPxS0IRVKWB7nwGsKLlUzuYUWBanzCic=; b=WYKrzkEMEv8mMGj6KCb7VWq0yzNEUs+MIXuVr4ld3cGtL4bsA51tinn2RxGrsMFIv9 G510qoCq08BALFV5oy1dfNfQFKyWLyp0/C/m2lEx64G+yXtcs+bZSxeFFzICcpAIoIBi QboJHHA5Mnenk4zNS8RNm1uVjO9zKnJEpdMZ+HrKXseeyt5U0dbZwT++R2KvXmjhz0Fu /D0LlNw0n65t4p3vn05ocxBz4+I3KexrdOXvS9ofWHlnYUVurFIfxAg3SKddGY+Ro3vj JBu5+JzPsASGANkfiX6q4PWrLYpXBqaydVt0i3oJkS7thVLlpgx6aBEhAGYawP+4KKwj ISuw== X-Gm-Message-State: ABy/qLbu7ynE9KPphc4knen50jOVK8OFTw5qDjJmrKw4n8qSF8B4k06c io9iOH500b/pUdrNHnbJQH/EIogCbDz3rVHfiK2sBg== X-Google-Smtp-Source: APBJJlFCkMwONrkOPji6GOVF1WqhLe0ax/KyFrRoFw/MxgR3+SawbGlJS857kyYZl07YlUDo1s7N+Q== X-Received: by 2002:adf:f88a:0:b0:314:37a:4d2 with SMTP id u10-20020adff88a000000b00314037a04d2mr2247525wrp.60.1689857899212; Thu, 20 Jul 2023 05:58:19 -0700 (PDT) Received: from localhost.localdomain (adsl-41.37.6.162.tellas.gr. [37.6.162.41]) by smtp.gmail.com with ESMTPSA id o2-20020a5d4742000000b003063a92bbf5sm1294816wrs.70.2023.07.20.05.58.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Jul 2023 05:58:18 -0700 (PDT) From: Emmanouil Pitsidianakis To: qemu-devel@nongnu.org Cc: Emmanouil Pitsidianakis , "Igor Skalkin" , "Anton Yakovlev" , "Paolo Bonzini" , "Gerd Hoffmann" , "Michael S. Tsirkin" , "Marcel Apfelbaum" , =?utf-8?q?Daniel_P=2E_Berr?= =?utf-8?q?ang=C3=A9?= , "Eduardo Habkost" , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Volker_R=C3=BCmelin?= , =?utf-8?b?S8WRdsOh?= =?utf-8?b?Z8OzLCBab2x0w6Fu?= , "Alex Bennee" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH v4 06/12] virtio-sound: handle VIRTIO_SND_R_PCM_INFO request Date: Thu, 20 Jul 2023 15:57:07 +0300 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::432; envelope-from=manos.pitsidianakis@linaro.org; helo=mail-wr1-x432.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Respond to the VIRTIO_SND_R_PCM_INFO control request with the parameters of each requested PCM stream. Signed-off-by: Emmanouil Pitsidianakis --- hw/virtio/trace-events | 1 + hw/virtio/virtio-snd.c | 78 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 8a223e36e9..3e619f778b 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -164,6 +164,7 @@ virtio_snd_vm_state_stopped(void) "vm state stopped" virtio_snd_realize(void *snd) "snd %p: realize" virtio_snd_unrealize(void *snd) "snd %p: unrealize" virtio_snd_handle_ctrl(void *vdev, void *vq) "snd %p: handle ctrl event for queue %p" +virtio_snd_handle_pcm_info(uint32_t stream) "VIRTIO_SND_R_PCM_INFO called for stream %"PRIu32 virtio_snd_handle_code(uint32_t val, const char *code) "ctrl code msg val = %"PRIu32" == %s" virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called" virtio_snd_handle_event(void) "event queue callback called" diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c index ca09c937c7..3f8b46f372 100644 --- a/hw/virtio/virtio-snd.c +++ b/hw/virtio/virtio-snd.c @@ -134,6 +134,19 @@ virtio_snd_set_config(VirtIODevice *vdev, const uint8_t *config) memcpy(&s->snd_conf, sndconfig, sizeof(s->snd_conf)); } +/* + * Get a specific stream from the virtio sound card device. + * Returns NULL if @stream_id is invalid or not allocated. + * + * @s: VirtIOSound device + * @stream_id: stream id + */ +static VirtIOSoundPCMStream *virtio_snd_pcm_get_stream(VirtIOSound *s, + uint32_t stream_id) +{ + return stream_id >= s->snd_conf.streams ? NULL : s->pcm->streams[stream_id]; +} + /* * Get params for a specific stream. * @@ -147,6 +160,69 @@ static VirtIOSoundPCMParams *virtio_snd_pcm_get_params(VirtIOSound *s, : s->pcm->pcm_params[stream_id]; } +/* + * Handle the VIRTIO_SND_R_PCM_INFO request. + * The function writes the info structs to the request element. + * + * @s: VirtIOSound device + * @cmd: The request command queue element from VirtIOSound cmdq field + */ +static void virtio_snd_handle_pcm_info(VirtIOSound *s, + virtio_snd_ctrl_command *cmd) +{ + virtio_snd_query_info req; + VirtIOSoundPCMStream *stream = NULL; + g_autofree virtio_snd_pcm_info *pcm_info = NULL; + size_t sz = iov_to_buf(cmd->elem->out_sg, + cmd->elem->out_num, + 0, + &req, + sizeof(req)); + if (sz != sizeof(virtio_snd_query_info)) { + cmd->resp.code = VIRTIO_SND_S_BAD_MSG; + return; + } + + if (iov_size(cmd->elem->in_sg, cmd->elem->in_num) < + sizeof(virtio_snd_hdr) + req.size * req.count) { + error_report("pcm info: buffer too small, got: %lu, needed: %lu", + iov_size(cmd->elem->in_sg, cmd->elem->in_num), + sizeof(virtio_snd_pcm_info)); + cmd->resp.code = VIRTIO_SND_S_BAD_MSG; + return; + } + + pcm_info = g_new0(virtio_snd_pcm_info, req.count); + for (uint32_t i = req.start_id; i < req.start_id + req.count; i++) { + trace_virtio_snd_handle_pcm_info(i); + stream = virtio_snd_pcm_get_stream(s, i); + + if (!stream) { + error_report("Invalid stream id: %"PRIu32, i); + cmd->resp.code = VIRTIO_SND_S_BAD_MSG; + return; + } + + pcm_info[i - req.start_id].hdr.hda_fn_nid = stream->info.hdr.hda_fn_nid; + pcm_info[i - req.start_id].features = stream->features; + pcm_info[i - req.start_id].formats = stream->formats; + pcm_info[i - req.start_id].rates = stream->rates; + pcm_info[i - req.start_id].direction = stream->direction; + pcm_info[i - req.start_id].channels_min = stream->channels_min; + pcm_info[i - req.start_id].channels_max = stream->channels_max; + + memset(&pcm_info[i].padding, 0, sizeof(pcm_info[i].padding)); + } + + cmd->resp.code = VIRTIO_SND_S_OK; + + iov_from_buf(cmd->elem->in_sg, + cmd->elem->in_num, + sizeof(virtio_snd_hdr), + pcm_info, + sizeof(virtio_snd_pcm_info) * req.count); +} + /* * Set the given stream params. * Called by both virtio_snd_handle_pcm_set_params and during device @@ -358,6 +434,8 @@ process_cmd(VirtIOSound *s, virtio_snd_ctrl_command *cmd) cmd->resp.code = VIRTIO_SND_S_NOT_SUPP; break; case VIRTIO_SND_R_PCM_INFO: + virtio_snd_handle_pcm_info(s, cmd); + break; case VIRTIO_SND_R_PCM_SET_PARAMS: case VIRTIO_SND_R_PCM_PREPARE: case VIRTIO_SND_R_PCM_START: From patchwork Thu Jul 20 12:57:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manos Pitsidianakis X-Patchwork-Id: 13320471 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DABADEB64DC for ; Thu, 20 Jul 2023 12:59:27 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qMTEj-0005Zg-1j; Thu, 20 Jul 2023 08:58:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qMTEh-0005ZE-4a for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:27 -0400 Received: from mail-wr1-x432.google.com ([2a00:1450:4864:20::432]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qMTEe-0004Px-F8 for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:26 -0400 Received: by mail-wr1-x432.google.com with SMTP id ffacd0b85a97d-3144bf65ce9so613833f8f.3 for ; Thu, 20 Jul 2023 05:58:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689857902; x=1690462702; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cOqRzWPu5Bnb3bXB3ts2cIUxbAreVIGKhW6hHo7k7Aw=; b=G8QSry5GTY9xRVA8/oMO5p2PiYjk6r74E4ioeN9BlYncwTYlbyPTcbjlbZ2GoFukFm ZTDmjDHa0MdJsLq+FRyOn+1gGVCxq2UUVo0OvXvXOFuiHfej9ifjaBnRz3JLRkRoljKT O9+0B8zucsOviKLMge3EJ7gBtc4oISVwHbbKVk5ArY68ik2Q3pZR32Dzdd7zsOUgeWDZ XwEKegr2AjRYEdJRPi+qz/WgqaU7kxVfC9HqqMH3sdaheKRXYDkhwMEcNWc1USUnQHP/ WrmSvIsNdiUVWxx8hju7puPV5P9a0rTdXxcrm8nVR/TwbylLsMIRt57HCTg6PJPhW9K4 GnXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689857902; x=1690462702; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cOqRzWPu5Bnb3bXB3ts2cIUxbAreVIGKhW6hHo7k7Aw=; b=AMkbuaCgogmJ8nZckGDw81r1UCMU7Ci/u0RLHUA0JFqQFYNKNXD+2ND9xcl27gjlDT Ul6XJ6Q6sQb+WBthl8jjCt4YU71578GPMKSP+BaqNL9waX7AwSvX218n4C1Vb0uZg3iy 7anEKbOAQ8VD7FTSDEDBNoPpsIRsrXDb2ruku58c5sivXxnSGBmAOgAB1xOfs8lbQtzo VqrtBgEatG2TB/2LAlgl7+/IWiJGQZckDVe5ZN7B+VzvaSAcMBX3EXEwGUz5iJNFisE0 N/pwUNjGNm511iz3pGnoJxpA8NgxJWQNzcz/UhGpSJkgCwjfLXK2pnBTTpNU5/qksNSr TPwA== X-Gm-Message-State: ABy/qLYtprD3HToZk1rUxSq1Yify4zkHWc4Tp0AiMm1xdaZcicgbXJiF jwaidpR2OopsufJIswBZ3R/ojOJcUwEPzVpfSURD0w== X-Google-Smtp-Source: APBJJlE9ionDEMpoXXvx1NdoLWNIuG7Ac0rZpVxa+cL4yvfep0Vi/+QIFtNsb/QfJMeFcSxV9XWgEg== X-Received: by 2002:adf:fcd0:0:b0:30a:e9cb:1a2e with SMTP id f16-20020adffcd0000000b0030ae9cb1a2emr2102420wrs.65.1689857902737; Thu, 20 Jul 2023 05:58:22 -0700 (PDT) Received: from localhost.localdomain (adsl-41.37.6.162.tellas.gr. [37.6.162.41]) by smtp.gmail.com with ESMTPSA id o2-20020a5d4742000000b003063a92bbf5sm1294816wrs.70.2023.07.20.05.58.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Jul 2023 05:58:22 -0700 (PDT) From: Emmanouil Pitsidianakis To: qemu-devel@nongnu.org Cc: Emmanouil Pitsidianakis , "Igor Skalkin" , "Anton Yakovlev" , "Paolo Bonzini" , "Gerd Hoffmann" , "Michael S. Tsirkin" , "Marcel Apfelbaum" , =?utf-8?q?Daniel_P=2E_Berr?= =?utf-8?q?ang=C3=A9?= , "Eduardo Habkost" , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Volker_R=C3=BCmelin?= , =?utf-8?b?S8WRdsOh?= =?utf-8?b?Z8OzLCBab2x0w6Fu?= , "Alex Bennee" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH v4 07/12] virtio-sound: handle VIRTIO_SND_R_PCM_{START,STOP} Date: Thu, 20 Jul 2023 15:57:08 +0300 Message-Id: <5939a6161e07c750366731ca40314c687e32d30a.1689857559.git.manos.pitsidianakis@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::432; envelope-from=manos.pitsidianakis@linaro.org; helo=mail-wr1-x432.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Handle the start and stop control messages for a stream_id. This request does nothing at the moment except for replying to it. Audio playback or capture will be started/stopped here in follow-up commits. Signed-off-by: Emmanouil Pitsidianakis --- hw/virtio/trace-events | 1 + hw/virtio/virtio-snd.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 3e619f778b..8eae1bf881 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -165,6 +165,7 @@ virtio_snd_realize(void *snd) "snd %p: realize" virtio_snd_unrealize(void *snd) "snd %p: unrealize" virtio_snd_handle_ctrl(void *vdev, void *vq) "snd %p: handle ctrl event for queue %p" virtio_snd_handle_pcm_info(uint32_t stream) "VIRTIO_SND_R_PCM_INFO called for stream %"PRIu32 +virtio_snd_handle_pcm_start_stop(const char *code, uint32_t stream) "%s called for stream %"PRIu32 virtio_snd_handle_code(uint32_t val, const char *code) "ctrl code msg val = %"PRIu32" == %s" virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called" virtio_snd_handle_event(void) "event queue callback called" diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c index 3f8b46f372..0dc28d5bdc 100644 --- a/hw/virtio/virtio-snd.c +++ b/hw/virtio/virtio-snd.c @@ -402,6 +402,40 @@ static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound *s, uint32_t stream_id) return VIRTIO_SND_S_OK; } +/* + * Handles VIRTIO_SND_R_PCM_START. + * + * @s: VirtIOSound device + * @cmd: The request command queue element from VirtIOSound cmdq field + * @start: whether to start or stop the device + */ +static void virtio_snd_handle_pcm_start_stop(VirtIOSound *s, + virtio_snd_ctrl_command *cmd, + bool start) +{ + VirtIOSoundPCMStream *stream; + virtio_snd_pcm_hdr req; + size_t sz = iov_to_buf(cmd->elem->out_sg, + cmd->elem->out_num, + 0, + &req, + sizeof(req)); + if (sz != sizeof(virtio_snd_pcm_hdr)) { + cmd->resp.code = VIRTIO_SND_S_BAD_MSG; + return; + } + + cmd->resp.code = VIRTIO_SND_S_OK; + trace_virtio_snd_handle_pcm_start_stop(start ? "VIRTIO_SND_R_PCM_START" : + "VIRTIO_SND_R_PCM_STOP", req.stream_id); + + stream = virtio_snd_pcm_get_stream(s, req.stream_id); + if (!stream) { + error_report("Invalid stream id: %"PRIu32, req.stream_id); + cmd->resp.code = VIRTIO_SND_S_BAD_MSG; + } +} + /* * The actual processing done in virtio_snd_process_cmdq(). * @@ -436,10 +470,14 @@ process_cmd(VirtIOSound *s, virtio_snd_ctrl_command *cmd) case VIRTIO_SND_R_PCM_INFO: virtio_snd_handle_pcm_info(s, cmd); break; - case VIRTIO_SND_R_PCM_SET_PARAMS: - case VIRTIO_SND_R_PCM_PREPARE: case VIRTIO_SND_R_PCM_START: + virtio_snd_handle_pcm_start_stop(s, cmd, true); + break; case VIRTIO_SND_R_PCM_STOP: + virtio_snd_handle_pcm_start_stop(s, cmd, false); + break; + case VIRTIO_SND_R_PCM_SET_PARAMS: + case VIRTIO_SND_R_PCM_PREPARE: case VIRTIO_SND_R_PCM_RELEASE: cmd->resp.code = VIRTIO_SND_S_NOT_SUPP; break; From patchwork Thu Jul 20 12:57:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manos Pitsidianakis X-Patchwork-Id: 13320468 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1016CEB64DA for ; Thu, 20 Jul 2023 12:58:43 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qMTEs-0005iB-C2; Thu, 20 Jul 2023 08:58:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qMTEp-0005dl-Fi for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:35 -0400 Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qMTEi-0004Ut-W5 for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:32 -0400 Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-3fbc77e76abso6125665e9.1 for ; Thu, 20 Jul 2023 05:58:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689857906; x=1690462706; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zTmZmNIhK1aJ9dGl/qSI8JMpkJ+0r1A4/7lLsA2eztE=; b=OHkrEVka0fHUEk8rw41/ceIPsAXsZ/WY7iMBrrJZsA6te0ws1Xeez8tzN5Agw/QrOa 6WYoGIraWqJF5Ll5beE0NQUq30Bb751xjwgy73h/mQaG5fsDf4qi+qbTMRmBz+dOuqNo ubNwwE24TFUde75e4VThspuPcoKtA2rLm5pWZpuTXvSrGuPuOubBDhuoUtwHSiRuPIfk JioU+sA3ESrB4A4zS8j08UUViekxHUl7YY4vMy8wlOrNfpq9tWehNntjf7FpAo7VFBgM NwHxNFu/63DM5RLl0CsapRtYRyQPfFNC3VeW3GCuF+73WqD4/V6NXfsJurOQIbEKQuh0 3egg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689857906; x=1690462706; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zTmZmNIhK1aJ9dGl/qSI8JMpkJ+0r1A4/7lLsA2eztE=; b=HXZS0AWcD9aSXR+lvwW7YjEFCg27U1keEmc/6FNejg6RXpOh14XVr7UO0ST8RTuhZi zMKSVlB7tsFw/jZnd0EUjEtEI14+CylIWSng9jb6i8Avx51vmKtlOh0beSszJbvw1jCH ofCYcGtwyivZrGN2YeiPTUAbl7bramMTkOgWkyoQDxWfyT0r3huK7NRgpfAvRqff9jwD IN9nZ78Rr6uQdJHkeR7libzjg9X0apBKsobFw+X1xpTBBNqkzkUxyxMELjSiU1mj09nM MgLukCwtq4C0aQ0Olo/1OwlkviaDRGWQ5qPACyOSCRbRlnStMSWodeJQPc4cT2xO4kzw d9aw== X-Gm-Message-State: ABy/qLZ2oIyOXmTAbXxlt7vee4sb8/1SUm3Z43bvDqmJZFSOPhdJ5/Tu wUthx0iam200yXTMEbdW04Zx+TD9V60ugJMy40AbUw== X-Google-Smtp-Source: APBJJlHyyImx9oUSyI8fEZ21Vr6cZSNtrKmz1uYAvl3Awt2NR1YXR9u8cqE8dlPN4WeB5Y7pv7aO+Q== X-Received: by 2002:a1c:e913:0:b0:3fb:9ef2:157 with SMTP id q19-20020a1ce913000000b003fb9ef20157mr3937928wmc.28.1689857906185; Thu, 20 Jul 2023 05:58:26 -0700 (PDT) Received: from localhost.localdomain (adsl-41.37.6.162.tellas.gr. [37.6.162.41]) by smtp.gmail.com with ESMTPSA id o2-20020a5d4742000000b003063a92bbf5sm1294816wrs.70.2023.07.20.05.58.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Jul 2023 05:58:25 -0700 (PDT) From: Emmanouil Pitsidianakis To: qemu-devel@nongnu.org Cc: Emmanouil Pitsidianakis , "Igor Skalkin" , "Anton Yakovlev" , "Paolo Bonzini" , "Gerd Hoffmann" , "Michael S. Tsirkin" , "Marcel Apfelbaum" , =?utf-8?q?Daniel_P=2E_Berr?= =?utf-8?q?ang=C3=A9?= , "Eduardo Habkost" , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Volker_R=C3=BCmelin?= , =?utf-8?b?S8WRdsOh?= =?utf-8?b?Z8OzLCBab2x0w6Fu?= , "Alex Bennee" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH v4 08/12] virtio-sound: handle VIRTIO_SND_PCM_SET_PARAMS Date: Thu, 20 Jul 2023 15:57:09 +0300 Message-Id: <8f78d3a132a2c0082dfa9b9f0386057f92cc66e8.1689857559.git.manos.pitsidianakis@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::332; envelope-from=manos.pitsidianakis@linaro.org; helo=mail-wm1-x332.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Handle the set parameters control request. It reconfigures a stream based on a guest's preference if the values are valid and supported. Signed-off-by: Emmanouil Pitsidianakis --- hw/virtio/trace-events | 1 + hw/virtio/virtio-snd.c | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 8eae1bf881..f70cde4f01 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -163,6 +163,7 @@ virtio_snd_vm_state_running(void) "vm state running" virtio_snd_vm_state_stopped(void) "vm state stopped" virtio_snd_realize(void *snd) "snd %p: realize" virtio_snd_unrealize(void *snd) "snd %p: unrealize" +virtio_snd_handle_pcm_set_params(uint32_t stream) "VIRTIO_SND_PCM_SET_PARAMS called for stream %"PRIu32 virtio_snd_handle_ctrl(void *vdev, void *vq) "snd %p: handle ctrl event for queue %p" virtio_snd_handle_pcm_info(uint32_t stream) "VIRTIO_SND_R_PCM_INFO called for stream %"PRIu32 virtio_snd_handle_pcm_start_stop(const char *code, uint32_t stream) "%s called for stream %"PRIu32 diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c index 0dc28d5bdc..ea1f07a66a 100644 --- a/hw/virtio/virtio-snd.c +++ b/hw/virtio/virtio-snd.c @@ -276,6 +276,30 @@ uint32_t virtio_snd_pcm_set_params_impl(VirtIOSound *s, return VIRTIO_SND_S_OK; } +/* + * Handles the VIRTIO_SND_R_PCM_SET_PARAMS request. + * + * @s: VirtIOSound device + * @cmd: The request command queue element from VirtIOSound cmdq field + */ +static void virtio_snd_handle_pcm_set_params(VirtIOSound *s, + virtio_snd_ctrl_command *cmd) +{ + virtio_snd_pcm_set_params req; + size_t sz = iov_to_buf(cmd->elem->out_sg, + cmd->elem->out_num, + 0, + &req, + sizeof(req)); + if (sz != sizeof(virtio_snd_pcm_set_params)) { + cmd->resp.code = VIRTIO_SND_S_BAD_MSG; + return; + } + + trace_virtio_snd_handle_pcm_set_params(req.hdr.stream_id); + cmd->resp.code = virtio_snd_pcm_set_params_impl(s, &req); +} + /* * Get a QEMU Audiosystem compatible format value from a VIRTIO_SND_PCM_FMT_* */ @@ -477,6 +501,8 @@ process_cmd(VirtIOSound *s, virtio_snd_ctrl_command *cmd) virtio_snd_handle_pcm_start_stop(s, cmd, false); break; case VIRTIO_SND_R_PCM_SET_PARAMS: + virtio_snd_handle_pcm_set_params(s, cmd); + break; case VIRTIO_SND_R_PCM_PREPARE: case VIRTIO_SND_R_PCM_RELEASE: cmd->resp.code = VIRTIO_SND_S_NOT_SUPP; From patchwork Thu Jul 20 12:57:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manos Pitsidianakis X-Patchwork-Id: 13320474 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 59EF6EB64DD for ; Thu, 20 Jul 2023 12:59:39 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qMTF7-0006sT-DS; Thu, 20 Jul 2023 08:58:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qMTF5-0006jm-4Y for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:51 -0400 Received: from mail-wm1-x32d.google.com ([2a00:1450:4864:20::32d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qMTEp-0004VI-1D for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:50 -0400 Received: by mail-wm1-x32d.google.com with SMTP id 5b1f17b1804b1-3fbc59de009so6080655e9.3 for ; Thu, 20 Jul 2023 05:58:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689857910; x=1690462710; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ktiuq0APAZpJtp1zCEE3+1kHE62a0w0gFPRmMA4ENgw=; b=I70Y+LkJR+dy8QIOB7/UgA0Wn07uPIG+RVMhAmg5tRQj++rNA97jzEBYXXczSyp2v8 0jv1e6Znn8XZAyw32WGkK5l3lmKBLFKiR749f9fJTeMxbpbnjeqOXTawsgNG5iD0xemy 92IXGncWztphoMnwodBFCTOTOEzwd+geKsIXPQIDCfp0Bo9DA3FwawuZcGtVFL5SL5Ca k7VSgYNS06FbfWu+N4KrwRHO1gUSNZnG97mLdGKf9hAtmL+tK+h6ciHqRZeJSdSLUR5W QsnlqCoF4FaxGmyZB4coqO61zxPLg/9f6/2hpv0LgwWF/rHnjupHRjxWPFzTkrH+RlTe Q3qg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689857910; x=1690462710; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ktiuq0APAZpJtp1zCEE3+1kHE62a0w0gFPRmMA4ENgw=; b=Uiv9bpT56G5d+OZsiA+fJuIS5+yn55LXcYPqBvku44HeX6VC0KPstxxP5Btv9xe6pt oNK9ouEqF4Y5JhorPcTRZt43ocElVei9/Lhxih8nHFjeJ8UBJWZyIT9NN20KZK2KKDfa 80tR7HMUMY51wsP/HT8QUU5Il7f5puDvsuxKlRVoIvLO4tfzGDACzX1zhj6cvhWFgXtI ngWKBO4Njmr64DrGJ8+MXPXyQsGHJv3egtm5cLkHabO6f1OwgJHI16tmnNcdfB/hSYjY OfCfC+IPjBmiTefWVpe1405qRBMykH19+EkpYBh6MzNcKNNi/74W3luG0RYlmPgYFsWy 1ONQ== X-Gm-Message-State: ABy/qLaJEU7nGlSfu/oiCKPmVPU+9RJybBWEOpaGT5Xo4Zrhoxh5HrTD 33It/JuqVNQ0phTK+i9bkiYqRHMWY/jrJ1/mBn1UyA== X-Google-Smtp-Source: APBJJlEui7lvRGn1e2efHh/aK6VQak3oIV2Tqh3oiltxSyg4xmnwwxdjItpCr3i3hQ3DgD1h3BpmuA== X-Received: by 2002:a7b:c417:0:b0:3fc:a49:4c05 with SMTP id k23-20020a7bc417000000b003fc0a494c05mr3833144wmi.40.1689857909712; Thu, 20 Jul 2023 05:58:29 -0700 (PDT) Received: from localhost.localdomain (adsl-41.37.6.162.tellas.gr. [37.6.162.41]) by smtp.gmail.com with ESMTPSA id o2-20020a5d4742000000b003063a92bbf5sm1294816wrs.70.2023.07.20.05.58.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Jul 2023 05:58:29 -0700 (PDT) From: Emmanouil Pitsidianakis To: qemu-devel@nongnu.org Cc: Emmanouil Pitsidianakis , "Igor Skalkin" , "Anton Yakovlev" , "Paolo Bonzini" , "Gerd Hoffmann" , "Michael S. Tsirkin" , "Marcel Apfelbaum" , =?utf-8?q?Daniel_P=2E_Berr?= =?utf-8?q?ang=C3=A9?= , "Eduardo Habkost" , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Volker_R=C3=BCmelin?= , =?utf-8?b?S8WRdsOh?= =?utf-8?b?Z8OzLCBab2x0w6Fu?= , "Alex Bennee" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH v4 09/12] virtio-sound: handle VIRTIO_SND_R_PCM_PREPARE Date: Thu, 20 Jul 2023 15:57:10 +0300 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32d; envelope-from=manos.pitsidianakis@linaro.org; helo=mail-wm1-x32d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Handles the PCM prepare control request. It initializes a PCM stream when the guests asks for it. Signed-off-by: Emmanouil Pitsidianakis --- hw/virtio/virtio-snd.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c index ea1f07a66a..de82ed60ad 100644 --- a/hw/virtio/virtio-snd.c +++ b/hw/virtio/virtio-snd.c @@ -426,6 +426,27 @@ static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound *s, uint32_t stream_id) return VIRTIO_SND_S_OK; } +/* + * Handles VIRTIO_SND_R_PCM_PREPARE. + * + * @s: VirtIOSound device + * @cmd: The request command queue element from VirtIOSound cmdq field + */ +static void virtio_snd_handle_pcm_prepare(VirtIOSound *s, + virtio_snd_ctrl_command *cmd) +{ + uint32_t stream_id; + size_t sz = iov_to_buf(cmd->elem->out_sg, + cmd->elem->out_num, + sizeof(virtio_snd_hdr), + &stream_id, + sizeof(stream_id)); + + cmd->resp.code = sz == sizeof(uint32_t) + ? virtio_snd_pcm_prepare_impl(s, stream_id) + : VIRTIO_SND_S_BAD_MSG; +} + /* * Handles VIRTIO_SND_R_PCM_START. * @@ -504,6 +525,8 @@ process_cmd(VirtIOSound *s, virtio_snd_ctrl_command *cmd) virtio_snd_handle_pcm_set_params(s, cmd); break; case VIRTIO_SND_R_PCM_PREPARE: + virtio_snd_handle_pcm_prepare(s, cmd); + break; case VIRTIO_SND_R_PCM_RELEASE: cmd->resp.code = VIRTIO_SND_S_NOT_SUPP; break; From patchwork Thu Jul 20 12:57:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manos Pitsidianakis X-Patchwork-Id: 13320475 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 32996C0015E for ; Thu, 20 Jul 2023 12:59:40 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qMTF1-0006Ah-GR; Thu, 20 Jul 2023 08:58:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qMTEu-0005wc-FD for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:41 -0400 Received: from mail-wr1-x42a.google.com ([2a00:1450:4864:20::42a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qMTEr-0004Ve-4J for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:40 -0400 Received: by mail-wr1-x42a.google.com with SMTP id ffacd0b85a97d-307d58b3efbso621338f8f.0 for ; Thu, 20 Jul 2023 05:58:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689857913; x=1690462713; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=iVcCqT33aYYqa+SnwavtcwXTmT9T8ESgXcng0tddxmo=; b=R39UoUmJnBKRKyMOKnA41ngwac5wD18yPB5tvUUofHBeTu9vzkk/VKRGtNmEYJwKsE DOHf0FpZMxrr/xLrIUe3JfdQETfDXMVSQoLXgC6KMbPFOTC1R9FqGYvwTBiFul0RyN7J z4uoCTAfiIAM5tDr5F/ozKXSCjzlcbjFbM2x+QQgCIAGkwtDFM3tS1GhFeIkYC+hKw7O eMFEDzAGP74LaC7N3iY/2RFdhOiOgJK5kFGSwRWGAPqBlTznlkaaKiB9pUBSXweo9ZVX bqzIJJ3Vx1oiWN9juqwLJeVNOgRU+i7WRcUIobFbR3lSs6skNMEbFSKJW2uc80M5BREt F0bA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689857913; x=1690462713; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=iVcCqT33aYYqa+SnwavtcwXTmT9T8ESgXcng0tddxmo=; b=V0a+eLJ+kf4Dlx0XJ446IuhGbcoNiOlVIqI4bMxZ3hnE9rFrVPT8/2d8K0MXFqjzP5 QfLD3fYT1LOW69y+xixZjpmnAfO0L8JKmedypUxtnZILlzb1/stlsoX7VP3qwtncdtMI NkByhuF3RuF3FuVCo62r7MjyWTvicyRZPUIIC09zjmwm3b4UHFBiBFTHUGxldLuP8HHg R/VVMLssdUrXlSZ7ftH+E/bBqv/PDEUE6+H5rItcmc3Uecvlg6Kr+f6RPePJq9JU0RUl FBuzfgvOW2cXdTmgrEp2u/pESQZKwK3FrG15g22gJgPzgf1GmV77BI1qEjG729U8nwgQ YG5w== X-Gm-Message-State: ABy/qLbSGhYwWC2+zAUitgUskNOzE0rx5eJLs6GJMfwWDMKBBTZKRxOr VX7yCNW/jqmr7VWqnL1w9woln6/b6t3FJ/AjXa9drQ== X-Google-Smtp-Source: APBJJlG+Tmi4RB7gzH3CeC4iMY1z2SjVEhikdbb9wr3uZ0V99WGgNQdw8l4GpEXdWzw1MH5iXp6CLA== X-Received: by 2002:a5d:6e53:0:b0:313:f463:9d40 with SMTP id j19-20020a5d6e53000000b00313f4639d40mr2044628wrz.65.1689857913125; Thu, 20 Jul 2023 05:58:33 -0700 (PDT) Received: from localhost.localdomain (adsl-41.37.6.162.tellas.gr. [37.6.162.41]) by smtp.gmail.com with ESMTPSA id o2-20020a5d4742000000b003063a92bbf5sm1294816wrs.70.2023.07.20.05.58.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Jul 2023 05:58:32 -0700 (PDT) From: Emmanouil Pitsidianakis To: qemu-devel@nongnu.org Cc: Emmanouil Pitsidianakis , "Igor Skalkin" , "Anton Yakovlev" , "Paolo Bonzini" , "Gerd Hoffmann" , "Michael S. Tsirkin" , "Marcel Apfelbaum" , =?utf-8?q?Daniel_P=2E_Berr?= =?utf-8?q?ang=C3=A9?= , "Eduardo Habkost" , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Volker_R=C3=BCmelin?= , =?utf-8?b?S8WRdsOh?= =?utf-8?b?Z8OzLCBab2x0w6Fu?= , "Alex Bennee" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH v4 10/12] virtio-sound: handle VIRTIO_SND_PCM_RELEASE Date: Thu, 20 Jul 2023 15:57:11 +0300 Message-Id: <4e14b2d129ffac210cde100381c38a86265799f6.1689857559.git.manos.pitsidianakis@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42a; envelope-from=manos.pitsidianakis@linaro.org; helo=mail-wr1-x42a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Handle the PCM release control request, which is necessary for flushing pending sound IO. No IO is handled yet so currently it only replies to the request. Signed-off-by: Emmanouil Pitsidianakis --- hw/virtio/trace-events | 1 + hw/virtio/virtio-snd.c | 51 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index f70cde4f01..60ab62a80d 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -167,6 +167,7 @@ virtio_snd_handle_pcm_set_params(uint32_t stream) "VIRTIO_SND_PCM_SET_PARAMS cal virtio_snd_handle_ctrl(void *vdev, void *vq) "snd %p: handle ctrl event for queue %p" virtio_snd_handle_pcm_info(uint32_t stream) "VIRTIO_SND_R_PCM_INFO called for stream %"PRIu32 virtio_snd_handle_pcm_start_stop(const char *code, uint32_t stream) "%s called for stream %"PRIu32 +virtio_snd_handle_pcm_release(uint32_t stream) "VIRTIO_SND_PCM_RELEASE called for stream %"PRIu32 virtio_snd_handle_code(uint32_t val, const char *code) "ctrl code msg val = %"PRIu32" == %s" virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called" virtio_snd_handle_event(void) "event queue callback called" diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c index de82ed60ad..e87783c38a 100644 --- a/hw/virtio/virtio-snd.c +++ b/hw/virtio/virtio-snd.c @@ -481,6 +481,55 @@ static void virtio_snd_handle_pcm_start_stop(VirtIOSound *s, } } +/* + * Releases the buffer resources allocated to a stream. Seperated from the + * handler so that the code can be reused in the unrealize function. Returns + * the response status code. (VIRTIO_SND_S_*). + * + * @stream: VirtIOSoundPCMStream stream + * @stream_id: stream id + */ +static uint32_t virtio_snd_pcm_release_impl(VirtIOSoundPCMStream *stream, + uint32_t stream_id) +{ + return VIRTIO_SND_S_OK; +} + +/* + * Handles VIRTIO_SND_R_PCM_RELEASE. + * + * @s: VirtIOSound device + * @cmd: The request command queue element from VirtIOSound cmdq field + */ +static void virtio_snd_handle_pcm_release(VirtIOSound *s, + virtio_snd_ctrl_command *cmd) +{ + uint32_t stream_id; + VirtIOSoundPCMStream *stream; + size_t sz = iov_to_buf(cmd->elem->out_sg, + cmd->elem->out_num, + sizeof(virtio_snd_hdr), + &stream_id, + sizeof(stream_id)); + if (sz != sizeof(uint32_t)) { + cmd->resp.code = VIRTIO_SND_S_BAD_MSG; + return; + } + + trace_virtio_snd_handle_pcm_release(stream_id); + + stream = virtio_snd_pcm_get_stream(s, stream_id); + if (!stream) { + error_report("already released stream %"PRIu32, stream_id); + virtio_error(VIRTIO_DEVICE(s), + "already released stream %"PRIu32, + stream_id); + cmd->resp.code = VIRTIO_SND_S_BAD_MSG; + return; + } + cmd->resp.code = virtio_snd_pcm_release_impl(stream, stream_id); +} + /* * The actual processing done in virtio_snd_process_cmdq(). * @@ -528,7 +577,7 @@ process_cmd(VirtIOSound *s, virtio_snd_ctrl_command *cmd) virtio_snd_handle_pcm_prepare(s, cmd); break; case VIRTIO_SND_R_PCM_RELEASE: - cmd->resp.code = VIRTIO_SND_S_NOT_SUPP; + virtio_snd_handle_pcm_release(s, cmd); break; case VIRTIO_SND_R_CHMAP_INFO: qemu_log_mask(LOG_UNIMP, From patchwork Thu Jul 20 12:57:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manos Pitsidianakis X-Patchwork-Id: 13320473 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E26BAEB64DA for ; Thu, 20 Jul 2023 12:59:32 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qMTF3-0006V0-I6; Thu, 20 Jul 2023 08:58:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qMTEx-000623-EF for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:43 -0400 Received: from mail-wm1-x32e.google.com ([2a00:1450:4864:20::32e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qMTEs-0004dL-8y for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:41 -0400 Received: by mail-wm1-x32e.google.com with SMTP id 5b1f17b1804b1-3fc0aecf107so5918555e9.2 for ; Thu, 20 Jul 2023 05:58:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689857916; x=1690462716; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JEJPF6UdPmjlEMb1FaY91hZlxocVANm928wmyuTDSys=; b=uEOsa3pSNW32CJVkuHdvAtUjdo/xh0lhvbHf1LZQJM7mrCo4bDGsuuZeHCemt/QlgF z6QqqSsLeL1S128PlrcEjcshKDgWH3z17f8qFSWaZsab3jI9X47mZJWi42xTP+s+TJAY z9RgECKOjrAHAHGm3NdEimtkuCt68achLBmteXTU4NAJ1AHE3RicLPbFNqwKDgZHr+Nl qchgSnoQaa0ieeoyoM5KD7WojBz/o9LKjUxBe3nxhGUnkFoAh3piqwrtMphOAu2ybuOu xVIxIcAnoNLVI1sr5MMJKn+UrT1QFzUxDBwQYO3ZhpT0LA8cTXaM1lh+7VFf5Bx7+JcV +MSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689857916; x=1690462716; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JEJPF6UdPmjlEMb1FaY91hZlxocVANm928wmyuTDSys=; b=Ie2QFWKvQFA8ZsAVONOGNmse3vnLFjCn20L3sBFqNv+ghnM06t1FaeajXnZ5dSf+bj W7u5YVeGxRh3Moq4JECrE5cBx08/Xh0FUbgbcURp8dT0mGfxQ5GxFi6aGAbatXlDqWQx yY2DqoB4h9I2BVvIzn8NURUKwDutZ06m1fQwb0y3rmUAsWix8kKe6zNITsrnpgR8m2c4 UQv8UxmjQmSXnpbtOFPujvE0S4hsxMnZ151UCat0dr3jkEQ3nyjddL1KwFd+k976GRrt loH7JN9tsKGHhH4KbQDif08R3bNPaoV78AqKs9dhhNtPB2OoHCxPUIGJj623zwtlWN9A 6yMg== X-Gm-Message-State: ABy/qLYiUd09+w8LTKLUWePF6uekoiUACU7cKYA1GYG6oNdqB0xiM9dC C2c+5dCarIN7Hu28HJjN9CZsrTVJV4Smk8O2424zAg== X-Google-Smtp-Source: APBJJlFOKR+KHSSElyzGRENZv2A0PcJBsrAPaUVVQ+MTHetPCTGrBjjTyOD0t44d7gnfSVzHyn5btg== X-Received: by 2002:a5d:5148:0:b0:313:f86f:2858 with SMTP id u8-20020a5d5148000000b00313f86f2858mr1819050wrt.2.1689857916541; Thu, 20 Jul 2023 05:58:36 -0700 (PDT) Received: from localhost.localdomain (adsl-41.37.6.162.tellas.gr. [37.6.162.41]) by smtp.gmail.com with ESMTPSA id o2-20020a5d4742000000b003063a92bbf5sm1294816wrs.70.2023.07.20.05.58.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Jul 2023 05:58:36 -0700 (PDT) From: Emmanouil Pitsidianakis To: qemu-devel@nongnu.org Cc: Emmanouil Pitsidianakis , "Igor Skalkin" , "Anton Yakovlev" , "Paolo Bonzini" , "Gerd Hoffmann" , "Michael S. Tsirkin" , "Marcel Apfelbaum" , =?utf-8?q?Daniel_P=2E_Berr?= =?utf-8?q?ang=C3=A9?= , "Eduardo Habkost" , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Volker_R=C3=BCmelin?= , =?utf-8?b?S8WRdsOh?= =?utf-8?b?Z8OzLCBab2x0w6Fu?= , "Alex Bennee" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH v4 11/12] virtio-sound: implement audio output (TX) Date: Thu, 20 Jul 2023 15:57:12 +0300 Message-Id: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32e; envelope-from=manos.pitsidianakis@linaro.org; helo=mail-wm1-x32e.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Handle output IO messages in the transmit (TX) virtqueue. It allocates a VirtIOSoundPCMBlock for each IO message and copies the data buffer to it. When the IO buffer is written to the host's sound card, the guest will be notified that it has been consumed. The lifetime of an IO message is: 1. Guest sends IO message to TX virtqueue. 2. QEMU adds it to the appropriate stream's IO buffer queue. 3. Sometime later, the host audio backend calls the output callback, virtio_snd_pcm_out_cb(), which is defined with an AUD_open_out() call. The callback gets an available number of bytes the backend can receive. Then it writes data from the IO buffer queue to the backend. If at any time a buffer is exhausted, it is returned to the guest as completed. 4. If the guest releases the stream, its buffer queue is flushed by attempting to write any leftover data to the audio backend and releasing all IO messages back to the guest. This is how according to the spec the guest knows the release was successful. Signed-off-by: Emmanouil Pitsidianakis --- hw/virtio/trace-events | 2 + hw/virtio/virtio-snd.c | 254 ++++++++++++++++++++++++++++++++- include/hw/virtio/virtio-snd.h | 11 ++ 3 files changed, 260 insertions(+), 7 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 60ab62a80d..3b95e745c2 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -171,3 +171,5 @@ virtio_snd_handle_pcm_release(uint32_t stream) "VIRTIO_SND_PCM_RELEASE called fo virtio_snd_handle_code(uint32_t val, const char *code) "ctrl code msg val = %"PRIu32" == %s" virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called" virtio_snd_handle_event(void) "event queue callback called" +virtio_snd_pcm_stream_flush(uint32_t stream) "flushing stream %"PRIu32 +virtio_snd_handle_xfer(void) "tx/rx queue callback called" diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c index e87783c38a..21983d9b8c 100644 --- a/hw/virtio/virtio-snd.c +++ b/hw/virtio/virtio-snd.c @@ -30,6 +30,15 @@ #define VIRTIO_SOUND_CHMAP_DEFAULT 0 #define VIRTIO_SOUND_HDA_FN_NID 0 +static void virtio_snd_pcm_out_cb(void *data, int available); +static void virtio_snd_process_cmdq(VirtIOSound *s); +static void virtio_snd_pcm_flush(VirtIOSoundPCMStream *stream); +static uint32_t +virtio_snd_pcm_read_write(VirtIOSoundPCMStream *stream, + VirtQueue *vq, + VirtQueueElement *element, + bool read); + static uint32_t supported_formats = BIT(VIRTIO_SND_PCM_FMT_S8) | BIT(VIRTIO_SND_PCM_FMT_U8) | BIT(VIRTIO_SND_PCM_FMT_S16) @@ -416,6 +425,17 @@ static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound *s, uint32_t stream_id) stream->positions[0] = VIRTIO_SND_CHMAP_FL; stream->positions[1] = VIRTIO_SND_CHMAP_FR; + if (stream->direction == VIRTIO_SND_D_OUTPUT) { + stream->voice.out = AUD_open_out(&s->card, + stream->voice.out, + "virtio_snd_card", + stream, + virtio_snd_pcm_out_cb, + &as); + } else { + qemu_log_mask(LOG_UNIMP, "virtio_snd: input/capture is unimplemented."); + } + stream->as = as; stream->desired_as = stream->as; qemu_mutex_init(&stream->queue_mutex); @@ -475,12 +495,35 @@ static void virtio_snd_handle_pcm_start_stop(VirtIOSound *s, "VIRTIO_SND_R_PCM_STOP", req.stream_id); stream = virtio_snd_pcm_get_stream(s, req.stream_id); - if (!stream) { + if (stream) { + if (stream->direction == VIRTIO_SND_D_OUTPUT) { + AUD_set_active_out(stream->voice.out, start); + } + } else { error_report("Invalid stream id: %"PRIu32, req.stream_id); cmd->resp.code = VIRTIO_SND_S_BAD_MSG; } } +/* + * Returns the number of bytes that have not been passed to AUD_write yet. + * + * @stream: VirtIOSoundPCMStream + */ +static size_t virtio_snd_pcm_get_pending_bytes(VirtIOSoundPCMStream *stream) +{ + VirtIOSoundPCMBlock *block; + VirtIOSoundPCMBlock *next; + size_t size = 0; + + WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) { + QSIMPLEQ_FOREACH_SAFE(block, &stream->queue, entry, next) { + size += block->size; + } + } + return size; +} + /* * Releases the buffer resources allocated to a stream. Seperated from the * handler so that the code can be reused in the unrealize function. Returns @@ -492,6 +535,21 @@ static void virtio_snd_handle_pcm_start_stop(VirtIOSound *s, static uint32_t virtio_snd_pcm_release_impl(VirtIOSoundPCMStream *stream, uint32_t stream_id) { + if (virtio_snd_pcm_get_pending_bytes(stream)) { + /* + * virtio-v1.2-csd01, 5.14.6.6.5.1, + * Device Requirements: Stream Release + * + * - The device MUST complete all pending I/O messages for the + * specified stream ID. + * - The device MUST NOT complete the control request while there + * are pending I/O messages for the specified stream ID. + */ + virtio_snd_process_cmdq(stream->s); + trace_virtio_snd_pcm_stream_flush(stream_id); + virtio_snd_pcm_flush(stream); + } + return VIRTIO_SND_S_OK; } @@ -676,6 +734,79 @@ static void virtio_snd_handle_event(VirtIODevice *vdev, VirtQueue *vq) trace_virtio_snd_handle_event(); } +/* + * The tx virtqueue handler. Makes the buffers available to their respective + * streams for consumption. + * + * @vdev: VirtIOSound device + * @vq: tx virtqueue + */ +static void virtio_snd_handle_tx(VirtIODevice *vdev, VirtQueue *vq) +{ + VirtIOSound *s = VIRTIO_SND(vdev); + VirtIOSoundPCMStream *stream = NULL; + VirtQueueElement *elem; + size_t sz; + virtio_snd_pcm_xfer hdr; + virtio_snd_pcm_status resp = { 0 }; + + trace_virtio_snd_handle_xfer(); + + for (;;) { + elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); + if (!elem) { + break; + } + /* get the message hdr object */ + sz = iov_to_buf(elem->out_sg, + elem->out_num, + 0, + &hdr, + sizeof(hdr)); + if (sz != sizeof(hdr) + || hdr.stream_id >= s->snd_conf.streams + || !s->pcm->streams[hdr.stream_id]) { + goto tx_err; + } + + stream = s->pcm->streams[hdr.stream_id]; + if (stream->direction == VIRTIO_SND_D_INPUT) { + goto tx_err; + } + + WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) { + virtio_snd_pcm_read_write(stream, + vq, + elem, + hdr.stream_id == VIRTIO_SND_D_INPUT); + + resp.status = VIRTIO_SND_S_OK; + iov_from_buf(elem->in_sg, + elem->in_num, + 0, + &resp, + sizeof(resp)); + } + continue; + +tx_err: + WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) { + resp.status = VIRTIO_SND_S_BAD_MSG; + iov_from_buf(elem->in_sg, + elem->in_num, + 0, + &resp, + sizeof(resp)); + } + } + + /* + * Notify vq about virtio_snd_pcm_status responses. + * Buffer responses must be notified separately later. + */ + virtio_notify(VIRTIO_DEVICE(s), vq); +} + /* * Stub buffer virtqueue handler. * @@ -806,7 +937,7 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp) virtio_snd_common_realize(dev, virtio_snd_handle_ctrl, virtio_snd_handle_event, - virtio_snd_handle_xfer, + virtio_snd_handle_tx, virtio_snd_handle_xfer, &err); if (err != NULL) { @@ -814,6 +945,73 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp) } } +/* + * AUD_* output callback. + * + * @data: VirtIOSoundPCMStream stream + * @available: number of bytes that can be written with AUD_write() + */ +static void virtio_snd_pcm_out_cb(void *data, int available) +{ + VirtIOSoundPCMStream *stream = data; + VirtIOSoundPCMBlock *block; + VirtIOSoundPCMBlock *next; + size_t size; + + WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) { + QSIMPLEQ_FOREACH_SAFE(block, &stream->queue, entry, next) { + for (;;) { + size = MIN(block->size, available); + size = AUD_write(stream->voice.out, + block->data + block->offset, + size); + block->size -= size; + block->offset += size; + if (!block->size) { + virtqueue_push(block->vq, + block->elem, + sizeof(block->elem)); + virtio_notify(VIRTIO_DEVICE(stream->s), + block->vq); + QSIMPLEQ_REMOVE_HEAD(&stream->queue, entry); + g_free(block); + available -= size; + break; + } + + available -= size; + if (!available) { + break; + } + } + if (!available) { + break; + } + } + } +} + +/* + * Flush all buffer data from this stream's queue into the driver's virtual + * queue. + * + * @stream: VirtIOSoundPCMStream *stream + */ +static void virtio_snd_pcm_flush(VirtIOSoundPCMStream *stream) +{ + VirtIOSoundPCMBlock *block; + VirtIOSoundPCMBlock *next; + + WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) { + QSIMPLEQ_FOREACH_SAFE(block, &stream->queue, entry, next) { + AUD_write(stream->voice.out, block->data, block->size); + virtqueue_push(block->vq, block->elem, sizeof(block->elem)); + virtio_notify(VIRTIO_DEVICE(stream->s), block->vq); + QSIMPLEQ_REMOVE(&stream->queue, block, VirtIOSoundPCMBlock, entry); + } + } +} + /* * Close the sound card. * @@ -822,6 +1020,10 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp) static void virtio_snd_pcm_close(VirtIOSoundPCMStream *stream) { virtio_snd_process_cmdq(stream->s); + if (stream->direction == VIRTIO_SND_D_OUTPUT) { + AUD_close_out(&stream->pcm->snd->card, stream->voice.out); + stream->voice.out = NULL; + } } static void virtio_snd_unrealize(DeviceState *dev) @@ -835,17 +1037,55 @@ static void virtio_snd_unrealize(DeviceState *dev) trace_virtio_snd_unrealize(vsnd); - for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) { - stream = vsnd->pcm->streams[i]; - virtio_snd_pcm_close(stream); - g_free(stream); + if (vsnd->pcm) { + if (vsnd->pcm->streams) { + for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) { + stream = vsnd->pcm->streams[i]; + if (stream) { + virtio_snd_pcm_close(stream); + g_free(stream); + } + } + g_free(vsnd->pcm->streams); + g_free(vsnd->pcm->pcm_params); + g_free(vsnd->pcm->jacks); + } + + g_free(vsnd->pcm); } + + vsnd->pcm = NULL; AUD_remove_card(&vsnd->card); - g_free(vsnd->pcm); virtio_cleanup(vdev); } +static uint32_t +virtio_snd_pcm_read_write(VirtIOSoundPCMStream *stream, + VirtQueue *vq, + VirtQueueElement *element, + bool read) +{ + VirtIOSoundPCMBlock *fragment; + size_t size = iov_size(element->out_sg, element->out_num) - + sizeof(virtio_snd_pcm_xfer); + + fragment = g_malloc0(sizeof(VirtIOSoundPCMBlock) + size); + fragment->elem = element; + fragment->vq = vq; + fragment->size = size; + fragment->offset = 0; + + iov_to_buf(element->out_sg, element->out_num, + sizeof(virtio_snd_pcm_xfer), + fragment->data, + size); + + QSIMPLEQ_INSERT_TAIL(&stream->queue, fragment, entry); + + return fragment->size; +} + static void virtio_snd_reset(VirtIODevice *vdev) { VirtIOSound *s = VIRTIO_SND(vdev); diff --git a/include/hw/virtio/virtio-snd.h b/include/hw/virtio/virtio-snd.h index 1a9835841d..156e1f5edd 100644 --- a/include/hw/virtio/virtio-snd.h +++ b/include/hw/virtio/virtio-snd.h @@ -81,6 +81,8 @@ typedef struct VirtIOSoundPCMParams VirtIOSoundPCMParams; typedef struct VirtIOSoundPCM VirtIOSoundPCM; +typedef struct VirtIOSoundPCMBlock VirtIOSoundPCMBlock; + /* Stream params */ struct VirtIOSoundPCMParams { uint32_t features; @@ -91,6 +93,15 @@ struct VirtIOSoundPCMParams { uint8_t rate; }; +struct VirtIOSoundPCMBlock { + QSIMPLEQ_ENTRY(VirtIOSoundPCMBlock) entry; + VirtQueueElement *elem; + VirtQueue *vq; + size_t size; + uint64_t offset; + uint8_t data[]; +}; + struct VirtIOSoundPCM { VirtIOSound *snd; VirtIOSoundPCMParams **pcm_params; From patchwork Thu Jul 20 12:57:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manos Pitsidianakis X-Patchwork-Id: 13320472 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B2FEDEB64DA for ; Thu, 20 Jul 2023 12:59:27 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qMTF9-00070o-Pj; Thu, 20 Jul 2023 08:58:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qMTF8-0006x4-ON for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:54 -0400 Received: from mail-wm1-x330.google.com ([2a00:1450:4864:20::330]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qMTEw-0004gj-EU for qemu-devel@nongnu.org; Thu, 20 Jul 2023 08:58:54 -0400 Received: by mail-wm1-x330.google.com with SMTP id 5b1f17b1804b1-3fb4146e8fcso5165045e9.0 for ; Thu, 20 Jul 2023 05:58:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689857920; x=1690462720; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Rlc4/bZY1atq5k/gBLdHXzivnoy0MLFLopl4wrA30pU=; b=pkAebfsTDYVEnRo92puq2TfyAeEBWdt9l01YXv/HqGuKR9ch1E3QBDjZZ64JBJSxn0 9qhf83YDomxocmiPAwMZrz1ROlTeMZczGUivi8X9aY6EAuiKKJzCcX/ClN74br7mq+qU rFUQjjNUY7TweClA3XUjcspPL/aRIroQ2JZwTY79tJThJdOR3PV7+piVkanYHnL34iU7 cNejotwOqnoeQeg/Mvpx5Bh2YGpqtmkP+4fyaUninpsARUaaR2u44Mxqtb3xkiseA0+j c7PpqJgYERHr2dyOmqOYIoZSPgiW73f0pPZc2cwt0Fo1TUiVKNFdgzMlBzF2GeDax1A+ IpAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689857920; x=1690462720; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Rlc4/bZY1atq5k/gBLdHXzivnoy0MLFLopl4wrA30pU=; b=kvWSyrKJnqEQZXA7lkicyBOn/3eAFKzcLvuJu+ZrgSY6loAT1Nq4qmKrl3gfFFy30M whqTL2asvcYKUBuocfL5DYI3ZZc1VCfQU1PlLnYYHQHefra3d2CIabIMdTh9D3Il7S4z hldljh7/WLtiZVu+4yeqQVJVdQvVxoo98/mwlgTVYqN4m8+Sp2yJkdwawMr8fLfDmKix ZYgQFFe1OV8Oyz1MWc3niwCNNlu61wWZhSVD4veqec0fEa0ZKeUicUCRYVss6z3Tl+XF 27NAjYrtez45/FwsyUYdnrtEf7G4w2xXzRmTpxWZSkz9Bxc3ZvYhJmrYseEknYdom0TV Cz5g== X-Gm-Message-State: ABy/qLavh4PWuiPs/qLUMDgmIP8QFKj/GW5nYUpAN2F612J+7etlOFmn 3S5XioauPMl4kCRbf1PHXPnZJmaMTE1ZGvmY2sk4Gw== X-Google-Smtp-Source: APBJJlHSRGiDBv3Er7aLY5wBzKCCrXwAhHYfRVkPjoo6FbVNXfEXvrGSwpdLL1diRP87T6jNDvJ12A== X-Received: by 2002:a05:600c:204:b0:3fc:6e8:d675 with SMTP id 4-20020a05600c020400b003fc06e8d675mr4533955wmi.13.1689857920113; Thu, 20 Jul 2023 05:58:40 -0700 (PDT) Received: from localhost.localdomain (adsl-41.37.6.162.tellas.gr. [37.6.162.41]) by smtp.gmail.com with ESMTPSA id o2-20020a5d4742000000b003063a92bbf5sm1294816wrs.70.2023.07.20.05.58.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Jul 2023 05:58:39 -0700 (PDT) From: Emmanouil Pitsidianakis To: qemu-devel@nongnu.org Cc: Emmanouil Pitsidianakis , "Igor Skalkin" , "Anton Yakovlev" , "Paolo Bonzini" , "Gerd Hoffmann" , "Michael S. Tsirkin" , "Marcel Apfelbaum" , =?utf-8?q?Daniel_P=2E_Berr?= =?utf-8?q?ang=C3=A9?= , "Eduardo Habkost" , =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Volker_R=C3=BCmelin?= , =?utf-8?b?S8WRdsOh?= =?utf-8?b?Z8OzLCBab2x0w6Fu?= , "Alex Bennee" , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PATCH v4 12/12] virtio-sound: implement audio capture (RX) Date: Thu, 20 Jul 2023 15:57:13 +0300 Message-Id: <1abb69dd05d18f9966bd7a959013dbc1ed07e627.1689857559.git.manos.pitsidianakis@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::330; envelope-from=manos.pitsidianakis@linaro.org; helo=mail-wm1-x330.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org To perform audio capture we duplicate the TX logic of the previous commit with the following difference: we receive data from the QEMU audio backend and write it in the virt queue IO buffers the guest sends to QEMU. When they are full (i.e. they have `period_bytes` amount of data) or when recording stops in QEMU's audio backend, the buffer is returned to the guest by notifying it. Signed-off-by: Emmanouil Pitsidianakis --- hw/virtio/trace-events | 3 +- hw/virtio/virtio-snd.c | 230 +++++++++++++++++++++++++++++++++++------ 2 files changed, 200 insertions(+), 33 deletions(-) diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 3b95e745c2..a5829b112c 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -172,4 +172,5 @@ virtio_snd_handle_code(uint32_t val, const char *code) "ctrl code msg val = %"PR virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called" virtio_snd_handle_event(void) "event queue callback called" virtio_snd_pcm_stream_flush(uint32_t stream) "flushing stream %"PRIu32 -virtio_snd_handle_xfer(void) "tx/rx queue callback called" +virtio_snd_handle_tx_xfer(void) "tx queue callback called" +virtio_snd_handle_rx_xfer(void) "tx queue callback called" diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c index 21983d9b8c..0643246434 100644 --- a/hw/virtio/virtio-snd.c +++ b/hw/virtio/virtio-snd.c @@ -26,18 +26,21 @@ #define VIRTIO_SOUND_VM_VERSION 1 #define VIRTIO_SOUND_JACK_DEFAULT 0 -#define VIRTIO_SOUND_STREAM_DEFAULT 1 +#define VIRTIO_SOUND_STREAM_DEFAULT 2 #define VIRTIO_SOUND_CHMAP_DEFAULT 0 #define VIRTIO_SOUND_HDA_FN_NID 0 static void virtio_snd_pcm_out_cb(void *data, int available); static void virtio_snd_process_cmdq(VirtIOSound *s); -static void virtio_snd_pcm_flush(VirtIOSoundPCMStream *stream); -static uint32_t -virtio_snd_pcm_read_write(VirtIOSoundPCMStream *stream, - VirtQueue *vq, - VirtQueueElement *element, - bool read); +static void virtio_snd_pcm_out_flush(VirtIOSoundPCMStream *stream); +static void virtio_snd_pcm_in_flush(VirtIOSoundPCMStream *stream); +static void virtio_snd_pcm_in_cb(void *data, int available); +static uint32_t virtio_snd_pcm_write(VirtIOSoundPCMStream *stream, + VirtQueue *vq, + VirtQueueElement *element); +static uint32_t virtio_snd_pcm_read(VirtIOSoundPCMStream *stream, + VirtQueue *vq, + VirtQueueElement *element); static uint32_t supported_formats = BIT(VIRTIO_SND_PCM_FMT_S8) | BIT(VIRTIO_SND_PCM_FMT_U8) @@ -433,7 +436,12 @@ static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound *s, uint32_t stream_id) virtio_snd_pcm_out_cb, &as); } else { - qemu_log_mask(LOG_UNIMP, "virtio_snd: input/capture is unimplemented."); + stream->voice.in = AUD_open_in(&s->card, + stream->voice.in, + "virtio_snd_card", + stream, + virtio_snd_pcm_in_cb, + &as); } stream->as = as; @@ -498,6 +506,8 @@ static void virtio_snd_handle_pcm_start_stop(VirtIOSound *s, if (stream) { if (stream->direction == VIRTIO_SND_D_OUTPUT) { AUD_set_active_out(stream->voice.out, start); + } else { + AUD_set_active_in(stream->voice.in, start); } } else { error_report("Invalid stream id: %"PRIu32, req.stream_id); @@ -547,7 +557,11 @@ static uint32_t virtio_snd_pcm_release_impl(VirtIOSoundPCMStream *stream, */ virtio_snd_process_cmdq(stream->s); trace_virtio_snd_pcm_stream_flush(stream_id); - virtio_snd_pcm_flush(stream); + if (stream->direction == VIRTIO_SND_D_OUTPUT) { + virtio_snd_pcm_out_flush(stream); + } else { + virtio_snd_pcm_in_flush(stream); + } } return VIRTIO_SND_S_OK; @@ -741,7 +755,7 @@ static void virtio_snd_handle_event(VirtIODevice *vdev, VirtQueue *vq) * @vdev: VirtIOSound device * @vq: tx virtqueue */ -static void virtio_snd_handle_tx(VirtIODevice *vdev, VirtQueue *vq) +static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq) { VirtIOSound *s = VIRTIO_SND(vdev); VirtIOSoundPCMStream *stream = NULL; @@ -750,7 +764,7 @@ static void virtio_snd_handle_tx(VirtIODevice *vdev, VirtQueue *vq) virtio_snd_pcm_xfer hdr; virtio_snd_pcm_status resp = { 0 }; - trace_virtio_snd_handle_xfer(); + trace_virtio_snd_handle_tx_xfer(); for (;;) { elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); @@ -774,11 +788,11 @@ static void virtio_snd_handle_tx(VirtIODevice *vdev, VirtQueue *vq) goto tx_err; } + assert(hdr.stream_id != VIRTIO_SND_D_INPUT); WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) { - virtio_snd_pcm_read_write(stream, + virtio_snd_pcm_write(stream, vq, - elem, - hdr.stream_id == VIRTIO_SND_D_INPUT); + elem); resp.status = VIRTIO_SND_S_OK; iov_from_buf(elem->in_sg, @@ -808,12 +822,54 @@ tx_err: } /* - * Stub buffer virtqueue handler. + * The rx virtqueue handler. Makes the buffers available to their respective + * streams for consumption. * * @vdev: VirtIOSound device - * @vq: virtqueue + * @vq: tx virtqueue */ -static void virtio_snd_handle_xfer(VirtIODevice *vdev, VirtQueue *vq) {} +static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq) +{ + VirtIOSound *s = VIRTIO_SND(vdev); + VirtIOSoundPCMStream *stream = NULL; + VirtQueueElement *elem; + size_t sz; + virtio_snd_pcm_xfer hdr; + + trace_virtio_snd_handle_rx_xfer(); + + for (;;) { + elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); + if (!elem) { + break; + } + /* get the message hdr object */ + sz = iov_to_buf(elem->out_sg, + elem->out_num, + 0, + &hdr, + sizeof(hdr)); + if (sz != sizeof(hdr) + || hdr.stream_id >= s->snd_conf.streams + || !s->pcm->streams[hdr.stream_id]) { + continue; + } + + stream = s->pcm->streams[hdr.stream_id]; + if (stream->direction == VIRTIO_SND_D_OUTPUT) { + continue; + } + WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) { + virtio_snd_pcm_read(stream, vq, elem); + } + } + + /* + * Notify vq about virtio_snd_pcm_status responses. + * Buffer responses must be notified separately later. + */ + virtio_notify(VIRTIO_DEVICE(s), vq); +} static uint64_t get_features(VirtIODevice *vdev, uint64_t features, Error **errp) @@ -937,8 +993,8 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp) virtio_snd_common_realize(dev, virtio_snd_handle_ctrl, virtio_snd_handle_event, - virtio_snd_handle_tx, - virtio_snd_handle_xfer, + virtio_snd_handle_tx_xfer, + virtio_snd_handle_rx_xfer, &err); if (err != NULL) { error_propagate(errp, err); @@ -992,26 +1048,119 @@ static void virtio_snd_pcm_out_cb(void *data, int available) } /* - * Flush all buffer data from this stream's queue into the driver's virtual - * queue. + * AUD_* input callback. * - * @stream: VirtIOSoundPCMStream *stream + * @data: VirtIOSoundPCMStream stream + * @available: number of bytes that can be read with AUD_read() */ -static void virtio_snd_pcm_flush(VirtIOSoundPCMStream *stream) +static void virtio_snd_pcm_in_cb(void *data, int available) { + VirtIOSoundPCMStream *stream = data; VirtIOSoundPCMBlock *block; - VirtIOSoundPCMBlock *next; + uint32_t sz; + virtio_snd_pcm_status resp = { 0 }; + size_t size; WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) { - QSIMPLEQ_FOREACH_SAFE(block, &stream->queue, entry, next) { - AUD_write(stream->voice.out, block->data, block->size); - virtqueue_push(block->vq, block->elem, sizeof(block->elem)); - virtio_notify(VIRTIO_DEVICE(stream->s), block->vq); - QSIMPLEQ_REMOVE(&stream->queue, block, VirtIOSoundPCMBlock, entry); + while (!QSIMPLEQ_EMPTY(&stream->queue)) { + block = QSIMPLEQ_FIRST(&stream->queue); + + for (;;) { + size = AUD_read(stream->voice.in, + block->data + block->offset, + MIN(stream->period_bytes - block->offset, available)); + block->offset += size; + block->size += size; + if (size == 0 || block->size >= stream->period_bytes) { + resp.status = VIRTIO_SND_S_OK; + sz = iov_from_buf(block->elem->in_sg, + block->elem->in_num, + 0, + &resp, + sizeof(resp)); + + /* Copy data -if any- to guest */ + if (block->size) { + iov_from_buf(block->elem->in_sg, + block->elem->in_num, + sz, + &block->data, + MIN(stream->period_bytes, block->size)); + } + virtqueue_push(block->vq, + block->elem, + sizeof(block->elem)); + virtio_notify(VIRTIO_DEVICE(stream->s), + block->vq); + QSIMPLEQ_REMOVE_HEAD(&stream->queue, entry); + g_free(block); + available -= size; + break; + } + + available -= size; + if (!available) { + break; + } + } + if (!available) { + break; + } } } } +#define virtio_snd_pcm_flush(AUD_CB) \ + VirtIOSoundPCMBlock *block; \ + VirtIOSoundPCMBlock *next; \ + WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) { \ + QSIMPLEQ_FOREACH_SAFE(block, &stream->queue, entry, next) { \ + do { \ + AUD_CB; \ + } while (0) \ + ; \ + virtqueue_push(block->vq, block->elem, sizeof(block->elem));\ + virtio_notify(VIRTIO_DEVICE(stream->s), block->vq); \ + QSIMPLEQ_REMOVE(&stream->queue, \ + block, \ + VirtIOSoundPCMBlock, \ + entry); \ + } \ + } \ + + +/* + * Flush all buffer data from this output stream's queue into the driver's + * virtual queue. + * + * @stream: VirtIOSoundPCMStream *stream + */ +static void virtio_snd_pcm_out_flush(VirtIOSoundPCMStream *stream) +{ + virtio_snd_pcm_flush( + AUD_write(stream->voice.out, + block->data, + block->size); + ); +} + +/* + * Flush all buffer data from this input stream's queue into the driver's + * virtual queue. + * + * @stream: VirtIOSoundPCMStream *stream + */ +static void virtio_snd_pcm_in_flush(VirtIOSoundPCMStream *stream) +{ + virtio_snd_pcm_flush( + iov_from_buf(block->elem->in_sg, + block->elem->in_num, + sizeof(virtio_snd_pcm_info), + block->data, + block->offset); + ); +} + /* * Close the sound card. * @@ -1061,10 +1210,9 @@ static void virtio_snd_unrealize(DeviceState *dev) static uint32_t -virtio_snd_pcm_read_write(VirtIOSoundPCMStream *stream, +virtio_snd_pcm_write(VirtIOSoundPCMStream *stream, VirtQueue *vq, - VirtQueueElement *element, - bool read) + VirtQueueElement *element) { VirtIOSoundPCMBlock *fragment; size_t size = iov_size(element->out_sg, element->out_num) - @@ -1086,6 +1234,24 @@ virtio_snd_pcm_read_write(VirtIOSoundPCMStream *stream, return fragment->size; } +static uint32_t +virtio_snd_pcm_read(VirtIOSoundPCMStream *stream, + VirtQueue *vq, + VirtQueueElement *element) +{ + VirtIOSoundPCMBlock *fragment; + + fragment = g_malloc0(sizeof(VirtIOSoundPCMBlock) + stream->period_bytes); + fragment->elem = element; + fragment->vq = vq; + fragment->size = 0; + fragment->offset = 0; + + QSIMPLEQ_INSERT_TAIL(&stream->queue, fragment, entry); + + return fragment->size; +} + static void virtio_snd_reset(VirtIODevice *vdev) { VirtIOSound *s = VIRTIO_SND(vdev);