rte_virtio: rework vtpci ops
Added vtpci_init/deinit() that set up vtpci_internal for given virtio device. This patch allows having multiple devices with different vtpci_ops. Change-Id: I249999cc24073b3de032db194730f496badd0f38 Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com> Reviewed-on: https://review.gerrithub.io/381311 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
5faa855989
commit
6175e0caf1
@ -621,7 +621,7 @@ bdev_virtio_initialize(void)
|
||||
}
|
||||
|
||||
if (scan_pci) {
|
||||
vtpci_init();
|
||||
vtpci_enumerate_pci();
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(vdev, &g_virtio_driver.init_ctrlrs, tailq) {
|
||||
|
@ -120,8 +120,8 @@ virtio_init_queue(struct virtio_dev *dev, uint16_t vtpci_queue_idx)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snprintf(vq_name, sizeof(vq_name), "port%d_vq%d",
|
||||
dev->port_id, vtpci_queue_idx);
|
||||
snprintf(vq_name, sizeof(vq_name), "dev%d_vq%d",
|
||||
dev->id, vtpci_queue_idx);
|
||||
|
||||
size = RTE_ALIGN_CEIL(sizeof(*vq) +
|
||||
vq_size * sizeof(struct vq_desc_extra),
|
||||
@ -318,9 +318,11 @@ virtio_dev_init(struct virtio_dev *dev, uint64_t req_features)
|
||||
void
|
||||
virtio_dev_free(struct virtio_dev *dev)
|
||||
{
|
||||
uint32_t vdev_id = dev->id;
|
||||
|
||||
virtio_free_queues(dev);
|
||||
vtpci_ops(dev)->free_vdev(dev);
|
||||
/* FIXME clear VTPCI_OPS(dev) */
|
||||
vtpci_deinit(vdev_id);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -45,7 +45,8 @@ struct virtio_dev {
|
||||
/** Max number of queues the host supports. */
|
||||
uint16_t max_queues;
|
||||
|
||||
uint8_t port_id;
|
||||
/* Device index. */
|
||||
uint32_t id;
|
||||
uint64_t req_guest_features;
|
||||
uint64_t guest_features;
|
||||
int is_hw;
|
||||
|
@ -83,6 +83,12 @@ check_vq_phys_addr_ok(struct virtqueue *vq)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct rte_pci_ioport *
|
||||
vtpci_io(struct virtio_dev *vdev)
|
||||
{
|
||||
return &g_virtio_driver.internal[vdev->id].io;
|
||||
}
|
||||
|
||||
static void
|
||||
free_virtio_hw(struct virtio_dev *dev)
|
||||
{
|
||||
@ -724,7 +730,10 @@ pci_enum_virtio_probe_cb(void *ctx, struct spdk_pci_device *pci_dev)
|
||||
*/
|
||||
if (virtio_read_caps(hw) == 0) {
|
||||
PMD_INIT_LOG(INFO, "modern virtio pci detected.");
|
||||
vtpci_ops(vdev) = &modern_ops;
|
||||
rc = vtpci_init(vdev, &modern_ops);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
vdev->modern = 1;
|
||||
TAILQ_INSERT_TAIL(&g_virtio_driver.init_ctrlrs, vdev, tailq);
|
||||
return 0;
|
||||
@ -745,8 +754,11 @@ pci_enum_virtio_probe_cb(void *ctx, struct spdk_pci_device *pci_dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
vtpci_ops(vdev) = &legacy_ops;
|
||||
vdev->modern = 0;
|
||||
rc = vtpci_init(vdev, &legacy_ops);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
vdev->modern = 0;
|
||||
|
||||
vtpci_read_dev_config(vdev, offsetof(struct virtio_scsi_config, num_queues),
|
||||
&vdev->max_queues, sizeof(vdev->max_queues));
|
||||
@ -760,7 +772,29 @@ err:
|
||||
}
|
||||
|
||||
int
|
||||
vtpci_init(void)
|
||||
vtpci_init(struct virtio_dev *vdev, const struct virtio_pci_ops *ops)
|
||||
{
|
||||
unsigned vdev_num;
|
||||
|
||||
for (vdev_num = 0; vdev_num < VIRTIO_MAX_DEVICES; vdev_num++) {
|
||||
if (g_virtio_driver.internal[vdev_num].vtpci_ops == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (vdev_num == VIRTIO_MAX_DEVICES) {
|
||||
PMD_INIT_LOG(ERR, "Max vhost device limit reached (%d).", VIRTIO_MAX_DEVICES);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
vdev->id = vdev_num;
|
||||
g_virtio_driver.internal[vdev_num].vtpci_ops = ops;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
vtpci_enumerate_pci(void)
|
||||
{
|
||||
if (!spdk_process_is_primary()) {
|
||||
PMD_INIT_LOG(INFO, "virtio_pci secondary process support is not implemented yet.");
|
||||
@ -769,3 +803,15 @@ vtpci_init(void)
|
||||
|
||||
return spdk_pci_virtio_enumerate(pci_enum_virtio_probe_cb, NULL);
|
||||
}
|
||||
|
||||
const struct virtio_pci_ops *
|
||||
vtpci_ops(struct virtio_dev *dev)
|
||||
{
|
||||
return g_virtio_driver.internal[dev->id].vtpci_ops;
|
||||
}
|
||||
|
||||
void
|
||||
vtpci_deinit(uint32_t id)
|
||||
{
|
||||
g_virtio_driver.internal[id].vtpci_ops = NULL;
|
||||
}
|
||||
|
@ -43,6 +43,8 @@
|
||||
|
||||
struct virtqueue;
|
||||
|
||||
#define VIRTIO_MAX_DEVICES 128
|
||||
|
||||
/* VirtIO PCI vendor/device ID. */
|
||||
#define VIRTIO_PCI_VENDORID 0x1AF4
|
||||
#define VIRTIO_PCI_DEVICEID_SCSI_MODERN 0x1004
|
||||
@ -242,11 +244,8 @@ struct vtpci_internal {
|
||||
struct rte_pci_ioport io;
|
||||
};
|
||||
|
||||
#define vtpci_ops(dev) (g_virtio_driver.internal[(dev)->port_id].vtpci_ops)
|
||||
#define vtpci_io(dev) (&g_virtio_driver.internal[(dev)->port_id].io)
|
||||
|
||||
struct virtio_driver {
|
||||
struct vtpci_internal internal[128];
|
||||
struct vtpci_internal internal[VIRTIO_MAX_DEVICES];
|
||||
TAILQ_HEAD(, virtio_dev) init_ctrlrs;
|
||||
TAILQ_HEAD(, virtio_dev) attached_ctrlrs;
|
||||
};
|
||||
@ -268,7 +267,17 @@ vtpci_with_feature(struct virtio_dev *dev, uint64_t bit)
|
||||
return (dev->guest_features & (1ULL << bit)) != 0;
|
||||
}
|
||||
|
||||
int vtpci_init(void);
|
||||
/**
|
||||
* Init all compatible Virtio PCI devices.
|
||||
*/
|
||||
int vtpci_enumerate_pci(void);
|
||||
|
||||
/**
|
||||
* Init virtual PCI layer for given device. This
|
||||
* will set vdev->id field.
|
||||
*/
|
||||
int vtpci_init(struct virtio_dev *vdev, const struct virtio_pci_ops *ops);
|
||||
|
||||
void vtpci_reset(struct virtio_dev *);
|
||||
|
||||
void vtpci_reinit_complete(struct virtio_dev *);
|
||||
@ -284,6 +293,10 @@ void vtpci_read_dev_config(struct virtio_dev *, size_t, void *, int);
|
||||
|
||||
uint8_t vtpci_isr(struct virtio_dev *);
|
||||
|
||||
const struct virtio_pci_ops *vtpci_ops(struct virtio_dev *dev);
|
||||
|
||||
void vtpci_deinit(uint32_t id);
|
||||
|
||||
extern const struct virtio_pci_ops virtio_user_ops;
|
||||
|
||||
#endif /* _VIRTIO_PCI_H_ */
|
||||
|
@ -199,7 +199,10 @@ virtio_user_dev_init(char *path, int queue_size)
|
||||
vdev = &dev->vdev;
|
||||
vdev->is_hw = 0;
|
||||
|
||||
vtpci_ops(vdev) = &virtio_user_ops;
|
||||
if (vtpci_init(vdev, &virtio_user_ops) != 0) {
|
||||
PMD_INIT_LOG(ERR, "Failed to init device: %s", path);
|
||||
goto err;
|
||||
}
|
||||
|
||||
snprintf(dev->path, PATH_MAX, "%s", path);
|
||||
dev->queue_size = queue_size;
|
||||
|
Loading…
x
Reference in New Issue
Block a user