static void unrealize(DeviceState *d, Error **errp) { sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d); sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); Object *root_container; char name[256]; Error *err = NULL; DPRINTFN("drc unrealize: %x", drck->get_index(drc)); root_container = container_get(object_get_root(), DRC_CONTAINER_PATH); snprintf(name, sizeof(name), "%x", drck->get_index(drc)); object_property_del(root_container, name, &err); if (err) { error_report_err(err); object_unref(OBJECT(drc)); } }
static void detach(sPAPRDRConnector *drc, DeviceState *d, spapr_drc_detach_cb *detach_cb, void *detach_cb_opaque, Error **errp) { DPRINTFN("drc: %x, detach", get_index(drc)); drc->detach_cb = detach_cb; drc->detach_cb_opaque = detach_cb_opaque; if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) { DPRINTFN("awaiting transition to isolated state before removal"); drc->awaiting_release = true; return; } if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI && drc->allocation_state != SPAPR_DR_ALLOCATION_STATE_UNUSABLE) { DPRINTFN("awaiting transition to unusable state before removal"); drc->awaiting_release = true; return; } drc->indicator_state = SPAPR_DR_INDICATOR_STATE_INACTIVE; if (drc->detach_cb) { drc->detach_cb(drc->dev, drc->detach_cb_opaque); } drc->awaiting_release = false; g_free(drc->fdt); drc->fdt = NULL; drc->fdt_start_offset = 0; object_property_del(OBJECT(drc), "device", NULL); drc->dev = NULL; drc->detach_cb = NULL; drc->detach_cb_opaque = NULL; }
Object *user_creatable_add_type(const char *type, const char *id, const QDict *qdict, Visitor *v, Error **errp) { Object *obj; ObjectClass *klass; const QDictEntry *e; Error *local_err = NULL; klass = object_class_by_name(type); if (!klass) { error_setg(errp, "invalid object type: %s", type); return NULL; } if (!object_class_dynamic_cast(klass, TYPE_USER_CREATABLE)) { error_setg(errp, "object type '%s' isn't supported by object-add", type); return NULL; } if (object_class_is_abstract(klass)) { error_setg(errp, "object type '%s' is abstract", type); return NULL; } assert(qdict); obj = object_new(type); visit_start_struct(v, NULL, NULL, 0, &local_err); if (local_err) { goto out; } for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) { object_property_set(obj, v, e->key, &local_err); if (local_err) { break; } } if (!local_err) { visit_check_struct(v, &local_err); } visit_end_struct(v, NULL); if (local_err) { goto out; } if (id != NULL) { object_property_add_child(object_get_objects_root(), id, obj, &local_err); if (local_err) { goto out; } } user_creatable_complete(USER_CREATABLE(obj), &local_err); if (local_err) { if (id != NULL) { object_property_del(object_get_objects_root(), id, &error_abort); } goto out; } out: if (local_err) { error_propagate(errp, local_err); object_unref(obj); return NULL; } return obj; }
static void dummy_bus_unparent(Object *obj) { DummyBus *bus = DUMMY_BUS(obj); object_property_del(obj->parent, "backend", NULL); object_unparent(OBJECT(bus->backend)); }
static void detach(sPAPRDRConnector *drc, DeviceState *d, spapr_drc_detach_cb *detach_cb, void *detach_cb_opaque, Error **errp) { trace_spapr_drc_detach(get_index(drc)); drc->detach_cb = detach_cb; drc->detach_cb_opaque = detach_cb_opaque; /* if we've signalled device presence to the guest, or if the guest * has gone ahead and configured the device (via manually-executed * device add via drmgr in guest, namely), we need to wait * for the guest to quiesce the device before completing detach. * Otherwise, we can assume the guest hasn't seen it and complete the * detach immediately. Note that there is a small race window * just before, or during, configuration, which is this context * refers mainly to fetching the device tree via RTAS. * During this window the device access will be arbitrated by * associated DRC, which will simply fail the RTAS calls as invalid. * This is recoverable within guest and current implementations of * drmgr should be able to cope. */ if (!drc->signalled && !drc->configured) { /* if the guest hasn't seen the device we can't rely on it to * set it back to an isolated state via RTAS, so do it here manually */ drc->isolation_state = SPAPR_DR_ISOLATION_STATE_ISOLATED; } if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) { trace_spapr_drc_awaiting_isolated(get_index(drc)); drc->awaiting_release = true; return; } if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI && drc->allocation_state != SPAPR_DR_ALLOCATION_STATE_UNUSABLE) { trace_spapr_drc_awaiting_unusable(get_index(drc)); drc->awaiting_release = true; return; } if (drc->awaiting_allocation) { drc->awaiting_release = true; trace_spapr_drc_awaiting_allocation(get_index(drc)); return; } drc->indicator_state = SPAPR_DR_INDICATOR_STATE_INACTIVE; if (drc->detach_cb) { drc->detach_cb(drc->dev, drc->detach_cb_opaque); } drc->awaiting_release = false; g_free(drc->fdt); drc->fdt = NULL; drc->fdt_start_offset = 0; object_property_del(OBJECT(drc), "device", NULL); drc->dev = NULL; drc->detach_cb = NULL; drc->detach_cb_opaque = NULL; }