On the HP8350w (and others with acpitz issues etc) IBF or OBF are set
well before the data is actually ready to read or write.  By adding some
delays on the way out we seem to work around this problem and the
machine goes from flaky (hung keyboard and hung graphics etc) to rock
solid.  It suspends/resumes, the works.

Looking at the linux driver it seems that they don't run into this issue
because it takes a while between getting IBF/OBF to reading/writing the
data.  Their driver waits before it starts handling a command, while
handling a command and on the way out.  So this seems like a safe
workaround for now.

Jordan has a state machine based acpiec diff in the works that does a
bit more checking.  Contact me off list if you want to play with that.
Do send me failure reports with this diff.

Index: acpiec.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpiec.c,v
retrieving revision 1.43
diff -u -p -r1.43 acpiec.c
--- acpiec.c    8 Aug 2010 17:25:41 -0000       1.43
+++ acpiec.c    29 Sep 2010 04:24:13 -0000
@@ -92,7 +92,7 @@ void
 acpiec_wait(struct acpiec_softc *sc, u_int8_t mask, u_int8_t val)
 {
        static int acpiecnowait;
-       u_int8_t                stat;
+       volatile u_int8_t stat;
 
        dnprintf(40, "%s: EC wait_ns for: %b == %02x\n",
            DEVNAME(sc), (int)mask,
@@ -104,8 +104,14 @@ acpiec_wait(struct acpiec_softc *sc, u_i
                if (cold || (stat & EC_STAT_BURST))
                        delay(1);
                else
-                       tsleep(&acpiecnowait, PWAIT, "acpiec", 1);
+                       tsleep(&acpiecnowait, PWAIT, "ecstat", 1);
        }
+
+       /* delay to make sure the data is actually ready */
+       if (cold)
+               delay(10);
+       else
+               tsleep(&acpiecnowait, PWAIT, "ecout", 1);
 
        dnprintf(40, "%s: EC wait_ns, stat: %b\n", DEVNAME(sc), (int)stat,
            "\20\x8IGN\x7SMI\x6SCI\05BURST\04CMD\03IGN\02IBF\01OBF");

Reply via email to