Il 24/09/2014 13:48, Igor Mammedov ha scritto: > it to be called for actual device removal and > will allow to separate request and removal handling > phases of x86-CPU devices and also it's a handler > to be called for synchronously removable devices. > > Signed-off-by: Igor Mammedov <imamm...@redhat.com> > --- > unplug handling for bus-less devices will be added > later in this series. > --- > hw/core/hotplug.c | 11 +++++++++++ > hw/core/qdev.c | 13 +++++++++++-- > include/hw/hotplug.h | 12 ++++++++++++ > 3 files changed, 34 insertions(+), 2 deletions(-) > > diff --git a/hw/core/hotplug.c b/hw/core/hotplug.c > index 2ec4736..4e01074 100644 > --- a/hw/core/hotplug.c > +++ b/hw/core/hotplug.c > @@ -34,6 +34,17 @@ void hotplug_handler_unplug_request(HotplugHandler > *plug_handler, > } > } > > +void hotplug_handler_unplug(HotplugHandler *plug_handler, > + DeviceState *plugged_dev, > + Error **errp) > +{ > + HotplugHandlerClass *hdc = HOTPLUG_HANDLER_GET_CLASS(plug_handler); > + > + if (hdc->unplug) { > + hdc->unplug(plug_handler, plugged_dev, errp); > + } > +} > + > static const TypeInfo hotplug_handler_info = { > .name = TYPE_HOTPLUG_HANDLER, > .parent = TYPE_INTERFACE, > diff --git a/hw/core/qdev.c b/hw/core/qdev.c > index c98e5db..c89d781 100644 > --- a/hw/core/qdev.c > +++ b/hw/core/qdev.c > @@ -227,8 +227,17 @@ void qdev_unplug(DeviceState *dev, Error **errp) > qdev_hot_removed = true; > > if (dev->parent_bus && dev->parent_bus->hotplug_handler) { > - hotplug_handler_unplug_request(dev->parent_bus->hotplug_handler, > - dev, errp); > + HotplugHandlerClass *hdc; > + > + /* If device supports async unplug just request it to be done, > + * otherwise just remove it synchronously */ > + hdc = HOTPLUG_HANDLER_GET_CLASS(dev->parent_bus->hotplug_handler); > + if (hdc->unplug_request) { > + hotplug_handler_unplug_request(dev->parent_bus->hotplug_handler, > + dev, errp); > + } else { > + hotplug_handler_unplug(dev->parent_bus->hotplug_handler, dev, > errp); > + } > } else { > assert(dc->unplug != NULL); > if (dc->unplug(dev) < 0) { /* legacy handler */ > diff --git a/include/hw/hotplug.h b/include/hw/hotplug.h > index e397d08..451d522 100644 > --- a/include/hw/hotplug.h > +++ b/include/hw/hotplug.h > @@ -50,6 +50,9 @@ typedef void (*hotplug_fn)(HotplugHandler *plug_handler, > * @unplug_request: unplug request callback. > * Used as a means to initiate device unplug for devices > that > * require asynchronous unplug handling. > + * @unplug_request: unplug callback. > + * Used for device removal with devices that implement > + * asynchronous and synchronous (suprise) removal. > */ > typedef struct HotplugHandlerClass { > /* <private> */ > @@ -58,6 +61,7 @@ typedef struct HotplugHandlerClass { > /* <public> */ > hotplug_fn plug; > hotplug_fn unplug_request; > + hotplug_fn unplug; > } HotplugHandlerClass; > > /** > @@ -77,4 +81,12 @@ void hotplug_handler_plug(HotplugHandler *plug_handler, > void hotplug_handler_unplug_request(HotplugHandler *plug_handler, > DeviceState *plugged_dev, > Error **errp); > +/** > + * hotplug_handler_unplug: > + * > + * Calls #HotplugHandlerClass.unplug callback of @plug_handler. > + */ > +void hotplug_handler_unplug(HotplugHandler *plug_handler, > + DeviceState *plugged_dev, > + Error **errp); > #endif >
Reviewed-by: Paolo Bonzini <pbonz...@redhat.com>