On Wed, 24 Oct 2018 12:19:30 +0200
David Hildenbrand <david@redhat.com> wrote:
> Preparation for multi-stage hotplug handlers.
>
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
Reviewed-by: Greg Kurz <groug@kaod.org>
> hw/ppc/spapr_pci.c | 33 +++++++++++++++++++++------------
> 1 file changed, 21 insertions(+), 12 deletions(-)
>
> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> index 58afa46204..64b8591023 100644
> --- a/hw/ppc/spapr_pci.c
> +++ b/hw/ppc/spapr_pci.c
> @@ -1370,18 +1370,9 @@ static int spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev,
> /* Callback to be called during DRC release. */
> void spapr_phb_remove_pci_device_cb(DeviceState *dev)
> {
> - /* some version guests do not wait for completion of a device
> - * cleanup (generally done asynchronously by the kernel) before
> - * signaling to QEMU that the device is safe, but instead sleep
> - * for some 'safe' period of time. unfortunately on a busy host
> - * this sleep isn't guaranteed to be long enough, resulting in
> - * bad things like IRQ lines being left asserted during final
> - * device removal. to deal with this we call reset just prior
> - * to finalizing the device, which will put the device back into
> - * an 'idle' state, as the device cleanup code expects.
> - */
> - pci_device_reset(PCI_DEVICE(dev));
> - object_unparent(OBJECT(dev));
> + HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(dev);
> +
> + hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort);
> }
>
> static sPAPRDRConnector *spapr_phb_get_pci_func_drc(sPAPRPHBState *phb,
> @@ -1490,6 +1481,23 @@ out:
> }
> }
>
> +static void spapr_pci_unplug(HotplugHandler *plug_handler,
> + DeviceState *plugged_dev, Error **errp)
> +{
> + /* some version guests do not wait for completion of a device
> + * cleanup (generally done asynchronously by the kernel) before
> + * signaling to QEMU that the device is safe, but instead sleep
> + * for some 'safe' period of time. unfortunately on a busy host
> + * this sleep isn't guaranteed to be long enough, resulting in
> + * bad things like IRQ lines being left asserted during final
> + * device removal. to deal with this we call reset just prior
> + * to finalizing the device, which will put the device back into
> + * an 'idle' state, as the device cleanup code expects.
> + */
> + pci_device_reset(PCI_DEVICE(plugged_dev));
> + object_unparent(OBJECT(plugged_dev));
> +}
> +
> static void spapr_pci_unplug_request(HotplugHandler *plug_handler,
> DeviceState *plugged_dev, Error **errp)
> {
> @@ -1965,6 +1973,7 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data)
> dc->user_creatable = true;
> set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
> hp->plug = spapr_pci_plug;
> + hp->unplug = spapr_pci_unplug;
> hp->unplug_request = spapr_pci_unplug_request;
> }
>