示例#1
0
static ACPI_STATUS
EcWrite(struct acpi_ec_softc *sc, UINT8 Address, UINT8 Data)
{
    ACPI_STATUS	status;
    u_int gen_count;

    ACPI_SERIAL_ASSERT(ec);

    status = EcCommand(sc, EC_COMMAND_WRITE);
    if (ACPI_FAILURE(status))
	return (status);

    gen_count = sc->ec_gencount;
    EC_SET_DATA(sc, Address);
    status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, gen_count);
    if (ACPI_FAILURE(status)) {
	device_printf(sc->ec_dev, "EcWrite: failed waiting for sent address\n");
	return (status);
    }

    gen_count = sc->ec_gencount;
    EC_SET_DATA(sc, Data);
    status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, gen_count);
    if (ACPI_FAILURE(status)) {
	device_printf(sc->ec_dev, "EcWrite: failed waiting for sent data\n");
	return (status);
    }

    return (AE_OK);
}
示例#2
0
static ACPI_STATUS
EcCommand(struct acpi_ec_softc *sc, EC_COMMAND cmd)
{
    ACPI_STATUS	status;
    EC_EVENT	event;
    EC_STATUS	ec_status;
    u_int	gen_count;

    ACPI_SERIAL_ASSERT(ec);

    /* Don't use burst mode if user disabled it. */
    if (!ec_burst_mode && cmd == EC_COMMAND_BURST_ENABLE)
	return (AE_ERROR);

    /* Decide what to wait for based on command type. */
    switch (cmd) {
    case EC_COMMAND_READ:
    case EC_COMMAND_WRITE:
    case EC_COMMAND_BURST_DISABLE:
	event = EC_EVENT_INPUT_BUFFER_EMPTY;
	break;
    case EC_COMMAND_QUERY:
    case EC_COMMAND_BURST_ENABLE:
	event = EC_EVENT_OUTPUT_BUFFER_FULL;
	break;
    default:
	device_printf(sc->ec_dev, "EcCommand: invalid command %#x\n", cmd);
	return (AE_BAD_PARAMETER);
    }

    /*
     * Ensure empty input buffer before issuing command.
     * Use generation count of zero to force a quick check.
     */
    status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, 0);
    if (ACPI_FAILURE(status))
	return (status);

    /* Run the command and wait for the chosen event. */
    CTR1(KTR_ACPI, "ec running command %#x", cmd);
    gen_count = sc->ec_gencount;
    EC_SET_CSR(sc, cmd);
    status = EcWaitEvent(sc, event, gen_count);
    if (ACPI_SUCCESS(status)) {
	/* If we succeeded, burst flag should now be present. */
	if (cmd == EC_COMMAND_BURST_ENABLE) {
	    ec_status = EC_GET_CSR(sc);
	    if ((ec_status & EC_FLAG_BURST_MODE) == 0)
		status = AE_ERROR;
	}
    } else
	device_printf(sc->ec_dev, "EcCommand: no response to %#x\n", cmd);
    return (status);
}
示例#3
0
static ACPI_STATUS
EcWrite(struct acpi_ec_softc *sc, UINT8 Address, UINT8 Data)
{
    ACPI_STATUS	status;
    UINT8 data;
    u_int gen_count;

    ACPI_SERIAL_ASSERT(ec);
    CTR2(KTR_ACPI, "ec write to %#x, data %#x", Address, Data);

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

    status = EcCommand(sc, EC_COMMAND_WRITE);
    if (ACPI_FAILURE(status))
	return (status);

    gen_count = sc->ec_gencount;
    EC_SET_DATA(sc, Address);
    status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, gen_count);
    if (ACPI_FAILURE(status)) {
	device_printf(sc->ec_dev, "EcRead: failed waiting for sent address\n");
	return (status);
    }

    gen_count = sc->ec_gencount;
    EC_SET_DATA(sc, Data);
    status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, gen_count);
    if (ACPI_FAILURE(status)) {
	device_printf(sc->ec_dev, "EcWrite: failed waiting for sent data\n");
	return (status);
    }

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

    return (AE_OK);
}
示例#4
0
static ACPI_STATUS
EcRead(struct acpi_ec_softc *sc, UINT8 Address, UINT8 *Data)
{
    ACPI_STATUS	status;
    u_int gen_count;
    int retry;

    ACPI_SERIAL_ASSERT(ec);

    for (retry = 0; retry < 2; retry++) {
	status = EcCommand(sc, EC_COMMAND_READ);
	if (ACPI_FAILURE(status))
	    return (status);

	gen_count = sc->ec_gencount;
	EC_SET_DATA(sc, Address);
	status = EcWaitEvent(sc, EC_EVENT_OUTPUT_BUFFER_FULL, gen_count);
	if (ACPI_FAILURE(status)) {
	    if (EcCheckStatus(sc, "retr_check",
		EC_EVENT_INPUT_BUFFER_EMPTY) == AE_OK)
		continue;
	    else
		break;
	}
	*Data = EC_GET_DATA(sc);
	return (AE_OK);
    }
    device_printf(sc->ec_dev, "EcRead: failed waiting to get data\n");
    return (status);
}
示例#5
0
static ACPI_STATUS
EcQuery(struct acpi_ec_softc *sc, UINT8 *Data)
{
    ACPI_STATUS	Status;

    if (ACPI_FAILURE(Status = EcLock(sc)))
	return(Status);

    EC_SET_CSR(sc, EC_COMMAND_QUERY);
    if (ACPI_SUCCESS(Status = EcWaitEvent(sc, EC_EVENT_OUTPUT_BUFFER_FULL)))
	*Data = EC_GET_DATA(sc);

    EcUnlock(sc);

    if (ACPI_FAILURE(Status))
	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
	    "timeout waiting for EC to respond to EC_COMMAND_QUERY\n");
    return(Status);
}    
示例#6
0
文件: acpi_ec.c 项目: MarginC/kame
static ACPI_STATUS
EcQuery(struct acpi_ec_softc *sc, UINT8 *Data)
{
	ACPI_STATUS Status;

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

	EC_CSR_WRITE(sc, EC_COMMAND_QUERY);
	Status = EcWaitEvent(sc, EC_EVENT_OUTPUT_BUFFER_FULL);
	if (Status == AE_OK)
		*Data = EC_DATA_READ(sc);

	EcUnlock(sc);

	if (Status != AE_OK)
		printf("%s: timed out waiting for EC to respond to "
		    "EC_COMMAND_QUERY\n", sc->sc_dev.dv_xname);

	return (Status);
}    
示例#7
0
/*
 * Wait for an event interrupt for a specific condition.
 */
