PATCH: new acpi embedded controller I/O model

From: Nate Lawson <nate_at_root.org>
Date: Mon, 26 Feb 2007 18:20:02 -0800
If you are having EC timeout problems as in the below PR, please try the
latest EC code.  I just committed it in rev 1.69 of acpi_ec.c to
-current. Attached is the patch for 6-stable.

http://www.freebsd.org/cgi/query-pr.cgi?pr=98171

To use it, just recompile your acpi kernel module and load it at boot:
cd /sys/modules/acpi/acpi && make && cp acpi.ko /

Then at the loader prompt after rebooting:
> load /acpi.ko
> boot

You should be able to see battery status and thermal settings via
"sysctl hw.acpi" as normal.  Check dmesg for any new errors.

If you notice slower performance or get EC "timed out" messages on
console, you try increasing these sysctls/tunables:

debug.acpi.ec.timeout
debug.acpi.ec.poll_time

Or turn off this sysctl/tunable, disabling the new burst mode:
debug.acpi.ec.burst=0

To find any performance problems, you'll need to rebuild the kernel and
modules with this added to your kernel config:

options KTR
options KTR_ENTRIES=65536

Then reboot, load this kernel/acpi.ko, use the system for a while to
trigger the problem behavior and generate output:
ktrdump -t | gzip -c > ktr.out.gz

This code is pretty well-tested so I expect the only issues we might see
is it not totally fixing some systems that previously didn't work or
needing to add some workaround code for systems that don't properly
support burst mode.

Thanks,
Nate

Index: acpi_ec.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/acpica/acpi_ec.c,v
retrieving revision 1.65.2.2
diff -u -r1.65.2.2 acpi_ec.c
--- acpi_ec.c	11 May 2006 17:41:00 -0000	1.65.2.2
+++ acpi_ec.c	27 Feb 2007 02:07:58 -0000
_at__at_ -187,15 +187,15 _at__at_
  *  | | | +--------- Burst Mode Enabled?
  *  | | +----------- SCI Event?
  *  | +------------- SMI Event?
- *  +--------------- <Reserved>
+ *  +--------------- <reserved>
  *
  */
 typedef UINT8				EC_STATUS;
 
 #define EC_FLAG_OUTPUT_BUFFER		((EC_STATUS) 0x01)
 #define EC_FLAG_INPUT_BUFFER		((EC_STATUS) 0x02)
+#define EC_FLAG_DATA_IS_CMD		((EC_STATUS) 0x08)
 #define EC_FLAG_BURST_MODE		((EC_STATUS) 0x10)
-#define EC_FLAG_SCI			((EC_STATUS) 0x20)
 
 /*
  * EC_EVENT:
_at__at_ -207,6 +207,10 _at__at_
 #define EC_EVENT_OUTPUT_BUFFER_FULL	((EC_EVENT) 0x01)
 #define EC_EVENT_INPUT_BUFFER_EMPTY	((EC_EVENT) 0x02)
 #define EC_EVENT_SCI			((EC_EVENT) 0x20)
+#define EC_EVENT_SMI			((EC_EVENT) 0x40)
+
+/* Data byte returned after burst enable indicating it was successful. */
+#define EC_BURST_ACK			0x90
 
 /*
  * Register access primitives
_at__at_ -265,8 +269,11 _at__at_
     bus_space_tag_t	ec_csr_tag;
     bus_space_handle_t	ec_csr_handle;
 
+    struct mtx		ec_mtx;
     int			ec_glk;
     int			ec_glkhandle;
+    int			ec_burstactive;
+    int			ec_sci_pend;
 };
 
 /*
_at__at_ -276,11 +283,14 _at__at_
  */
 #define EC_LOCK_TIMEOUT	1000
 
-/* Default interval in microseconds for the status polling loop. */
+/* Default delay in microseconds between each run of the status polling loop. */
 #define EC_POLL_DELAY	10
 
