@@ -56,12 +56,32 @@ out:
return ret;
}
+#define IGD_PT_I440FX_CLASS(class) \
+ OBJECT_CLASS_CHECK(IGDPtI440fxClass, (class), \
+ TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE)
+#define IGD_PT_I440FX_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(IGDPtI440fxClass, (obj), \
+ TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE)
+
+typedef struct IGDPtI440fxClass {
+ PCIDeviceClass parent_class;
+ void (*parent_realize)(PCIDevice *dev, Error **errp);
+} IGDPtI440fxClass;
+
static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
{
+ IGDPtI440fxClass *k = IGD_PT_I440FX_GET_CLASS(pci_dev);
+ Error *err = NULL;
uint32_t val = 0;
int rc, i, num;
int pos, len;
+ k->parent_realize(pci_dev, &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
+
num = ARRAY_SIZE(igd_host_bridge_infos);
for (i = 0; i < num; i++) {
pos = igd_host_bridge_infos[i].offset;
@@ -77,17 +97,20 @@ static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
{
+ IGDPtI440fxClass *k = IGD_PT_I440FX_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
- k->realize = igd_pt_i440fx_realize;
- dc->desc = "IGD Passthrough Host bridge";
+ k->parent_realize = pc->realize;
+ pc->realize = igd_pt_i440fx_realize;
+ dc->desc = "IGD Passthrough Host bridge (i440fx)";
}
static const TypeInfo igd_passthrough_i440fx_info = {
.name = TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE,
.parent = TYPE_I440FX_PCI_DEVICE,
.class_init = igd_passthrough_i440fx_class_init,
+ .class_size = sizeof(IGDPtI440fxClass),
};
static void igd_register_types(void)
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/pci-host/igd.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-)