From 91a074d8934de4de3b406bd4e25ce663b889703f Mon Sep 17 00:00:00 2001 From: jmcneill Date: Fri, 18 Jan 2008 00:33:54 +0000 Subject: [PATCH] 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. --- sys/dev/acpi/acpi_ec.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/sys/dev/acpi/acpi_ec.c b/sys/dev/acpi/acpi_ec.c index 14499e72e0fb..d6a5728a75ae 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 . @@ -59,7 +59,7 @@ */ #include -__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 #include @@ -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);