提交 61736732 编写于 作者: D David Gibson

spapr: Clean up DRC set_allocation_state path

The allocation-state indicator should only actually be implemented for
"logical" DRCs, not physical ones.  Factor a check for this, and also for
valid indicator state values into rtas_set_allocation_state().  Because
they don't exist for physical DRCs, there's no reason that we'd ever want
more than one method implementation, so it can just be a plain function.

In addition, the setting to USABLE and setting to UNUSABLE paths in
set_allocation_state() don't actually have much in common.  So, split the
method separate functions for each parameter value (drc_set_usable()
and drc_set_unusable()).
Signed-off-by: NDavid Gibson <david@gibson.dropbear.id.au>
Reviewed-by: NGreg Kurz <groug@kaod.org>
Reviewed-by: NMichael Roth <mdroth@linux.vnet.ibm.com>
上级 4f9242fc
...@@ -114,33 +114,42 @@ static uint32_t set_isolation_state(sPAPRDRConnector *drc, ...@@ -114,33 +114,42 @@ static uint32_t set_isolation_state(sPAPRDRConnector *drc,
return RTAS_OUT_SUCCESS; return RTAS_OUT_SUCCESS;
} }
static uint32_t set_allocation_state(sPAPRDRConnector *drc, static uint32_t drc_set_usable(sPAPRDRConnector *drc)
sPAPRDRAllocationState state)
{ {
trace_spapr_drc_set_allocation_state(spapr_drc_index(drc), state); /* if there's no resource/device associated with the DRC, there's
* no way for us to put it in an allocation state consistent with
if (state == SPAPR_DR_ALLOCATION_STATE_USABLE) { * being 'USABLE'. PAPR 2.7, 13.5.3.4 documents that this should
/* if there's no resource/device associated with the DRC, there's * result in an RTAS return code of -3 / "no such indicator"
* no way for us to put it in an allocation state consistent with */
* being 'USABLE'. PAPR 2.7, 13.5.3.4 documents that this should if (!drc->dev) {
* result in an RTAS return code of -3 / "no such indicator" return RTAS_OUT_NO_SUCH_INDICATOR;
}
if (drc->awaiting_release && drc->awaiting_allocation) {
/* kernel is acknowledging a previous hotplug event
* while we are already removing it.
* it's safe to ignore awaiting_allocation here since we know the
* situation is predicated on the guest either already having done
* so (boot-time hotplug), or never being able to acquire in the
* first place (hotplug followed by immediate unplug).
*/ */
if (!drc->dev) { return RTAS_OUT_NO_SUCH_INDICATOR;
return RTAS_OUT_NO_SUCH_INDICATOR;
}
} }
if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI) { drc->allocation_state = SPAPR_DR_ALLOCATION_STATE_USABLE;
drc->allocation_state = state; drc->awaiting_allocation = false;
if (drc->awaiting_release &&
drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) { return RTAS_OUT_SUCCESS;
uint32_t drc_index = spapr_drc_index(drc); }
trace_spapr_drc_set_allocation_state_finalizing(drc_index);
spapr_drc_detach(drc, DEVICE(drc->dev), NULL); static uint32_t drc_set_unusable(sPAPRDRConnector *drc)
} else if (drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE) { {
drc->awaiting_allocation = false; drc->allocation_state = SPAPR_DR_ALLOCATION_STATE_UNUSABLE;
} if (drc->awaiting_release) {
uint32_t drc_index = spapr_drc_index(drc);
trace_spapr_drc_set_allocation_state_finalizing(drc_index);
spapr_drc_detach(drc, DEVICE(drc->dev), NULL);
} }
return RTAS_OUT_SUCCESS; return RTAS_OUT_SUCCESS;
} }
...@@ -547,7 +556,6 @@ static void spapr_dr_connector_class_init(ObjectClass *k, void *data) ...@@ -547,7 +556,6 @@ static void spapr_dr_connector_class_init(ObjectClass *k, void *data)
dk->realize = realize; dk->realize = realize;
dk->unrealize = unrealize; dk->unrealize = unrealize;
drck->set_isolation_state = set_isolation_state; drck->set_isolation_state = set_isolation_state;
drck->set_allocation_state = set_allocation_state;
drck->release_pending = release_pending; drck->release_pending = release_pending;
/* /*
* Reason: it crashes FIXME find and document the real reason * Reason: it crashes FIXME find and document the real reason
...@@ -817,14 +825,23 @@ static uint32_t rtas_set_isolation_state(uint32_t idx, uint32_t state) ...@@ -817,14 +825,23 @@ static uint32_t rtas_set_isolation_state(uint32_t idx, uint32_t state)
static uint32_t rtas_set_allocation_state(uint32_t idx, uint32_t state) static uint32_t rtas_set_allocation_state(uint32_t idx, uint32_t state)
{ {
sPAPRDRConnector *drc = spapr_drc_by_index(idx); sPAPRDRConnector *drc = spapr_drc_by_index(idx);
sPAPRDRConnectorClass *drck;
if (!drc) { if (!drc || !object_dynamic_cast(OBJECT(drc), TYPE_SPAPR_DRC_LOGICAL)) {
return RTAS_OUT_PARAM_ERROR; return RTAS_OUT_NO_SUCH_INDICATOR;
} }
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); trace_spapr_drc_set_allocation_state(spapr_drc_index(drc), state);
return drck->set_allocation_state(drc, state);
switch (state) {
case SPAPR_DR_ALLOCATION_STATE_USABLE:
return drc_set_usable(drc);
case SPAPR_DR_ALLOCATION_STATE_UNUSABLE:
return drc_set_unusable(drc);
default:
return RTAS_OUT_PARAM_ERROR;
}
} }
static uint32_t rtas_set_dr_indicator(uint32_t idx, uint32_t state) static uint32_t rtas_set_dr_indicator(uint32_t idx, uint32_t state)
......
...@@ -219,8 +219,6 @@ typedef struct sPAPRDRConnectorClass { ...@@ -219,8 +219,6 @@ typedef struct sPAPRDRConnectorClass {
/* accessors for guest-visible (generally via RTAS) DR state */ /* accessors for guest-visible (generally via RTAS) DR state */
uint32_t (*set_isolation_state)(sPAPRDRConnector *drc, uint32_t (*set_isolation_state)(sPAPRDRConnector *drc,
sPAPRDRIsolationState state); sPAPRDRIsolationState state);
uint32_t (*set_allocation_state)(sPAPRDRConnector *drc,
sPAPRDRAllocationState state);
/* QEMU interfaces for managing hotplug operations */ /* QEMU interfaces for managing hotplug operations */
bool (*release_pending)(sPAPRDRConnector *drc); bool (*release_pending)(sPAPRDRConnector *drc);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册