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]"

Reply via email to