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