spapr_drc: use RTAS return codes for methods called by RTAS

Certain methods in sPAPRDRConnector objects are only ever called by
RTAS and in many cases are responsible for the logic that determines
the RTAS return codes.

Rather than having a level of indirection requiring RTAS code to
re-interpret return values from such methods to determine the
appropriate return code, just pass them through directly.

This requires changing method return types to uint32_t to match the
type of values currently passed to RTAS helpers.

In the case of read accesses like drc->entity_sense() where we weren't
previously reporting any errors, just the read value, we modify the
function to return RTAS return code, and pass the read value back via
reference.

Suggested-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Suggested-by: David Gibson <david@gibson.dropbear.id.au>
Cc: Bharata B Rao <bharata@linux.vnet.ibm.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Michael Roth 2015-09-10 16:11:02 -05:00 committed by David Gibson
parent 4a1c9cf007
commit 0cb688d22b
3 changed files with 48 additions and 43 deletions

View File

@ -15,6 +15,7 @@
#include "hw/qdev.h"
#include "qapi/visitor.h"
#include "qemu/error-report.h"
#include "hw/ppc/spapr.h" /* for RTAS return codes */
/* #define DEBUG_SPAPR_DRC */
@ -59,8 +60,8 @@ static uint32_t get_index(sPAPRDRConnector *drc)
(drc->id & DRC_INDEX_ID_MASK);
}
static int set_isolation_state(sPAPRDRConnector *drc,
sPAPRDRIsolationState state)
static uint32_t set_isolation_state(sPAPRDRConnector *drc,
sPAPRDRIsolationState state)
{
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
@ -99,19 +100,19 @@ static int set_isolation_state(sPAPRDRConnector *drc,
drc->configured = false;
}
return 0;
return RTAS_OUT_SUCCESS;
}
static int set_indicator_state(sPAPRDRConnector *drc,
sPAPRDRIndicatorState state)
static uint32_t set_indicator_state(sPAPRDRConnector *drc,
sPAPRDRIndicatorState state)
{
DPRINTFN("drc: %x, set_indicator_state: %x", get_index(drc), state);
drc->indicator_state = state;
return 0;
return RTAS_OUT_SUCCESS;
}
static int set_allocation_state(sPAPRDRConnector *drc,
sPAPRDRAllocationState state)
static uint32_t set_allocation_state(sPAPRDRConnector *drc,
sPAPRDRAllocationState state)
{
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
@ -137,7 +138,7 @@ static int set_allocation_state(sPAPRDRConnector *drc,
drc->detach_cb_opaque, NULL);
}
}
return 0;
return RTAS_OUT_SUCCESS;
}
static uint32_t get_type(sPAPRDRConnector *drc)
@ -178,10 +179,8 @@ static void set_configured(sPAPRDRConnector *drc)
* based on the current allocation/indicator/power states
* for the DR connector.
*/
static sPAPRDREntitySense entity_sense(sPAPRDRConnector *drc)
static uint32_t entity_sense(sPAPRDRConnector *drc, sPAPRDREntitySense *state)
{
sPAPRDREntitySense state;
if (drc->dev) {
if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI &&
drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
@ -190,7 +189,7 @@ static sPAPRDREntitySense entity_sense(sPAPRDRConnector *drc)
* Otherwise, report the state as USABLE/PRESENT,
* as we would for PCI.
*/
state = SPAPR_DR_ENTITY_SENSE_UNUSABLE;
*state = SPAPR_DR_ENTITY_SENSE_UNUSABLE;
} else {
/* this assumes all PCI devices are assigned to
* a 'live insertion' power domain, where QEMU
@ -198,21 +197,21 @@ static sPAPRDREntitySense entity_sense(sPAPRDRConnector *drc)
* to the guest. present, non-PCI resources are
* unaffected by power state.
*/
state = SPAPR_DR_ENTITY_SENSE_PRESENT;
*state = SPAPR_DR_ENTITY_SENSE_PRESENT;
}
} else {
if (drc->type == SPAPR_DR_CONNECTOR_TYPE_PCI) {
/* PCI devices, and only PCI devices, use EMPTY
* in cases where we'd otherwise use UNUSABLE
*/
state = SPAPR_DR_ENTITY_SENSE_EMPTY;
*state = SPAPR_DR_ENTITY_SENSE_EMPTY;
} else {
state = SPAPR_DR_ENTITY_SENSE_UNUSABLE;
*state = SPAPR_DR_ENTITY_SENSE_UNUSABLE;
}
}
DPRINTFN("drc: %x, entity_sense: %x", get_index(drc), state);
return state;
return RTAS_OUT_SUCCESS;
}
static void prop_get_index(Object *obj, Visitor *v, void *opaque,
@ -245,7 +244,9 @@ static void prop_get_entity_sense(Object *obj, Visitor *v, void *opaque,
{
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
uint32_t value = (uint32_t)drck->entity_sense(drc);
uint32_t value;
drck->entity_sense(drc, &value);
visit_type_uint32(v, &value, name, errp);
}

View File

@ -372,12 +372,13 @@ static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr,
uint32_t sensor_type;
uint32_t sensor_index;
uint32_t sensor_state;
uint32_t ret = RTAS_OUT_SUCCESS;
sPAPRDRConnector *drc;
sPAPRDRConnectorClass *drck;
if (nargs != 3 || nret != 1) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
ret = RTAS_OUT_PARAM_ERROR;
goto out;
}
sensor_type = rtas_ld(args, 0);
@ -393,8 +394,8 @@ static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr,
if (!drc) {
DPRINTF("rtas_set_indicator: invalid sensor/DRC index: %xh\n",
sensor_index);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
ret = RTAS_OUT_PARAM_ERROR;
goto out;
}
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
@ -413,19 +414,20 @@ static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr,
spapr_ccs_remove(spapr, ccs);
}
}
drck->set_isolation_state(drc, sensor_state);
ret = drck->set_isolation_state(drc, sensor_state);
break;
case RTAS_SENSOR_TYPE_DR:
drck->set_indicator_state(drc, sensor_state);
ret = drck->set_indicator_state(drc, sensor_state);
break;
case RTAS_SENSOR_TYPE_ALLOCATION_STATE:
drck->set_allocation_state(drc, sensor_state);
ret = drck->set_allocation_state(drc, sensor_state);
break;
default:
goto out_unimplemented;
}
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
out:
rtas_st(rets, 0, ret);
return;
out_unimplemented:
@ -442,13 +444,14 @@ static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr,
{
uint32_t sensor_type;
uint32_t sensor_index;
uint32_t sensor_state = 0;
sPAPRDRConnector *drc;
sPAPRDRConnectorClass *drck;
uint32_t entity_sense;
uint32_t ret = RTAS_OUT_SUCCESS;
if (nargs != 2 || nret != 2) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
ret = RTAS_OUT_PARAM_ERROR;
goto out;
}
sensor_type = rtas_ld(args, 0);
@ -458,22 +461,23 @@ static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr,
/* currently only DR-related sensors are implemented */
DPRINTF("rtas_get_sensor_state: sensor/indicator not implemented: %d\n",
sensor_type);
rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
return;
ret = RTAS_OUT_NOT_SUPPORTED;
goto out;
}
drc = spapr_dr_connector_by_index(sensor_index);
if (!drc) {
DPRINTF("rtas_get_sensor_state: invalid sensor/DRC index: %xh\n",
sensor_index);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
ret = RTAS_OUT_PARAM_ERROR;
goto out;
}
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
entity_sense = drck->entity_sense(drc);
ret = drck->entity_sense(drc, &sensor_state);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
rtas_st(rets, 1, entity_sense);
out:
rtas_st(rets, 0, ret);
rtas_st(rets, 1, sensor_state);
}
/* configure-connector work area offsets, int32_t units for field

View File

@ -165,17 +165,17 @@ typedef struct sPAPRDRConnectorClass {
/*< public >*/
/* accessors for guest-visible (generally via RTAS) DR state */
int (*set_isolation_state)(sPAPRDRConnector *drc,
sPAPRDRIsolationState state);
int (*set_indicator_state)(sPAPRDRConnector *drc,
sPAPRDRIndicatorState state);
int (*set_allocation_state)(sPAPRDRConnector *drc,
sPAPRDRAllocationState state);
uint32_t (*set_isolation_state)(sPAPRDRConnector *drc,
sPAPRDRIsolationState state);
uint32_t (*set_indicator_state)(sPAPRDRConnector *drc,
sPAPRDRIndicatorState state);
uint32_t (*set_allocation_state)(sPAPRDRConnector *drc,
sPAPRDRAllocationState state);
uint32_t (*get_index)(sPAPRDRConnector *drc);
uint32_t (*get_type)(sPAPRDRConnector *drc);
const char *(*get_name)(sPAPRDRConnector *drc);
sPAPRDREntitySense (*entity_sense)(sPAPRDRConnector *drc);
uint32_t (*entity_sense)(sPAPRDRConnector *drc, sPAPRDREntitySense *state);
/* QEMU interfaces for managing FDT/configure-connector */
const void *(*get_fdt)(sPAPRDRConnector *drc, int *fdt_start_offset);