static int ioh3420_initfn(PCIDevice *d) { PCIEPort *p = PCIE_PORT(d); PCIESlot *s = PCIE_SLOT(d); int rc; Error *err = NULL; pci_bridge_initfn(d, TYPE_PCIE_BUS); pcie_port_init_reg(d); rc = pci_bridge_ssvid_init(d, IOH_EP_SSVID_OFFSET, IOH_EP_SSVID_SVID, IOH_EP_SSVID_SSID); if (rc < 0) { goto err_bridge; } rc = msi_init(d, IOH_EP_MSI_OFFSET, IOH_EP_MSI_NR_VECTOR, IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT, IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT, &err); if (rc < 0) { assert(rc == -ENOTSUP); error_report_err(err); goto err_bridge; } rc = pcie_cap_init(d, IOH_EP_EXP_OFFSET, PCI_EXP_TYPE_ROOT_PORT, p->port); if (rc < 0) { goto err_msi; } pcie_cap_arifwd_init(d); pcie_cap_deverr_init(d); pcie_cap_slot_init(d, s->slot); pcie_cap_root_init(d); pcie_chassis_create(s->chassis); rc = pcie_chassis_add_slot(s); if (rc < 0) { goto err_pcie_cap; } rc = pcie_aer_init(d, IOH_EP_AER_OFFSET, PCI_ERR_SIZEOF); if (rc < 0) { goto err; } pcie_aer_root_init(d); ioh3420_aer_vector_update(d); return 0; err: pcie_chassis_del_slot(s); err_pcie_cap: pcie_cap_exit(d); err_msi: msi_uninit(d); err_bridge: pci_bridge_exitfn(d); return rc; }
static void ioh3420_exitfn(PCIDevice *d) { PCIESlot *s = PCIE_SLOT(d); pcie_aer_exit(d); pcie_chassis_del_slot(s); pcie_cap_exit(d); msi_uninit(d); pci_bridge_exitfn(d); }
static void rp_instance_post_init(Object *obj) { PCIESlot *s = PCIE_SLOT(obj); if (!s->speed) { s->speed = QEMU_PCI_EXP_LNK_2_5GT; } if (!s->width) { s->width = QEMU_PCI_EXP_LNK_X1; } }
static void rp_exit(PCIDevice *d) { PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); PCIESlot *s = PCIE_SLOT(d); pcie_aer_exit(d); pcie_chassis_del_slot(s); pcie_cap_exit(d); if (rpc->interrupts_uninit) { rpc->interrupts_uninit(d); } pci_bridge_exitfn(d); }
PCIESlot *ioh3420_init(PCIBus *bus, int devfn, bool multifunction, const char *bus_name, pci_map_irq_fn map_irq, uint8_t port, uint8_t chassis, uint16_t slot) { PCIDevice *d; PCIBridge *br; DeviceState *qdev; d = pci_create_multifunction(bus, devfn, multifunction, "ioh3420"); if (!d) { return NULL; } br = PCI_BRIDGE(d); 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); qdev_prop_set_uint16(qdev, "slot", slot); qdev_init_nofail(qdev); return PCIE_SLOT(d); }
static void rp_realize(PCIDevice *d, Error **errp) { PCIEPort *p = PCIE_PORT(d); PCIESlot *s = PCIE_SLOT(d); PCIDeviceClass *dc = PCI_DEVICE_GET_CLASS(d); PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); int rc; pci_config_set_interrupt_pin(d->config, 1); pci_bridge_initfn(d, TYPE_PCIE_BUS); pcie_port_init_reg(d); rc = pci_bridge_ssvid_init(d, rpc->ssvid_offset, dc->vendor_id, rpc->ssid, errp); if (rc < 0) { error_append_hint(errp, "Can't init SSV ID, error %d\n", rc); goto err_bridge; } if (rpc->interrupts_init) { rc = rpc->interrupts_init(d, errp); if (rc < 0) { goto err_bridge; } } rc = pcie_cap_init(d, rpc->exp_offset, PCI_EXP_TYPE_ROOT_PORT, p->port, errp); if (rc < 0) { error_append_hint(errp, "Can't add Root Port capability, " "error %d\n", rc); goto err_int; } pcie_cap_arifwd_init(d); pcie_cap_deverr_init(d); pcie_cap_slot_init(d, s->slot); pcie_cap_root_init(d); pcie_chassis_create(s->chassis); rc = pcie_chassis_add_slot(s); if (rc < 0) { error_setg(errp, "Can't add chassis slot, error %d", rc); goto err_pcie_cap; } rc = pcie_aer_init(d, PCI_ERR_VER, rpc->aer_offset, PCI_ERR_SIZEOF, errp); if (rc < 0) { goto err; } pcie_aer_root_init(d); rp_aer_vector_update(d); return; err: pcie_chassis_del_slot(s); err_pcie_cap: pcie_cap_exit(d); err_int: if (rpc->interrupts_uninit) { rpc->interrupts_uninit(d); } err_bridge: pci_bridge_exitfn(d); }