static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,

                                    DeviceState *dev, Error **errp)

{

    PCIDevice *pci_dev = NULL;

    PCIBus *bus;

    int32_t devfn;

    S390PCIBusDevice *pbdev = NULL;

    S390pciState *s = s390_get_phb();



    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {

        error_setg(errp, "PCI bridge hot unplug currently not supported");

        return;

    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {

        pci_dev = PCI_DEVICE(dev);



        QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) {

            if (pbdev->pdev == pci_dev) {

                break;

            }

        }

        assert(pbdev != NULL);

    } else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {

        pbdev = S390_PCI_DEVICE(dev);

        pci_dev = pbdev->pdev;

    }



    switch (pbdev->state) {

    case ZPCI_FS_RESERVED:

        goto out;

    case ZPCI_FS_STANDBY:

        break;

    default:

        s390_pci_generate_plug_event(HP_EVENT_DECONFIGURE_REQUEST,

                                     pbdev->fh, pbdev->fid);

        pbdev->release_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,

                                            s390_pcihost_timer_cb,

                                            pbdev);

        timer_mod(pbdev->release_timer,

                  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + HOT_UNPLUG_TIMEOUT);

        return;

    }



    if (pbdev->release_timer && timer_pending(pbdev->release_timer)) {

        timer_del(pbdev->release_timer);

        timer_free(pbdev->release_timer);

        pbdev->release_timer = NULL;

    }



    s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED,

                                 pbdev->fh, pbdev->fid);

    bus = pci_dev->bus;

    devfn = pci_dev->devfn;

    object_unparent(OBJECT(pci_dev));

    s390_pci_msix_free(pbdev);

    s390_pci_iommu_free(s, bus, devfn);

    pbdev->pdev = NULL;

    pbdev->state = ZPCI_FS_RESERVED;

out:

    pbdev->fid = 0;

    QTAILQ_REMOVE(&s->zpci_devs, pbdev, link);

    g_hash_table_remove(s->zpci_table, &pbdev->idx);

    object_unparent(OBJECT(pbdev));

}

static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,

                                    DeviceState *dev, Error **errp)

{

    PCIDevice *pci_dev = NULL;

    PCIBus *bus;

    int32_t devfn;

    S390PCIBusDevice *pbdev = NULL;

    S390pciState *s = s390_get_phb();



    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {

        error_setg(errp, "PCI bridge hot unplug currently not supported");

        return;

    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {

        pci_dev = PCI_DEVICE(dev);



        QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) {

            if (pbdev->pdev == pci_dev) {

                break;

            }

        }

        assert(pbdev != NULL);

    } else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {

        pbdev = S390_PCI_DEVICE(dev);

        pci_dev = pbdev->pdev;

    }



    switch (pbdev->state) {

    case ZPCI_FS_RESERVED:

        goto out;

    case ZPCI_FS_STANDBY:

        break;

    default:

        s390_pci_generate_plug_event(HP_EVENT_DECONFIGURE_REQUEST,

                                     pbdev->fh, pbdev->fid);

        pbdev->release_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,

                                            s390_pcihost_timer_cb,

                                            pbdev);

        timer_mod(pbdev->release_timer,

                  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + HOT_UNPLUG_TIMEOUT);

        return;

    }



    if (pbdev->release_timer && timer_pending(pbdev->release_timer)) {

        timer_del(pbdev->release_timer);

        timer_free(pbdev->release_timer);

        pbdev->release_timer = NULL;

    }



    s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED,

                                 pbdev->fh, pbdev->fid);

    bus = pci_dev->bus;

    devfn = pci_dev->devfn;

    object_unparent(OBJECT(pci_dev));

    s390_pci_msix_free(pbdev);

    s390_pci_iommu_free(s, bus, devfn);

    pbdev->pdev = NULL;

    pbdev->state = ZPCI_FS_RESERVED;

out:

    pbdev->fid = 0;

    QTAILQ_REMOVE(&s->zpci_devs, pbdev, link);

    g_hash_table_remove(s->zpci_table, &pbdev->idx);

    object_unparent(OBJECT(pbdev));

}

static void FUNC_0(HotplugHandler *VAR_0,

                                    DeviceState *VAR_1, Error **VAR_2)

