On Thu, 25 Sep 2014 09:53:20 +0800 Tang Chen <tangc...@cn.fujitsu.com> wrote:
> > On 09/24/2014 07:48 PM, Igor Mammedov wrote: > > 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. > > Typo, s/unplug_request/unplug ? Yep, I'll fix it. > > Thanks. > > > + * 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 > >