Exemplo n.º 1
0
static ACPI_STATUS
EcSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 width,
	       ACPI_INTEGER *Value, void *Context, void *RegionContext)
{
    struct acpi_ec_softc	*sc = (struct acpi_ec_softc *)Context;
    ACPI_STATUS			Status;
    UINT8			EcAddr, EcData;
    int				i;

    ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, (UINT32)Address);

    if (width % 8 != 0 || Value == NULL || Context == NULL)
	return_ACPI_STATUS (AE_BAD_PARAMETER);
    if (Address + (width / 8) - 1 > 0xFF)
	return_ACPI_STATUS (AE_BAD_ADDRESS);

    if (Function == ACPI_READ)
	*Value = 0;
    EcAddr = Address;
    Status = AE_ERROR;

    /*
     * If booting, check if we need to run the query handler.  If so, we
     * we call it directly here since our thread taskq is not active yet.
     */
    if (cold || rebooting) {
	if ((EC_GET_CSR(sc) & EC_EVENT_SCI)) {
	    CTR0(KTR_ACPI, "ec running gpe handler directly");
	    EcGpeQueryHandler(sc);
	}
    }

    /* Serialize with EcGpeQueryHandler() at transaction granularity. */
    Status = EcLock(sc);
    if (ACPI_FAILURE(Status))
	return_ACPI_STATUS (Status);

    /* Perform the transaction(s), based on width. */
    for (i = 0; i < width; i += 8, EcAddr++) {
	switch (Function) {
	case ACPI_READ:
	    Status = EcRead(sc, EcAddr, &EcData);
	    if (ACPI_SUCCESS(Status))
		*Value |= ((ACPI_INTEGER)EcData) << i;
	    break;
	case ACPI_WRITE:
	    EcData = (UINT8)((*Value) >> i);
	    Status = EcWrite(sc, EcAddr, &EcData);
	    break;
	default:
	    device_printf(sc->ec_dev, "invalid EcSpaceHandler function %d\n",
			  Function);
	    Status = AE_BAD_PARAMETER;
	    break;
	}
	if (ACPI_FAILURE(Status))
	    break;
    }

    EcUnlock(sc);
    return_ACPI_STATUS (Status);
}
Exemplo n.º 2
0
static ACPI_STATUS
EcSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 Width,
               UINT64 *Value, void *Context, void *RegionContext)
{
    struct acpi_ec_softc	*sc = (struct acpi_ec_softc *)Context;
    ACPI_PHYSICAL_ADDRESS	EcAddr;
    UINT8			*EcData;
    ACPI_STATUS			Status;

    ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, (UINT32)Address);

    if (Function != ACPI_READ && Function != ACPI_WRITE)
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    if (Width % 8 != 0 || Value == NULL || Context == NULL)
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    if (Address + Width / 8 > 256)
        return_ACPI_STATUS (AE_BAD_ADDRESS);

    /*
     * If booting, check if we need to run the query handler.  If so, we
     * we call it directly here since our thread taskq is not active yet.
     */
    if (cold || rebooting || sc->ec_suspending) {
        if ((EC_GET_CSR(sc) & EC_EVENT_SCI)) {
            CTR0(KTR_ACPI, "ec running gpe handler directly");
            EcGpeQueryHandler(sc);
        }
    }

    /* Serialize with EcGpeQueryHandler() at transaction granularity. */
    Status = EcLock(sc);
    if (ACPI_FAILURE(Status))
        return_ACPI_STATUS (Status);

    /* If we can't start burst mode, continue anyway. */
    Status = EcCommand(sc, EC_COMMAND_BURST_ENABLE);
    if (ACPI_SUCCESS(Status)) {
        if (EC_GET_DATA(sc) == EC_BURST_ACK) {
            CTR0(KTR_ACPI, "ec burst enabled");
            sc->ec_burstactive = TRUE;
        }
    }

    /* Perform the transaction(s), based on Width. */
    EcAddr = Address;
    EcData = (UINT8 *)Value;
    if (Function == ACPI_READ)
        *Value = 0;
    do {
        switch (Function) {
        case ACPI_READ:
            Status = EcRead(sc, EcAddr, EcData);
            break;
        case ACPI_WRITE:
            Status = EcWrite(sc, EcAddr, *EcData);
            break;
        }
        if (ACPI_FAILURE(Status))
            break;
        EcAddr++;
        EcData++;
    } while (EcAddr < Address + Width / 8);

    if (sc->ec_burstactive) {
        sc->ec_burstactive = FALSE;
        if (ACPI_SUCCESS(EcCommand(sc, EC_COMMAND_BURST_DISABLE)))
            CTR0(KTR_ACPI, "ec disabled burst ok");
    }

    EcUnlock(sc);
    return_ACPI_STATUS (Status);
}