diff options
Diffstat (limited to 'hw/ppc/spapr_drc.c')
-rw-r--r-- | hw/ppc/spapr_drc.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 1f5f1d790a..26a067951c 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -140,6 +140,8 @@ static uint32_t set_allocation_state(sPAPRDRConnector *drc, DPRINTFN("finalizing device removal"); drck->detach(drc, DEVICE(drc->dev), drc->detach_cb, drc->detach_cb_opaque, NULL); + } else if (drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE) { + drc->awaiting_allocation = false; } } return RTAS_OUT_SUCCESS; @@ -269,11 +271,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name, void *fdt; if (!drc->fdt) { - visit_start_struct(v, name, NULL, 0, &err); - if (!err) { - visit_end_struct(v, &err); - } - error_propagate(errp, err); + visit_type_null(v, NULL, errp); return; } @@ -301,7 +299,8 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name, case FDT_END_NODE: /* shouldn't ever see an FDT_END_NODE before FDT_BEGIN_NODE */ g_assert(fdt_depth > 0); - visit_end_struct(v, &err); + visit_check_struct(v, &err); + visit_end_struct(v, NULL); if (err) { error_propagate(errp, err); return; @@ -312,7 +311,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name, int i; prop = fdt_get_property_by_offset(fdt, fdt_offset, &prop_len); name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); - visit_start_list(v, name, &err); + visit_start_list(v, name, NULL, 0, &err); if (err) { error_propagate(errp, err); return; @@ -324,7 +323,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name, return; } } - visit_end_list(v); + visit_end_list(v, NULL); break; } default: @@ -376,6 +375,10 @@ static void attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt, drc->signalled = (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI) ? true : coldplug; + if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI) { + drc->awaiting_allocation = true; + } + object_property_add_link(OBJECT(drc), "device", object_get_typename(OBJECT(drc->dev)), (Object **)(&drc->dev), @@ -424,6 +427,12 @@ static void detach(sPAPRDRConnector *drc, DeviceState *d, return; } + if (drc->awaiting_allocation) { + drc->awaiting_release = true; + DPRINTFN("awaiting allocation to complete before removal"); + return; + } + drc->indicator_state = SPAPR_DR_INDICATOR_STATE_INACTIVE; if (drc->detach_cb) { |