xref: /openbsd-src/sys/dev/acpi/acpi.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /* $OpenBSD: acpi.c,v 1.316 2016/09/18 23:56:45 guenther 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(union acpi_resource *crs, void *arg);
517 
518 int
519 acpi_getminbus(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 		}
1117 	}
1118 
1119 #endif /* SMALL_KERNEL */
1120 
1121 	/* Setup threads */
1122 	sc->sc_thread = malloc(sizeof(struct acpi_thread), M_DEVBUF, M_WAITOK);
1123 	sc->sc_thread->sc = sc;
1124 	sc->sc_thread->running = 1;
1125 
1126 	/* Enable PCI Power Management. */
1127 	pci_dopm = 1;
1128 
1129 	acpi_attach_machdep(sc);
1130 
1131 	kthread_create_deferred(acpi_create_thread, sc);
1132 }
1133 
1134 int
1135 acpi_submatch(struct device *parent, void *match, void *aux)
1136 {
1137 	struct acpi_attach_args *aaa = (struct acpi_attach_args *)aux;
1138 	struct cfdata *cf = match;
1139 
1140 	if (aaa->aaa_table == NULL)
1141 		return (0);
1142 	return ((*cf->cf_attach->ca_match)(parent, match, aux));
1143 }
1144 
1145 int
1146 acpi_print(void *aux, const char *pnp)
1147 {
1148 	struct acpi_attach_args *aa = aux;
1149 
1150 	if (pnp) {
1151 		if (aa->aaa_name)
1152 			printf("%s at %s", aa->aaa_name, pnp);
1153 		else if (aa->aaa_dev)
1154 			printf("\"%s\" at %s", aa->aaa_dev, pnp);
1155 		else
1156 			return (QUIET);
1157 	}
1158 
1159 	return (UNCONF);
1160 }
1161 
1162 struct acpi_q *
1163 acpi_maptable(struct acpi_softc *sc, paddr_t addr, const char *sig,
1164     const char *oem, const char *tbl, int flag)
1165 {
1166 	static int tblid;
1167 	struct acpi_mem_map handle;
1168 	struct acpi_table_header *hdr;
1169 	struct acpi_q *entry;
1170 	size_t len;
1171 
1172 	/* Check if we can map address */
1173 	if (addr == 0)
1174 		return NULL;
1175 	if (acpi_map(addr, sizeof(*hdr), &handle))
1176 		return NULL;
1177 	hdr = (struct acpi_table_header *)handle.va;
1178 	len = hdr->length;
1179 	acpi_unmap(&handle);
1180 
1181 	/* Validate length/checksum */
1182 	if (acpi_map(addr, len, &handle))
1183 		return NULL;
1184 	hdr = (struct acpi_table_header *)handle.va;
1185 	if (acpi_checksum(hdr, len))
1186 		printf("\n%s: %.4s checksum error",
1187 		    DEVNAME(sc), hdr->signature);
1188 
1189 	if ((sig && memcmp(sig, hdr->signature, 4)) ||
1190 	    (oem && memcmp(oem, hdr->oemid, 6)) ||
1191 	    (tbl && memcmp(tbl, hdr->oemtableid, 8))) {
1192 		acpi_unmap(&handle);
1193 		return NULL;
1194 	}
1195 
1196 	/* Allocate copy */
1197 	entry = malloc(sizeof(*entry) + len, M_DEVBUF, M_NOWAIT);
1198 	if (entry != NULL) {
1199 		memcpy(entry->q_data, handle.va, len);
1200 		entry->q_table = entry->q_data;
1201 		entry->q_id = ++tblid;
1202 
1203 		if (flag < 0)
1204 			SIMPLEQ_INSERT_HEAD(&sc->sc_tables, entry,
1205 			    q_next);
1206 		else if (flag > 0)
1207 			SIMPLEQ_INSERT_TAIL(&sc->sc_tables, entry,
1208 			    q_next);
1209 	}
1210 	acpi_unmap(&handle);
1211 	return entry;
1212 }
1213 
1214 int
1215 acpi_loadtables(struct acpi_softc *sc, struct acpi_rsdp *rsdp)
1216 {
1217 	struct acpi_q *sdt;
1218 	int i, ntables;
1219 	size_t len;
1220 
1221 	if (rsdp->rsdp_revision == 2 && rsdp->rsdp_xsdt) {
1222 		struct acpi_xsdt *xsdt;
1223 
1224 		sdt = acpi_maptable(sc, rsdp->rsdp_xsdt, NULL, NULL, NULL, 0);
1225 		if (sdt == NULL) {
1226 			printf("couldn't map rsdt\n");
1227 			return (ENOMEM);
1228 		}
1229 
1230 		xsdt = (struct acpi_xsdt *)sdt->q_data;
1231 		len  = xsdt->hdr.length;
1232 		ntables = (len - sizeof(struct acpi_table_header)) /
1233 		    sizeof(xsdt->table_offsets[0]);
1234 
1235 		for (i = 0; i < ntables; i++)
1236 			acpi_maptable(sc, xsdt->table_offsets[i], NULL, NULL,
1237 			    NULL, 1);
1238 
1239 		free(sdt, M_DEVBUF, 0);
1240 	} else {
1241 		struct acpi_rsdt *rsdt;
1242 
1243 		sdt = acpi_maptable(sc, rsdp->rsdp_rsdt, NULL, NULL, NULL, 0);
1244 		if (sdt == NULL) {
1245 			printf("couldn't map rsdt\n");
1246 			return (ENOMEM);
1247 		}
1248 
1249 		rsdt = (struct acpi_rsdt *)sdt->q_data;
1250 		len  = rsdt->hdr.length;
1251 		ntables = (len - sizeof(struct acpi_table_header)) /
1252 		    sizeof(rsdt->table_offsets[0]);
1253 
1254 		for (i = 0; i < ntables; i++)
1255 			acpi_maptable(sc, rsdt->table_offsets[i], NULL, NULL,
1256 			    NULL, 1);
1257 
1258 		free(sdt, M_DEVBUF, 0);
1259 	}
1260 
1261 	return (0);
1262 }
1263 
1264 /* Read from power management register */
1265 int
1266 acpi_read_pmreg(struct acpi_softc *sc, int reg, int offset)
1267 {
1268 	bus_space_handle_t ioh;
1269 	bus_size_t size;
1270 	int regval;
1271 
1272 	/*
1273 	 * For Hardware-reduced ACPI we emulate PM1B_CNT to reflect
1274 	 * that the system is always in ACPI mode.
1275 	 */
1276 	if (sc->sc_hw_reduced && reg == ACPIREG_PM1B_CNT) {
1277 		KASSERT(offset == 0);
1278 		return ACPI_PM1_SCI_EN;
1279 	}
1280 
1281 	/*
1282 	 * For Hardware-reduced ACPI we also emulate PM1A_STS using
1283 	 * SLEEP_STATUS_REG.
1284 	 */
1285 	if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_STS) {
1286 		uint8_t value;
1287 
1288 		KASSERT(offset == 0);
1289 		acpi_gasio(sc, ACPI_IOREAD,
1290 		    sc->sc_fadt->sleep_status_reg.address_space_id,
1291 		    sc->sc_fadt->sleep_status_reg.address,
1292 		    sc->sc_fadt->sleep_status_reg.register_bit_width / 8,
1293 		    sc->sc_fadt->sleep_status_reg.access_size, &value);
1294 		return ((int)value << 8);
1295 	}
1296 
1297 	/* Special cases: 1A/1B blocks can be OR'ed together */
1298 	switch (reg) {
1299 	case ACPIREG_PM1_EN:
1300 		return (acpi_read_pmreg(sc, ACPIREG_PM1A_EN, offset) |
1301 		    acpi_read_pmreg(sc, ACPIREG_PM1B_EN, offset));
1302 	case ACPIREG_PM1_STS:
1303 		return (acpi_read_pmreg(sc, ACPIREG_PM1A_STS, offset) |
1304 		    acpi_read_pmreg(sc, ACPIREG_PM1B_STS, offset));
1305 	case ACPIREG_PM1_CNT:
1306 		return (acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, offset) |
1307 		    acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, offset));
1308 	case ACPIREG_GPE_STS:
1309 		dnprintf(50, "read GPE_STS  offset: %.2x %.2x %.2x\n", offset,
1310 		    sc->sc_fadt->gpe0_blk_len>>1, sc->sc_fadt->gpe1_blk_len>>1);
1311 		if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) {
1312 			reg = ACPIREG_GPE0_STS;
1313 		}
1314 		break;
1315 	case ACPIREG_GPE_EN:
1316 		dnprintf(50, "read GPE_EN   offset: %.2x %.2x %.2x\n",
1317 		    offset, sc->sc_fadt->gpe0_blk_len>>1,
1318 		    sc->sc_fadt->gpe1_blk_len>>1);
1319 		if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) {
1320 			reg = ACPIREG_GPE0_EN;
1321 		}
1322 		break;
1323 	}
1324 
1325 	if (reg >= ACPIREG_MAXREG || sc->sc_pmregs[reg].size == 0)
1326 		return (0);
1327 
1328 	regval = 0;
1329 	ioh = sc->sc_pmregs[reg].ioh;
1330 	size = sc->sc_pmregs[reg].size;
1331 	if (size > sc->sc_pmregs[reg].access)
1332 		size = sc->sc_pmregs[reg].access;
1333 
1334 	switch (size) {
1335 	case 1:
1336 		regval = bus_space_read_1(sc->sc_iot, ioh, offset);
1337 		break;
1338 	case 2:
1339 		regval = bus_space_read_2(sc->sc_iot, ioh, offset);
1340 		break;
1341 	case 4:
1342 		regval = bus_space_read_4(sc->sc_iot, ioh, offset);
1343 		break;
1344 	}
1345 
1346 	dnprintf(30, "acpi_readpm: %s = %.4x:%.4x %x\n",
1347 	    sc->sc_pmregs[reg].name,
1348 	    sc->sc_pmregs[reg].addr, offset, regval);
1349 	return (regval);
1350 }
1351 
1352 /* Write to power management register */
1353 void
1354 acpi_write_pmreg(struct acpi_softc *sc, int reg, int offset, int regval)
1355 {
1356 	bus_space_handle_t ioh;
1357 	bus_size_t size;
1358 
1359 	/*
1360 	 * For Hardware-reduced ACPI we also emulate PM1A_STS using
1361 	 * SLEEP_STATUS_REG.
1362 	 */
1363 	if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_STS) {
1364 		uint8_t value = (regval >> 8);
1365 
1366 		KASSERT(offset == 0);
1367 		acpi_gasio(sc, ACPI_IOWRITE,
1368 		    sc->sc_fadt->sleep_status_reg.address_space_id,
1369 		    sc->sc_fadt->sleep_status_reg.address,
1370 		    sc->sc_fadt->sleep_status_reg.register_bit_width / 8,
1371 		    sc->sc_fadt->sleep_status_reg.access_size, &value);
1372 		return;
1373 	}
1374 
1375 	/*
1376 	 * For Hardware-reduced ACPI we also emulate PM1A_CNT using
1377 	 * SLEEP_CONTROL_REG.
1378 	 */
1379 	if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_CNT) {
1380 		uint8_t value = (regval >> 8);
1381 
1382 		KASSERT(offset == 0);
1383 		acpi_gasio(sc, ACPI_IOWRITE,
1384 		    sc->sc_fadt->sleep_control_reg.address_space_id,
1385 		    sc->sc_fadt->sleep_control_reg.address,
1386 		    sc->sc_fadt->sleep_control_reg.register_bit_width / 8,
1387 		    sc->sc_fadt->sleep_control_reg.access_size, &value);
1388 		return;
1389 	}
1390 
1391 	/* Special cases: 1A/1B blocks can be written with same value */
1392 	switch (reg) {
1393 	case ACPIREG_PM1_EN:
1394 		acpi_write_pmreg(sc, ACPIREG_PM1A_EN, offset, regval);
1395 		acpi_write_pmreg(sc, ACPIREG_PM1B_EN, offset, regval);
1396 		break;
1397 	case ACPIREG_PM1_STS:
1398 		acpi_write_pmreg(sc, ACPIREG_PM1A_STS, offset, regval);
1399 		acpi_write_pmreg(sc, ACPIREG_PM1B_STS, offset, regval);
1400 		break;
1401 	case ACPIREG_PM1_CNT:
1402 		acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, offset, regval);
1403 		acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, offset, regval);
1404 		break;
1405 	case ACPIREG_GPE_STS:
1406 		dnprintf(50, "write GPE_STS offset: %.2x %.2x %.2x %.2x\n",
1407 		    offset, sc->sc_fadt->gpe0_blk_len>>1,
1408 		    sc->sc_fadt->gpe1_blk_len>>1, regval);
1409 		if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) {
1410 			reg = ACPIREG_GPE0_STS;
1411 		}
1412 		break;
1413 	case ACPIREG_GPE_EN:
1414 		dnprintf(50, "write GPE_EN  offset: %.2x %.2x %.2x %.2x\n",
1415 		    offset, sc->sc_fadt->gpe0_blk_len>>1,
1416 		    sc->sc_fadt->gpe1_blk_len>>1, regval);
1417 		if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) {
1418 			reg = ACPIREG_GPE0_EN;
1419 		}
1420 		break;
1421 	}
1422 
1423 	/* All special case return here */
1424 	if (reg >= ACPIREG_MAXREG)
1425 		return;
1426 
1427 	ioh = sc->sc_pmregs[reg].ioh;
1428 	size = sc->sc_pmregs[reg].size;
1429 	if (size > sc->sc_pmregs[reg].access)
1430 		size = sc->sc_pmregs[reg].access;
1431 
1432 	switch (size) {
1433 	case 1:
1434 		bus_space_write_1(sc->sc_iot, ioh, offset, regval);
1435 		break;
1436 	case 2:
1437 		bus_space_write_2(sc->sc_iot, ioh, offset, regval);
1438 		break;
1439 	case 4:
1440 		bus_space_write_4(sc->sc_iot, ioh, offset, regval);
1441 		break;
1442 	}
1443 
1444 	dnprintf(30, "acpi_writepm: %s = %.4x:%.4x %x\n",
1445 	    sc->sc_pmregs[reg].name, sc->sc_pmregs[reg].addr, offset, regval);
1446 }
1447 
1448 /* Map Power Management registers */
1449 void
1450 acpi_map_pmregs(struct acpi_softc *sc)
1451 {
1452 	bus_addr_t addr;
1453 	bus_size_t size, access;
1454 	const char *name;
1455 	int reg;
1456 
1457 	/* Registers don't exist on Hardware-reduced ACPI. */
1458 	if (sc->sc_hw_reduced)
1459 		return;
1460 
1461 	for (reg = 0; reg < ACPIREG_MAXREG; reg++) {
1462 		size = 0;
1463 		access = 0;
1464 		switch (reg) {
1465 		case ACPIREG_SMICMD:
1466 			name = "smi";
1467 			size = access = 1;
1468 			addr = sc->sc_fadt->smi_cmd;
1469 			break;
1470 		case ACPIREG_PM1A_STS:
1471 		case ACPIREG_PM1A_EN:
1472 			name = "pm1a_sts";
1473 			size = sc->sc_fadt->pm1_evt_len >> 1;
1474 			addr = sc->sc_fadt->pm1a_evt_blk;
1475 			access = 2;
1476 			if (reg == ACPIREG_PM1A_EN && addr) {
1477 				addr += size;
1478 				name = "pm1a_en";
1479 			}
1480 			break;
1481 		case ACPIREG_PM1A_CNT:
1482 			name = "pm1a_cnt";
1483 			size = sc->sc_fadt->pm1_cnt_len;
1484 			addr = sc->sc_fadt->pm1a_cnt_blk;
1485 			access = 2;
1486 			break;
1487 		case ACPIREG_PM1B_STS:
1488 		case ACPIREG_PM1B_EN:
1489 			name = "pm1b_sts";
1490 			size = sc->sc_fadt->pm1_evt_len >> 1;
1491 			addr = sc->sc_fadt->pm1b_evt_blk;
1492 			access = 2;
1493 			if (reg == ACPIREG_PM1B_EN && addr) {
1494 				addr += size;
1495 				name = "pm1b_en";
1496 			}
1497 			break;
1498 		case ACPIREG_PM1B_CNT:
1499 			name = "pm1b_cnt";
1500 			size = sc->sc_fadt->pm1_cnt_len;
1501 			addr = sc->sc_fadt->pm1b_cnt_blk;
1502 			access = 2;
1503 			break;
1504 		case ACPIREG_PM2_CNT:
1505 			name = "pm2_cnt";
1506 			size = sc->sc_fadt->pm2_cnt_len;
1507 			addr = sc->sc_fadt->pm2_cnt_blk;
1508 			access = size;
1509 			break;
1510 #if 0
1511 		case ACPIREG_PM_TMR:
1512 			/* Allocated in acpitimer */
1513 			name = "pm_tmr";
1514 			size = sc->sc_fadt->pm_tmr_len;
1515 			addr = sc->sc_fadt->pm_tmr_blk;
1516 			access = 4;
1517 			break;
1518 #endif
1519 		case ACPIREG_GPE0_STS:
1520 		case ACPIREG_GPE0_EN:
1521 			name = "gpe0_sts";
1522 			size = sc->sc_fadt->gpe0_blk_len >> 1;
1523 			addr = sc->sc_fadt->gpe0_blk;
1524 			access = 1;
1525 
1526 			dnprintf(20, "gpe0 block len : %x\n",
1527 			    sc->sc_fadt->gpe0_blk_len >> 1);
1528 			dnprintf(20, "gpe0 block addr: %x\n",
1529 			    sc->sc_fadt->gpe0_blk);
1530 			if (reg == ACPIREG_GPE0_EN && addr) {
1531 				addr += size;
1532 				name = "gpe0_en";
1533 			}
1534 			break;
1535 		case ACPIREG_GPE1_STS:
1536 		case ACPIREG_GPE1_EN:
1537 			name = "gpe1_sts";
1538 			size = sc->sc_fadt->gpe1_blk_len >> 1;
1539 			addr = sc->sc_fadt->gpe1_blk;
1540 			access = 1;
1541 
1542 			dnprintf(20, "gpe1 block len : %x\n",
1543 			    sc->sc_fadt->gpe1_blk_len >> 1);
1544 			dnprintf(20, "gpe1 block addr: %x\n",
1545 			    sc->sc_fadt->gpe1_blk);
1546 			if (reg == ACPIREG_GPE1_EN && addr) {
1547 				addr += size;
1548 				name = "gpe1_en";
1549 			}
1550 			break;
1551 		}
1552 		if (size && addr) {
1553 			dnprintf(50, "mapping: %.4lx %.4lx %s\n",
1554 			    addr, size, name);
1555 
1556 			/* Size and address exist; map register space */
1557 			bus_space_map(sc->sc_iot, addr, size, 0,
1558 			    &sc->sc_pmregs[reg].ioh);
1559 
1560 			sc->sc_pmregs[reg].name = name;
1561 			sc->sc_pmregs[reg].size = size;
1562 			sc->sc_pmregs[reg].addr = addr;
1563 			sc->sc_pmregs[reg].access = min(access, 4);
1564 		}
1565 	}
1566 }
1567 
1568 void
1569 acpi_unmap_pmregs(struct acpi_softc *sc)
1570 {
1571 	int reg;
1572 
1573 	for (reg = 0; reg < ACPIREG_MAXREG; reg++) {
1574 		if (sc->sc_pmregs[reg].size && sc->sc_pmregs[reg].addr)
1575 			bus_space_unmap(sc->sc_iot, sc->sc_pmregs[reg].ioh,
1576 			    sc->sc_pmregs[reg].size);
1577 	}
1578 }
1579 
1580 int
1581 acpi_enable(struct acpi_softc *sc)
1582 {
1583 	int idx;
1584 
1585 	acpi_write_pmreg(sc, ACPIREG_SMICMD, 0, sc->sc_fadt->acpi_enable);
1586 	idx = 0;
1587 	do {
1588 		if (idx++ > ACPIEN_RETRIES) {
1589 			return ETIMEDOUT;
1590 		}
1591 	} while (!(acpi_read_pmreg(sc, ACPIREG_PM1_CNT, 0) & ACPI_PM1_SCI_EN));
1592 
1593 	return 0;
1594 }
1595 
1596 /* ACPI Workqueue support */
1597 SIMPLEQ_HEAD(,acpi_taskq) acpi_taskq =
1598     SIMPLEQ_HEAD_INITIALIZER(acpi_taskq);
1599 
1600 void
1601 acpi_addtask(struct acpi_softc *sc, void (*handler)(void *, int),
1602     void *arg0, int arg1)
1603 {
1604 	struct acpi_taskq *wq;
1605 	int s;
1606 
1607 	wq = malloc(sizeof(*wq), M_DEVBUF, M_ZERO | M_NOWAIT);
1608 	if (wq == NULL)
1609 		return;
1610 	wq->handler = handler;
1611 	wq->arg0 = arg0;
1612 	wq->arg1 = arg1;
1613 
1614 	s = spltty();
1615 	SIMPLEQ_INSERT_TAIL(&acpi_taskq, wq, next);
1616 	splx(s);
1617 }
1618 
1619 int
1620 acpi_dotask(struct acpi_softc *sc)
1621 {
1622 	struct acpi_taskq *wq;
1623 	int s;
1624 
1625 	s = spltty();
1626 	if (SIMPLEQ_EMPTY(&acpi_taskq)) {
1627 		splx(s);
1628 
1629 		/* we don't have anything to do */
1630 		return (0);
1631 	}
1632 	wq = SIMPLEQ_FIRST(&acpi_taskq);
1633 	SIMPLEQ_REMOVE_HEAD(&acpi_taskq, next);
1634 	splx(s);
1635 
1636 	wq->handler(wq->arg0, wq->arg1);
1637 
1638 	free(wq, M_DEVBUF, sizeof(*wq));
1639 
1640 	/* We did something */
1641 	return (1);
1642 }
1643 
1644 #ifndef SMALL_KERNEL
1645 
1646 int
1647 is_ata(struct aml_node *node)
1648 {
1649 	return (aml_searchname(node, "_GTM") != NULL ||
1650 	    aml_searchname(node, "_GTF") != NULL ||
1651 	    aml_searchname(node, "_STM") != NULL ||
1652 	    aml_searchname(node, "_SDD") != NULL);
1653 }
1654 
1655 int
1656 is_ejectable(struct aml_node *node)
1657 {
1658 	return (aml_searchname(node, "_EJ0") != NULL);
1659 }
1660 
1661 int
1662 is_ejectable_bay(struct aml_node *node)
1663 {
1664 	return ((is_ata(node) || is_ata(node->parent)) && is_ejectable(node));
1665 }
1666 
1667 #if NWD > 0
1668 int
1669 acpiide_notify(struct aml_node *node, int ntype, void *arg)
1670 {
1671 	struct idechnl 		*ide = arg;
1672 	struct acpi_softc 	*sc = ide->sc;
1673 	struct pciide_softc 	*wsc;
1674 	struct device 		*dev;
1675 	int 			b,d,f;
1676 	int64_t 		sta;
1677 
1678 	if (aml_evalinteger(sc, node, "_STA", 0, NULL, &sta) != 0)
1679 		return (0);
1680 
1681 	dnprintf(10, "IDE notify! %s %d status:%llx\n", aml_nodename(node),
1682 	    ntype, sta);
1683 
1684 	/* Walk device list looking for IDE device match */
1685 	TAILQ_FOREACH(dev, &alldevs, dv_list) {
1686 		if (strcmp(dev->dv_cfdata->cf_driver->cd_name, "pciide"))
1687 			continue;
1688 
1689 		wsc = (struct pciide_softc *)dev;
1690 		pci_decompose_tag(NULL, wsc->sc_tag, &b, &d, &f);
1691 		if (b != ACPI_PCI_BUS(ide->addr) ||
1692 		    d != ACPI_PCI_DEV(ide->addr) ||
1693 		    f != ACPI_PCI_FN(ide->addr))
1694 			continue;
1695 		dnprintf(10, "Found pciide: %s %x.%x.%x channel:%llx\n",
1696 		    dev->dv_xname, b,d,f, ide->chnl);
1697 
1698 		if (sta == 0 && ide->sta)
1699 			wdcdetach(
1700 			    &wsc->pciide_channels[ide->chnl].wdc_channel, 0);
1701 		else if (sta && !ide->sta)
1702 			wdcattach(
1703 			    &wsc->pciide_channels[ide->chnl].wdc_channel);
1704 		ide->sta = sta;
1705 	}
1706 	return (0);
1707 }
1708 
1709 int
1710 acpi_foundide(struct aml_node *node, void *arg)
1711 {
1712 	struct acpi_softc 	*sc = arg;
1713 	struct aml_node 	*pp;
1714 	struct idechnl 		*ide;
1715 	union amlpci_t 		pi;
1716 	int 			lvl;
1717 
1718 	/* Check if this is an ejectable bay */
1719 	if (!is_ejectable_bay(node))
1720 		return (0);
1721 
1722 	ide = malloc(sizeof(struct idechnl), M_DEVBUF, M_NOWAIT | M_ZERO);
1723 	ide->sc = sc;
1724 
1725 	/* GTM/GTF can be at 2/3 levels:  pciX.ideX.channelX[.driveX] */
1726 	lvl = 0;
1727 	for (pp=node->parent; pp; pp=pp->parent) {
1728 		lvl++;
1729 		if (aml_searchname(pp, "_HID"))
1730 			break;
1731 	}
1732 
1733 	/* Get PCI address and channel */
1734 	if (lvl == 3) {
1735 		aml_evalinteger(sc, node->parent, "_ADR", 0, NULL,
1736 		    &ide->chnl);
1737 		aml_rdpciaddr(node->parent->parent, &pi);
1738 		ide->addr = pi.addr;
1739 	} else if (lvl == 4) {
1740 		aml_evalinteger(sc, node->parent->parent, "_ADR", 0, NULL,
1741 		    &ide->chnl);
1742 		aml_rdpciaddr(node->parent->parent->parent, &pi);
1743 		ide->addr = pi.addr;
1744 	}
1745 	dnprintf(10, "%s %llx channel:%llx\n",
1746 	    aml_nodename(node), ide->addr, ide->chnl);
1747 
1748 	aml_evalinteger(sc, node, "_STA", 0, NULL, &ide->sta);
1749 	dnprintf(10, "Got Initial STA: %llx\n", ide->sta);
1750 
1751 	aml_register_notify(node, "acpiide", acpiide_notify, ide, 0);
1752 	return (0);
1753 }
1754 #endif /* NWD > 0 */
1755 
1756 void
1757 acpi_sleep_task(void *arg0, int sleepmode)
1758 {
1759 	struct acpi_softc *sc = arg0;
1760 	struct acpi_ac *ac;
1761 	struct acpi_bat *bat;
1762 
1763 	/* System goes to sleep here.. */
1764 	acpi_sleep_state(sc, sleepmode);
1765 
1766 	/* AC and battery information needs refreshing */
1767 	SLIST_FOREACH(ac, &sc->sc_ac, aac_link)
1768 		aml_notify(ac->aac_softc->sc_devnode,
1769 		    0x80);
1770 	SLIST_FOREACH(bat, &sc->sc_bat, aba_link)
1771 		aml_notify(bat->aba_softc->sc_devnode,
1772 		    0x80);
1773 }
1774 
1775 #endif /* SMALL_KERNEL */
1776 
1777 void
1778 acpi_reset(void)
1779 {
1780 	u_int32_t		 reset_as, reset_len;
1781 	u_int32_t		 value;
1782 	struct acpi_softc	*sc = acpi_softc;
1783 	struct acpi_fadt	*fadt = sc->sc_fadt;
1784 
1785 	if (acpi_enabled == 0)
1786 		return;
1787 
1788 	/*
1789 	 * RESET_REG_SUP is not properly set in some implementations,
1790 	 * but not testing against it breaks more machines than it fixes
1791 	 */
1792 	if (fadt->hdr_revision <= 1 ||
1793 	    !(fadt->flags & FADT_RESET_REG_SUP) || fadt->reset_reg.address == 0)
1794 		return;
1795 
1796 	value = fadt->reset_value;
1797 
1798 	reset_as = fadt->reset_reg.register_bit_width / 8;
1799 	if (reset_as == 0)
1800 		reset_as = 1;
1801 
1802 	reset_len = fadt->reset_reg.access_size;
1803 	if (reset_len == 0)
1804 		reset_len = reset_as;
1805 
1806 	acpi_gasio(sc, ACPI_IOWRITE,
1807 	    fadt->reset_reg.address_space_id,
1808 	    fadt->reset_reg.address, reset_as, reset_len, &value);
1809 
1810 	delay(100000);
1811 }
1812 
1813 void
1814 acpi_gpe_task(void *arg0, int gpe)
1815 {
1816 	struct acpi_softc *sc = acpi_softc;
1817 	struct gpe_block *pgpe = &sc->gpe_table[gpe];
1818 
1819 	dnprintf(10, "handle gpe: %x\n", gpe);
1820 	if (pgpe->handler && pgpe->active) {
1821 		pgpe->active = 0;
1822 		pgpe->handler(sc, gpe, pgpe->arg);
1823 	}
1824 }
1825 
1826 void
1827 acpi_pbtn_task(void *arg0, int dummy)
1828 {
1829 	struct acpi_softc *sc = arg0;
1830 	uint16_t en;
1831 	int s;
1832 
1833 	dnprintf(1,"power button pressed\n");
1834 
1835 	/* Reset the latch and re-enable the GPE */
1836 	s = spltty();
1837 	en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
1838 	acpi_write_pmreg(sc, ACPIREG_PM1_EN,  0,
1839 	    en | ACPI_PM1_PWRBTN_EN);
1840 	splx(s);
1841 
1842 	acpi_addtask(sc, acpi_powerdown_task, sc, 0);
1843 }
1844 
1845 void
1846 acpi_sbtn_task(void *arg0, int dummy)
1847 {
1848 	struct acpi_softc *sc = arg0;
1849 	uint16_t en;
1850 	int s;
1851 
1852 	dnprintf(1,"sleep button pressed\n");
1853 	aml_notify_dev(ACPI_DEV_SBD, 0x80);
1854 
1855 	/* Reset the latch and re-enable the GPE */
1856 	s = spltty();
1857 	en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
1858 	acpi_write_pmreg(sc, ACPIREG_PM1_EN,  0,
1859 	    en | ACPI_PM1_SLPBTN_EN);
1860 	splx(s);
1861 }
1862 
1863 void
1864 acpi_powerdown_task(void *arg0, int dummy)
1865 {
1866 	extern int allowpowerdown;
1867 
1868 	if (allowpowerdown == 1) {
1869 		allowpowerdown = 0;
1870 		prsignal(initprocess, SIGUSR2);
1871 	}
1872 }
1873 
1874 int
1875 acpi_interrupt(void *arg)
1876 {
1877 	struct acpi_softc *sc = (struct acpi_softc *)arg;
1878 	u_int32_t processed = 0, idx, jdx;
1879 	u_int16_t sts, en;
1880 
1881 	dnprintf(40, "ACPI Interrupt\n");
1882 	for (idx = 0; idx < sc->sc_lastgpe; idx += 8) {
1883 		sts = acpi_read_pmreg(sc, ACPIREG_GPE_STS, idx>>3);
1884 		en  = acpi_read_pmreg(sc, ACPIREG_GPE_EN,  idx>>3);
1885 		if (en & sts) {
1886 			dnprintf(10, "GPE block: %.2x %.2x %.2x\n", idx, sts,
1887 			    en);
1888 			/* Mask the GPE until it is serviced */
1889 			acpi_write_pmreg(sc, ACPIREG_GPE_EN, idx>>3, en & ~sts);
1890 			for (jdx = 0; jdx < 8; jdx++) {
1891 				if (en & sts & (1L << jdx)) {
1892 					/* Signal this GPE */
1893 					sc->gpe_table[idx+jdx].active = 1;
1894 					dnprintf(10, "queue gpe: %x\n", idx+jdx);
1895 					acpi_addtask(sc, acpi_gpe_task, NULL, idx+jdx);
1896 
1897 					/*
1898 					 * Edge interrupts need their STS bits
1899 					 * cleared now.  Level interrupts will
1900 					 * have their STS bits cleared just
1901 					 * before they are re-enabled.
1902 					 */
1903 					if (sc->gpe_table[idx+jdx].edge)
1904 						acpi_write_pmreg(sc,
1905 						    ACPIREG_GPE_STS, idx>>3,
1906 						    1L << jdx);
1907 					processed = 1;
1908 				}
1909 			}
1910 		}
1911 	}
1912 
1913 	sts = acpi_read_pmreg(sc, ACPIREG_PM1_STS, 0);
1914 	en  = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
1915 	if (sts & en) {
1916 		dnprintf(10,"GEN interrupt: %.4x\n", sts & en);
1917 		sts &= en;
1918 		if (sts & ACPI_PM1_PWRBTN_STS) {
1919 			/* Mask and acknowledge */
1920 			en &= ~ACPI_PM1_PWRBTN_EN;
1921 			acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en);
1922 			acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0,
1923 			    ACPI_PM1_PWRBTN_STS);
1924 			sts &= ~ACPI_PM1_PWRBTN_STS;
1925 
1926 			acpi_addtask(sc, acpi_pbtn_task, sc, 0);
1927 		}
1928 		if (sts & ACPI_PM1_SLPBTN_STS) {
1929 			/* Mask and acknowledge */
1930 			en &= ~ACPI_PM1_SLPBTN_EN;
1931 			acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en);
1932 			acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0,
1933 			    ACPI_PM1_SLPBTN_STS);
1934 			sts &= ~ACPI_PM1_SLPBTN_STS;
1935 
1936 			acpi_addtask(sc, acpi_sbtn_task, sc, 0);
1937 		}
1938 		if (sts) {
1939 			printf("%s: PM1 stuck (en 0x%x st 0x%x), clearing\n",
1940 			    sc->sc_dev.dv_xname, en, sts);
1941 			acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en & ~sts);
1942 			acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, sts);
1943 		}
1944 		processed = 1;
1945 	}
1946 
1947 	if (processed) {
1948 		acpi_wakeup(sc);
1949 	}
1950 
1951 	return (processed);
1952 }
1953 
1954 int
1955 acpi_add_device(struct aml_node *node, void *arg)
1956 {
1957 	static int nacpicpus = 0;
1958 	struct device *self = arg;
1959 	struct acpi_softc *sc = arg;
1960 	struct acpi_attach_args aaa;
1961 	struct aml_value res;
1962 	CPU_INFO_ITERATOR cii;
1963 	struct cpu_info *ci;
1964 	int proc_id = -1;
1965 
1966 	memset(&aaa, 0, sizeof(aaa));
1967 	aaa.aaa_node = node;
1968 	aaa.aaa_iot = sc->sc_iot;
1969 	aaa.aaa_memt = sc->sc_memt;
1970 	if (node == NULL || node->value == NULL)
1971 		return 0;
1972 
1973 	switch (node->value->type) {
1974 	case AML_OBJTYPE_PROCESSOR:
1975 		if (nacpicpus >= ncpus)
1976 			return 0;
1977 		if (aml_evalnode(sc, aaa.aaa_node, 0, NULL, &res) == 0) {
1978 			if (res.type == AML_OBJTYPE_PROCESSOR)
1979 				proc_id = res.v_processor.proc_id;
1980 			aml_freevalue(&res);
1981 		}
1982 		CPU_INFO_FOREACH(cii, ci) {
1983 			if (ci->ci_acpi_proc_id == proc_id)
1984 				break;
1985 		}
1986 		if (ci == NULL)
1987 			return 0;
1988 		nacpicpus++;
1989 
1990 		aaa.aaa_name = "acpicpu";
1991 		break;
1992 	case AML_OBJTYPE_THERMZONE:
1993 		aaa.aaa_name = "acpitz";
1994 		break;
1995 	case AML_OBJTYPE_POWERRSRC:
1996 		aaa.aaa_name = "acpipwrres";
1997 		break;
1998 	default:
1999 		return 0;
2000 	}
2001 	config_found(self, &aaa, acpi_print);
2002 	return 0;
2003 }
2004 
2005 void
2006 acpi_enable_onegpe(struct acpi_softc *sc, int gpe)
2007 {
2008 	uint8_t mask, en;
2009 
2010 	/* Read enabled register */
2011 	mask = (1L << (gpe & 7));
2012 	en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, gpe>>3);
2013 	dnprintf(50, "enabling GPE %.2x (current: %sabled) %.2x\n",
2014 	    gpe, (en & mask) ? "en" : "dis", en);
2015 	acpi_write_pmreg(sc, ACPIREG_GPE_EN, gpe>>3, en | mask);
2016 }
2017 
2018 /* Clear all GPEs */
2019 void
2020 acpi_disable_allgpes(struct acpi_softc *sc)
2021 {
2022 	int idx;
2023 
2024 	for (idx = 0; idx < sc->sc_lastgpe; idx += 8) {
2025 		acpi_write_pmreg(sc, ACPIREG_GPE_EN, idx >> 3, 0);
2026 		acpi_write_pmreg(sc, ACPIREG_GPE_STS, idx >> 3, -1);
2027 	}
2028 }
2029 
2030 /* Enable runtime GPEs */
2031 void
2032 acpi_enable_rungpes(struct acpi_softc *sc)
2033 {
2034 	int idx;
2035 
2036 	for (idx = 0; idx < sc->sc_lastgpe; idx++)
2037 		if (sc->gpe_table[idx].handler)
2038 			acpi_enable_onegpe(sc, idx);
2039 }
2040 
2041 /* Enable wakeup GPEs */
2042 void
2043 acpi_enable_wakegpes(struct acpi_softc *sc, int state)
2044 {
2045 	struct acpi_wakeq *wentry;
2046 
2047 	SIMPLEQ_FOREACH(wentry, &sc->sc_wakedevs, q_next) {
2048 		dnprintf(10, "%.4s(S%d) gpe %.2x\n", wentry->q_node->name,
2049 		    wentry->q_state,
2050 		    wentry->q_gpe);
2051 		if (state <= wentry->q_state)
2052 			acpi_enable_onegpe(sc, wentry->q_gpe);
2053 	}
2054 }
2055 
2056 int
2057 acpi_set_gpehandler(struct acpi_softc *sc, int gpe, int (*handler)
2058     (struct acpi_softc *, int, void *), void *arg, int edge)
2059 {
2060 	struct gpe_block *ptbl;
2061 
2062 	ptbl = acpi_find_gpe(sc, gpe);
2063 	if (ptbl == NULL || handler == NULL)
2064 		return -EINVAL;
2065 	if (ptbl->handler != NULL) {
2066 		dnprintf(10, "error: GPE %.2x already enabled\n", gpe);
2067 		return -EBUSY;
2068 	}
2069 	dnprintf(50, "Adding GPE handler %.2x (%s)\n", gpe, edge ? "edge" : "level");
2070 	ptbl->handler = handler;
2071 	ptbl->arg = arg;
2072 	ptbl->edge = edge;
2073 
2074 	return (0);
2075 }
2076 
2077 int
2078 acpi_gpe(struct acpi_softc *sc, int gpe, void *arg)
2079 {
2080 	struct aml_node *node = arg;
2081 	uint8_t mask, en;
2082 
2083 	dnprintf(10, "handling GPE %.2x\n", gpe);
2084 	aml_evalnode(sc, node, 0, NULL, NULL);
2085 
2086 	mask = (1L << (gpe & 7));
2087 	if (!sc->gpe_table[gpe].edge)
2088 		acpi_write_pmreg(sc, ACPIREG_GPE_STS, gpe>>3, mask);
2089 	en = acpi_read_pmreg(sc, ACPIREG_GPE_EN,  gpe>>3);
2090 	acpi_write_pmreg(sc, ACPIREG_GPE_EN,  gpe>>3, en | mask);
2091 	return (0);
2092 }
2093 
2094 /* Discover Devices that can wakeup the system
2095  * _PRW returns a package
2096  *  pkg[0] = integer (FADT gpe bit) or package (gpe block,gpe bit)
2097  *  pkg[1] = lowest sleep state
2098  *  pkg[2+] = power resource devices (optional)
2099  *
2100  * To enable wakeup devices:
2101  *    Evaluate _ON method in each power resource device
2102  *    Evaluate _PSW method
2103  */
2104 int
2105 acpi_foundprw(struct aml_node *node, void *arg)
2106 {
2107 	struct acpi_softc *sc = arg;
2108 	struct acpi_wakeq *wq;
2109 	int64_t sta;
2110 
2111 	if (aml_evalinteger(sc, node->parent, "_STA", 0, NULL, &sta))
2112 		sta = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000;
2113 
2114 	if ((sta & STA_PRESENT) == 0)
2115 		return 0;
2116 
2117 	wq = malloc(sizeof(struct acpi_wakeq), M_DEVBUF, M_NOWAIT | M_ZERO);
2118 	if (wq == NULL)
2119 		return 0;
2120 
2121 	wq->q_wakepkg = malloc(sizeof(struct aml_value), M_DEVBUF,
2122 	    M_NOWAIT | M_ZERO);
2123 	if (wq->q_wakepkg == NULL) {
2124 		free(wq, M_DEVBUF, sizeof(*wq));
2125 		return 0;
2126 	}
2127 	dnprintf(10, "Found _PRW (%s)\n", node->parent->name);
2128 	aml_evalnode(sc, node, 0, NULL, wq->q_wakepkg);
2129 	wq->q_node = node->parent;
2130 	wq->q_gpe = -1;
2131 
2132 	/* Get GPE of wakeup device, and lowest sleep level */
2133 	if (wq->q_wakepkg->type == AML_OBJTYPE_PACKAGE &&
2134 	    wq->q_wakepkg->length >= 2) {
2135 		if (wq->q_wakepkg->v_package[0]->type == AML_OBJTYPE_INTEGER)
2136 			wq->q_gpe = wq->q_wakepkg->v_package[0]->v_integer;
2137 		if (wq->q_wakepkg->v_package[1]->type == AML_OBJTYPE_INTEGER)
2138 			wq->q_state = wq->q_wakepkg->v_package[1]->v_integer;
2139 	}
2140 	SIMPLEQ_INSERT_TAIL(&sc->sc_wakedevs, wq, q_next);
2141 	return 0;
2142 }
2143 
2144 struct gpe_block *
2145 acpi_find_gpe(struct acpi_softc *sc, int gpe)
2146 {
2147 	if (gpe >= sc->sc_lastgpe)
2148 		return NULL;
2149 	return &sc->gpe_table[gpe];
2150 }
2151 
2152 void
2153 acpi_init_gpes(struct acpi_softc *sc)
2154 {
2155 	struct aml_node *gpe;
2156 	char name[12];
2157 	int  idx, ngpe;
2158 
2159 	sc->sc_lastgpe = sc->sc_fadt->gpe0_blk_len << 2;
2160 	if (sc->sc_fadt->gpe1_blk_len) {
2161 	}
2162 	dnprintf(50, "Last GPE: %.2x\n", sc->sc_lastgpe);
2163 
2164 	/* Allocate GPE table */
2165 	sc->gpe_table = mallocarray(sc->sc_lastgpe, sizeof(struct gpe_block),
2166 	    M_DEVBUF, M_WAITOK | M_ZERO);
2167 
2168 	ngpe = 0;
2169 
2170 	/* Clear GPE status */
2171 	acpi_disable_allgpes(sc);
2172 	for (idx = 0; idx < sc->sc_lastgpe; idx++) {
2173 		/* Search Level-sensitive GPES */
2174 		snprintf(name, sizeof(name), "\\_GPE._L%.2X", idx);
2175 		gpe = aml_searchname(&aml_root, name);
2176 		if (gpe != NULL)
2177 			acpi_set_gpehandler(sc, idx, acpi_gpe, gpe, 0);
2178 		if (gpe == NULL) {
2179 			/* Search Edge-sensitive GPES */
2180 			snprintf(name, sizeof(name), "\\_GPE._E%.2X", idx);
2181 			gpe = aml_searchname(&aml_root, name);
2182 			if (gpe != NULL)
2183 				acpi_set_gpehandler(sc, idx, acpi_gpe, gpe, 1);
2184 		}
2185 	}
2186 	aml_find_node(&aml_root, "_PRW", acpi_foundprw, sc);
2187 	sc->sc_maxgpe = ngpe;
2188 }
2189 
2190 void
2191 acpi_init_pm(struct acpi_softc *sc)
2192 {
2193 	sc->sc_tts = aml_searchname(&aml_root, "_TTS");
2194 	sc->sc_pts = aml_searchname(&aml_root, "_PTS");
2195 	sc->sc_wak = aml_searchname(&aml_root, "_WAK");
2196 	sc->sc_bfs = aml_searchname(&aml_root, "_BFS");
2197 	sc->sc_gts = aml_searchname(&aml_root, "_GTS");
2198 	sc->sc_sst = aml_searchname(&aml_root, "_SI_._SST");
2199 }
2200 
2201 #ifndef SMALL_KERNEL
2202 
2203 void
2204 acpi_init_states(struct acpi_softc *sc)
2205 {
2206 	struct aml_value res;
2207 	char name[8];
2208 	int i;
2209 
2210 	printf("\n%s: sleep states", DEVNAME(sc));
2211 	for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) {
2212 		snprintf(name, sizeof(name), "_S%d_", i);
2213 		sc->sc_sleeptype[i].slp_typa = -1;
2214 		sc->sc_sleeptype[i].slp_typb = -1;
2215 		if (aml_evalname(sc, &aml_root, name, 0, NULL, &res) == 0) {
2216 			if (res.type == AML_OBJTYPE_PACKAGE) {
2217 				sc->sc_sleeptype[i].slp_typa = aml_val2int(res.v_package[0]);
2218 				sc->sc_sleeptype[i].slp_typb = aml_val2int(res.v_package[1]);
2219 				printf(" S%d", i);
2220 			}
2221 			aml_freevalue(&res);
2222 		}
2223 	}
2224 }
2225 
2226 void
2227 acpi_sleep_pm(struct acpi_softc *sc, int state)
2228 {
2229 	uint16_t rega, regb, regra, regrb;
2230 	int retry = 0;
2231 
2232 	disable_intr();
2233 
2234 	/* Clear WAK_STS bit */
2235 	acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_WAK_STS);
2236 
2237 	/* Disable BM arbitration at deep sleep and beyond */
2238 	if (state >= ACPI_STATE_S3 &&
2239 	    sc->sc_fadt->pm2_cnt_blk && sc->sc_fadt->pm2_cnt_len)
2240 		acpi_write_pmreg(sc, ACPIREG_PM2_CNT, 0, ACPI_PM2_ARB_DIS);
2241 
2242 	/* Write SLP_TYPx values */
2243 	rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0);
2244 	regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, 0);
2245 	rega &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
2246 	regb &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
2247 	rega |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typa);
2248 	regb |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typb);
2249 	acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
2250 	acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
2251 
2252 	/* Loop on WAK_STS, setting the SLP_EN bits once in a while */
2253 	rega |= ACPI_PM1_SLP_EN;
2254 	regb |= ACPI_PM1_SLP_EN;
2255 	while (1) {
2256 		if (retry == 0) {
2257 			acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
2258 			acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
2259 		}
2260 		retry = (retry + 1) % 100000;
2261 
2262 		regra = acpi_read_pmreg(sc, ACPIREG_PM1A_STS, 0);
2263 		regrb = acpi_read_pmreg(sc, ACPIREG_PM1B_STS, 0);
2264 		if ((regra & ACPI_PM1_WAK_STS) ||
2265 		    (regrb & ACPI_PM1_WAK_STS))
2266 			break;
2267 	}
2268 }
2269 
2270 u_int32_t acpi_force_bm;
2271 
2272 void
2273 acpi_resume_pm(struct acpi_softc *sc, int fromstate)
2274 {
2275 	uint16_t rega, regb, en;
2276 
2277 	/* Write SLP_TYPx values */
2278 	rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0);
2279 	regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, 0);
2280 	rega &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
2281 	regb &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
2282 	rega |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[ACPI_STATE_S0].slp_typa);
2283 	regb |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[ACPI_STATE_S0].slp_typb);
2284 	acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
2285 	acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
2286 
2287 	/* Force SCI_EN on resume to fix horribly broken machines */
2288 	acpi_write_pmreg(sc, ACPIREG_PM1_CNT, 0,
2289 	    ACPI_PM1_SCI_EN | acpi_force_bm);
2290 
2291 	/* Clear fixed event status */
2292 	acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_ALL_STS);
2293 
2294 	/* acpica-reference.pdf page 148 says do not call _BFS */
2295 	/* 1st resume AML step: _BFS(fromstate) */
2296 	aml_node_setval(sc, sc->sc_bfs, fromstate);
2297 
2298 	/* Enable runtime GPEs */
2299 	acpi_disable_allgpes(sc);
2300 	acpi_enable_rungpes(sc);
2301 
2302 	acpi_indicator(sc, ACPI_SST_WAKING);
2303 
2304 	/* 2nd resume AML step: _WAK(fromstate) */
2305 	aml_node_setval(sc, sc->sc_wak, fromstate);
2306 
2307 	/* Clear WAK_STS bit */
2308 	acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_WAK_STS);
2309 
2310 	en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
2311 	if (!(sc->sc_fadt->flags & FADT_PWR_BUTTON))
2312 		en |= ACPI_PM1_PWRBTN_EN;
2313 	if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON))
2314 		en |= ACPI_PM1_SLPBTN_EN;
2315 	acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en);
2316 
2317 	/*
2318 	 * If PM2 exists, re-enable BM arbitration (reportedly some
2319 	 * BIOS forget to)
2320 	 */
2321 	if (sc->sc_fadt->pm2_cnt_blk && sc->sc_fadt->pm2_cnt_len) {
2322 		rega = acpi_read_pmreg(sc, ACPIREG_PM2_CNT, 0);
2323 		rega &= ~ACPI_PM2_ARB_DIS;
2324 		acpi_write_pmreg(sc, ACPIREG_PM2_CNT, 0, rega);
2325 	}
2326 }
2327 
2328 /* Set the indicator light to some state */
2329 void
2330 acpi_indicator(struct acpi_softc *sc, int led_state)
2331 {
2332 	static int save_led_state = -1;
2333 
2334 	if (save_led_state != led_state) {
2335 		aml_node_setval(sc, sc->sc_sst, led_state);
2336 		save_led_state = led_state;
2337 	}
2338 }
2339 
2340 
2341 int
2342 acpi_sleep_state(struct acpi_softc *sc, int state)
2343 {
2344 	extern int perflevel;
2345 	extern int lid_suspend;
2346 	int error = ENXIO;
2347 	size_t rndbuflen = 0;
2348 	char *rndbuf = NULL;
2349 	int s;
2350 
2351 	switch (state) {
2352 	case ACPI_STATE_S0:
2353 		return (0);
2354 	case ACPI_STATE_S1:
2355 		return (EOPNOTSUPP);
2356 	case ACPI_STATE_S5:	/* only sleep states handled here */
2357 		return (EOPNOTSUPP);
2358 	}
2359 
2360 	if (sc->sc_sleeptype[state].slp_typa == -1 ||
2361 	    sc->sc_sleeptype[state].slp_typb == -1) {
2362 		printf("%s: state S%d unavailable\n",
2363 		    sc->sc_dev.dv_xname, state);
2364 		return (EOPNOTSUPP);
2365 	}
2366 
2367 	/* 1st suspend AML step: _TTS(tostate) */
2368 	if (aml_node_setval(sc, sc->sc_tts, state) != 0)
2369 		goto fail_tts;
2370 	acpi_indicator(sc, ACPI_SST_WAKING);	/* blink */
2371 
2372 #if NWSDISPLAY > 0
2373 	/*
2374 	 * Temporarily release the lock to prevent the X server from
2375 	 * blocking on setting the display brightness.
2376 	 */
2377 	rw_exit_write(&sc->sc_lck);
2378 	wsdisplay_suspend();
2379 	rw_enter_write(&sc->sc_lck);
2380 #endif /* NWSDISPLAY > 0 */
2381 
2382 	stop_periodic_resettodr();
2383 
2384 #ifdef HIBERNATE
2385 	if (state == ACPI_STATE_S4) {
2386 		uvmpd_hibernate();
2387 		hibernate_suspend_bufcache();
2388 		if (hibernate_alloc()) {
2389 			printf("%s: failed to allocate hibernate memory\n",
2390 			    sc->sc_dev.dv_xname);
2391 			goto fail_alloc;
2392 		}
2393 	}
2394 #endif /* HIBERNATE */
2395 
2396 	if (config_suspend_all(DVACT_QUIESCE))
2397 		goto fail_quiesce;
2398 
2399 	bufq_quiesce();
2400 
2401 #ifdef MULTIPROCESSOR
2402 	acpi_sleep_mp();
2403 #endif
2404 
2405 	resettodr();
2406 
2407 	s = splhigh();
2408 	disable_intr();	/* PSL_I for resume; PIC/APIC broken until repair */
2409 	cold = 2;	/* Force other code to delay() instead of tsleep() */
2410 
2411 	if (config_suspend_all(DVACT_SUSPEND) != 0)
2412 		goto fail_suspend;
2413 	acpi_sleep_clocks(sc, state);
2414 
2415 	suspend_randomness();
2416 
2417 	/* 2nd suspend AML step: _PTS(tostate) */
2418 	if (aml_node_setval(sc, sc->sc_pts, state) != 0)
2419 		goto fail_pts;
2420 
2421 	acpibtn_enable_psw();	/* enable _LID for wakeup */
2422 	acpi_indicator(sc, ACPI_SST_SLEEPING);
2423 
2424 	/* 3rd suspend AML step: _GTS(tostate) */
2425 	aml_node_setval(sc, sc->sc_gts, state);
2426 
2427 	/* Clear fixed event status */
2428 	acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_ALL_STS);
2429 
2430 	/* Enable wake GPEs */
2431 	acpi_disable_allgpes(sc);
2432 	acpi_enable_wakegpes(sc, state);
2433 
2434 	/* Sleep */
2435 	sc->sc_state = state;
2436 	error = acpi_sleep_cpu(sc, state);
2437 	sc->sc_state = ACPI_STATE_S0;
2438 	/* Resume */
2439 
2440 #ifdef HIBERNATE
2441 	if (state == ACPI_STATE_S4) {
2442 		uvm_pmr_dirty_everything();
2443 		hib_getentropy(&rndbuf, &rndbuflen);
2444 	}
2445 #endif /* HIBERNATE */
2446 
2447 	acpi_resume_clocks(sc);		/* AML may need clocks */
2448 	acpi_resume_pm(sc, state);
2449 	acpi_resume_cpu(sc);
2450 
2451 fail_pts:
2452 	config_suspend_all(DVACT_RESUME);
2453 
2454 fail_suspend:
2455 	cold = 0;
2456 	enable_intr();
2457 	splx(s);
2458 
2459 	acpibtn_disable_psw();		/* disable _LID for wakeup */
2460 	inittodr(time_second);
2461 
2462 	/* 3rd resume AML step: _TTS(runstate) */
2463 	aml_node_setval(sc, sc->sc_tts, sc->sc_state);
2464 
2465 	resume_randomness(rndbuf, rndbuflen);	/* force RNG upper level reseed */
2466 
2467 #ifdef MULTIPROCESSOR
2468 	acpi_resume_mp();
2469 #endif
2470 
2471 	bufq_restart();
2472 
2473 fail_quiesce:
2474 	config_suspend_all(DVACT_WAKEUP);
2475 
2476 #ifdef HIBERNATE
2477 fail_alloc:
2478 	if (state == ACPI_STATE_S4) {
2479 		hibernate_free();
2480 		hibernate_resume_bufcache();
2481 	}
2482 #endif /* HIBERNATE */
2483 
2484 	start_periodic_resettodr();
2485 
2486 #if NWSDISPLAY > 0
2487 	rw_exit_write(&sc->sc_lck);
2488 	wsdisplay_resume();
2489 	rw_enter_write(&sc->sc_lck);
2490 #endif /* NWSDISPLAY > 0 */
2491 
2492 	/* Restore hw.setperf */
2493 	if (cpu_setperf != NULL)
2494 		cpu_setperf(perflevel);
2495 
2496 	acpi_record_event(sc, APM_NORMAL_RESUME);
2497 	acpi_indicator(sc, ACPI_SST_WORKING);
2498 
2499 	/* If we woke up but all the lids are closed, go back to sleep */
2500 	if (acpibtn_numopenlids() == 0 && lid_suspend != 0)
2501 		acpi_addtask(sc, acpi_sleep_task, sc, state);
2502 
2503 fail_tts:
2504 	return (error);
2505 }
2506 
2507 /* XXX
2508  * We are going to do AML execution but are not in the acpi thread.
2509  * We do not know if the acpi thread is sleeping on acpiec in some
2510  * intermediate context.  Wish us luck.
2511  */
2512 void
2513 acpi_powerdown(void)
2514 {
2515 	int state = ACPI_STATE_S5, s;
2516 	struct acpi_softc *sc = acpi_softc;
2517 
2518 	if (acpi_enabled == 0)
2519 		return;
2520 
2521 	s = splhigh();
2522 	disable_intr();
2523 	cold = 1;
2524 
2525 	/* 1st powerdown AML step: _PTS(tostate) */
2526 	aml_node_setval(sc, sc->sc_pts, state);
2527 
2528 	acpi_disable_allgpes(sc);
2529 	acpi_enable_wakegpes(sc, state);
2530 
2531 	/* 2nd powerdown AML step: _GTS(tostate) */
2532 	aml_node_setval(sc, sc->sc_gts, state);
2533 
2534 	acpi_sleep_pm(sc, state);
2535 	panic("acpi S5 transition did not happen");
2536 	while (1)
2537 		;
2538 }
2539 
2540 int
2541 acpi_map_address(struct acpi_softc *sc, struct acpi_gas *gas, bus_addr_t base,
2542     bus_size_t size, bus_space_handle_t *pioh, bus_space_tag_t *piot)
2543 {
2544 	int iospace = GAS_SYSTEM_IOSPACE;
2545 
2546 	/* No GAS structure, default to I/O space */
2547 	if (gas != NULL) {
2548 		base += gas->address;
2549 		iospace = gas->address_space_id;
2550 	}
2551 	switch (iospace) {
2552 	case GAS_SYSTEM_MEMORY:
2553 		*piot = sc->sc_memt;
2554 		break;
2555 	case GAS_SYSTEM_IOSPACE:
2556 		*piot = sc->sc_iot;
2557 		break;
2558 	default:
2559 		return -1;
2560 	}
2561 	if (bus_space_map(*piot, base, size, 0, pioh))
2562 		return -1;
2563 
2564 	return 0;
2565 }
2566 
2567 #endif /* SMALL_KERNEL */
2568 
2569 void
2570 acpi_wakeup(void *arg)
2571 {
2572 	struct acpi_softc  *sc = (struct acpi_softc *)arg;
2573 
2574 	sc->sc_threadwaiting = 0;
2575 	wakeup(sc);
2576 }
2577 
2578 
2579 void
2580 acpi_thread(void *arg)
2581 {
2582 	struct acpi_thread *thread = arg;
2583 	struct acpi_softc  *sc = thread->sc;
2584 	extern int aml_busy;
2585 	int s;
2586 
2587 	/* AML/SMI cannot be trusted -- only run on the BSP */
2588 	sched_peg_curproc(&cpu_info_primary);
2589 
2590 	rw_enter_write(&sc->sc_lck);
2591 
2592 	/*
2593 	 * If we have an interrupt handler, we can get notification
2594 	 * when certain status bits changes in the ACPI registers,
2595 	 * so let us enable some events we can forward to userland
2596 	 */
2597 	if (sc->sc_interrupt) {
2598 		int16_t en;
2599 
2600 		dnprintf(1,"slpbtn:%c  pwrbtn:%c\n",
2601 		    sc->sc_fadt->flags & FADT_SLP_BUTTON ? 'n' : 'y',
2602 		    sc->sc_fadt->flags & FADT_PWR_BUTTON ? 'n' : 'y');
2603 		dnprintf(10, "Enabling acpi interrupts...\n");
2604 		sc->sc_threadwaiting = 1;
2605 
2606 		/* Enable Sleep/Power buttons if they exist */
2607 		s = spltty();
2608 		en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
2609 		if (!(sc->sc_fadt->flags & FADT_PWR_BUTTON))
2610 			en |= ACPI_PM1_PWRBTN_EN;
2611 		if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON))
2612 			en |= ACPI_PM1_SLPBTN_EN;
2613 		acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en);
2614 
2615 		/* Enable handled GPEs here */
2616 		acpi_enable_rungpes(sc);
2617 		splx(s);
2618 	}
2619 
2620 	while (thread->running) {
2621 		s = spltty();
2622 		while (sc->sc_threadwaiting) {
2623 			dnprintf(10, "acpi thread going to sleep...\n");
2624 			rw_exit_write(&sc->sc_lck);
2625 			tsleep(sc, PWAIT, "acpi0", 0);
2626 			rw_enter_write(&sc->sc_lck);
2627 		}
2628 		sc->sc_threadwaiting = 1;
2629 		splx(s);
2630 		if (aml_busy) {
2631 			panic("thread woke up to find aml was busy");
2632 			continue;
2633 		}
2634 
2635 		/* Run ACPI taskqueue */
2636 		while(acpi_dotask(acpi_softc))
2637 			;
2638 	}
2639 	free(thread, M_DEVBUF, sizeof(*thread));
2640 
2641 	kthread_exit(0);
2642 }
2643 
2644 void
2645 acpi_create_thread(void *arg)
2646 {
2647 	struct acpi_softc *sc = arg;
2648 
2649 	if (kthread_create(acpi_thread, sc->sc_thread, NULL, DEVNAME(sc))
2650 	    != 0)
2651 		printf("%s: unable to create isr thread, GPEs disabled\n",
2652 		    DEVNAME(sc));
2653 }
2654 
2655 int
2656 acpi_foundec(struct aml_node *node, void *arg)
2657 {
2658 	struct acpi_softc	*sc = (struct acpi_softc *)arg;
2659 	struct device		*self = (struct device *)arg;
2660 	const char		*dev;
2661 	struct aml_value	 res;
2662 	struct acpi_attach_args	aaa;
2663 
2664 	if (aml_evalnode(sc, node, 0, NULL, &res) != 0)
2665 		return 0;
2666 
2667 	switch (res.type) {
2668 	case AML_OBJTYPE_STRING:
2669 		dev = res.v_string;
2670 		break;
2671 	case AML_OBJTYPE_INTEGER:
2672 		dev = aml_eisaid(aml_val2int(&res));
2673 		break;
2674 	default:
2675 		dev = "unknown";
2676 		break;
2677 	}
2678 
2679 	if (strcmp(dev, ACPI_DEV_ECD))
2680 		return 0;
2681 
2682 	/* Check if we're already attached */
2683 	if (sc->sc_ec && sc->sc_ec->sc_devnode == node->parent)
2684 		return 0;
2685 
2686 	memset(&aaa, 0, sizeof(aaa));
2687 	aaa.aaa_iot = sc->sc_iot;
2688 	aaa.aaa_memt = sc->sc_memt;
2689 	aaa.aaa_node = node->parent;
2690 	aaa.aaa_dev = dev;
2691 	aaa.aaa_name = "acpiec";
2692 	config_found(self, &aaa, acpi_print);
2693 	aml_freevalue(&res);
2694 
2695 	return 0;
2696 }
2697 
2698 int
2699 acpi_foundsony(struct aml_node *node, void *arg)
2700 {
2701 	struct acpi_softc *sc = (struct acpi_softc *)arg;
2702 	struct device *self = (struct device *)arg;
2703 	struct acpi_attach_args aaa;
2704 
2705 	memset(&aaa, 0, sizeof(aaa));
2706 	aaa.aaa_iot = sc->sc_iot;
2707 	aaa.aaa_memt = sc->sc_memt;
2708 	aaa.aaa_node = node->parent;
2709 	aaa.aaa_name = "acpisony";
2710 
2711 	config_found(self, &aaa, acpi_print);
2712 
2713 	return 0;
2714 }
2715 
2716 int
2717 acpi_parsehid(struct aml_node *node, void *arg, char *outcdev, char *outdev,
2718     size_t devlen)
2719 {
2720 	struct acpi_softc	*sc = (struct acpi_softc *)arg;
2721 	struct aml_value	 res;
2722 	const char		*dev;
2723 
2724 	/* NB aml_eisaid returns a static buffer, this must come first */
2725 	if (aml_evalname(acpi_softc, node->parent, "_CID", 0, NULL, &res) == 0) {
2726 		switch (res.type) {
2727 		case AML_OBJTYPE_STRING:
2728 			dev = res.v_string;
2729 			break;
2730 		case AML_OBJTYPE_INTEGER:
2731 			dev = aml_eisaid(aml_val2int(&res));
2732 			break;
2733 		default:
2734 			dev = "unknown";
2735 			break;
2736 		}
2737 		strlcpy(outcdev, dev, devlen);
2738 		aml_freevalue(&res);
2739 
2740 		dnprintf(10, "compatible with device: %s\n", outcdev);
2741 	} else {
2742 		outcdev[0] = '\0';
2743 	}
2744 
2745 	dnprintf(10, "found hid device: %s ", node->parent->name);
2746 	if (aml_evalnode(sc, node, 0, NULL, &res) != 0)
2747 		return (1);
2748 
2749 	switch (res.type) {
2750 	case AML_OBJTYPE_STRING:
2751 		dev = res.v_string;
2752 		break;
2753 	case AML_OBJTYPE_INTEGER:
2754 		dev = aml_eisaid(aml_val2int(&res));
2755 		break;
2756 	default:
2757 		dev = "unknown";
2758 		break;
2759 	}
2760 	dnprintf(10, "	device: %s\n", dev);
2761 
2762 	strlcpy(outdev, dev, devlen);
2763 
2764 	aml_freevalue(&res);
2765 
2766 	return (0);
2767 }
2768 
2769 /* Devices for which we don't want to attach a driver */
2770 const char *acpi_skip_hids[] = {
2771 	"INT0800",	/* Intel 82802Firmware Hub Device */
2772 	"PNP0000",	/* 8259-compatible Programmable Interrupt Controller */
2773 	"PNP0100",	/* PC-class System Timer */
2774 	"PNP0103",	/* HPET System Timer */
2775 	"PNP0200",	/* PC-class DMA Controller */
2776 	"PNP0800",	/* Microsoft Sound System Compatible Device */
2777 	"PNP0A03",	/* PCI Bus */
2778 	"PNP0A08",	/* PCI Express Bus */
2779 	"PNP0B00",	/* AT Real-Time Clock */
2780 	"PNP0C01",	/* System Board */
2781 	"PNP0C02",	/* PNP Motherboard Resources */
2782 	"PNP0C04",	/* x87-compatible Floating Point Processing Unit */
2783 	"PNP0C09",	/* Embedded Controller Device */
2784 	"PNP0C0F",	/* PCI Interrupt Link Device */
2785 	NULL
2786 };
2787 
2788 void
2789 acpi_attach_deps(struct acpi_softc *sc, struct aml_node *node)
2790 {
2791 	struct aml_value res;
2792 	struct aml_node *dep;
2793 	int i;
2794 
2795 	if (aml_evalname(sc, node, "_DEP", 0, NULL, &res))
2796 		return;
2797 
2798 	if (res.type != AML_OBJTYPE_PACKAGE)
2799 		return;
2800 
2801 	for (i = 0; i < res.length; i++) {
2802 		if (res.v_package[i]->type != AML_OBJTYPE_STRING)
2803 			continue;
2804 		dep = aml_searchrel(node, res.v_package[i]->v_string);
2805 		if (dep == NULL || dep->attached)
2806 			continue;
2807 		dep = aml_searchname(dep, "_HID");
2808 		if (dep)
2809 			acpi_foundhid(dep, sc);
2810 	}
2811 
2812 	aml_freevalue(&res);
2813 }
2814 
2815 int
2816 acpi_foundhid(struct aml_node *node, void *arg)
2817 {
2818 	struct acpi_softc	*sc = (struct acpi_softc *)arg;
2819 	struct device		*self = (struct device *)arg;
2820 	char		 	 cdev[16];
2821 	char		 	 dev[16];
2822 	struct acpi_attach_args	 aaa;
2823 	int64_t			 sta;
2824 #ifndef SMALL_KERNEL
2825 	int			 i;
2826 #endif
2827 
2828 	if (acpi_parsehid(node, arg, cdev, dev, 16) != 0)
2829 		return (0);
2830 
2831 	if (aml_evalinteger(sc, node->parent, "_STA", 0, NULL, &sta))
2832 		sta = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000;
2833 
2834 	if ((sta & STA_PRESENT) == 0)
2835 		return (0);
2836 
2837 	acpi_attach_deps(sc, node->parent);
2838 
2839 	memset(&aaa, 0, sizeof(aaa));
2840 	aaa.aaa_iot = sc->sc_iot;
2841 	aaa.aaa_memt = sc->sc_memt;
2842 	aaa.aaa_node = node->parent;
2843 	aaa.aaa_dev = dev;
2844 
2845 	if (acpi_matchhids(&aaa, acpi_skip_hids, "none"))
2846 		return (0);
2847 
2848 #ifndef SMALL_KERNEL
2849 	if (!strcmp(cdev, ACPI_DEV_MOUSE)) {
2850 		for (i = 0; i < nitems(sbtn_pnp); i++) {
2851 			if (!strcmp(dev, sbtn_pnp[i])) {
2852 				mouse_has_softbtn = 1;
2853 				break;
2854 			}
2855 		}
2856 	}
2857 #endif
2858 
2859 	if (!node->parent->attached) {
2860 		config_found(self, &aaa, acpi_print);
2861 		node->parent->attached = 1;
2862 	}
2863 
2864 	return (0);
2865 }
2866 
2867 #ifndef SMALL_KERNEL
2868 int
2869 acpi_founddock(struct aml_node *node, void *arg)
2870 {
2871 	struct acpi_softc	*sc = (struct acpi_softc *)arg;
2872 	struct device		*self = (struct device *)arg;
2873 	struct acpi_attach_args	aaa;
2874 
2875 	dnprintf(10, "found dock entry: %s\n", node->parent->name);
2876 
2877 	memset(&aaa, 0, sizeof(aaa));
2878 	aaa.aaa_iot = sc->sc_iot;
2879 	aaa.aaa_memt = sc->sc_memt;
2880 	aaa.aaa_node = node->parent;
2881 	aaa.aaa_name = "acpidock";
2882 
2883 	config_found(self, &aaa, acpi_print);
2884 
2885 	return 0;
2886 }
2887 
2888 int
2889 acpi_foundvideo(struct aml_node *node, void *arg)
2890 {
2891 	struct acpi_softc *sc = (struct acpi_softc *)arg;
2892 	struct device *self = (struct device *)arg;
2893 	struct acpi_attach_args	aaa;
2894 
2895 	memset(&aaa, 0, sizeof(aaa));
2896 	aaa.aaa_iot = sc->sc_iot;
2897 	aaa.aaa_memt = sc->sc_memt;
2898 	aaa.aaa_node = node->parent;
2899 	aaa.aaa_name = "acpivideo";
2900 
2901 	config_found(self, &aaa, acpi_print);
2902 
2903 	return (0);
2904 }
2905 
2906 int
2907 acpiopen(dev_t dev, int flag, int mode, struct proc *p)
2908 {
2909 	int error = 0;
2910 	struct acpi_softc *sc;
2911 	int s;
2912 
2913 	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
2914 	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
2915 		return (ENXIO);
2916 
2917 	s = spltty();
2918 	switch (APMDEV(dev)) {
2919 	case APMDEV_CTL:
2920 		if (!(flag & FWRITE)) {
2921 			error = EINVAL;
2922 			break;
2923 		}
2924 		if (sc->sc_flags & SCFLAG_OWRITE) {
2925 			error = EBUSY;
2926 			break;
2927 		}
2928 		sc->sc_flags |= SCFLAG_OWRITE;
2929 		break;
2930 	case APMDEV_NORMAL:
2931 		if (!(flag & FREAD) || (flag & FWRITE)) {
2932 			error = EINVAL;
2933 			break;
2934 		}
2935 		sc->sc_flags |= SCFLAG_OREAD;
2936 		break;
2937 	default:
2938 		error = ENXIO;
2939 		break;
2940 	}
2941 	splx(s);
2942 	return (error);
2943 }
2944 
2945 int
2946 acpiclose(dev_t dev, int flag, int mode, struct proc *p)
2947 {
2948 	int error = 0;
2949 	struct acpi_softc *sc;
2950 	int s;
2951 
2952 	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
2953 	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
2954 		return (ENXIO);
2955 
2956 	s = spltty();
2957 	switch (APMDEV(dev)) {
2958 	case APMDEV_CTL:
2959 		sc->sc_flags &= ~SCFLAG_OWRITE;
2960 		break;
2961 	case APMDEV_NORMAL:
2962 		sc->sc_flags &= ~SCFLAG_OREAD;
2963 		break;
2964 	default:
2965 		error = ENXIO;
2966 		break;
2967 	}
2968 	splx(s);
2969 	return (error);
2970 }
2971 
2972 int
2973 acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
2974 {
2975 	int error = 0;
2976 	struct acpi_softc *sc;
2977 	struct acpi_ac *ac;
2978 	struct acpi_bat *bat;
2979 	struct apm_power_info *pi = (struct apm_power_info *)data;
2980 	int bats;
2981 	unsigned int remaining, rem, minutes, rate;
2982 	int s;
2983 
2984 	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
2985 	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
2986 		return (ENXIO);
2987 
2988 	s = spltty();
2989 	/* fake APM */
2990 	switch (cmd) {
2991 	case APM_IOC_SUSPEND:
2992 	case APM_IOC_STANDBY:
2993 		if ((flag & FWRITE) == 0) {
2994 			error = EBADF;
2995 			break;
2996 		}
2997 		acpi_addtask(sc, acpi_sleep_task, sc, ACPI_STATE_S3);
2998 		acpi_wakeup(sc);
2999 		break;
3000 #ifdef HIBERNATE
3001 	case APM_IOC_HIBERNATE:
3002 		if ((error = suser(p, 0)) != 0)
3003 			break;
3004 		if ((flag & FWRITE) == 0) {
3005 			error = EBADF;
3006 			break;
3007 		}
3008 		if (get_hibernate_io_function(swdevt[0].sw_dev) == NULL) {
3009 			error = EOPNOTSUPP;
3010 			break;
3011 		}
3012 		acpi_addtask(sc, acpi_sleep_task, sc, ACPI_STATE_S4);
3013 		acpi_wakeup(sc);
3014 		break;
3015 #endif
3016 	case APM_IOC_GETPOWER:
3017 		/* A/C */
3018 		pi->ac_state = APM_AC_UNKNOWN;
3019 		SLIST_FOREACH(ac, &sc->sc_ac, aac_link) {
3020 			if (ac->aac_softc->sc_ac_stat == PSR_ONLINE)
3021 				pi->ac_state = APM_AC_ON;
3022 			else if (ac->aac_softc->sc_ac_stat == PSR_OFFLINE)
3023 				if (pi->ac_state == APM_AC_UNKNOWN)
3024 					pi->ac_state = APM_AC_OFF;
3025 		}
3026 
3027 		/* battery */
3028 		pi->battery_state = APM_BATT_UNKNOWN;
3029 		pi->battery_life = 0;
3030 		pi->minutes_left = 0;
3031 		bats = 0;
3032 		remaining = rem = 0;
3033 		minutes = 0;
3034 		rate = 0;
3035 		SLIST_FOREACH(bat, &sc->sc_bat, aba_link) {
3036 			if (bat->aba_softc->sc_bat_present == 0)
3037 				continue;
3038 
3039 			if (bat->aba_softc->sc_bif.bif_last_capacity == 0)
3040 				continue;
3041 
3042 			bats++;
3043 			rem = (bat->aba_softc->sc_bst.bst_capacity * 100) /
3044 			    bat->aba_softc->sc_bif.bif_last_capacity;
3045 			if (rem > 100)
3046 				rem = 100;
3047 			remaining += rem;
3048 
3049 			if (bat->aba_softc->sc_bst.bst_rate == BST_UNKNOWN)
3050 				continue;
3051 			else if (bat->aba_softc->sc_bst.bst_rate > 1)
3052 				rate = bat->aba_softc->sc_bst.bst_rate;
3053 
3054 			minutes += bat->aba_softc->sc_bst.bst_capacity;
3055 		}
3056 
3057 		if (bats == 0) {
3058 			pi->battery_state = APM_BATTERY_ABSENT;
3059 			pi->battery_life = 0;
3060 			pi->minutes_left = (unsigned int)-1;
3061 			break;
3062 		}
3063 
3064 		if (pi->ac_state == APM_AC_ON || rate == 0)
3065 			pi->minutes_left = (unsigned int)-1;
3066 		else
3067 			pi->minutes_left = 60 * minutes / rate;
3068 
3069 		/* running on battery */
3070 		pi->battery_life = remaining / bats;
3071 		if (pi->battery_life > 50)
3072 			pi->battery_state = APM_BATT_HIGH;
3073 		else if (pi->battery_life > 25)
3074 			pi->battery_state = APM_BATT_LOW;
3075 		else
3076 			pi->battery_state = APM_BATT_CRITICAL;
3077 
3078 		break;
3079 
3080 	default:
3081 		error = ENOTTY;
3082 	}
3083 
3084 	splx(s);
3085 	return (error);
3086 }
3087 
3088 void	acpi_filtdetach(struct knote *);
3089 int	acpi_filtread(struct knote *, long);
3090 
3091 struct filterops acpiread_filtops = {
3092 	1, NULL, acpi_filtdetach, acpi_filtread
3093 };
3094 
3095 int acpi_evindex;
3096 
3097 int
3098 acpi_record_event(struct acpi_softc *sc, u_int type)
3099 {
3100 	if ((sc->sc_flags & SCFLAG_OPEN) == 0)
3101 		return (1);
3102 
3103 	acpi_evindex++;
3104 	KNOTE(sc->sc_note, APM_EVENT_COMPOSE(type, acpi_evindex));
3105 	return (0);
3106 }
3107 
3108 void
3109 acpi_filtdetach(struct knote *kn)
3110 {
3111 	struct acpi_softc *sc = kn->kn_hook;
3112 	int s;
3113 
3114 	s = spltty();
3115 	SLIST_REMOVE(sc->sc_note, kn, knote, kn_selnext);
3116 	splx(s);
3117 }
3118 
3119 int
3120 acpi_filtread(struct knote *kn, long hint)
3121 {
3122 	/* XXX weird kqueue_scan() semantics */
3123 	if (hint && !kn->kn_data)
3124 		kn->kn_data = hint;
3125 	return (1);
3126 }
3127 
3128 int
3129 acpikqfilter(dev_t dev, struct knote *kn)
3130 {
3131 	struct acpi_softc *sc;
3132 	int s;
3133 
3134 	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
3135 	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
3136 		return (ENXIO);
3137 
3138 	switch (kn->kn_filter) {
3139 	case EVFILT_READ:
3140 		kn->kn_fop = &acpiread_filtops;
3141 		break;
3142 	default:
3143 		return (EINVAL);
3144 	}
3145 
3146 	kn->kn_hook = sc;
3147 
3148 	s = spltty();
3149 	SLIST_INSERT_HEAD(sc->sc_note, kn, kn_selnext);
3150 	splx(s);
3151 
3152 	return (0);
3153 }
3154 
3155 #else /* SMALL_KERNEL */
3156 
3157 int
3158 acpiopen(dev_t dev, int flag, int mode, struct proc *p)
3159 {
3160 	return (ENXIO);
3161 }
3162 
3163 int
3164 acpiclose(dev_t dev, int flag, int mode, struct proc *p)
3165 {
3166 	return (ENXIO);
3167 }
3168 
3169 int
3170 acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
3171 {
3172 	return (ENXIO);
3173 }
3174 
3175 int
3176 acpikqfilter(dev_t dev, struct knote *kn)
3177 {
3178 	return (ENXIO);
3179 }
3180 #endif /* SMALL_KERNEL */
3181