-/* Total time in ms spent in the poll loop waiting for a response. */
-#define EC_POLL_TIMEOUT	100
+/* Default time in microseconds spent polling before sleep waiting. */
+#define EC_POLL_TIME	500
+
+/* Total time in ms spent waiting for a response from EC. */
+#define EC_TIMEOUT	500
 
 #define EVENT_READY(event, status)			\
 	(((event) == EC_EVENT_OUTPUT_BUFFER_FULL &&	\
_at__at_ -288,25 +298,47 _at__at_
 	 ((event) == EC_EVENT_INPUT_BUFFER_EMPTY && 	\
 	 ((status) & EC_FLAG_INPUT_BUFFER) == 0))
 
-static int	ec_poll_timeout = EC_POLL_TIMEOUT;
-TUNABLE_INT("hw.acpi.ec.poll_timeout", &ec_poll_timeout);
-
 ACPI_SERIAL_DECL(ec, "ACPI embedded controller");
 
+SYSCTL_DECL(_debug_acpi);
+SYSCTL_NODE(_debug_acpi, OID_AUTO, ec, CTLFLAG_RD, NULL, "EC debugging");
+
+static int	ec_burst_mode = TRUE;
+TUNABLE_INT("debug.acpi.ec.burst", &ec_burst_mode);
+SYSCTL_INT(_debug_acpi_ec, OID_AUTO, burst, CTLFLAG_RW, &ec_burst_mode, TRUE,
+    "Enable use of burst mode (faster for nearly all systems)");
+static int	ec_poll_time = EC_POLL_TIME;
+TUNABLE_INT("debug.acpi.ec.poll_time", &ec_poll_time);
+SYSCTL_INT(_debug_acpi_ec, OID_AUTO, poll_time, CTLFLAG_RW, &ec_poll_time,
+    EC_POLL_TIME, "Time spent polling vs. sleeping (CPU intensive)");
+static int	ec_timeout = EC_TIMEOUT;
+TUNABLE_INT("debug.acpi.ec.timeout", &ec_timeout);
+SYSCTL_INT(_debug_acpi_ec, OID_AUTO, timeout, CTLFLAG_RW, &ec_timeout,
+    EC_TIMEOUT, "Total time spent waiting for a response (poll+sleep)");
+
 static __inline ACPI_STATUS
-EcLock(struct acpi_ec_softc *sc)
+EcLock(struct acpi_ec_softc *sc, int serialize)
 {
     ACPI_STATUS	status;
 
-    /* Always acquire the exclusive lock. */
+    /*
+     * If caller is executing a series of commands, acquire the exclusive lock
+     * to serialize with other users.
+     * To sync with bottom-half interrupt handler, always acquire the mutex.
+     */
     status = AE_OK;
-    ACPI_SERIAL_BEGIN(ec);
+    if (serialize)
+	ACPI_SERIAL_BEGIN(ec);
+    mtx_lock(&sc->ec_mtx);
 
     /* If _GLK is non-zero, also acquire the global lock. */
     if (sc->ec_glk) {
 	status = AcpiAcquireGlobalLock(EC_LOCK_TIMEOUT, &sc->ec_glkhandle);
-	if (ACPI_FAILURE(status))
-	    ACPI_SERIAL_END(ec);
+	if (ACPI_FAILURE(status)) {
+	    mtx_unlock(&sc->ec_mtx);
+	    if (serialize)
+		ACPI_SERIAL_END(ec);
+	}
     }
 
     return (status);
_at__at_ -317,7 +349,9 _at__at_
 {
     if (sc->ec_glk)
 	AcpiReleaseGlobalLock(sc->ec_glkhandle);
-    ACPI_SERIAL_END(ec);
+    mtx_unlock(&sc->ec_mtx);
+    if (sx_xlocked(&ec_sxlock))
+	ACPI_SERIAL_END(ec);
 }
 
 static uint32_t		EcGpeHandler(void *Context);
_at__at_ -558,6 +592,7 _at__at_
     params = acpi_get_private(dev);
     sc->ec_dev = dev;
     sc->ec_handle = acpi_get_handle(dev);
+    mtx_init(&sc->ec_mtx, "ACPI EC lock", NULL, MTX_DEF);
 
     /* Retrieve previously probed values via device ivars. */
     sc->ec_glk = params->glk;
_at__at_ -640,6 +675,7 _at__at_
     if (sc->ec_data_res)
 	bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_data_rid,
 			     sc->ec_data_res);
+    mtx_destroy(&sc->ec_mtx);
     return (ENXIO);
 }
 
