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