This converts init() callback to realize(). The conversion includes: 1. change of prototype; 2. conversion of fprintf to error_setg; 3. introducing a finish_realize() callback which at the moment does IOMMU setup.
Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru> --- hw/ppc/spapr_pci.c | 82 +++++++++++++++++++++++++++------------------ include/hw/pci-host/spapr.h | 18 ++++++++-- 2 files changed, 66 insertions(+), 34 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 9b6ee32..11bb737 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -32,6 +32,7 @@ #include "exec/address-spaces.h" #include <libfdt.h> #include "trace.h" +#include "qemu/error-report.h" #include "hw/pci/pci_bus.h" @@ -483,15 +484,17 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn) return &phb->iommu_as; } -static int spapr_phb_init(SysBusDevice *s) +static void spapr_phb_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(s); + SysBusDevice *s = SYS_BUS_DEVICE(dev); sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s); PCIHostState *phb = PCI_HOST_BRIDGE(s); + sPAPRPHBClass *info = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(s); const char *busname; char *namebuf; int i; PCIBus *bus; + Error *error = NULL; if (sphb->index != -1) { hwaddr windows_base; @@ -499,9 +502,9 @@ static int spapr_phb_init(SysBusDevice *s) if ((sphb->buid != -1) || (sphb->dma_liobn != -1) || (sphb->mem_win_addr != -1) || (sphb->io_win_addr != -1)) { - fprintf(stderr, "Either \"index\" or other parameters must" - " be specified for PAPR PHB, not both\n"); - return -1; + error_setg(errp, "Either \"index\" or other parameters must" + " be specified for PAPR PHB, not both"); + return; } sphb->buid = SPAPR_PCI_BASE_BUID + sphb->index; @@ -514,28 +517,28 @@ static int spapr_phb_init(SysBusDevice *s) } if (sphb->buid == -1) { - fprintf(stderr, "BUID not specified for PHB\n"); - return -1; + error_setg(errp, "BUID not specified for PHB"); + return; } if (sphb->dma_liobn == -1) { - fprintf(stderr, "LIOBN not specified for PHB\n"); - return -1; + error_setg(errp, "LIOBN not specified for PHB"); + return; } if (sphb->mem_win_addr == -1) { - fprintf(stderr, "Memory window address not specified for PHB\n"); - return -1; + error_setg(errp, "Memory window address not specified for PHB"); + return; } if (sphb->io_win_addr == -1) { - fprintf(stderr, "IO window address not specified for PHB\n"); - return -1; + error_setg(errp, "IO window address not specified for PHB"); + return; } if (find_phb(spapr, sphb->buid)) { - fprintf(stderr, "PCI host bridges must have unique BUIDs\n"); - return -1; + error_setg(errp, "PCI host bridges must have unique BUIDs"); + return; } sphb->dtbusname = g_strdup_printf("pci@%" PRIx64, sphb->buid); @@ -597,19 +600,6 @@ static int spapr_phb_init(SysBusDevice *s) PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS); phb->bus = bus; - sphb->dma_window_start = 0; - sphb->dma_window_size = 0x40000000; - sphb->tcet = spapr_tce_new_table(dev, sphb->dma_liobn, - sphb->dma_window_size); - if (!sphb->tcet) { - fprintf(stderr, "Unable to create TCE table for %s\n", sphb->dtbusname); - return -1; - } - address_space_init(&sphb->iommu_as, spapr_tce_get_iommu(sphb->tcet), - sphb->dtbusname); - - pci_setup_iommu(bus, spapr_pci_dma_iommu, sphb); - QLIST_INSERT_HEAD(&spapr->phbs, sphb, list); /* Initialize the LSI table */ @@ -618,13 +608,39 @@ static int spapr_phb_init(SysBusDevice *s) irq = spapr_allocate_lsi(0); if (!irq) { - return -1; + error_setg(errp, "spapr_allocate_lsi failed"); + return; } sphb->lsi_table[i].irq = irq; } - return 0; + if (!info->finish_realize) { + error_setg(errp, "finish_realize not defined"); + return; + } + info->finish_realize(sphb, &error); + if (error) { + error_propagate(errp, error); + return; + } + + pci_setup_iommu(sphb->parent_obj.bus, spapr_pci_dma_iommu, sphb); +} + +static void spapr_phb_finish_realize(sPAPRPHBState *sphb, Error **errp) +{ + sphb->dma_window_start = 0; + sphb->dma_window_size = 0x40000000; + sphb->tcet = spapr_tce_new_table(DEVICE(sphb), sphb->dma_liobn, + sphb->dma_window_size); + if (!sphb->tcet) { + error_setg(errp, "Unable to create TCE table for %s", + sphb->dtbusname); + return ; + } + address_space_init(&sphb->iommu_as, spapr_tce_get_iommu(sphb->tcet), + sphb->dtbusname); } static void spapr_phb_reset(DeviceState *qdev) @@ -707,14 +723,15 @@ static const char *spapr_phb_root_bus_path(PCIHostState *host_bridge, static void spapr_phb_class_init(ObjectClass *klass, void *data) { PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass); - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); + sPAPRPHBClass *spc = SPAPR_PCI_HOST_BRIDGE_CLASS(klass); hc->root_bus_path = spapr_phb_root_bus_path; - sdc->init = spapr_phb_init; + dc->realize = spapr_phb_realize; dc->props = spapr_phb_properties; dc->reset = spapr_phb_reset; dc->vmsd = &vmstate_spapr_pci; + spc->finish_realize = spapr_phb_finish_realize; } static const TypeInfo spapr_phb_info = { @@ -722,6 +739,7 @@ static const TypeInfo spapr_phb_info = { .parent = TYPE_PCI_HOST_BRIDGE, .instance_size = sizeof(sPAPRPHBState), .class_init = spapr_phb_class_init, + .class_size = sizeof(sPAPRPHBClass), }; PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index) diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 970b4a9..0f428a1 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -34,7 +34,21 @@ #define SPAPR_PCI_HOST_BRIDGE(obj) \ OBJECT_CHECK(sPAPRPHBState, (obj), TYPE_SPAPR_PCI_HOST_BRIDGE) -typedef struct sPAPRPHBState { +#define SPAPR_PCI_HOST_BRIDGE_CLASS(klass) \ + OBJECT_CLASS_CHECK(sPAPRPHBClass, (klass), TYPE_SPAPR_PCI_HOST_BRIDGE) +#define SPAPR_PCI_HOST_BRIDGE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(sPAPRPHBClass, (obj), TYPE_SPAPR_PCI_HOST_BRIDGE) + +typedef struct sPAPRPHBClass sPAPRPHBClass; +typedef struct sPAPRPHBState sPAPRPHBState; + +struct sPAPRPHBClass { + PCIHostBridgeClass parent_class; + + void (*finish_realize)(sPAPRPHBState *sphb, Error **errp); +}; + +struct sPAPRPHBState { PCIHostState parent_obj; int32_t index; @@ -62,7 +76,7 @@ typedef struct sPAPRPHBState { } msi_table[SPAPR_MSIX_MAX_DEVS]; QLIST_ENTRY(sPAPRPHBState) list; -} sPAPRPHBState; +}; #define SPAPR_PCI_BASE_BUID 0x800000020000000ULL -- 1.8.4.rc4