diff --git a/include/spdk_internal/virtio.h b/include/spdk_internal/virtio.h index 3d3e93372..5f9f18f8c 100644 --- a/include/spdk_internal/virtio.h +++ b/include/spdk_internal/virtio.h @@ -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. diff --git a/lib/virtio/virtio_pci.c b/lib/virtio/virtio_pci.c index ac37558d4..3be6cc1b9 100644 --- a/lib/virtio/virtio_pci.c +++ b/lib/virtio/virtio_pci.c @@ -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); diff --git a/module/bdev/virtio/bdev_virtio_blk.c b/module/bdev/virtio/bdev_virtio_blk.c index 198d67ca9..7d5d0298f 100644 --- a/module/bdev/virtio/bdev_virtio_blk.c +++ b/module/bdev/virtio/bdev_virtio_blk.c @@ -48,6 +48,7 @@ #include "spdk_internal/vhost_user.h" #include +#include #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; diff --git a/module/bdev/virtio/bdev_virtio_scsi.c b/module/bdev/virtio/bdev_virtio_scsi.c index 6091b541b..1283881e9 100644 --- a/module/bdev/virtio/bdev_virtio_scsi.c +++ b/module/bdev/virtio/bdev_virtio_scsi.c @@ -48,6 +48,7 @@ #include "spdk_internal/vhost_user.h" #include +#include #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