This patch series adds an audio device implementing the recent virtio sound spec (1.2) and a corresponding PCI wrapper device.
https://github.com/epilys/qemu-virtio-snd/tree/sound-v6 Main differences with v4 patch [^v4] <cover.1689857559.git.manos.pitsidiana...@linaro.org>: - Use ERRP_GUARD() to propagate errors. - Use virtio_add_feature() instead of XORing constants. - Use %zu format specifier for size_t. [^v4]: https://lore.kernel.org/qemu-devel/cover.1689857559.git.manos.pitsidiana...@linaro.org/ Previously: [^v3]: https://lore.kernel.org/qemu-devel/cover.1689692765.git.manos.pitsidiana...@linaro.org/ Emmanouil Pitsidianakis (12): Add virtio-sound device stub Add virtio-sound-pci device virtio-sound: handle control messages and streams virtio-sound: set PCM stream parameters virtio-sound: prepare PCM streams virtio-sound: handle VIRTIO_SND_R_PCM_INFO request virtio-sound: handle VIRTIO_SND_R_PCM_{START,STOP} virtio-sound: handle VIRTIO_SND_PCM_SET_PARAMS virtio-sound: handle VIRTIO_SND_R_PCM_PREPARE virtio-sound: handle VIRTIO_SND_PCM_RELEASE virtio-sound: implement audio output (TX) virtio-sound: implement audio capture (RX) MAINTAINERS | 6 + hw/virtio/Kconfig | 5 + hw/virtio/meson.build | 2 + hw/virtio/trace-events | 20 + hw/virtio/virtio-snd-pci.c | 91 +++ hw/virtio/virtio-snd.c | 1300 ++++++++++++++++++++++++++++++++ include/hw/pci/pci.h | 1 + include/hw/virtio/virtio-snd.h | 158 ++++ softmmu/qdev-monitor.c | 1 + 9 files changed, 1584 insertions(+) create mode 100644 hw/virtio/virtio-snd-pci.c create mode 100644 hw/virtio/virtio-snd.c create mode 100644 include/hw/virtio/virtio-snd.h Range-diff against v4: 1: ae372de565 ! 1: 899b9a06bb Add virtio-sound device stub @@ hw/virtio/virtio-snd.c (new) + * Feature Bits + * None currently defined. + */ ++ VirtIOSound *s = VIRTIO_SND(vdev); ++ features |= s->features; ++ + trace_virtio_snd_get_features(vdev, features); -+ return features | 1UL << VIRTIO_F_VERSION_1 | 1UL << VIRTIO_F_IN_ORDER; ++ ++ return features; +} + +static void virtio_snd_common_realize(DeviceState *dev, @@ hw/virtio/virtio-snd.c (new) + VirtIOSound *vsnd = VIRTIO_SND(dev); + + virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config)); ++ virtio_add_feature(&vsnd->features, VIRTIO_F_VERSION_1); + + /* set number of jacks and streams */ + if (vsnd->snd_conf.jacks > 8) { @@ hw/virtio/virtio-snd.c (new) + +static void virtio_snd_realize(DeviceState *dev, Error **errp) +{ ++ ERRP_GUARD(); + VirtIOSound *vsnd = VIRTIO_SND(dev); -+ Error *err = NULL; + + vsnd->vmstate = + qemu_add_vm_change_state_handler(virtio_snd_vm_state_change, vsnd); @@ hw/virtio/virtio-snd.c (new) + virtio_snd_handle_queue, + virtio_snd_handle_queue, + virtio_snd_handle_queue, -+ &err); -+ if (err != NULL) { -+ error_propagate(errp, err); -+ return; -+ } ++ errp); +} + +static void virtio_snd_unrealize(DeviceState *dev) @@ include/hw/virtio/virtio-snd.h (new) +typedef struct VirtIOSound { + VirtIODevice parent_obj; + VirtQueue *queues[VIRTIO_SND_VQ_MAX]; ++ uint64_t features; + QEMUSoundCard card; + VMChangeStateEntry *vmstate; + virtio_snd_config snd_conf; 2: 5cde5472ea = 2: 035be510f8 Add virtio-sound-pci device 3: dc65cac2f4 ! 3: e6a3624f89 virtio-sound: handle control messages and streams @@ hw/virtio/virtio-snd.c: virtio_snd_set_config(VirtIODevice *vdev, const uint8_t static uint64_t get_features(VirtIODevice *vdev, uint64_t features, Error **errp) @@ hw/virtio/virtio-snd.c: static uint64_t get_features(VirtIODevice *vdev, uint64_t features, - return features | 1UL << VIRTIO_F_VERSION_1 | 1UL << VIRTIO_F_IN_ORDER; + return features; } +static void virtio_snd_set_pcm(VirtIOSound *snd) @@ hw/virtio/virtio-snd.c: static void virtio_snd_common_realize(DeviceState *dev, + virtio_snd_set_pcm(vsnd); + virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config)); + virtio_add_feature(&vsnd->features, VIRTIO_F_VERSION_1); - /* set number of jacks and streams */ @@ hw/virtio/virtio-snd.c: 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); @@ hw/virtio/virtio-snd.c: static void virtio_snd_common_realize(DeviceState *dev, static void @@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error **errp) + ERRP_GUARD(); VirtIOSound *vsnd = VIRTIO_SND(dev); - Error *err = NULL; + vsnd->pcm = NULL; vsnd->vmstate = @@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error * + virtio_snd_handle_event, + virtio_snd_handle_xfer, + virtio_snd_handle_xfer, - &err); - if (err != NULL) { - error_propagate(errp, err); -- return; - } + errp); } +/* @@ include/hw/virtio/virtio-snd.h: typedef struct virtio_snd_pcm_xfer virtio_snd_pc +struct VirtIOSound { VirtIODevice parent_obj; VirtQueue *queues[VIRTIO_SND_VQ_MAX]; + uint64_t features; + VirtIOSoundPCM *pcm; QEMUSoundCard card; VMChangeStateEntry *vmstate; 4: bbd1799fc9 = 4: 82c80e2ae4 virtio-sound: set PCM stream parameters 5: 68a13c4385 = 5: 19d95e8411 virtio-sound: prepare PCM streams 6: f267d41957 ! 6: 78777fb46f virtio-sound: handle VIRTIO_SND_R_PCM_INFO request @@ hw/virtio/virtio-snd.c: static VirtIOSoundPCMParams *virtio_snd_pcm_get_params(V + + 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", ++ error_report("pcm info: buffer too small, got: %zu, needed: %zu", + iov_size(cmd->elem->in_sg, cmd->elem->in_num), + sizeof(virtio_snd_pcm_info)); + cmd->resp.code = VIRTIO_SND_S_BAD_MSG; 7: 5939a6161e = 7: 7641e21ee8 virtio-sound: handle VIRTIO_SND_R_PCM_{START,STOP} 8: 8f78d3a132 = 8: 48f9b776f5 virtio-sound: handle VIRTIO_SND_PCM_SET_PARAMS 9: d2b3854084 = 9: cdb8ab3ee2 virtio-sound: handle VIRTIO_SND_R_PCM_PREPARE 10: 4e14b2d129 = 10: bbc11d0348 virtio-sound: handle VIRTIO_SND_PCM_RELEASE 11: 65442a1cd1 ! 11: d5fb4b058c virtio-sound: implement audio output (TX) @@ Metadata ## Commit message ## virtio-sound: implement audio output (TX) - Handle output IO messages in the receive (RX) virtqueue. + 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 @@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error * - virtio_snd_handle_xfer, + virtio_snd_handle_tx, virtio_snd_handle_xfer, - &err); - if (err != NULL) { -@@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error **errp) - } + errp); } +/* 12: aeb0caf7dc ! 12: e2c30e2a21 virtio-sound: implement audio capture (RX) @@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error * - virtio_snd_handle_xfer, + virtio_snd_handle_tx_xfer, + virtio_snd_handle_rx_xfer, - &err); - if (err != NULL) { - error_propagate(errp, err); + errp); + } + @@ hw/virtio/virtio-snd.c: static void virtio_snd_pcm_out_cb(void *data, int available) } base-commit: ccb86f079a9e4d94918086a9df18c1844347aff8 -- 2.39.2