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