static ACPI_STATUS
EcWaitEventIntr(struct acpi_ec_softc *sc, EC_EVENT Event)
{
    EC_STATUS	EcStatus;
    int		i;

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

    /* XXX this should test whether interrupts are available some other way */
    if (cold || acpi_ec_event_driven)
	return_ACPI_STATUS(EcWaitEvent(sc, Event));

    if (!EcIsLocked(sc))
	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
	    "EcWaitEventIntr called without EC lock!\n");

    EcStatus = EC_GET_CSR(sc);

    /* XXX waiting too long? */
    for(i = 0; i < 10; i++){
	/*
	 * Check EC status against the desired event.
	 */
    	if ((Event == EC_EVENT_OUTPUT_BUFFER_FULL) &&
	    (EcStatus & EC_FLAG_OUTPUT_BUFFER))
	    return_ACPI_STATUS(AE_OK);
      
	if ((Event == EC_EVENT_INPUT_BUFFER_EMPTY) && 
	    !(EcStatus & EC_FLAG_INPUT_BUFFER))
	    return_ACPI_STATUS(AE_OK);
	
	sc->ec_csrvalue = 0;
	if (ACPI_MSLEEP(&sc->ec_csrvalue, &acpi_mutex, PZERO, "EcWait", 1) != EWOULDBLOCK){
	    EcStatus = sc->ec_csrvalue;
	}else{
	    EcStatus = EC_GET_CSR(sc);
	}
    }
    return_ACPI_STATUS(AE_ERROR);
}
示例#8
0
文件: acpi_ec.c 项目: MarginC/kame
static ACPI_STATUS
EcWaitEventIntr(struct acpi_ec_softc *sc, EC_EVENT Event)
{
	EC_STATUS EcStatus;
	int i;

	FUNCTION_TRACE_U32(__FUNCTION__, (UINT32)Event);

	/* XXX Need better test for "yes, you have interrupts". */
	if (cold)
		return_ACPI_STATUS(EcWaitEvent(sc, Event));

	if (EcIsLocked(sc) == 0)
		printf("%s: EcWaitEventIntr called without EC lock!\n",
		    sc->sc_dev.dv_xname);

	EcStatus = EC_CSR_READ(sc);

	/* Too long? */
	for (i = 0; i < 10; i++) {
		/* Check EC status against the desired event. */
		if ((Event == EC_EVENT_OUTPUT_BUFFER_FULL) &&
		    (EcStatus & EC_FLAG_OUTPUT_BUFFER) != 0)
			return_ACPI_STATUS(AE_OK);
      
		if ((Event == EC_EVENT_INPUT_BUFFER_EMPTY) &&
		    (EcStatus & EC_FLAG_INPUT_BUFFER) == 0)
			return_ACPI_STATUS(AE_OK);

		sc->sc_csrvalue = 0;
		/* XXXJRT Sleeping with a lock held? */
		if (tsleep(&sc->sc_csrvalue, 0, "EcWait", 1) != EWOULDBLOCK)
			EcStatus = sc->sc_csrvalue;
		else
			EcStatus = EC_CSR_READ(sc);
	}
	return_ACPI_STATUS(AE_ERROR);
}