_at__at_ -687,13 +723,13 _at__at_
     struct acpi_ec_softc	*sc = (struct acpi_ec_softc *)Context;
     UINT8			Data;
     ACPI_STATUS			Status;
-    EC_STATUS			EcStatus;
     char			qxx[5];
 
     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
     KASSERT(Context != NULL, ("EcGpeQueryHandler called with NULL"));
 
-    Status = EcLock(sc);
+    /* Serialize user access with EcSpaceHandler(). */
+    Status = EcLock(sc, TRUE);
     if (ACPI_FAILURE(Status)) {
 	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
 		    "GpeQuery lock error: %s\n", AcpiFormatException(Status));
_at__at_ -701,19 +737,6 _at__at_
     }
 
     /*
-     * If the EC_SCI bit of the status register is not set, then pass
-     * it along to any potential waiters as it may be an IBE/OBF event.
-     */
-    EcStatus = EC_GET_CSR(sc);
-    if ((EcStatus & EC_EVENT_SCI) == 0) {
-	CTR1(KTR_ACPI, "ec event was not SCI, status %#x", EcStatus);
-	sc->ec_csrvalue = EcStatus;
-	wakeup(&sc->ec_csrvalue);
-	EcUnlock(sc);
-	goto re_enable;
-    }
-
-    /*
      * Send a query command to the EC to find out which _Qxx call it
      * wants to make.  This command clears the SCI bit and also the
      * interrupt source since we are edge-triggered.
_at__at_ -726,6 +749,9 _at__at_
 	goto re_enable;
     }
     Data = EC_GET_DATA(sc);
+    sc->ec_sci_pend = FALSE;
+
+    /* Drop locks before evaluating _Qxx method since it may trigger GPEs. */
     EcUnlock(sc);
 
     /* Ignore the value for "no outstanding event". (13.3.5) */
_at__at_ -734,7 +760,7 _at__at_
 	goto re_enable;
 
     /* Evaluate _Qxx to respond to the controller. */
-    sprintf(qxx, "_Q%02x", Data);
+    snprintf(qxx, sizeof(qxx), "_Q%02x", Data);
     AcpiUtStrupr(qxx);
     Status = AcpiEvaluateObject(sc->ec_handle, qxx, NULL, NULL);
     if (ACPI_FAILURE(Status) && Status != AE_NOT_FOUND) {
_at__at_ -745,7 +771,7 _at__at_
 
 re_enable:
     /* Re-enable the GPE event so we'll get future requests. */
-    Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR);
+    Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_ISR);
     if (ACPI_FAILURE(Status))
 	printf("EcGpeQueryHandler: AcpiEnableEvent failed\n");
 }
_at__at_ -760,27 +786,61 _at__at_
 {
     struct acpi_ec_softc *sc = Context;
     ACPI_STATUS		       Status;
+    EC_STATUS		       EcStatus;
 
     KASSERT(Context != NULL, ("EcGpeHandler called with NULL"));
 
     /*
      * Disable further GPEs while we handle this one.  Since we are directly
      * called by ACPI-CA and it may have unknown locks held, we specify the
-     * ACPI_ISR flag to keep it from acquiring any more mutexes (which could
-     * potentially sleep.)
+     * ACPI_ISR flag to keep it from acquiring any more mutexes (although
+     * sleeping would be ok since we're in an ithread.)
      */
     AcpiDisableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_ISR);
 
-    /* Schedule the GPE query handler. */
-    Status = AcpiOsQueueForExecution(OSD_PRIORITY_GPE, EcGpeQueryHandler,
-		Context);
+    /* For interrupt (GPE) handler, don't acquire serialization lock. */
+    Status = EcLock(sc, FALSE);
     if (ACPI_FAILURE(Status)) {
-	printf("Queuing GPE query handler failed.\n");
-	Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_ISR);
-	if (ACPI_FAILURE(Status))
-	    printf("EcGpeHandler: AcpiEnableEvent failed\n");
+	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
+		    "GpeQuery lock error: %s\n", AcpiFormatException(Status));
+	return (-1);
     }
 
