summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica/acpi_ec.c
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2010-08-06 23:35:33 +0000
committerjkim <jkim@FreeBSD.org>2010-08-06 23:35:33 +0000
commit2c643eaad8bc406694b08214c18389cd94446e22 (patch)
tree022402fc2c4c119c4e89f7a9ebdde68fffa65994 /sys/dev/acpica/acpi_ec.c
parent68285361e2b84f72f44b4146a32b9766dd28f986 (diff)
downloadFreeBSD-src-2c643eaad8bc406694b08214c18389cd94446e22.zip
FreeBSD-src-2c643eaad8bc406694b08214c18389cd94446e22.tar.gz
When EC burst mode is activated and multiple bytes are accessed, do not
disable and enable repeatedly, just do it once per call. It also reduces code duplication. Check all parameters early and fail immediately.
Diffstat (limited to 'sys/dev/acpica/acpi_ec.c')
-rw-r--r--sys/dev/acpica/acpi_ec.c81
1 files changed, 27 insertions, 54 deletions
diff --git a/sys/dev/acpica/acpi_ec.c b/sys/dev/acpica/acpi_ec.c
index 94dca9e..2c18972 100644
--- a/sys/dev/acpica/acpi_ec.c
+++ b/sys/dev/acpica/acpi_ec.c
@@ -720,24 +720,19 @@ 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_STATUS Status;
+ ACPI_PHYSICAL_ADDRESS EcAddr;
UINT8 *EcData;
- UINT8 EcAddr;
- int bytes, i;
+ 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);
- bytes = Width / 8;
- if (Address + bytes - 1 > 0xFF)
+ if (Address + Width / 8 > 256)
return_ACPI_STATUS (AE_BAD_ADDRESS);
- if (Function == ACPI_READ)
- *Value = 0;
- EcAddr = Address;
- EcData = (UINT8 *)Value;
-
/*
* 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.
@@ -754,8 +749,21 @@ EcSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 Width,
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. */
- for (i = 0; i < bytes; i++, EcAddr++, EcData++) {
+ EcAddr = Address;
+ EcData = (UINT8 *)Value;
+ if (Function == ACPI_READ)
+ *Value = 0;
+ do {
switch (Function) {
case ACPI_READ:
Status = EcRead(sc, EcAddr, EcData);
@@ -763,14 +771,17 @@ EcSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 Width,
case ACPI_WRITE:
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;
+ 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);
@@ -943,22 +954,11 @@ static ACPI_STATUS
EcRead(struct acpi_ec_softc *sc, UINT8 Address, UINT8 *Data)
{
ACPI_STATUS status;
- UINT8 data;
u_int gen_count;
ACPI_SERIAL_ASSERT(ec);
CTR1(KTR_ACPI, "ec read from %#x", Address);
- /* 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_READ);
if (ACPI_FAILURE(status))
return (status);
@@ -972,14 +972,6 @@ EcRead(struct acpi_ec_softc *sc, UINT8 Address, UINT8 *Data)
}
*Data = EC_GET_DATA(sc);
- 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);
}
@@ -987,22 +979,11 @@ 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);
@@ -1023,13 +1004,5 @@ EcWrite(struct acpi_ec_softc *sc, UINT8 Address, UINT8 Data)
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);
}
OpenPOWER on IntegriCloud