diff options
author | 2024-10-01 18:16:29 +0300 | |
---|---|---|
committer | 2024-10-01 15:36:35 +0000 | |
commit | 9941dec970111be9e02dcaf6819c037946bde160 (patch) | |
tree | bea826b7fc861fe09c53d43f60d1a7d464e4cf9b /vhost_user_sound.c | |
parent | 1cc834724919caf5ea21c146b29f62b6cd213db7 (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.c | 322 |
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); -} |