| /* |
| * VDUSE (vDPA Device in Userspace) library |
| * |
| * Copyright (C) 2022 Bytedance Inc. and/or its affiliates. All rights reserved. |
| * |
| * Author: |
| * Xie Yongji <xieyongji@bytedance.com> |
| * |
| * This work is licensed under the terms of the GNU GPL, version 2 or |
| * later. See the COPYING file in the top-level directory. |
| */ |
| |
| #ifndef LIBVDUSE_H |
| #define LIBVDUSE_H |
| |
| #include <stdint.h> |
| #include <sys/uio.h> |
| |
| #define VIRTQUEUE_MAX_SIZE 1024 |
| |
| /* VDUSE device structure */ |
| typedef struct VduseDev VduseDev; |
| |
| /* Virtqueue structure */ |
| typedef struct VduseVirtq VduseVirtq; |
| |
| /* Some operation of VDUSE backend */ |
| typedef struct VduseOps { |
| /* Called when virtqueue can be processed */ |
| void (*enable_queue)(VduseDev *dev, VduseVirtq *vq); |
| /* Called when virtqueue processing should be stopped */ |
| void (*disable_queue)(VduseDev *dev, VduseVirtq *vq); |
| } VduseOps; |
| |
| /* Describing elements of the I/O buffer */ |
| typedef struct VduseVirtqElement { |
| /* Descriptor table index */ |
| unsigned int index; |
| /* Number of physically-contiguous device-readable descriptors */ |
| unsigned int out_num; |
| /* Number of physically-contiguous device-writable descriptors */ |
| unsigned int in_num; |
| /* Array to store physically-contiguous device-writable descriptors */ |
| struct iovec *in_sg; |
| /* Array to store physically-contiguous device-readable descriptors */ |
| struct iovec *out_sg; |
| } VduseVirtqElement; |
| |
| |
| /** |
| * vduse_get_virtio_features: |
| * |
| * Get supported virtio features |
| * |
| * Returns: supported feature bits |
| */ |
| uint64_t vduse_get_virtio_features(void); |
| |
| /** |
| * vduse_queue_get_dev: |
| * @vq: specified virtqueue |
| * |
| * Get corresponding VDUSE device from the virtqueue. |
| * |
| * Returns: a pointer to VDUSE device on success, NULL on failure. |
| */ |
| VduseDev *vduse_queue_get_dev(VduseVirtq *vq); |
| |
| /** |
| * vduse_queue_get_fd: |
| * @vq: specified virtqueue |
| * |
| * Get the kick fd for the virtqueue. |
| * |
| * Returns: file descriptor on success, -1 on failure. |
| */ |
| int vduse_queue_get_fd(VduseVirtq *vq); |
| |
| /** |
| * vduse_queue_pop: |
| * @vq: specified virtqueue |
| * @sz: the size of struct to return (must be >= VduseVirtqElement) |
| * |
| * Pop an element from virtqueue available ring. |
| * |
| * Returns: a pointer to a structure containing VduseVirtqElement on success, |
| * NULL on failure. |
| */ |
| void *vduse_queue_pop(VduseVirtq *vq, size_t sz); |
| |
| /** |
| * vduse_queue_push: |
| * @vq: specified virtqueue |
| * @elem: pointer to VduseVirtqElement returned by vduse_queue_pop() |
| * @len: length in bytes to write |
| * |
| * Push an element to virtqueue used ring. |
| */ |
| void vduse_queue_push(VduseVirtq *vq, const VduseVirtqElement *elem, |
| unsigned int len); |
| /** |
| * vduse_queue_notify: |
| * @vq: specified virtqueue |
| * |
| * Request to notify the queue. |
| */ |
| void vduse_queue_notify(VduseVirtq *vq); |
| |
| /** |
| * vduse_dev_get_priv: |
| * @dev: VDUSE device |
| * |
| * Get the private pointer passed to vduse_dev_create(). |
| * |
| * Returns: private pointer on success, NULL on failure. |
| */ |
| void *vduse_dev_get_priv(VduseDev *dev); |
| |
| /** |
| * vduse_dev_get_queue: |
| * @dev: VDUSE device |
| * @index: virtqueue index |
| * |
| * Get the specified virtqueue. |
| * |
| * Returns: a pointer to the virtqueue on success, NULL on failure. |
| */ |
| VduseVirtq *vduse_dev_get_queue(VduseDev *dev, int index); |
| |
| /** |
| * vduse_dev_get_fd: |
| * @dev: VDUSE device |
| * |
| * Get the control message fd for the VDUSE device. |
| * |
| * Returns: file descriptor on success, -1 on failure. |
| */ |
| int vduse_dev_get_fd(VduseDev *dev); |
| |
| /** |
| * vduse_dev_handler: |
| * @dev: VDUSE device |
| * |
| * Used to process the control message. |
| * |
| * Returns: file descriptor on success, -errno on failure. |
| */ |
| int vduse_dev_handler(VduseDev *dev); |
| |
| /** |
| * vduse_dev_update_config: |
| * @dev: VDUSE device |
| * @size: the size to write to configuration space |
| * @offset: the offset from the beginning of configuration space |
| * @buffer: the buffer used to write from |
| * |
| * Update device configuration space and inject a config interrupt. |
| * |
| * Returns: 0 on success, -errno on failure. |
| */ |
| int vduse_dev_update_config(VduseDev *dev, uint32_t size, |
| uint32_t offset, char *buffer); |
| |
| /** |
| * vduse_dev_setup_queue: |
| * @dev: VDUSE device |
| * @index: virtqueue index |
| * @max_size: the max size of virtqueue |
| * |
| * Setup the specified virtqueue. |
| * |
| * Returns: 0 on success, -errno on failure. |
| */ |
| int vduse_dev_setup_queue(VduseDev *dev, int index, int max_size); |
| |
| /** |
| * vduse_set_reconnect_log_file: |
| * @dev: VDUSE device |
| * @file: filename of reconnect log |
| * |
| * Specify the file to store log for reconnecting. It should |
| * be called before vduse_dev_setup_queue(). |
| * |
| * Returns: 0 on success, -errno on failure. |
| */ |
| int vduse_set_reconnect_log_file(VduseDev *dev, const char *filename); |
| |
| /** |
| * vduse_dev_create_by_fd: |
| * @fd: passed file descriptor |
| * @num_queues: the number of virtqueues |
| * @ops: the operation of VDUSE backend |
| * @priv: private pointer |
| * |
| * Create VDUSE device from a passed file descriptor. |
| * |
| * Returns: pointer to VDUSE device on success, NULL on failure. |
| */ |
| VduseDev *vduse_dev_create_by_fd(int fd, uint16_t num_queues, |
| const VduseOps *ops, void *priv); |
| |
| /** |
| * vduse_dev_create_by_name: |
| * @name: VDUSE device name |
| * @num_queues: the number of virtqueues |
| * @ops: the operation of VDUSE backend |
| * @priv: private pointer |
| * |
| * Create VDUSE device on /dev/vduse/$NAME. |
| * |
| * Returns: pointer to VDUSE device on success, NULL on failure. |
| */ |
| VduseDev *vduse_dev_create_by_name(const char *name, uint16_t num_queues, |
| const VduseOps *ops, void *priv); |
| |
| /** |
| * vduse_dev_create: |
| * @name: VDUSE device name |
| * @device_id: virtio device id |
| * @vendor_id: virtio vendor id |
| * @features: virtio features |
| * @num_queues: the number of virtqueues |
| * @config_size: the size of the configuration space |
| * @config: the buffer of the configuration space |
| * @ops: the operation of VDUSE backend |
| * @priv: private pointer |
| * |
| * Create VDUSE device. |
| * |
| * Returns: pointer to VDUSE device on success, NULL on failure. |
| */ |
| VduseDev *vduse_dev_create(const char *name, uint32_t device_id, |
| uint32_t vendor_id, uint64_t features, |
| uint16_t num_queues, uint32_t config_size, |
| char *config, const VduseOps *ops, void *priv); |
| |
| /** |
| * vduse_dev_destroy: |
| * @dev: VDUSE device |
| * |
| * Destroy the VDUSE device. |
| * |
| * Returns: 0 on success, -errno on failure. |
| */ |
| int vduse_dev_destroy(VduseDev *dev); |
| |
| #endif |