virtio: get class_id and pci device id by the virtio id
Add helpers to get the "Transitional PCI Device ID" and "class_id" of the device specified by the "Virtio Device ID". These helpers will be used to build the generic vDPA device later. Acked-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Longpeng <longpeng2@huawei.com> Message-Id: <20221215134944.2809-2-longpeng2@huawei.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
ee1c08bd73
commit
2273324540
@ -19,6 +19,7 @@
|
||||
|
||||
#include "exec/memop.h"
|
||||
#include "standard-headers/linux/virtio_pci.h"
|
||||
#include "standard-headers/linux/virtio_ids.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/virtio/virtio.h"
|
||||
#include "migration/qemu-file-types.h"
|
||||
@ -224,6 +225,90 @@ static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f)
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct VirtIOPCIIDInfo {
|
||||
/* virtio id */
|
||||
uint16_t vdev_id;
|
||||
/* pci device id for the transitional device */
|
||||
uint16_t trans_devid;
|
||||
uint16_t class_id;
|
||||
} VirtIOPCIIDInfo;
|
||||
|
||||
static const VirtIOPCIIDInfo virtio_pci_id_info[] = {
|
||||
{
|
||||
.vdev_id = VIRTIO_ID_CRYPTO,
|
||||
.class_id = PCI_CLASS_OTHERS,
|
||||
}, {
|
||||
.vdev_id = VIRTIO_ID_FS,
|
||||
.class_id = PCI_CLASS_STORAGE_OTHER,
|
||||
}, {
|
||||
.vdev_id = VIRTIO_ID_NET,
|
||||
.trans_devid = PCI_DEVICE_ID_VIRTIO_NET,
|
||||
.class_id = PCI_CLASS_NETWORK_ETHERNET,
|
||||
}, {
|
||||
.vdev_id = VIRTIO_ID_BLOCK,
|
||||
.trans_devid = PCI_DEVICE_ID_VIRTIO_BLOCK,
|
||||
.class_id = PCI_CLASS_STORAGE_SCSI,
|
||||
}, {
|
||||
.vdev_id = VIRTIO_ID_CONSOLE,
|
||||
.trans_devid = PCI_DEVICE_ID_VIRTIO_CONSOLE,
|
||||
.class_id = PCI_CLASS_COMMUNICATION_OTHER,
|
||||
}, {
|
||||
.vdev_id = VIRTIO_ID_SCSI,
|
||||
.trans_devid = PCI_DEVICE_ID_VIRTIO_SCSI,
|
||||
.class_id = PCI_CLASS_STORAGE_SCSI
|
||||
}, {
|
||||
.vdev_id = VIRTIO_ID_9P,
|
||||
.trans_devid = PCI_DEVICE_ID_VIRTIO_9P,
|
||||
.class_id = PCI_BASE_CLASS_NETWORK,
|
||||
}, {
|
||||
.vdev_id = VIRTIO_ID_BALLOON,
|
||||
.trans_devid = PCI_DEVICE_ID_VIRTIO_BALLOON,
|
||||
.class_id = PCI_CLASS_OTHERS,
|
||||
}, {
|
||||
.vdev_id = VIRTIO_ID_RNG,
|
||||
.trans_devid = PCI_DEVICE_ID_VIRTIO_RNG,
|
||||
.class_id = PCI_CLASS_OTHERS,
|
||||
},
|
||||
};
|
||||
|
||||
static const VirtIOPCIIDInfo *virtio_pci_get_id_info(uint16_t vdev_id)
|
||||
{
|
||||
const VirtIOPCIIDInfo *info = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(virtio_pci_id_info); i++) {
|
||||
if (virtio_pci_id_info[i].vdev_id == vdev_id) {
|
||||
info = &virtio_pci_id_info[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!info) {
|
||||
/* The device id is invalid or not added to the id_info yet. */
|
||||
error_report("Invalid virtio device(id %u)", vdev_id);
|
||||
abort();
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the Transitional Device ID for the specific device, return
|
||||
* zero if the device is non-transitional.
|
||||
*/
|
||||
uint16_t virtio_pci_get_trans_devid(uint16_t device_id)
|
||||
{
|
||||
return virtio_pci_get_id_info(device_id)->trans_devid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the Class ID for the specific device.
|
||||
*/
|
||||
uint16_t virtio_pci_get_class_id(uint16_t device_id)
|
||||
{
|
||||
return virtio_pci_get_id_info(device_id)->class_id;
|
||||
}
|
||||
|
||||
static bool virtio_pci_ioeventfd_enabled(DeviceState *d)
|
||||
{
|
||||
VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
|
||||
@ -1729,6 +1814,9 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
|
||||
* is set to PCI_SUBVENDOR_ID_REDHAT_QUMRANET by default.
|
||||
*/
|
||||
pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus));
|
||||
if (proxy->trans_devid) {
|
||||
pci_config_set_device_id(config, proxy->trans_devid);
|
||||
}
|
||||
} else {
|
||||
/* pure virtio-1.0 */
|
||||
pci_set_word(config + PCI_VENDOR_ID,
|
||||
|
@ -151,6 +151,8 @@ struct VirtIOPCIProxy {
|
||||
bool disable_modern;
|
||||
bool ignore_backend_features;
|
||||
OnOffAuto disable_legacy;
|
||||
/* Transitional device id */
|
||||
uint16_t trans_devid;
|
||||
uint32_t class_code;
|
||||
uint32_t nvectors;
|
||||
uint32_t dfselect;
|
||||
@ -184,6 +186,9 @@ static inline void virtio_pci_disable_modern(VirtIOPCIProxy *proxy)
|
||||
proxy->disable_modern = true;
|
||||
}
|
||||
|
||||
uint16_t virtio_pci_get_trans_devid(uint16_t device_id);
|
||||
uint16_t virtio_pci_get_class_id(uint16_t device_id);
|
||||
|
||||
/*
|
||||
* virtio-input-pci: This extends VirtioPCIProxy.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user