mirror of https://github.com/xemu-project/xemu.git
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: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Greg Kurz <groug@kaod.org> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
This commit is contained in:
parent
4f9242fc93
commit
617367321e
|
@ -114,12 +114,8 @@ 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 (state == SPAPR_DR_ALLOCATION_STATE_USABLE) {
|
|
||||||
/* if there's no resource/device associated with the DRC, there's
|
/* 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
|
* 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
|
* being 'USABLE'. PAPR 2.7, 13.5.3.4 documents that this should
|
||||||
|
@ -128,19 +124,32 @@ static uint32_t set_allocation_state(sPAPRDRConnector *drc,
|
||||||
if (!drc->dev) {
|
if (!drc->dev) {
|
||||||
return RTAS_OUT_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).
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t drc_set_unusable(sPAPRDRConnector *drc)
|
||||||
|
{
|
||||||
|
drc->allocation_state = SPAPR_DR_ALLOCATION_STATE_UNUSABLE;
|
||||||
|
if (drc->awaiting_release) {
|
||||||
uint32_t drc_index = spapr_drc_index(drc);
|
uint32_t drc_index = spapr_drc_index(drc);
|
||||||
trace_spapr_drc_set_allocation_state_finalizing(drc_index);
|
trace_spapr_drc_set_allocation_state_finalizing(drc_index);
|
||||||
spapr_drc_detach(drc, DEVICE(drc->dev), NULL);
|
spapr_drc_detach(drc, DEVICE(drc->dev), NULL);
|
||||||
} else if (drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE) {
|
|
||||||
drc->awaiting_allocation = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return RTAS_OUT_SUCCESS;
|
return RTAS_OUT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
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 {
|
||||||
/* 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);
|
||||||
|
|
Loading…
Reference in New Issue