1 /* $OpenBSD: acpi.c,v 1.335 2017/11/29 22:51:01 kettenis 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 #include <sys/sysctl.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/rndvar.h> 43 #include <dev/pci/pcivar.h> 44 #include <dev/acpi/acpireg.h> 45 #include <dev/acpi/acpivar.h> 46 #include <dev/acpi/amltypes.h> 47 #include <dev/acpi/acpidev.h> 48 #include <dev/acpi/dsdt.h> 49 #include <dev/wscons/wsdisplayvar.h> 50 51 #include <dev/pci/pcidevs.h> 52 #include <dev/pci/ppbreg.h> 53 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 struct aml_node *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 int acpi_pci_notify(struct aml_node *, int, void *); 78 79 int acpi_match(struct device *, void *, void *); 80 void acpi_attach(struct device *, struct device *, void *); 81 int acpi_submatch(struct device *, void *, void *); 82 int acpi_print(void *, const char *); 83 84 void acpi_map_pmregs(struct acpi_softc *); 85 void acpi_unmap_pmregs(struct acpi_softc *); 86 87 int acpi_loadtables(struct acpi_softc *, struct acpi_rsdp *); 88 89 int _acpi_matchhids(const char *, const char *[]); 90 91 int acpi_inidev(struct aml_node *, void *); 92 int acpi_foundprt(struct aml_node *, void *); 93 94 int acpi_enable(struct acpi_softc *); 95 void acpi_init_states(struct acpi_softc *); 96 97 void acpi_gpe_task(void *, int); 98 void acpi_sbtn_task(void *, int); 99 void acpi_pbtn_task(void *, int); 100 101 int acpi_enabled; 102 103 void acpi_init_gpes(struct acpi_softc *); 104 void acpi_disable_allgpes(struct acpi_softc *); 105 struct gpe_block *acpi_find_gpe(struct acpi_softc *, int); 106 void acpi_enable_onegpe(struct acpi_softc *, int); 107 int acpi_gpe(struct acpi_softc *, int, void *); 108 109 void acpi_enable_rungpes(struct acpi_softc *); 110 void acpi_enable_wakegpes(struct acpi_softc *, int); 111 112 113 int acpi_foundec(struct aml_node *, void *); 114 int acpi_foundsony(struct aml_node *node, void *arg); 115 int acpi_foundhid(struct aml_node *, void *); 116 int acpi_add_device(struct aml_node *node, void *arg); 117 118 void acpi_thread(void *); 119 void acpi_create_thread(void *); 120 121 #ifndef SMALL_KERNEL 122 123 void acpi_indicator(struct acpi_softc *, int); 124 125 int acpi_matchhids(struct acpi_attach_args *aa, const char *hids[], 126 const char *driver); 127 128 void acpi_init_pm(struct acpi_softc *); 129 130 int acpi_founddock(struct aml_node *, void *); 131 int acpi_foundpss(struct aml_node *, void *); 132 int acpi_foundtmp(struct aml_node *, void *); 133 int acpi_foundprw(struct aml_node *, void *); 134 int acpi_foundvideo(struct aml_node *, void *); 135 int acpi_foundsbs(struct aml_node *node, void *); 136 137 int acpi_foundide(struct aml_node *node, void *arg); 138 int acpiide_notify(struct aml_node *, int, void *); 139 void wdcattach(struct channel_softc *); 140 int wdcdetach(struct channel_softc *, int); 141 int is_ejectable_bay(struct aml_node *node); 142 int is_ata(struct aml_node *node); 143 int is_ejectable(struct aml_node *node); 144 145 struct idechnl { 146 struct acpi_softc *sc; 147 int64_t addr; 148 int64_t chnl; 149 int64_t sta; 150 }; 151 152 /* 153 * This is a list of Synaptics devices with a 'top button area' 154 * based on the list in Linux supplied by Synaptics 155 * Synaptics clickpads with the following pnp ids will get a unique 156 * wscons mouse type that is used to define trackpad regions that will 157 * emulate mouse buttons 158 */ 159 static const char *sbtn_pnp[] = { 160 "LEN0017", 161 "LEN0018", 162 "LEN0019", 163 "LEN0023", 164 "LEN002A", 165 "LEN002B", 166 "LEN002C", 167 "LEN002D", 168 "LEN002E", 169 "LEN0033", 170 "LEN0034", 171 "LEN0035", 172 "LEN0036", 173 "LEN0037", 174 "LEN0038", 175 "LEN0039", 176 "LEN0041", 177 "LEN0042", 178 "LEN0045", 179 "LEN0047", 180 "LEN0049", 181 "LEN2000", 182 "LEN2001", 183 "LEN2002", 184 "LEN2003", 185 "LEN2004", 186 "LEN2005", 187 "LEN2006", 188 "LEN2007", 189 "LEN2008", 190 "LEN2009", 191 "LEN200A", 192 "LEN200B", 193 }; 194 195 int mouse_has_softbtn; 196 #endif /* SMALL_KERNEL */ 197 198 /* XXX move this into dsdt softc at some point */ 199 extern struct aml_node aml_root; 200 201 struct cfattach acpi_ca = { 202 sizeof(struct acpi_softc), acpi_match, acpi_attach 203 }; 204 205 struct cfdriver acpi_cd = { 206 NULL, "acpi", DV_DULL 207 }; 208 209 struct acpi_softc *acpi_softc; 210 211 #define acpi_bus_space_map _bus_space_map 212 #define acpi_bus_space_unmap _bus_space_unmap 213 214 uint8_t 215 acpi_pci_conf_read_1(pci_chipset_tag_t pc, pcitag_t tag, int reg) 216 { 217 uint32_t val = pci_conf_read(pc, tag, reg & ~0x3); 218 return (val >> ((reg & 0x3) << 3)); 219 } 220 221 uint16_t 222 acpi_pci_conf_read_2(pci_chipset_tag_t pc, pcitag_t tag, int reg) 223 { 224 uint32_t val = pci_conf_read(pc, tag, reg & ~0x2); 225 return (val >> ((reg & 0x2) << 3)); 226 } 227 228 uint32_t 229 acpi_pci_conf_read_4(pci_chipset_tag_t pc, pcitag_t tag, int reg) 230 { 231 return pci_conf_read(pc, tag, reg); 232 } 233 234 void 235 acpi_pci_conf_write_1(pci_chipset_tag_t pc, pcitag_t tag, int reg, uint8_t val) 236 { 237 uint32_t tmp = pci_conf_read(pc, tag, reg & ~0x3); 238 tmp &= ~(0xff << ((reg & 0x3) << 3)); 239 tmp |= (val << ((reg & 0x3) << 3)); 240 pci_conf_write(pc, tag, reg & ~0x3, tmp); 241 } 242 243 void 244 acpi_pci_conf_write_2(pci_chipset_tag_t pc, pcitag_t tag, int reg, uint16_t val) 245 { 246 uint32_t tmp = pci_conf_read(pc, tag, reg & ~0x2); 247 tmp &= ~(0xffff << ((reg & 0x2) << 3)); 248 tmp |= (val << ((reg & 0x2) << 3)); 249 pci_conf_write(pc, tag, reg & ~0x2, tmp); 250 } 251 252 void 253 acpi_pci_conf_write_4(pci_chipset_tag_t pc, pcitag_t tag, int reg, uint32_t val) 254 { 255 pci_conf_write(pc, tag, reg, val); 256 } 257 258 int 259 acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address, 260 int access_size, int len, void *buffer) 261 { 262 u_int8_t *pb; 263 bus_space_tag_t iot; 264 bus_space_handle_t ioh; 265 pci_chipset_tag_t pc; 266 pcitag_t tag; 267 int reg, idx; 268 269 dnprintf(50, "gasio: %.2x 0x%.8llx %s\n", 270 iospace, address, (iodir == ACPI_IOWRITE) ? "write" : "read"); 271 272 KASSERT((len % access_size) == 0); 273 274 pb = (u_int8_t *)buffer; 275 switch (iospace) { 276 case GAS_SYSTEM_MEMORY: 277 case GAS_SYSTEM_IOSPACE: 278 if (iospace == GAS_SYSTEM_MEMORY) 279 iot = sc->sc_memt; 280 else 281 iot = sc->sc_iot; 282 283 if (acpi_bus_space_map(iot, address, len, 0, &ioh) != 0) { 284 printf("%s: unable to map iospace\n", DEVNAME(sc)); 285 return (-1); 286 } 287 for (reg = 0; reg < len; reg += access_size) { 288 if (iodir == ACPI_IOREAD) { 289 switch (access_size) { 290 case 1: 291 *(uint8_t *)(pb + reg) = 292 bus_space_read_1(iot, ioh, reg); 293 dnprintf(80, "os_in8(%llx) = %x\n", 294 reg+address, *(uint8_t *)(pb+reg)); 295 break; 296 case 2: 297 *(uint16_t *)(pb + reg) = 298 bus_space_read_2(iot, ioh, reg); 299 dnprintf(80, "os_in16(%llx) = %x\n", 300 reg+address, *(uint16_t *)(pb+reg)); 301 break; 302 case 4: 303 *(uint32_t *)(pb + reg) = 304 bus_space_read_4(iot, ioh, reg); 305 break; 306 default: 307 printf("%s: rdio: invalid size %d\n", 308 DEVNAME(sc), access_size); 309 return (-1); 310 } 311 } else { 312 switch (access_size) { 313 case 1: 314 bus_space_write_1(iot, ioh, reg, 315 *(uint8_t *)(pb + reg)); 316 dnprintf(80, "os_out8(%llx,%x)\n", 317 reg+address, *(uint8_t *)(pb+reg)); 318 break; 319 case 2: 320 bus_space_write_2(iot, ioh, reg, 321 *(uint16_t *)(pb + reg)); 322 dnprintf(80, "os_out16(%llx,%x)\n", 323 reg+address, *(uint16_t *)(pb+reg)); 324 break; 325 case 4: 326 bus_space_write_4(iot, ioh, reg, 327 *(uint32_t *)(pb + reg)); 328 break; 329 default: 330 printf("%s: wrio: invalid size %d\n", 331 DEVNAME(sc), access_size); 332 return (-1); 333 } 334 } 335 } 336 acpi_bus_space_unmap(iot, ioh, len, NULL); 337 break; 338 339 case GAS_PCI_CFG_SPACE: 340 /* format of address: 341 * bits 00..15 = register 342 * bits 16..31 = function 343 * bits 32..47 = device 344 * bits 48..63 = bus 345 */ 346 347 /* 348 * The ACPI standard says that a function number of 349 * FFFF can be used to refer to all functions on a 350 * device. This makes no sense though in the context 351 * of accessing PCI config space. Yet there is AML 352 * out there that does this. We simulate a read from 353 * a nonexistent device here. Writes will panic when 354 * we try to construct the tag below. 355 */ 356 if (ACPI_PCI_FN(address) == 0xffff && iodir == ACPI_IOREAD) { 357 memset(buffer, 0xff, len); 358 return (0); 359 } 360 361 pc = NULL; 362 tag = pci_make_tag(pc, 363 ACPI_PCI_BUS(address), ACPI_PCI_DEV(address), 364 ACPI_PCI_FN(address)); 365 366 reg = ACPI_PCI_REG(address); 367 for (idx = 0; idx < len; idx += access_size) { 368 if (iodir == ACPI_IOREAD) { 369 switch (access_size) { 370 case 1: 371 *(uint8_t *)(pb + idx) = 372 acpi_pci_conf_read_1(pc, tag, reg + idx); 373 break; 374 case 2: 375 *(uint16_t *)(pb + idx) = 376 acpi_pci_conf_read_2(pc, tag, reg + idx); 377 break; 378 case 4: 379 *(uint32_t *)(pb + idx) = 380 acpi_pci_conf_read_4(pc, tag, reg + idx); 381 break; 382 default: 383 printf("%s: rdcfg: invalid size %d\n", 384 DEVNAME(sc), access_size); 385 return (-1); 386 } 387 } else { 388 switch (access_size) { 389 case 1: 390 acpi_pci_conf_write_1(pc, tag, reg + idx, 391 *(uint8_t *)(pb + idx)); 392 break; 393 case 2: 394 acpi_pci_conf_write_2(pc, tag, reg + idx, 395 *(uint16_t *)(pb + idx)); 396 break; 397 case 4: 398 acpi_pci_conf_write_4(pc, tag, reg + idx, 399 *(uint32_t *)(pb + idx)); 400 break; 401 default: 402 printf("%s: wrcfg: invalid size %d\n", 403 DEVNAME(sc), access_size); 404 return (-1); 405 } 406 } 407 } 408 break; 409 410 case GAS_EMBEDDED: 411 if (sc->sc_ec == NULL) { 412 printf("%s: WARNING EC not initialized\n", DEVNAME(sc)); 413 return (-1); 414 } 415 if (iodir == ACPI_IOREAD) 416 acpiec_read(sc->sc_ec, (u_int8_t)address, len, buffer); 417 else 418 acpiec_write(sc->sc_ec, (u_int8_t)address, len, buffer); 419 break; 420 } 421 return (0); 422 } 423 424 int 425 acpi_inidev(struct aml_node *node, void *arg) 426 { 427 struct acpi_softc *sc = (struct acpi_softc *)arg; 428 int64_t st; 429 430 /* 431 * Per the ACPI spec 6.5.1, only run _INI when device is there or 432 * when there is no _STA. We terminate the tree walk (with return 1) 433 * early if necessary. 434 */ 435 436 /* Evaluate _STA to decide _INI fate and walk fate */ 437 if (aml_evalinteger(sc, node->parent, "_STA", 0, NULL, &st)) 438 st = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000; 439 440 /* Evaluate _INI if we are present */ 441 if (st & STA_PRESENT) 442 aml_evalnode(sc, node, 0, NULL, NULL); 443 444 /* If we are functioning, we walk/search our children */ 445 if (st & STA_DEV_OK) 446 return 0; 447 448 /* If we are not enabled, or not present, terminate search */ 449 if (!(st & (STA_PRESENT|STA_ENABLED))) 450 return 1; 451 452 /* Default just continue search */ 453 return 0; 454 } 455 456 int 457 acpi_foundprt(struct aml_node *node, void *arg) 458 { 459 struct acpi_softc *sc = (struct acpi_softc *)arg; 460 struct device *self = (struct device *)arg; 461 struct acpi_attach_args aaa; 462 int64_t st = 0; 463 464 dnprintf(10, "found prt entry: %s\n", node->parent->name); 465 466 /* Evaluate _STA to decide _PRT fate and walk fate */ 467 if (aml_evalinteger(sc, node->parent, "_STA", 0, NULL, &st)) 468 st = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000; 469 470 if (st & STA_PRESENT) { 471 memset(&aaa, 0, sizeof(aaa)); 472 aaa.aaa_iot = sc->sc_iot; 473 aaa.aaa_memt = sc->sc_memt; 474 aaa.aaa_node = node; 475 aaa.aaa_name = "acpiprt"; 476 477 config_found(self, &aaa, acpi_print); 478 } 479 480 /* If we are functioning, we walk/search our children */ 481 if (st & STA_DEV_OK) 482 return 0; 483 484 /* If we are not enabled, or not present, terminate search */ 485 if (!(st & (STA_PRESENT|STA_ENABLED))) 486 return 1; 487 488 /* Default just continue search */ 489 return 0; 490 } 491 492 int 493 acpi_match(struct device *parent, void *match, void *aux) 494 { 495 struct bios_attach_args *ba = aux; 496 struct cfdata *cf = match; 497 498 /* sanity */ 499 if (strcmp(ba->ba_name, cf->cf_driver->cd_name)) 500 return (0); 501 502 if (!acpi_probe(parent, cf, ba)) 503 return (0); 504 505 return (1); 506 } 507 508 TAILQ_HEAD(, acpi_pci) acpi_pcidevs = 509 TAILQ_HEAD_INITIALIZER(acpi_pcidevs); 510 TAILQ_HEAD(, acpi_pci) acpi_pcirootdevs = 511 TAILQ_HEAD_INITIALIZER(acpi_pcirootdevs); 512 513 int acpi_getpci(struct aml_node *node, void *arg); 514 int acpi_getminbus(int crsidx, union acpi_resource *crs, void *arg); 515 516 int 517 acpi_getminbus(int crsidx, union acpi_resource *crs, void *arg) 518 { 519 int *bbn = arg; 520 int typ = AML_CRSTYPE(crs); 521 522 /* Check for embedded bus number */ 523 if (typ == LR_WORD && crs->lr_word.type == 2) { 524 /* If _MIN > _MAX, the resource is considered to be invalid. */ 525 if (crs->lr_word._min > crs->lr_word._max) 526 return -1; 527 *bbn = crs->lr_word._min; 528 } 529 return 0; 530 } 531 532 int 533 _acpi_matchhids(const char *hid, const char *hids[]) 534 { 535 int i; 536 537 for (i = 0; hids[i]; i++) 538 if (!strcmp(hid, hids[i])) 539 return (1); 540 return (0); 541 } 542 543 int 544 acpi_matchhids(struct acpi_attach_args *aa, const char *hids[], 545 const char *driver) 546 { 547 if (aa->aaa_dev == NULL || aa->aaa_node == NULL) 548 return (0); 549 if (_acpi_matchhids(aa->aaa_dev, hids)) { 550 dnprintf(5, "driver %s matches at least one hid\n", driver); 551 return (1); 552 } 553 554 return (0); 555 } 556 557 /* Map ACPI device node to PCI */ 558 int 559 acpi_getpci(struct aml_node *node, void *arg) 560 { 561 const char *pcihid[] = { ACPI_DEV_PCIB, ACPI_DEV_PCIEB, "HWP0002", 0 }; 562 struct acpi_pci *pci, *ppci; 563 struct aml_value res; 564 struct acpi_softc *sc = arg; 565 pci_chipset_tag_t pc = NULL; 566 pcitag_t tag; 567 uint64_t val; 568 uint32_t reg; 569 570 if (!node->value || node->value->type != AML_OBJTYPE_DEVICE) 571 return 0; 572 if (!aml_evalhid(node, &res)) { 573 /* Check if this is a PCI Root node */ 574 if (_acpi_matchhids(res.v_string, pcihid)) { 575 aml_freevalue(&res); 576 577 pci = malloc(sizeof(*pci), M_DEVBUF, M_WAITOK|M_ZERO); 578 579 pci->bus = -1; 580 if (!aml_evalinteger(sc, node, "_SEG", 0, NULL, &val)) 581 pci->seg = val; 582 if (!aml_evalname(sc, node, "_CRS", 0, NULL, &res)) { 583 aml_parse_resource(&res, acpi_getminbus, 584 &pci->bus); 585 dnprintf(10, "%s post-crs: %d\n", aml_nodename(node), 586 pci->bus); 587 } 588 if (!aml_evalinteger(sc, node, "_BBN", 0, NULL, &val)) { 589 dnprintf(10, "%s post-bbn: %d, %lld\n", aml_nodename(node), 590 pci->bus, val); 591 if (pci->bus == -1) 592 pci->bus = val; 593 } 594 pci->sub = pci->bus; 595 node->pci = pci; 596 dnprintf(10, "found PCI root: %s %d\n", 597 aml_nodename(node), pci->bus); 598 TAILQ_INSERT_TAIL(&acpi_pcirootdevs, pci, next); 599 } 600 aml_freevalue(&res); 601 return 0; 602 } 603 604 /* If parent is not PCI, or device does not have _ADR, return */ 605 if (!node->parent || (ppci = node->parent->pci) == NULL) 606 return 0; 607 if (aml_evalinteger(sc, node, "_ADR", 0, NULL, &val)) 608 return 0; 609 610 pci = malloc(sizeof(*pci), M_DEVBUF, M_WAITOK|M_ZERO); 611 pci->bus = ppci->sub; 612 pci->dev = ACPI_ADR_PCIDEV(val); 613 pci->fun = ACPI_ADR_PCIFUN(val); 614 pci->node = node; 615 pci->sub = -1; 616 617 dnprintf(10, "%.2x:%.2x.%x -> %s\n", 618 pci->bus, pci->dev, pci->fun, 619 aml_nodename(node)); 620 621 /* Collect device power state information. */ 622 if (aml_evalinteger(sc, node, "_S3D", 0, NULL, &val) == 0) 623 pci->_s3d = val; 624 else 625 pci->_s3d = -1; 626 if (aml_evalinteger(sc, node, "_S3W", 0, NULL, &val) == 0) 627 pci->_s3w = val; 628 else 629 pci->_s3w = -1; 630 if (aml_evalinteger(sc, node, "_S4D", 0, NULL, &val) == 0) 631 pci->_s4d = val; 632 else 633 pci->_s4d = -1; 634 if (aml_evalinteger(sc, node, "_S4W", 0, NULL, &val) == 0) 635 pci->_s4w = val; 636 else 637 pci->_s4w = -1; 638 639 /* Check if PCI device exists */ 640 if (pci->dev > 0x1F || pci->fun > 7) { 641 free(pci, M_DEVBUF, sizeof(*pci)); 642 return (1); 643 } 644 tag = pci_make_tag(pc, pci->bus, pci->dev, pci->fun); 645 reg = pci_conf_read(pc, tag, PCI_ID_REG); 646 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID) { 647 free(pci, M_DEVBUF, sizeof(*pci)); 648 return (1); 649 } 650 node->pci = pci; 651 652 TAILQ_INSERT_TAIL(&acpi_pcidevs, pci, next); 653 654 /* Check if this is a PCI bridge */ 655 reg = pci_conf_read(pc, tag, PCI_CLASS_REG); 656 if (PCI_CLASS(reg) == PCI_CLASS_BRIDGE && 657 PCI_SUBCLASS(reg) == PCI_SUBCLASS_BRIDGE_PCI) { 658 reg = pci_conf_read(pc, tag, PPB_REG_BUSINFO); 659 pci->sub = PPB_BUSINFO_SECONDARY(reg); 660 661 dnprintf(10, "found PCI bridge: %s %d\n", 662 aml_nodename(node), pci->sub); 663 664 /* Continue scanning */ 665 return (0); 666 } 667 668 /* Device does not have children, stop scanning */ 669 return (1); 670 } 671 672 struct aml_node * 673 acpi_pci_match(struct device *dev, struct pci_attach_args *pa) 674 { 675 struct acpi_pci *pdev; 676 int state; 677 678 TAILQ_FOREACH(pdev, &acpi_pcidevs, next) { 679 if (pdev->bus != pa->pa_bus || 680 pdev->dev != pa->pa_device || 681 pdev->fun != pa->pa_function) 682 continue; 683 684 dnprintf(10,"%s at acpi0 %s\n", dev->dv_xname, 685 aml_nodename(pdev->node)); 686 687 pdev->device = dev; 688 689 /* 690 * If some Power Resources are dependent on this device 691 * initialize them. 692 */ 693 state = pci_get_powerstate(pa->pa_pc, pa->pa_tag); 694 acpi_pci_set_powerstate(pa->pa_pc, pa->pa_tag, state, 1); 695 acpi_pci_set_powerstate(pa->pa_pc, pa->pa_tag, state, 0); 696 697 aml_register_notify(pdev->node, NULL, acpi_pci_notify, pdev, 0); 698 699 return pdev->node; 700 } 701 702 return NULL; 703 } 704 705 pcireg_t 706 acpi_pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag) 707 { 708 struct acpi_pci *pdev; 709 int bus, dev, fun; 710 int state = -1, defaultstate = pci_get_powerstate(pc, tag); 711 712 pci_decompose_tag(pc, tag, &bus, &dev, &fun); 713 TAILQ_FOREACH(pdev, &acpi_pcidevs, next) { 714 if (pdev->bus == bus && pdev->dev == dev && pdev->fun == fun) { 715 switch (acpi_softc->sc_state) { 716 case ACPI_STATE_S3: 717 defaultstate = PCI_PMCSR_STATE_D3; 718 state = MAX(pdev->_s3d, pdev->_s3w); 719 break; 720 case ACPI_STATE_S4: 721 state = MAX(pdev->_s4d, pdev->_s4w); 722 break; 723 case ACPI_STATE_S5: 724 default: 725 break; 726 } 727 728 if (state >= PCI_PMCSR_STATE_D0 && 729 state <= PCI_PMCSR_STATE_D3) 730 return state; 731 } 732 } 733 734 return defaultstate; 735 } 736 737 void 738 acpi_pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, int state, int pre) 739 { 740 #if NACPIPWRRES > 0 741 struct acpi_softc *sc = acpi_softc; 742 struct acpi_pwrres *pr; 743 struct acpi_pci *pdev; 744 int bus, dev, fun; 745 char name[5]; 746 747 pci_decompose_tag(pc, tag, &bus, &dev, &fun); 748 TAILQ_FOREACH(pdev, &acpi_pcidevs, next) { 749 if (pdev->bus == bus && pdev->dev == dev && pdev->fun == fun) 750 break; 751 } 752 753 /* XXX Add a check to discard nodes without Power Resources? */ 754 if (pdev == NULL) 755 return; 756 757 SIMPLEQ_FOREACH(pr, &sc->sc_pwrresdevs, p_next) { 758 if (pr->p_node != pdev->node) 759 continue; 760 761 /* 762 * If the firmware is already aware that the device 763 * is in the given state, there's nothing to do. 764 */ 765 if (pr->p_state == state) 766 continue; 767 768 if (pre) { 769 /* 770 * If a Resource is dependent on this device for 771 * the given state, make sure it is turned "_ON". 772 */ 773 if (pr->p_res_state == state) 774 acpipwrres_ref_incr(pr->p_res_sc, pr->p_node); 775 } else { 776 /* 777 * If a Resource was referenced for the state we 778 * left, drop a reference and turn it "_OFF" if 779 * it was the last one. 780 */ 781 if (pr->p_res_state == pr->p_state) 782 acpipwrres_ref_decr(pr->p_res_sc, pr->p_node); 783 784 if (pr->p_res_state == state) { 785 snprintf(name, sizeof(name), "_PS%d", state); 786 aml_evalname(sc, pr->p_node, name, 0, 787 NULL, NULL); 788 } 789 790 pr->p_state = state; 791 } 792 793 } 794 #endif /* NACPIPWRRES > 0 */ 795 } 796 797 int 798 acpi_pci_notify(struct aml_node *node, int ntype, void *arg) 799 { 800 struct acpi_pci *pdev = arg; 801 pci_chipset_tag_t pc = NULL; 802 pcitag_t tag; 803 pcireg_t reg; 804 int offset; 805 806 /* We're only interested in Device Wake notifications. */ 807 if (ntype != 2) 808 return (0); 809 810 tag = pci_make_tag(pc, pdev->bus, pdev->dev, pdev->fun); 811 if (pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &offset, 0)) { 812 /* Clear the PME Status bit if it is set. */ 813 reg = pci_conf_read(pc, tag, offset + PCI_PMCSR); 814 pci_conf_write(pc, tag, offset + PCI_PMCSR, reg); 815 } 816 817 return (0); 818 } 819 820 void 821 acpi_pciroots_attach(struct device *dev, void *aux, cfprint_t pr) 822 { 823 struct acpi_pci *pdev; 824 struct pcibus_attach_args *pba = aux; 825 826 KASSERT(pba->pba_busex != NULL); 827 828 TAILQ_FOREACH(pdev, &acpi_pcirootdevs, next) { 829 if (extent_alloc_region(pba->pba_busex, pdev->bus, 830 1, EX_NOWAIT) != 0) 831 continue; 832 pba->pba_bus = pdev->bus; 833 config_found(dev, pba, pr); 834 } 835 } 836 837 /* GPIO support */ 838 839 struct acpi_gpio_event { 840 struct aml_node *node; 841 uint16_t pin; 842 }; 843 844 void 845 acpi_gpio_event_task(void *arg0, int arg1) 846 { 847 struct aml_node *node = arg0; 848 uint16_t pin = arg1; 849 char name[5]; 850 851 snprintf(name, sizeof(name), "_E%.2X", pin); 852 aml_evalname(acpi_softc, node, name, 0, NULL, NULL); 853 } 854 855 int 856 acpi_gpio_event(void *arg) 857 { 858 struct acpi_gpio_event *ev = arg; 859 860 acpi_addtask(acpi_softc, acpi_gpio_event_task, ev->node, ev->pin); 861 return 1; 862 } 863 864 int 865 acpi_gpio_parse_events(int crsidx, union acpi_resource *crs, void *arg) 866 { 867 struct aml_node *devnode = arg; 868 struct aml_node *node; 869 uint16_t pin; 870 871 switch (AML_CRSTYPE(crs)) { 872 case LR_GPIO: 873 node = aml_searchname(devnode, 874 (char *)&crs->pad[crs->lr_gpio.res_off]); 875 pin = *(uint16_t *)&crs->pad[crs->lr_gpio.pin_off]; 876 if (crs->lr_gpio.type == LR_GPIO_INT && 877 node && node->gpio && pin < 256) { 878 struct acpi_gpio *gpio = node->gpio; 879 struct acpi_gpio_event *ev; 880 881 ev = malloc(sizeof(*ev), M_DEVBUF, M_WAITOK); 882 ev->node = devnode; 883 ev->pin = pin; 884 gpio->intr_establish(gpio->cookie, pin, 885 crs->lr_gpio.tflags, acpi_gpio_event, ev); 886 } 887 break; 888 default: 889 printf("%s: unknown resource type %d\n", __func__, 890 AML_CRSTYPE(crs)); 891 } 892 893 return 0; 894 } 895 896 void 897 acpi_register_gpio(struct acpi_softc *sc, struct aml_node *devnode) 898 { 899 struct aml_value arg[2]; 900 struct aml_node *node; 901 struct aml_value res; 902 903 /* Register GeneralPurposeIO address space. */ 904 memset(&arg, 0, sizeof(arg)); 905 arg[0].type = AML_OBJTYPE_INTEGER; 906 arg[0].v_integer = ACPI_OPREG_GPIO; 907 arg[1].type = AML_OBJTYPE_INTEGER; 908 arg[1].v_integer = 1; 909 node = aml_searchname(devnode, "_REG"); 910 if (node && aml_evalnode(sc, node, 2, arg, NULL)) 911 printf("%s: _REG failed\n", node->name); 912 913 /* Register GPIO signaled ACPI events. */ 914 if (aml_evalname(sc, devnode, "_AEI", 0, NULL, &res)) 915 return; 916 aml_parse_resource(&res, acpi_gpio_parse_events, devnode); 917 } 918 919 void 920 acpi_attach(struct device *parent, struct device *self, void *aux) 921 { 922 struct bios_attach_args *ba = aux; 923 struct acpi_softc *sc = (struct acpi_softc *)self; 924 struct acpi_mem_map handle; 925 struct acpi_rsdp *rsdp; 926 struct acpi_q *entry; 927 struct acpi_dsdt *p_dsdt; 928 #ifndef SMALL_KERNEL 929 int wakeup_dev_ct; 930 struct acpi_wakeq *wentry; 931 struct device *dev; 932 #endif /* SMALL_KERNEL */ 933 paddr_t facspa; 934 uint16_t pm1; 935 int s; 936 937 sc->sc_iot = ba->ba_iot; 938 sc->sc_memt = ba->ba_memt; 939 940 rw_init(&sc->sc_lck, "acpilk"); 941 942 acpi_softc = sc; 943 944 if (acpi_map(ba->ba_acpipbase, sizeof(struct acpi_rsdp), &handle)) { 945 printf(": can't map memory\n"); 946 return; 947 } 948 949 rsdp = (struct acpi_rsdp *)handle.va; 950 sc->sc_revision = (int)rsdp->rsdp_revision; 951 printf(": rev %d", sc->sc_revision); 952 953 SIMPLEQ_INIT(&sc->sc_tables); 954 SIMPLEQ_INIT(&sc->sc_wakedevs); 955 #if NACPIPWRRES > 0 956 SIMPLEQ_INIT(&sc->sc_pwrresdevs); 957 #endif /* NACPIPWRRES > 0 */ 958 959 960 #ifndef SMALL_KERNEL 961 sc->sc_note = malloc(sizeof(struct klist), M_DEVBUF, M_NOWAIT | M_ZERO); 962 if (sc->sc_note == NULL) { 963 printf(", can't allocate memory\n"); 964 acpi_unmap(&handle); 965 return; 966 } 967 #endif /* SMALL_KERNEL */ 968 969 if (acpi_loadtables(sc, rsdp)) { 970 printf(", can't load tables\n"); 971 acpi_unmap(&handle); 972 return; 973 } 974 975 acpi_unmap(&handle); 976 977 /* 978 * Find the FADT 979 */ 980 SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) { 981 if (memcmp(entry->q_table, FADT_SIG, 982 sizeof(FADT_SIG) - 1) == 0) { 983 sc->sc_fadt = entry->q_table; 984 break; 985 } 986 } 987 if (sc->sc_fadt == NULL) { 988 printf(", no FADT\n"); 989 return; 990 } 991 992 /* 993 * A bunch of things need to be done differently for 994 * Hardware-reduced ACPI. 995 */ 996 if (sc->sc_fadt->hdr_revision >= 5 && 997 sc->sc_fadt->flags & FADT_HW_REDUCED_ACPI) 998 sc->sc_hw_reduced = 1; 999 1000 /* Map Power Management registers */ 1001 acpi_map_pmregs(sc); 1002 1003 /* 1004 * Check if we can and need to enable ACPI control. 1005 */ 1006 pm1 = acpi_read_pmreg(sc, ACPIREG_PM1_CNT, 0); 1007 if ((pm1 & ACPI_PM1_SCI_EN) == 0 && sc->sc_fadt->smi_cmd && 1008 (!sc->sc_fadt->acpi_enable && !sc->sc_fadt->acpi_disable)) { 1009 printf(", ACPI control unavailable\n"); 1010 acpi_unmap_pmregs(sc); 1011 return; 1012 } 1013 1014 /* 1015 * Set up a pointer to the firmware control structure 1016 */ 1017 if (sc->sc_fadt->hdr_revision < 3 || sc->sc_fadt->x_firmware_ctl == 0) 1018 facspa = sc->sc_fadt->firmware_ctl; 1019 else 1020 facspa = sc->sc_fadt->x_firmware_ctl; 1021 1022 if (acpi_map(facspa, sizeof(struct acpi_facs), &handle)) 1023 printf(" !FACS"); 1024 else 1025 sc->sc_facs = (struct acpi_facs *)handle.va; 1026 1027 /* Create opcode hashtable */ 1028 aml_hashopcodes(); 1029 1030 /* Create Default AML objects */ 1031 aml_create_defaultobjects(); 1032 1033 /* 1034 * Load the DSDT from the FADT pointer -- use the 1035 * extended (64-bit) pointer if it exists 1036 */ 1037 if (sc->sc_fadt->hdr_revision < 3 || sc->sc_fadt->x_dsdt == 0) 1038 entry = acpi_maptable(sc, sc->sc_fadt->dsdt, NULL, NULL, NULL, -1); 1039 else 1040 entry = acpi_maptable(sc, sc->sc_fadt->x_dsdt, NULL, NULL, NULL, -1); 1041 1042 if (entry == NULL) 1043 printf(" !DSDT"); 1044 1045 p_dsdt = entry->q_table; 1046 acpi_parse_aml(sc, p_dsdt->aml, p_dsdt->hdr_length - 1047 sizeof(p_dsdt->hdr)); 1048 1049 /* Load SSDT's */ 1050 SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) { 1051 if (memcmp(entry->q_table, SSDT_SIG, 1052 sizeof(SSDT_SIG) - 1) == 0) { 1053 p_dsdt = entry->q_table; 1054 acpi_parse_aml(sc, p_dsdt->aml, p_dsdt->hdr_length - 1055 sizeof(p_dsdt->hdr)); 1056 } 1057 } 1058 1059 /* Perform post-parsing fixups */ 1060 aml_postparse(); 1061 1062 1063 #ifndef SMALL_KERNEL 1064 /* Find available sleeping states */ 1065 acpi_init_states(sc); 1066 1067 /* Find available sleep/resume related methods. */ 1068 acpi_init_pm(sc); 1069 #endif /* SMALL_KERNEL */ 1070 1071 /* Initialize GPE handlers */ 1072 s = spltty(); 1073 acpi_init_gpes(sc); 1074 splx(s); 1075 1076 /* some devices require periodic polling */ 1077 timeout_set(&sc->sc_dev_timeout, acpi_poll, sc); 1078 1079 acpi_enabled = 1; 1080 1081 /* 1082 * Take over ACPI control. Note that once we do this, we 1083 * effectively tell the system that we have ownership of 1084 * the ACPI hardware registers, and that SMI should leave 1085 * them alone 1086 * 1087 * This may prevent thermal control on some systems where 1088 * that actually does work 1089 */ 1090 if ((pm1 & ACPI_PM1_SCI_EN) == 0 && sc->sc_fadt->smi_cmd) { 1091 if (acpi_enable(sc)) { 1092 printf(", can't enable ACPI\n"); 1093 return; 1094 } 1095 } 1096 1097 printf("\n%s: tables", DEVNAME(sc)); 1098 SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) { 1099 printf(" %.4s", (char *)entry->q_table); 1100 } 1101 printf("\n"); 1102 1103 #ifndef SMALL_KERNEL 1104 /* Display wakeup devices and lowest S-state */ 1105 wakeup_dev_ct = 0; 1106 printf("%s: wakeup devices", DEVNAME(sc)); 1107 SIMPLEQ_FOREACH(wentry, &sc->sc_wakedevs, q_next) { 1108 if (wakeup_dev_ct < 16) 1109 printf(" %.4s(S%d)", wentry->q_node->name, 1110 wentry->q_state); 1111 else if (wakeup_dev_ct == 16) 1112 printf(" [...]"); 1113 wakeup_dev_ct ++; 1114 } 1115 printf("\n"); 1116 1117 /* 1118 * ACPI is enabled now -- attach timer 1119 */ 1120 if (!sc->sc_hw_reduced && 1121 (sc->sc_fadt->pm_tmr_blk || sc->sc_fadt->x_pm_tmr_blk.address)) { 1122 struct acpi_attach_args aaa; 1123 1124 memset(&aaa, 0, sizeof(aaa)); 1125 aaa.aaa_name = "acpitimer"; 1126 aaa.aaa_iot = sc->sc_iot; 1127 aaa.aaa_memt = sc->sc_memt; 1128 #if 0 1129 aaa.aaa_pcit = sc->sc_pcit; 1130 aaa.aaa_smbust = sc->sc_smbust; 1131 #endif 1132 config_found(self, &aaa, acpi_print); 1133 } 1134 #endif /* SMALL_KERNEL */ 1135 1136 /* 1137 * Attach table-defined devices 1138 */ 1139 SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) { 1140 struct acpi_attach_args aaa; 1141 1142 memset(&aaa, 0, sizeof(aaa)); 1143 aaa.aaa_iot = sc->sc_iot; 1144 aaa.aaa_memt = sc->sc_memt; 1145 #if 0 1146 aaa.aaa_pcit = sc->sc_pcit; 1147 aaa.aaa_smbust = sc->sc_smbust; 1148 #endif 1149 aaa.aaa_table = entry->q_table; 1150 config_found_sm(self, &aaa, acpi_print, acpi_submatch); 1151 } 1152 1153 /* initialize runtime environment */ 1154 aml_find_node(&aml_root, "_INI", acpi_inidev, sc); 1155 1156 /* Get PCI mapping */ 1157 aml_walknodes(&aml_root, AML_WALK_PRE, acpi_getpci, sc); 1158 1159 /* attach pci interrupt routing tables */ 1160 aml_find_node(&aml_root, "_PRT", acpi_foundprt, sc); 1161 1162 aml_find_node(&aml_root, "_HID", acpi_foundec, sc); 1163 1164 /* check if we're running on a sony */ 1165 aml_find_node(&aml_root, "GBRT", acpi_foundsony, sc); 1166 1167 aml_walknodes(&aml_root, AML_WALK_PRE, acpi_add_device, sc); 1168 1169 #ifndef SMALL_KERNEL 1170 /* try to find smart battery first */ 1171 aml_find_node(&aml_root, "_HID", acpi_foundsbs, sc); 1172 #endif /* SMALL_KERNEL */ 1173 1174 /* attach battery, power supply and button devices */ 1175 aml_find_node(&aml_root, "_HID", acpi_foundhid, sc); 1176 1177 #ifndef SMALL_KERNEL 1178 #if NWD > 0 1179 /* Attach IDE bay */ 1180 aml_walknodes(&aml_root, AML_WALK_PRE, acpi_foundide, sc); 1181 #endif 1182 1183 /* attach docks */ 1184 aml_find_node(&aml_root, "_DCK", acpi_founddock, sc); 1185 1186 /* attach video */ 1187 aml_find_node(&aml_root, "_DOS", acpi_foundvideo, sc); 1188 1189 /* create list of devices we want to query when APM comes in */ 1190 SLIST_INIT(&sc->sc_ac); 1191 SLIST_INIT(&sc->sc_bat); 1192 TAILQ_FOREACH(dev, &alldevs, dv_list) { 1193 if (!strcmp(dev->dv_cfdata->cf_driver->cd_name, "acpiac")) { 1194 struct acpi_ac *ac; 1195 1196 ac = malloc(sizeof(*ac), M_DEVBUF, M_WAITOK | M_ZERO); 1197 ac->aac_softc = (struct acpiac_softc *)dev; 1198 SLIST_INSERT_HEAD(&sc->sc_ac, ac, aac_link); 1199 } else if (!strcmp(dev->dv_cfdata->cf_driver->cd_name, "acpibat")) { 1200 struct acpi_bat *bat; 1201 1202 bat = malloc(sizeof(*bat), M_DEVBUF, M_WAITOK | M_ZERO); 1203 bat->aba_softc = (struct acpibat_softc *)dev; 1204 SLIST_INSERT_HEAD(&sc->sc_bat, bat, aba_link); 1205 } else if (!strcmp(dev->dv_cfdata->cf_driver->cd_name, "acpisbs")) { 1206 struct acpi_sbs *sbs; 1207 1208 sbs = malloc(sizeof(*sbs), M_DEVBUF, M_WAITOK | M_ZERO); 1209 sbs->asbs_softc = (struct acpisbs_softc *)dev; 1210 SLIST_INSERT_HEAD(&sc->sc_sbs, sbs, asbs_link); 1211 } 1212 } 1213 1214 #endif /* SMALL_KERNEL */ 1215 1216 /* Setup threads */ 1217 sc->sc_thread = malloc(sizeof(struct acpi_thread), M_DEVBUF, M_WAITOK); 1218 sc->sc_thread->sc = sc; 1219 sc->sc_thread->running = 1; 1220 1221 /* Enable PCI Power Management. */ 1222 pci_dopm = 1; 1223 1224 acpi_attach_machdep(sc); 1225 1226 kthread_create_deferred(acpi_create_thread, sc); 1227 } 1228 1229 int 1230 acpi_submatch(struct device *parent, void *match, void *aux) 1231 { 1232 struct acpi_attach_args *aaa = (struct acpi_attach_args *)aux; 1233 struct cfdata *cf = match; 1234 1235 if (aaa->aaa_table == NULL) 1236 return (0); 1237 return ((*cf->cf_attach->ca_match)(parent, match, aux)); 1238 } 1239 1240 int 1241 acpi_print(void *aux, const char *pnp) 1242 { 1243 struct acpi_attach_args *aa = aux; 1244 1245 if (pnp) { 1246 if (aa->aaa_name) 1247 printf("%s at %s", aa->aaa_name, pnp); 1248 else if (aa->aaa_dev) 1249 printf("\"%s\" at %s", aa->aaa_dev, pnp); 1250 else 1251 return (QUIET); 1252 } 1253 1254 return (UNCONF); 1255 } 1256 1257 struct acpi_q * 1258 acpi_maptable(struct acpi_softc *sc, paddr_t addr, const char *sig, 1259 const char *oem, const char *tbl, int flag) 1260 { 1261 static int tblid; 1262 struct acpi_mem_map handle; 1263 struct acpi_table_header *hdr; 1264 struct acpi_q *entry; 1265 size_t len; 1266 1267 /* Check if we can map address */ 1268 if (addr == 0) 1269 return NULL; 1270 if (acpi_map(addr, sizeof(*hdr), &handle)) 1271 return NULL; 1272 hdr = (struct acpi_table_header *)handle.va; 1273 len = hdr->length; 1274 acpi_unmap(&handle); 1275 1276 /* Validate length/checksum */ 1277 if (acpi_map(addr, len, &handle)) 1278 return NULL; 1279 hdr = (struct acpi_table_header *)handle.va; 1280 if (acpi_checksum(hdr, len)) 1281 printf("\n%s: %.4s checksum error", 1282 DEVNAME(sc), hdr->signature); 1283 1284 if ((sig && memcmp(sig, hdr->signature, 4)) || 1285 (oem && memcmp(oem, hdr->oemid, 6)) || 1286 (tbl && memcmp(tbl, hdr->oemtableid, 8))) { 1287 acpi_unmap(&handle); 1288 return NULL; 1289 } 1290 1291 /* Allocate copy */ 1292 entry = malloc(sizeof(*entry) + len, M_DEVBUF, M_NOWAIT); 1293 if (entry != NULL) { 1294 memcpy(entry->q_data, handle.va, len); 1295 entry->q_table = entry->q_data; 1296 entry->q_id = ++tblid; 1297 1298 if (flag < 0) 1299 SIMPLEQ_INSERT_HEAD(&sc->sc_tables, entry, 1300 q_next); 1301 else if (flag > 0) 1302 SIMPLEQ_INSERT_TAIL(&sc->sc_tables, entry, 1303 q_next); 1304 } 1305 acpi_unmap(&handle); 1306 return entry; 1307 } 1308 1309 int 1310 acpi_loadtables(struct acpi_softc *sc, struct acpi_rsdp *rsdp) 1311 { 1312 struct acpi_q *sdt; 1313 int i, ntables; 1314 size_t len; 1315 1316 if (rsdp->rsdp_revision == 2 && rsdp->rsdp_xsdt) { 1317 struct acpi_xsdt *xsdt; 1318 1319 sdt = acpi_maptable(sc, rsdp->rsdp_xsdt, NULL, NULL, NULL, 0); 1320 if (sdt == NULL) { 1321 printf("couldn't map rsdt\n"); 1322 return (ENOMEM); 1323 } 1324 1325 xsdt = (struct acpi_xsdt *)sdt->q_data; 1326 len = xsdt->hdr.length; 1327 ntables = (len - sizeof(struct acpi_table_header)) / 1328 sizeof(xsdt->table_offsets[0]); 1329 1330 for (i = 0; i < ntables; i++) 1331 acpi_maptable(sc, xsdt->table_offsets[i], NULL, NULL, 1332 NULL, 1); 1333 1334 free(sdt, M_DEVBUF, 0); 1335 } else { 1336 struct acpi_rsdt *rsdt; 1337 1338 sdt = acpi_maptable(sc, rsdp->rsdp_rsdt, NULL, NULL, NULL, 0); 1339 if (sdt == NULL) { 1340 printf("couldn't map rsdt\n"); 1341 return (ENOMEM); 1342 } 1343 1344 rsdt = (struct acpi_rsdt *)sdt->q_data; 1345 len = rsdt->hdr.length; 1346 ntables = (len - sizeof(struct acpi_table_header)) / 1347 sizeof(rsdt->table_offsets[0]); 1348 1349 for (i = 0; i < ntables; i++) 1350 acpi_maptable(sc, rsdt->table_offsets[i], NULL, NULL, 1351 NULL, 1); 1352 1353 free(sdt, M_DEVBUF, 0); 1354 } 1355 1356 return (0); 1357 } 1358 1359 /* Read from power management register */ 1360 int 1361 acpi_read_pmreg(struct acpi_softc *sc, int reg, int offset) 1362 { 1363 bus_space_handle_t ioh; 1364 bus_size_t size; 1365 int regval; 1366 1367 /* 1368 * For Hardware-reduced ACPI we emulate PM1B_CNT to reflect 1369 * that the system is always in ACPI mode. 1370 */ 1371 if (sc->sc_hw_reduced && reg == ACPIREG_PM1B_CNT) { 1372 KASSERT(offset == 0); 1373 return ACPI_PM1_SCI_EN; 1374 } 1375 1376 /* 1377 * For Hardware-reduced ACPI we also emulate PM1A_STS using 1378 * SLEEP_STATUS_REG. 1379 */ 1380 if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_STS) { 1381 uint8_t value; 1382 1383 KASSERT(offset == 0); 1384 acpi_gasio(sc, ACPI_IOREAD, 1385 sc->sc_fadt->sleep_status_reg.address_space_id, 1386 sc->sc_fadt->sleep_status_reg.address, 1387 sc->sc_fadt->sleep_status_reg.register_bit_width / 8, 1388 sc->sc_fadt->sleep_status_reg.access_size, &value); 1389 return ((int)value << 8); 1390 } 1391 1392 /* Special cases: 1A/1B blocks can be OR'ed together */ 1393 switch (reg) { 1394 case ACPIREG_PM1_EN: 1395 return (acpi_read_pmreg(sc, ACPIREG_PM1A_EN, offset) | 1396 acpi_read_pmreg(sc, ACPIREG_PM1B_EN, offset)); 1397 case ACPIREG_PM1_STS: 1398 return (acpi_read_pmreg(sc, ACPIREG_PM1A_STS, offset) | 1399 acpi_read_pmreg(sc, ACPIREG_PM1B_STS, offset)); 1400 case ACPIREG_PM1_CNT: 1401 return (acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, offset) | 1402 acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, offset)); 1403 case ACPIREG_GPE_STS: 1404 dnprintf(50, "read GPE_STS offset: %.2x %.2x %.2x\n", offset, 1405 sc->sc_fadt->gpe0_blk_len>>1, sc->sc_fadt->gpe1_blk_len>>1); 1406 if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { 1407 reg = ACPIREG_GPE0_STS; 1408 } 1409 break; 1410 case ACPIREG_GPE_EN: 1411 dnprintf(50, "read GPE_EN offset: %.2x %.2x %.2x\n", 1412 offset, sc->sc_fadt->gpe0_blk_len>>1, 1413 sc->sc_fadt->gpe1_blk_len>>1); 1414 if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { 1415 reg = ACPIREG_GPE0_EN; 1416 } 1417 break; 1418 } 1419 1420 if (reg >= ACPIREG_MAXREG || sc->sc_pmregs[reg].size == 0) 1421 return (0); 1422 1423 regval = 0; 1424 ioh = sc->sc_pmregs[reg].ioh; 1425 size = sc->sc_pmregs[reg].size; 1426 if (size > sc->sc_pmregs[reg].access) 1427 size = sc->sc_pmregs[reg].access; 1428 1429 switch (size) { 1430 case 1: 1431 regval = bus_space_read_1(sc->sc_iot, ioh, offset); 1432 break; 1433 case 2: 1434 regval = bus_space_read_2(sc->sc_iot, ioh, offset); 1435 break; 1436 case 4: 1437 regval = bus_space_read_4(sc->sc_iot, ioh, offset); 1438 break; 1439 } 1440 1441 dnprintf(30, "acpi_readpm: %s = %.4x:%.4x %x\n", 1442 sc->sc_pmregs[reg].name, 1443 sc->sc_pmregs[reg].addr, offset, regval); 1444 return (regval); 1445 } 1446 1447 /* Write to power management register */ 1448 void 1449 acpi_write_pmreg(struct acpi_softc *sc, int reg, int offset, int regval) 1450 { 1451 bus_space_handle_t ioh; 1452 bus_size_t size; 1453 1454 /* 1455 * For Hardware-reduced ACPI we also emulate PM1A_STS using 1456 * SLEEP_STATUS_REG. 1457 */ 1458 if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_STS) { 1459 uint8_t value = (regval >> 8); 1460 1461 KASSERT(offset == 0); 1462 acpi_gasio(sc, ACPI_IOWRITE, 1463 sc->sc_fadt->sleep_status_reg.address_space_id, 1464 sc->sc_fadt->sleep_status_reg.address, 1465 sc->sc_fadt->sleep_status_reg.register_bit_width / 8, 1466 sc->sc_fadt->sleep_status_reg.access_size, &value); 1467 return; 1468 } 1469 1470 /* 1471 * For Hardware-reduced ACPI we also emulate PM1A_CNT using 1472 * SLEEP_CONTROL_REG. 1473 */ 1474 if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_CNT) { 1475 uint8_t value = (regval >> 8); 1476 1477 KASSERT(offset == 0); 1478 acpi_gasio(sc, ACPI_IOWRITE, 1479 sc->sc_fadt->sleep_control_reg.address_space_id, 1480 sc->sc_fadt->sleep_control_reg.address, 1481 sc->sc_fadt->sleep_control_reg.register_bit_width / 8, 1482 sc->sc_fadt->sleep_control_reg.access_size, &value); 1483 return; 1484 } 1485 1486 /* Special cases: 1A/1B blocks can be written with same value */ 1487 switch (reg) { 1488 case ACPIREG_PM1_EN: 1489 acpi_write_pmreg(sc, ACPIREG_PM1A_EN, offset, regval); 1490 acpi_write_pmreg(sc, ACPIREG_PM1B_EN, offset, regval); 1491 break; 1492 case ACPIREG_PM1_STS: 1493 acpi_write_pmreg(sc, ACPIREG_PM1A_STS, offset, regval); 1494 acpi_write_pmreg(sc, ACPIREG_PM1B_STS, offset, regval); 1495 break; 1496 case ACPIREG_PM1_CNT: 1497 acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, offset, regval); 1498 acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, offset, regval); 1499 break; 1500 case ACPIREG_GPE_STS: 1501 dnprintf(50, "write GPE_STS offset: %.2x %.2x %.2x %.2x\n", 1502 offset, sc->sc_fadt->gpe0_blk_len>>1, 1503 sc->sc_fadt->gpe1_blk_len>>1, regval); 1504 if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { 1505 reg = ACPIREG_GPE0_STS; 1506 } 1507 break; 1508 case ACPIREG_GPE_EN: 1509 dnprintf(50, "write GPE_EN offset: %.2x %.2x %.2x %.2x\n", 1510 offset, sc->sc_fadt->gpe0_blk_len>>1, 1511 sc->sc_fadt->gpe1_blk_len>>1, regval); 1512 if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { 1513 reg = ACPIREG_GPE0_EN; 1514 } 1515 break; 1516 } 1517 1518 /* All special case return here */ 1519 if (reg >= ACPIREG_MAXREG) 1520 return; 1521 1522 ioh = sc->sc_pmregs[reg].ioh; 1523 size = sc->sc_pmregs[reg].size; 1524 if (size > sc->sc_pmregs[reg].access) 1525 size = sc->sc_pmregs[reg].access; 1526 1527 switch (size) { 1528 case 1: 1529 bus_space_write_1(sc->sc_iot, ioh, offset, regval); 1530 break; 1531 case 2: 1532 bus_space_write_2(sc->sc_iot, ioh, offset, regval); 1533 break; 1534 case 4: 1535 bus_space_write_4(sc->sc_iot, ioh, offset, regval); 1536 break; 1537 } 1538 1539 dnprintf(30, "acpi_writepm: %s = %.4x:%.4x %x\n", 1540 sc->sc_pmregs[reg].name, sc->sc_pmregs[reg].addr, offset, regval); 1541 } 1542 1543 /* Map Power Management registers */ 1544 void 1545 acpi_map_pmregs(struct acpi_softc *sc) 1546 { 1547 bus_addr_t addr; 1548 bus_size_t size, access; 1549 const char *name; 1550 int reg; 1551 1552 /* Registers don't exist on Hardware-reduced ACPI. */ 1553 if (sc->sc_hw_reduced) 1554 return; 1555 1556 for (reg = 0; reg < ACPIREG_MAXREG; reg++) { 1557 size = 0; 1558 access = 0; 1559 switch (reg) { 1560 case ACPIREG_SMICMD: 1561 name = "smi"; 1562 size = access = 1; 1563 addr = sc->sc_fadt->smi_cmd; 1564 break; 1565 case ACPIREG_PM1A_STS: 1566 case ACPIREG_PM1A_EN: 1567 name = "pm1a_sts"; 1568 size = sc->sc_fadt->pm1_evt_len >> 1; 1569 addr = sc->sc_fadt->pm1a_evt_blk; 1570 access = 2; 1571 if (reg == ACPIREG_PM1A_EN && addr) { 1572 addr += size; 1573 name = "pm1a_en"; 1574 } 1575 break; 1576 case ACPIREG_PM1A_CNT: 1577 name = "pm1a_cnt"; 1578 size = sc->sc_fadt->pm1_cnt_len; 1579 addr = sc->sc_fadt->pm1a_cnt_blk; 1580 access = 2; 1581 break; 1582 case ACPIREG_PM1B_STS: 1583 case ACPIREG_PM1B_EN: 1584 name = "pm1b_sts"; 1585 size = sc->sc_fadt->pm1_evt_len >> 1; 1586 addr = sc->sc_fadt->pm1b_evt_blk; 1587 access = 2; 1588 if (reg == ACPIREG_PM1B_EN && addr) { 1589 addr += size; 1590 name = "pm1b_en"; 1591 } 1592 break; 1593 case ACPIREG_PM1B_CNT: 1594 name = "pm1b_cnt"; 1595 size = sc->sc_fadt->pm1_cnt_len; 1596 addr = sc->sc_fadt->pm1b_cnt_blk; 1597 access = 2; 1598 break; 1599 case ACPIREG_PM2_CNT: 1600 name = "pm2_cnt"; 1601 size = sc->sc_fadt->pm2_cnt_len; 1602 addr = sc->sc_fadt->pm2_cnt_blk; 1603 access = size; 1604 break; 1605 #if 0 1606 case ACPIREG_PM_TMR: 1607 /* Allocated in acpitimer */ 1608 name = "pm_tmr"; 1609 size = sc->sc_fadt->pm_tmr_len; 1610 addr = sc->sc_fadt->pm_tmr_blk; 1611 access = 4; 1612 break; 1613 #endif 1614 case ACPIREG_GPE0_STS: 1615 case ACPIREG_GPE0_EN: 1616 name = "gpe0_sts"; 1617 size = sc->sc_fadt->gpe0_blk_len >> 1; 1618 addr = sc->sc_fadt->gpe0_blk; 1619 access = 1; 1620 1621 dnprintf(20, "gpe0 block len : %x\n", 1622 sc->sc_fadt->gpe0_blk_len >> 1); 1623 dnprintf(20, "gpe0 block addr: %x\n", 1624 sc->sc_fadt->gpe0_blk); 1625 if (reg == ACPIREG_GPE0_EN && addr) { 1626 addr += size; 1627 name = "gpe0_en"; 1628 } 1629 break; 1630 case ACPIREG_GPE1_STS: 1631 case ACPIREG_GPE1_EN: 1632 name = "gpe1_sts"; 1633 size = sc->sc_fadt->gpe1_blk_len >> 1; 1634 addr = sc->sc_fadt->gpe1_blk; 1635 access = 1; 1636 1637 dnprintf(20, "gpe1 block len : %x\n", 1638 sc->sc_fadt->gpe1_blk_len >> 1); 1639 dnprintf(20, "gpe1 block addr: %x\n", 1640 sc->sc_fadt->gpe1_blk); 1641 if (reg == ACPIREG_GPE1_EN && addr) { 1642 addr += size; 1643 name = "gpe1_en"; 1644 } 1645 break; 1646 } 1647 if (size && addr) { 1648 dnprintf(50, "mapping: %.4lx %.4lx %s\n", 1649 addr, size, name); 1650 1651 /* Size and address exist; map register space */ 1652 bus_space_map(sc->sc_iot, addr, size, 0, 1653 &sc->sc_pmregs[reg].ioh); 1654 1655 sc->sc_pmregs[reg].name = name; 1656 sc->sc_pmregs[reg].size = size; 1657 sc->sc_pmregs[reg].addr = addr; 1658 sc->sc_pmregs[reg].access = min(access, 4); 1659 } 1660 } 1661 } 1662 1663 void 1664 acpi_unmap_pmregs(struct acpi_softc *sc) 1665 { 1666 int reg; 1667 1668 for (reg = 0; reg < ACPIREG_MAXREG; reg++) { 1669 if (sc->sc_pmregs[reg].size && sc->sc_pmregs[reg].addr) 1670 bus_space_unmap(sc->sc_iot, sc->sc_pmregs[reg].ioh, 1671 sc->sc_pmregs[reg].size); 1672 } 1673 } 1674 1675 int 1676 acpi_enable(struct acpi_softc *sc) 1677 { 1678 int idx; 1679 1680 acpi_write_pmreg(sc, ACPIREG_SMICMD, 0, sc->sc_fadt->acpi_enable); 1681 idx = 0; 1682 do { 1683 if (idx++ > ACPIEN_RETRIES) { 1684 return ETIMEDOUT; 1685 } 1686 } while (!(acpi_read_pmreg(sc, ACPIREG_PM1_CNT, 0) & ACPI_PM1_SCI_EN)); 1687 1688 return 0; 1689 } 1690 1691 /* ACPI Workqueue support */ 1692 SIMPLEQ_HEAD(,acpi_taskq) acpi_taskq = 1693 SIMPLEQ_HEAD_INITIALIZER(acpi_taskq); 1694 1695 void 1696 acpi_addtask(struct acpi_softc *sc, void (*handler)(void *, int), 1697 void *arg0, int arg1) 1698 { 1699 struct acpi_taskq *wq; 1700 int s; 1701 1702 wq = malloc(sizeof(*wq), M_DEVBUF, M_ZERO | M_NOWAIT); 1703 if (wq == NULL) 1704 return; 1705 wq->handler = handler; 1706 wq->arg0 = arg0; 1707 wq->arg1 = arg1; 1708 1709 s = spltty(); 1710 SIMPLEQ_INSERT_TAIL(&acpi_taskq, wq, next); 1711 splx(s); 1712 } 1713 1714 int 1715 acpi_dotask(struct acpi_softc *sc) 1716 { 1717 struct acpi_taskq *wq; 1718 int s; 1719 1720 s = spltty(); 1721 if (SIMPLEQ_EMPTY(&acpi_taskq)) { 1722 splx(s); 1723 1724 /* we don't have anything to do */ 1725 return (0); 1726 } 1727 wq = SIMPLEQ_FIRST(&acpi_taskq); 1728 SIMPLEQ_REMOVE_HEAD(&acpi_taskq, next); 1729 splx(s); 1730 1731 wq->handler(wq->arg0, wq->arg1); 1732 1733 free(wq, M_DEVBUF, sizeof(*wq)); 1734 1735 /* We did something */ 1736 return (1); 1737 } 1738 1739 #ifndef SMALL_KERNEL 1740 1741 int 1742 is_ata(struct aml_node *node) 1743 { 1744 return (aml_searchname(node, "_GTM") != NULL || 1745 aml_searchname(node, "_GTF") != NULL || 1746 aml_searchname(node, "_STM") != NULL || 1747 aml_searchname(node, "_SDD") != NULL); 1748 } 1749 1750 int 1751 is_ejectable(struct aml_node *node) 1752 { 1753 return (aml_searchname(node, "_EJ0") != NULL); 1754 } 1755 1756 int 1757 is_ejectable_bay(struct aml_node *node) 1758 { 1759 return ((is_ata(node) || is_ata(node->parent)) && is_ejectable(node)); 1760 } 1761 1762 #if NWD > 0 1763 int 1764 acpiide_notify(struct aml_node *node, int ntype, void *arg) 1765 { 1766 struct idechnl *ide = arg; 1767 struct acpi_softc *sc = ide->sc; 1768 struct pciide_softc *wsc; 1769 struct device *dev; 1770 int b,d,f; 1771 int64_t sta; 1772 1773 if (aml_evalinteger(sc, node, "_STA", 0, NULL, &sta) != 0) 1774 return (0); 1775 1776 dnprintf(10, "IDE notify! %s %d status:%llx\n", aml_nodename(node), 1777 ntype, sta); 1778 1779 /* Walk device list looking for IDE device match */ 1780 TAILQ_FOREACH(dev, &alldevs, dv_list) { 1781 if (strcmp(dev->dv_cfdata->cf_driver->cd_name, "pciide")) 1782 continue; 1783 1784 wsc = (struct pciide_softc *)dev; 1785 pci_decompose_tag(NULL, wsc->sc_tag, &b, &d, &f); 1786 if (b != ACPI_PCI_BUS(ide->addr) || 1787 d != ACPI_PCI_DEV(ide->addr) || 1788 f != ACPI_PCI_FN(ide->addr)) 1789 continue; 1790 dnprintf(10, "Found pciide: %s %x.%x.%x channel:%llx\n", 1791 dev->dv_xname, b,d,f, ide->chnl); 1792 1793 if (sta == 0 && ide->sta) 1794 wdcdetach( 1795 &wsc->pciide_channels[ide->chnl].wdc_channel, 0); 1796 else if (sta && !ide->sta) 1797 wdcattach( 1798 &wsc->pciide_channels[ide->chnl].wdc_channel); 1799 ide->sta = sta; 1800 } 1801 return (0); 1802 } 1803 1804 int 1805 acpi_foundide(struct aml_node *node, void *arg) 1806 { 1807 struct acpi_softc *sc = arg; 1808 struct aml_node *pp; 1809 struct idechnl *ide; 1810 union amlpci_t pi; 1811 int lvl; 1812 1813 /* Check if this is an ejectable bay */ 1814 if (!is_ejectable_bay(node)) 1815 return (0); 1816 1817 ide = malloc(sizeof(struct idechnl), M_DEVBUF, M_NOWAIT | M_ZERO); 1818 ide->sc = sc; 1819 1820 /* GTM/GTF can be at 2/3 levels: pciX.ideX.channelX[.driveX] */ 1821 lvl = 0; 1822 for (pp=node->parent; pp; pp=pp->parent) { 1823 lvl++; 1824 if (aml_searchname(pp, "_HID")) 1825 break; 1826 } 1827 1828 /* Get PCI address and channel */ 1829 if (lvl == 3) { 1830 aml_evalinteger(sc, node->parent, "_ADR", 0, NULL, 1831 &ide->chnl); 1832 aml_rdpciaddr(node->parent->parent, &pi); 1833 ide->addr = pi.addr; 1834 } else if (lvl == 4) { 1835 aml_evalinteger(sc, node->parent->parent, "_ADR", 0, NULL, 1836 &ide->chnl); 1837 aml_rdpciaddr(node->parent->parent->parent, &pi); 1838 ide->addr = pi.addr; 1839 } 1840 dnprintf(10, "%s %llx channel:%llx\n", 1841 aml_nodename(node), ide->addr, ide->chnl); 1842 1843 aml_evalinteger(sc, node, "_STA", 0, NULL, &ide->sta); 1844 dnprintf(10, "Got Initial STA: %llx\n", ide->sta); 1845 1846 aml_register_notify(node, "acpiide", acpiide_notify, ide, 0); 1847 return (0); 1848 } 1849 #endif /* NWD > 0 */ 1850 1851 void 1852 acpi_sleep_task(void *arg0, int sleepmode) 1853 { 1854 struct acpi_softc *sc = arg0; 1855 struct acpi_ac *ac; 1856 struct acpi_bat *bat; 1857 struct acpi_sbs *sbs; 1858 1859 /* System goes to sleep here.. */ 1860 acpi_sleep_state(sc, sleepmode); 1861 1862 /* AC and battery information needs refreshing */ 1863 SLIST_FOREACH(ac, &sc->sc_ac, aac_link) 1864 aml_notify(ac->aac_softc->sc_devnode, 0x80); 1865 SLIST_FOREACH(bat, &sc->sc_bat, aba_link) 1866 aml_notify(bat->aba_softc->sc_devnode, 0x80); 1867 SLIST_FOREACH(sbs, &sc->sc_sbs, asbs_link) 1868 aml_notify(sbs->asbs_softc->sc_devnode, 0x80); 1869 } 1870 1871 #endif /* SMALL_KERNEL */ 1872 1873 void 1874 acpi_reset(void) 1875 { 1876 u_int32_t reset_as, reset_len; 1877 u_int32_t value; 1878 struct acpi_softc *sc = acpi_softc; 1879 struct acpi_fadt *fadt = sc->sc_fadt; 1880 1881 if (acpi_enabled == 0) 1882 return; 1883 1884 /* 1885 * RESET_REG_SUP is not properly set in some implementations, 1886 * but not testing against it breaks more machines than it fixes 1887 */ 1888 if (fadt->hdr_revision <= 1 || 1889 !(fadt->flags & FADT_RESET_REG_SUP) || fadt->reset_reg.address == 0) 1890 return; 1891 1892 value = fadt->reset_value; 1893 1894 reset_as = fadt->reset_reg.register_bit_width / 8; 1895 if (reset_as == 0) 1896 reset_as = 1; 1897 1898 reset_len = fadt->reset_reg.access_size; 1899 if (reset_len == 0) 1900 reset_len = reset_as; 1901 1902 acpi_gasio(sc, ACPI_IOWRITE, 1903 fadt->reset_reg.address_space_id, 1904 fadt->reset_reg.address, reset_as, reset_len, &value); 1905 1906 delay(100000); 1907 } 1908 1909 void 1910 acpi_gpe_task(void *arg0, int gpe) 1911 { 1912 struct acpi_softc *sc = acpi_softc; 1913 struct gpe_block *pgpe = &sc->gpe_table[gpe]; 1914 1915 dnprintf(10, "handle gpe: %x\n", gpe); 1916 if (pgpe->handler && pgpe->active) { 1917 pgpe->active = 0; 1918 pgpe->handler(sc, gpe, pgpe->arg); 1919 } 1920 } 1921 1922 void 1923 acpi_pbtn_task(void *arg0, int dummy) 1924 { 1925 struct acpi_softc *sc = arg0; 1926 uint16_t en; 1927 int s; 1928 1929 dnprintf(1,"power button pressed\n"); 1930 1931 /* Reset the latch and re-enable the GPE */ 1932 s = spltty(); 1933 en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); 1934 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, 1935 en | ACPI_PM1_PWRBTN_EN); 1936 splx(s); 1937 1938 acpi_addtask(sc, acpi_powerdown_task, sc, 0); 1939 } 1940 1941 void 1942 acpi_sbtn_task(void *arg0, int dummy) 1943 { 1944 struct acpi_softc *sc = arg0; 1945 uint16_t en; 1946 int s; 1947 1948 dnprintf(1,"sleep button pressed\n"); 1949 aml_notify_dev(ACPI_DEV_SBD, 0x80); 1950 1951 /* Reset the latch and re-enable the GPE */ 1952 s = spltty(); 1953 en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); 1954 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, 1955 en | ACPI_PM1_SLPBTN_EN); 1956 splx(s); 1957 } 1958 1959 void 1960 acpi_powerdown_task(void *arg0, int dummy) 1961 { 1962 extern int allowpowerdown; 1963 1964 if (allowpowerdown == 1) { 1965 allowpowerdown = 0; 1966 prsignal(initprocess, SIGUSR2); 1967 } 1968 } 1969 1970 int 1971 acpi_interrupt(void *arg) 1972 { 1973 struct acpi_softc *sc = (struct acpi_softc *)arg; 1974 u_int32_t processed = 0, idx, jdx; 1975 u_int16_t sts, en; 1976 1977 dnprintf(40, "ACPI Interrupt\n"); 1978 for (idx = 0; idx < sc->sc_lastgpe; idx += 8) { 1979 sts = acpi_read_pmreg(sc, ACPIREG_GPE_STS, idx>>3); 1980 en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, idx>>3); 1981 if (en & sts) { 1982 dnprintf(10, "GPE block: %.2x %.2x %.2x\n", idx, sts, 1983 en); 1984 /* Mask the GPE until it is serviced */ 1985 acpi_write_pmreg(sc, ACPIREG_GPE_EN, idx>>3, en & ~sts); 1986 for (jdx = 0; jdx < 8; jdx++) { 1987 if (en & sts & (1L << jdx)) { 1988 /* Signal this GPE */ 1989 sc->gpe_table[idx+jdx].active = 1; 1990 dnprintf(10, "queue gpe: %x\n", idx+jdx); 1991 acpi_addtask(sc, acpi_gpe_task, NULL, idx+jdx); 1992 1993 /* 1994 * Edge interrupts need their STS bits 1995 * cleared now. Level interrupts will 1996 * have their STS bits cleared just 1997 * before they are re-enabled. 1998 */ 1999 if (sc->gpe_table[idx+jdx].edge) 2000 acpi_write_pmreg(sc, 2001 ACPIREG_GPE_STS, idx>>3, 2002 1L << jdx); 2003 processed = 1; 2004 } 2005 } 2006 } 2007 } 2008 2009 sts = acpi_read_pmreg(sc, ACPIREG_PM1_STS, 0); 2010 en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); 2011 if (sts & en) { 2012 dnprintf(10,"GEN interrupt: %.4x\n", sts & en); 2013 sts &= en; 2014 if (sts & ACPI_PM1_PWRBTN_STS) { 2015 /* Mask and acknowledge */ 2016 en &= ~ACPI_PM1_PWRBTN_EN; 2017 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en); 2018 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, 2019 ACPI_PM1_PWRBTN_STS); 2020 sts &= ~ACPI_PM1_PWRBTN_STS; 2021 2022 acpi_addtask(sc, acpi_pbtn_task, sc, 0); 2023 } 2024 if (sts & ACPI_PM1_SLPBTN_STS) { 2025 /* Mask and acknowledge */ 2026 en &= ~ACPI_PM1_SLPBTN_EN; 2027 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en); 2028 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, 2029 ACPI_PM1_SLPBTN_STS); 2030 sts &= ~ACPI_PM1_SLPBTN_STS; 2031 2032 acpi_addtask(sc, acpi_sbtn_task, sc, 0); 2033 } 2034 if (sts) { 2035 printf("%s: PM1 stuck (en 0x%x st 0x%x), clearing\n", 2036 sc->sc_dev.dv_xname, en, sts); 2037 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en & ~sts); 2038 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, sts); 2039 } 2040 processed = 1; 2041 } 2042 2043 if (processed) { 2044 acpi_wakeup(sc); 2045 } 2046 2047 return (processed); 2048 } 2049 2050 int 2051 acpi_add_device(struct aml_node *node, void *arg) 2052 { 2053 static int nacpicpus = 0; 2054 struct device *self = arg; 2055 struct acpi_softc *sc = arg; 2056 struct acpi_attach_args aaa; 2057 struct aml_value res; 2058 CPU_INFO_ITERATOR cii; 2059 struct cpu_info *ci; 2060 int proc_id = -1; 2061 2062 memset(&aaa, 0, sizeof(aaa)); 2063 aaa.aaa_node = node; 2064 aaa.aaa_iot = sc->sc_iot; 2065 aaa.aaa_memt = sc->sc_memt; 2066 if (node == NULL || node->value == NULL) 2067 return 0; 2068 2069 switch (node->value->type) { 2070 case AML_OBJTYPE_PROCESSOR: 2071 if (nacpicpus >= ncpus) 2072 return 0; 2073 if (aml_evalnode(sc, aaa.aaa_node, 0, NULL, &res) == 0) { 2074 if (res.type == AML_OBJTYPE_PROCESSOR) 2075 proc_id = res.v_processor.proc_id; 2076 aml_freevalue(&res); 2077 } 2078 CPU_INFO_FOREACH(cii, ci) { 2079 if (ci->ci_acpi_proc_id == proc_id) 2080 break; 2081 } 2082 if (ci == NULL) 2083 return 0; 2084 nacpicpus++; 2085 2086 aaa.aaa_name = "acpicpu"; 2087 break; 2088 case AML_OBJTYPE_THERMZONE: 2089 aaa.aaa_name = "acpitz"; 2090 break; 2091 case AML_OBJTYPE_POWERRSRC: 2092 aaa.aaa_name = "acpipwrres"; 2093 break; 2094 default: 2095 return 0; 2096 } 2097 config_found(self, &aaa, acpi_print); 2098 return 0; 2099 } 2100 2101 void 2102 acpi_enable_onegpe(struct acpi_softc *sc, int gpe) 2103 { 2104 uint8_t mask, en; 2105 2106 /* Read enabled register */ 2107 mask = (1L << (gpe & 7)); 2108 en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, gpe>>3); 2109 dnprintf(50, "enabling GPE %.2x (current: %sabled) %.2x\n", 2110 gpe, (en & mask) ? "en" : "dis", en); 2111 acpi_write_pmreg(sc, ACPIREG_GPE_EN, gpe>>3, en | mask); 2112 } 2113 2114 /* Clear all GPEs */ 2115 void 2116 acpi_disable_allgpes(struct acpi_softc *sc) 2117 { 2118 int idx; 2119 2120 for (idx = 0; idx < sc->sc_lastgpe; idx += 8) { 2121 acpi_write_pmreg(sc, ACPIREG_GPE_EN, idx >> 3, 0); 2122 acpi_write_pmreg(sc, ACPIREG_GPE_STS, idx >> 3, -1); 2123 } 2124 } 2125 2126 /* Enable runtime GPEs */ 2127 void 2128 acpi_enable_rungpes(struct acpi_softc *sc) 2129 { 2130 int idx; 2131 2132 for (idx = 0; idx < sc->sc_lastgpe; idx++) 2133 if (sc->gpe_table[idx].handler) 2134 acpi_enable_onegpe(sc, idx); 2135 } 2136 2137 /* Enable wakeup GPEs */ 2138 void 2139 acpi_enable_wakegpes(struct acpi_softc *sc, int state) 2140 { 2141 struct acpi_wakeq *wentry; 2142 2143 SIMPLEQ_FOREACH(wentry, &sc->sc_wakedevs, q_next) { 2144 dnprintf(10, "%.4s(S%d) gpe %.2x\n", wentry->q_node->name, 2145 wentry->q_state, 2146 wentry->q_gpe); 2147 if (state <= wentry->q_state) 2148 acpi_enable_onegpe(sc, wentry->q_gpe); 2149 } 2150 } 2151 2152 int 2153 acpi_set_gpehandler(struct acpi_softc *sc, int gpe, int (*handler) 2154 (struct acpi_softc *, int, void *), void *arg, int edge) 2155 { 2156 struct gpe_block *ptbl; 2157 2158 ptbl = acpi_find_gpe(sc, gpe); 2159 if (ptbl == NULL || handler == NULL) 2160 return -EINVAL; 2161 if (ptbl->handler != NULL) { 2162 dnprintf(10, "error: GPE %.2x already enabled\n", gpe); 2163 return -EBUSY; 2164 } 2165 dnprintf(50, "Adding GPE handler %.2x (%s)\n", gpe, edge ? "edge" : "level"); 2166 ptbl->handler = handler; 2167 ptbl->arg = arg; 2168 ptbl->edge = edge; 2169 2170 return (0); 2171 } 2172 2173 int 2174 acpi_gpe(struct acpi_softc *sc, int gpe, void *arg) 2175 { 2176 struct aml_node *node = arg; 2177 uint8_t mask, en; 2178 2179 dnprintf(10, "handling GPE %.2x\n", gpe); 2180 aml_evalnode(sc, node, 0, NULL, NULL); 2181 2182 mask = (1L << (gpe & 7)); 2183 if (!sc->gpe_table[gpe].edge) 2184 acpi_write_pmreg(sc, ACPIREG_GPE_STS, gpe>>3, mask); 2185 en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, gpe>>3); 2186 acpi_write_pmreg(sc, ACPIREG_GPE_EN, gpe>>3, en | mask); 2187 return (0); 2188 } 2189 2190 /* Discover Devices that can wakeup the system 2191 * _PRW returns a package 2192 * pkg[0] = integer (FADT gpe bit) or package (gpe block,gpe bit) 2193 * pkg[1] = lowest sleep state 2194 * pkg[2+] = power resource devices (optional) 2195 * 2196 * To enable wakeup devices: 2197 * Evaluate _ON method in each power resource device 2198 * Evaluate _PSW method 2199 */ 2200 int 2201 acpi_foundprw(struct aml_node *node, void *arg) 2202 { 2203 struct acpi_softc *sc = arg; 2204 struct acpi_wakeq *wq; 2205 int64_t sta; 2206 2207 if (aml_evalinteger(sc, node->parent, "_STA", 0, NULL, &sta)) 2208 sta = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000; 2209 2210 if ((sta & STA_PRESENT) == 0) 2211 return 0; 2212 2213 wq = malloc(sizeof(struct acpi_wakeq), M_DEVBUF, M_NOWAIT | M_ZERO); 2214 if (wq == NULL) 2215 return 0; 2216 2217 wq->q_wakepkg = malloc(sizeof(struct aml_value), M_DEVBUF, 2218 M_NOWAIT | M_ZERO); 2219 if (wq->q_wakepkg == NULL) { 2220 free(wq, M_DEVBUF, sizeof(*wq)); 2221 return 0; 2222 } 2223 dnprintf(10, "Found _PRW (%s)\n", node->parent->name); 2224 aml_evalnode(sc, node, 0, NULL, wq->q_wakepkg); 2225 wq->q_node = node->parent; 2226 wq->q_gpe = -1; 2227 2228 /* Get GPE of wakeup device, and lowest sleep level */ 2229 if (wq->q_wakepkg->type == AML_OBJTYPE_PACKAGE && 2230 wq->q_wakepkg->length >= 2) { 2231 if (wq->q_wakepkg->v_package[0]->type == AML_OBJTYPE_INTEGER) 2232 wq->q_gpe = wq->q_wakepkg->v_package[0]->v_integer; 2233 if (wq->q_wakepkg->v_package[1]->type == AML_OBJTYPE_INTEGER) 2234 wq->q_state = wq->q_wakepkg->v_package[1]->v_integer; 2235 } 2236 SIMPLEQ_INSERT_TAIL(&sc->sc_wakedevs, wq, q_next); 2237 return 0; 2238 } 2239 2240 struct gpe_block * 2241 acpi_find_gpe(struct acpi_softc *sc, int gpe) 2242 { 2243 if (gpe >= sc->sc_lastgpe) 2244 return NULL; 2245 return &sc->gpe_table[gpe]; 2246 } 2247 2248 void 2249 acpi_init_gpes(struct acpi_softc *sc) 2250 { 2251 struct aml_node *gpe; 2252 char name[12]; 2253 int idx, ngpe; 2254 2255 sc->sc_lastgpe = sc->sc_fadt->gpe0_blk_len << 2; 2256 if (sc->sc_fadt->gpe1_blk_len) { 2257 } 2258 dnprintf(50, "Last GPE: %.2x\n", sc->sc_lastgpe); 2259 2260 /* Allocate GPE table */ 2261 sc->gpe_table = mallocarray(sc->sc_lastgpe, sizeof(struct gpe_block), 2262 M_DEVBUF, M_WAITOK | M_ZERO); 2263 2264 ngpe = 0; 2265 2266 /* Clear GPE status */ 2267 acpi_disable_allgpes(sc); 2268 for (idx = 0; idx < sc->sc_lastgpe; idx++) { 2269 /* Search Level-sensitive GPES */ 2270 snprintf(name, sizeof(name), "\\_GPE._L%.2X", idx); 2271 gpe = aml_searchname(&aml_root, name); 2272 if (gpe != NULL) 2273 acpi_set_gpehandler(sc, idx, acpi_gpe, gpe, 0); 2274 if (gpe == NULL) { 2275 /* Search Edge-sensitive GPES */ 2276 snprintf(name, sizeof(name), "\\_GPE._E%.2X", idx); 2277 gpe = aml_searchname(&aml_root, name); 2278 if (gpe != NULL) 2279 acpi_set_gpehandler(sc, idx, acpi_gpe, gpe, 1); 2280 } 2281 } 2282 aml_find_node(&aml_root, "_PRW", acpi_foundprw, sc); 2283 sc->sc_maxgpe = ngpe; 2284 } 2285 2286 void 2287 acpi_init_pm(struct acpi_softc *sc) 2288 { 2289 sc->sc_tts = aml_searchname(&aml_root, "_TTS"); 2290 sc->sc_pts = aml_searchname(&aml_root, "_PTS"); 2291 sc->sc_wak = aml_searchname(&aml_root, "_WAK"); 2292 sc->sc_bfs = aml_searchname(&aml_root, "_BFS"); 2293 sc->sc_gts = aml_searchname(&aml_root, "_GTS"); 2294 sc->sc_sst = aml_searchname(&aml_root, "_SI_._SST"); 2295 } 2296 2297 #ifndef SMALL_KERNEL 2298 2299 void 2300 acpi_init_states(struct acpi_softc *sc) 2301 { 2302 struct aml_value res; 2303 char name[8]; 2304 int i; 2305 2306 printf("\n%s: sleep states", DEVNAME(sc)); 2307 for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) { 2308 snprintf(name, sizeof(name), "_S%d_", i); 2309 sc->sc_sleeptype[i].slp_typa = -1; 2310 sc->sc_sleeptype[i].slp_typb = -1; 2311 if (aml_evalname(sc, &aml_root, name, 0, NULL, &res) == 0) { 2312 if (res.type == AML_OBJTYPE_PACKAGE) { 2313 sc->sc_sleeptype[i].slp_typa = aml_val2int(res.v_package[0]); 2314 sc->sc_sleeptype[i].slp_typb = aml_val2int(res.v_package[1]); 2315 printf(" S%d", i); 2316 } 2317 aml_freevalue(&res); 2318 } 2319 } 2320 } 2321 2322 void 2323 acpi_sleep_pm(struct acpi_softc *sc, int state) 2324 { 2325 uint16_t rega, regb, regra, regrb; 2326 int retry = 0; 2327 2328 disable_intr(); 2329 2330 /* Clear WAK_STS bit */ 2331 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_WAK_STS); 2332 2333 /* Disable BM arbitration at deep sleep and beyond */ 2334 if (state >= ACPI_STATE_S3 && 2335 sc->sc_fadt->pm2_cnt_blk && sc->sc_fadt->pm2_cnt_len) 2336 acpi_write_pmreg(sc, ACPIREG_PM2_CNT, 0, ACPI_PM2_ARB_DIS); 2337 2338 /* Write SLP_TYPx values */ 2339 rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0); 2340 regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, 0); 2341 rega &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN); 2342 regb &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN); 2343 rega |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typa); 2344 regb |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typb); 2345 acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega); 2346 acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb); 2347 2348 /* Loop on WAK_STS, setting the SLP_EN bits once in a while */ 2349 rega |= ACPI_PM1_SLP_EN; 2350 regb |= ACPI_PM1_SLP_EN; 2351 while (1) { 2352 if (retry == 0) { 2353 acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega); 2354 acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb); 2355 } 2356 retry = (retry + 1) % 100000; 2357 2358 regra = acpi_read_pmreg(sc, ACPIREG_PM1A_STS, 0); 2359 regrb = acpi_read_pmreg(sc, ACPIREG_PM1B_STS, 0); 2360 if ((regra & ACPI_PM1_WAK_STS) || 2361 (regrb & ACPI_PM1_WAK_STS)) 2362 break; 2363 } 2364 } 2365 2366 u_int32_t acpi_force_bm; 2367 2368 void 2369 acpi_resume_pm(struct acpi_softc *sc, int fromstate) 2370 { 2371 uint16_t rega, regb, en; 2372 2373 /* Write SLP_TYPx values */ 2374 rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0); 2375 regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, 0); 2376 rega &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN); 2377 regb &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN); 2378 rega |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[ACPI_STATE_S0].slp_typa); 2379 regb |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[ACPI_STATE_S0].slp_typb); 2380 acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega); 2381 acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb); 2382 2383 /* Force SCI_EN on resume to fix horribly broken machines */ 2384 acpi_write_pmreg(sc, ACPIREG_PM1_CNT, 0, 2385 ACPI_PM1_SCI_EN | acpi_force_bm); 2386 2387 /* Clear fixed event status */ 2388 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_ALL_STS); 2389 2390 /* acpica-reference.pdf page 148 says do not call _BFS */ 2391 /* 1st resume AML step: _BFS(fromstate) */ 2392 aml_node_setval(sc, sc->sc_bfs, fromstate); 2393 2394 /* Enable runtime GPEs */ 2395 acpi_disable_allgpes(sc); 2396 acpi_enable_rungpes(sc); 2397 2398 acpi_indicator(sc, ACPI_SST_WAKING); 2399 2400 /* 2nd resume AML step: _WAK(fromstate) */ 2401 aml_node_setval(sc, sc->sc_wak, fromstate); 2402 2403 /* Clear WAK_STS bit */ 2404 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_WAK_STS); 2405 2406 en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); 2407 if (!(sc->sc_fadt->flags & FADT_PWR_BUTTON)) 2408 en |= ACPI_PM1_PWRBTN_EN; 2409 if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON)) 2410 en |= ACPI_PM1_SLPBTN_EN; 2411 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en); 2412 2413 /* 2414 * If PM2 exists, re-enable BM arbitration (reportedly some 2415 * BIOS forget to) 2416 */ 2417 if (sc->sc_fadt->pm2_cnt_blk && sc->sc_fadt->pm2_cnt_len) { 2418 rega = acpi_read_pmreg(sc, ACPIREG_PM2_CNT, 0); 2419 rega &= ~ACPI_PM2_ARB_DIS; 2420 acpi_write_pmreg(sc, ACPIREG_PM2_CNT, 0, rega); 2421 } 2422 } 2423 2424 /* Set the indicator light to some state */ 2425 void 2426 acpi_indicator(struct acpi_softc *sc, int led_state) 2427 { 2428 static int save_led_state = -1; 2429 2430 if (save_led_state != led_state) { 2431 aml_node_setval(sc, sc->sc_sst, led_state); 2432 save_led_state = led_state; 2433 } 2434 } 2435 2436 2437 int 2438 acpi_sleep_state(struct acpi_softc *sc, int sleepmode) 2439 { 2440 extern int perflevel; 2441 extern int lid_action; 2442 int error = ENXIO; 2443 size_t rndbuflen = 0; 2444 char *rndbuf = NULL; 2445 int state, s; 2446 2447 switch (sleepmode) { 2448 case ACPI_SLEEP_SUSPEND: 2449 state = ACPI_STATE_S3; 2450 break; 2451 case ACPI_SLEEP_HIBERNATE: 2452 state = ACPI_STATE_S4; 2453 break; 2454 default: 2455 return (EOPNOTSUPP); 2456 } 2457 2458 if (sc->sc_sleeptype[state].slp_typa == -1 || 2459 sc->sc_sleeptype[state].slp_typb == -1) { 2460 printf("%s: state S%d unavailable\n", 2461 sc->sc_dev.dv_xname, state); 2462 return (EOPNOTSUPP); 2463 } 2464 2465 /* 1st suspend AML step: _TTS(tostate) */ 2466 if (aml_node_setval(sc, sc->sc_tts, state) != 0) 2467 goto fail_tts; 2468 acpi_indicator(sc, ACPI_SST_WAKING); /* blink */ 2469 2470 #if NWSDISPLAY > 0 2471 /* 2472 * Temporarily release the lock to prevent the X server from 2473 * blocking on setting the display brightness. 2474 */ 2475 rw_exit_write(&sc->sc_lck); 2476 wsdisplay_suspend(); 2477 rw_enter_write(&sc->sc_lck); 2478 #endif /* NWSDISPLAY > 0 */ 2479 2480 stop_periodic_resettodr(); 2481 2482 #ifdef HIBERNATE 2483 if (sleepmode == ACPI_SLEEP_HIBERNATE) { 2484 uvmpd_hibernate(); 2485 hibernate_suspend_bufcache(); 2486 if (hibernate_alloc()) { 2487 printf("%s: failed to allocate hibernate memory\n", 2488 sc->sc_dev.dv_xname); 2489 goto fail_alloc; 2490 } 2491 } 2492 #endif /* HIBERNATE */ 2493 2494 sensor_quiesce(); 2495 if (config_suspend_all(DVACT_QUIESCE)) 2496 goto fail_quiesce; 2497 2498 bufq_quiesce(); 2499 2500 #ifdef MULTIPROCESSOR 2501 acpi_sleep_mp(); 2502 #endif 2503 2504 resettodr(); 2505 2506 s = splhigh(); 2507 disable_intr(); /* PSL_I for resume; PIC/APIC broken until repair */ 2508 cold = 2; /* Force other code to delay() instead of tsleep() */ 2509 2510 if (config_suspend_all(DVACT_SUSPEND) != 0) 2511 goto fail_suspend; 2512 acpi_sleep_clocks(sc, state); 2513 2514 suspend_randomness(); 2515 2516 /* 2nd suspend AML step: _PTS(tostate) */ 2517 if (aml_node_setval(sc, sc->sc_pts, state) != 0) 2518 goto fail_pts; 2519 2520 acpibtn_enable_psw(); /* enable _LID for wakeup */ 2521 acpi_indicator(sc, ACPI_SST_SLEEPING); 2522 2523 /* 3rd suspend AML step: _GTS(tostate) */ 2524 aml_node_setval(sc, sc->sc_gts, state); 2525 2526 /* Clear fixed event status */ 2527 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_ALL_STS); 2528 2529 /* Enable wake GPEs */ 2530 acpi_disable_allgpes(sc); 2531 acpi_enable_wakegpes(sc, state); 2532 2533 /* Sleep */ 2534 sc->sc_state = state; 2535 error = acpi_sleep_cpu(sc, state); 2536 sc->sc_state = ACPI_STATE_S0; 2537 /* Resume */ 2538 2539 #ifdef HIBERNATE 2540 if (sleepmode == ACPI_SLEEP_HIBERNATE) { 2541 uvm_pmr_dirty_everything(); 2542 hib_getentropy(&rndbuf, &rndbuflen); 2543 } 2544 #endif /* HIBERNATE */ 2545 2546 acpi_resume_clocks(sc); /* AML may need clocks */ 2547 acpi_resume_pm(sc, state); 2548 acpi_resume_cpu(sc); 2549 2550 fail_pts: 2551 config_suspend_all(DVACT_RESUME); 2552 2553 fail_suspend: 2554 cold = 0; 2555 enable_intr(); 2556 splx(s); 2557 2558 acpibtn_disable_psw(); /* disable _LID for wakeup */ 2559 inittodr(time_second); 2560 2561 /* 3rd resume AML step: _TTS(runstate) */ 2562 aml_node_setval(sc, sc->sc_tts, sc->sc_state); 2563 2564 resume_randomness(rndbuf, rndbuflen); /* force RNG upper level reseed */ 2565 2566 #ifdef MULTIPROCESSOR 2567 acpi_resume_mp(); 2568 #endif 2569 2570 bufq_restart(); 2571 2572 fail_quiesce: 2573 config_suspend_all(DVACT_WAKEUP); 2574 sensor_restart(); 2575 2576 #ifdef HIBERNATE 2577 if (sleepmode == ACPI_SLEEP_HIBERNATE) { 2578 hibernate_free(); 2579 fail_alloc: 2580 hibernate_resume_bufcache(); 2581 } 2582 #endif /* HIBERNATE */ 2583 2584 start_periodic_resettodr(); 2585 2586 #if NWSDISPLAY > 0 2587 rw_exit_write(&sc->sc_lck); 2588 wsdisplay_resume(); 2589 rw_enter_write(&sc->sc_lck); 2590 #endif /* NWSDISPLAY > 0 */ 2591 2592 /* Restore hw.setperf */ 2593 if (cpu_setperf != NULL) 2594 cpu_setperf(perflevel); 2595 2596 acpi_record_event(sc, APM_NORMAL_RESUME); 2597 acpi_indicator(sc, ACPI_SST_WORKING); 2598 2599 /* If we woke up but all the lids are closed, go back to sleep */ 2600 if (acpibtn_numopenlids() == 0 && lid_action != 0) 2601 acpi_addtask(sc, acpi_sleep_task, sc, sleepmode); 2602 2603 fail_tts: 2604 return (error); 2605 } 2606 2607 /* XXX 2608 * We are going to do AML execution but are not in the acpi thread. 2609 * We do not know if the acpi thread is sleeping on acpiec in some 2610 * intermediate context. Wish us luck. 2611 */ 2612 void 2613 acpi_powerdown(void) 2614 { 2615 int state = ACPI_STATE_S5, s; 2616 struct acpi_softc *sc = acpi_softc; 2617 2618 if (acpi_enabled == 0) 2619 return; 2620 2621 s = splhigh(); 2622 disable_intr(); 2623 cold = 1; 2624 2625 /* 1st powerdown AML step: _PTS(tostate) */ 2626 aml_node_setval(sc, sc->sc_pts, state); 2627 2628 acpi_disable_allgpes(sc); 2629 acpi_enable_wakegpes(sc, state); 2630 2631 /* 2nd powerdown AML step: _GTS(tostate) */ 2632 aml_node_setval(sc, sc->sc_gts, state); 2633 2634 acpi_sleep_pm(sc, state); 2635 panic("acpi S5 transition did not happen"); 2636 while (1) 2637 ; 2638 } 2639 2640 int 2641 acpi_map_address(struct acpi_softc *sc, struct acpi_gas *gas, bus_addr_t base, 2642 bus_size_t size, bus_space_handle_t *pioh, bus_space_tag_t *piot) 2643 { 2644 int iospace = GAS_SYSTEM_IOSPACE; 2645 2646 /* No GAS structure, default to I/O space */ 2647 if (gas != NULL) { 2648 base += gas->address; 2649 iospace = gas->address_space_id; 2650 } 2651 switch (iospace) { 2652 case GAS_SYSTEM_MEMORY: 2653 *piot = sc->sc_memt; 2654 break; 2655 case GAS_SYSTEM_IOSPACE: 2656 *piot = sc->sc_iot; 2657 break; 2658 default: 2659 return -1; 2660 } 2661 if (bus_space_map(*piot, base, size, 0, pioh)) 2662 return -1; 2663 2664 return 0; 2665 } 2666 2667 #endif /* SMALL_KERNEL */ 2668 2669 void 2670 acpi_wakeup(void *arg) 2671 { 2672 struct acpi_softc *sc = (struct acpi_softc *)arg; 2673 2674 sc->sc_threadwaiting = 0; 2675 wakeup(sc); 2676 } 2677 2678 2679 void 2680 acpi_thread(void *arg) 2681 { 2682 struct acpi_thread *thread = arg; 2683 struct acpi_softc *sc = thread->sc; 2684 extern int aml_busy; 2685 int s; 2686 2687 /* AML/SMI cannot be trusted -- only run on the BSP */ 2688 sched_peg_curproc(&cpu_info_primary); 2689 2690 rw_enter_write(&sc->sc_lck); 2691 2692 /* 2693 * If we have an interrupt handler, we can get notification 2694 * when certain status bits changes in the ACPI registers, 2695 * so let us enable some events we can forward to userland 2696 */ 2697 if (sc->sc_interrupt) { 2698 int16_t en; 2699 2700 dnprintf(1,"slpbtn:%c pwrbtn:%c\n", 2701 sc->sc_fadt->flags & FADT_SLP_BUTTON ? 'n' : 'y', 2702 sc->sc_fadt->flags & FADT_PWR_BUTTON ? 'n' : 'y'); 2703 dnprintf(10, "Enabling acpi interrupts...\n"); 2704 sc->sc_threadwaiting = 1; 2705 2706 /* Enable Sleep/Power buttons if they exist */ 2707 s = spltty(); 2708 en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); 2709 if (!(sc->sc_fadt->flags & FADT_PWR_BUTTON)) 2710 en |= ACPI_PM1_PWRBTN_EN; 2711 if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON)) 2712 en |= ACPI_PM1_SLPBTN_EN; 2713 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en); 2714 2715 /* Enable handled GPEs here */ 2716 acpi_enable_rungpes(sc); 2717 splx(s); 2718 } 2719 2720 while (thread->running) { 2721 s = spltty(); 2722 while (sc->sc_threadwaiting) { 2723 dnprintf(10, "acpi thread going to sleep...\n"); 2724 rw_exit_write(&sc->sc_lck); 2725 tsleep(sc, PWAIT, "acpi0", 0); 2726 rw_enter_write(&sc->sc_lck); 2727 } 2728 sc->sc_threadwaiting = 1; 2729 splx(s); 2730 if (aml_busy) { 2731 panic("thread woke up to find aml was busy"); 2732 continue; 2733 } 2734 2735 /* Run ACPI taskqueue */ 2736 while(acpi_dotask(acpi_softc)) 2737 ; 2738 } 2739 free(thread, M_DEVBUF, sizeof(*thread)); 2740 2741 kthread_exit(0); 2742 } 2743 2744 void 2745 acpi_create_thread(void *arg) 2746 { 2747 struct acpi_softc *sc = arg; 2748 2749 if (kthread_create(acpi_thread, sc->sc_thread, NULL, DEVNAME(sc)) 2750 != 0) 2751 printf("%s: unable to create isr thread, GPEs disabled\n", 2752 DEVNAME(sc)); 2753 } 2754 2755 int 2756 acpi_foundec(struct aml_node *node, void *arg) 2757 { 2758 struct acpi_softc *sc = (struct acpi_softc *)arg; 2759 struct device *self = (struct device *)arg; 2760 const char *dev; 2761 struct aml_value res; 2762 struct acpi_attach_args aaa; 2763 2764 if (aml_evalnode(sc, node, 0, NULL, &res) != 0) 2765 return 0; 2766 2767 switch (res.type) { 2768 case AML_OBJTYPE_STRING: 2769 dev = res.v_string; 2770 break; 2771 case AML_OBJTYPE_INTEGER: 2772 dev = aml_eisaid(aml_val2int(&res)); 2773 break; 2774 default: 2775 dev = "unknown"; 2776 break; 2777 } 2778 2779 if (strcmp(dev, ACPI_DEV_ECD)) 2780 return 0; 2781 2782 /* Check if we're already attached */ 2783 if (sc->sc_ec && sc->sc_ec->sc_devnode == node->parent) 2784 return 0; 2785 2786 memset(&aaa, 0, sizeof(aaa)); 2787 aaa.aaa_iot = sc->sc_iot; 2788 aaa.aaa_memt = sc->sc_memt; 2789 aaa.aaa_node = node->parent; 2790 aaa.aaa_dev = dev; 2791 aaa.aaa_name = "acpiec"; 2792 config_found(self, &aaa, acpi_print); 2793 aml_freevalue(&res); 2794 2795 return 0; 2796 } 2797 2798 int 2799 acpi_foundsony(struct aml_node *node, void *arg) 2800 { 2801 struct acpi_softc *sc = (struct acpi_softc *)arg; 2802 struct device *self = (struct device *)arg; 2803 struct acpi_attach_args aaa; 2804 2805 memset(&aaa, 0, sizeof(aaa)); 2806 aaa.aaa_iot = sc->sc_iot; 2807 aaa.aaa_memt = sc->sc_memt; 2808 aaa.aaa_node = node->parent; 2809 aaa.aaa_name = "acpisony"; 2810 2811 config_found(self, &aaa, acpi_print); 2812 2813 return 0; 2814 } 2815 2816 int 2817 acpi_parsehid(struct aml_node *node, void *arg, char *outcdev, char *outdev, 2818 size_t devlen) 2819 { 2820 struct acpi_softc *sc = (struct acpi_softc *)arg; 2821 struct aml_value res; 2822 const char *dev; 2823 2824 /* NB aml_eisaid returns a static buffer, this must come first */ 2825 if (aml_evalname(acpi_softc, node->parent, "_CID", 0, NULL, &res) == 0) { 2826 switch (res.type) { 2827 case AML_OBJTYPE_STRING: 2828 dev = res.v_string; 2829 break; 2830 case AML_OBJTYPE_INTEGER: 2831 dev = aml_eisaid(aml_val2int(&res)); 2832 break; 2833 default: 2834 dev = "unknown"; 2835 break; 2836 } 2837 strlcpy(outcdev, dev, devlen); 2838 aml_freevalue(&res); 2839 2840 dnprintf(10, "compatible with device: %s\n", outcdev); 2841 } else { 2842 outcdev[0] = '\0'; 2843 } 2844 2845 dnprintf(10, "found hid device: %s ", node->parent->name); 2846 if (aml_evalnode(sc, node, 0, NULL, &res) != 0) 2847 return (1); 2848 2849 switch (res.type) { 2850 case AML_OBJTYPE_STRING: 2851 dev = res.v_string; 2852 break; 2853 case AML_OBJTYPE_INTEGER: 2854 dev = aml_eisaid(aml_val2int(&res)); 2855 break; 2856 default: 2857 dev = "unknown"; 2858 break; 2859 } 2860 dnprintf(10, " device: %s\n", dev); 2861 2862 strlcpy(outdev, dev, devlen); 2863 2864 aml_freevalue(&res); 2865 2866 return (0); 2867 } 2868 2869 /* Devices for which we don't want to attach a driver */ 2870 const char *acpi_skip_hids[] = { 2871 "INT0800", /* Intel 82802Firmware Hub Device */ 2872 "PNP0000", /* 8259-compatible Programmable Interrupt Controller */ 2873 "PNP0001", /* EISA Interrupt Controller */ 2874 "PNP0100", /* PC-class System Timer */ 2875 "PNP0103", /* HPET System Timer */ 2876 "PNP0200", /* PC-class DMA Controller */ 2877 "PNP0201", /* EISA DMA Controller */ 2878 "PNP0800", /* Microsoft Sound System Compatible Device */ 2879 "PNP0A03", /* PCI Bus */ 2880 "PNP0A08", /* PCI Express Bus */ 2881 "PNP0B00", /* AT Real-Time Clock */ 2882 "PNP0C01", /* System Board */ 2883 "PNP0C02", /* PNP Motherboard Resources */ 2884 "PNP0C04", /* x87-compatible Floating Point Processing Unit */ 2885 "PNP0C09", /* Embedded Controller Device */ 2886 "PNP0C0F", /* PCI Interrupt Link Device */ 2887 NULL 2888 }; 2889 2890 /* ISA devices for which we attach a driver later */ 2891 const char *acpi_isa_hids[] = { 2892 "PNP0303", /* IBM Enhanced Keyboard (101/102-key, PS/2 Mouse) */ 2893 "PNP0400", /* Standard LPT Parallel Port */ 2894 "PNP0401", /* ECP Parallel Port */ 2895 "PNP0501", /* 16550A-compatible COM Serial Port */ 2896 "PNP0700", /* PC-class Floppy Disk Controller */ 2897 "PNP0F03", /* Microsoft PS/2-style Mouse */ 2898 "PNP0F13", /* PS/2 Mouse */ 2899 NULL 2900 }; 2901 2902 void 2903 acpi_attach_deps(struct acpi_softc *sc, struct aml_node *node) 2904 { 2905 struct aml_value res; 2906 struct aml_node *dep; 2907 int i; 2908 2909 if (aml_evalname(sc, node, "_DEP", 0, NULL, &res)) 2910 return; 2911 2912 if (res.type != AML_OBJTYPE_PACKAGE) 2913 return; 2914 2915 for (i = 0; i < res.length; i++) { 2916 if (res.v_package[i]->type != AML_OBJTYPE_STRING) 2917 continue; 2918 dep = aml_searchrel(node, res.v_package[i]->v_string); 2919 if (dep == NULL || dep->attached) 2920 continue; 2921 dep = aml_searchname(dep, "_HID"); 2922 if (dep) 2923 acpi_foundhid(dep, sc); 2924 } 2925 2926 aml_freevalue(&res); 2927 } 2928 2929 int 2930 acpi_foundhid(struct aml_node *node, void *arg) 2931 { 2932 struct acpi_softc *sc = (struct acpi_softc *)arg; 2933 struct device *self = (struct device *)arg; 2934 char cdev[32]; 2935 char dev[32]; 2936 struct acpi_attach_args aaa; 2937 int64_t sta; 2938 #ifndef SMALL_KERNEL 2939 int i; 2940 #endif 2941 2942 if (acpi_parsehid(node, arg, cdev, dev, sizeof(dev)) != 0) 2943 return (0); 2944 2945 if (aml_evalinteger(sc, node->parent, "_STA", 0, NULL, &sta)) 2946 sta = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000; 2947 2948 if ((sta & STA_PRESENT) == 0) 2949 return (0); 2950 2951 acpi_attach_deps(sc, node->parent); 2952 2953 memset(&aaa, 0, sizeof(aaa)); 2954 aaa.aaa_iot = sc->sc_iot; 2955 aaa.aaa_memt = sc->sc_memt; 2956 aaa.aaa_node = node->parent; 2957 aaa.aaa_dev = dev; 2958 2959 if (acpi_matchhids(&aaa, acpi_skip_hids, "none") || 2960 acpi_matchhids(&aaa, acpi_isa_hids, "none")) 2961 return (0); 2962 2963 #ifndef SMALL_KERNEL 2964 if (!strcmp(cdev, ACPI_DEV_MOUSE)) { 2965 for (i = 0; i < nitems(sbtn_pnp); i++) { 2966 if (!strcmp(dev, sbtn_pnp[i])) { 2967 mouse_has_softbtn = 1; 2968 break; 2969 } 2970 } 2971 } 2972 #endif 2973 2974 if (!node->parent->attached) { 2975 node->parent->attached = 1; 2976 config_found(self, &aaa, acpi_print); 2977 } 2978 2979 return (0); 2980 } 2981 2982 #ifndef SMALL_KERNEL 2983 int 2984 acpi_founddock(struct aml_node *node, void *arg) 2985 { 2986 struct acpi_softc *sc = (struct acpi_softc *)arg; 2987 struct device *self = (struct device *)arg; 2988 struct acpi_attach_args aaa; 2989 2990 dnprintf(10, "found dock entry: %s\n", node->parent->name); 2991 2992 memset(&aaa, 0, sizeof(aaa)); 2993 aaa.aaa_iot = sc->sc_iot; 2994 aaa.aaa_memt = sc->sc_memt; 2995 aaa.aaa_node = node->parent; 2996 aaa.aaa_name = "acpidock"; 2997 2998 config_found(self, &aaa, acpi_print); 2999 3000 return 0; 3001 } 3002 3003 int 3004 acpi_foundvideo(struct aml_node *node, void *arg) 3005 { 3006 struct acpi_softc *sc = (struct acpi_softc *)arg; 3007 struct device *self = (struct device *)arg; 3008 struct acpi_attach_args aaa; 3009 3010 memset(&aaa, 0, sizeof(aaa)); 3011 aaa.aaa_iot = sc->sc_iot; 3012 aaa.aaa_memt = sc->sc_memt; 3013 aaa.aaa_node = node->parent; 3014 aaa.aaa_name = "acpivideo"; 3015 3016 config_found(self, &aaa, acpi_print); 3017 3018 return (0); 3019 } 3020 3021 int 3022 acpi_foundsbs(struct aml_node *node, void *arg) 3023 { 3024 struct acpi_softc *sc = (struct acpi_softc *)arg; 3025 struct device *self = (struct device *)arg; 3026 char cdev[32], dev[32]; 3027 struct acpi_attach_args aaa; 3028 int64_t sta; 3029 3030 if (acpi_parsehid(node, arg, cdev, dev, sizeof(dev)) != 0) 3031 return (0); 3032 3033 if (aml_evalinteger(sc, node->parent, "_STA", 0, NULL, &sta)) 3034 sta = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000; 3035 3036 if ((sta & STA_PRESENT) == 0) 3037 return (0); 3038 3039 acpi_attach_deps(sc, node->parent); 3040 3041 if (strcmp(dev, ACPI_DEV_SBS) != 0) 3042 return (0); 3043 3044 if (node->parent->attached) 3045 return (0); 3046 3047 memset(&aaa, 0, sizeof(aaa)); 3048 aaa.aaa_iot = sc->sc_iot; 3049 aaa.aaa_memt = sc->sc_memt; 3050 aaa.aaa_node = node->parent; 3051 aaa.aaa_dev = dev; 3052 3053 config_found(self, &aaa, acpi_print); 3054 node->parent->attached = 1; 3055 3056 return (0); 3057 } 3058 3059 int 3060 acpiopen(dev_t dev, int flag, int mode, struct proc *p) 3061 { 3062 int error = 0; 3063 struct acpi_softc *sc; 3064 int s; 3065 3066 if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || 3067 !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) 3068 return (ENXIO); 3069 3070 s = spltty(); 3071 switch (APMDEV(dev)) { 3072 case APMDEV_CTL: 3073 if (!(flag & FWRITE)) { 3074 error = EINVAL; 3075 break; 3076 } 3077 if (sc->sc_flags & SCFLAG_OWRITE) { 3078 error = EBUSY; 3079 break; 3080 } 3081 sc->sc_flags |= SCFLAG_OWRITE; 3082 break; 3083 case APMDEV_NORMAL: 3084 if (!(flag & FREAD) || (flag & FWRITE)) { 3085 error = EINVAL; 3086 break; 3087 } 3088 sc->sc_flags |= SCFLAG_OREAD; 3089 break; 3090 default: 3091 error = ENXIO; 3092 break; 3093 } 3094 splx(s); 3095 return (error); 3096 } 3097 3098 int 3099 acpiclose(dev_t dev, int flag, int mode, struct proc *p) 3100 { 3101 int error = 0; 3102 struct acpi_softc *sc; 3103 int s; 3104 3105 if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || 3106 !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) 3107 return (ENXIO); 3108 3109 s = spltty(); 3110 switch (APMDEV(dev)) { 3111 case APMDEV_CTL: 3112 sc->sc_flags &= ~SCFLAG_OWRITE; 3113 break; 3114 case APMDEV_NORMAL: 3115 sc->sc_flags &= ~SCFLAG_OREAD; 3116 break; 3117 default: 3118 error = ENXIO; 3119 break; 3120 } 3121 splx(s); 3122 return (error); 3123 } 3124 3125 int 3126 acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 3127 { 3128 int error = 0; 3129 struct acpi_softc *sc; 3130 struct acpi_ac *ac; 3131 struct acpi_bat *bat; 3132 struct acpi_sbs *sbs; 3133 struct apm_power_info *pi = (struct apm_power_info *)data; 3134 int bats; 3135 unsigned int remaining, rem, minutes, rate; 3136 int s; 3137 3138 if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || 3139 !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) 3140 return (ENXIO); 3141 3142 s = spltty(); 3143 /* fake APM */ 3144 switch (cmd) { 3145 case APM_IOC_SUSPEND: 3146 case APM_IOC_STANDBY: 3147 if ((flag & FWRITE) == 0) { 3148 error = EBADF; 3149 break; 3150 } 3151 acpi_addtask(sc, acpi_sleep_task, sc, ACPI_SLEEP_SUSPEND); 3152 acpi_wakeup(sc); 3153 break; 3154 #ifdef HIBERNATE 3155 case APM_IOC_HIBERNATE: 3156 if ((error = suser(p, 0)) != 0) 3157 break; 3158 if ((flag & FWRITE) == 0) { 3159 error = EBADF; 3160 break; 3161 } 3162 if (get_hibernate_io_function(swdevt[0].sw_dev) == NULL) { 3163 error = EOPNOTSUPP; 3164 break; 3165 } 3166 acpi_addtask(sc, acpi_sleep_task, sc, ACPI_SLEEP_HIBERNATE); 3167 acpi_wakeup(sc); 3168 break; 3169 #endif 3170 case APM_IOC_GETPOWER: 3171 /* A/C */ 3172 pi->ac_state = APM_AC_UNKNOWN; 3173 SLIST_FOREACH(ac, &sc->sc_ac, aac_link) { 3174 if (ac->aac_softc->sc_ac_stat == PSR_ONLINE) 3175 pi->ac_state = APM_AC_ON; 3176 else if (ac->aac_softc->sc_ac_stat == PSR_OFFLINE) 3177 if (pi->ac_state == APM_AC_UNKNOWN) 3178 pi->ac_state = APM_AC_OFF; 3179 } 3180 3181 /* battery */ 3182 pi->battery_state = APM_BATT_UNKNOWN; 3183 pi->battery_life = 0; 3184 pi->minutes_left = 0; 3185 bats = 0; 3186 remaining = rem = 0; 3187 minutes = 0; 3188 rate = 0; 3189 SLIST_FOREACH(bat, &sc->sc_bat, aba_link) { 3190 if (bat->aba_softc->sc_bat_present == 0) 3191 continue; 3192 3193 if (bat->aba_softc->sc_bix.bix_last_capacity == 0) 3194 continue; 3195 3196 bats++; 3197 rem = (bat->aba_softc->sc_bst.bst_capacity * 100) / 3198 bat->aba_softc->sc_bix.bix_last_capacity; 3199 if (rem > 100) 3200 rem = 100; 3201 remaining += rem; 3202 3203 if (bat->aba_softc->sc_bst.bst_rate == BST_UNKNOWN) 3204 continue; 3205 else if (bat->aba_softc->sc_bst.bst_rate > 1) 3206 rate = bat->aba_softc->sc_bst.bst_rate; 3207 3208 minutes += bat->aba_softc->sc_bst.bst_capacity; 3209 } 3210 3211 SLIST_FOREACH(sbs, &sc->sc_sbs, asbs_link) { 3212 if (sbs->asbs_softc->sc_batteries_present == 0) 3213 continue; 3214 3215 if (sbs->asbs_softc->sc_battery.rel_charge == 0) 3216 continue; 3217 3218 bats++; 3219 rem = sbs->asbs_softc->sc_battery.rel_charge; 3220 if (rem > 100) 3221 rem = 100; 3222 remaining += rem; 3223 3224 if (sbs->asbs_softc->sc_battery.run_time == 3225 ACPISBS_VALUE_UNKNOWN) 3226 continue; 3227 3228 rate = 60; /* XXX */ 3229 minutes += sbs->asbs_softc->sc_battery.run_time; 3230 } 3231 3232 if (bats == 0) { 3233 pi->battery_state = APM_BATTERY_ABSENT; 3234 pi->battery_life = 0; 3235 pi->minutes_left = (unsigned int)-1; 3236 break; 3237 } 3238 3239 if (pi->ac_state == APM_AC_ON || rate == 0) 3240 pi->minutes_left = (unsigned int)-1; 3241 else 3242 pi->minutes_left = 60 * minutes / rate; 3243 3244 /* running on battery */ 3245 pi->battery_life = remaining / bats; 3246 if (pi->battery_life > 50) 3247 pi->battery_state = APM_BATT_HIGH; 3248 else if (pi->battery_life > 25) 3249 pi->battery_state = APM_BATT_LOW; 3250 else 3251 pi->battery_state = APM_BATT_CRITICAL; 3252 3253 break; 3254 3255 default: 3256 error = ENOTTY; 3257 } 3258 3259 splx(s); 3260 return (error); 3261 } 3262 3263 void acpi_filtdetach(struct knote *); 3264 int acpi_filtread(struct knote *, long); 3265 3266 struct filterops acpiread_filtops = { 3267 1, NULL, acpi_filtdetach, acpi_filtread 3268 }; 3269 3270 int acpi_evindex; 3271 3272 int 3273 acpi_record_event(struct acpi_softc *sc, u_int type) 3274 { 3275 if ((sc->sc_flags & SCFLAG_OPEN) == 0) 3276 return (1); 3277 3278 acpi_evindex++; 3279 KNOTE(sc->sc_note, APM_EVENT_COMPOSE(type, acpi_evindex)); 3280 return (0); 3281 } 3282 3283 void 3284 acpi_filtdetach(struct knote *kn) 3285 { 3286 struct acpi_softc *sc = kn->kn_hook; 3287 int s; 3288 3289 s = spltty(); 3290 SLIST_REMOVE(sc->sc_note, kn, knote, kn_selnext); 3291 splx(s); 3292 } 3293 3294 int 3295 acpi_filtread(struct knote *kn, long hint) 3296 { 3297 /* XXX weird kqueue_scan() semantics */ 3298 if (hint && !kn->kn_data) 3299 kn->kn_data = hint; 3300 return (1); 3301 } 3302 3303 int 3304 acpikqfilter(dev_t dev, struct knote *kn) 3305 { 3306 struct acpi_softc *sc; 3307 int s; 3308 3309 if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || 3310 !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) 3311 return (ENXIO); 3312 3313 switch (kn->kn_filter) { 3314 case EVFILT_READ: 3315 kn->kn_fop = &acpiread_filtops; 3316 break; 3317 default: 3318 return (EINVAL); 3319 } 3320 3321 kn->kn_hook = sc; 3322 3323 s = spltty(); 3324 SLIST_INSERT_HEAD(sc->sc_note, kn, kn_selnext); 3325 splx(s); 3326 3327 return (0); 3328 } 3329 3330 #else /* SMALL_KERNEL */ 3331 3332 int 3333 acpiopen(dev_t dev, int flag, int mode, struct proc *p) 3334 { 3335 return (ENXIO); 3336 } 3337 3338 int 3339 acpiclose(dev_t dev, int flag, int mode, struct proc *p) 3340 { 3341 return (ENXIO); 3342 } 3343 3344 int 3345 acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 3346 { 3347 return (ENXIO); 3348 } 3349 3350 int 3351 acpikqfilter(dev_t dev, struct knote *kn) 3352 { 3353 return (ENXIO); 3354 } 3355 #endif /* SMALL_KERNEL */ 3356