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