{

    PCIDevice *pci_dev = NULL;

    PCIBus *bus;

    int32_t devfn;

    S390PCIBusDevice *pbdev = NULL;

    S390pciState *s = s390_get_phb();



    if (object_dynamic_cast(OBJECT(VAR_1), TYPE_PCI_BRIDGE)) {

        error_setg(VAR_2, "PCI bridge hot unplug currently not supported");

        return;

    } else if (object_dynamic_cast(OBJECT(VAR_1), TYPE_PCI_DEVICE)) {

        pci_dev = PCI_DEVICE(VAR_1);



        QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) {

            if (pbdev->pdev == pci_dev) {

                break;

            }

        }

        assert(pbdev != NULL);

    } else if (object_dynamic_cast(OBJECT(VAR_1), TYPE_S390_PCI_DEVICE)) {

        pbdev = S390_PCI_DEVICE(VAR_1);

        pci_dev = pbdev->pdev;

    }



    switch (pbdev->state) {

    case ZPCI_FS_RESERVED:

        goto out;

    case ZPCI_FS_STANDBY:

        break;

    default:

        s390_pci_generate_plug_event(HP_EVENT_DECONFIGURE_REQUEST,

                                     pbdev->fh, pbdev->fid);

        pbdev->release_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,

                                            s390_pcihost_timer_cb,

                                            pbdev);

        timer_mod(pbdev->release_timer,

                  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + HOT_UNPLUG_TIMEOUT);

        return;

    }



    if (pbdev->release_timer && timer_pending(pbdev->release_timer)) {

        timer_del(pbdev->release_timer);

        timer_free(pbdev->release_timer);

        pbdev->release_timer = NULL;

    }



    s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED,

                                 pbdev->fh, pbdev->fid);

    bus = pci_dev->bus;

    devfn = pci_dev->devfn;

    object_unparent(OBJECT(pci_dev));

    s390_pci_msix_free(pbdev);

    s390_pci_iommu_free(s, bus, devfn);

    pbdev->pdev = NULL;

    pbdev->state = ZPCI_FS_RESERVED;

out:

    pbdev->fid = 0;

    QTAILQ_REMOVE(&s->zpci_devs, pbdev, link);

    g_hash_table_remove(s->zpci_table, &pbdev->idx);

    object_unparent(OBJECT(pbdev));

}

static void FUNC_0(HotplugHandler *VAR_0,
DeviceState *VAR_1, Error **VAR_2)
{ PCIDevice *pci_dev = NULL; PCIBus *bus; int32_t devfn; S390PCIBusDevice *pbdev = NULL; S390pciState *s = s390_get_phb(); if (object_dynamic_cast(OBJECT(VAR_1), TYPE_PCI_BRIDGE)) { error_setg(VAR_2, "PCI bridge hot unplug currently not supported"); return; } else if (object_dynamic_cast(OBJECT(VAR_1), TYPE_PCI_DEVICE)) { pci_dev = PCI_DEVICE(VAR_1); QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) { if (pbdev->pdev == pci_dev) { break; } } assert(pbdev != NULL); } else if (object_dynamic_cast(OBJECT(VAR_1), TYPE_S390_PCI_DEVICE)) { pbdev = S390_PCI_DEVICE(VAR_1); pci_dev = pbdev->pdev; } switch (pbdev->state) { case ZPCI_FS_RESERVED:
goto out; case ZPCI_FS_STANDBY:
break; default:
s390_pci_generate_plug_event(HP_EVENT_DECONFIGURE_REQUEST,
pbdev->fh, pbdev->fid); pbdev->release_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
s390_pcihost_timer_cb,
pbdev); timer_mod(pbdev->release_timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + HOT_UNPLUG_TIMEOUT); return; } if (pbdev->release_timer && timer_pending(pbdev->release_timer)) { timer_del(pbdev->release_timer); timer_free(pbdev->release_timer); pbdev->release_timer = NULL; } s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED,
pbdev->fh, pbdev->fid); bus = pci_dev->bus; devfn = pci_dev->devfn; object_unparent(OBJECT(pci_dev)); s390_pci_msix_free(pbdev); s390_pci_iommu_free(s, bus, devfn); pbdev->pdev = NULL; pbdev->state = ZPCI_FS_RESERVED; out:
pbdev->fid = 0; QTAILQ_REMOVE(&s->zpci_devs, pbdev, link); g_hash_table_remove(s->zpci_table, &pbdev->idx); object_unparent(OBJECT(pbdev)); }