1 /*
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
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
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.
17 *
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
28 * SUCH DAMAGE.
29 */
30
31
32 #include "EmbeddedController.h"
33
34 #include <kernel.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38
39 #include <condition_variable.h>
40 #include <Errors.h>
41 #include <KernelExport.h>
42 #include <drivers/PCI.h>
43
44
45 #define ACPI_EC_DRIVER_NAME "drivers/power/acpi_embedded_controller/driver_v1"
46
47 #define ACPI_EC_DEVICE_NAME "drivers/power/acpi_embedded_controller/device_v1"
48
49 /* Base Namespace devices are published to */
50 #define ACPI_EC_BASENAME "power/embedded_controller/%d"
51
52 // name of pnp generator of path ids
53 #define ACPI_EC_PATHID_GENERATOR "embedded_controller/path_id"
54
55
56 uint8
bus_space_read_1(int address)57 bus_space_read_1(int address)
58 {
59 return gPCIManager->read_io_8(address);
60 }
61
62
63 void
bus_space_write_1(int address,uint8 value)64 bus_space_write_1(int address, uint8 value)
65 {
66 gPCIManager->write_io_8(address, value);
67 }
68
69
70 status_t
acpi_GetInteger(acpi_device_module_info * acpi,acpi_device & acpiCookie,const char * path,int * number)71 acpi_GetInteger(acpi_device_module_info* acpi, acpi_device& acpiCookie,
72 const char* path, int* number)
73 {
74 acpi_data buf;
75 acpi_object_type object;
76 buf.pointer = &object;
77 buf.length = sizeof(acpi_object_type);
78
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);
82 if (status == B_OK) {
83 if (object.object_type == ACPI_TYPE_INTEGER)
84 *number = object.integer.integer;
85 else
86 status = B_BAD_VALUE;
87 }
88 return status;
89 }
90
91
92 acpi_handle
acpi_GetReference(acpi_module_info * acpi,acpi_handle scope,acpi_object_type * obj)93 acpi_GetReference(acpi_module_info* acpi, acpi_handle scope,
94 acpi_object_type* obj)
95 {
96 if (obj == NULL)
97 return NULL;
98
99 switch (obj->object_type) {
100 case ACPI_TYPE_LOCAL_REFERENCE:
101 case ACPI_TYPE_ANY:
102 return obj->reference.handle;
103
104 case ACPI_TYPE_STRING:
105 {
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.
109 acpi_handle handle;
110 if (acpi->get_handle(scope, obj->string.string, &handle)
111 == B_OK)
112 return handle;
113 }
114 }
115
116 return NULL;
117 }
118
119
120 status_t
acpi_PkgInt(acpi_object_type * res,int idx,int * dst)121 acpi_PkgInt(acpi_object_type* res, int idx, int* dst)
122 {
123 acpi_object_type* obj = &res->package.objects[idx];
124 if (obj == NULL || obj->object_type != ACPI_TYPE_INTEGER)
125 return B_BAD_VALUE;
126 *dst = obj->integer.integer;
127
128 return B_OK;
129 }
130
131
132 status_t
acpi_PkgInt32(acpi_object_type * res,int idx,uint32 * dst)133 acpi_PkgInt32(acpi_object_type* res, int idx, uint32* dst)
134 {
135 int tmp;
136
137 status_t status = acpi_PkgInt(res, idx, &tmp);
138 if (status == B_OK)
139 *dst = (uint32) tmp;
140
141 return status;
142 }
143
144
145 acpi_status
embedded_controller_io_ports_parse_callback(ACPI_RESOURCE * resource,void * _context)146 embedded_controller_io_ports_parse_callback(ACPI_RESOURCE* resource,
147 void* _context)
148 {
149 acpi_ec_cookie* sc = (acpi_ec_cookie*)_context;
150 if (resource->Type != ACPI_RESOURCE_TYPE_IO)
151 return AE_OK;
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;
156 } else {
157 return AE_CTRL_TERMINATE;
158 }
159
160 return AE_OK;
161 }
162
163
164 // #pragma mark -
165
166
167 static status_t
embedded_controller_open(void * initCookie,const char * path,int flags,void ** cookie)168 embedded_controller_open(void* initCookie, const char* path, int flags,
169 void** cookie)
170 {
171 acpi_ec_cookie* device = (acpi_ec_cookie*) initCookie;
172 *cookie = device;
173
174 return B_OK;
175 }
176
177
178 static status_t
embedded_controller_close(void * cookie)179 embedded_controller_close(void* cookie)
180 {
181 return B_OK;
182 }
183
184
185 static status_t
embedded_controller_read(void * _cookie,off_t position,void * buffer,size_t * numBytes)186 embedded_controller_read(void* _cookie, off_t position, void* buffer,
187 size_t* numBytes)
188 {
189 return B_IO_ERROR;
190 }
191
192
193 static status_t
embedded_controller_write(void * cookie,off_t position,const void * buffer,size_t * numBytes)194 embedded_controller_write(void* cookie, off_t position, const void* buffer,
195 size_t* numBytes)
196 {
197 return B_IO_ERROR;
198 }
199
200
201 status_t
embedded_controller_control(void * _cookie,uint32 op,void * arg,size_t len)202 embedded_controller_control(void* _cookie, uint32 op, void* arg, size_t len)
203 {
204 return B_ERROR;
205 }
206
207
208 static status_t
embedded_controller_free(void * cookie)209 embedded_controller_free(void* cookie)
210 {
211 return B_OK;
212 }
213
214
215 // #pragma mark - driver module API
216
217
218 static int32
acpi_get_type(device_node * dev)219 acpi_get_type(device_node* dev)
220 {
221 const char *bus;
222 if (gDeviceManager->get_attr_string(dev, B_DEVICE_BUS, &bus, false))
223 return -1;
224
225 if (strcmp(bus, "acpi"))
226 return -1;
227
228 uint32 deviceType;
229 if (gDeviceManager->get_attr_uint32(dev, ACPI_DEVICE_TYPE_ITEM,
230 &deviceType, false) != B_OK)
231 return -1;
232
233 return deviceType;
234 }
235
236
237 static float
embedded_controller_support(device_node * dev)238 embedded_controller_support(device_node* dev)
239 {
240 TRACE("embedded_controller_support()\n");
241
242 // Check that this is a device
243 if (acpi_get_type(dev) != ACPI_TYPE_DEVICE)
244 return 0.0;
245
246 const char* name;
247 if (gDeviceManager->get_attr_string(dev, ACPI_DEVICE_HID_ITEM, &name, false)
248 != B_OK)
249 return 0.0;
250
251 // Test all known IDs
252
253 static const char* kEmbeddedControllerIDs[] = { "PNP0C09" };
254
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);
259 return 0.6;
260 }
261 }
262
263 return 0.0;
264 }
265
266
267 static status_t
embedded_controller_register_device(device_node * node)268 embedded_controller_register_device(device_node* node)
269 {
270 device_attr attrs[] = {
271 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE,
272 { .string = "ACPI embedded controller" }},
273 { NULL }
274 };
275
276 return gDeviceManager->register_node(node, ACPI_EC_DRIVER_NAME, attrs,
277 NULL, NULL);
278 }
279
280
281 static status_t
embedded_controller_init_driver(device_node * dev,void ** _driverCookie)282 embedded_controller_init_driver(device_node* dev, void** _driverCookie)
283 {
284 TRACE("init driver\n");
285
286 acpi_ec_cookie* sc;
287 sc = (acpi_ec_cookie*)malloc(sizeof(acpi_ec_cookie));
288 if (sc == NULL)
289 return B_NO_MEMORY;
290
291 memset(sc, 0, sizeof(acpi_ec_cookie));
292
293 *_driverCookie = sc;
294 sc->ec_dev = dev;
295
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);
302
303 if (get_module(B_ACPI_MODULE_NAME, (module_info**)&sc->ec_acpi_module)
304 != B_OK)
305 return B_ERROR;
306
307 acpi_data buf;
308 buf.pointer = NULL;
309 buf.length = ACPI_ALLOCATE_BUFFER;
310
311 // Read the unit ID to check for duplicate attach and the
312 // global lock value to see if we should acquire it when
313 // accessing the EC.
314 status_t status = acpi_GetInteger(sc->ec_acpi, sc->ec_handle, "_UID",
315 &sc->ec_uid);
316 if (status != B_OK)
317 sc->ec_uid = 0;
318 status = acpi_GetInteger(sc->ec_acpi, sc->ec_handle, "_GLK", &sc->ec_glk);
319 if (status != B_OK)
320 sc->ec_glk = 0;
321
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 %s\n", strerror(status));
328 goto error2;
329 }
330
331 acpi_object_type* obj;
332 obj = (acpi_object_type*)buf.pointer;
333 if (obj == NULL)
334 goto error2;
335
336 switch (obj->object_type) {
337 case ACPI_TYPE_INTEGER:
338 sc->ec_gpehandle = NULL;
339 sc->ec_gpebit = obj->integer.integer;
340 break;
341 case ACPI_TYPE_PACKAGE:
342 if (!ACPI_PKG_VALID(obj, 2))
343 goto error2;
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)
348 goto error2;
349 break;
350 default:
351 ERROR("_GPE has invalid type %i\n", int(obj->object_type));
352 goto error2;
353 }
354
355 sc->ec_suspending = FALSE;
356
357 // Attach bus resources for data and command/status ports.
358 status = sc->ec_acpi->walk_resources(sc->ec_handle, (ACPI_STRING)"_CRS",
359 embedded_controller_io_ports_parse_callback, sc);
360 if (status != B_OK) {
361 ERROR("Error while getting IO ports addresses\n");
362 goto error2;
363 }
364
365 // Install a handler for this EC's GPE bit. We want edge-triggered
366 // behavior.
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");
372 goto error1;
373 }
374
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");
381 goto error1;
382 }
383
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");
388 goto error1;
389 }
390
391 return 0;
392
393 error1:
394 sc->ec_acpi_module->remove_gpe_handler(sc->ec_gpehandle, sc->ec_gpebit,
395 &EcGpeHandler);
396 sc->ec_acpi->remove_address_space_handler(sc->ec_handle, ACPI_ADR_SPACE_EC,
397 EcSpaceHandler);
398
399 error2:
400 free(buf.pointer);
401
402 // remove child nodes
403 device_node *child = NULL;
404 const device_attr attrs[] = { { NULL } };
405 while (gDeviceManager->get_next_child_node(dev, attrs, &child) == B_OK)
406 gDeviceManager->unregister_node(child);
407
408 return ENXIO;
409 }
410
411
412 static void
embedded_controller_uninit_driver(void * driverCookie)413 embedded_controller_uninit_driver(void* driverCookie)
414 {
415 acpi_ec_cookie* sc = (struct acpi_ec_cookie*)driverCookie;
416 mutex_destroy(&sc->ec_lock);
417 free(sc);
418 put_module(B_ACPI_MODULE_NAME);
419 }
420
421
422 static status_t
embedded_controller_register_child_devices(void * _cookie)423 embedded_controller_register_child_devices(void* _cookie)
424 {
425 device_node* node = ((acpi_ec_cookie*)_cookie)->ec_dev;
426
427 int pathID = gDeviceManager->create_id(ACPI_EC_PATHID_GENERATOR);
428 if (pathID < 0) {
429 TRACE("register_child_device couldn't create a path_id\n");
430 return B_ERROR;
431 }
432
433 char name[128];
434 snprintf(name, sizeof(name), ACPI_EC_BASENAME, pathID);
435
436 return gDeviceManager->publish_device(node, name, ACPI_EC_DEVICE_NAME);
437 }
438
439
440 static status_t
embedded_controller_init_device(void * driverCookie,void ** cookie)441 embedded_controller_init_device(void* driverCookie, void** cookie)
442 {
443 *cookie = driverCookie;
444 return B_OK;
445 }
446
447
448 static void
embedded_controller_uninit_device(void * _cookie)449 embedded_controller_uninit_device(void* _cookie)
450 {
451 }
452
453
454 driver_module_info embedded_controller_driver_module = {
455 {
456 ACPI_EC_DRIVER_NAME,
457 0,
458 NULL
459 },
460
461 embedded_controller_support,
462 embedded_controller_register_device,
463 embedded_controller_init_driver,
464 embedded_controller_uninit_driver,
465 embedded_controller_register_child_devices,
466 NULL, // rescan
467 NULL, // removed
468 };
469
470
471 struct device_module_info embedded_controller_device_module = {
472 {
473 ACPI_EC_DEVICE_NAME,
474 0,
475 NULL
476 },
477
478 embedded_controller_init_device,
479 embedded_controller_uninit_device,
480 NULL,
481
482 embedded_controller_open,
483 embedded_controller_close,
484 embedded_controller_free,
485 embedded_controller_read,
486 embedded_controller_write,
487 NULL,
488 embedded_controller_control,
489
490 NULL,
491 NULL
492 };
493
494
495 // #pragma mark -
496
497
498 static acpi_status
EcCheckStatus(struct acpi_ec_cookie * sc,const char * msg,EC_EVENT event)499 EcCheckStatus(struct acpi_ec_cookie* sc, const char* msg, EC_EVENT event)
500 {
501 acpi_status status = AE_NO_HARDWARE_RESPONSE;
502 EC_STATUS ec_status = EC_GET_CSR(sc);
503
504 if (sc->ec_burstactive && !(ec_status & EC_FLAG_BURST_MODE)) {
505 TRACE("burst disabled in waitevent (%s)\n", msg);
506 sc->ec_burstactive = false;
507 }
508 if (EVENT_READY(event, ec_status)) {
509 TRACE("%s wait ready, status %#x\n", msg, ec_status);
510 status = AE_OK;
511 }
512 return status;
513 }
514
515
516 static void
EcGpeQueryHandlerSub(struct acpi_ec_cookie * sc)517 EcGpeQueryHandlerSub(struct acpi_ec_cookie *sc)
518 {
519 // Serialize user access with EcSpaceHandler().
520 status_t status = EcLock(sc);
521 if (status != B_OK) {
522 TRACE("GpeQuery lock error.\n");
523 return;
524 }
525
526 // Send a query command to the EC to find out which _Qxx call it
527 // wants to make. This command clears the SCI bit and also the
528 // interrupt source since we are edge-triggered. To prevent the GPE
529 // that may arise from running the query from causing another query
530 // to be queued, we clear the pending flag only after running it.
531 acpi_status acpi_status = AE_ERROR;
532 for (uint8 retry = 0; retry < 2; retry++) {
533 acpi_status = EcCommand(sc, EC_COMMAND_QUERY);
534 if (acpi_status == AE_OK)
535 break;
536 if (EcCheckStatus(sc, "retr_check",
537 EC_EVENT_INPUT_BUFFER_EMPTY) != AE_OK)
538 break;
539 }
540
541 if (acpi_status != AE_OK) {
542 EcUnlock(sc);
543 TRACE("GPE query failed.\n");
544 return;
545 }
546 uint8 data = EC_GET_DATA(sc);
547
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.
551 EcUnlock(sc);
552
553 // Ignore the value for "no outstanding event". (13.3.5)
554 TRACE("query ok,%s running _Q%02X\n", data ? "" : " not", data);
555 if (data == 0)
556 return;
557
558 // Evaluate _Qxx to respond to the controller.
559 char qxx[5];
560 snprintf(qxx, sizeof(qxx), "_Q%02X", data);
561 AcpiUtStrupr(qxx);
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);
565 }
566 }
567
568
569 static void
EcGpeQueryHandler(void * context)570 EcGpeQueryHandler(void* context)
571 {
572 struct acpi_ec_cookie* sc = (struct acpi_ec_cookie*)context;
573 int32 pending;
574
575 ASSERT(context != NULL);
576
577 do {
578 // Read the current pending count
579 pending = atomic_get(&sc->ec_sci_pending);
580
581 // Call GPE handler function
582 EcGpeQueryHandlerSub(sc);
583
584 // Try to reset the pending count to zero. If this fails we
585 // know another GPE event has occurred while handling the
586 // current GPE event and need to loop.
587 } while (atomic_test_and_set(&sc->ec_sci_pending, 0, pending));
588 }
589
590
591 /*! The GPE handler is called when IBE/OBF or SCI events occur. We are
592 called from an unknown lock context.
593 */
594 static uint32
EcGpeHandler(acpi_handle gpeDevice,uint32 gpeNumber,void * context)595 EcGpeHandler(acpi_handle gpeDevice, uint32 gpeNumber, void* context)
596 {
597 struct acpi_ec_cookie* sc = (acpi_ec_cookie*)context;
598
599 ASSERT(context != NULL);//, ("EcGpeHandler called with NULL"));
600 TRACE("gpe handler start\n");
601
602 // Notify EcWaitEvent() that the status register is now fresh. If we
603 // didn't do this, it wouldn't be possible to distinguish an old IBE
604 // from a new one, for example when doing a write transaction (writing
605 // address and then data values.)
606 atomic_add(&sc->ec_gencount, 1);
607 sc->ec_condition_var.NotifyAll();
608
609 // If the EC_SCI bit of the status register is set, queue a query handler.
610 // It will run the query and _Qxx method later, under the lock.
611 EC_STATUS ecStatus = EC_GET_CSR(sc);
612 if ((ecStatus & EC_EVENT_SCI) && atomic_add(&sc->ec_sci_pending, 1) == 0) {
613 TRACE("gpe queueing query handler\n");
614 acpi_status status = AcpiOsExecute(OSL_GPE_HANDLER, EcGpeQueryHandler,
615 context);
616 if (status != AE_OK) {
617 dprintf("EcGpeHandler: queuing GPE query handler failed\n");
618 atomic_add(&sc->ec_sci_pending, -1);
619 }
620 }
621 return ACPI_REENABLE_GPE;
622 }
623
624
625 static acpi_status
EcSpaceSetup(acpi_handle region,uint32 function,void * context,void ** regionContext)626 EcSpaceSetup(acpi_handle region, uint32 function, void* context,
627 void** regionContext)
628 {
629 // If deactivating a region, always set the output to NULL. Otherwise,
630 // just pass the context through.
631 if (function == ACPI_REGION_DEACTIVATE)
632 *regionContext = NULL;
633 else
634 *regionContext = context;
635
636 return AE_OK;
637 }
638
639
640 static acpi_status
EcSpaceHandler(uint32 function,acpi_physical_address address,uint32 width,int * value,void * context,void * regionContext)641 EcSpaceHandler(uint32 function, acpi_physical_address address, uint32 width,
642 int* value, void* context, void* regionContext)
643 {
644 TRACE("enter EcSpaceHandler\n");
645 struct acpi_ec_cookie* sc = (struct acpi_ec_cookie*)context;
646
647 if (function != ACPI_READ && function != ACPI_WRITE)
648 return AE_BAD_PARAMETER;
649 if (width % 8 != 0 || value == NULL || context == NULL)
650 return AE_BAD_PARAMETER;
651 if (address + width / 8 > 256)
652 return AE_BAD_ADDRESS;
653
654 // If booting, check if we need to run the query handler. If so, we
655 // we call it directly here as scheduling and dpc might not be up yet.
656 // (Not sure if it's needed)
657
658 if (gKernelStartup || gKernelShutdown || sc->ec_suspending) {
659 if ((EC_GET_CSR(sc) & EC_EVENT_SCI) &&
660 atomic_add(&sc->ec_sci_pending, 1) == 0) {
661 //CTR0(KTR_ACPI, "ec running gpe handler directly");
662 EcGpeQueryHandler(sc);
663 }
664 }
665
666 // Serialize with EcGpeQueryHandler() at transaction granularity.
667 acpi_status status = EcLock(sc);
668 if (status != B_OK)
669 return AE_NOT_ACQUIRED;
670
671 // If we can't start burst mode, continue anyway.
672 status = EcCommand(sc, EC_COMMAND_BURST_ENABLE);
673 if (status == B_OK) {
674 if (EC_GET_DATA(sc) == EC_BURST_ACK) {
675 TRACE("burst enabled.\n");
676 sc->ec_burstactive = TRUE;
677 }
678 }
679
680 // Perform the transaction(s), based on width.
681 ACPI_PHYSICAL_ADDRESS ecAddr = address;
682 uint8* ecData = (uint8 *) value;
683 if (function == ACPI_READ)
684 *value = 0;
685 do {
686 switch (function) {
687 case ACPI_READ:
688 status = EcRead(sc, ecAddr, ecData);
689 break;
690 case ACPI_WRITE:
691 status = EcWrite(sc, ecAddr, *ecData);
692 break;
693 }
694 if (status != AE_OK)
695 break;
696 ecAddr++;
697 ecData++;
698 } while (ecAddr < address + width / 8);
699
700 if (sc->ec_burstactive) {
701 sc->ec_burstactive = FALSE;
702 if (EcCommand(sc, EC_COMMAND_BURST_DISABLE) == AE_OK)
703 TRACE("disabled burst ok.");
704 }
705
706 EcUnlock(sc);
707 return status;
708 }
709
710
711 static acpi_status
EcWaitEvent(struct acpi_ec_cookie * sc,EC_EVENT event,int32 generationCount)712 EcWaitEvent(struct acpi_ec_cookie* sc, EC_EVENT event, int32 generationCount)
713 {
714 static int32 noIntr = 0;
715 acpi_status status = AE_NO_HARDWARE_RESPONSE;
716 int32 count, i;
717
718 int needPoll = ec_polled_mode || sc->ec_suspending
719 || gKernelStartup || gKernelShutdown;
720
721 // Wait for event by polling or GPE (interrupt).
722 if (needPoll) {
723 count = (ec_timeout * 1000) / EC_POLL_DELAY;
724 if (count == 0)
725 count = 1;
726 spin(10);
727 for (i = 0; i < count; i++) {
728 status = EcCheckStatus(sc, "poll", event);
729 if (status == AE_OK)
730 break;
731 spin(EC_POLL_DELAY);
732 }
733 } else {
734 // Wait for the GPE to signal the status changed, checking the
735 // status register each time we get one. It's possible to get a
736 // GPE for an event we're not interested in here (i.e., SCI for
737 // EC query).
738 for (i = 0; i < ec_timeout; i++) {
739 if (generationCount == sc->ec_gencount) {
740 sc->ec_condition_var.Wait(B_RELATIVE_TIMEOUT, 1000);
741 }
742 /*
743 * Record new generation count. It's possible the GPE was
744 * just to notify us that a query is needed and we need to
745 * wait for a second GPE to signal the completion of the
746 * event we are actually waiting for.
747 */
748 status = EcCheckStatus(sc, "sleep", event);
749 if (status == AE_OK) {
750 if (generationCount == sc->ec_gencount)
751 noIntr++;
752 else
753 noIntr = 0;
754 break;
755 }
756 generationCount = sc->ec_gencount;
757 }
758
759 /*
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 */
764 if (status != AE_OK)
765 status = EcCheckStatus(sc, "sleep_end", event);
766 }
767 if (!needPoll && noIntr > 10) {
768 TRACE("not getting interrupts, switched to polled mode\n");
769 ec_polled_mode = true;
770 }
771
772 if (status != AE_OK)
773 TRACE("error: ec wait timed out\n");
774
775 return status;
776 }
777
778
779 static acpi_status
EcCommand(struct acpi_ec_cookie * sc,EC_COMMAND cmd)780 EcCommand(struct acpi_ec_cookie* sc, EC_COMMAND cmd)
781 {
782 // Don't use burst mode if user disabled it.
783 if (!ec_burst_mode && cmd == EC_COMMAND_BURST_ENABLE)
784 return AE_ERROR;
785
786 // Decide what to wait for based on command type.
787 EC_EVENT event;
788 switch (cmd) {
789 case EC_COMMAND_READ:
790 case EC_COMMAND_WRITE:
791 case EC_COMMAND_BURST_DISABLE:
792 event = EC_EVENT_INPUT_BUFFER_EMPTY;
793 break;
794 case EC_COMMAND_QUERY:
795 case EC_COMMAND_BURST_ENABLE:
796 event = EC_EVENT_OUTPUT_BUFFER_FULL;
797 break;
798 default:
799 TRACE("EcCommand: invalid command %#x\n", cmd);
800 return AE_BAD_PARAMETER;
801 }
802
803 // Ensure empty input buffer before issuing command.
804 // Use generation count of zero to force a quick check.
805 acpi_status status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, 0);
806 if (status != AE_OK)
807 return status;
808
809 // Run the command and wait for the chosen event.
810 TRACE("running command %#x\n", cmd);
811 int32 generationCount = sc->ec_gencount;
812 EC_SET_CSR(sc, cmd);
813 status = EcWaitEvent(sc, event, generationCount);
814 if (status == AE_OK) {
815 // If we succeeded, burst flag should now be present.
816 if (cmd == EC_COMMAND_BURST_ENABLE) {
817 EC_STATUS ec_status = EC_GET_CSR(sc);
818 if ((ec_status & EC_FLAG_BURST_MODE) == 0)
819 status = AE_ERROR;
820 }
821 } else
822 TRACE("EcCommand: no response to %#x\n", cmd);
823
824 return status;
825 }
826
827
828 static acpi_status
EcRead(struct acpi_ec_cookie * sc,uint8 address,uint8 * readData)829 EcRead(struct acpi_ec_cookie* sc, uint8 address, uint8* readData)
830 {
831 TRACE("read from %#x\n", address);
832
833 acpi_status status;
834 for (uint8 retry = 0; retry < 2; retry++) {
835 status = EcCommand(sc, EC_COMMAND_READ);
836 if (status != AE_OK)
837 return status;
838
839 int32 generationCount = sc->ec_gencount;
840 EC_SET_DATA(sc, address);
841 status = EcWaitEvent(sc, EC_EVENT_OUTPUT_BUFFER_FULL, generationCount);
842 if (status == AE_OK) {
843 *readData = EC_GET_DATA(sc);
844 return AE_OK;
845 }
846 if (EcCheckStatus(sc, "retr_check", EC_EVENT_INPUT_BUFFER_EMPTY)
847 != AE_OK) {
848 break;
849 }
850 }
851
852 TRACE("EcRead: failed waiting to get data\n");
853 return status;
854 }
855
856
857 static acpi_status
EcWrite(struct acpi_ec_cookie * sc,uint8 address,uint8 writeData)858 EcWrite(struct acpi_ec_cookie* sc, uint8 address, uint8 writeData)
859 {
860 acpi_status status = EcCommand(sc, EC_COMMAND_WRITE);
861 if (status != AE_OK)
862 return status;
863
864 int32 generationCount = sc->ec_gencount;
865 EC_SET_DATA(sc, address);
866 status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, generationCount);
867 if (status != AE_OK) {
868 TRACE("EcWrite: failed waiting for sent address\n");
869 return status;
870 }
871
872 generationCount = sc->ec_gencount;
873 EC_SET_DATA(sc, writeData);
874 status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, generationCount);
875 if (status != AE_OK) {
876 TRACE("EcWrite: failed waiting for sent data\n");
877 return status;
878 }
879
880 return AE_OK;
881 }
882