diff options
| author | jmcneill <jmcneill@NetBSD.org> | 2008-01-18 00:33:54 +0000 |
|---|---|---|
| committer | jmcneill <jmcneill@NetBSD.org> | 2008-01-18 00:33:54 +0000 |
| commit | 91a074d8934de4de3b406bd4e25ce663b889703f (patch) | |
| tree | 3781d4ac8d8638f29d334413ffb4d5a2831e6c4c /sys/dev | |
| parent | 80a83a2b7ed2ab80984dd0569b116947eb6bd16e (diff) | |
If we are in polling mode, do not try to spin forever in the state machine
waiting for a read or write to complete. Workaround an issue on my VAIO,
but we really need to figure out why it is failing in the first place.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/acpi/acpi_ec.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/sys/dev/acpi/acpi_ec.c b/sys/dev/acpi/acpi_ec.c index 14499e72e0f..d6a5728a75a 100644 --- a/sys/dev/acpi/acpi_ec.c +++ b/sys/dev/acpi/acpi_ec.c @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_ec.c,v 1.48 2007/12/21 21:22:54 jmcneill Exp $ */ +/* $NetBSD: acpi_ec.c,v 1.49 2008/01/18 00:33:54 jmcneill Exp $ */ /*- * Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>. @@ -59,7 +59,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_ec.c,v 1.48 2007/12/21 21:22:54 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_ec.c,v 1.49 2008/01/18 00:33:54 jmcneill Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -554,7 +554,7 @@ static ACPI_STATUS acpiec_read(device_t dv, uint8_t addr, uint8_t *val) { struct acpiec_softc *sc = device_private(dv); - int i; + int i, timeo = 10000; acpiec_lock(dv); mutex_enter(&sc->sc_mtx); @@ -570,10 +570,18 @@ acpiec_read(device_t dv, uint8_t addr, uint8_t *val) } if (cold || acpiec_cold) { - while (sc->sc_state != EC_STATE_FREE) { + while (sc->sc_state != EC_STATE_FREE && timeo-- > 0) { delay(1); acpiec_gpe_state_machine(dv); } + if (sc->sc_state != EC_STATE_FREE) { + mutex_exit(&sc->sc_mtx); + AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_NOT_ISR); + acpiec_unlock(dv); + aprint_error_dev(dv, "command timed out, state %d\n", + sc->sc_state); + return AE_ERROR; + } } else while (cv_timedwait(&sc->sc_cv, &sc->sc_mtx, EC_CMD_TIMEOUT * hz)) { mutex_exit(&sc->sc_mtx); AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_NOT_ISR); @@ -594,7 +602,7 @@ static ACPI_STATUS acpiec_write(device_t dv, uint8_t addr, uint8_t val) { struct acpiec_softc *sc = device_private(dv); - int i; + int i, timeo = 10000; acpiec_lock(dv); mutex_enter(&sc->sc_mtx); @@ -611,10 +619,18 @@ acpiec_write(device_t dv, uint8_t addr, uint8_t val) } if (cold || acpiec_cold) { - while (sc->sc_state != EC_STATE_FREE) { + while (sc->sc_state != EC_STATE_FREE && timeo-- > 0) { delay(1); acpiec_gpe_state_machine(dv); } + if (sc->sc_state != EC_STATE_FREE) { + mutex_exit(&sc->sc_mtx); + AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_NOT_ISR); + acpiec_unlock(dv); + aprint_error_dev(dv, "command timed out, state %d\n", + sc->sc_state); + return AE_ERROR; + } } else while (cv_timedwait(&sc->sc_cv, &sc->sc_mtx, EC_CMD_TIMEOUT * hz)) { mutex_exit(&sc->sc_mtx); AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_NOT_ISR); |
