Index: acpi_ec.c =================================================================== RCS file: /home/ncvs/src/sys/dev/acpica/acpi_ec.c,v retrieving revision 1.29 diff -u -r1.29 acpi_ec.c --- acpi_ec.c 27 Nov 2002 18:09:20 -0000 1.29 +++ acpi_ec.c 23 Jun 2003 18:46:00 -0000 @@ -616,7 +616,6 @@ EcWaitEventIntr(struct acpi_ec_softc *sc, EC_EVENT Event) { EC_STATUS EcStatus; - int i; ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, (UINT32)Event); @@ -628,28 +627,33 @@ ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev), "EcWaitEventIntr called without EC lock!\n"); + /* + * Stall for 1 microsecond before reading the status register + * for the first time. This allows the EC to set the IBF/OBF + * bit to its proper state. + */ + AcpiOsStall(1); EcStatus = EC_GET_CSR(sc); + if ((Event == EC_EVENT_OUTPUT_BUFFER_FULL && + (EcStatus & EC_FLAG_OUTPUT_BUFFER) != 0) || + (Event == EC_EVENT_INPUT_BUFFER_EMPTY && + (EcStatus & EC_FLAG_INPUT_BUFFER) == 0)) + return(AE_OK); - /* 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); - } + /* Wait up to 10ms for the EC status to indicate completion. */ + sc->ec_csrvalue = 0; + if (ACPI_MSLEEP(&sc->ec_csrvalue, &acpi_mutex, PZERO, "EcWait", hz / 100) + != EWOULDBLOCK) { + EcStatus = sc->ec_csrvalue; + } else { + EcStatus = EC_GET_CSR(sc); } + if ((Event == EC_EVENT_OUTPUT_BUFFER_FULL && + (EcStatus & EC_FLAG_OUTPUT_BUFFER) != 0) || + (Event == EC_EVENT_INPUT_BUFFER_EMPTY && + (EcStatus & EC_FLAG_INPUT_BUFFER) == 0)) + return(AE_OK); + return_ACPI_STATUS(AE_ERROR); } @@ -669,11 +673,8 @@ * Stall for 1 microsecond before reading the status register * for the first time. This allows the EC to set the IBF/OBF * bit to its proper state. - * - * XXX it is not clear why we read the CSR twice. */ AcpiOsStall(1); - EcStatus = EC_GET_CSR(sc); /* * Wait For Event: @@ -684,13 +685,11 @@ for (i = 0; i < 1000; i++) { EcStatus = EC_GET_CSR(sc); - if ((Event == EC_EVENT_OUTPUT_BUFFER_FULL) && - (EcStatus & EC_FLAG_OUTPUT_BUFFER)) - return(AE_OK); - - if ((Event == EC_EVENT_INPUT_BUFFER_EMPTY) && - !(EcStatus & EC_FLAG_INPUT_BUFFER)) - return(AE_OK); + if ((Event == EC_EVENT_OUTPUT_BUFFER_FULL && + (EcStatus & EC_FLAG_OUTPUT_BUFFER) != 0) || + (Event == EC_EVENT_INPUT_BUFFER_EMPTY && + (EcStatus & EC_FLAG_INPUT_BUFFER) == 0)) + return(AE_OK); AcpiOsStall(10); }