+    /*
+     * If burst was active, but the status bit was cleared, the EC had to
+     * exit burst mode for some reason.  Record this for later.
+     */
+    EcStatus = EC_GET_CSR(sc);
+    if (sc->ec_burstactive && (EcStatus & EC_FLAG_BURST_MODE) == 0) {
+	CTR0(KTR_ACPI, "ec burst disabled in query handler");
+	sc->ec_burstactive = FALSE;
+    }
+
+    /*
+     * If the EC_SCI bit of the status register is not set, then pass
+     * it along to any potential waiters as it may be an IBE/OBF event.
+     * If it is set, queue a query handler.
+     */
+    if ((EcStatus & EC_EVENT_SCI) == 0) {
+	CTR1(KTR_ACPI, "ec event was IBE/OBF, status %#x", EcStatus);
+	sc->ec_csrvalue = EcStatus;
+	wakeup(&sc->ec_csrvalue);
+    } else if (!sc->ec_sci_pend) {
+	/* SCI bit set and no pending query handler, so schedule one. */
+	CTR0(KTR_ACPI, "ec queueing gpe handler");
+	Status = AcpiOsQueueForExecution(OSD_PRIORITY_GPE, EcGpeQueryHandler,
+	    Context);
+	if (ACPI_SUCCESS(Status)) {
+	    sc->ec_sci_pend = TRUE;
+	} else {
+	    printf("Queuing GPE query handler failed.\n");
+	    Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_ISR);
+	    if (ACPI_FAILURE(Status))
+		printf("EcGpeHandler: AcpiEnableEvent failed\n");
+	}
+    }
+
+    EcUnlock(sc);
     return (0);
 }
 
_at__at_ -824,7 +884,8 _at__at_
     EcAddr = Address;
     Status = AE_ERROR;
 
-    Status = EcLock(sc);
+    /* Grab serialization lock to hold across command sequence. */
+    Status = EcLock(sc, TRUE);
     if (ACPI_FAILURE(Status))
 	return_ACPI_STATUS (Status);
 
