Commit 9c914e53 authored by David Gibson's avatar David Gibson
Browse files

spapr: Split DRC release from DRC detach



spapr_drc_detach() is called when qemu generic code requests a device be
unplugged.  It makes a number of tests, which could well delay further
action until later, before actually detach the device from the DRC.

This splits out the part which actually removes the device from the DRC
into spapr_drc_release().  This will be useful for further cleanups.

Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Reviewed-by: default avatarGreg Kurz <groug@kaod.org>
Reviewed-by: default avatarMichael Roth <mdroth@linux.vnet.ibm.com>
parent 307b7715
Loading
Loading
Loading
Loading
+27 −22
Original line number Diff line number Diff line
@@ -315,29 +315,8 @@ void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
                             NULL, 0, NULL);
}

void spapr_drc_detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp)
static void spapr_drc_release(sPAPRDRConnector *drc)
{
    trace_spapr_drc_detach(spapr_drc_index(drc));

    if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) {
        trace_spapr_drc_awaiting_isolated(spapr_drc_index(drc));
        drc->awaiting_release = true;
        return;
    }

    if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI &&
        drc->allocation_state != SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
        trace_spapr_drc_awaiting_unusable(spapr_drc_index(drc));
        drc->awaiting_release = true;
        return;
    }

    if (drc->awaiting_allocation) {
        drc->awaiting_release = true;
        trace_spapr_drc_awaiting_allocation(spapr_drc_index(drc));
        return;
    }

    drc->dr_indicator = SPAPR_DR_INDICATOR_INACTIVE;

    /* Calling release callbacks based on spapr_drc_type(drc). */
@@ -365,6 +344,32 @@ void spapr_drc_detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp)
    drc->dev = NULL;
}

void spapr_drc_detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp)
{
    trace_spapr_drc_detach(spapr_drc_index(drc));

    if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) {
        trace_spapr_drc_awaiting_isolated(spapr_drc_index(drc));
        drc->awaiting_release = true;
        return;
    }

    if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI &&
        drc->allocation_state != SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
        trace_spapr_drc_awaiting_unusable(spapr_drc_index(drc));
        drc->awaiting_release = true;
        return;
    }

    if (drc->awaiting_allocation) {
        drc->awaiting_release = true;
        trace_spapr_drc_awaiting_allocation(spapr_drc_index(drc));
        return;
    }

    spapr_drc_release(drc);
}

static bool release_pending(sPAPRDRConnector *drc)
{
    return drc->awaiting_release;