1 /* $OpenBSD: acpi.c,v 1.266 2014/07/16 07:42:50 mlarkin Exp $ */ 2 /* 3 * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> 4 * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 20 #include <sys/systm.h> 21 #include <sys/buf.h> 22 #include <sys/device.h> 23 #include <sys/malloc.h> 24 #include <sys/fcntl.h> 25 #include <sys/ioccom.h> 26 #include <sys/event.h> 27 #include <sys/signalvar.h> 28 #include <sys/proc.h> 29 #include <sys/kthread.h> 30 #include <sys/sched.h> 31 #include <sys/reboot.h> 32 33 #ifdef HIBERNATE 34 #include <sys/hibernate.h> 35 #endif 36 37 #include <machine/conf.h> 38 #include <machine/cpufunc.h> 39 #include <machine/bus.h> 40 41 #include <dev/pci/pcivar.h> 42 #include <dev/acpi/acpireg.h> 43 #include <dev/acpi/acpivar.h> 44 #include <dev/acpi/amltypes.h> 45 #include <dev/acpi/acpidev.h> 46 #include <dev/acpi/dsdt.h> 47 #include <dev/wscons/wsdisplayvar.h> 48 49 #include <dev/pci/pcivar.h> 50 #include <dev/pci/pcidevs.h> 51 #include <dev/pci/ppbreg.h> 52 53 #include <dev/pci/pciidereg.h> 54 #include <dev/pci/pciidevar.h> 55 56 #include <machine/apmvar.h> 57 #define APMUNIT(dev) (minor(dev)&0xf0) 58 #define APMDEV(dev) (minor(dev)&0x0f) 59 #define APMDEV_NORMAL 0 60 #define APMDEV_CTL 8 61 62 #include "wd.h" 63 #include "wsdisplay.h" 64 65 #ifdef ACPI_DEBUG 66 int acpi_debug = 16; 67 #endif 68 69 int acpi_poll_enabled; 70 int acpi_hasprocfvs; 71 72 #define ACPIEN_RETRIES 15 73 74 void acpi_pci_match(struct device *, struct pci_attach_args *); 75 pcireg_t acpi_pci_min_powerstate(pci_chipset_tag_t, pcitag_t); 76 void acpi_pci_set_powerstate(pci_chipset_tag_t, pcitag_t, int, int); 77 78 int acpi_match(struct device *, void *, void *); 79 void acpi_attach(struct device *, struct device *, void *); 80 int acpi_submatch(struct device *, void *, void *); 81 int acpi_print(void *, const char *); 82 83 void acpi_map_pmregs(struct acpi_softc *); 84 85 int acpi_loadtables(struct acpi_softc *, struct acpi_rsdp *); 86 87 int _acpi_matchhids(const char *, const char *[]); 88 89 int acpi_inidev(struct aml_node *, void *); 90 int acpi_foundprt(struct aml_node *, void *); 91 92 struct acpi_q *acpi_maptable(struct acpi_softc *, paddr_t, const char *, 93 const char *, const char *, int); 94 95 int acpi_enable(struct acpi_softc *); 96 void acpi_init_states(struct acpi_softc *); 97 98 void acpi_gpe_task(void *, int); 99 void acpi_sbtn_task(void *, int); 100 void acpi_pbtn_task(void *, int); 101 102 #ifndef SMALL_KERNEL 103 104 int acpi_thinkpad_enabled; 105 int acpi_toshiba_enabled; 106 int acpi_asus_enabled; 107 int acpi_saved_boothowto; 108 int acpi_enabled; 109 110 int acpi_matchhids(struct acpi_attach_args *aa, const char *hids[], 111 const char *driver); 112 113 void acpi_thread(void *); 114 void acpi_create_thread(void *); 115 void acpi_init_pm(struct acpi_softc *); 116 void acpi_init_gpes(struct acpi_softc *); 117 void acpi_indicator(struct acpi_softc *, int); 118 119 int acpi_founddock(struct aml_node *, void *); 120 int acpi_foundpss(struct aml_node *, void *); 121 int acpi_foundhid(struct aml_node *, void *); 122 int acpi_foundec(struct aml_node *, void *); 123 int acpi_foundtmp(struct aml_node *, void *); 124 int acpi_foundprw(struct aml_node *, void *); 125 int acpi_foundvideo(struct aml_node *, void *); 126 int acpi_foundsony(struct aml_node *node, void *arg); 127 128 int acpi_foundide(struct aml_node *node, void *arg); 129 int acpiide_notify(struct aml_node *, int, void *); 130 void wdcattach(struct channel_softc *); 131 int wdcdetach(struct channel_softc *, int); 132 int is_ejectable_bay(struct aml_node *node); 133 int is_ata(struct aml_node *node); 134 int is_ejectable(struct aml_node *node); 135 136 struct idechnl { 137 struct acpi_softc *sc; 138 int64_t addr; 139 int64_t chnl; 140 int64_t sta; 141 }; 142 143 int acpi_add_device(struct aml_node *node, void *arg); 144 145 struct gpe_block *acpi_find_gpe(struct acpi_softc *, int); 146 void acpi_enable_onegpe(struct acpi_softc *, int); 147 int acpi_gpe(struct acpi_softc *, int, void *); 148 149 void acpi_enable_rungpes(struct acpi_softc *); 150 void acpi_enable_wakegpes(struct acpi_softc *, int); 151 void acpi_disable_allgpes(struct acpi_softc *); 152 153 #endif /* SMALL_KERNEL */ 154 155 /* XXX move this into dsdt softc at some point */ 156 extern struct aml_node aml_root; 157 158 struct cfattach acpi_ca = { 159 sizeof(struct acpi_softc), acpi_match, acpi_attach 160 }; 161 162 struct cfdriver acpi_cd = { 163 NULL, "acpi", DV_DULL 164 }; 165 166 struct acpi_softc *acpi_softc; 167 168 #define acpi_bus_space_map _bus_space_map 169 #define acpi_bus_space_unmap _bus_space_unmap 170 171 int 172 acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address, 173 int access_size, int len, void *buffer) 174 { 175 u_int8_t *pb; 176 bus_space_tag_t iot; 177 bus_space_handle_t ioh; 178 pci_chipset_tag_t pc; 179 pcitag_t tag; 180 int reg, idx, ival, sval; 181 182 dnprintf(50, "gasio: %.2x 0x%.8llx %s\n", 183 iospace, address, (iodir == ACPI_IOWRITE) ? "write" : "read"); 184 185 KASSERT((len % access_size) == 0); 186 187 pb = (u_int8_t *)buffer; 188 switch (iospace) { 189 case GAS_SYSTEM_MEMORY: 190 case GAS_SYSTEM_IOSPACE: 191 if (iospace == GAS_SYSTEM_MEMORY) 192 iot = sc->sc_memt; 193 else 194 iot = sc->sc_iot; 195 196 if (acpi_bus_space_map(iot, address, len, 0, &ioh) != 0) { 197 printf("%s: unable to map iospace\n", DEVNAME(sc)); 198 return (-1); 199 } 200 for (reg = 0; reg < len; reg += access_size) { 201 if (iodir == ACPI_IOREAD) { 202 switch (access_size) { 203 case 1: 204 *(uint8_t *)(pb + reg) = 205 bus_space_read_1(iot, ioh, reg); 206 dnprintf(80, "os_in8(%llx) = %x\n", 207 reg+address, *(uint8_t *)(pb+reg)); 208 break; 209 case 2: 210 *(uint16_t *)(pb + reg) = 211 bus_space_read_2(iot, ioh, reg); 212 dnprintf(80, "os_in16(%llx) = %x\n", 213 reg+address, *(uint16_t *)(pb+reg)); 214 break; 215 case 4: 216 *(uint32_t *)(pb + reg) = 217 bus_space_read_4(iot, ioh, reg); 218 break; 219 default: 220 printf("%s: rdio: invalid size %d\n", 221 DEVNAME(sc), access_size); 222 return (-1); 223 } 224 } else { 225 switch (access_size) { 226 case 1: 227 bus_space_write_1(iot, ioh, reg, 228 *(uint8_t *)(pb + reg)); 229 dnprintf(80, "os_out8(%llx,%x)\n", 230 reg+address, *(uint8_t *)(pb+reg)); 231 break; 232 case 2: 233 bus_space_write_2(iot, ioh, reg, 234 *(uint16_t *)(pb + reg)); 235 dnprintf(80, "os_out16(%llx,%x)\n", 236 reg+address, *(uint16_t *)(pb+reg)); 237 break; 238 case 4: 239 bus_space_write_4(iot, ioh, reg, 240 *(uint32_t *)(pb + reg)); 241 break; 242 default: 243 printf("%s: wrio: invalid size %d\n", 244 DEVNAME(sc), access_size); 245 return (-1); 246 } 247 } 248 } 249 acpi_bus_space_unmap(iot, ioh, len, NULL); 250 break; 251 252 case GAS_PCI_CFG_SPACE: 253 /* format of address: 254 * bits 00..15 = register 255 * bits 16..31 = function 256 * bits 32..47 = device 257 * bits 48..63 = bus 258 */ 259 pc = NULL; 260 tag = pci_make_tag(pc, 261 ACPI_PCI_BUS(address), ACPI_PCI_DEV(address), 262 ACPI_PCI_FN(address)); 263 264 /* XXX: This is ugly. read-modify-write does a byte at a time */ 265 reg = ACPI_PCI_REG(address); 266 for (idx = reg; idx < reg+len; idx++) { 267 ival = pci_conf_read(pc, tag, idx & ~0x3); 268 if (iodir == ACPI_IOREAD) { 269 *pb = ival >> (8 * (idx & 0x3)); 270 } else { 271 sval = *pb; 272 ival &= ~(0xFF << (8* (idx & 0x3))); 273 ival |= sval << (8* (idx & 0x3)); 274 pci_conf_write(pc, tag, idx & ~0x3, ival); 275 } 276 pb++; 277 } 278 break; 279 280 case GAS_EMBEDDED: 281 if (sc->sc_ec == NULL) { 282 printf("%s: WARNING EC not initialized\n", DEVNAME(sc)); 283 return (-1); 284 } 285 #ifndef SMALL_KERNEL 286 if (iodir == ACPI_IOREAD) 287 acpiec_read(sc->sc_ec, (u_int8_t)address, len, buffer); 288 else 289 acpiec_write(sc->sc_ec, (u_int8_t)address, len, buffer); 290 #endif 291 break; 292 } 293 return (0); 294 } 295 296 int 297 acpi_inidev(struct aml_node *node, void *arg) 298 { 299 struct acpi_softc *sc = (struct acpi_softc *)arg; 300 int64_t st; 301 302 /* 303 * Per the ACPI spec 6.5.1, only run _INI when device is there or 304 * when there is no _STA. We terminate the tree walk (with return 1) 305 * early if necessary. 306 */ 307 308 /* Evaluate _STA to decide _INI fate and walk fate */ 309 if (aml_evalinteger(sc, node->parent, "_STA", 0, NULL, &st)) 310 st = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000; 311 312 /* Evaluate _INI if we are present */ 313 if (st & STA_PRESENT) 314 aml_evalnode(sc, node, 0, NULL, NULL); 315 316 /* If we are functioning, we walk/search our children */ 317 if (st & STA_DEV_OK) 318 return 0; 319 320 /* If we are not enabled, or not present, terminate search */ 321 if (!(st & (STA_PRESENT|STA_ENABLED))) 322 return 1; 323 324 /* Default just continue search */ 325 return 0; 326 } 327 328 int 329 acpi_foundprt(struct aml_node *node, void *arg) 330 { 331 struct acpi_softc *sc = (struct acpi_softc *)arg; 332 struct device *self = (struct device *)arg; 333 struct acpi_attach_args aaa; 334 int64_t st = 0; 335 336 dnprintf(10, "found prt entry: %s\n", node->parent->name); 337 338 /* Evaluate _STA to decide _PRT fate and walk fate */ 339 if (aml_evalinteger(sc, node->parent, "_STA", 0, NULL, &st)) 340 st = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000; 341 342 if (st & STA_PRESENT) { 343 memset(&aaa, 0, sizeof(aaa)); 344 aaa.aaa_iot = sc->sc_iot; 345 aaa.aaa_memt = sc->sc_memt; 346 aaa.aaa_node = node; 347 aaa.aaa_name = "acpiprt"; 348 349 config_found(self, &aaa, acpi_print); 350 } 351 352 /* If we are functioning, we walk/search our children */ 353 if (st & STA_DEV_OK) 354 return 0; 355 356 /* If we are not enabled, or not present, terminate search */ 357 if (!(st & (STA_PRESENT|STA_ENABLED))) 358 return 1; 359 360 /* Default just continue search */ 361 return 0; 362 } 363 364 int 365 acpi_match(struct device *parent, void *match, void *aux) 366 { 367 struct bios_attach_args *ba = aux; 368 struct cfdata *cf = match; 369 370 /* sanity */ 371 if (strcmp(ba->ba_name, cf->cf_driver->cd_name)) 372 return (0); 373 374 if (!acpi_probe(parent, cf, ba)) 375 return (0); 376 377 return (1); 378 } 379 380 TAILQ_HEAD(, acpi_pci) acpi_pcidevs = 381 TAILQ_HEAD_INITIALIZER(acpi_pcidevs); 382 TAILQ_HEAD(, acpi_pci) acpi_pcirootdevs = 383 TAILQ_HEAD_INITIALIZER(acpi_pcirootdevs); 384 385 int acpi_getpci(struct aml_node *node, void *arg); 386 int acpi_getminbus(union acpi_resource *crs, void *arg); 387 388 int 389 acpi_getminbus(union acpi_resource *crs, void *arg) 390 { 391 int *bbn = arg; 392 int typ = AML_CRSTYPE(crs); 393 394 /* Check for embedded bus number */ 395 if (typ == LR_WORD && crs->lr_word.type == 2) { 396 /* If _MIN > _MAX, the resource is considered to be invalid. */ 397 if (crs->lr_word._min > crs->lr_word._max) 398 return -1; 399 *bbn = crs->lr_word._min; 400 } 401 return 0; 402 } 403 404 int 405 _acpi_matchhids(const char *hid, const char *hids[]) 406 { 407 int i; 408 409 for (i = 0; hids[i]; i++) 410 if (!strcmp(hid, hids[i])) 411 return (1); 412 return (0); 413 } 414 415 #ifndef SMALL_KERNEL 416 int 417 acpi_matchhids(struct acpi_attach_args *aa, const char *hids[], 418 const char *driver) 419 { 420 if (aa->aaa_dev == NULL || aa->aaa_node == NULL) 421 return (0); 422 if (_acpi_matchhids(aa->aaa_dev, hids)) { 423 dnprintf(5, "driver %s matches at least one hid\n", driver); 424 return (1); 425 } 426 427 return (0); 428 } 429 #endif /* SMALL_KERNEL */ 430 431 /* Map ACPI device node to PCI */ 432 int 433 acpi_getpci(struct aml_node *node, void *arg) 434 { 435 const char *pcihid[] = { ACPI_DEV_PCIB, ACPI_DEV_PCIEB, "HWP0002", 0 }; 436 struct acpi_pci *pci, *ppci; 437 struct aml_value res; 438 struct acpi_softc *sc = arg; 439 pci_chipset_tag_t pc = NULL; 440 pcitag_t tag; 441 uint64_t val; 442 uint32_t reg; 443 444 if (!node->value || node->value->type != AML_OBJTYPE_DEVICE) 445 return 0; 446 if (!aml_evalhid(node, &res)) { 447 /* Check if this is a PCI Root node */ 448 if (_acpi_matchhids(res.v_string, pcihid)) { 449 aml_freevalue(&res); 450 451 pci = malloc(sizeof(*pci), M_DEVBUF, M_WAITOK|M_ZERO); 452 453 pci->bus = -1; 454 if (!aml_evalinteger(sc, node, "_SEG", 0, NULL, &val)) 455 pci->seg = val; 456 if (!aml_evalname(sc, node, "_CRS", 0, NULL, &res)) { 457 aml_parse_resource(&res, acpi_getminbus, 458 &pci->bus); 459 dnprintf(10, "%s post-crs: %d\n", aml_nodename(node), 460 pci->bus); 461 } 462 if (!aml_evalinteger(sc, node, "_BBN", 0, NULL, &val)) { 463 dnprintf(10, "%s post-bbn: %d, %lld\n", aml_nodename(node), 464 pci->bus, val); 465 if (pci->bus == -1) 466 pci->bus = val; 467 } 468 pci->sub = pci->bus; 469 node->pci = pci; 470 dnprintf(10, "found PCI root: %s %d\n", 471 aml_nodename(node), pci->bus); 472 TAILQ_INSERT_TAIL(&acpi_pcirootdevs, pci, next); 473 } 474 aml_freevalue(&res); 475 return 0; 476 } 477 478 /* If parent is not PCI, or device does not have _ADR, return */ 479 if (!node->parent || (ppci = node->parent->pci) == NULL) 480 return 0; 481 if (aml_evalinteger(sc, node, "_ADR", 0, NULL, &val)) 482 return 0; 483 484 pci = malloc(sizeof(*pci), M_DEVBUF, M_WAITOK|M_ZERO); 485 pci->bus = ppci->sub; 486 pci->dev = ACPI_ADR_PCIDEV(val); 487 pci->fun = ACPI_ADR_PCIFUN(val); 488 pci->node = node; 489 pci->sub = -1; 490 491 dnprintf(10, "%.2x:%.2x.%x -> %s\n", 492 pci->bus, pci->dev, pci->fun, 493 aml_nodename(node)); 494 495 /* Collect device power state information. */ 496 if (aml_evalinteger(sc, node, "_S3D", 0, NULL, &val) == 0) 497 pci->_s3d = val; 498 else 499 pci->_s3d = -1; 500 if (aml_evalinteger(sc, node, "_S3W", 0, NULL, &val) == 0) 501 pci->_s3w = val; 502 else 503 pci->_s3w = -1; 504 if (aml_evalinteger(sc, node, "_S4D", 0, NULL, &val) == 0) 505 pci->_s4d = val; 506 else 507 pci->_s4d = -1; 508 if (aml_evalinteger(sc, node, "_S4W", 0, NULL, &val) == 0) 509 pci->_s4w = val; 510 else 511 pci->_s4w = -1; 512 513 /* Check if PCI device exists */ 514 if (pci->dev > 0x1F || pci->fun > 7) { 515 free(pci, M_DEVBUF, 0); 516 return (1); 517 } 518 tag = pci_make_tag(pc, pci->bus, pci->dev, pci->fun); 519 reg = pci_conf_read(pc, tag, PCI_ID_REG); 520 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID) { 521 free(pci, M_DEVBUF, 0); 522 return (1); 523 } 524 node->pci = pci; 525 526 TAILQ_INSERT_TAIL(&acpi_pcidevs, pci, next); 527 528 /* Check if this is a PCI bridge */ 529 reg = pci_conf_read(pc, tag, PCI_CLASS_REG); 530 if (PCI_CLASS(reg) == PCI_CLASS_BRIDGE && 531 PCI_SUBCLASS(reg) == PCI_SUBCLASS_BRIDGE_PCI) { 532 reg = pci_conf_read(pc, tag, PPB_REG_BUSINFO); 533 pci->sub = PPB_BUSINFO_SECONDARY(reg); 534 535 dnprintf(10, "found PCI bridge: %s %d\n", 536 aml_nodename(node), pci->sub); 537 538 /* Continue scanning */ 539 return (0); 540 } 541 542 /* Device does not have children, stop scanning */ 543 return (1); 544 } 545 546 void 547 acpi_pci_match(struct device *dev, struct pci_attach_args *pa) 548 { 549 struct acpi_pci *pdev; 550 int state; 551 552 TAILQ_FOREACH(pdev, &acpi_pcidevs, next) { 553 if (pdev->bus != pa->pa_bus || 554 pdev->dev != pa->pa_device || 555 pdev->fun != pa->pa_function) 556 continue; 557 558 dnprintf(10,"%s at acpi0 %s\n", dev->dv_xname, 559 aml_nodename(pdev->node)); 560 561 pdev->device = dev; 562 563 /* 564 * If some Power Resources are dependent on this device 565 * initialize them. 566 */ 567 state = pci_get_powerstate(pa->pa_pc, pa->pa_tag); 568 acpi_pci_set_powerstate(pa->pa_pc, pa->pa_tag, state, 1); 569 acpi_pci_set_powerstate(pa->pa_pc, pa->pa_tag, state, 0); 570 } 571 } 572 573 pcireg_t 574 acpi_pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag) 575 { 576 struct acpi_pci *pdev; 577 int bus, dev, fun; 578 int state = -1, defaultstate = pci_get_powerstate(pc, tag); 579 580 pci_decompose_tag(pc, tag, &bus, &dev, &fun); 581 TAILQ_FOREACH(pdev, &acpi_pcidevs, next) { 582 if (pdev->bus == bus && pdev->dev == dev && pdev->fun == fun) { 583 switch (acpi_softc->sc_state) { 584 case ACPI_STATE_S3: 585 defaultstate = PCI_PMCSR_STATE_D3; 586 state = MAX(pdev->_s3d, pdev->_s3w); 587 break; 588 case ACPI_STATE_S4: 589 state = MAX(pdev->_s4d, pdev->_s4w); 590 break; 591 case ACPI_STATE_S5: 592 default: 593 break; 594 } 595 596 if (state >= PCI_PMCSR_STATE_D0 && 597 state <= PCI_PMCSR_STATE_D3) 598 return state; 599 } 600 } 601 602 return defaultstate; 603 } 604 605 void 606 acpi_pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, int state, int pre) 607 { 608 #if NACPIPWRRES > 0 609 struct acpi_softc *sc = acpi_softc; 610 struct acpi_pwrres *pr; 611 struct acpi_pci *pdev; 612 int bus, dev, fun; 613 char name[5]; 614 615 pci_decompose_tag(pc, tag, &bus, &dev, &fun); 616 TAILQ_FOREACH(pdev, &acpi_pcidevs, next) { 617 if (pdev->bus == bus && pdev->dev == dev && pdev->fun == fun) 618 break; 619 } 620 621 /* XXX Add a check to discard nodes without Power Resources? */ 622 if (pdev == NULL) 623 return; 624 625 SIMPLEQ_FOREACH(pr, &sc->sc_pwrresdevs, p_next) { 626 if (pr->p_node != pdev->node) 627 continue; 628 629 /* 630 * If the firmware is already aware that the device 631 * is in the given state, there's nothing to do. 632 */ 633 if (pr->p_state == state) 634 continue; 635 636 if (pre) { 637 /* 638 * If a Resource is dependent on this device for 639 * the given state, make sure it is turned "_ON". 640 */ 641 if (pr->p_res_state == state) 642 acpipwrres_ref_incr(pr->p_res_sc, pr->p_node); 643 } else { 644 /* 645 * If a Resource was referenced for the state we 646 * left, drop a reference and turn it "_OFF" if 647 * it was the last one. 648 */ 649 if (pr->p_res_state == pr->p_state) 650 acpipwrres_ref_decr(pr->p_res_sc, pr->p_node); 651 652 if (pr->p_res_state == state) { 653 snprintf(name, sizeof(name), "_PS%d", state); 654 aml_evalname(sc, pr->p_node, name, 0, 655 NULL, NULL); 656 } 657 658 pr->p_state = state; 659 } 660 661 } 662 #endif /* NACPIPWRRES > 0 */ 663 } 664 665 void 666 acpi_pciroots_attach(struct device *dev, void *aux, cfprint_t pr) 667 { 668 struct acpi_pci *pdev; 669 struct pcibus_attach_args *pba = aux; 670 671 KASSERT(pba->pba_busex != NULL); 672 673 TAILQ_FOREACH(pdev, &acpi_pcirootdevs, next) { 674 if (extent_alloc_region(pba->pba_busex, pdev->bus, 675 1, EX_NOWAIT) != 0) 676 continue; 677 pba->pba_bus = pdev->bus; 678 config_found(dev, pba, pr); 679 } 680 } 681 682 void 683 acpi_attach(struct device *parent, struct device *self, void *aux) 684 { 685 struct bios_attach_args *ba = aux; 686 struct acpi_softc *sc = (struct acpi_softc *)self; 687 struct acpi_mem_map handle; 688 struct acpi_rsdp *rsdp; 689 struct acpi_q *entry; 690 struct acpi_dsdt *p_dsdt; 691 #ifndef SMALL_KERNEL 692 int wakeup_dev_ct; 693 struct acpi_wakeq *wentry; 694 struct device *dev; 695 struct acpi_ac *ac; 696 struct acpi_bat *bat; 697 int s; 698 #endif /* SMALL_KERNEL */ 699 paddr_t facspa; 700 701 sc->sc_iot = ba->ba_iot; 702 sc->sc_memt = ba->ba_memt; 703 704 rw_init(&sc->sc_lck, "acpilk"); 705 706 acpi_softc = sc; 707 708 if (acpi_map(ba->ba_acpipbase, sizeof(struct acpi_rsdp), &handle)) { 709 printf(": can't map memory\n"); 710 return; 711 } 712 713 rsdp = (struct acpi_rsdp *)handle.va; 714 sc->sc_revision = (int)rsdp->rsdp_revision; 715 printf(": rev %d", sc->sc_revision); 716 717 SIMPLEQ_INIT(&sc->sc_tables); 718 SIMPLEQ_INIT(&sc->sc_wakedevs); 719 #if NACPIPWRRES > 0 720 SIMPLEQ_INIT(&sc->sc_pwrresdevs); 721 #endif /* NACPIPWRRES > 0 */ 722 723 724 #ifndef SMALL_KERNEL 725 sc->sc_note = malloc(sizeof(struct klist), M_DEVBUF, M_NOWAIT | M_ZERO); 726 if (sc->sc_note == NULL) { 727 printf(", can't allocate memory\n"); 728 acpi_unmap(&handle); 729 return; 730 } 731 #endif /* SMALL_KERNEL */ 732 733 if (acpi_loadtables(sc, rsdp)) { 734 printf(", can't load tables\n"); 735 acpi_unmap(&handle); 736 return; 737 } 738 739 acpi_unmap(&handle); 740 741 /* 742 * Find the FADT 743 */ 744 SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) { 745 if (memcmp(entry->q_table, FADT_SIG, 746 sizeof(FADT_SIG) - 1) == 0) { 747 sc->sc_fadt = entry->q_table; 748 break; 749 } 750 } 751 if (sc->sc_fadt == NULL) { 752 printf(", no FADT\n"); 753 return; 754 } 755 756 /* 757 * Check if we are able to enable ACPI control 758 */ 759 if (sc->sc_fadt->smi_cmd && 760 (!sc->sc_fadt->acpi_enable && !sc->sc_fadt->acpi_disable)) { 761 printf(", ACPI control unavailable\n"); 762 return; 763 } 764 765 /* 766 * Set up a pointer to the firmware control structure 767 */ 768 if (sc->sc_fadt->hdr_revision < 3 || sc->sc_fadt->x_firmware_ctl == 0) 769 facspa = sc->sc_fadt->firmware_ctl; 770 else 771 facspa = sc->sc_fadt->x_firmware_ctl; 772 773 if (acpi_map(facspa, sizeof(struct acpi_facs), &handle)) 774 printf(" !FACS"); 775 else 776 sc->sc_facs = (struct acpi_facs *)handle.va; 777 778 /* Create opcode hashtable */ 779 aml_hashopcodes(); 780 781 /* Create Default AML objects */ 782 aml_create_defaultobjects(); 783 784 /* 785 * Load the DSDT from the FADT pointer -- use the 786 * extended (64-bit) pointer if it exists 787 */ 788 if (sc->sc_fadt->hdr_revision < 3 || sc->sc_fadt->x_dsdt == 0) 789 entry = acpi_maptable(sc, sc->sc_fadt->dsdt, NULL, NULL, NULL, -1); 790 else 791 entry = acpi_maptable(sc, sc->sc_fadt->x_dsdt, NULL, NULL, NULL, -1); 792 793 if (entry == NULL) 794 printf(" !DSDT"); 795 796 p_dsdt = entry->q_table; 797 acpi_parse_aml(sc, p_dsdt->aml, p_dsdt->hdr_length - 798 sizeof(p_dsdt->hdr)); 799 800 /* Load SSDT's */ 801 SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) { 802 if (memcmp(entry->q_table, SSDT_SIG, 803 sizeof(SSDT_SIG) - 1) == 0) { 804 p_dsdt = entry->q_table; 805 acpi_parse_aml(sc, p_dsdt->aml, p_dsdt->hdr_length - 806 sizeof(p_dsdt->hdr)); 807 } 808 } 809 810 /* Perform post-parsing fixups */ 811 aml_postparse(); 812 813 /* Find available sleeping states */ 814 acpi_init_states(sc); 815 816 #ifndef SMALL_KERNEL 817 /* Find available sleep/resume related methods. */ 818 acpi_init_pm(sc); 819 #endif /* SMALL_KERNEL */ 820 821 /* Map Power Management registers */ 822 acpi_map_pmregs(sc); 823 824 #ifndef SMALL_KERNEL 825 /* Initialize GPE handlers */ 826 s = spltty(); 827 acpi_init_gpes(sc); 828 splx(s); 829 830 /* some devices require periodic polling */ 831 timeout_set(&sc->sc_dev_timeout, acpi_poll, sc); 832 833 acpi_enabled = 1; 834 #endif /* SMALL_KERNEL */ 835 836 /* 837 * Take over ACPI control. Note that once we do this, we 838 * effectively tell the system that we have ownership of 839 * the ACPI hardware registers, and that SMI should leave 840 * them alone 841 * 842 * This may prevent thermal control on some systems where 843 * that actually does work 844 */ 845 if (sc->sc_fadt->smi_cmd) { 846 if (acpi_enable(sc)) { 847 printf(", can't enable ACPI\n"); 848 return; 849 } 850 } 851 852 printf("\n%s: tables", DEVNAME(sc)); 853 SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) { 854 printf(" %.4s", (char *)entry->q_table); 855 } 856 printf("\n"); 857 858 #ifndef SMALL_KERNEL 859 /* Display wakeup devices and lowest S-state */ 860 wakeup_dev_ct = 0; 861 printf("%s: wakeup devices", DEVNAME(sc)); 862 SIMPLEQ_FOREACH(wentry, &sc->sc_wakedevs, q_next) { 863 if (wakeup_dev_ct < 16) 864 printf(" %.4s(S%d)", wentry->q_node->name, 865 wentry->q_state); 866 else if (wakeup_dev_ct == 16) 867 printf(" [...]"); 868 wakeup_dev_ct ++; 869 } 870 printf("\n"); 871 872 /* 873 * ACPI is enabled now -- attach timer 874 */ 875 { 876 struct acpi_attach_args aaa; 877 878 memset(&aaa, 0, sizeof(aaa)); 879 aaa.aaa_name = "acpitimer"; 880 aaa.aaa_iot = sc->sc_iot; 881 aaa.aaa_memt = sc->sc_memt; 882 #if 0 883 aaa.aaa_pcit = sc->sc_pcit; 884 aaa.aaa_smbust = sc->sc_smbust; 885 #endif 886 config_found(self, &aaa, acpi_print); 887 } 888 #endif /* SMALL_KERNEL */ 889 890 /* 891 * Attach table-defined devices 892 */ 893 SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) { 894 struct acpi_attach_args aaa; 895 896 memset(&aaa, 0, sizeof(aaa)); 897 aaa.aaa_iot = sc->sc_iot; 898 aaa.aaa_memt = sc->sc_memt; 899 #if 0 900 aaa.aaa_pcit = sc->sc_pcit; 901 aaa.aaa_smbust = sc->sc_smbust; 902 #endif 903 aaa.aaa_table = entry->q_table; 904 config_found_sm(self, &aaa, acpi_print, acpi_submatch); 905 } 906 907 /* initialize runtime environment */ 908 aml_find_node(&aml_root, "_INI", acpi_inidev, sc); 909 910 /* Get PCI mapping */ 911 aml_walknodes(&aml_root, AML_WALK_PRE, acpi_getpci, sc); 912 913 /* attach pci interrupt routing tables */ 914 aml_find_node(&aml_root, "_PRT", acpi_foundprt, sc); 915 916 #ifndef SMALL_KERNEL 917 aml_find_node(&aml_root, "_HID", acpi_foundec, sc); 918 919 aml_walknodes(&aml_root, AML_WALK_PRE, acpi_add_device, sc); 920 921 /* attach battery, power supply and button devices */ 922 aml_find_node(&aml_root, "_HID", acpi_foundhid, sc); 923 924 #if NWD > 0 925 /* Attach IDE bay */ 926 aml_walknodes(&aml_root, AML_WALK_PRE, acpi_foundide, sc); 927 #endif 928 929 /* attach docks */ 930 aml_find_node(&aml_root, "_DCK", acpi_founddock, sc); 931 932 /* check if we're running on a sony */ 933 aml_find_node(&aml_root, "GBRT", acpi_foundsony, sc); 934 935 /* attach video only if this is not a stinkpad or toshiba */ 936 if (!acpi_thinkpad_enabled && !acpi_toshiba_enabled && 937 !acpi_asus_enabled) 938 aml_find_node(&aml_root, "_DOS", acpi_foundvideo, sc); 939 940 /* create list of devices we want to query when APM come in */ 941 SLIST_INIT(&sc->sc_ac); 942 SLIST_INIT(&sc->sc_bat); 943 TAILQ_FOREACH(dev, &alldevs, dv_list) { 944 if (!strcmp(dev->dv_cfdata->cf_driver->cd_name, "acpiac")) { 945 ac = malloc(sizeof(*ac), M_DEVBUF, M_WAITOK | M_ZERO); 946 ac->aac_softc = (struct acpiac_softc *)dev; 947 SLIST_INSERT_HEAD(&sc->sc_ac, ac, aac_link); 948 } else if (!strcmp(dev->dv_cfdata->cf_driver->cd_name, "acpibat")) { 949 bat = malloc(sizeof(*bat), M_DEVBUF, M_WAITOK | M_ZERO); 950 bat->aba_softc = (struct acpibat_softc *)dev; 951 SLIST_INSERT_HEAD(&sc->sc_bat, bat, aba_link); 952 } 953 } 954 955 /* Setup threads */ 956 sc->sc_thread = malloc(sizeof(struct acpi_thread), M_DEVBUF, M_WAITOK); 957 sc->sc_thread->sc = sc; 958 sc->sc_thread->running = 1; 959 960 /* Enable PCI Power Management. */ 961 pci_dopm = 1; 962 963 acpi_attach_machdep(sc); 964 965 kthread_create_deferred(acpi_create_thread, sc); 966 #endif /* SMALL_KERNEL */ 967 } 968 969 int 970 acpi_submatch(struct device *parent, void *match, void *aux) 971 { 972 struct acpi_attach_args *aaa = (struct acpi_attach_args *)aux; 973 struct cfdata *cf = match; 974 975 if (aaa->aaa_table == NULL) 976 return (0); 977 return ((*cf->cf_attach->ca_match)(parent, match, aux)); 978 } 979 980 int 981 acpi_print(void *aux, const char *pnp) 982 { 983 struct acpi_attach_args *aa = aux; 984 985 if (pnp) { 986 if (aa->aaa_name) 987 printf("%s at %s", aa->aaa_name, pnp); 988 else 989 return (QUIET); 990 } 991 992 return (UNCONF); 993 } 994 995 struct acpi_q * 996 acpi_maptable(struct acpi_softc *sc, paddr_t addr, const char *sig, 997 const char *oem, const char *tbl, int flag) 998 { 999 static int tblid; 1000 struct acpi_mem_map handle; 1001 struct acpi_table_header *hdr; 1002 struct acpi_q *entry; 1003 size_t len; 1004 1005 /* Check if we can map address */ 1006 if (addr == 0) 1007 return NULL; 1008 if (acpi_map(addr, sizeof(*hdr), &handle)) 1009 return NULL; 1010 hdr = (struct acpi_table_header *)handle.va; 1011 len = hdr->length; 1012 acpi_unmap(&handle); 1013 1014 /* Validate length/checksum */ 1015 if (acpi_map(addr, len, &handle)) 1016 return NULL; 1017 hdr = (struct acpi_table_header *)handle.va; 1018 if (acpi_checksum(hdr, len)) { 1019 acpi_unmap(&handle); 1020 return NULL; 1021 } 1022 if ((sig && memcmp(sig, hdr->signature, 4)) || 1023 (oem && memcmp(oem, hdr->oemid, 6)) || 1024 (tbl && memcmp(tbl, hdr->oemtableid, 8))) { 1025 acpi_unmap(&handle); 1026 return NULL; 1027 } 1028 1029 /* Allocate copy */ 1030 entry = malloc(len + sizeof(*entry), M_DEVBUF, M_NOWAIT); 1031 if (entry != NULL) { 1032 memcpy(entry->q_data, handle.va, len); 1033 entry->q_table = entry->q_data; 1034 entry->q_id = ++tblid; 1035 1036 if (flag < 0) 1037 SIMPLEQ_INSERT_HEAD(&sc->sc_tables, entry, 1038 q_next); 1039 else if (flag > 0) 1040 SIMPLEQ_INSERT_TAIL(&sc->sc_tables, entry, 1041 q_next); 1042 } 1043 acpi_unmap(&handle); 1044 return entry; 1045 } 1046 1047 int 1048 acpi_loadtables(struct acpi_softc *sc, struct acpi_rsdp *rsdp) 1049 { 1050 struct acpi_q *sdt; 1051 int i, ntables; 1052 size_t len; 1053 1054 if (rsdp->rsdp_revision == 2 && rsdp->rsdp_xsdt) { 1055 struct acpi_xsdt *xsdt; 1056 1057 sdt = acpi_maptable(sc, rsdp->rsdp_xsdt, NULL, NULL, NULL, 0); 1058 if (sdt == NULL) { 1059 printf("couldn't map rsdt\n"); 1060 return (ENOMEM); 1061 } 1062 1063 xsdt = (struct acpi_xsdt *)sdt->q_data; 1064 len = xsdt->hdr.length; 1065 ntables = (len - sizeof(struct acpi_table_header)) / 1066 sizeof(xsdt->table_offsets[0]); 1067 1068 for (i = 0; i < ntables; i++) 1069 acpi_maptable(sc, xsdt->table_offsets[i], NULL, NULL, 1070 NULL, 1); 1071 1072 free(sdt, M_DEVBUF, 0); 1073 } else { 1074 struct acpi_rsdt *rsdt; 1075 1076 sdt = acpi_maptable(sc, rsdp->rsdp_rsdt, NULL, NULL, NULL, 0); 1077 if (sdt == NULL) { 1078 printf("couldn't map rsdt\n"); 1079 return (ENOMEM); 1080 } 1081 1082 rsdt = (struct acpi_rsdt *)sdt->q_data; 1083 len = rsdt->hdr.length; 1084 ntables = (len - sizeof(struct acpi_table_header)) / 1085 sizeof(rsdt->table_offsets[0]); 1086 1087 for (i = 0; i < ntables; i++) 1088 acpi_maptable(sc, rsdt->table_offsets[i], NULL, NULL, 1089 NULL, 1); 1090 1091 free(sdt, M_DEVBUF, 0); 1092 } 1093 1094 return (0); 1095 } 1096 1097 /* Read from power management register */ 1098 int 1099 acpi_read_pmreg(struct acpi_softc *sc, int reg, int offset) 1100 { 1101 bus_space_handle_t ioh; 1102 bus_size_t size; 1103 int regval; 1104 1105 /* Special cases: 1A/1B blocks can be OR'ed together */ 1106 switch (reg) { 1107 case ACPIREG_PM1_EN: 1108 return (acpi_read_pmreg(sc, ACPIREG_PM1A_EN, offset) | 1109 acpi_read_pmreg(sc, ACPIREG_PM1B_EN, offset)); 1110 case ACPIREG_PM1_STS: 1111 return (acpi_read_pmreg(sc, ACPIREG_PM1A_STS, offset) | 1112 acpi_read_pmreg(sc, ACPIREG_PM1B_STS, offset)); 1113 case ACPIREG_PM1_CNT: 1114 return (acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, offset) | 1115 acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, offset)); 1116 case ACPIREG_GPE_STS: 1117 dnprintf(50, "read GPE_STS offset: %.2x %.2x %.2x\n", offset, 1118 sc->sc_fadt->gpe0_blk_len>>1, sc->sc_fadt->gpe1_blk_len>>1); 1119 if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { 1120 reg = ACPIREG_GPE0_STS; 1121 } 1122 break; 1123 case ACPIREG_GPE_EN: 1124 dnprintf(50, "read GPE_EN offset: %.2x %.2x %.2x\n", 1125 offset, sc->sc_fadt->gpe0_blk_len>>1, 1126 sc->sc_fadt->gpe1_blk_len>>1); 1127 if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { 1128 reg = ACPIREG_GPE0_EN; 1129 } 1130 break; 1131 } 1132 1133 if (reg >= ACPIREG_MAXREG || sc->sc_pmregs[reg].size == 0) 1134 return (0); 1135 1136 regval = 0; 1137 ioh = sc->sc_pmregs[reg].ioh; 1138 size = sc->sc_pmregs[reg].size; 1139 if (size > sc->sc_pmregs[reg].access) 1140 size = sc->sc_pmregs[reg].access; 1141 1142 switch (size) { 1143 case 1: 1144 regval = bus_space_read_1(sc->sc_iot, ioh, offset); 1145 break; 1146 case 2: 1147 regval = bus_space_read_2(sc->sc_iot, ioh, offset); 1148 break; 1149 case 4: 1150 regval = bus_space_read_4(sc->sc_iot, ioh, offset); 1151 break; 1152 } 1153 1154 dnprintf(30, "acpi_readpm: %s = %.4x:%.4x %x\n", 1155 sc->sc_pmregs[reg].name, 1156 sc->sc_pmregs[reg].addr, offset, regval); 1157 return (regval); 1158 } 1159 1160 /* Write to power management register */ 1161 void 1162 acpi_write_pmreg(struct acpi_softc *sc, int reg, int offset, int regval) 1163 { 1164 bus_space_handle_t ioh; 1165 bus_size_t size; 1166 1167 /* Special cases: 1A/1B blocks can be written with same value */ 1168 switch (reg) { 1169 case ACPIREG_PM1_EN: 1170 acpi_write_pmreg(sc, ACPIREG_PM1A_EN, offset, regval); 1171 acpi_write_pmreg(sc, ACPIREG_PM1B_EN, offset, regval); 1172 break; 1173 case ACPIREG_PM1_STS: 1174 acpi_write_pmreg(sc, ACPIREG_PM1A_STS, offset, regval); 1175 acpi_write_pmreg(sc, ACPIREG_PM1B_STS, offset, regval); 1176 break; 1177 case ACPIREG_PM1_CNT: 1178 acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, offset, regval); 1179 acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, offset, regval); 1180 break; 1181 case ACPIREG_GPE_STS: 1182 dnprintf(50, "write GPE_STS offset: %.2x %.2x %.2x %.2x\n", 1183 offset, sc->sc_fadt->gpe0_blk_len>>1, 1184 sc->sc_fadt->gpe1_blk_len>>1, regval); 1185 if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { 1186 reg = ACPIREG_GPE0_STS; 1187 } 1188 break; 1189 case ACPIREG_GPE_EN: 1190 dnprintf(50, "write GPE_EN offset: %.2x %.2x %.2x %.2x\n", 1191 offset, sc->sc_fadt->gpe0_blk_len>>1, 1192 sc->sc_fadt->gpe1_blk_len>>1, regval); 1193 if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { 1194 reg = ACPIREG_GPE0_EN; 1195 } 1196 break; 1197 } 1198 1199 /* All special case return here */ 1200 if (reg >= ACPIREG_MAXREG) 1201 return; 1202 1203 ioh = sc->sc_pmregs[reg].ioh; 1204 size = sc->sc_pmregs[reg].size; 1205 if (size > sc->sc_pmregs[reg].access) 1206 size = sc->sc_pmregs[reg].access; 1207 1208 switch (size) { 1209 case 1: 1210 bus_space_write_1(sc->sc_iot, ioh, offset, regval); 1211 break; 1212 case 2: 1213 bus_space_write_2(sc->sc_iot, ioh, offset, regval); 1214 break; 1215 case 4: 1216 bus_space_write_4(sc->sc_iot, ioh, offset, regval); 1217 break; 1218 } 1219 1220 dnprintf(30, "acpi_writepm: %s = %.4x:%.4x %x\n", 1221 sc->sc_pmregs[reg].name, sc->sc_pmregs[reg].addr, offset, regval); 1222 } 1223 1224 /* Map Power Management registers */ 1225 void 1226 acpi_map_pmregs(struct acpi_softc *sc) 1227 { 1228 bus_addr_t addr; 1229 bus_size_t size, access; 1230 const char *name; 1231 int reg; 1232 1233 for (reg = 0; reg < ACPIREG_MAXREG; reg++) { 1234 size = 0; 1235 access = 0; 1236 switch (reg) { 1237 case ACPIREG_SMICMD: 1238 name = "smi"; 1239 size = access = 1; 1240 addr = sc->sc_fadt->smi_cmd; 1241 break; 1242 case ACPIREG_PM1A_STS: 1243 case ACPIREG_PM1A_EN: 1244 name = "pm1a_sts"; 1245 size = sc->sc_fadt->pm1_evt_len >> 1; 1246 addr = sc->sc_fadt->pm1a_evt_blk; 1247 access = 2; 1248 if (reg == ACPIREG_PM1A_EN && addr) { 1249 addr += size; 1250 name = "pm1a_en"; 1251 } 1252 break; 1253 case ACPIREG_PM1A_CNT: 1254 name = "pm1a_cnt"; 1255 size = sc->sc_fadt->pm1_cnt_len; 1256 addr = sc->sc_fadt->pm1a_cnt_blk; 1257 access = 2; 1258 break; 1259 case ACPIREG_PM1B_STS: 1260 case ACPIREG_PM1B_EN: 1261 name = "pm1b_sts"; 1262 size = sc->sc_fadt->pm1_evt_len >> 1; 1263 addr = sc->sc_fadt->pm1b_evt_blk; 1264 access = 2; 1265 if (reg == ACPIREG_PM1B_EN && addr) { 1266 addr += size; 1267 name = "pm1b_en"; 1268 } 1269 break; 1270 case ACPIREG_PM1B_CNT: 1271 name = "pm1b_cnt"; 1272 size = sc->sc_fadt->pm1_cnt_len; 1273 addr = sc->sc_fadt->pm1b_cnt_blk; 1274 access = 2; 1275 break; 1276 case ACPIREG_PM2_CNT: 1277 name = "pm2_cnt"; 1278 size = sc->sc_fadt->pm2_cnt_len; 1279 addr = sc->sc_fadt->pm2_cnt_blk; 1280 access = size; 1281 break; 1282 #if 0 1283 case ACPIREG_PM_TMR: 1284 /* Allocated in acpitimer */ 1285 name = "pm_tmr"; 1286 size = sc->sc_fadt->pm_tmr_len; 1287 addr = sc->sc_fadt->pm_tmr_blk; 1288 access = 4; 1289 break; 1290 #endif 1291 case ACPIREG_GPE0_STS: 1292 case ACPIREG_GPE0_EN: 1293 name = "gpe0_sts"; 1294 size = sc->sc_fadt->gpe0_blk_len >> 1; 1295 addr = sc->sc_fadt->gpe0_blk; 1296 access = 1; 1297 1298 dnprintf(20, "gpe0 block len : %x\n", 1299 sc->sc_fadt->gpe0_blk_len >> 1); 1300 dnprintf(20, "gpe0 block addr: %x\n", 1301 sc->sc_fadt->gpe0_blk); 1302 if (reg == ACPIREG_GPE0_EN && addr) { 1303 addr += size; 1304 name = "gpe0_en"; 1305 } 1306 break; 1307 case ACPIREG_GPE1_STS: 1308 case ACPIREG_GPE1_EN: 1309 name = "gpe1_sts"; 1310 size = sc->sc_fadt->gpe1_blk_len >> 1; 1311 addr = sc->sc_fadt->gpe1_blk; 1312 access = 1; 1313 1314 dnprintf(20, "gpe1 block len : %x\n", 1315 sc->sc_fadt->gpe1_blk_len >> 1); 1316 dnprintf(20, "gpe1 block addr: %x\n", 1317 sc->sc_fadt->gpe1_blk); 1318 if (reg == ACPIREG_GPE1_EN && addr) { 1319 addr += size; 1320 name = "gpe1_en"; 1321 } 1322 break; 1323 } 1324 if (size && addr) { 1325 dnprintf(50, "mapping: %.4lx %.4lx %s\n", 1326 addr, size, name); 1327 1328 /* Size and address exist; map register space */ 1329 bus_space_map(sc->sc_iot, addr, size, 0, 1330 &sc->sc_pmregs[reg].ioh); 1331 1332 sc->sc_pmregs[reg].name = name; 1333 sc->sc_pmregs[reg].size = size; 1334 sc->sc_pmregs[reg].addr = addr; 1335 sc->sc_pmregs[reg].access = min(access, 4); 1336 } 1337 } 1338 } 1339 1340 int 1341 acpi_enable(struct acpi_softc *sc) 1342 { 1343 int idx; 1344 1345 acpi_write_pmreg(sc, ACPIREG_SMICMD, 0, sc->sc_fadt->acpi_enable); 1346 idx = 0; 1347 do { 1348 if (idx++ > ACPIEN_RETRIES) { 1349 return ETIMEDOUT; 1350 } 1351 } while (!(acpi_read_pmreg(sc, ACPIREG_PM1_CNT, 0) & ACPI_PM1_SCI_EN)); 1352 1353 return 0; 1354 } 1355 1356 void 1357 acpi_init_states(struct acpi_softc *sc) 1358 { 1359 struct aml_value res; 1360 char name[8]; 1361 int i; 1362 1363 printf("\n%s: sleep states", DEVNAME(sc)); 1364 for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) { 1365 snprintf(name, sizeof(name), "_S%d_", i); 1366 sc->sc_sleeptype[i].slp_typa = -1; 1367 sc->sc_sleeptype[i].slp_typb = -1; 1368 if (aml_evalname(sc, &aml_root, name, 0, NULL, &res) == 0) { 1369 if (res.type == AML_OBJTYPE_PACKAGE) { 1370 sc->sc_sleeptype[i].slp_typa = aml_val2int(res.v_package[0]); 1371 sc->sc_sleeptype[i].slp_typb = aml_val2int(res.v_package[1]); 1372 printf(" S%d", i); 1373 } 1374 aml_freevalue(&res); 1375 } 1376 } 1377 } 1378 1379 /* ACPI Workqueue support */ 1380 SIMPLEQ_HEAD(,acpi_taskq) acpi_taskq = 1381 SIMPLEQ_HEAD_INITIALIZER(acpi_taskq); 1382 1383 void 1384 acpi_addtask(struct acpi_softc *sc, void (*handler)(void *, int), 1385 void *arg0, int arg1) 1386 { 1387 struct acpi_taskq *wq; 1388 int s; 1389 1390 wq = malloc(sizeof(*wq), M_DEVBUF, M_ZERO | M_NOWAIT); 1391 if (wq == NULL) 1392 return; 1393 wq->handler = handler; 1394 wq->arg0 = arg0; 1395 wq->arg1 = arg1; 1396 1397 s = spltty(); 1398 SIMPLEQ_INSERT_TAIL(&acpi_taskq, wq, next); 1399 splx(s); 1400 } 1401 1402 int 1403 acpi_dotask(struct acpi_softc *sc) 1404 { 1405 struct acpi_taskq *wq; 1406 int s; 1407 1408 s = spltty(); 1409 if (SIMPLEQ_EMPTY(&acpi_taskq)) { 1410 splx(s); 1411 1412 /* we don't have anything to do */ 1413 return (0); 1414 } 1415 wq = SIMPLEQ_FIRST(&acpi_taskq); 1416 SIMPLEQ_REMOVE_HEAD(&acpi_taskq, next); 1417 splx(s); 1418 1419 wq->handler(wq->arg0, wq->arg1); 1420 1421 free(wq, M_DEVBUF, 0); 1422 1423 /* We did something */ 1424 return (1); 1425 } 1426 1427 #ifndef SMALL_KERNEL 1428 int 1429 is_ata(struct aml_node *node) 1430 { 1431 return (aml_searchname(node, "_GTM") != NULL || 1432 aml_searchname(node, "_GTF") != NULL || 1433 aml_searchname(node, "_STM") != NULL || 1434 aml_searchname(node, "_SDD") != NULL); 1435 } 1436 1437 int 1438 is_ejectable(struct aml_node *node) 1439 { 1440 return (aml_searchname(node, "_EJ0") != NULL); 1441 } 1442 1443 int 1444 is_ejectable_bay(struct aml_node *node) 1445 { 1446 return ((is_ata(node) || is_ata(node->parent)) && is_ejectable(node)); 1447 } 1448 1449 #if NWD > 0 1450 int 1451 acpiide_notify(struct aml_node *node, int ntype, void *arg) 1452 { 1453 struct idechnl *ide = arg; 1454 struct acpi_softc *sc = ide->sc; 1455 struct pciide_softc *wsc; 1456 struct device *dev; 1457 int b,d,f; 1458 int64_t sta; 1459 1460 if (aml_evalinteger(sc, node, "_STA", 0, NULL, &sta) != 0) 1461 return (0); 1462 1463 dnprintf(10, "IDE notify! %s %d status:%llx\n", aml_nodename(node), 1464 ntype, sta); 1465 1466 /* Walk device list looking for IDE device match */ 1467 TAILQ_FOREACH(dev, &alldevs, dv_list) { 1468 if (strcmp(dev->dv_cfdata->cf_driver->cd_name, "pciide")) 1469 continue; 1470 1471 wsc = (struct pciide_softc *)dev; 1472 pci_decompose_tag(NULL, wsc->sc_tag, &b, &d, &f); 1473 if (b != ACPI_PCI_BUS(ide->addr) || 1474 d != ACPI_PCI_DEV(ide->addr) || 1475 f != ACPI_PCI_FN(ide->addr)) 1476 continue; 1477 dnprintf(10, "Found pciide: %s %x.%x.%x channel:%llx\n", 1478 dev->dv_xname, b,d,f, ide->chnl); 1479 1480 if (sta == 0 && ide->sta) 1481 wdcdetach( 1482 &wsc->pciide_channels[ide->chnl].wdc_channel, 0); 1483 else if (sta && !ide->sta) 1484 wdcattach( 1485 &wsc->pciide_channels[ide->chnl].wdc_channel); 1486 ide->sta = sta; 1487 } 1488 return (0); 1489 } 1490 1491 int 1492 acpi_foundide(struct aml_node *node, void *arg) 1493 { 1494 struct acpi_softc *sc = arg; 1495 struct aml_node *pp; 1496 struct idechnl *ide; 1497 union amlpci_t pi; 1498 int lvl; 1499 1500 /* Check if this is an ejectable bay */ 1501 if (!is_ejectable_bay(node)) 1502 return (0); 1503 1504 ide = malloc(sizeof(struct idechnl), M_DEVBUF, M_NOWAIT | M_ZERO); 1505 ide->sc = sc; 1506 1507 /* GTM/GTF can be at 2/3 levels: pciX.ideX.channelX[.driveX] */ 1508 lvl = 0; 1509 for (pp=node->parent; pp; pp=pp->parent) { 1510 lvl++; 1511 if (aml_searchname(pp, "_HID")) 1512 break; 1513 } 1514 1515 /* Get PCI address and channel */ 1516 if (lvl == 3) { 1517 aml_evalinteger(sc, node->parent, "_ADR", 0, NULL, 1518 &ide->chnl); 1519 aml_rdpciaddr(node->parent->parent, &pi); 1520 ide->addr = pi.addr; 1521 } else if (lvl == 4) { 1522 aml_evalinteger(sc, node->parent->parent, "_ADR", 0, NULL, 1523 &ide->chnl); 1524 aml_rdpciaddr(node->parent->parent->parent, &pi); 1525 ide->addr = pi.addr; 1526 } 1527 dnprintf(10, "%s %llx channel:%llx\n", 1528 aml_nodename(node), ide->addr, ide->chnl); 1529 1530 aml_evalinteger(sc, node, "_STA", 0, NULL, &ide->sta); 1531 dnprintf(10, "Got Initial STA: %llx\n", ide->sta); 1532 1533 aml_register_notify(node, "acpiide", acpiide_notify, ide, 0); 1534 return (0); 1535 } 1536 #endif /* NWD > 0 */ 1537 1538 void 1539 acpi_reset(void) 1540 { 1541 u_int32_t reset_as, reset_len; 1542 u_int32_t value; 1543 struct acpi_softc *sc = acpi_softc; 1544 struct acpi_fadt *fadt = sc->sc_fadt; 1545 1546 if (acpi_enabled == 0) 1547 return; 1548 1549 /* 1550 * RESET_REG_SUP is not properly set in some implementations, 1551 * but not testing against it breaks more machines than it fixes 1552 */ 1553 if (fadt->hdr_revision <= 1 || 1554 !(fadt->flags & FADT_RESET_REG_SUP) || fadt->reset_reg.address == 0) 1555 return; 1556 1557 value = fadt->reset_value; 1558 1559 reset_as = fadt->reset_reg.register_bit_width / 8; 1560 if (reset_as == 0) 1561 reset_as = 1; 1562 1563 reset_len = fadt->reset_reg.access_size; 1564 if (reset_len == 0) 1565 reset_len = reset_as; 1566 1567 acpi_gasio(sc, ACPI_IOWRITE, 1568 fadt->reset_reg.address_space_id, 1569 fadt->reset_reg.address, reset_as, reset_len, &value); 1570 1571 delay(100000); 1572 } 1573 1574 void 1575 acpi_gpe_task(void *arg0, int gpe) 1576 { 1577 struct acpi_softc *sc = acpi_softc; 1578 struct gpe_block *pgpe = &sc->gpe_table[gpe]; 1579 1580 dnprintf(10, "handle gpe: %x\n", gpe); 1581 if (pgpe->handler && pgpe->active) { 1582 pgpe->active = 0; 1583 pgpe->handler(sc, gpe, pgpe->arg); 1584 } 1585 } 1586 1587 void 1588 acpi_pbtn_task(void *arg0, int dummy) 1589 { 1590 struct acpi_softc *sc = arg0; 1591 uint16_t en; 1592 int s; 1593 1594 dnprintf(1,"power button pressed\n"); 1595 1596 /* Reset the latch and re-enable the GPE */ 1597 s = spltty(); 1598 en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); 1599 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, 1600 en | ACPI_PM1_PWRBTN_EN); 1601 splx(s); 1602 1603 acpi_addtask(sc, acpi_powerdown_task, sc, 0); 1604 } 1605 1606 void 1607 acpi_sbtn_task(void *arg0, int dummy) 1608 { 1609 struct acpi_softc *sc = arg0; 1610 uint16_t en; 1611 int s; 1612 1613 dnprintf(1,"sleep button pressed\n"); 1614 aml_notify_dev(ACPI_DEV_SBD, 0x80); 1615 1616 /* Reset the latch and re-enable the GPE */ 1617 s = spltty(); 1618 en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); 1619 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, 1620 en | ACPI_PM1_SLPBTN_EN); 1621 splx(s); 1622 } 1623 1624 void 1625 acpi_powerdown_task(void *arg0, int dummy) 1626 { 1627 extern int allowpowerdown; 1628 1629 if (allowpowerdown == 1) { 1630 allowpowerdown = 0; 1631 prsignal(initprocess, SIGUSR2); 1632 } 1633 } 1634 1635 void 1636 acpi_sleep_task(void *arg0, int sleepmode) 1637 { 1638 struct acpi_softc *sc = arg0; 1639 struct acpi_ac *ac; 1640 struct acpi_bat *bat; 1641 1642 /* System goes to sleep here.. */ 1643 acpi_sleep_state(sc, sleepmode); 1644 1645 /* AC and battery information needs refreshing */ 1646 SLIST_FOREACH(ac, &sc->sc_ac, aac_link) 1647 aml_notify(ac->aac_softc->sc_devnode, 1648 0x80); 1649 SLIST_FOREACH(bat, &sc->sc_bat, aba_link) 1650 aml_notify(bat->aba_softc->sc_devnode, 1651 0x80); 1652 } 1653 1654 int 1655 acpi_interrupt(void *arg) 1656 { 1657 struct acpi_softc *sc = (struct acpi_softc *)arg; 1658 u_int32_t processed = 0, idx, jdx; 1659 u_int16_t sts, en; 1660 1661 dnprintf(40, "ACPI Interrupt\n"); 1662 for (idx = 0; idx < sc->sc_lastgpe; idx += 8) { 1663 sts = acpi_read_pmreg(sc, ACPIREG_GPE_STS, idx>>3); 1664 en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, idx>>3); 1665 if (en & sts) { 1666 dnprintf(10, "GPE block: %.2x %.2x %.2x\n", idx, sts, 1667 en); 1668 /* Mask the GPE until it is serviced */ 1669 acpi_write_pmreg(sc, ACPIREG_GPE_EN, idx>>3, en & ~sts); 1670 for (jdx = 0; jdx < 8; jdx++) { 1671 if (en & sts & (1L << jdx)) { 1672 /* Signal this GPE */ 1673 sc->gpe_table[idx+jdx].active = 1; 1674 dnprintf(10, "queue gpe: %x\n", idx+jdx); 1675 acpi_addtask(sc, acpi_gpe_task, NULL, idx+jdx); 1676 1677 /* 1678 * Edge interrupts need their STS bits 1679 * cleared now. Level interrupts will 1680 * have their STS bits cleared just 1681 * before they are re-enabled. 1682 */ 1683 if (sc->gpe_table[idx+jdx].edge) 1684 acpi_write_pmreg(sc, 1685 ACPIREG_GPE_STS, idx>>3, 1686 1L << jdx); 1687 processed = 1; 1688 } 1689 } 1690 } 1691 } 1692 1693 sts = acpi_read_pmreg(sc, ACPIREG_PM1_STS, 0); 1694 en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); 1695 if (sts & en) { 1696 dnprintf(10,"GEN interrupt: %.4x\n", sts & en); 1697 sts &= en; 1698 if (sts & ACPI_PM1_PWRBTN_STS) { 1699 /* Mask and acknowledge */ 1700 en &= ~ACPI_PM1_PWRBTN_EN; 1701 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en); 1702 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, 1703 ACPI_PM1_PWRBTN_STS); 1704 sts &= ~ACPI_PM1_PWRBTN_STS; 1705 1706 acpi_addtask(sc, acpi_pbtn_task, sc, 0); 1707 } 1708 if (sts & ACPI_PM1_SLPBTN_STS) { 1709 /* Mask and acknowledge */ 1710 en &= ~ACPI_PM1_SLPBTN_EN; 1711 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en); 1712 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, 1713 ACPI_PM1_SLPBTN_STS); 1714 sts &= ~ACPI_PM1_SLPBTN_STS; 1715 1716 acpi_addtask(sc, acpi_sbtn_task, sc, 0); 1717 } 1718 if (sts) { 1719 printf("%s: PM1 stuck (en 0x%x st 0x%x), clearing\n", 1720 sc->sc_dev.dv_xname, en, sts); 1721 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en & ~sts); 1722 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, sts); 1723 } 1724 processed = 1; 1725 } 1726 1727 if (processed) { 1728 acpi_wakeup(sc); 1729 } 1730 1731 return (processed); 1732 } 1733 1734 int 1735 acpi_add_device(struct aml_node *node, void *arg) 1736 { 1737 static int nacpicpus = 0; 1738 struct device *self = arg; 1739 struct acpi_softc *sc = arg; 1740 struct acpi_attach_args aaa; 1741 #ifdef MULTIPROCESSOR 1742 struct aml_value res; 1743 int proc_id = -1; 1744 #endif 1745 1746 memset(&aaa, 0, sizeof(aaa)); 1747 aaa.aaa_node = node; 1748 aaa.aaa_iot = sc->sc_iot; 1749 aaa.aaa_memt = sc->sc_memt; 1750 if (node == NULL || node->value == NULL) 1751 return 0; 1752 1753 switch (node->value->type) { 1754 case AML_OBJTYPE_PROCESSOR: 1755 if (nacpicpus >= ncpus) 1756 return 0; 1757 #ifdef MULTIPROCESSOR 1758 if (aml_evalnode(sc, aaa.aaa_node, 0, NULL, &res) == 0) { 1759 if (res.type == AML_OBJTYPE_PROCESSOR) 1760 proc_id = res.v_processor.proc_id; 1761 aml_freevalue(&res); 1762 } 1763 if (proc_id < -1 || proc_id >= LAPIC_MAP_SIZE || 1764 (acpi_lapic_flags[proc_id] & ACPI_PROC_ENABLE) == 0) 1765 return 0; 1766 #endif 1767 nacpicpus++; 1768 1769 aaa.aaa_name = "acpicpu"; 1770 break; 1771 case AML_OBJTYPE_THERMZONE: 1772 aaa.aaa_name = "acpitz"; 1773 break; 1774 case AML_OBJTYPE_POWERRSRC: 1775 aaa.aaa_name = "acpipwrres"; 1776 break; 1777 default: 1778 return 0; 1779 } 1780 config_found(self, &aaa, acpi_print); 1781 return 0; 1782 } 1783 1784 void 1785 acpi_enable_onegpe(struct acpi_softc *sc, int gpe) 1786 { 1787 uint8_t mask, en; 1788 1789 /* Read enabled register */ 1790 mask = (1L << (gpe & 7)); 1791 en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, gpe>>3); 1792 dnprintf(50, "enabling GPE %.2x (current: %sabled) %.2x\n", 1793 gpe, (en & mask) ? "en" : "dis", en); 1794 acpi_write_pmreg(sc, ACPIREG_GPE_EN, gpe>>3, en | mask); 1795 } 1796 1797 /* Clear all GPEs */ 1798 void 1799 acpi_disable_allgpes(struct acpi_softc *sc) 1800 { 1801 int idx; 1802 1803 for (idx = 0; idx < sc->sc_lastgpe; idx += 8) { 1804 acpi_write_pmreg(sc, ACPIREG_GPE_EN, idx >> 3, 0); 1805 acpi_write_pmreg(sc, ACPIREG_GPE_STS, idx >> 3, -1); 1806 } 1807 } 1808 1809 /* Enable runtime GPEs */ 1810 void 1811 acpi_enable_rungpes(struct acpi_softc *sc) 1812 { 1813 int idx; 1814 1815 for (idx = 0; idx < sc->sc_lastgpe; idx++) 1816 if (sc->gpe_table[idx].handler) 1817 acpi_enable_onegpe(sc, idx); 1818 } 1819 1820 /* Enable wakeup GPEs */ 1821 void 1822 acpi_enable_wakegpes(struct acpi_softc *sc, int state) 1823 { 1824 struct acpi_wakeq *wentry; 1825 1826 SIMPLEQ_FOREACH(wentry, &sc->sc_wakedevs, q_next) { 1827 dnprintf(10, "%.4s(S%d) gpe %.2x\n", wentry->q_node->name, 1828 wentry->q_state, 1829 wentry->q_gpe); 1830 if (state <= wentry->q_state) 1831 acpi_enable_onegpe(sc, wentry->q_gpe); 1832 } 1833 } 1834 1835 int 1836 acpi_set_gpehandler(struct acpi_softc *sc, int gpe, int (*handler) 1837 (struct acpi_softc *, int, void *), void *arg, int edge) 1838 { 1839 struct gpe_block *ptbl; 1840 1841 ptbl = acpi_find_gpe(sc, gpe); 1842 if (ptbl == NULL || handler == NULL) 1843 return -EINVAL; 1844 if (ptbl->handler != NULL) { 1845 dnprintf(10, "error: GPE %.2x already enabled\n", gpe); 1846 return -EBUSY; 1847 } 1848 dnprintf(50, "Adding GPE handler %.2x (%s)\n", gpe, edge ? "edge" : "level"); 1849 ptbl->handler = handler; 1850 ptbl->arg = arg; 1851 ptbl->edge = edge; 1852 1853 return (0); 1854 } 1855 1856 int 1857 acpi_gpe(struct acpi_softc *sc, int gpe, void *arg) 1858 { 1859 struct aml_node *node = arg; 1860 uint8_t mask, en; 1861 1862 dnprintf(10, "handling GPE %.2x\n", gpe); 1863 aml_evalnode(sc, node, 0, NULL, NULL); 1864 1865 mask = (1L << (gpe & 7)); 1866 if (!sc->gpe_table[gpe].edge) 1867 acpi_write_pmreg(sc, ACPIREG_GPE_STS, gpe>>3, mask); 1868 en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, gpe>>3); 1869 acpi_write_pmreg(sc, ACPIREG_GPE_EN, gpe>>3, en | mask); 1870 return (0); 1871 } 1872 1873 /* Discover Devices that can wakeup the system 1874 * _PRW returns a package 1875 * pkg[0] = integer (FADT gpe bit) or package (gpe block,gpe bit) 1876 * pkg[1] = lowest sleep state 1877 * pkg[2+] = power resource devices (optional) 1878 * 1879 * To enable wakeup devices: 1880 * Evaluate _ON method in each power resource device 1881 * Evaluate _PSW method 1882 */ 1883 int 1884 acpi_foundprw(struct aml_node *node, void *arg) 1885 { 1886 struct acpi_softc *sc = arg; 1887 struct acpi_wakeq *wq; 1888 1889 wq = malloc(sizeof(struct acpi_wakeq), M_DEVBUF, M_NOWAIT | M_ZERO); 1890 if (wq == NULL) 1891 return 0; 1892 1893 wq->q_wakepkg = malloc(sizeof(struct aml_value), M_DEVBUF, 1894 M_NOWAIT | M_ZERO); 1895 if (wq->q_wakepkg == NULL) { 1896 free(wq, M_DEVBUF, 0); 1897 return 0; 1898 } 1899 dnprintf(10, "Found _PRW (%s)\n", node->parent->name); 1900 aml_evalnode(sc, node, 0, NULL, wq->q_wakepkg); 1901 wq->q_node = node->parent; 1902 wq->q_gpe = -1; 1903 1904 /* Get GPE of wakeup device, and lowest sleep level */ 1905 if (wq->q_wakepkg->type == AML_OBJTYPE_PACKAGE && 1906 wq->q_wakepkg->length >= 2) { 1907 if (wq->q_wakepkg->v_package[0]->type == AML_OBJTYPE_INTEGER) 1908 wq->q_gpe = wq->q_wakepkg->v_package[0]->v_integer; 1909 if (wq->q_wakepkg->v_package[1]->type == AML_OBJTYPE_INTEGER) 1910 wq->q_state = wq->q_wakepkg->v_package[1]->v_integer; 1911 } 1912 SIMPLEQ_INSERT_TAIL(&sc->sc_wakedevs, wq, q_next); 1913 return 0; 1914 } 1915 1916 struct gpe_block * 1917 acpi_find_gpe(struct acpi_softc *sc, int gpe) 1918 { 1919 if (gpe >= sc->sc_lastgpe) 1920 return NULL; 1921 return &sc->gpe_table[gpe]; 1922 } 1923 1924 void 1925 acpi_init_gpes(struct acpi_softc *sc) 1926 { 1927 struct aml_node *gpe; 1928 char name[12]; 1929 int idx, ngpe; 1930 1931 sc->sc_lastgpe = sc->sc_fadt->gpe0_blk_len << 2; 1932 if (sc->sc_fadt->gpe1_blk_len) { 1933 } 1934 dnprintf(50, "Last GPE: %.2x\n", sc->sc_lastgpe); 1935 1936 /* Allocate GPE table */ 1937 sc->gpe_table = malloc(sc->sc_lastgpe * sizeof(struct gpe_block), 1938 M_DEVBUF, M_WAITOK | M_ZERO); 1939 1940 ngpe = 0; 1941 1942 /* Clear GPE status */ 1943 acpi_disable_allgpes(sc); 1944 for (idx = 0; idx < sc->sc_lastgpe; idx++) { 1945 /* Search Level-sensitive GPES */ 1946 snprintf(name, sizeof(name), "\\_GPE._L%.2X", idx); 1947 gpe = aml_searchname(&aml_root, name); 1948 if (gpe != NULL) 1949 acpi_set_gpehandler(sc, idx, acpi_gpe, gpe, 0); 1950 if (gpe == NULL) { 1951 /* Search Edge-sensitive GPES */ 1952 snprintf(name, sizeof(name), "\\_GPE._E%.2X", idx); 1953 gpe = aml_searchname(&aml_root, name); 1954 if (gpe != NULL) 1955 acpi_set_gpehandler(sc, idx, acpi_gpe, gpe, 1); 1956 } 1957 } 1958 aml_find_node(&aml_root, "_PRW", acpi_foundprw, sc); 1959 sc->sc_maxgpe = ngpe; 1960 } 1961 1962 void 1963 acpi_init_pm(struct acpi_softc *sc) 1964 { 1965 sc->sc_tts = aml_searchname(&aml_root, "_TTS"); 1966 sc->sc_pts = aml_searchname(&aml_root, "_PTS"); 1967 sc->sc_wak = aml_searchname(&aml_root, "_WAK"); 1968 sc->sc_bfs = aml_searchname(&aml_root, "_BFS"); 1969 sc->sc_gts = aml_searchname(&aml_root, "_GTS"); 1970 sc->sc_sst = aml_searchname(&aml_root, "_SI_._SST"); 1971 } 1972 1973 void 1974 acpi_sleep_pm(struct acpi_softc *sc, int state) 1975 { 1976 uint16_t rega, regb, regra, regrb; 1977 int retry = 0; 1978 1979 disable_intr(); 1980 1981 /* Clear WAK_STS bit */ 1982 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_WAK_STS); 1983 1984 /* Disable BM arbitration at deep sleep and beyond */ 1985 if (state >= ACPI_STATE_S3 && 1986 sc->sc_fadt->pm2_cnt_blk && sc->sc_fadt->pm2_cnt_len) 1987 acpi_write_pmreg(sc, ACPIREG_PM2_CNT, 0, ACPI_PM2_ARB_DIS); 1988 1989 /* Write SLP_TYPx values */ 1990 rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0); 1991 regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, 0); 1992 rega &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN); 1993 regb &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN); 1994 rega |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typa); 1995 regb |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typb); 1996 acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega); 1997 acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb); 1998 1999 /* Loop on WAK_STS, setting the SLP_EN bits once in a while */ 2000 rega |= ACPI_PM1_SLP_EN; 2001 regb |= ACPI_PM1_SLP_EN; 2002 while (1) { 2003 if (retry == 0) { 2004 acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega); 2005 acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb); 2006 } 2007 retry = (retry + 1) % 100000; 2008 2009 regra = acpi_read_pmreg(sc, ACPIREG_PM1A_STS, 0); 2010 regrb = acpi_read_pmreg(sc, ACPIREG_PM1B_STS, 0); 2011 if ((regra & ACPI_PM1_WAK_STS) || 2012 (regrb & ACPI_PM1_WAK_STS)) 2013 break; 2014 } 2015 } 2016 2017 void 2018 acpi_resume_pm(struct acpi_softc *sc, int fromstate) 2019 { 2020 uint16_t rega, regb, en; 2021 2022 /* Write SLP_TYPx values */ 2023 rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0); 2024 regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, 0); 2025 rega &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN); 2026 regb &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN); 2027 rega |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[ACPI_STATE_S0].slp_typa); 2028 regb |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[ACPI_STATE_S0].slp_typb); 2029 acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega); 2030 acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb); 2031 2032 /* Force SCI_EN on resume to fix horribly broken machines */ 2033 acpi_write_pmreg(sc, ACPIREG_PM1_CNT, 0, ACPI_PM1_SCI_EN); 2034 2035 /* Clear fixed event status */ 2036 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_ALL_STS); 2037 2038 /* acpica-reference.pdf page 148 says do not call _BFS */ 2039 /* 1st resume AML step: _BFS(fromstate) */ 2040 aml_node_setval(sc, sc->sc_bfs, fromstate); 2041 2042 /* Enable runtime GPEs */ 2043 acpi_disable_allgpes(sc); 2044 acpi_enable_rungpes(sc); 2045 2046 acpi_indicator(sc, ACPI_SST_WAKING); 2047 2048 /* 2nd resume AML step: _WAK(fromstate) */ 2049 aml_node_setval(sc, sc->sc_wak, fromstate); 2050 2051 /* Clear WAK_STS bit */ 2052 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_WAK_STS); 2053 2054 en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); 2055 if (!(sc->sc_fadt->flags & FADT_PWR_BUTTON)) 2056 en |= ACPI_PM1_PWRBTN_EN; 2057 if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON)) 2058 en |= ACPI_PM1_SLPBTN_EN; 2059 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en); 2060 2061 /* 2062 * If PM2 exists, re-enable BM arbitration (reportedly some 2063 * BIOS forget to) 2064 */ 2065 if (sc->sc_fadt->pm2_cnt_blk && sc->sc_fadt->pm2_cnt_len) { 2066 rega = acpi_read_pmreg(sc, ACPIREG_PM2_CNT, 0); 2067 rega &= ~ACPI_PM2_ARB_DIS; 2068 acpi_write_pmreg(sc, ACPIREG_PM2_CNT, 0, rega); 2069 } 2070 } 2071 2072 /* Set the indicator light to some state */ 2073 void 2074 acpi_indicator(struct acpi_softc *sc, int led_state) 2075 { 2076 static int save_led_state = -1; 2077 2078 if (save_led_state != led_state) { 2079 aml_node_setval(sc, sc->sc_sst, led_state); 2080 save_led_state = led_state; 2081 } 2082 } 2083 2084 int 2085 acpi_sleep_state(struct acpi_softc *sc, int state) 2086 { 2087 struct device *mainbus = device_mainbus(); 2088 int error = ENXIO; 2089 int s; 2090 2091 switch (state) { 2092 case ACPI_STATE_S0: 2093 return (0); 2094 case ACPI_STATE_S1: 2095 return (EOPNOTSUPP); 2096 case ACPI_STATE_S5: /* only sleep states handled here */ 2097 return (EOPNOTSUPP); 2098 } 2099 2100 if (sc->sc_sleeptype[state].slp_typa == -1 || 2101 sc->sc_sleeptype[state].slp_typb == -1) { 2102 printf("%s: state S%d unavailable\n", 2103 sc->sc_dev.dv_xname, state); 2104 return (EOPNOTSUPP); 2105 } 2106 2107 /* 1st suspend AML step: _TTS(tostate) */ 2108 if (aml_node_setval(sc, sc->sc_tts, state) != 0) 2109 goto fail_tts; 2110 acpi_indicator(sc, ACPI_SST_WAKING); /* blink */ 2111 2112 #if NWSDISPLAY > 0 2113 wsdisplay_suspend(); 2114 #endif /* NWSDISPLAY > 0 */ 2115 2116 if (config_suspend(mainbus, DVACT_QUIESCE)) 2117 goto fail_quiesce; 2118 2119 #ifdef HIBERNATE 2120 if (state == ACPI_STATE_S4) { 2121 uvmpd_hibernate(); 2122 hibernate_suspend_bufcache(); 2123 } 2124 #endif /* HIBERNATE */ 2125 2126 bufq_quiesce(); 2127 2128 #ifdef MULTIPROCESSOR 2129 acpi_sleep_mp(); 2130 #endif 2131 2132 resettodr(); 2133 2134 s = splhigh(); 2135 disable_intr(); /* PSL_I for resume; PIC/APIC broken until repair */ 2136 cold = 1; /* Force other code to delay() instead of tsleep() */ 2137 2138 if (config_suspend(mainbus, DVACT_SUSPEND) != 0) 2139 goto fail_suspend; 2140 acpi_sleep_clocks(sc, state); 2141 2142 /* 2nd suspend AML step: _PTS(tostate) */ 2143 if (aml_node_setval(sc, sc->sc_pts, state) != 0) 2144 goto fail_pts; 2145 2146 acpibtn_enable_psw(); /* enable _LID for wakeup */ 2147 acpi_indicator(sc, ACPI_SST_SLEEPING); 2148 2149 /* 3rd suspend AML step: _GTS(tostate) */ 2150 aml_node_setval(sc, sc->sc_gts, state); 2151 2152 /* Clear fixed event status */ 2153 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_ALL_STS); 2154 2155 /* Enable wake GPEs */ 2156 acpi_disable_allgpes(sc); 2157 acpi_enable_wakegpes(sc, state); 2158 2159 /* Sleep */ 2160 sc->sc_state = state; 2161 error = acpi_sleep_cpu(sc, state); 2162 sc->sc_state = ACPI_STATE_S0; 2163 /* Resume */ 2164 2165 #ifdef HIBERNATE 2166 if (state == ACPI_STATE_S4) { 2167 uvm_pmr_dirty_everything(); 2168 uvm_pmr_zero_everything(); 2169 } 2170 #endif /* HIBERNATE */ 2171 2172 acpi_resume_clocks(sc); /* AML may need clocks */ 2173 acpi_resume_pm(sc, state); 2174 acpi_resume_cpu(sc); 2175 2176 fail_pts: 2177 config_suspend(mainbus, DVACT_RESUME); 2178 2179 fail_suspend: 2180 cold = 0; 2181 enable_intr(); 2182 splx(s); 2183 2184 acpibtn_disable_psw(); /* disable _LID for wakeup */ 2185 inittodr(time_second); 2186 2187 /* 3rd resume AML step: _TTS(runstate) */ 2188 aml_node_setval(sc, sc->sc_tts, sc->sc_state); 2189 2190 #ifdef MULTIPROCESSOR 2191 acpi_resume_mp(); 2192 #endif 2193 2194 bufq_restart(); 2195 2196 fail_quiesce: 2197 config_suspend(mainbus, DVACT_WAKEUP); 2198 2199 #if NWSDISPLAY > 0 2200 wsdisplay_resume(); 2201 #endif /* NWSDISPLAY > 0 */ 2202 2203 acpi_record_event(sc, APM_NORMAL_RESUME); 2204 acpi_indicator(sc, ACPI_SST_WORKING); 2205 2206 #ifdef HIBERNATE 2207 if (state == ACPI_STATE_S4) { 2208 hibernate_free(); 2209 hibernate_resume_bufcache(); 2210 } 2211 #endif /* HIBERNATE */ 2212 2213 fail_tts: 2214 return (error); 2215 } 2216 2217 void 2218 acpi_wakeup(void *arg) 2219 { 2220 struct acpi_softc *sc = (struct acpi_softc *)arg; 2221 2222 sc->sc_threadwaiting = 0; 2223 wakeup(sc); 2224 } 2225 2226 /* XXX 2227 * We are going to do AML execution but are not in the acpi thread. 2228 * We do not know if the acpi thread is sleeping on acpiec in some 2229 * intermediate context. Wish us luck. 2230 */ 2231 void 2232 acpi_powerdown(void) 2233 { 2234 int state = ACPI_STATE_S5, s; 2235 struct acpi_softc *sc = acpi_softc; 2236 2237 if (acpi_enabled == 0) 2238 return; 2239 2240 s = splhigh(); 2241 disable_intr(); 2242 cold = 1; 2243 2244 /* 1st powerdown AML step: _PTS(tostate) */ 2245 aml_node_setval(sc, sc->sc_pts, state); 2246 2247 acpi_disable_allgpes(sc); 2248 acpi_enable_wakegpes(sc, state); 2249 2250 /* 2nd powerdown AML step: _GTS(tostate) */ 2251 aml_node_setval(sc, sc->sc_gts, state); 2252 2253 acpi_sleep_pm(sc, state); 2254 panic("acpi S5 transition did not happen"); 2255 while (1) 2256 ; 2257 } 2258 2259 void 2260 acpi_thread(void *arg) 2261 { 2262 struct acpi_thread *thread = arg; 2263 struct acpi_softc *sc = thread->sc; 2264 extern int aml_busy; 2265 int s; 2266 2267 /* AML/SMI cannot be trusted -- only run on the BSP */ 2268 sched_peg_curproc(&cpu_info_primary); 2269 2270 rw_enter_write(&sc->sc_lck); 2271 2272 /* 2273 * If we have an interrupt handler, we can get notification 2274 * when certain status bits changes in the ACPI registers, 2275 * so let us enable some events we can forward to userland 2276 */ 2277 if (sc->sc_interrupt) { 2278 int16_t en; 2279 2280 dnprintf(1,"slpbtn:%c pwrbtn:%c\n", 2281 sc->sc_fadt->flags & FADT_SLP_BUTTON ? 'n' : 'y', 2282 sc->sc_fadt->flags & FADT_PWR_BUTTON ? 'n' : 'y'); 2283 dnprintf(10, "Enabling acpi interrupts...\n"); 2284 sc->sc_threadwaiting = 1; 2285 2286 /* Enable Sleep/Power buttons if they exist */ 2287 s = spltty(); 2288 en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); 2289 if (!(sc->sc_fadt->flags & FADT_PWR_BUTTON)) 2290 en |= ACPI_PM1_PWRBTN_EN; 2291 if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON)) 2292 en |= ACPI_PM1_SLPBTN_EN; 2293 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en); 2294 2295 /* Enable handled GPEs here */ 2296 acpi_enable_rungpes(sc); 2297 splx(s); 2298 } 2299 2300 while (thread->running) { 2301 s = spltty(); 2302 while (sc->sc_threadwaiting) { 2303 dnprintf(10, "acpi thread going to sleep...\n"); 2304 rw_exit_write(&sc->sc_lck); 2305 tsleep(sc, PWAIT, "acpi0", 0); 2306 rw_enter_write(&sc->sc_lck); 2307 } 2308 sc->sc_threadwaiting = 1; 2309 splx(s); 2310 if (aml_busy) { 2311 panic("thread woke up to find aml was busy"); 2312 continue; 2313 } 2314 2315 /* Run ACPI taskqueue */ 2316 while(acpi_dotask(acpi_softc)) 2317 ; 2318 } 2319 free(thread, M_DEVBUF, 0); 2320 2321 kthread_exit(0); 2322 } 2323 2324 void 2325 acpi_create_thread(void *arg) 2326 { 2327 struct acpi_softc *sc = arg; 2328 2329 if (kthread_create(acpi_thread, sc->sc_thread, NULL, DEVNAME(sc)) 2330 != 0) 2331 printf("%s: unable to create isr thread, GPEs disabled\n", 2332 DEVNAME(sc)); 2333 } 2334 2335 int 2336 acpi_map_address(struct acpi_softc *sc, struct acpi_gas *gas, bus_addr_t base, 2337 bus_size_t size, bus_space_handle_t *pioh, bus_space_tag_t *piot) 2338 { 2339 int iospace = GAS_SYSTEM_IOSPACE; 2340 2341 /* No GAS structure, default to I/O space */ 2342 if (gas != NULL) { 2343 base += gas->address; 2344 iospace = gas->address_space_id; 2345 } 2346 switch (iospace) { 2347 case GAS_SYSTEM_MEMORY: 2348 *piot = sc->sc_memt; 2349 break; 2350 case GAS_SYSTEM_IOSPACE: 2351 *piot = sc->sc_iot; 2352 break; 2353 default: 2354 return -1; 2355 } 2356 if (bus_space_map(*piot, base, size, 0, pioh)) 2357 return -1; 2358 2359 return 0; 2360 } 2361 2362 int 2363 acpi_foundec(struct aml_node *node, void *arg) 2364 { 2365 struct acpi_softc *sc = (struct acpi_softc *)arg; 2366 struct device *self = (struct device *)arg; 2367 const char *dev; 2368 struct aml_value res; 2369 struct acpi_attach_args aaa; 2370 2371 if (aml_evalnode(sc, node, 0, NULL, &res) != 0) 2372 return 0; 2373 2374 switch (res.type) { 2375 case AML_OBJTYPE_STRING: 2376 dev = res.v_string; 2377 break; 2378 case AML_OBJTYPE_INTEGER: 2379 dev = aml_eisaid(aml_val2int(&res)); 2380 break; 2381 default: 2382 dev = "unknown"; 2383 break; 2384 } 2385 2386 if (strcmp(dev, ACPI_DEV_ECD)) 2387 return 0; 2388 2389 /* Check if we're already attached */ 2390 if (sc->sc_ec && sc->sc_ec->sc_devnode == node->parent) 2391 return 0; 2392 2393 memset(&aaa, 0, sizeof(aaa)); 2394 aaa.aaa_iot = sc->sc_iot; 2395 aaa.aaa_memt = sc->sc_memt; 2396 aaa.aaa_node = node->parent; 2397 aaa.aaa_dev = dev; 2398 aaa.aaa_name = "acpiec"; 2399 config_found(self, &aaa, acpi_print); 2400 aml_freevalue(&res); 2401 2402 return 0; 2403 } 2404 2405 int 2406 acpi_foundhid(struct aml_node *node, void *arg) 2407 { 2408 struct acpi_softc *sc = (struct acpi_softc *)arg; 2409 struct device *self = (struct device *)arg; 2410 const char *dev; 2411 struct aml_value res; 2412 struct acpi_attach_args aaa; 2413 2414 dnprintf(10, "found hid device: %s ", node->parent->name); 2415 if (aml_evalnode(sc, node, 0, NULL, &res) != 0) 2416 return 0; 2417 2418 switch (res.type) { 2419 case AML_OBJTYPE_STRING: 2420 dev = res.v_string; 2421 break; 2422 case AML_OBJTYPE_INTEGER: 2423 dev = aml_eisaid(aml_val2int(&res)); 2424 break; 2425 default: 2426 dev = "unknown"; 2427 break; 2428 } 2429 dnprintf(10, " device: %s\n", dev); 2430 2431 memset(&aaa, 0, sizeof(aaa)); 2432 aaa.aaa_iot = sc->sc_iot; 2433 aaa.aaa_memt = sc->sc_memt; 2434 aaa.aaa_node = node->parent; 2435 aaa.aaa_dev = dev; 2436 2437 if (!strcmp(dev, ACPI_DEV_AC)) 2438 aaa.aaa_name = "acpiac"; 2439 else if (!strcmp(dev, ACPI_DEV_CMB)) 2440 aaa.aaa_name = "acpibat"; 2441 else if (!strcmp(dev, ACPI_DEV_LD) || 2442 !strcmp(dev, ACPI_DEV_PBD) || 2443 !strcmp(dev, ACPI_DEV_SBD)) 2444 aaa.aaa_name = "acpibtn"; 2445 else if (!strcmp(dev, ACPI_DEV_ASUS) || !strcmp(dev, ACPI_DEV_ASUS1)) { 2446 aaa.aaa_name = "acpiasus"; 2447 acpi_asus_enabled = 1; 2448 } else if (!strcmp(dev, ACPI_DEV_IBM) || 2449 !strcmp(dev, ACPI_DEV_LENOVO)) { 2450 aaa.aaa_name = "acpithinkpad"; 2451 acpi_thinkpad_enabled = 1; 2452 } else if (!strcmp(dev, ACPI_DEV_ASUSAIBOOSTER)) 2453 aaa.aaa_name = "aibs"; 2454 else if (!strcmp(dev, ACPI_DEV_TOSHIBA_LIBRETTO) || 2455 !strcmp(dev, ACPI_DEV_TOSHIBA_DYNABOOK) || 2456 !strcmp(dev, ACPI_DEV_TOSHIBA_SPA40)) { 2457 aaa.aaa_name = "acpitoshiba"; 2458 acpi_toshiba_enabled = 1; 2459 } 2460 2461 2462 if (aaa.aaa_name) 2463 config_found(self, &aaa, acpi_print); 2464 2465 aml_freevalue(&res); 2466 2467 return 0; 2468 } 2469 2470 int 2471 acpi_founddock(struct aml_node *node, void *arg) 2472 { 2473 struct acpi_softc *sc = (struct acpi_softc *)arg; 2474 struct device *self = (struct device *)arg; 2475 struct acpi_attach_args aaa; 2476 2477 dnprintf(10, "found dock entry: %s\n", node->parent->name); 2478 2479 memset(&aaa, 0, sizeof(aaa)); 2480 aaa.aaa_iot = sc->sc_iot; 2481 aaa.aaa_memt = sc->sc_memt; 2482 aaa.aaa_node = node->parent; 2483 aaa.aaa_name = "acpidock"; 2484 2485 config_found(self, &aaa, acpi_print); 2486 2487 return 0; 2488 } 2489 2490 int 2491 acpi_foundvideo(struct aml_node *node, void *arg) 2492 { 2493 struct acpi_softc *sc = (struct acpi_softc *)arg; 2494 struct device *self = (struct device *)arg; 2495 struct acpi_attach_args aaa; 2496 2497 memset(&aaa, 0, sizeof(aaa)); 2498 aaa.aaa_iot = sc->sc_iot; 2499 aaa.aaa_memt = sc->sc_memt; 2500 aaa.aaa_node = node->parent; 2501 aaa.aaa_name = "acpivideo"; 2502 2503 config_found(self, &aaa, acpi_print); 2504 2505 return (0); 2506 } 2507 2508 int 2509 acpi_foundsony(struct aml_node *node, void *arg) 2510 { 2511 struct acpi_softc *sc = (struct acpi_softc *)arg; 2512 struct device *self = (struct device *)arg; 2513 struct acpi_attach_args aaa; 2514 2515 memset(&aaa, 0, sizeof(aaa)); 2516 aaa.aaa_iot = sc->sc_iot; 2517 aaa.aaa_memt = sc->sc_memt; 2518 aaa.aaa_node = node->parent; 2519 aaa.aaa_name = "acpisony"; 2520 2521 config_found(self, &aaa, acpi_print); 2522 2523 return 0; 2524 } 2525 2526 int 2527 acpiopen(dev_t dev, int flag, int mode, struct proc *p) 2528 { 2529 int error = 0; 2530 struct acpi_softc *sc; 2531 int s; 2532 2533 if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || 2534 !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) 2535 return (ENXIO); 2536 2537 s = spltty(); 2538 switch (APMDEV(dev)) { 2539 case APMDEV_CTL: 2540 if (!(flag & FWRITE)) { 2541 error = EINVAL; 2542 break; 2543 } 2544 if (sc->sc_flags & SCFLAG_OWRITE) { 2545 error = EBUSY; 2546 break; 2547 } 2548 sc->sc_flags |= SCFLAG_OWRITE; 2549 break; 2550 case APMDEV_NORMAL: 2551 if (!(flag & FREAD) || (flag & FWRITE)) { 2552 error = EINVAL; 2553 break; 2554 } 2555 sc->sc_flags |= SCFLAG_OREAD; 2556 break; 2557 default: 2558 error = ENXIO; 2559 break; 2560 } 2561 splx(s); 2562 return (error); 2563 } 2564 2565 int 2566 acpiclose(dev_t dev, int flag, int mode, struct proc *p) 2567 { 2568 int error = 0; 2569 struct acpi_softc *sc; 2570 int s; 2571 2572 if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || 2573 !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) 2574 return (ENXIO); 2575 2576 s = spltty(); 2577 switch (APMDEV(dev)) { 2578 case APMDEV_CTL: 2579 sc->sc_flags &= ~SCFLAG_OWRITE; 2580 break; 2581 case APMDEV_NORMAL: 2582 sc->sc_flags &= ~SCFLAG_OREAD; 2583 break; 2584 default: 2585 error = ENXIO; 2586 break; 2587 } 2588 splx(s); 2589 return (error); 2590 } 2591 2592 int 2593 acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 2594 { 2595 int error = 0; 2596 struct acpi_softc *sc; 2597 struct acpi_ac *ac; 2598 struct acpi_bat *bat; 2599 struct apm_power_info *pi = (struct apm_power_info *)data; 2600 int bats; 2601 unsigned int remaining, rem, minutes, rate; 2602 int s; 2603 2604 if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || 2605 !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) 2606 return (ENXIO); 2607 2608 s = spltty(); 2609 /* fake APM */ 2610 switch (cmd) { 2611 case APM_IOC_SUSPEND: 2612 case APM_IOC_STANDBY: 2613 if ((flag & FWRITE) == 0) { 2614 error = EBADF; 2615 break; 2616 } 2617 acpi_addtask(sc, acpi_sleep_task, sc, ACPI_STATE_S3); 2618 acpi_wakeup(sc); 2619 break; 2620 #ifdef HIBERNATE 2621 case APM_IOC_HIBERNATE: 2622 if ((error = suser(p, 0)) != 0) 2623 break; 2624 if ((flag & FWRITE) == 0) { 2625 error = EBADF; 2626 break; 2627 } 2628 if (get_hibernate_io_function() == NULL) { 2629 error = EOPNOTSUPP; 2630 break; 2631 } 2632 acpi_addtask(sc, acpi_sleep_task, sc, ACPI_STATE_S4); 2633 acpi_wakeup(sc); 2634 break; 2635 #endif 2636 case APM_IOC_GETPOWER: 2637 /* A/C */ 2638 pi->ac_state = APM_AC_UNKNOWN; 2639 SLIST_FOREACH(ac, &sc->sc_ac, aac_link) { 2640 if (ac->aac_softc->sc_ac_stat == PSR_ONLINE) 2641 pi->ac_state = APM_AC_ON; 2642 else if (ac->aac_softc->sc_ac_stat == PSR_OFFLINE) 2643 if (pi->ac_state == APM_AC_UNKNOWN) 2644 pi->ac_state = APM_AC_OFF; 2645 } 2646 2647 /* battery */ 2648 pi->battery_state = APM_BATT_UNKNOWN; 2649 pi->battery_life = 0; 2650 pi->minutes_left = 0; 2651 bats = 0; 2652 remaining = rem = 0; 2653 minutes = 0; 2654 rate = 0; 2655 SLIST_FOREACH(bat, &sc->sc_bat, aba_link) { 2656 if (bat->aba_softc->sc_bat_present == 0) 2657 continue; 2658 2659 if (bat->aba_softc->sc_bif.bif_last_capacity == 0) 2660 continue; 2661 2662 bats++; 2663 rem = (bat->aba_softc->sc_bst.bst_capacity * 100) / 2664 bat->aba_softc->sc_bif.bif_last_capacity; 2665 if (rem > 100) 2666 rem = 100; 2667 remaining += rem; 2668 2669 if (bat->aba_softc->sc_bst.bst_rate == BST_UNKNOWN) 2670 continue; 2671 else if (bat->aba_softc->sc_bst.bst_rate > 1) 2672 rate = bat->aba_softc->sc_bst.bst_rate; 2673 2674 minutes += bat->aba_softc->sc_bst.bst_capacity; 2675 } 2676 2677 if (bats == 0) { 2678 pi->battery_state = APM_BATTERY_ABSENT; 2679 pi->battery_life = 0; 2680 pi->minutes_left = (unsigned int)-1; 2681 break; 2682 } 2683 2684 if (pi->ac_state == APM_AC_ON || rate == 0) 2685 pi->minutes_left = (unsigned int)-1; 2686 else 2687 pi->minutes_left = 60 * minutes / rate; 2688 2689 /* running on battery */ 2690 pi->battery_life = remaining / bats; 2691 if (pi->battery_life > 50) 2692 pi->battery_state = APM_BATT_HIGH; 2693 else if (pi->battery_life > 25) 2694 pi->battery_state = APM_BATT_LOW; 2695 else 2696 pi->battery_state = APM_BATT_CRITICAL; 2697 2698 break; 2699 2700 default: 2701 error = ENOTTY; 2702 } 2703 2704 splx(s); 2705 return (error); 2706 } 2707 2708 void acpi_filtdetach(struct knote *); 2709 int acpi_filtread(struct knote *, long); 2710 2711 struct filterops acpiread_filtops = { 2712 1, NULL, acpi_filtdetach, acpi_filtread 2713 }; 2714 2715 int acpi_evindex; 2716 2717 int 2718 acpi_record_event(struct acpi_softc *sc, u_int type) 2719 { 2720 if ((sc->sc_flags & SCFLAG_OPEN) == 0) 2721 return (1); 2722 2723 acpi_evindex++; 2724 KNOTE(sc->sc_note, APM_EVENT_COMPOSE(type, acpi_evindex)); 2725 return (0); 2726 } 2727 2728 void 2729 acpi_filtdetach(struct knote *kn) 2730 { 2731 struct acpi_softc *sc = kn->kn_hook; 2732 int s; 2733 2734 s = spltty(); 2735 SLIST_REMOVE(sc->sc_note, kn, knote, kn_selnext); 2736 splx(s); 2737 } 2738 2739 int 2740 acpi_filtread(struct knote *kn, long hint) 2741 { 2742 /* XXX weird kqueue_scan() semantics */ 2743 if (hint && !kn->kn_data) 2744 kn->kn_data = hint; 2745 return (1); 2746 } 2747 2748 int 2749 acpikqfilter(dev_t dev, struct knote *kn) 2750 { 2751 struct acpi_softc *sc; 2752 int s; 2753 2754 if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || 2755 !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) 2756 return (ENXIO); 2757 2758 switch (kn->kn_filter) { 2759 case EVFILT_READ: 2760 kn->kn_fop = &acpiread_filtops; 2761 break; 2762 default: 2763 return (EINVAL); 2764 } 2765 2766 kn->kn_hook = sc; 2767 2768 s = spltty(); 2769 SLIST_INSERT_HEAD(sc->sc_note, kn, kn_selnext); 2770 splx(s); 2771 2772 return (0); 2773 } 2774 2775 #else /* SMALL_KERNEL */ 2776 2777 int 2778 acpiopen(dev_t dev, int flag, int mode, struct proc *p) 2779 { 2780 return (ENXIO); 2781 } 2782 2783 int 2784 acpiclose(dev_t dev, int flag, int mode, struct proc *p) 2785 { 2786 return (ENXIO); 2787 } 2788 2789 int 2790 acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 2791 { 2792 return (ENXIO); 2793 } 2794 2795 int 2796 acpikqfilter(dev_t dev, struct knote *kn) 2797 { 2798 return (ENXIO); 2799 } 2800 #endif /* SMALL_KERNEL */ 2801