_at__at_ -859,87 +920,103 _at__at_
 {
     EC_STATUS	EcStatus;
     ACPI_STATUS	Status;
-    int		count, i, period, retval, slp_ival;
+    int		count, i, retval, slp_ival;
 
     ACPI_SERIAL_ASSERT(ec);
     Status = AE_NO_HARDWARE_RESPONSE;
-
-    /* 
-     * Wait for 1 us before checking the CSR.  Testing shows about
-     * 50% of requests complete in 1 us and 90% of them complete
-     * in 5 us or less.
-     */
-    AcpiOsStall(1);
+    EcStatus = 0;
 
     /*
-     * Poll the EC status register for up to 1 ms in chunks of 10 us 
-     * to detect completion of the last command.
+     * Poll for up to ec_poll_time microseconds since many ECs complete
+     * the command quickly, especially if in burst mode.
      */
-    for (i = 0; i < 1000 / EC_POLL_DELAY; i++) {
+#if 0 /* Enable this as a possible workaround if EC times out. */
+    AcpiOsStall(EC_POLL_DELAY);
+#endif
+    count = ec_poll_time / EC_POLL_DELAY;
+    if (count <= 0)
+	count = 1;
+    for (i = 0; i < count; i++) {
 	EcStatus = EC_GET_CSR(sc);
+	if (sc->ec_burstactive && (EcStatus & EC_FLAG_BURST_MODE) == 0) {
+	    CTR0(KTR_ACPI, "ec burst disabled in waitevent (poll)");
+	    sc->ec_burstactive = FALSE;
+	}
 	if (EVENT_READY(Event, EcStatus)) {
+	    CTR1(KTR_ACPI, "ec poll wait ready, status %#x", EcStatus);
 	    Status = AE_OK;
 	    break;
 	}
 	AcpiOsStall(EC_POLL_DELAY);
     }
-    period = i * EC_POLL_DELAY;
 
     /*
      * If we still don't have a response and we're up and running, wait up
-     * to ec_poll_timeout ms for completion, sleeping for chunks of 10 ms.
+     * to ec_timeout ms for completion, sleeping for chunks of 1 ms or the
+     * smallest resolution hz supports.
      */
     slp_ival = 0;
     if (Status != AE_OK) {
 	retval = ENXIO;
-	count = ec_poll_timeout / 10;
-	if (count == 0)
-	    count = 1;
-	slp_ival = hz / 100;
-	if (slp_ival == 0)
-	    slp_ival = 1;
+	if (!cold) {
+	    slp_ival = hz / 1000;
+	    if (slp_ival != 0) {
+		count = ec_timeout / slp_ival;
+	    } else {
+		/* hz has less than 1000 Hz resolution so scale timeout. */
+		slp_ival = 1;
+		count = ec_timeout / (1000 / hz);
+	    }
+	} else
+	    count = ec_timeout;
 	for (i = 0; i < count; i++) {
 	    if (retval != 0)
 		EcStatus = EC_GET_CSR(sc);
 	    else
 		EcStatus = sc->ec_csrvalue;
+	    if (sc->ec_burstactive && (EcStatus & EC_FLAG_BURST_MODE) == 0) {
+		CTR0(KTR_ACPI, "ec burst disabled in waitevent (slp)");
+		sc->ec_burstactive = FALSE;
+	    }
 	    if (EVENT_READY(Event, EcStatus)) {
+		CTR1(KTR_ACPI, "ec sleep wait ready, status %#x", EcStatus);
 		Status = AE_OK;
 		break;
 	    }
-	    if (!cold)
-		retval = tsleep(&sc->ec_csrvalue, PZERO, "ecpoll", slp_ival);
-	    else
-		AcpiOsStall(10000);
+	    if (!cold) {
+		retval = msleep(&sc->ec_csrvalue, &sc->ec_mtx, PZERO, "ecpoll",
+		    slp_ival);
+	    } else
+		AcpiOsStall(1000);
 	}
     }
 
-    /* Calculate new delay and log it. */
-    if (slp_ival > 0)
-	period += i * 10000;
-    CTR2(KTR_ACPI, "ec got event %#x after %d us", EcStatus, period);
-
     return (Status);
 }    
 
 static ACPI_STATUS
 EcCommand(struct acpi_ec_softc *sc, EC_COMMAND cmd)
 {
-    ACPI_STATUS	Status;
-    EC_EVENT	Event;
+    ACPI_STATUS	status;
+    EC_EVENT	event;
+    EC_STATUS	ec_status;
 
     ACPI_SERIAL_ASSERT(ec);
 
+    /* Don't use burst mode if user disabled it. */
+    if (!ec_burst_mode && cmd == EC_COMMAND_BURST_ENABLE)
+	return (AE_ERROR);
+
     /* Decide what to wait for based on command type. */
     switch (cmd) {
     case EC_COMMAND_READ:
     case EC_COMMAND_WRITE:
     case EC_COMMAND_BURST_DISABLE:
-	Event = EC_EVENT_INPUT_BUFFER_EMPTY;
+	event = EC_EVENT_INPUT_BUFFER_EMPTY;
 	break;
     case EC_COMMAND_QUERY:
     case EC_COMMAND_BURST_ENABLE:
-	Event = EC_EVENT_OUTPUT_BUFFER_FULL;
+	event = EC_EVENT_OUTPUT_BUFFER_FULL;
 	break;
     default:
 	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
_at__at_ -948,50 +1025,64 _at__at_
     }
 
     /* Run the command and wait for the chosen event. */
+    CTR1(KTR_ACPI, "ec running command %#x", cmd);
     EC_SET_CSR(sc, cmd);
-    Status = EcWaitEvent(sc, Event);
-    if (ACPI_FAILURE(Status)) {
+    status = EcWaitEvent(sc, event);
+    if (ACPI_SUCCESS(status)) {
+	/* If we succeeded, burst flag should now be present. */
+	if (cmd == EC_COMMAND_BURST_ENABLE) {
+	    ec_status = EC_GET_CSR(sc);
+	    if ((ec_status & EC_FLAG_BURST_MODE) == 0)
+		status = AE_ERROR;
+	}
+    } else {
 	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
 		    "EcCommand: no response to %#x\n", cmd);
     }
 
-    return (Status);
+    return (status);
 }
 
 static ACPI_STATUS
 EcRead(struct acpi_ec_softc *sc, UINT8 Address, UINT8 *Data)
 {
-    ACPI_STATUS	Status;
+    ACPI_STATUS	status;
+    UINT8 data;
 
     ACPI_SERIAL_ASSERT(ec);
     CTR1(KTR_ACPI, "ec read from %#x", Address);
 
-#ifdef notyet
     /* If we can't start burst mode, continue anyway. */
-    EcCommand(sc, EC_COMMAND_BURST_ENABLE);
-#endif
+    status = EcCommand(sc, EC_COMMAND_BURST_ENABLE);
+    if (status == AE_OK) {
+    	data = EC_GET_DATA(sc);
+	if (data == EC_BURST_ACK) {
+	    CTR0(KTR_ACPI, "ec burst enabled");
+	    sc->ec_burstactive = TRUE;
+	}
+    }
 
-    Status = EcCommand(sc, EC_COMMAND_READ);
-    if (ACPI_FAILURE(Status))
-	return (Status);
+    status = EcCommand(sc, EC_COMMAND_READ);
+    if (ACPI_FAILURE(status))
+	return (status);
 
     EC_SET_DATA(sc, Address);
-    Status = EcWaitEvent(sc, EC_EVENT_OUTPUT_BUFFER_FULL);
-    if (ACPI_FAILURE(Status)) {
+    status = EcWaitEvent(sc, EC_EVENT_OUTPUT_BUFFER_FULL);
+    if (ACPI_FAILURE(status)) {
 	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
 		    "EcRead: Failed waiting for EC to send data.\n");
-	return (Status);
+	return (status);
     }
 
     *Data = EC_GET_DATA(sc);
 
-#ifdef notyet
     if (sc->ec_burstactive) {
-	Status = EcCommand(sc, EC_COMMAND_BURST_DISABLE);
-	if (ACPI_FAILURE(Status))
-	    return (Status);
+	status = EcCommand(sc, EC_COMMAND_BURST_DISABLE);
+	if (ACPI_FAILURE(status))
+	    return (status);
+	sc->ec_burstactive = FALSE;
+	CTR0(KTR_ACPI, "ec disabled burst ok");
     }
-#endif
 
     return (AE_OK);
 }    
_at__at_ -999,43 +1090,49 _at__at_
 static ACPI_STATUS
 EcWrite(struct acpi_ec_softc *sc, UINT8 Address, UINT8 *Data)
 {
-    ACPI_STATUS	Status;
+    ACPI_STATUS	status;
+    UINT8 data;
 
     ACPI_SERIAL_ASSERT(ec);
     CTR2(KTR_ACPI, "ec write to %#x, data %#x", Address, *Data);
 
-#ifdef notyet
     /* If we can't start burst mode, continue anyway. */
-    EcCommand(sc, EC_COMMAND_BURST_ENABLE);
-#endif
+    status = EcCommand(sc, EC_COMMAND_BURST_ENABLE);
+    if (status == AE_OK) {
+    	data = EC_GET_DATA(sc);
+	if (data == EC_BURST_ACK) {
+	    CTR0(KTR_ACPI, "ec burst enabled");
+	    sc->ec_burstactive = TRUE;
+	}
+    }
 
-    Status = EcCommand(sc, EC_COMMAND_WRITE);
-    if (ACPI_FAILURE(Status))
-	return (Status);
+    status = EcCommand(sc, EC_COMMAND_WRITE);
+    if (ACPI_FAILURE(status))
+	return (status);
 
     EC_SET_DATA(sc, Address);
-    Status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY);
-    if (ACPI_FAILURE(Status)) {
+    status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY);
+    if (ACPI_FAILURE(status)) {
 	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
 		    "EcRead: Failed waiting for EC to process address\n");
-	return (Status);
+	return (status);
     }
 
     EC_SET_DATA(sc, *Data);
-    Status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY);
-    if (ACPI_FAILURE(Status)) {
+    status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY);
+    if (ACPI_FAILURE(status)) {
 	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
 		    "EcWrite: Failed waiting for EC to process data\n");
-	return (Status);
+	return (status);
     }
 
-#ifdef notyet
     if (sc->ec_burstactive) {
-	Status = EcCommand(sc, EC_COMMAND_BURST_DISABLE);
-	if (ACPI_FAILURE(Status))
-	    return (Status);
+	status = EcCommand(sc, EC_COMMAND_BURST_DISABLE);
+	if (ACPI_FAILURE(status))
+	    return (status);
+	sc->ec_burstactive = FALSE;
+	CTR0(KTR_ACPI, "ec disabled burst ok");
     }
-#endif
 
     return (AE_OK);
 }
Received on Tue Feb 27 2007 - 02:11:58 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:06 UTC