Skip to content

Commit

Permalink
virtio: add create_virtqueues and delete_virtqueues in virtio_dispatch
Browse files Browse the repository at this point in the history
This is the first step to decoupling the virtio device and transport
layer.

Signed-off-by: Bowen Wang <[email protected]>
  • Loading branch information
CV-Bowen committed Jul 10, 2023
1 parent dcc21e6 commit 375fc2c
Show file tree
Hide file tree
Showing 2 changed files with 194 additions and 0 deletions.
189 changes: 189 additions & 0 deletions lib/include/openamp/virtio.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define _VIRTIO_H_

#include <openamp/virtqueue.h>
#include <metal/errno.h>
#include <metal/spinlock.h>

#if defined __cplusplus
Expand Down Expand Up @@ -176,6 +177,11 @@ void virtio_describe(struct virtio_device *dev, const char *msg,
*/

struct virtio_dispatch {
int (*create_virtqueues)(struct virtio_device *vdev,
unsigned int flags,
unsigned int nvqs, const char *names[],
vq_callback callbacks[]);
void (*delete_virtqueues)(struct virtio_device *vdev);
uint8_t (*get_status)(struct virtio_device *dev);
void (*set_status)(struct virtio_device *dev, uint8_t status);
uint32_t (*get_features)(struct virtio_device *dev);
Expand All @@ -196,10 +202,193 @@ struct virtio_dispatch {
void (*notify)(struct virtqueue *vq);
};

/**
* @brief Create the virtio device virtqueue.
*
* @param vdev Pointer to virtio device structure.
* @param flags Create flag.
* @param nvqs The virtqueue number.
* @param names Virtqueue names.
* @param callbacks Virtqueue callback functions.
*
* @return 0 on success, otherwise error code.
*/
int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
unsigned int nvqs, const char *names[],
vq_callback callbacks[]);

/**
* @brief Delete the virtio device virtqueue.
*
* @param vdev Pointer to virtio device structure.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_delete_virtqueues(struct virtio_device *vdev)
{
if (!vdev->func->delete_virtqueues)

This comment has been minimized.

Copy link
@tnmysh

tnmysh Jul 10, 2023

Collaborator

This should check vdev->func and vdev->func->delete_virtqueues both.
so,
if (!vdev->func)
return -ENXIO;

if (!vdev->func->delete_virtqueues)
return -ENXIO;

This validates NULL check for both func and delete_virtqueues ops.

This comment has been minimized.

Copy link
@CV-Bowen

CV-Bowen Jul 10, 2023

Author Contributor

Thanks, done.

return -ENXIO;

vdev->func->delete_virtqueues(vdev);
return 0;
}

/**
* @brief Retrieve device status.
*
* @param dev Pointer to device structure.
* @param status Pointer to the virtio device status.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_get_status(struct virtio_device *vdev, uint8_t *status)
{
if (!status)
return -EINVAL;

if (!vdev->func->get_status)
return -ENXIO;

*status = vdev->func->get_status(vdev);
return 0;
}

/**
* @brief Set device status.
*
* @param dev Pointer to device structure.
* @param status Value to be set as device status.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_set_status(struct virtio_device *vdev, uint8_t status)
{
if (!vdev->func->set_status)
return -ENXIO;

vdev->func->set_status(vdev, status);
return 0;
}

/**
* @brief Retrieve configuration data from the device.
*
* @param dev Pointer to device structure.
* @param offset Offset of the data within the configuration area.
* @param dst Address of the buffer that will hold the data.
* @param len Length of the data to be retrieved.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_read_config(struct virtio_device *vdev,
uint32_t offset, void *dst, int len)
{
if (!vdev->func->read_config)
return -ENXIO;

vdev->func->read_config(vdev, offset, dst, len);
return 0;
}

/**
* @brief Write configuration data to the device.
*
* @param dev Pointer to device structure.
* @param offset Offset of the data within the configuration area.
* @param src Address of the buffer that holds the data to write.
* @param len Length of the data to be written.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_write_config(struct virtio_device *vdev,
uint32_t offset, void *src, int len)
{
if (!vdev->func->write_config)
return -ENXIO;

vdev->func->write_config(vdev, offset, src, len);
return 0;
}

/**
* @brief Get the virtio device features.
*
* @param dev Pointer to device structure.
* @param features Pointer to features supported by both the driver and
* the device as a bitfield.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_get_features(struct virtio_device *vdev,
uint32_t *features)
{
if (!features)
return -EINVAL;

if (!vdev->func->get_features)
return -ENXIO;

*features = vdev->func->get_features(vdev);
return 0;
}

/**
* @brief Set features supported by the VIRTIO driver.
*
* @param dev Pointer to device structure.
* @param features Features supported by the driver as a bitfield.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_set_features(struct virtio_device *vdev,
uint32_t features)
{
if (!vdev->func->set_features)
return -ENXIO;

vdev->func->set_features(vdev, features);
return 0;
}

/**
* @brief Negotiate features between virtio device and driver.
*
* @param dev Pointer to device structure.
* @param features Supported features.
* @param final_features Pointer to the final features after negotiate.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_negotiate_features(struct virtio_device *vdev,
uint32_t features,
uint32_t *final_features)
{
if (!final_features)
return -EINVAL;

if (!vdev->func->negotiate_features)
return -ENXIO;

*final_features = vdev->func->negotiate_features(vdev, features);
return 0;
}

/**
* @brief Reset virtio device.
*
* @param vdev Pointer to virtio_device structure.
*
* @return 0 on success, otherwise error code.
*/
static inline int virtio_reset_device(struct virtio_device *vdev)
{
if (!vdev->func->reset_device)
return -ENXIO;

vdev->func->reset_device(vdev);
return 0;
}

#if defined __cplusplus
}
#endif
Expand Down
5 changes: 5 additions & 0 deletions lib/virtio/virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
int ret;
(void)flags;

if (vdev->func->create_virtqueues) {
return vdev->func->create_virtqueues(vdev, flags, nvqs,
names, callbacks);
}

num_vrings = vdev->vrings_num;
if (nvqs > num_vrings)
return ERROR_VQUEUE_INVLD_PARAM;
Expand Down

0 comments on commit 375fc2c

Please sign in to comment.