virtio: add transitional virtio device support

SPDK virtio driver does not support the virtio legacy
device but it's ok for the modern and transitional
device. So update the probe function.

From the spec:
Transitional PCI Device ID Virtio Device
0x1000 network card
0x1001 block device
0x1002 memory ballooning (traditional)
0x1003 console
0x1004 SCSI host
0x1005 entropy source
0x1009 9P transport

Transitional Device: a device supporting both drivers conforming to
modern specification, and allowing legacy drivers.

Change-Id: I28cd277fb2b2e07a429082b7d7bd581f254eae9c
Signed-off-by: Jin Yu <jin.yu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5053
Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Jin Yu 2020-11-09 21:35:36 +08:00 committed by Tomasz Zawadzki
parent 0bcaf050d7
commit 4c890c3160
4 changed files with 25 additions and 7 deletions

View File

@ -452,11 +452,11 @@ int virtio_pci_dev_enumerate(virtio_pci_create_cb enum_cb, void *enum_ctx,
* Returning any other value will cause the PCI context to be freed,
* making it unusable.
* \param enum_ctx additional opaque context to be passed into `enum_cb`
* \param pci_device_id PCI Device ID of devices to iterate through
* \param device_id Device ID of devices to iterate through
* \param pci_addr PCI address of the device to attach
*/
int virtio_pci_dev_attach(virtio_pci_create_cb create_cb, void *enum_ctx,
uint16_t pci_device_id, struct spdk_pci_addr *pci_addr);
uint16_t device_id, struct spdk_pci_addr *pci_addr);
/**
* Connect to a vhost-user device and init corresponding virtio_dev struct.

View File

@ -538,8 +538,24 @@ virtio_pci_dev_probe_cb(void *probe_ctx, struct spdk_pci_device *pci_dev)
{
struct virtio_pci_probe_ctx *ctx = probe_ctx;
uint16_t pci_device_id = spdk_pci_device_get_device_id(pci_dev);
uint16_t device_id;
if (pci_device_id != ctx->device_id) {
if (pci_device_id < 0x1000 || pci_device_id > 0x107f) {
SPDK_ERRLOG("Probe device is not a virtio device\n");
return 1;
}
if (pci_device_id < 0x1040) {
/* Transitional devices: use the PCI subsystem device id as
* virtio device id, same as legacy driver always did.
*/
device_id = spdk_pci_device_get_subdevice_id(pci_dev);
} else {
/* Modern devices: simply use PCI device id, but start from 0x1040. */
device_id = pci_device_id - 0x1040;
}
if (device_id != ctx->device_id) {
return 1;
}
@ -567,7 +583,7 @@ virtio_pci_dev_enumerate(virtio_pci_create_cb enum_cb, void *enum_ctx,
int
virtio_pci_dev_attach(virtio_pci_create_cb enum_cb, void *enum_ctx,
uint16_t pci_device_id, struct spdk_pci_addr *pci_address)
uint16_t device_id, struct spdk_pci_addr *pci_address)
{
struct virtio_pci_probe_ctx ctx;
@ -578,7 +594,7 @@ virtio_pci_dev_attach(virtio_pci_create_cb enum_cb, void *enum_ctx,
ctx.enum_cb = enum_cb;
ctx.enum_ctx = enum_ctx;
ctx.device_id = pci_device_id;
ctx.device_id = device_id;
return spdk_pci_device_attach(spdk_pci_virtio_get_driver(),
virtio_pci_dev_probe_cb, &ctx, pci_address);

View File

@ -48,6 +48,7 @@
#include "spdk_internal/vhost_user.h"
#include <linux/virtio_blk.h>
#include <linux/virtio_ids.h>
#include "bdev_virtio.h"
@ -646,7 +647,7 @@ bdev_virtio_pci_blk_dev_create(const char *name, struct spdk_pci_addr *pci_addr)
create_ctx.ret = NULL;
virtio_pci_dev_attach(bdev_virtio_pci_blk_dev_create_cb, &create_ctx,
PCI_DEVICE_ID_VIRTIO_BLK_MODERN, pci_addr);
VIRTIO_ID_BLOCK, pci_addr);
if (create_ctx.ret == NULL) {
return NULL;

View File

@ -48,6 +48,7 @@
#include "spdk_internal/vhost_user.h"
#include <linux/virtio_scsi.h>
#include <linux/virtio_ids.h>
#include "bdev_virtio.h"
@ -1862,7 +1863,7 @@ bdev_virtio_pci_scsi_dev_create(const char *name, struct spdk_pci_addr *pci_addr
create_ctx.cb_arg = cb_arg;
return virtio_pci_dev_attach(bdev_virtio_pci_scsi_dev_create_cb, &create_ctx,
PCI_DEVICE_ID_VIRTIO_SCSI_MODERN, pci_addr);
VIRTIO_ID_SCSI, pci_addr);
}
int