コード例 #1
0
ファイル: acpi_ec.c プロジェクト: AhmadTux/DragonFlyBSD
static void
EcGpeQueryHandler(void *Context)
{
    struct acpi_ec_softc	*sc = (struct acpi_ec_softc *)Context;
    UINT8			Data;
    ACPI_STATUS			Status;
    int				retry, sci_enqueued;
    char			qxx[5];

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
    KASSERT(Context != NULL, ("EcGpeQueryHandler called with NULL"));

    /* Serialize user access with EcSpaceHandler(). */
    Status = EcLock(sc);
    if (ACPI_FAILURE(Status)) {
	device_printf(sc->ec_dev, "GpeQuery lock error: %s\n",
	    AcpiFormatException(Status));
	return;
    }

    /*
     * Send a query command to the EC to find out which _Qxx call it
     * wants to make.  This command clears the SCI bit and also the
     * interrupt source since we are edge-triggered.  To prevent the GPE
     * that may arise from running the query from causing another query
     * to be queued, we clear the pending flag only after running it.
     */
    sci_enqueued = sc->ec_sci_pend;
    for (retry = 0; retry < 2; retry++) {
	Status = EcCommand(sc, EC_COMMAND_QUERY);
	if (ACPI_SUCCESS(Status))
	    break;
	if (EcCheckStatus(sc, "retr_check",
	    EC_EVENT_INPUT_BUFFER_EMPTY) == AE_OK)
	    continue;
	else
	    break;
    }
    sc->ec_sci_pend = FALSE;
    if (ACPI_FAILURE(Status)) {
	EcUnlock(sc);
	device_printf(sc->ec_dev, "GPE query failed: %s\n",
	    AcpiFormatException(Status));
	return;
    }
    Data = EC_GET_DATA(sc);

    /*
     * We have to unlock before running the _Qxx method below since that
     * method may attempt to read/write from EC address space, causing
     * recursive acquisition of the lock.
     */
    EcUnlock(sc);

    /* Ignore the value for "no outstanding event". (13.3.5) */
    if (Data == 0)
	return;

    /* Evaluate _Qxx to respond to the controller. */
    ksnprintf(qxx, sizeof(qxx), "_Q%02X", Data);
    AcpiUtStrupr(qxx);
    Status = AcpiEvaluateObject(sc->ec_handle, qxx, NULL, NULL);
    if (ACPI_FAILURE(Status) && Status != AE_NOT_FOUND) {
	device_printf(sc->ec_dev, "evaluation of query method %s failed: %s\n",
	    qxx, AcpiFormatException(Status));
    }

    /* Reenable runtime GPE if its execution was deferred. */
    if (sci_enqueued) {
	Status = AcpiFinishGpe(sc->ec_gpehandle, sc->ec_gpebit);
	if (ACPI_FAILURE(Status))
	    device_printf(sc->ec_dev, "reenabling runtime GPE failed: %s\n",
		AcpiFormatException(Status));
    }
}
コード例 #2
0
ファイル: BusManager.cpp プロジェクト: simonsouth/haiku
status_t
finish_gpe(acpi_handle handle, uint32 gpeNumber)
{
    return AcpiFinishGpe(handle, gpeNumber) == AE_OK ? B_OK : B_ERROR;
}