Patchwork [qom-next,v2,1/4] pci-bridge: Turn PCIBridge into abstract QOM type

login
register
mail settings
Submitter Andreas Färber
Date July 22, 2013, 10:36 p.m.
Message ID <1374532568-28051-2-git-send-email-afaerber@suse.de>
Download mbox | patch
Permalink /patch/260829/
State New
Headers show

Comments

Andreas Färber - July 22, 2013, 10:36 p.m.
Introduce TYPE_PCI_BRIDGE as base type and use PCI_BRIDGE() casts.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 hw/pci-bridge/dec.c                |  4 ++--
 hw/pci-bridge/i82801b11.c          |  6 +++---
 hw/pci-bridge/ioh3420.c            | 18 ++++++++---------
 hw/pci-bridge/pci_bridge_dev.c     | 10 +++++-----
 hw/pci-bridge/xio3130_downstream.c | 18 ++++++++---------
 hw/pci-bridge/xio3130_upstream.c   | 19 +++++++++---------
 hw/pci-host/apb.c                  |  4 ++--
 hw/pci/pci.c                       |  2 +-
 hw/pci/pci_bridge.c                | 40 +++++++++++++++++++++++++++-----------
 hw/pci/pcie.c                      |  2 +-
 include/hw/pci/pci_bus.h           |  7 ++++++-
 11 files changed, 77 insertions(+), 53 deletions(-)
Don Koch - July 25, 2013, 8:15 p.m.
On 07/22/2013 06:36 PM, Andreas Färber wrote:
> Introduce TYPE_PCI_BRIDGE as base type and use PCI_BRIDGE() casts.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  hw/pci-bridge/dec.c                |  4 ++--
>  hw/pci-bridge/i82801b11.c          |  6 +++---
>  hw/pci-bridge/ioh3420.c            | 18 ++++++++---------
>  hw/pci-bridge/pci_bridge_dev.c     | 10 +++++-----
>  hw/pci-bridge/xio3130_downstream.c | 18 ++++++++---------
>  hw/pci-bridge/xio3130_upstream.c   | 19 +++++++++---------
>  hw/pci-host/apb.c                  |  4 ++--
>  hw/pci/pci.c                       |  2 +-
>  hw/pci/pci_bridge.c                | 40 +++++++++++++++++++++++++++-----------
>  hw/pci/pcie.c                      |  2 +-
>  include/hw/pci/pci_bus.h           |  7 ++++++-
>  11 files changed, 77 insertions(+), 53 deletions(-)

Saved me the trouble of doing this myself. Thanks! ;)

