aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/ppc/spapr_drc.c12
-rw-r--r--include/hw/ppc/spapr_drc.h1
2 files changed, 13 insertions, 0 deletions
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 94c875d..d276db3a 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 fa21ba0..08e8411 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;