aboutsummaryrefslogtreecommitdiffstats
path: root/vhost_user_sound.c
diff options
context:
space:
mode:
authorTimos Ampelikiotis <t.ampelikiotis@virtualopensystems.com>2024-10-01 18:16:29 +0300
committerTimos Ampelikiotis <t.ampelikiotis@virtualopensystems.com>2024-10-01 15:36:35 +0000
commit9941dec970111be9e02dcaf6819c037946bde160 (patch)
treebea826b7fc861fe09c53d43f60d1a7d464e4cf9b /vhost_user_sound.c
parent1cc834724919caf5ea21c146b29f62b6cd213db7 (diff)
Add multiple-device support virtio-loopback-adapter
Updates [v1]: - The adapter supports multiple vhost-user devices running in parallel. - Redesign the devices interfaces. Unified their common functionality and add it into vhost-user-loopback lib. This eases the addition of new vhost-user devices and makes the virtio-loopback adapter more device agnostic. Bug-AGL: SPEC-4834 Change-Id: I9aff91dce0207ccdd8c2d1c5d0769a13b4e9ae04 Signed-off-by: Timos Ampelikiotis <t.ampelikiotis@virtualopensystems.com>
Diffstat (limited to 'vhost_user_sound.c')
-rw-r--r--vhost_user_sound.c322
1 files changed, 0 insertions, 322 deletions
diff --git a/vhost_user_sound.c b/vhost_user_sound.c
deleted file mode 100644
index d9f6a98..0000000
--- a/vhost_user_sound.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Based on vhost-user-sound.c of QEMU project
- *
- * Copyright 2020 Red Hat, Inc.
- *
- * Copyright (c) 2023 Virtual Open Systems SAS.
- *
- * 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 <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdbool.h>
-#include <sys/param.h>
-
-/* Project header files */
-#include "vhost_user_sound.h"
-
-#ifdef DEBUG
-#define DBG(...) printf("vhost-user-sound: " __VA_ARGS__)
-#else
-#define DBG(...)
-#endif /* DEBUG */
-
-/***************************** vhost-user-sound ******************************/
-
-/*
- * Features supported by the vhost-user-sound frontend:
- * VIRTIO_F_VERSION_1,
- * VIRTIO_RING_F_INDIRECT_DESC,
- * VIRTIO_RING_F_EVENT_IDX,
- * VIRTIO_F_RING_RESET,
- * VIRTIO_F_NOTIFY_ON_EMPTY,
- * VHOST_INVALID_FEATURE_BIT
- */
-static const int user_feature_bits[] = {
- VIRTIO_F_VERSION_1,
- VIRTIO_RING_F_INDIRECT_DESC,
- VIRTIO_RING_F_EVENT_IDX,
- VIRTIO_F_RING_RESET,
- VIRTIO_F_NOTIFY_ON_EMPTY,
- VHOST_INVALID_FEATURE_BIT
-};
-
-static void vus_get_config(VirtIODevice *vdev, uint8_t *config)
-{
- VHostUserSound *snd = vdev->vhusnd;
-
- memcpy(config, &snd->config, sizeof(struct virtio_snd_config));
-}
-
-
-static void vus_start(VirtIODevice *vdev)
-{
- VHostUserSound *vhusnd = vdev->vhusnd;
- VirtioBus *k = vdev->vbus;
- int ret;
- unsigned int i;
-
- DBG("vus_start(...)\n");
-
- if (!k->set_guest_notifiers) {
- DBG("binding does not support guest notifiers\n");
- return;
- }
-
- ret = vhost_dev_enable_notifiers(vhusnd->vhost_dev, vdev);
- if (ret < 0) {
- DBG("Error enabling host notifiers: %d\n", -ret);
- return;
- }
-
- ret = k->set_guest_notifiers(k->vdev, vhusnd->vhost_dev->nvqs, true);
- if (ret < 0) {
- DBG("Error binding guest notifier: %d\n", -ret);
- goto err_host_notifiers;
- }
-
- vhusnd->vhost_dev->acked_features = vdev->guest_features;
-
- ret = vhost_dev_start(vhusnd->vhost_dev, vdev, true);
- if (ret < 0) {
- DBG("Error starting vhost: %d\n", -ret);
- goto err_guest_notifiers;
- }
-
- /*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
- for (i = 0; i < vhusnd->vhost_dev->nvqs; i++) {
- vhost_virtqueue_mask(vhusnd->vhost_dev, vdev, i, false);
- }
-
- return;
-
-err_guest_notifiers:
-err_host_notifiers:
- DBG("vhu_start error\n");
- return;
-}
-
-static void vus_stop(VirtIODevice *vdev)
-{
- DBG("vus_stop: not yet implemented\n");
- (void)vdev;
-}
-
-static void vus_set_status(VirtIODevice *vdev, uint8_t status)
-{
- VHostUserSound *vhusnd = vdev->vhusnd;
- bool should_start = virtio_device_started(vdev, status);
- DBG("vus_set_status\n");
-
- if (vhusnd->vhost_dev->started == should_start) {
- DBG("snd->vhost_dev->started == should_start\n");
- return;
- }
-
- if (should_start) {
- vus_start(vdev);
- } else {
- vus_stop(vdev);
- }
-}
-
-static uint64_t vus_get_features(VirtIODevice *vdev, uint64_t features)
-{
- VHostUserSound *s = vdev->vhusnd;
-
- DBG("vus_get_features()\n");
-
- return vhost_get_features(s->vhost_dev, user_feature_bits, features);
-}
-
-static void vus_snd_handle_output(VirtIODevice *vdev, VirtQueue *vq)
-{
- /*
- * Not normally called; it's the daemon that handles the queue;
- * however virtio's cleanup path can call this.
- */
- (void)vdev;
- (void)vq;
-}
-
-/*
- * TODO: Add it later
- * static void vhost_sound_guest_notifier_mask(VirtIODevice *vdev, int idx,
- * bool mask)
- */
-
-/*
- * TODO: Add it later
- * static bool vhost_sound_guest_notifier_pending(VirtIODevice *vdev,
- * int idx)
- */
-
-static int vus_sound_config_change(struct vhost_dev *dev)
-{
- VHostUserSound *vhusnd = dev->vdev->vhusnd;
- DBG("vus_sound_config_change\n");
-
- int ret = vhost_dev_get_config(dev, (uint8_t *)&vhusnd->config,
- sizeof(struct virtio_snd_config));
- if (ret < 0) {
- DBG("vus_sound_config_change error\n");
- return -1;
- }
-
- virtio_notify_config(dev->vdev);
-
- return 0;
-}
-
-const VhostDevConfigOps snd_config_ops = {
- .vhost_dev_config_notifier = vus_sound_config_change,
-};
-
-static void vhost_user_snd_init(VirtIODevice *vdev);
-
-void vus_device_realize(int queue_num, int queue_size)
-{
- VirtIODevice *vdev = global_vdev;
- int ret;
-
- DBG("vus_device_realize\n");
- (void)queue_num;
- (void)queue_size;
-
- /* This needs to be added */
- proxy = (VirtIOMMIOProxy *)malloc(sizeof(VirtIOMMIOProxy));
- *proxy = (VirtIOMMIOProxy) {
- .legacy = 1,
- };
-
- /* VIRTIO_ID_SOUND is 25, check virtio_ids.h in linux*/
- virtio_dev_init(vdev, "virtio-sound", 25, sizeof(vdev->vhusnd->config));
- vhost_user_snd_init(global_vdev);
-
- /* add queues */
- vdev->vhusnd->ctrl_vq = virtio_add_queue(vdev, 64, vus_snd_handle_output);
- vdev->vhusnd->event_vq = virtio_add_queue(vdev, 64, vus_snd_handle_output);
- vdev->vhusnd->tx_vq = virtio_add_queue(vdev, 64, vus_snd_handle_output);
- vdev->vhusnd->rx_vq = virtio_add_queue(vdev, 64, vus_snd_handle_output);
- vdev->vhusnd->vhost_dev->nvqs = 4;
- vdev->vhusnd->num_queues = 4;
- vdev->vhusnd->queue_size = 64;
-
- /* NOTE: global_vdev->vqs == vhublk->virtqs */
- vdev->vqs = (VirtQueue **)malloc(sizeof(VirtQueue *)
- * global_vdev->vhusnd->num_queues);
- vdev->vqs[0] = vdev->vhusnd->ctrl_vq;
- vdev->vqs[1] = vdev->vhusnd->event_vq;
- vdev->vqs[2] = vdev->vhusnd->tx_vq;
- vdev->vqs[3] = vdev->vhusnd->rx_vq;
-
- vdev->vhusnd->vhost_vqs = (struct vhost_virtqueue *)malloc(
- sizeof(struct vhost_virtqueue) *
- vdev->vhusnd->num_queues);
-
- /* Set up vhost device */
- vdev->vhusnd->vhost_dev->num_queues = vdev->vhusnd->num_queues;
- vdev->vhusnd->vhost_dev->nvqs = vdev->vhusnd->num_queues;
- vdev->vhusnd->vhost_dev->vqs = vdev->vhusnd->vhost_vqs;
- vdev->vhusnd->vhost_dev->vq_index = 0;
- vdev->vhusnd->vhost_dev->backend_features = 0;
-
- vhost_dev_set_config_notifier(vdev->vhusnd->vhost_dev, &snd_config_ops);
-
- /* TODO: Add error handling */
- vhost_dev_init(vdev->vhusnd->vhost_dev);
-
- /* Pass the new obtained features */
- global_vdev->host_features = vdev->vhusnd->vhost_dev->features;
-
- ret = vhost_dev_get_config(vdev->vhusnd->vhost_dev,
- (uint8_t *)&vdev->vhusnd->config,
- sizeof(struct virtio_snd_config));
- if (ret < 0) {
- goto vhost_dev_init_failed;
- }
-
- vdev->vdev_class->print_config((uint8_t *)&vdev->vhusnd->config);
-
- return;
-
-vhost_dev_init_failed:
- DBG("vhost_dev_init_failed\n");
- return;
-}
-
-static void vus_device_unrealize(VirtIODevice *vdev)
-{
- DBG("vhost_user_blk_device_unrealize not yet implemented\n");
- (void)vdev;
-}
-
-/*
- * This will be might be useful in the future
- *
- * static struct vhost_dev *vus_get_vhost(VirtIODevice *vdev)
- * {
- * VHostUserSound *vhusnd = vdev->vhusnd;
- * return vhusnd->vhost_dev;
- * }
- *
- */
-
-static void print_config_snd(uint8_t *config_data)
-{
- struct virtio_snd_config *config_strct =
- (struct virtio_snd_config *)config_data;
-
- (void)config_strct;
-
- DBG("print_config_snd:\n");
- /* # of available physical jacks */
- DBG("\tuint32_t jacks: %u\n", config_strct->jacks);
- /* # of available PCM streams */
- DBG("\tuint32_t streams: %u\n", config_strct->streams);
- /* # of available channel maps */
- DBG("\tuint32_t chmaps: %u\n", config_strct->chmaps);
-}
-
-static void virtio_dev_class_init(VirtIODevice *vdev)
-{
- DBG("virtio_dev_class_init\n");
-
- vdev->vdev_class = (VirtioDeviceClass *)malloc(sizeof(VirtioDeviceClass));
- vdev->vdev_class->parent = vdev;
- vdev->vdev_class->realize = vus_device_realize;
- vdev->vdev_class->unrealize = vus_device_unrealize;
- vdev->vdev_class->get_config = vus_get_config;
- vdev->vdev_class->get_features = vus_get_features;
- vdev->vdev_class->set_status = vus_set_status;
- vdev->vdev_class->update_mem_table = update_mem_table;
- vdev->vdev_class->print_config = print_config_snd;
-}
-
-static void vhost_user_snd_init(VirtIODevice *vdev)
-{
-
- DBG("vhost_user_blk_init\n");
-
- VHostUserSound *vhusnd = (VHostUserSound *)malloc(sizeof(VHostUserSound));
- vdev->vhusnd = vhusnd;
- vdev->nvqs = (int *)&vdev->vhdev->nvqs;
- vhusnd->parent = vdev;
- vhusnd->virtqs = vdev->vqs;
- vhusnd->vhost_dev = vdev->vhdev;
-
- virtio_dev_class_init(vdev);
- virtio_loopback_bus_init(vdev->vbus);
-}