Reviewed-by: Don Koch <dkoch@verizon.com>
Michael S. Tsirkin - July 25, 2013, 9:08 p.m.
On Tue, Jul 23, 2013 at 12:36:05AM +0200, Andreas Färber wrote:
> Introduce TYPE_PCI_BRIDGE as base type and use PCI_BRIDGE() casts.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  hw/pci-bridge/dec.c                |  4 ++--
>  hw/pci-bridge/i82801b11.c          |  6 +++---
>  hw/pci-bridge/ioh3420.c            | 18 ++++++++---------
>  hw/pci-bridge/pci_bridge_dev.c     | 10 +++++-----
>  hw/pci-bridge/xio3130_downstream.c | 18 ++++++++---------
>  hw/pci-bridge/xio3130_upstream.c   | 19 +++++++++---------
>  hw/pci-host/apb.c                  |  4 ++--
>  hw/pci/pci.c                       |  2 +-
>  hw/pci/pci_bridge.c                | 40 +++++++++++++++++++++++++++-----------
>  hw/pci/pcie.c                      |  2 +-
>  include/hw/pci/pci_bus.h           |  7 ++++++-
>  11 files changed, 77 insertions(+), 53 deletions(-)
> 
> diff --git a/hw/pci-bridge/dec.c b/hw/pci-bridge/dec.c
> index efc07c4..e5e3be8 100644
> --- a/hw/pci-bridge/dec.c
> +++ b/hw/pci-bridge/dec.c
> @@ -74,7 +74,7 @@ static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
>  
>  static const TypeInfo dec_21154_pci_bridge_info = {
>      .name          = "dec-21154-p2p-bridge",
> -    .parent        = TYPE_PCI_DEVICE,
> +    .parent        = TYPE_PCI_BRIDGE,
>      .instance_size = sizeof(PCIBridge),
>      .class_init    = dec_21154_pci_bridge_class_init,
>  };
> @@ -86,7 +86,7 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
>  
>      dev = pci_create_multifunction(parent_bus, devfn, false,
>                                     "dec-21154-p2p-bridge");
> -    br = DO_UPCAST(PCIBridge, dev, dev);
> +    br = PCI_BRIDGE(dev);
>      pci_bridge_map_irq(br, "DEC 21154 PCI-PCI bridge", dec_map_irq);
>      qdev_init_nofail(&dev->qdev);
>      return pci_bridge_get_sec_bus(br);
> diff --git a/hw/pci-bridge/i82801b11.c b/hw/pci-bridge/i82801b11.c
> index b98bfb0..88f489a 100644
> --- a/hw/pci-bridge/i82801b11.c
> +++ b/hw/pci-bridge/i82801b11.c
> @@ -91,7 +91,7 @@ static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
>  
>  static const TypeInfo i82801b11_bridge_info = {
>      .name          = "i82801b11-bridge",
> -    .parent        = TYPE_PCI_DEVICE,
> +    .parent        = TYPE_PCI_BRIDGE,
>      .instance_size = sizeof(I82801b11Bridge),
>      .class_init    = i82801b11_bridge_class_init,
>  };
> @@ -107,8 +107,8 @@ PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus)
>      if (!d) {
>          return NULL;
>      }
> -    br = DO_UPCAST(PCIBridge, dev, d);
> -    qdev = &br->dev.qdev;
> +    br = PCI_BRIDGE(d);
> +    qdev = DEVICE(d);
>  
>      snprintf(buf, sizeof(buf), "pci.%d", sec_bus);
>      pci_bridge_map_irq(br, buf, pci_swizzle_map_irq_fn);
> diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c
> index bb541eb..728f658 100644
> --- a/hw/pci-bridge/ioh3420.c
> +++ b/hw/pci-bridge/ioh3420.c
> @@ -92,7 +92,7 @@ static void ioh3420_reset(DeviceState *qdev)
>  
>  static int ioh3420_initfn(PCIDevice *d)
>  {
> -    PCIBridge* br = DO_UPCAST(PCIBridge, dev, d);
> +    PCIBridge *br = PCI_BRIDGE(d);
>      PCIEPort *p = DO_UPCAST(PCIEPort, br, br);
>      PCIESlot *s = DO_UPCAST(PCIESlot, port, p);
>      int rc;
> @@ -148,7 +148,7 @@ err_bridge:
>  
>  static void ioh3420_exitfn(PCIDevice *d)
>  {
> -    PCIBridge* br = DO_UPCAST(PCIBridge, dev, d);
> +    PCIBridge *br = PCI_BRIDGE(d);
>      PCIEPort *p = DO_UPCAST(PCIEPort, br, br);
>      PCIESlot *s = DO_UPCAST(PCIESlot, port, p);
>  
> @@ -171,9 +171,9 @@ PCIESlot *ioh3420_init(PCIBus *bus, int devfn, bool multifunction,
>      if (!d) {
>          return NULL;
>      }
> -    br = DO_UPCAST(PCIBridge, dev, d);
> +    br = PCI_BRIDGE(d);
>  
> -    qdev = &br->dev.qdev;
> +    qdev = DEVICE(d);
>      pci_bridge_map_irq(br, bus_name, map_irq);
>      qdev_prop_set_uint8(qdev, "port", port);
>      qdev_prop_set_uint8(qdev, "chassis", chassis);
> @@ -190,8 +190,8 @@ static const VMStateDescription vmstate_ioh3420 = {
>      .minimum_version_id_old = 1,
>      .post_load = pcie_cap_slot_post_load,
>      .fields = (VMStateField[]) {
> -        VMSTATE_PCIE_DEVICE(port.br.dev, PCIESlot),
> -        VMSTATE_STRUCT(port.br.dev.exp.aer_log, PCIESlot, 0,
> +        VMSTATE_PCIE_DEVICE(port.br.parent_obj, PCIESlot),
> +        VMSTATE_STRUCT(port.br.parent_obj.exp.aer_log, PCIESlot, 0,
>                         vmstate_pcie_aer_log, PCIEAERLog),
>          VMSTATE_END_OF_LIST()
>      }
> @@ -202,8 +202,8 @@ static Property ioh3420_properties[] = {
>      DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
>      DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
>      DEFINE_PROP_UINT16("aer_log_max", PCIESlot,
> -    port.br.dev.exp.aer_log.log_max,
> -    PCIE_AER_LOG_MAX_DEFAULT),
> +                       port.br.parent_obj.exp.aer_log.log_max,
> +                       PCIE_AER_LOG_MAX_DEFAULT),
>      DEFINE_PROP_END_OF_LIST(),
>  };
>  
> @@ -228,7 +228,7 @@ static void ioh3420_class_init(ObjectClass *klass, void *data)
>  
>  static const TypeInfo ioh3420_info = {
>      .name          = "ioh3420",
> -    .parent        = TYPE_PCI_DEVICE,
> +    .parent        = TYPE_PCI_BRIDGE,
>      .instance_size = sizeof(PCIESlot),
>      .class_init    = ioh3420_class_init,
>  };
> diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c
> index 5f11323..00d2382 100644
> --- a/hw/pci-bridge/pci_bridge_dev.c
> +++ b/hw/pci-bridge/pci_bridge_dev.c
> @@ -38,7 +38,7 @@ typedef struct PCIBridgeDev PCIBridgeDev;
>  
>  static int pci_bridge_dev_initfn(PCIDevice *dev)
>  {
> -    PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev);
> +    PCIBridge *br = PCI_BRIDGE(dev);
>      PCIBridgeDev *bridge_dev = DO_UPCAST(PCIBridgeDev, bridge, br);
>      int err;
>  
> @@ -81,7 +81,7 @@ bridge_error:
>  
>  static void pci_bridge_dev_exitfn(PCIDevice *dev)
>  {
> -    PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev);
> +    PCIBridge *br = PCI_BRIDGE(dev);
>      PCIBridgeDev *bridge_dev = DO_UPCAST(PCIBridgeDev, bridge, br);
>      if (msi_present(dev)) {
>          msi_uninit(dev);
> @@ -120,8 +120,8 @@ static Property pci_bridge_dev_properties[] = {
>  static const VMStateDescription pci_bridge_dev_vmstate = {
>      .name = "pci_bridge",
>      .fields = (VMStateField[]) {
> -        VMSTATE_PCI_DEVICE(bridge.dev, PCIBridgeDev),
> -        SHPC_VMSTATE(bridge.dev.shpc, PCIBridgeDev),
> +        VMSTATE_PCI_DEVICE(bridge.parent_obj, PCIBridgeDev),
> +        SHPC_VMSTATE(bridge.parent_obj.shpc, PCIBridgeDev),
>          VMSTATE_END_OF_LIST()
>      }
>  };
> @@ -145,7 +145,7 @@ static void pci_bridge_dev_class_init(ObjectClass *klass, void *data)
>  
>  static const TypeInfo pci_bridge_dev_info = {
>      .name = "pci-bridge",
> -    .parent        = TYPE_PCI_DEVICE,
> +    .parent        = TYPE_PCI_BRIDGE,
>      .instance_size = sizeof(PCIBridgeDev),
>      .class_init = pci_bridge_dev_class_init,
>  };
> diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
> index 1810dd2..9acce3f 100644
> --- a/hw/pci-bridge/xio3130_downstream.c
> +++ b/hw/pci-bridge/xio3130_downstream.c
> @@ -56,7 +56,7 @@ static void xio3130_downstream_reset(DeviceState *qdev)
>  
>  static int xio3130_downstream_initfn(PCIDevice *d)
>  {
> -    PCIBridge* br = DO_UPCAST(PCIBridge, dev, d);
> +    PCIBridge *br = PCI_BRIDGE(d);
>      PCIEPort *p = DO_UPCAST(PCIEPort, br, br);
>      PCIESlot *s = DO_UPCAST(PCIESlot, port, p);
>      int rc;
> @@ -113,7 +113,7 @@ err_bridge:
>  
>  static void xio3130_downstream_exitfn(PCIDevice *d)
>  {
> -    PCIBridge* br = DO_UPCAST(PCIBridge, dev, d);
> +    PCIBridge *br = PCI_BRIDGE(d);
>      PCIEPort *p = DO_UPCAST(PCIEPort, br, br);
>      PCIESlot *s = DO_UPCAST(PCIESlot, port, p);
>  
> @@ -138,9 +138,9 @@ PCIESlot *xio3130_downstream_init(PCIBus *bus, int devfn, bool multifunction,
>      if (!d) {
>          return NULL;
>      }
> -    br = DO_UPCAST(PCIBridge, dev, d);
> +    br = PCI_BRIDGE(d);
>  
> -    qdev = &br->dev.qdev;
> +    qdev = DEVICE(d);
>      pci_bridge_map_irq(br, bus_name, map_irq);
>      qdev_prop_set_uint8(qdev, "port", port);
>      qdev_prop_set_uint8(qdev, "chassis", chassis);
> @@ -157,8 +157,8 @@ static const VMStateDescription vmstate_xio3130_downstream = {
>      .minimum_version_id_old = 1,
>      .post_load = pcie_cap_slot_post_load,
>      .fields = (VMStateField[]) {
> -        VMSTATE_PCIE_DEVICE(port.br.dev, PCIESlot),
> -        VMSTATE_STRUCT(port.br.dev.exp.aer_log, PCIESlot, 0,
> +        VMSTATE_PCIE_DEVICE(port.br.parent_obj, PCIESlot),
> +        VMSTATE_STRUCT(port.br.parent_obj.exp.aer_log, PCIESlot, 0,
>                         vmstate_pcie_aer_log, PCIEAERLog),
>          VMSTATE_END_OF_LIST()
>      }
> @@ -169,8 +169,8 @@ static Property xio3130_downstream_properties[] = {
>      DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
>      DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
>      DEFINE_PROP_UINT16("aer_log_max", PCIESlot,
> -    port.br.dev.exp.aer_log.log_max,
> -    PCIE_AER_LOG_MAX_DEFAULT),
> +                       port.br.parent_obj.exp.aer_log.log_max,
> +                       PCIE_AER_LOG_MAX_DEFAULT),
>      DEFINE_PROP_END_OF_LIST(),
>  };
>  
> @@ -195,7 +195,7 @@ static void xio3130_downstream_class_init(ObjectClass *klass, void *data)
>  
>  static const TypeInfo xio3130_downstream_info = {
>      .name          = "xio3130-downstream",
> -    .parent        = TYPE_PCI_DEVICE,
> +    .parent        = TYPE_PCI_BRIDGE,
>      .instance_size = sizeof(PCIESlot),
>      .class_init    = xio3130_downstream_class_init,
>  };
> diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c
> index 8e0d97a..0bc1d05 100644
> --- a/hw/pci-bridge/xio3130_upstream.c
> +++ b/hw/pci-bridge/xio3130_upstream.c
> @@ -53,7 +53,7 @@ static void xio3130_upstream_reset(DeviceState *qdev)
>  
>  static int xio3130_upstream_initfn(PCIDevice *d)
>  {
> -    PCIBridge* br = DO_UPCAST(PCIBridge, dev, d);
> +    PCIBridge *br = PCI_BRIDGE(d);
>      PCIEPort *p = DO_UPCAST(PCIEPort, br, br);
>      int rc;
>  
> @@ -118,9 +118,9 @@ PCIEPort *xio3130_upstream_init(PCIBus *bus, int devfn, bool multifunction,
>      if (!d) {
>          return NULL;
>      }
> -    br = DO_UPCAST(PCIBridge, dev, d);
> +    br = PCI_BRIDGE(d);
>  
> -    qdev = &br->dev.qdev;
> +    qdev = DEVICE(d);
>      pci_bridge_map_irq(br, bus_name, map_irq);
>      qdev_prop_set_uint8(qdev, "port", port);
>      qdev_init_nofail(qdev);
> @@ -134,17 +134,18 @@ static const VMStateDescription vmstate_xio3130_upstream = {
>      .minimum_version_id = 1,
>      .minimum_version_id_old = 1,
>      .fields = (VMStateField[]) {
> -        VMSTATE_PCIE_DEVICE(br.dev, PCIEPort),
> -        VMSTATE_STRUCT(br.dev.exp.aer_log, PCIEPort, 0, vmstate_pcie_aer_log,
> -                       PCIEAERLog),
> +        VMSTATE_PCIE_DEVICE(br.parent_obj, PCIEPort),
> +        VMSTATE_STRUCT(br.parent_obj.exp.aer_log, PCIEPort, 0,
> +                       vmstate_pcie_aer_log, PCIEAERLog),
>          VMSTATE_END_OF_LIST()
>      }
>  };
>  
>  static Property xio3130_upstream_properties[] = {
>      DEFINE_PROP_UINT8("port", PCIEPort, port, 0),
> -    DEFINE_PROP_UINT16("aer_log_max", PCIEPort, br.dev.exp.aer_log.log_max,
> -    PCIE_AER_LOG_MAX_DEFAULT),
> +    DEFINE_PROP_UINT16("aer_log_max", PCIEPort,
> +                       br.parent_obj.exp.aer_log.log_max,
> +                       PCIE_AER_LOG_MAX_DEFAULT),
>      DEFINE_PROP_END_OF_LIST(),
>  };
>  
> @@ -169,7 +170,7 @@ static void xio3130_upstream_class_init(ObjectClass *klass, void *data)
>  
>  static const TypeInfo xio3130_upstream_info = {
>      .name          = "x3130-upstream",
> -    .parent        = TYPE_PCI_DEVICE,
> +    .parent        = TYPE_PCI_BRIDGE,
>      .instance_size = sizeof(PCIEPort),
>      .class_init    = xio3130_upstream_class_init,
>  };
> diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
> index 06ace08..0277aa0 100644
> --- a/hw/pci-host/apb.c
> +++ b/hw/pci-host/apb.c
> @@ -464,7 +464,7 @@ PCIBus *pci_apb_init(hwaddr special_base,
>      /* APB secondary busses */
>      pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 0), true,
>                                     "pbm-bridge");
> -    br = DO_UPCAST(PCIBridge, dev, pci_dev);
> +    br = PCI_BRIDGE(pci_dev);
>      pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 1",
>                         pci_apb_map_irq);
>      qdev_init_nofail(&pci_dev->qdev);
> @@ -472,7 +472,7 @@ PCIBus *pci_apb_init(hwaddr special_base,
>  
>      pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 1), true,
>                                     "pbm-bridge");
> -    br = DO_UPCAST(PCIBridge, dev, pci_dev);
> +    br = PCI_BRIDGE(pci_dev);
>      pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 2",
>                         pci_apb_map_irq);
>      qdev_init_nofail(&pci_dev->qdev);
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index 81cf5a9..4c004f5 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -397,7 +397,7 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
>  
>      pci_update_mappings(s);
>      if (pc->is_bridge) {
> -        PCIBridge *b = container_of(s, PCIBridge, dev);
> +        PCIBridge *b = PCI_BRIDGE(s);
>          pci_bridge_update_mappings(b);
>      }
>  
> diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
> index 02a396b..a90671d 100644
> --- a/hw/pci/pci_bridge.c
> +++ b/hw/pci/pci_bridge.c
> @@ -141,8 +141,9 @@ static void pci_bridge_init_alias(PCIBridge *bridge, MemoryRegion *alias,
>                                    MemoryRegion *parent_space,
>                                    bool enabled)
>  {
> -    pcibus_t base = pci_bridge_get_base(&bridge->dev, type);
> -    pcibus_t limit = pci_bridge_get_limit(&bridge->dev, type);
> +    PCIDevice *bridge_dev = PCI_DEVICE(bridge);
> +    pcibus_t base = pci_bridge_get_base(bridge_dev, type);
> +    pcibus_t limit = pci_bridge_get_limit(bridge_dev, type);
>      /* TODO: this doesn't handle base = 0 limit = 2^64 - 1 correctly.
>       * Apparently no way to do this with existing memory APIs. */
>      pcibus_t size = enabled && limit >= base ? limit + 1 - base : 0;
> @@ -154,7 +155,8 @@ static void pci_bridge_init_alias(PCIBridge *bridge, MemoryRegion *alias,
>  static void pci_bridge_init_vga_aliases(PCIBridge *br, PCIBus *parent,
>                                          MemoryRegion *alias_vga)
>  {
> -    uint16_t brctl = pci_get_word(br->dev.config + PCI_BRIDGE_CONTROL);
> +    PCIDevice *pd = PCI_DEVICE(br);
> +    uint16_t brctl = pci_get_word(pd->config + PCI_BRIDGE_CONTROL);
>  
>      memory_region_init_alias(&alias_vga[QEMU_PCI_VGA_IO_LO], OBJECT(br),
>                               "pci_bridge_vga_io_lo", &br->address_space_io,
> @@ -167,7 +169,7 @@ static void pci_bridge_init_vga_aliases(PCIBridge *br, PCIBus *parent,
>                               QEMU_PCI_VGA_MEM_BASE, QEMU_PCI_VGA_MEM_SIZE);
>  
>      if (brctl & PCI_BRIDGE_CTL_VGA) {
> -        pci_register_vga(&br->dev, &alias_vga[QEMU_PCI_VGA_MEM],
> +        pci_register_vga(pd, &alias_vga[QEMU_PCI_VGA_MEM],
>                           &alias_vga[QEMU_PCI_VGA_IO_LO],
>                           &alias_vga[QEMU_PCI_VGA_IO_HI]);
>      }
> @@ -175,9 +177,10 @@ static void pci_bridge_init_vga_aliases(PCIBridge *br, PCIBus *parent,
>  
>  static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br)
>  {
> -    PCIBus *parent = br->dev.bus;
> +    PCIDevice *pd = PCI_DEVICE(br);
> +    PCIBus *parent = pd->bus;
>      PCIBridgeWindows *w = g_new(PCIBridgeWindows, 1);
> -    uint16_t cmd = pci_get_word(br->dev.config + PCI_COMMAND);
> +    uint16_t cmd = pci_get_word(pd->config + PCI_COMMAND);
>  
>      pci_bridge_init_alias(br, &w->alias_pref_mem,
>                            PCI_BASE_ADDRESS_MEM_PREFETCH,
> @@ -205,12 +208,13 @@ static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br)
>  
>  static void pci_bridge_region_del(PCIBridge *br, PCIBridgeWindows *w)
>  {
> -    PCIBus *parent = br->dev.bus;
> +    PCIDevice *pd = PCI_DEVICE(br);
> +    PCIBus *parent = pd->bus;
>  
>      memory_region_del_subregion(parent->address_space_io, &w->alias_io);
>      memory_region_del_subregion(parent->address_space_mem, &w->alias_mem);
>      memory_region_del_subregion(parent->address_space_mem, &w->alias_pref_mem);
> -    pci_unregister_vga(&br->dev);
> +    pci_unregister_vga(pd);
>  }
>  
>  static void pci_bridge_region_cleanup(PCIBridge *br, PCIBridgeWindows *w)
> @@ -241,7 +245,7 @@ void pci_bridge_update_mappings(PCIBridge *br)
>  void pci_bridge_write_config(PCIDevice *d,
>                               uint32_t address, uint32_t val, int len)
>  {
> -    PCIBridge *s = container_of(d, PCIBridge, dev);
> +    PCIBridge *s = PCI_BRIDGE(d);
>      uint16_t oldctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL);
>      uint16_t newctl;
>  
> @@ -331,7 +335,7 @@ void pci_bridge_reset(DeviceState *qdev)
>  int pci_bridge_initfn(PCIDevice *dev, const char *typename)
>  {
>      PCIBus *parent = dev->bus;
> -    PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev);
> +    PCIBridge *br = PCI_BRIDGE(dev);
>      PCIBus *sec_bus = &br->sec_bus;
>  
>      pci_word_test_and_set_mask(dev->config + PCI_STATUS,
> @@ -379,7 +383,7 @@ int pci_bridge_initfn(PCIDevice *dev, const char *typename)
>  /* default qdev clean up function for PCI-to-PCI bridge */
>  void pci_bridge_exitfn(PCIDevice *pci_dev)
>  {
> -    PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev);
> +    PCIBridge *s = PCI_BRIDGE(pci_dev);
>      assert(QLIST_EMPTY(&s->sec_bus.child));
>      QLIST_REMOVE(&s->sec_bus, sibling);
>      pci_bridge_region_del(s, s->windows);
> @@ -400,3 +404,17 @@ void pci_bridge_map_irq(PCIBridge *br, const char* bus_name,
>      br->map_irq = map_irq;
>      br->bus_name = bus_name;
>  }
> +
> +static const TypeInfo pci_bridge_type_info = {
> +    .name = TYPE_PCI_BRIDGE,
> +    .parent = TYPE_PCI_DEVICE,
> +    .instance_size = sizeof(PCIBridge),
> +    .abstract = true,
> +};
> +
> +static void pci_bridge_register_types(void)
> +{
> +    type_register_static(&pci_bridge_type_info);
> +}
> +
> +type_init(pci_bridge_register_types)
> diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
> index 62bd0b8..50af3c1 100644
> --- a/hw/pci/pcie.c
> +++ b/hw/pci/pcie.c
> @@ -305,7 +305,7 @@ void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
>  
>      dev->exp.hpev_notified = false;
>  
> -    pci_bus_hotplug(pci_bridge_get_sec_bus(DO_UPCAST(PCIBridge, dev, dev)),
> +    pci_bus_hotplug(pci_bridge_get_sec_bus(PCI_BRIDGE(dev)),
>                      pcie_cap_slot_hotplug, &dev->qdev);
>  }
>  
> diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
> index 66762f6..9df1788 100644
> --- a/include/hw/pci/pci_bus.h
> +++ b/include/hw/pci/pci_bus.h
> @@ -53,8 +53,13 @@ struct PCIBridgeWindows {
>      MemoryRegion alias_vga[QEMU_PCI_VGA_NUM_REGIONS];
>  };
>  
> +#define TYPE_PCI_BRIDGE "base-pci-bridge"
> +#define PCI_BRIDGE(obj) OBJECT_CHECK(PCIBridge, (obj), TYPE_PCI_BRIDGE)
> +
>  struct PCIBridge {
> -    PCIDevice dev;
> +    /*< private >*/
> +    PCIDevice parent_obj;
> +    /*< public >*/
>  
>      /* private member */
>      PCIBus sec_bus;

I'd prefer keeping it called dev as a more descriptive name,
but I guess we can live with it as is.

Acked-by: Michael S. Tsirkin <mst@redhat.com>


> -- 
> 1.8.1.4

Patch

diff --git a/hw/pci-bridge/dec.c b/hw/pci-bridge/dec.c
index efc07c4..e5e3be8 100644
--- a/hw/pci-bridge/dec.c
+++ b/hw/pci-bridge/dec.c
@@ -74,7 +74,7 @@  static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
 
 static const TypeInfo dec_21154_pci_bridge_info = {
     .name          = "dec-21154-p2p-bridge",
-    .parent        = TYPE_PCI_DEVICE,
+    .parent        = TYPE_PCI_BRIDGE,
     .instance_size = sizeof(PCIBridge),
     .class_init    = dec_21154_pci_bridge_class_init,
 };
@@ -86,7 +86,7 @@  PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
 
     dev = pci_create_multifunction(parent_bus, devfn, false,
                                    "dec-21154-p2p-bridge");
-    br = DO_UPCAST(PCIBridge, dev, dev);
+    br = PCI_BRIDGE(dev);
     pci_bridge_map_irq(br, "DEC 21154 PCI-PCI bridge", dec_map_irq);
     qdev_init_nofail(&dev->qdev);
     return pci_bridge_get_sec_bus(br);
diff --git a/hw/pci-bridge/i82801b11.c b/hw/pci-bridge/i82801b11.c
index b98bfb0..88f489a 100644
--- a/hw/pci-bridge/i82801b11.c
+++ b/hw/pci-bridge/i82801b11.c
@@ -91,7 +91,7 @@  static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
 
 static const TypeInfo i82801b11_bridge_info = {
     .name          = "i82801b11-bridge",
-    .parent        = TYPE_PCI_DEVICE,
+    .parent        = TYPE_PCI_BRIDGE,
     .instance_size = sizeof(I82801b11Bridge),
     .class_init    = i82801b11_bridge_class_init,
 };
@@ -107,8 +107,8 @@  PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus)
     if (!d) {
         return NULL;
     }
-    br = DO_UPCAST(PCIBridge, dev, d);
-    qdev = &br->dev.qdev;
+    br = PCI_BRIDGE(d);
+    qdev = DEVICE(d);
 
     snprintf(buf, sizeof(buf), "pci.%d", sec_bus);
     pci_bridge_map_irq(br, buf, pci_swizzle_map_irq_fn);
diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c
index bb541eb..728f658 100644
--- a/hw/pci-bridge/ioh3420.c
+++ b/hw/pci-bridge/ioh3420.c
@@ -92,7 +92,7 @@  static void ioh3420_reset(DeviceState *qdev)
 
 static int ioh3420_initfn(PCIDevice *d)
 {
-    PCIBridge* br = DO_UPCAST(PCIBridge, dev, d);
+    PCIBridge *br = PCI_BRIDGE(d);
     PCIEPort *p = DO_UPCAST(PCIEPort, br, br);
     PCIESlot *s = DO_UPCAST(PCIESlot, port, p);
     int rc;
@@ -148,7 +148,7 @@  err_bridge:
 
 static void ioh3420_exitfn(PCIDevice *d)
 {
-    PCIBridge* br = DO_UPCAST(PCIBridge, dev, d);
+    PCIBridge *br = PCI_BRIDGE(d);
     PCIEPort *p = DO_UPCAST(PCIEPort, br, br);
     PCIESlot *s = DO_UPCAST(PCIESlot, port, p);
 
@@ -171,9 +171,9 @@  PCIESlot *ioh3420_init(PCIBus *bus, int devfn, bool multifunction,
     if (!d) {
         return NULL;
     }
-    br = DO_UPCAST(PCIBridge, dev, d);
+    br = PCI_BRIDGE(d);
 
-    qdev = &br->dev.qdev;
+    qdev = DEVICE(d);
     pci_bridge_map_irq(br, bus_name, map_irq);
     qdev_prop_set_uint8(qdev, "port", port);
     qdev_prop_set_uint8(qdev, "chassis", chassis);
@@ -190,8 +190,8 @@  static const VMStateDescription vmstate_ioh3420 = {
     .minimum_version_id_old = 1,
     .post_load = pcie_cap_slot_post_load,
     .fields = (VMStateField[]) {
-        VMSTATE_PCIE_DEVICE(port.br.dev, PCIESlot),
-        VMSTATE_STRUCT(port.br.dev.exp.aer_log, PCIESlot, 0,
+        VMSTATE_PCIE_DEVICE(port.br.parent_obj, PCIESlot),
+        VMSTATE_STRUCT(port.br.parent_obj.exp.aer_log, PCIESlot, 0,
                        vmstate_pcie_aer_log, PCIEAERLog),
         VMSTATE_END_OF_LIST()
     }
@@ -202,8 +202,8 @@  static Property ioh3420_properties[] = {
     DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
     DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
     DEFINE_PROP_UINT16("aer_log_max", PCIESlot,
-    port.br.dev.exp.aer_log.log_max,
-    PCIE_AER_LOG_MAX_DEFAULT),
+                       port.br.parent_obj.exp.aer_log.log_max,
+                       PCIE_AER_LOG_MAX_DEFAULT),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -228,7 +228,7 @@  static void ioh3420_class_init(ObjectClass *klass, void *data)
 
 static const TypeInfo ioh3420_info = {
     .name          = "ioh3420",
-    .parent        = TYPE_PCI_DEVICE,
+    .parent        = TYPE_PCI_BRIDGE,
     .instance_size = sizeof(PCIESlot),
     .class_init    = ioh3420_class_init,
 };
diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c
index 5f11323..00d2382 100644
--- a/hw/pci-bridge/pci_bridge_dev.c
+++ b/hw/pci-bridge/pci_bridge_dev.c
@@ -38,7 +38,7 @@  typedef struct PCIBridgeDev PCIBridgeDev;
 
 static int pci_bridge_dev_initfn(PCIDevice *dev)
 {
-    PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev);
+    PCIBridge *br = PCI_BRIDGE(dev);
     PCIBridgeDev *bridge_dev = DO_UPCAST(PCIBridgeDev, bridge, br);
     int err;
 
@@ -81,7 +81,7 @@  bridge_error:
 
 static void pci_bridge_dev_exitfn(PCIDevice *dev)
 {
-    PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev);
+    PCIBridge *br = PCI_BRIDGE(dev);
     PCIBridgeDev *bridge_dev = DO_UPCAST(PCIBridgeDev, bridge, br);
     if (msi_present(dev)) {
         msi_uninit(dev);
@@ -120,8 +120,8 @@  static Property pci_bridge_dev_properties[] = {
 static const VMStateDescription pci_bridge_dev_vmstate = {
     .name = "pci_bridge",
     .fields = (VMStateField[]) {
-        VMSTATE_PCI_DEVICE(bridge.dev, PCIBridgeDev),
-        SHPC_VMSTATE(bridge.dev.shpc, PCIBridgeDev),
+        VMSTATE_PCI_DEVICE(bridge.parent_obj, PCIBridgeDev),
+        SHPC_VMSTATE(bridge.parent_obj.shpc, PCIBridgeDev),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -145,7 +145,7 @@  static void pci_bridge_dev_class_init(ObjectClass *klass, void *data)
 
 static const TypeInfo pci_bridge_dev_info = {
     .name = "pci-bridge",
-    .parent        = TYPE_PCI_DEVICE,
+    .parent        = TYPE_PCI_BRIDGE,
     .instance_size = sizeof(PCIBridgeDev),
     .class_init = pci_bridge_dev_class_init,
 };
diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
index 1810dd2..9acce3f 100644
--- a/hw/pci-bridge/xio3130_downstream.c
+++ b/hw/pci-bridge/xio3130_downstream.c
@@ -56,7 +56,7 @@  static void xio3130_downstream_reset(DeviceState *qdev)
 
 static int xio3130_downstream_initfn(PCIDevice *d)
 {
-    PCIBridge* br = DO_UPCAST(PCIBridge, dev, d);
+    PCIBridge *br = PCI_BRIDGE(d);
     PCIEPort *p = DO_UPCAST(PCIEPort, br, br);
     PCIESlot *s = DO_UPCAST(PCIESlot, port, p);
     int rc;
@@ -113,7 +113,7 @@  err_bridge:
 
 static void xio3130_downstream_exitfn(PCIDevice *d)
 {
-    PCIBridge* br = DO_UPCAST(PCIBridge, dev, d);
+    PCIBridge *br = PCI_BRIDGE(d);
     PCIEPort *p = DO_UPCAST(PCIEPort, br, br);
     PCIESlot *s = DO_UPCAST(PCIESlot, port, p);
 
@@ -138,9 +138,9 @@  PCIESlot *xio3130_downstream_init(PCIBus *bus, int devfn, bool multifunction,
     if (!d) {
         return NULL;
     }
-    br = DO_UPCAST(PCIBridge, dev, d);
+    br = PCI_BRIDGE(d);
 
-    qdev = &br->dev.qdev;
+    qdev = DEVICE(d);
     pci_bridge_map_irq(br, bus_name, map_irq);
     qdev_prop_set_uint8(qdev, "port", port);
     qdev_prop_set_uint8(qdev, "chassis", chassis);
@@ -157,8 +157,8 @@  static const VMStateDescription vmstate_xio3130_downstream = {
     .minimum_version_id_old = 1,
     .post_load = pcie_cap_slot_post_load,
     .fields = (VMStateField[]) {
-        VMSTATE_PCIE_DEVICE(port.br.dev, PCIESlot),
-        VMSTATE_STRUCT(port.br.dev.exp.aer_log, PCIESlot, 0,
+        VMSTATE_PCIE_DEVICE(port.br.parent_obj, PCIESlot),
+        VMSTATE_STRUCT(port.br.parent_obj.exp.aer_log, PCIESlot, 0,
                        vmstate_pcie_aer_log, PCIEAERLog),
         VMSTATE_END_OF_LIST()
     }
@@ -169,8 +169,8 @@  static Property xio3130_downstream_properties[] = {
     DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
     DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
     DEFINE_PROP_UINT16("aer_log_max", PCIESlot,
-    port.br.dev.exp.aer_log.log_max,
-    PCIE_AER_LOG_MAX_DEFAULT),
+                       port.br.parent_obj.exp.aer_log.log_max,
+                       PCIE_AER_LOG_MAX_DEFAULT),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -195,7 +195,7 @@  static void xio3130_downstream_class_init(ObjectClass *klass, void *data)
 
 static const TypeInfo xio3130_downstream_info = {
     .name          = "xio3130-downstream",
-    .parent        = TYPE_PCI_DEVICE,
+    .parent        = TYPE_PCI_BRIDGE,
     .instance_size = sizeof(PCIESlot),
     .class_init    = xio3130_downstream_class_init,
 };
diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c
index 8e0d97a..0bc1d05 100644
--- a/hw/pci-bridge/xio3130_upstream.c
+++ b/hw/pci-bridge/xio3130_upstream.c
@@ -53,7 +53,7 @@  static void xio3130_upstream_reset(DeviceState *qdev)
 
 static int xio3130_upstream_initfn(PCIDevice *d)
 {
-    PCIBridge* br = DO_UPCAST(PCIBridge, dev, d);
+    PCIBridge *br = PCI_BRIDGE(d);
     PCIEPort *p = DO_UPCAST(PCIEPort, br, br);
     int rc;
 
@@ -118,9 +118,9 @@  PCIEPort *xio3130_upstream_init(PCIBus *bus, int devfn, bool multifunction,
     if (!d) {
         return NULL;
     }
-    br = DO_UPCAST(PCIBridge, dev, d);
+    br = PCI_BRIDGE(d);
 
-    qdev = &br->dev.qdev;
+    qdev = DEVICE(d);
     pci_bridge_map_irq(br, bus_name, map_irq);
     qdev_prop_set_uint8(qdev, "port", port);
     qdev_init_nofail(qdev);
@@ -134,17 +134,18 @@  static const VMStateDescription vmstate_xio3130_upstream = {
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .fields = (VMStateField[]) {
-        VMSTATE_PCIE_DEVICE(br.dev, PCIEPort),
-        VMSTATE_STRUCT(br.dev.exp.aer_log, PCIEPort, 0, vmstate_pcie_aer_log,
-                       PCIEAERLog),
+        VMSTATE_PCIE_DEVICE(br.parent_obj, PCIEPort),
+        VMSTATE_STRUCT(br.parent_obj.exp.aer_log, PCIEPort, 0,
+                       vmstate_pcie_aer_log, PCIEAERLog),
         VMSTATE_END_OF_LIST()
     }
 };
 
 static Property xio3130_upstream_properties[] = {
     DEFINE_PROP_UINT8("port", PCIEPort, port, 0),
-    DEFINE_PROP_UINT16("aer_log_max", PCIEPort, br.dev.exp.aer_log.log_max,
-    PCIE_AER_LOG_MAX_DEFAULT),
+    DEFINE_PROP_UINT16("aer_log_max", PCIEPort,
+                       br.parent_obj.exp.aer_log.log_max,
+                       PCIE_AER_LOG_MAX_DEFAULT),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -169,7 +170,7 @@  static void xio3130_upstream_class_init(ObjectClass *klass, void *data)
 
 static const TypeInfo xio3130_upstream_info = {
     .name          = "x3130-upstream",
-    .parent        = TYPE_PCI_DEVICE,
+    .parent        = TYPE_PCI_BRIDGE,
     .instance_size = sizeof(PCIEPort),
     .class_init    = xio3130_upstream_class_init,
 };
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
index 06ace08..0277aa0 100644
--- a/hw/pci-host/apb.c
+++ b/hw/pci-host/apb.c
@@ -464,7 +464,7 @@  PCIBus *pci_apb_init(hwaddr special_base,
     /* APB secondary busses */
     pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 0), true,
                                    "pbm-bridge");
-    br = DO_UPCAST(PCIBridge, dev, pci_dev);
+    br = PCI_BRIDGE(pci_dev);
     pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 1",
                        pci_apb_map_irq);
     qdev_init_nofail(&pci_dev->qdev);
@@ -472,7 +472,7 @@  PCIBus *pci_apb_init(hwaddr special_base,
 
     pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 1), true,
                                    "pbm-bridge");
-    br = DO_UPCAST(PCIBridge, dev, pci_dev);
+    br = PCI_BRIDGE(pci_dev);
     pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 2",
                        pci_apb_map_irq);
     qdev_init_nofail(&pci_dev->qdev);
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 81cf5a9..4c004f5 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -397,7 +397,7 @@  static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
 
     pci_update_mappings(s);
     if (pc->is_bridge) {
-        PCIBridge *b = container_of(s, PCIBridge, dev);
+        PCIBridge *b = PCI_BRIDGE(s);
         pci_bridge_update_mappings(b);
     }
 
diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
index 02a396b..a90671d 100644
--- a/hw/pci/pci_bridge.c
+++ b/hw/pci/pci_bridge.c
@@ -141,8 +141,9 @@  static void pci_bridge_init_alias(PCIBridge *bridge, MemoryRegion *alias,
                                   MemoryRegion *parent_space,
                                   bool enabled)
 {
-    pcibus_t base = pci_bridge_get_base(&bridge->dev, type);
-    pcibus_t limit = pci_bridge_get_limit(&bridge->dev, type);
+    PCIDevice *bridge_dev = PCI_DEVICE(bridge);
+    pcibus_t base = pci_bridge_get_base(bridge_dev, type);
+    pcibus_t limit = pci_bridge_get_limit(bridge_dev, type);
     /* TODO: this doesn't handle base = 0 limit = 2^64 - 1 correctly.
      * Apparently no way to do this with existing memory APIs. */
     pcibus_t size = enabled && limit >= base ? limit + 1 - base : 0;
@@ -154,7 +155,8 @@  static void pci_bridge_init_alias(PCIBridge *bridge, MemoryRegion *alias,
 static void pci_bridge_init_vga_aliases(PCIBridge *br, PCIBus *parent,
                                         MemoryRegion *alias_vga)
 {
-    uint16_t brctl = pci_get_word(br->dev.config + PCI_BRIDGE_CONTROL);
+    PCIDevice *pd = PCI_DEVICE(br);
+    uint16_t brctl = pci_get_word(pd->config + PCI_BRIDGE_CONTROL);
 
     memory_region_init_alias(&alias_vga[QEMU_PCI_VGA_IO_LO], OBJECT(br),
                              "pci_bridge_vga_io_lo", &br->address_space_io,
@@ -167,7 +169,7 @@  static void pci_bridge_init_vga_aliases(PCIBridge *br, PCIBus *parent,
                              QEMU_PCI_VGA_MEM_BASE, QEMU_PCI_VGA_MEM_SIZE);
 
     if (brctl & PCI_BRIDGE_CTL_VGA) {
-        pci_register_vga(&br->dev, &alias_vga[QEMU_PCI_VGA_MEM],
+        pci_register_vga(pd, &alias_vga[QEMU_PCI_VGA_MEM],
                          &alias_vga[QEMU_PCI_VGA_IO_LO],
                          &alias_vga[QEMU_PCI_VGA_IO_HI]);
     }
@@ -175,9 +177,10 @@  static void pci_bridge_init_vga_aliases(PCIBridge *br, PCIBus *parent,
 
 static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br)
 {
-    PCIBus *parent = br->dev.bus;
+    PCIDevice *pd = PCI_DEVICE(br);
+    PCIBus *parent = pd->bus;
     PCIBridgeWindows *w = g_new(PCIBridgeWindows, 1);
-    uint16_t cmd = pci_get_word(br->dev.config + PCI_COMMAND);
+    uint16_t cmd = pci_get_word(pd->config + PCI_COMMAND);
 
     pci_bridge_init_alias(br, &w->alias_pref_mem,
                           PCI_BASE_ADDRESS_MEM_PREFETCH,
@@ -205,12 +208,13 @@  static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br)
 
 static void pci_bridge_region_del(PCIBridge *br, PCIBridgeWindows *w)
 {
-    PCIBus *parent = br->dev.bus;
+    PCIDevice *pd = PCI_DEVICE(br);
+    PCIBus *parent = pd->bus;
 
     memory_region_del_subregion(parent->address_space_io, &w->alias_io);
     memory_region_del_subregion(parent->address_space_mem, &w->alias_mem);
     memory_region_del_subregion(parent->address_space_mem, &w->alias_pref_mem);
-    pci_unregister_vga(&br->dev);
+    pci_unregister_vga(pd);
 }
 
 static void pci_bridge_region_cleanup(PCIBridge *br, PCIBridgeWindows *w)
@@ -241,7 +245,7 @@  void pci_bridge_update_mappings(PCIBridge *br)
 void pci_bridge_write_config(PCIDevice *d,
                              uint32_t address, uint32_t val, int len)
 {
-    PCIBridge *s = container_of(d, PCIBridge, dev);
+    PCIBridge *s = PCI_BRIDGE(d);
     uint16_t oldctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL);
     uint16_t newctl;
 
@@ -331,7 +335,7 @@  void pci_bridge_reset(DeviceState *qdev)
 int pci_bridge_initfn(PCIDevice *dev, const char *typename)
 {
     PCIBus *parent = dev->bus;
-    PCIBridge *br = DO_UPCAST(PCIBridge, dev, dev);
+    PCIBridge *br = PCI_BRIDGE(dev);
     PCIBus *sec_bus = &br->sec_bus;
 
     pci_word_test_and_set_mask(dev->config + PCI_STATUS,
@@ -379,7 +383,7 @@  int pci_bridge_initfn(PCIDevice *dev, const char *typename)
 /* default qdev clean up function for PCI-to-PCI bridge */
 void pci_bridge_exitfn(PCIDevice *pci_dev)
 {
-    PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev);
+    PCIBridge *s = PCI_BRIDGE(pci_dev);
     assert(QLIST_EMPTY(&s->sec_bus.child));
     QLIST_REMOVE(&s->sec_bus, sibling);
     pci_bridge_region_del(s, s->windows);
@@ -400,3 +404,17 @@  void pci_bridge_map_irq(PCIBridge *br, const char* bus_name,
     br->map_irq = map_irq;
     br->bus_name = bus_name;
 }
+
+static const TypeInfo pci_bridge_type_info = {
+    .name = TYPE_PCI_BRIDGE,
+    .parent = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIBridge),
+    .abstract = true,
+};
+
+static void pci_bridge_register_types(void)
+{
+    type_register_static(&pci_bridge_type_info);
+}
+
+type_init(pci_bridge_register_types)
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 62bd0b8..50af3c1 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -305,7 +305,7 @@  void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
 
     dev->exp.hpev_notified = false;
 
-    pci_bus_hotplug(pci_bridge_get_sec_bus(DO_UPCAST(PCIBridge, dev, dev)),
+    pci_bus_hotplug(pci_bridge_get_sec_bus(PCI_BRIDGE(dev)),
                     pcie_cap_slot_hotplug, &dev->qdev);
 }
 
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index 66762f6..9df1788 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -53,8 +53,13 @@  struct PCIBridgeWindows {
     MemoryRegion alias_vga[QEMU_PCI_VGA_NUM_REGIONS];
 };
 
+#define TYPE_PCI_BRIDGE "base-pci-bridge"
+#define PCI_BRIDGE(obj) OBJECT_CHECK(PCIBridge, (obj), TYPE_PCI_BRIDGE)
+
 struct PCIBridge {
-    PCIDevice dev;
+    /*< private >*/
+    PCIDevice parent_obj;
+    /*< public >*/
 
     /* private member */
     PCIBus sec_bus;