@@ -41,6 +41,7 @@
#include "hw/hotplug.h"
#include "hw/boards.h"
#include "qemu/cutils.h"
+#include "qapi-visit.h"
//#define DEBUG_PCI
#ifdef DEBUG_PCI
@@ -2504,6 +2505,55 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev)
return dev->bus->address_space_io;
}
+static void pci_device_get_devnr(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ PCIDevice *dev = PCI_DEVICE(obj);
+ uint32_t devnr = PCI_SLOT(dev->devfn);
+
+ visit_type_uint32(v, "device-number", &devnr, errp);
+}
+
+static void pci_device_set_devnr(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ PCIDevice *dev = PCI_DEVICE(obj);
+ uint32_t devnr;
+ Error *local_err = NULL;
+
+ visit_type_uint32(v, "device-number", &devnr, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ dev->devfn = PCI_DEVFN(devnr, PCI_FUNC(dev->devfn));
+}
+
+static void pci_device_get_function(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ PCIDevice *dev = PCI_DEVICE(obj);
+ uint32_t function = PCI_FUNC(dev->devfn);
+
+ visit_type_uint32(v, "function", &function, errp);
+}
+
+static void pci_device_set_function(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ PCIDevice *dev = PCI_DEVICE(obj);
+ uint32_t function;
+ Error *local_err = NULL;
+
+ visit_type_uint32(v, "function", &function, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ dev->devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), function);
+}
+
static void pci_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
@@ -2514,6 +2564,19 @@ static void pci_device_class_init(ObjectClass *klass, void *data)
k->bus_type = TYPE_PCI_BUS;
k->props = pci_props;
pc->realize = pci_default_realize;
+
+ /* Internally, bits 3:8 of devfn are called "slots", but:
+ * - they can be confused with physical slot numbers;
+ * - TYPE_PCIE_SLOT objects already have a "slot" property.
+ * So we use the terminology used in the PCI specifiction:
+ * "device number".
+ */
+ object_class_property_add(klass, "device-number", "uint32",
+ pci_device_get_devnr, pci_device_set_devnr,
+ NULL, NULL, &error_abort);
+ object_class_property_add(klass, "function", "uint32",
+ pci_device_get_function, pci_device_set_function,
+ NULL, NULL, &error_abort);
}
AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
The "addr" property on PCI devices has some magic for parsing it as a single PCI device number (called "slot" internally), or a "<slot>.<function>" string. Add simple integer properties that can represent the device address with no special parsing. Cc: "Michael S. Tsirkin" <mst@redhat.com> Cc: Marcel Apfelbaum <marcel@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- hw/pci/pci.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)