diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 94c875d752..d276db3a72 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; @@ -373,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), @@ -421,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) { diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h index fa21ba0444..08e8411463 100644 --- a/include/hw/ppc/spapr_drc.h +++ b/include/hw/ppc/spapr_drc.h @@ -152,6 +152,7 @@ typedef struct sPAPRDRConnector { bool awaiting_release; bool signalled; + bool awaiting_allocation; /* device pointer, via link property */ DeviceState *dev;