Thanks for your patch submission. I looked into it and found a few
problems. Attached is a patch based on yours that should be equivalent
but fixes a few problems:
* Don't call msleep if event has already occurred
* Don't read CSR twice if not necessary (also fixed in EcEventWait)
* Unused loop variable removed
And same as yours:
* 1 us wait added before first EC_STATUS read
* A single call of msleep with 10 ms timeout is now used
Please try the patch and see if it works for you.
-Nate
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);
}
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"