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