Exemple #1
0
static ACPI_STATUS
EcTransaction(struct acpi_ec_softc *sc, EC_REQUEST *EcRequest)
{
    ACPI_STATUS	Status;

    /*
     * Lock the EC
     */
    if (ACPI_FAILURE(Status = EcLock(sc)))
	return(Status);

    /*
     * Perform the transaction.
     */
    switch (EcRequest->Command) {
    case EC_COMMAND_READ:
	Status = EcRead(sc, EcRequest->Address, &(EcRequest->Data));
	break;

    case EC_COMMAND_WRITE:
	Status = EcWrite(sc, EcRequest->Address, &(EcRequest->Data));
	break;

    default:
	Status = AE_SUPPORT;
	break;
    }

    /*
     * Unlock the EC
     */
    EcUnlock(sc);
    
    /*
     * Clear & Re-Enable the EC GPE:
     * -----------------------------
     * 'Consume' any EC GPE events that we generated while performing
     * the transaction (e.g. IBF/OBF).	Clearing the GPE here shouldn't
     * have an adverse affect on outstanding EC-SCI's, as the source
     * (EC-SCI) will still be high and thus should trigger the GPE
     * immediately after we re-enabling it.
     */
    if (sc->ec_pendquery){
	if (ACPI_FAILURE(AcpiOsQueueForExecution(OSD_PRIORITY_HIGH,
						 EcGpeQueryHandler, sc)))
	    printf("Pend Query Queuing Failed\n");
	sc->ec_pendquery = 0;
    }

    if (ACPI_FAILURE(AcpiClearEvent(sc->ec_gpebit, ACPI_EVENT_GPE)))
	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
	    "EcRequest: Unable to clear the EC GPE.\n");
    if (ACPI_FAILURE(AcpiEnableEvent(sc->ec_gpebit, ACPI_EVENT_GPE, 0)))
	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
	    "EcRequest: Unable to re-enable the EC GPE.\n");

    return(Status);
}
Exemple #2
0
static ACPI_STATUS
EcTransaction(struct acpi_ec_softc *sc, EC_REQUEST *EcRequest)
{
	ACPI_STATUS Status;

	if ((Status = EcLock(sc)) != AE_OK)
		return (Status);

	/*
	 * Perform the transaction.
	 */
	switch (EcRequest->Command) {
	case EC_COMMAND_READ:
		Status = EcRead(sc, EcRequest->Address, &(EcRequest->Data));
		break;

	case EC_COMMAND_WRITE:
		Status = EcWrite(sc, EcRequest->Address, &(EcRequest->Data));
		break;

	default:
		Status = AE_SUPPORT;
		break;
	}

	/*
	 * Clear & Re-Enable the EC GPE:
	 * -----------------------------
	 * 'Consume' any EC GPE events that we generated while performing
	 * the transaction (e.g. IBF/OBF). Clearing the GPE here shouldn't
	 * have an adverse affect on outstanding EC-SCI's, as the source
	 * (EC-SCI) will still be high and thus should trigger the GPE
	 * immediately after we re-enabling it.
	 */
	if (sc->sc_flags & EC_F_PENDQUERY) {
		if (AcpiOsQueueForExecution(OSD_PRIORITY_HIGH,
		    EcGpeQueryHandler, sc) != AE_OK)
			printf("%s: unable to queue pending query\n",
			    sc->sc_dev.dv_xname);
		sc->sc_flags &= ~EC_F_PENDQUERY;
	}

	if (AcpiClearEvent(sc->sc_gpebit, ACPI_EVENT_GPE) != AE_OK)
		printf("%s: EcRequest: unable to clear EC GPE\n",
		    sc->sc_dev.dv_xname);
	if (AcpiEnableEvent(sc->sc_gpebit, ACPI_EVENT_GPE) != AE_OK)
		printf("%s: EcRequest: unable to reenable EC GPE\n",
		    sc->sc_dev.dv_xname);

	EcUnlock(sc);

	return(Status);
}
Exemple #3
0
static int
acpi_button_attach(device_t dev)
{
    struct acpi_prw_data	prw;
    struct acpi_button_softc	*sc;
    ACPI_STATUS			status;
    int event;

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

    sc = device_get_softc(dev);
    sc->button_dev = dev;
    sc->button_handle = acpi_get_handle(dev);
    event = (sc->button_type == ACPI_SLEEP_BUTTON) ?
	    ACPI_EVENT_SLEEP_BUTTON : ACPI_EVENT_POWER_BUTTON;

    /* 
     * Install the new handler.  We could remove any fixed handlers added
     * from the FADT once we have a duplicate from the AML but some systems
     * only return events on one or the other so we have to keep both.
     */
    if (sc->fixed) {
	AcpiClearEvent(event);
	status = AcpiInstallFixedEventHandler(event,
			acpi_button_fixed_handler, sc);
    } else {
	/*
	 * If a system does not get lid events, it may make sense to change
	 * the type to ACPI_ALL_NOTIFY.  Some systems generate both a wake
	 * and runtime notify in that case though.
	 */
	status = AcpiInstallNotifyHandler(sc->button_handle,
			ACPI_DEVICE_NOTIFY, acpi_button_notify_handler, sc);
    }
    if (ACPI_FAILURE(status)) {
	device_printf(sc->button_dev, "couldn't install notify handler - %s\n",
		      AcpiFormatException(status));
	return_VALUE (ENXIO);
    }

    /* Enable the GPE for wake/runtime */
    acpi_wake_set_enable(dev, 1);
    if (acpi_parse_prw(sc->button_handle, &prw) == 0)
	AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit);
    
    return_VALUE (0);
}
Exemple #4
0
void
reset_fixed_event(uint32 event)
{
    AcpiClearEvent(event);
}
Exemple #5
0
ACPI_STATUS
AtFixedEventsCommon(
    UINT32                  ApiCall,
    UINT32                  CheckAction,
    ACPI_STATUS             ExpectedStatus)
{
    ACPI_STATUS             Status;
    UINT32                  Event, Flags = 0;
    UINT32                  i;
    char                    *ApiCallName;
    ACPI_EVENT_STATUS       EventStatus, *EventStatusPointer = &EventStatus;

    Status = AtSubsystemInit(
        AAPITS_INI_DEF,
        AAPITS_EN_FLAGS, AAPITS_OI_FLAGS, NULL);
    if (ACPI_FAILURE(Status))
    {
        return (Status);
    }

    for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++)
    {
        switch (i)
        {
        case 0:
            Event = ACPI_EVENT_PMTIMER;
            break;
        case 1:
            Event = ACPI_EVENT_GLOBAL;
            break;
        case 2:
            Event = ACPI_EVENT_POWER_BUTTON;
            break;
        case 3:
            Event = ACPI_EVENT_SLEEP_BUTTON;
            break;
        case 4:
            Event = ACPI_EVENT_RTC;
            break;
        default:
            TestErrors++;
            printf ("Test Error: the number of Fixed Events (%d) too big (should be 5)\n",
                ACPI_NUM_FIXED_EVENTS);
            return (AE_ERROR);
        }
        if (CheckAction == 1)
        {
            Event += ACPI_NUM_FIXED_EVENTS;
        }
        else if (CheckAction == 2)
        {
            EventStatusPointer = NULL;
        }

        switch (ApiCall)
        {
        case 0:
            ApiCallName = "AcpiEnableEvent";
            Status = AcpiEnableEvent(Event, Flags);
            break;
        case 1:
            ApiCallName = "AcpiDisableEvent";
            Status = AcpiDisableEvent(Event, Flags);
            break;
        case 2:
            ApiCallName = "AcpiClearEvent";
            Status = AcpiClearEvent(Event);
            break;
        case 3:
            ApiCallName = "AcpiGetEventStatus";
            Status = AcpiGetEventStatus(Event, EventStatusPointer);
            break;
        default:
            TestErrors++;
            printf ("Test Error: the ApiCall number (%d) should be in range 0-3\n",
                ApiCall);
            return (AE_ERROR);
        }

        if (Status != ExpectedStatus)
        {
            AapiErrors++;
            printf ("Api Error: %s(%d) returned %s, expected %s\n",
                ApiCallName, Event, AcpiFormatException(Status),
                AcpiFormatException(ExpectedStatus));
            if (Status != AE_OK)
            {
                return (Status);
            }
            else
            {
                return (AE_ERROR);
            }
        }
    }

    return (AtTerminateCtrlCheck(AE_OK, ALL_STAT));
}
Exemple #6
0
static void
EcGpeQueryHandler(void *Context)
{
    struct acpi_ec_softc	*sc = (struct acpi_ec_softc *)Context;
    UINT8			Data;
    ACPI_STATUS			Status;
    char			qxx[5];

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

    for (;;) {

	/*
	 * Check EC_SCI.
	 * 
	 * Bail out if the EC_SCI bit of the status register is not set.
	 * Note that this function should only be called when
	 * this bit is set (polling is used to detect IBE/OBF events).
	 *
	 * It is safe to do this without locking the controller, as it's
	 * OK to call EcQuery when there's no data ready; in the worst
	 * case we should just find nothing waiting for us and bail.
	 */
	if (!(EC_GET_CSR(sc) & EC_EVENT_SCI))
	    break;

	/*
	 * Find out why the EC is signalling us
	 */
	Status = EcQuery(sc, &Data);
	    
	/*
	 * If we failed to get anything from the EC, give up
	 */
	if (ACPI_FAILURE(Status)) {
	    ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
		"GPE query failed - %s\n", AcpiFormatException(Status));
	    break;
	}

	/*
	 * Evaluate _Qxx to respond to the controller.
	 */
	sprintf(qxx, "_Q%02x", Data);
	strupr(qxx);
	Status = AcpiEvaluateObject(sc->ec_handle, qxx, NULL, NULL);
	/*
	 * Ignore spurious query requests.
	 */
	if (ACPI_FAILURE(Status) && (Data != 0 || Status != AE_NOT_FOUND)) {
	    ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
	    	"evaluation of GPE query method %s failed - %s\n", 
			qxx, AcpiFormatException(Status));
	}
    }
        /* I know I request Level trigger cleanup */
    if (ACPI_FAILURE(AcpiClearEvent(sc->ec_gpebit, ACPI_EVENT_GPE)))
	    printf("EcGpeQueryHandler:ClearEvent Failed\n");
    if (ACPI_FAILURE(AcpiEnableEvent(sc->ec_gpebit, ACPI_EVENT_GPE, 0)))
	    printf("EcGpeQueryHandler:EnableEvent Failed\n");
    return_VOID;
}
Exemple #7
0
static void
EcGpeQueryHandler(void *Context)
{
	struct acpi_ec_softc *sc = Context;
	UINT8 Data;
	ACPI_STATUS Status;
	char qxx[5];

	FUNCTION_TRACE(__FUNCTION__);

	for (;;) {
		/*
		 * Check EC_SCI.
		 * 
		 * Bail out if the EC_SCI bit of the status register is not
		 * set. Note that this function should only be called when
		 * this bit is set (polling is used to detect IBE/OBF events).
		 *
		 * It is safe to do this without locking the controller, as
		 * it's OK to call EcQuery when there's no data ready; in the
		 * worst case we should just find nothing waiting for us and
		 * bail.
		 */
		if ((EC_CSR_READ(sc) & EC_EVENT_SCI) == 0)
			break;

		/*
		 * Find out why the EC is signalling us
		 */
		Status = EcQuery(sc, &Data);
	    
		/*
		 * If we failed to get anything from the EC, give up.
		 */
		if (Status != AE_OK) {
			printf("%s: GPE query failed: %d\n",
			    sc->sc_dev.dv_xname, Status);
			break;
		}

		/*
		 * Evaluate _Qxx to respond to the controller.
		 */
		sprintf(qxx, "_Q%02x", Data);
		strupr(qxx);
		Status = AcpiEvaluateObject(sc->sc_node->ad_handle, qxx,
		    NULL, NULL);

		/*
		 * Ignore spurious query requests.
		 */
		if (Status != AE_OK &&
		    (Data != 0 || Status != AE_NOT_FOUND)) {
			printf("%s: evaluation of GPE query method %s "
			    "failed: %d\n", sc->sc_dev.dv_xname, qxx, Status);
		}
	}

	/* I know I request Level trigger cleanup */
	if (AcpiClearEvent(sc->sc_gpebit, ACPI_EVENT_GPE) != AE_OK)
		printf("%s: AcpiClearEvent failed\n", sc->sc_dev.dv_xname);
	if (AcpiEnableEvent(sc->sc_gpebit, ACPI_EVENT_GPE) != AE_OK)
		printf("%s: AcpiEnableEvent failed\n", sc->sc_dev.dv_xname);

	return_VOID;
}