2 * Copyright 2013, Jérôme Duval, korli@users.berlios.de.
3 * Copyright (c) 2009 Clemens Zeidler
4 * Copyright (c) 2003-2007 Nate Lawson
5 * Copyright (c) 2000 Michael Smith
6 * Copyright (c) 2000 BSDi
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include "EmbeddedController.h"
39 #include <condition_variable.h>
41 #include <KernelExport.h>
42 #include <drivers/PCI.h>
45 #define ACPI_EC_DRIVER_NAME "drivers/power/acpi_embedded_controller/driver_v1"
47 #define ACPI_EC_DEVICE_NAME "drivers/power/acpi_embedded_controller/device_v1"
49 /* Base Namespace devices are published to */
50 #define ACPI_EC_BASENAME "power/embedded_controller/%d"
52 // name of pnp generator of path ids
53 #define ACPI_EC_PATHID_GENERATOR "embedded_controller/path_id"
57 bus_space_read_1(int address
)
59 return gPCIManager
->read_io_8(address
);
64 bus_space_write_1(int address
, uint8 value
)
66 gPCIManager
->write_io_8(address
, value
);
71 acpi_GetInteger(acpi_device_module_info
* acpi
, acpi_device
& acpiCookie
,
72 const char* path
, int* number
)
75 acpi_object_type object
;
76 buf
.pointer
= &object
;
77 buf
.length
= sizeof(acpi_object_type
);
79 // Assume that what we've been pointed at is an Integer object, or
80 // a method that will return an Integer.
81 status_t status
= acpi
->evaluate_method(acpiCookie
, path
, NULL
, &buf
);
83 if (object
.object_type
== ACPI_TYPE_INTEGER
)
84 *number
= object
.integer
.integer
;
93 acpi_GetReference(acpi_module_info
* acpi
, acpi_handle scope
,
94 acpi_object_type
* obj
)
99 switch (obj
->object_type
) {
100 case ACPI_TYPE_LOCAL_REFERENCE
:
102 return obj
->reference
.handle
;
104 case ACPI_TYPE_STRING
:
106 // The String object usually contains a fully-qualified path, so
107 // scope can be NULL.
108 // TODO: This may not always be the case.
110 if (acpi
->get_handle(scope
, obj
->string
.string
, &handle
)
121 acpi_PkgInt(acpi_object_type
* res
, int idx
, int* dst
)
123 acpi_object_type
* obj
= &res
->package
.objects
[idx
];
124 if (obj
== NULL
|| obj
->object_type
!= ACPI_TYPE_INTEGER
)
126 *dst
= obj
->integer
.integer
;
133 acpi_PkgInt32(acpi_object_type
* res
, int idx
, uint32
* dst
)
137 status_t status
= acpi_PkgInt(res
, idx
, &tmp
);
146 embedded_controller_io_ports_parse_callback(ACPI_RESOURCE
* resource
,
149 acpi_ec_cookie
* sc
= (acpi_ec_cookie
*)_context
;
150 if (resource
->Type
!= ACPI_RESOURCE_TYPE_IO
)
152 if (sc
->ec_data_pci_address
== 0) {
153 sc
->ec_data_pci_address
= resource
->Data
.Io
.Minimum
;
154 } else if (sc
->ec_csr_pci_address
== 0) {
155 sc
->ec_csr_pci_address
= resource
->Data
.Io
.Minimum
;
157 return AE_CTRL_TERMINATE
;
168 embedded_controller_open(void* initCookie
, const char* path
, int flags
,
171 acpi_ec_cookie
* device
= (acpi_ec_cookie
*) initCookie
;
179 embedded_controller_close(void* cookie
)
186 embedded_controller_read(void* _cookie
, off_t position
, void* buffer
,
194 embedded_controller_write(void* cookie
, off_t position
, const void* buffer
,
202 embedded_controller_control(void* _cookie
, uint32 op
, void* arg
, size_t len
)
209 embedded_controller_free(void* cookie
)
215 // #pragma mark - driver module API
219 acpi_get_type(device_node
* dev
)
222 if (gDeviceManager
->get_attr_string(dev
, B_DEVICE_BUS
, &bus
, false))
225 if (strcmp(bus
, "acpi"))
229 if (gDeviceManager
->get_attr_uint32(dev
, ACPI_DEVICE_TYPE_ITEM
,
230 &deviceType
, false) != B_OK
)
238 embedded_controller_support(device_node
* dev
)
240 TRACE("embedded_controller_support()\n");
242 // Check that this is a device
243 if (acpi_get_type(dev
) != ACPI_TYPE_DEVICE
)
247 if (gDeviceManager
->get_attr_string(dev
, ACPI_DEVICE_HID_ITEM
, &name
, false)
251 // Test all known IDs
253 static const char* kEmbeddedControllerIDs
[] = { "PNP0C09" };
255 for (size_t i
= 0; i
< sizeof(kEmbeddedControllerIDs
)
256 / sizeof(kEmbeddedControllerIDs
[0]); i
++) {
257 if (!strcmp(name
, kEmbeddedControllerIDs
[i
])) {
258 TRACE("supported device found %s\n", name
);
268 embedded_controller_register_device(device_node
* node
)
270 device_attr attrs
[] = {
271 { B_DEVICE_PRETTY_NAME
, B_STRING_TYPE
,
272 { string
: "ACPI embedded controller" }},
276 return gDeviceManager
->register_node(node
, ACPI_EC_DRIVER_NAME
, attrs
,
282 embedded_controller_init_driver(device_node
* dev
, void** _driverCookie
)
284 TRACE("init driver\n");
287 sc
= (acpi_ec_cookie
*)malloc(sizeof(acpi_ec_cookie
));
291 memset(sc
, 0, sizeof(acpi_ec_cookie
));
296 sc
->ec_condition_var
.Init(NULL
, "ec condition variable");
297 mutex_init(&sc
->ec_lock
, "ec lock");
298 device_node
* parent
= gDeviceManager
->get_parent_node(dev
);
299 gDeviceManager
->get_driver(parent
, (driver_module_info
**)&sc
->ec_acpi
,
300 (void**)&sc
->ec_handle
);
301 gDeviceManager
->put_node(parent
);
303 if (get_module(B_ACPI_MODULE_NAME
, (module_info
**)&sc
->ec_acpi_module
)
309 buf
.length
= ACPI_ALLOCATE_BUFFER
;
311 // Read the unit ID to check for duplicate attach and the
312 // global lock value to see if we should acquire it when
314 status_t status
= acpi_GetInteger(sc
->ec_acpi
, sc
->ec_handle
, "_UID",
318 status
= acpi_GetInteger(sc
->ec_acpi
, sc
->ec_handle
, "_GLK", &sc
->ec_glk
);
322 // Evaluate the _GPE method to find the GPE bit used by the EC to
323 // signal status (SCI). If it's a package, it contains a reference
324 // and GPE bit, similar to _PRW.
325 status
= sc
->ec_acpi
->evaluate_method(sc
->ec_handle
, "_GPE", NULL
, &buf
);
326 if (status
!= B_OK
) {
327 ERROR("can't evaluate _GPE\n");
331 acpi_object_type
* obj
;
332 obj
= (acpi_object_type
*)buf
.pointer
;
336 switch (obj
->object_type
) {
337 case ACPI_TYPE_INTEGER
:
338 sc
->ec_gpehandle
= NULL
;
339 sc
->ec_gpebit
= obj
->integer
.integer
;
341 case ACPI_TYPE_PACKAGE
:
342 if (!ACPI_PKG_VALID(obj
, 2))
344 sc
->ec_gpehandle
= acpi_GetReference(sc
->ec_acpi_module
, NULL
,
345 &obj
->package
.objects
[0]);
346 if (sc
->ec_gpehandle
== NULL
347 || acpi_PkgInt32(obj
, 1, (uint32
*)&sc
->ec_gpebit
) != B_OK
)
351 ERROR("_GPE has invalid type %i\n", int(obj
->object_type
));
355 sc
->ec_suspending
= FALSE
;
357 // Attach bus resources for data and command/status ports.
358 status
= sc
->ec_acpi
->walk_resources(sc
->ec_handle
, "_CRS",
359 embedded_controller_io_ports_parse_callback
, sc
);
360 if (status
!= B_OK
) {
361 ERROR("Error while getting IO ports addresses\n");
365 // Install a handler for this EC's GPE bit. We want edge-triggered
367 TRACE("attaching GPE handler\n");
368 status
= sc
->ec_acpi_module
->install_gpe_handler(sc
->ec_gpehandle
,
369 sc
->ec_gpebit
, ACPI_GPE_EDGE_TRIGGERED
, &EcGpeHandler
, sc
);
370 if (status
!= B_OK
) {
371 TRACE("can't install ec GPE handler\n");
375 // Install address space handler
376 TRACE("attaching address space handler\n");
377 status
= sc
->ec_acpi
->install_address_space_handler(sc
->ec_handle
,
378 ACPI_ADR_SPACE_EC
, &EcSpaceHandler
, &EcSpaceSetup
, sc
);
379 if (status
!= B_OK
) {
380 ERROR("can't install address space handler\n");
384 // Enable runtime GPEs for the handler.
385 status
= sc
->ec_acpi_module
->enable_gpe(sc
->ec_gpehandle
, sc
->ec_gpebit
);
386 if (status
!= B_OK
) {
387 ERROR("AcpiEnableGpe failed.\n");
396 sc
->ec_acpi_module
->remove_gpe_handler(sc
->ec_gpehandle
, sc
->ec_gpebit
,
398 sc
->ec_acpi
->remove_address_space_handler(sc
->ec_handle
, ACPI_ADR_SPACE_EC
,
406 embedded_controller_uninit_driver(void* driverCookie
)
408 acpi_ec_cookie
* sc
= (struct acpi_ec_cookie
*)driverCookie
;
409 mutex_destroy(&sc
->ec_lock
);
411 put_module(B_ACPI_MODULE_NAME
);
416 embedded_controller_register_child_devices(void* _cookie
)
418 device_node
* node
= ((acpi_ec_cookie
*)_cookie
)->ec_dev
;
420 int pathID
= gDeviceManager
->create_id(ACPI_EC_PATHID_GENERATOR
);
422 TRACE("register_child_device couldn't create a path_id\n");
427 snprintf(name
, sizeof(name
), ACPI_EC_BASENAME
, pathID
);
429 return gDeviceManager
->publish_device(node
, name
, ACPI_EC_DEVICE_NAME
);
434 embedded_controller_init_device(void* driverCookie
, void** cookie
)
441 embedded_controller_uninit_device(void* _cookie
)
443 acpi_ec_cookie
* device
= (acpi_ec_cookie
*)_cookie
;
448 driver_module_info embedded_controller_driver_module
= {
455 embedded_controller_support
,
456 embedded_controller_register_device
,
457 embedded_controller_init_driver
,
458 embedded_controller_uninit_driver
,
459 embedded_controller_register_child_devices
,
465 struct device_module_info embedded_controller_device_module
= {
472 embedded_controller_init_device
,
473 embedded_controller_uninit_device
,
476 embedded_controller_open
,
477 embedded_controller_close
,
478 embedded_controller_free
,
479 embedded_controller_read
,
480 embedded_controller_write
,
482 embedded_controller_control
,
493 EcCheckStatus(struct acpi_ec_cookie
* sc
, const char* msg
, EC_EVENT event
)
495 acpi_status status
= AE_NO_HARDWARE_RESPONSE
;
496 EC_STATUS ec_status
= EC_GET_CSR(sc
);
498 if (sc
->ec_burstactive
&& !(ec_status
& EC_FLAG_BURST_MODE
)) {
499 TRACE("burst disabled in waitevent (%s)\n", msg
);
500 sc
->ec_burstactive
= false;
502 if (EVENT_READY(event
, ec_status
)) {
503 TRACE("%s wait ready, status %#x\n", msg
, ec_status
);
511 EcGpeQueryHandler(void* context
)
513 struct acpi_ec_cookie
* sc
= (struct acpi_ec_cookie
*)context
;
515 ASSERT(context
!= NULL
);
517 // Serialize user access with EcSpaceHandler().
518 status_t status
= EcLock(sc
);
519 if (status
!= B_OK
) {
520 TRACE("GpeQuery lock error.\n");
524 // Send a query command to the EC to find out which _Qxx call it
525 // wants to make. This command clears the SCI bit and also the
526 // interrupt source since we are edge-triggered. To prevent the GPE
527 // that may arise from running the query from causing another query
528 // to be queued, we clear the pending flag only after running it.
529 int sci_enqueued
= sc
->ec_sci_pending
;
530 acpi_status acpi_status
= AE_ERROR
;
531 for (uint8 retry
= 0; retry
< 2; retry
++) {
532 acpi_status
= EcCommand(sc
, EC_COMMAND_QUERY
);
533 if (acpi_status
== AE_OK
)
535 if (EcCheckStatus(sc
, "retr_check",
536 EC_EVENT_INPUT_BUFFER_EMPTY
) != AE_OK
)
540 sc
->ec_sci_pending
= FALSE
;
541 if (acpi_status
!= AE_OK
) {
543 TRACE("GPE query failed.\n");
546 uint8 data
= EC_GET_DATA(sc
);
548 // We have to unlock before running the _Qxx method below since that
549 // method may attempt to read/write from EC address space, causing
550 // recursive acquisition of the lock.
553 // Ignore the value for "no outstanding event". (13.3.5)
554 TRACE("query ok,%s running _Q%02X\n", data
? "" : " not", data
);
558 // Evaluate _Qxx to respond to the controller.
560 snprintf(qxx
, sizeof(qxx
), "_Q%02X", data
);
562 status
= sc
->ec_acpi
->evaluate_method(sc
->ec_handle
, qxx
, NULL
, NULL
);
563 if (status
!= B_OK
) {
564 TRACE("evaluation of query method %s failed\n", qxx
);
567 // Reenable runtime GPE if its execution was deferred.
569 status
= sc
->ec_acpi_module
->finish_gpe(sc
->ec_gpehandle
, sc
->ec_gpebit
);
571 ERROR("reenabling runtime GPE failed.\n");
577 /*! The GPE handler is called when IBE/OBF or SCI events occur. We are
578 called from an unknown lock context.
581 EcGpeHandler(acpi_handle gpeDevice
, uint32 gpeNumber
, void* context
)
583 struct acpi_ec_cookie
* sc
= (acpi_ec_cookie
*)context
;
585 ASSERT(context
!= NULL
);//, ("EcGpeHandler called with NULL"));
586 TRACE("gpe handler start\n");
588 // Notify EcWaitEvent() that the status register is now fresh. If we
589 // didn't do this, it wouldn't be possible to distinguish an old IBE
590 // from a new one, for example when doing a write transaction (writing
591 // address and then data values.)
592 atomic_add(&sc
->ec_gencount
, 1);
593 sc
->ec_condition_var
.NotifyAll();
595 // If the EC_SCI bit of the status register is set, queue a query handler.
596 // It will run the query and _Qxx method later, under the lock.
597 EC_STATUS ecStatus
= EC_GET_CSR(sc
);
598 if ((ecStatus
& EC_EVENT_SCI
) && !sc
->ec_sci_pending
) {
599 TRACE("gpe queueing query handler\n");
600 acpi_status status
= AcpiOsExecute(OSL_GPE_HANDLER
, EcGpeQueryHandler
,
603 sc
->ec_sci_pending
= TRUE
;
605 dprintf("EcGpeHandler: queuing GPE query handler failed\n");
607 return ACPI_REENABLE_GPE
;
612 EcSpaceSetup(acpi_handle region
, uint32 function
, void* context
,
613 void** regionContext
)
615 // If deactivating a region, always set the output to NULL. Otherwise,
616 // just pass the context through.
617 if (function
== ACPI_REGION_DEACTIVATE
)
618 *regionContext
= NULL
;
620 *regionContext
= context
;
627 EcSpaceHandler(uint32 function
, acpi_physical_address address
, uint32 width
,
628 int* value
, void* context
, void* regionContext
)
630 TRACE("enter EcSpaceHandler\n");
631 struct acpi_ec_cookie
* sc
= (struct acpi_ec_cookie
*)context
;
633 if (function
!= ACPI_READ
&& function
!= ACPI_WRITE
) return AE_BAD_PARAMETER
;
634 if (width
% 8 != 0 || value
== NULL
|| context
== NULL
)
635 return AE_BAD_PARAMETER
;
636 if (address
+ width
/ 8 > 256)
637 return AE_BAD_ADDRESS
;
639 // If booting, check if we need to run the query handler. If so, we
640 // we call it directly here as scheduling and dpc might not be up yet.
641 // (Not sure if it's needed)
643 if (gKernelStartup
|| gKernelShutdown
|| sc
->ec_suspending
) {
644 if ((EC_GET_CSR(sc
) & EC_EVENT_SCI
)) {
645 //CTR0(KTR_ACPI, "ec running gpe handler directly");
646 EcGpeQueryHandler(sc
);
650 // Serialize with EcGpeQueryHandler() at transaction granularity.
651 acpi_status status
= EcLock(sc
);
653 return AE_NOT_ACQUIRED
;
655 // If we can't start burst mode, continue anyway.
656 status
= EcCommand(sc
, EC_COMMAND_BURST_ENABLE
);
657 if (status
== B_OK
) {
658 if (EC_GET_DATA(sc
) == EC_BURST_ACK
) {
659 TRACE("burst enabled.\n");
660 sc
->ec_burstactive
= TRUE
;
664 // Perform the transaction(s), based on width.
665 acpi_physical_address ecAddr
= address
;
666 uint8
* ecData
= (uint8
*) value
;
667 if (function
== ACPI_READ
)
672 status
= EcRead(sc
, ecAddr
, ecData
);
675 status
= EcWrite(sc
, ecAddr
, *ecData
);
682 } while (ecAddr
< address
+ width
/ 8);
684 if (sc
->ec_burstactive
) {
685 sc
->ec_burstactive
= FALSE
;
686 if (EcCommand(sc
, EC_COMMAND_BURST_DISABLE
) == AE_OK
)
687 TRACE("disabled burst ok.");
696 EcWaitEvent(struct acpi_ec_cookie
* sc
, EC_EVENT event
, int32 generationCount
)
698 acpi_status status
= AE_NO_HARDWARE_RESPONSE
;
701 // int need_poll = cold || rebooting || ec_polled_mode || sc->ec_suspending;
702 int needPoll
= ec_polled_mode
|| sc
->ec_suspending
|| gKernelStartup
|| gKernelShutdown
;
704 // Wait for event by polling or GPE (interrupt).
705 // be "not ready" when we start waiting. But if the main CPU is really
706 // slow, it's possible we see the current "ready" response. Since that
707 // can't be distinguished from the previous response in polled mode,
708 // this is a potential issue. We really should have interrupts enabled
709 // during boot so there is no ambiguity in polled mode.
711 // If this occurs, we add an additional delay before actually entering
712 // the status checking loop, hopefully to allow the EC to go to work
713 // and produce a non-stale status.
717 if (EcCheckStatus(sc
, "pre-check", event
) == B_OK
) {
719 TRACE("warning: EC done before starting event wait\n");
726 // Wait for event by polling or GPE (interrupt).
728 count
= (ec_timeout
* 1000) / EC_POLL_DELAY
;
731 for (i
= 0; i
< count
; i
++) {
732 status
= EcCheckStatus(sc
, "poll", event
);
738 bigtime_t sleepInterval
= system_time() + ec_timeout
* 1000;
740 // Wait for the GPE to signal the status changed, checking the
741 // status register each time we get one. It's possible to get a
742 // GPE for an event we're not interested in here (i.e., SCI for
744 status_t waitStatus
= B_NO_ERROR
;
745 while (waitStatus
!= B_TIMED_OUT
) {
746 if (generationCount
!= sc
->ec_gencount
) {
747 // Record new generation count. It's possible the GPE was
748 // just to notify us that a query is needed and we need to
749 // wait for a second GPE to signal the completion of the
750 // event we are actually waiting for.
751 generationCount
= sc
->ec_gencount
;
752 status
= EcCheckStatus(sc
, "sleep", event
);
756 waitStatus
= sc
->ec_condition_var
.Wait(B_ABSOLUTE_TIMEOUT
,
760 // We finished waiting for the GPE and it never arrived. Try to
761 // read the register once and trust whatever value we got. This is
762 // the best we can do at this point.
763 // since this system doesn't appear to generate GPEs.
764 if (status
!= AE_OK
) {
765 status
= EcCheckStatus(sc
, "sleep_end", event
);
766 TRACE("wait timed out (%sresponse), forcing polled mode\n",
767 status
== AE_OK
? "" : "no ");
768 ec_polled_mode
= TRUE
;
774 TRACE("error: ec wait timed out\n");
781 EcCommand(struct acpi_ec_cookie
* sc
, EC_COMMAND cmd
)
783 // Don't use burst mode if user disabled it.
784 if (!ec_burst_mode
&& cmd
== EC_COMMAND_BURST_ENABLE
)
787 // Decide what to wait for based on command type.
790 case EC_COMMAND_READ
:
791 case EC_COMMAND_WRITE
:
792 case EC_COMMAND_BURST_DISABLE
:
793 event
= EC_EVENT_INPUT_BUFFER_EMPTY
;
795 case EC_COMMAND_QUERY
:
796 case EC_COMMAND_BURST_ENABLE
:
797 event
= EC_EVENT_OUTPUT_BUFFER_FULL
;
800 TRACE("EcCommand: invalid command %#x\n", cmd
);
801 return AE_BAD_PARAMETER
;
804 // Ensure empty input buffer before issuing command.
805 // Use generation count of zero to force a quick check.
806 acpi_status status
= EcWaitEvent(sc
, EC_EVENT_INPUT_BUFFER_EMPTY
, 0);
810 // Run the command and wait for the chosen event.
811 TRACE("running command %#x\n", cmd
);
812 int32 generationCount
= sc
->ec_gencount
;
814 status
= EcWaitEvent(sc
, event
, generationCount
);
815 if (status
== AE_OK
) {
816 // If we succeeded, burst flag should now be present.
817 if (cmd
== EC_COMMAND_BURST_ENABLE
) {
818 EC_STATUS ec_status
= EC_GET_CSR(sc
);
819 if ((ec_status
& EC_FLAG_BURST_MODE
) == 0)
823 TRACE("EcCommand: no response to %#x\n", cmd
);
830 EcRead(struct acpi_ec_cookie
* sc
, uint8 address
, uint8
* readData
)
832 TRACE("read from %#x\n", address
);
835 for (uint8 retry
= 0; retry
< 2; retry
++) {
836 status
= EcCommand(sc
, EC_COMMAND_READ
);
840 int32 generationCount
= sc
->ec_gencount
;
841 EC_SET_DATA(sc
, address
);
842 status
= EcWaitEvent(sc
, EC_EVENT_OUTPUT_BUFFER_FULL
, generationCount
);
843 if (status
!= AE_OK
) {
844 if (EcCheckStatus(sc
, "retr_check",
845 EC_EVENT_INPUT_BUFFER_EMPTY
) == AE_OK
)
850 *readData
= EC_GET_DATA(sc
);
854 TRACE("EcRead: failed waiting to get data\n");
860 EcWrite(struct acpi_ec_cookie
* sc
, uint8 address
, uint8 writeData
)
862 acpi_status status
= EcCommand(sc
, EC_COMMAND_WRITE
);
866 int32 generationCount
= sc
->ec_gencount
;
867 EC_SET_DATA(sc
, address
);
868 status
= EcWaitEvent(sc
, EC_EVENT_INPUT_BUFFER_EMPTY
, generationCount
);
869 if (status
!= AE_OK
) {
870 TRACE("EcWrite: failed waiting for sent address\n");
874 generationCount
= sc
->ec_gencount
;
875 EC_SET_DATA(sc
, writeData
);
876 status
= EcWaitEvent(sc
, EC_EVENT_INPUT_BUFFER_EMPTY
, generationCount
);
877 if (status
!= AE_OK
) {
878 TRACE("EcWrite: failed waiting for sent data\n");