xref: /openbsd-src/sys/dev/acpi/acpi.c (revision 0b7734b3d77bb9b21afec6f4621cae6c805dbd45)
1 /* $OpenBSD: acpi.c,v 1.312 2016/06/10 20:03:46 kettenis Exp $ */
2 /*
3  * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
4  * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/buf.h>
22 #include <sys/device.h>
23 #include <sys/malloc.h>
24 #include <sys/fcntl.h>
25 #include <sys/ioccom.h>
26 #include <sys/event.h>
27 #include <sys/signalvar.h>
28 #include <sys/proc.h>
29 #include <sys/kthread.h>
30 #include <sys/sched.h>
31 #include <sys/reboot.h>
32 #include <sys/sysctl.h>
33 
34 #ifdef HIBERNATE
35 #include <sys/hibernate.h>
36 #endif
37 
38 #include <machine/conf.h>
39 #include <machine/cpufunc.h>
40 #include <machine/bus.h>
41 
42 #include <dev/rndvar.h>
43 #include <dev/pci/pcivar.h>
44 #include <dev/acpi/acpireg.h>
45 #include <dev/acpi/acpivar.h>
46 #include <dev/acpi/amltypes.h>
47 #include <dev/acpi/acpidev.h>
48 #include <dev/acpi/dsdt.h>
49 #include <dev/wscons/wsdisplayvar.h>
50 
51 #include <dev/pci/pcidevs.h>
52 #include <dev/pci/ppbreg.h>
53 
54 #include <dev/pci/pciidevar.h>
55 
56 #include <machine/apmvar.h>
57 #define APMUNIT(dev)	(minor(dev)&0xf0)
58 #define APMDEV(dev)	(minor(dev)&0x0f)
59 #define APMDEV_NORMAL	0
60 #define APMDEV_CTL	8
61 
62 #include "wd.h"
63 #include "wsdisplay.h"
64 
65 #ifdef ACPI_DEBUG
66 int	acpi_debug = 16;
67 #endif
68 
69 int	acpi_poll_enabled;
70 int	acpi_hasprocfvs;
71 
72 #define ACPIEN_RETRIES 15
73 
74 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 #ifdef MULTIPROCESSOR
1962 	struct aml_value res;
1963 	int proc_id = -1;
1964 #endif
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 #ifdef MULTIPROCESSOR
1978 		if (aml_evalnode(sc, aaa.aaa_node, 0, NULL, &res) == 0) {
1979 			if (res.type == AML_OBJTYPE_PROCESSOR)
1980 				proc_id = res.v_processor.proc_id;
1981 			aml_freevalue(&res);
1982 		}
1983 		if (proc_id < -1 || proc_id >= LAPIC_MAP_SIZE ||
1984 		    (acpi_lapic_flags[proc_id] & ACPI_PROC_ENABLE) == 0)
1985 			return 0;
1986 #endif
1987 		nacpicpus++;
1988 
1989 		aaa.aaa_name = "acpicpu";
1990 		break;
1991 	case AML_OBJTYPE_THERMZONE:
1992 		aaa.aaa_name = "acpitz";
1993 		break;
1994 	case AML_OBJTYPE_POWERRSRC:
1995 		aaa.aaa_name = "acpipwrres";
1996 		break;
1997 	default:
1998 		return 0;
1999 	}
2000 	config_found(self, &aaa, acpi_print);
2001 	return 0;
2002 }
2003 
2004 void
2005 acpi_enable_onegpe(struct acpi_softc *sc, int gpe)
2006 {
2007 	uint8_t mask, en;
2008 
2009 	/* Read enabled register */
2010 	mask = (1L << (gpe & 7));
2011 	en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, gpe>>3);
2012 	dnprintf(50, "enabling GPE %.2x (current: %sabled) %.2x\n",
2013 	    gpe, (en & mask) ? "en" : "dis", en);
2014 	acpi_write_pmreg(sc, ACPIREG_GPE_EN, gpe>>3, en | mask);
2015 }
2016 
2017 /* Clear all GPEs */
2018 void
2019 acpi_disable_allgpes(struct acpi_softc *sc)
2020 {
2021 	int idx;
2022 
2023 	for (idx = 0; idx < sc->sc_lastgpe; idx += 8) {
2024 		acpi_write_pmreg(sc, ACPIREG_GPE_EN, idx >> 3, 0);
2025 		acpi_write_pmreg(sc, ACPIREG_GPE_STS, idx >> 3, -1);
2026 	}
2027 }
2028 
2029 /* Enable runtime GPEs */
2030 void
2031 acpi_enable_rungpes(struct acpi_softc *sc)
2032 {
2033 	int idx;
2034 
2035 	for (idx = 0; idx < sc->sc_lastgpe; idx++)
2036 		if (sc->gpe_table[idx].handler)
2037 			acpi_enable_onegpe(sc, idx);
2038 }
2039 
2040 /* Enable wakeup GPEs */
2041 void
2042 acpi_enable_wakegpes(struct acpi_softc *sc, int state)
2043 {
2044 	struct acpi_wakeq *wentry;
2045 
2046 	SIMPLEQ_FOREACH(wentry, &sc->sc_wakedevs, q_next) {
2047 		dnprintf(10, "%.4s(S%d) gpe %.2x\n", wentry->q_node->name,
2048 		    wentry->q_state,
2049 		    wentry->q_gpe);
2050 		if (state <= wentry->q_state)
2051 			acpi_enable_onegpe(sc, wentry->q_gpe);
2052 	}
2053 }
2054 
2055 int
2056 acpi_set_gpehandler(struct acpi_softc *sc, int gpe, int (*handler)
2057     (struct acpi_softc *, int, void *), void *arg, int edge)
2058 {
2059 	struct gpe_block *ptbl;
2060 
2061 	ptbl = acpi_find_gpe(sc, gpe);
2062 	if (ptbl == NULL || handler == NULL)
2063 		return -EINVAL;
2064 	if (ptbl->handler != NULL) {
2065 		dnprintf(10, "error: GPE %.2x already enabled\n", gpe);
2066 		return -EBUSY;
2067 	}
2068 	dnprintf(50, "Adding GPE handler %.2x (%s)\n", gpe, edge ? "edge" : "level");
2069 	ptbl->handler = handler;
2070 	ptbl->arg = arg;
2071 	ptbl->edge = edge;
2072 
2073 	return (0);
2074 }
2075 
2076 int
2077 acpi_gpe(struct acpi_softc *sc, int gpe, void *arg)
2078 {
2079 	struct aml_node *node = arg;
2080 	uint8_t mask, en;
2081 
2082 	dnprintf(10, "handling GPE %.2x\n", gpe);
2083 	aml_evalnode(sc, node, 0, NULL, NULL);
2084 
2085 	mask = (1L << (gpe & 7));
2086 	if (!sc->gpe_table[gpe].edge)
2087 		acpi_write_pmreg(sc, ACPIREG_GPE_STS, gpe>>3, mask);
2088 	en = acpi_read_pmreg(sc, ACPIREG_GPE_EN,  gpe>>3);
2089 	acpi_write_pmreg(sc, ACPIREG_GPE_EN,  gpe>>3, en | mask);
2090 	return (0);
2091 }
2092 
2093 /* Discover Devices that can wakeup the system
2094  * _PRW returns a package
2095  *  pkg[0] = integer (FADT gpe bit) or package (gpe block,gpe bit)
2096  *  pkg[1] = lowest sleep state
2097  *  pkg[2+] = power resource devices (optional)
2098  *
2099  * To enable wakeup devices:
2100  *    Evaluate _ON method in each power resource device
2101  *    Evaluate _PSW method
2102  */
2103 int
2104 acpi_foundprw(struct aml_node *node, void *arg)
2105 {
2106 	struct acpi_softc *sc = arg;
2107 	struct acpi_wakeq *wq;
2108 
2109 	wq = malloc(sizeof(struct acpi_wakeq), M_DEVBUF, M_NOWAIT | M_ZERO);
2110 	if (wq == NULL)
2111 		return 0;
2112 
2113 	wq->q_wakepkg = malloc(sizeof(struct aml_value), M_DEVBUF,
2114 	    M_NOWAIT | M_ZERO);
2115 	if (wq->q_wakepkg == NULL) {
2116 		free(wq, M_DEVBUF, sizeof(*wq));
2117 		return 0;
2118 	}
2119 	dnprintf(10, "Found _PRW (%s)\n", node->parent->name);
2120 	aml_evalnode(sc, node, 0, NULL, wq->q_wakepkg);
2121 	wq->q_node = node->parent;
2122 	wq->q_gpe = -1;
2123 
2124 	/* Get GPE of wakeup device, and lowest sleep level */
2125 	if (wq->q_wakepkg->type == AML_OBJTYPE_PACKAGE &&
2126 	    wq->q_wakepkg->length >= 2) {
2127 		if (wq->q_wakepkg->v_package[0]->type == AML_OBJTYPE_INTEGER)
2128 			wq->q_gpe = wq->q_wakepkg->v_package[0]->v_integer;
2129 		if (wq->q_wakepkg->v_package[1]->type == AML_OBJTYPE_INTEGER)
2130 			wq->q_state = wq->q_wakepkg->v_package[1]->v_integer;
2131 	}
2132 	SIMPLEQ_INSERT_TAIL(&sc->sc_wakedevs, wq, q_next);
2133 	return 0;
2134 }
2135 
2136 struct gpe_block *
2137 acpi_find_gpe(struct acpi_softc *sc, int gpe)
2138 {
2139 	if (gpe >= sc->sc_lastgpe)
2140 		return NULL;
2141 	return &sc->gpe_table[gpe];
2142 }
2143 
2144 void
2145 acpi_init_gpes(struct acpi_softc *sc)
2146 {
2147 	struct aml_node *gpe;
2148 	char name[12];
2149 	int  idx, ngpe;
2150 
2151 	sc->sc_lastgpe = sc->sc_fadt->gpe0_blk_len << 2;
2152 	if (sc->sc_fadt->gpe1_blk_len) {
2153 	}
2154 	dnprintf(50, "Last GPE: %.2x\n", sc->sc_lastgpe);
2155 
2156 	/* Allocate GPE table */
2157 	sc->gpe_table = mallocarray(sc->sc_lastgpe, sizeof(struct gpe_block),
2158 	    M_DEVBUF, M_WAITOK | M_ZERO);
2159 
2160 	ngpe = 0;
2161 
2162 	/* Clear GPE status */
2163 	acpi_disable_allgpes(sc);
2164 	for (idx = 0; idx < sc->sc_lastgpe; idx++) {
2165 		/* Search Level-sensitive GPES */
2166 		snprintf(name, sizeof(name), "\\_GPE._L%.2X", idx);
2167 		gpe = aml_searchname(&aml_root, name);
2168 		if (gpe != NULL)
2169 			acpi_set_gpehandler(sc, idx, acpi_gpe, gpe, 0);
2170 		if (gpe == NULL) {
2171 			/* Search Edge-sensitive GPES */
2172 			snprintf(name, sizeof(name), "\\_GPE._E%.2X", idx);
2173 			gpe = aml_searchname(&aml_root, name);
2174 			if (gpe != NULL)
2175 				acpi_set_gpehandler(sc, idx, acpi_gpe, gpe, 1);
2176 		}
2177 	}
2178 	aml_find_node(&aml_root, "_PRW", acpi_foundprw, sc);
2179 	sc->sc_maxgpe = ngpe;
2180 }
2181 
2182 void
2183 acpi_init_pm(struct acpi_softc *sc)
2184 {
2185 	sc->sc_tts = aml_searchname(&aml_root, "_TTS");
2186 	sc->sc_pts = aml_searchname(&aml_root, "_PTS");
2187 	sc->sc_wak = aml_searchname(&aml_root, "_WAK");
2188 	sc->sc_bfs = aml_searchname(&aml_root, "_BFS");
2189 	sc->sc_gts = aml_searchname(&aml_root, "_GTS");
2190 	sc->sc_sst = aml_searchname(&aml_root, "_SI_._SST");
2191 }
2192 
2193 #ifndef SMALL_KERNEL
2194 
2195 void
2196 acpi_init_states(struct acpi_softc *sc)
2197 {
2198 	struct aml_value res;
2199 	char name[8];
2200 	int i;
2201 
2202 	printf("\n%s: sleep states", DEVNAME(sc));
2203 	for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) {
2204 		snprintf(name, sizeof(name), "_S%d_", i);
2205 		sc->sc_sleeptype[i].slp_typa = -1;
2206 		sc->sc_sleeptype[i].slp_typb = -1;
2207 		if (aml_evalname(sc, &aml_root, name, 0, NULL, &res) == 0) {
2208 			if (res.type == AML_OBJTYPE_PACKAGE) {
2209 				sc->sc_sleeptype[i].slp_typa = aml_val2int(res.v_package[0]);
2210 				sc->sc_sleeptype[i].slp_typb = aml_val2int(res.v_package[1]);
2211 				printf(" S%d", i);
2212 			}
2213 			aml_freevalue(&res);
2214 		}
2215 	}
2216 }
2217 
2218 void
2219 acpi_sleep_pm(struct acpi_softc *sc, int state)
2220 {
2221 	uint16_t rega, regb, regra, regrb;
2222 	int retry = 0;
2223 
2224 	disable_intr();
2225 
2226 	/* Clear WAK_STS bit */
2227 	acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_WAK_STS);
2228 
2229 	/* Disable BM arbitration at deep sleep and beyond */
2230 	if (state >= ACPI_STATE_S3 &&
2231 	    sc->sc_fadt->pm2_cnt_blk && sc->sc_fadt->pm2_cnt_len)
2232 		acpi_write_pmreg(sc, ACPIREG_PM2_CNT, 0, ACPI_PM2_ARB_DIS);
2233 
2234 	/* Write SLP_TYPx values */
2235 	rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0);
2236 	regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, 0);
2237 	rega &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
2238 	regb &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
2239 	rega |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typa);
2240 	regb |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typb);
2241 	acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
2242 	acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
2243 
2244 	/* Loop on WAK_STS, setting the SLP_EN bits once in a while */
2245 	rega |= ACPI_PM1_SLP_EN;
2246 	regb |= ACPI_PM1_SLP_EN;
2247 	while (1) {
2248 		if (retry == 0) {
2249 			acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
2250 			acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
2251 		}
2252 		retry = (retry + 1) % 100000;
2253 
2254 		regra = acpi_read_pmreg(sc, ACPIREG_PM1A_STS, 0);
2255 		regrb = acpi_read_pmreg(sc, ACPIREG_PM1B_STS, 0);
2256 		if ((regra & ACPI_PM1_WAK_STS) ||
2257 		    (regrb & ACPI_PM1_WAK_STS))
2258 			break;
2259 	}
2260 }
2261 
2262 u_int32_t acpi_force_bm;
2263 
2264 void
2265 acpi_resume_pm(struct acpi_softc *sc, int fromstate)
2266 {
2267 	uint16_t rega, regb, en;
2268 
2269 	/* Write SLP_TYPx values */
2270 	rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0);
2271 	regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, 0);
2272 	rega &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
2273 	regb &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
2274 	rega |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[ACPI_STATE_S0].slp_typa);
2275 	regb |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[ACPI_STATE_S0].slp_typb);
2276 	acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
2277 	acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
2278 
2279 	/* Force SCI_EN on resume to fix horribly broken machines */
2280 	acpi_write_pmreg(sc, ACPIREG_PM1_CNT, 0,
2281 	    ACPI_PM1_SCI_EN | acpi_force_bm);
2282 
2283 	/* Clear fixed event status */
2284 	acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_ALL_STS);
2285 
2286 	/* acpica-reference.pdf page 148 says do not call _BFS */
2287 	/* 1st resume AML step: _BFS(fromstate) */
2288 	aml_node_setval(sc, sc->sc_bfs, fromstate);
2289 
2290 	/* Enable runtime GPEs */
2291 	acpi_disable_allgpes(sc);
2292 	acpi_enable_rungpes(sc);
2293 
2294 	acpi_indicator(sc, ACPI_SST_WAKING);
2295 
2296 	/* 2nd resume AML step: _WAK(fromstate) */
2297 	aml_node_setval(sc, sc->sc_wak, fromstate);
2298 
2299 	/* Clear WAK_STS bit */
2300 	acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_WAK_STS);
2301 
2302 	en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
2303 	if (!(sc->sc_fadt->flags & FADT_PWR_BUTTON))
2304 		en |= ACPI_PM1_PWRBTN_EN;
2305 	if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON))
2306 		en |= ACPI_PM1_SLPBTN_EN;
2307 	acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en);
2308 
2309 	/*
2310 	 * If PM2 exists, re-enable BM arbitration (reportedly some
2311 	 * BIOS forget to)
2312 	 */
2313 	if (sc->sc_fadt->pm2_cnt_blk && sc->sc_fadt->pm2_cnt_len) {
2314 		rega = acpi_read_pmreg(sc, ACPIREG_PM2_CNT, 0);
2315 		rega &= ~ACPI_PM2_ARB_DIS;
2316 		acpi_write_pmreg(sc, ACPIREG_PM2_CNT, 0, rega);
2317 	}
2318 }
2319 
2320 /* Set the indicator light to some state */
2321 void
2322 acpi_indicator(struct acpi_softc *sc, int led_state)
2323 {
2324 	static int save_led_state = -1;
2325 
2326 	if (save_led_state != led_state) {
2327 		aml_node_setval(sc, sc->sc_sst, led_state);
2328 		save_led_state = led_state;
2329 	}
2330 }
2331 
2332 
2333 int
2334 acpi_sleep_state(struct acpi_softc *sc, int state)
2335 {
2336 	extern int perflevel;
2337 	extern int lid_suspend;
2338 	int error = ENXIO;
2339 	size_t rndbuflen = 0;
2340 	char *rndbuf = NULL;
2341 	int s;
2342 
2343 	switch (state) {
2344 	case ACPI_STATE_S0:
2345 		return (0);
2346 	case ACPI_STATE_S1:
2347 		return (EOPNOTSUPP);
2348 	case ACPI_STATE_S5:	/* only sleep states handled here */
2349 		return (EOPNOTSUPP);
2350 	}
2351 
2352 	if (sc->sc_sleeptype[state].slp_typa == -1 ||
2353 	    sc->sc_sleeptype[state].slp_typb == -1) {
2354 		printf("%s: state S%d unavailable\n",
2355 		    sc->sc_dev.dv_xname, state);
2356 		return (EOPNOTSUPP);
2357 	}
2358 
2359 	/* 1st suspend AML step: _TTS(tostate) */
2360 	if (aml_node_setval(sc, sc->sc_tts, state) != 0)
2361 		goto fail_tts;
2362 	acpi_indicator(sc, ACPI_SST_WAKING);	/* blink */
2363 
2364 #if NWSDISPLAY > 0
2365 	/*
2366 	 * Temporarily release the lock to prevent the X server from
2367 	 * blocking on setting the display brightness.
2368 	 */
2369 	rw_exit_write(&sc->sc_lck);
2370 	wsdisplay_suspend();
2371 	rw_enter_write(&sc->sc_lck);
2372 #endif /* NWSDISPLAY > 0 */
2373 
2374 #ifdef HIBERNATE
2375 	if (state == ACPI_STATE_S4) {
2376 		uvmpd_hibernate();
2377 		hibernate_suspend_bufcache();
2378 		if (hibernate_alloc()) {
2379 			printf("%s: failed to allocate hibernate memory\n",
2380 			    sc->sc_dev.dv_xname);
2381 			goto fail_alloc;
2382 		}
2383 	}
2384 #endif /* HIBERNATE */
2385 
2386 	if (config_suspend_all(DVACT_QUIESCE))
2387 		goto fail_quiesce;
2388 
2389 	bufq_quiesce();
2390 
2391 #ifdef MULTIPROCESSOR
2392 	acpi_sleep_mp();
2393 #endif
2394 
2395 	resettodr();
2396 
2397 	s = splhigh();
2398 	disable_intr();	/* PSL_I for resume; PIC/APIC broken until repair */
2399 	cold = 2;	/* Force other code to delay() instead of tsleep() */
2400 
2401 	if (config_suspend_all(DVACT_SUSPEND) != 0)
2402 		goto fail_suspend;
2403 	acpi_sleep_clocks(sc, state);
2404 
2405 	suspend_randomness();
2406 
2407 	/* 2nd suspend AML step: _PTS(tostate) */
2408 	if (aml_node_setval(sc, sc->sc_pts, state) != 0)
2409 		goto fail_pts;
2410 
2411 	acpibtn_enable_psw();	/* enable _LID for wakeup */
2412 	acpi_indicator(sc, ACPI_SST_SLEEPING);
2413 
2414 	/* 3rd suspend AML step: _GTS(tostate) */
2415 	aml_node_setval(sc, sc->sc_gts, state);
2416 
2417 	/* Clear fixed event status */
2418 	acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_ALL_STS);
2419 
2420 	/* Enable wake GPEs */
2421 	acpi_disable_allgpes(sc);
2422 	acpi_enable_wakegpes(sc, state);
2423 
2424 	/* Sleep */
2425 	sc->sc_state = state;
2426 	error = acpi_sleep_cpu(sc, state);
2427 	sc->sc_state = ACPI_STATE_S0;
2428 	/* Resume */
2429 
2430 #ifdef HIBERNATE
2431 	if (state == ACPI_STATE_S4) {
2432 		uvm_pmr_dirty_everything();
2433 		hib_getentropy(&rndbuf, &rndbuflen);
2434 	}
2435 #endif /* HIBERNATE */
2436 
2437 	acpi_resume_clocks(sc);		/* AML may need clocks */
2438 	acpi_resume_pm(sc, state);
2439 	acpi_resume_cpu(sc);
2440 
2441 fail_pts:
2442 	config_suspend_all(DVACT_RESUME);
2443 
2444 fail_suspend:
2445 	cold = 0;
2446 	enable_intr();
2447 	splx(s);
2448 
2449 	acpibtn_disable_psw();		/* disable _LID for wakeup */
2450 	inittodr(time_second);
2451 
2452 	/* 3rd resume AML step: _TTS(runstate) */
2453 	aml_node_setval(sc, sc->sc_tts, sc->sc_state);
2454 
2455 	resume_randomness(rndbuf, rndbuflen);	/* force RNG upper level reseed */
2456 
2457 #ifdef MULTIPROCESSOR
2458 	acpi_resume_mp();
2459 #endif
2460 
2461 	bufq_restart();
2462 
2463 fail_quiesce:
2464 	config_suspend_all(DVACT_WAKEUP);
2465 
2466 #ifdef HIBERNATE
2467 fail_alloc:
2468 	if (state == ACPI_STATE_S4) {
2469 		hibernate_free();
2470 		hibernate_resume_bufcache();
2471 	}
2472 #endif /* HIBERNATE */
2473 
2474 #if NWSDISPLAY > 0
2475 	rw_exit_write(&sc->sc_lck);
2476 	wsdisplay_resume();
2477 	rw_enter_write(&sc->sc_lck);
2478 #endif /* NWSDISPLAY > 0 */
2479 
2480 	/* Restore hw.setperf */
2481 	if (cpu_setperf != NULL)
2482 		cpu_setperf(perflevel);
2483 
2484 	acpi_record_event(sc, APM_NORMAL_RESUME);
2485 	acpi_indicator(sc, ACPI_SST_WORKING);
2486 
2487 	/* If we woke up but all the lids are closed, go back to sleep */
2488 	if (acpibtn_numopenlids() == 0 && lid_suspend != 0)
2489 		acpi_addtask(sc, acpi_sleep_task, sc, state);
2490 
2491 fail_tts:
2492 	return (error);
2493 }
2494 
2495 /* XXX
2496  * We are going to do AML execution but are not in the acpi thread.
2497  * We do not know if the acpi thread is sleeping on acpiec in some
2498  * intermediate context.  Wish us luck.
2499  */
2500 void
2501 acpi_powerdown(void)
2502 {
2503 	int state = ACPI_STATE_S5, s;
2504 	struct acpi_softc *sc = acpi_softc;
2505 
2506 	if (acpi_enabled == 0)
2507 		return;
2508 
2509 	s = splhigh();
2510 	disable_intr();
2511 	cold = 1;
2512 
2513 	/* 1st powerdown AML step: _PTS(tostate) */
2514 	aml_node_setval(sc, sc->sc_pts, state);
2515 
2516 	acpi_disable_allgpes(sc);
2517 	acpi_enable_wakegpes(sc, state);
2518 
2519 	/* 2nd powerdown AML step: _GTS(tostate) */
2520 	aml_node_setval(sc, sc->sc_gts, state);
2521 
2522 	acpi_sleep_pm(sc, state);
2523 	panic("acpi S5 transition did not happen");
2524 	while (1)
2525 		;
2526 }
2527 
2528 int
2529 acpi_map_address(struct acpi_softc *sc, struct acpi_gas *gas, bus_addr_t base,
2530     bus_size_t size, bus_space_handle_t *pioh, bus_space_tag_t *piot)
2531 {
2532 	int iospace = GAS_SYSTEM_IOSPACE;
2533 
2534 	/* No GAS structure, default to I/O space */
2535 	if (gas != NULL) {
2536 		base += gas->address;
2537 		iospace = gas->address_space_id;
2538 	}
2539 	switch (iospace) {
2540 	case GAS_SYSTEM_MEMORY:
2541 		*piot = sc->sc_memt;
2542 		break;
2543 	case GAS_SYSTEM_IOSPACE:
2544 		*piot = sc->sc_iot;
2545 		break;
2546 	default:
2547 		return -1;
2548 	}
2549 	if (bus_space_map(*piot, base, size, 0, pioh))
2550 		return -1;
2551 
2552 	return 0;
2553 }
2554 
2555 #endif /* SMALL_KERNEL */
2556 
2557 void
2558 acpi_wakeup(void *arg)
2559 {
2560 	struct acpi_softc  *sc = (struct acpi_softc *)arg;
2561 
2562 	sc->sc_threadwaiting = 0;
2563 	wakeup(sc);
2564 }
2565 
2566 
2567 void
2568 acpi_thread(void *arg)
2569 {
2570 	struct acpi_thread *thread = arg;
2571 	struct acpi_softc  *sc = thread->sc;
2572 	extern int aml_busy;
2573 	int s;
2574 
2575 	/* AML/SMI cannot be trusted -- only run on the BSP */
2576 	sched_peg_curproc(&cpu_info_primary);
2577 
2578 	rw_enter_write(&sc->sc_lck);
2579 
2580 	/*
2581 	 * If we have an interrupt handler, we can get notification
2582 	 * when certain status bits changes in the ACPI registers,
2583 	 * so let us enable some events we can forward to userland
2584 	 */
2585 	if (sc->sc_interrupt) {
2586 		int16_t en;
2587 
2588 		dnprintf(1,"slpbtn:%c  pwrbtn:%c\n",
2589 		    sc->sc_fadt->flags & FADT_SLP_BUTTON ? 'n' : 'y',
2590 		    sc->sc_fadt->flags & FADT_PWR_BUTTON ? 'n' : 'y');
2591 		dnprintf(10, "Enabling acpi interrupts...\n");
2592 		sc->sc_threadwaiting = 1;
2593 
2594 		/* Enable Sleep/Power buttons if they exist */
2595 		s = spltty();
2596 		en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
2597 		if (!(sc->sc_fadt->flags & FADT_PWR_BUTTON))
2598 			en |= ACPI_PM1_PWRBTN_EN;
2599 		if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON))
2600 			en |= ACPI_PM1_SLPBTN_EN;
2601 		acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en);
2602 
2603 		/* Enable handled GPEs here */
2604 		acpi_enable_rungpes(sc);
2605 		splx(s);
2606 	}
2607 
2608 	while (thread->running) {
2609 		s = spltty();
2610 		while (sc->sc_threadwaiting) {
2611 			dnprintf(10, "acpi thread going to sleep...\n");
2612 			rw_exit_write(&sc->sc_lck);
2613 			tsleep(sc, PWAIT, "acpi0", 0);
2614 			rw_enter_write(&sc->sc_lck);
2615 		}
2616 		sc->sc_threadwaiting = 1;
2617 		splx(s);
2618 		if (aml_busy) {
2619 			panic("thread woke up to find aml was busy");
2620 			continue;
2621 		}
2622 
2623 		/* Run ACPI taskqueue */
2624 		while(acpi_dotask(acpi_softc))
2625 			;
2626 	}
2627 	free(thread, M_DEVBUF, sizeof(*thread));
2628 
2629 	kthread_exit(0);
2630 }
2631 
2632 void
2633 acpi_create_thread(void *arg)
2634 {
2635 	struct acpi_softc *sc = arg;
2636 
2637 	if (kthread_create(acpi_thread, sc->sc_thread, NULL, DEVNAME(sc))
2638 	    != 0)
2639 		printf("%s: unable to create isr thread, GPEs disabled\n",
2640 		    DEVNAME(sc));
2641 }
2642 
2643 int
2644 acpi_foundec(struct aml_node *node, void *arg)
2645 {
2646 	struct acpi_softc	*sc = (struct acpi_softc *)arg;
2647 	struct device		*self = (struct device *)arg;
2648 	const char		*dev;
2649 	struct aml_value	 res;
2650 	struct acpi_attach_args	aaa;
2651 
2652 	if (aml_evalnode(sc, node, 0, NULL, &res) != 0)
2653 		return 0;
2654 
2655 	switch (res.type) {
2656 	case AML_OBJTYPE_STRING:
2657 		dev = res.v_string;
2658 		break;
2659 	case AML_OBJTYPE_INTEGER:
2660 		dev = aml_eisaid(aml_val2int(&res));
2661 		break;
2662 	default:
2663 		dev = "unknown";
2664 		break;
2665 	}
2666 
2667 	if (strcmp(dev, ACPI_DEV_ECD))
2668 		return 0;
2669 
2670 	/* Check if we're already attached */
2671 	if (sc->sc_ec && sc->sc_ec->sc_devnode == node->parent)
2672 		return 0;
2673 
2674 	memset(&aaa, 0, sizeof(aaa));
2675 	aaa.aaa_iot = sc->sc_iot;
2676 	aaa.aaa_memt = sc->sc_memt;
2677 	aaa.aaa_node = node->parent;
2678 	aaa.aaa_dev = dev;
2679 	aaa.aaa_name = "acpiec";
2680 	config_found(self, &aaa, acpi_print);
2681 	aml_freevalue(&res);
2682 
2683 	return 0;
2684 }
2685 
2686 int
2687 acpi_foundsony(struct aml_node *node, void *arg)
2688 {
2689 	struct acpi_softc *sc = (struct acpi_softc *)arg;
2690 	struct device *self = (struct device *)arg;
2691 	struct acpi_attach_args aaa;
2692 
2693 	memset(&aaa, 0, sizeof(aaa));
2694 	aaa.aaa_iot = sc->sc_iot;
2695 	aaa.aaa_memt = sc->sc_memt;
2696 	aaa.aaa_node = node->parent;
2697 	aaa.aaa_name = "acpisony";
2698 
2699 	config_found(self, &aaa, acpi_print);
2700 
2701 	return 0;
2702 }
2703 
2704 int
2705 acpi_parsehid(struct aml_node *node, void *arg, char *outcdev, char *outdev,
2706     size_t devlen)
2707 {
2708 	struct acpi_softc	*sc = (struct acpi_softc *)arg;
2709 	struct aml_value	 res;
2710 	const char		*dev;
2711 
2712 	/* NB aml_eisaid returns a static buffer, this must come first */
2713 	if (aml_evalname(acpi_softc, node->parent, "_CID", 0, NULL, &res) == 0) {
2714 		switch (res.type) {
2715 		case AML_OBJTYPE_STRING:
2716 			dev = res.v_string;
2717 			break;
2718 		case AML_OBJTYPE_INTEGER:
2719 			dev = aml_eisaid(aml_val2int(&res));
2720 			break;
2721 		default:
2722 			dev = "unknown";
2723 			break;
2724 		}
2725 		strlcpy(outcdev, dev, devlen);
2726 		aml_freevalue(&res);
2727 
2728 		dnprintf(10, "compatible with device: %s\n", outcdev);
2729 	} else {
2730 		outcdev[0] = '\0';
2731 	}
2732 
2733 	dnprintf(10, "found hid device: %s ", node->parent->name);
2734 	if (aml_evalnode(sc, node, 0, NULL, &res) != 0)
2735 		return (1);
2736 
2737 	switch (res.type) {
2738 	case AML_OBJTYPE_STRING:
2739 		dev = res.v_string;
2740 		break;
2741 	case AML_OBJTYPE_INTEGER:
2742 		dev = aml_eisaid(aml_val2int(&res));
2743 		break;
2744 	default:
2745 		dev = "unknown";
2746 		break;
2747 	}
2748 	dnprintf(10, "	device: %s\n", dev);
2749 
2750 	strlcpy(outdev, dev, devlen);
2751 
2752 	aml_freevalue(&res);
2753 
2754 	return (0);
2755 }
2756 
2757 /* Devices for which we don't want to attach a driver */
2758 const char *acpi_skip_hids[] = {
2759 	"INT0800",	/* Intel 82802Firmware Hub Device */
2760 	"PNP0000",	/* 8259-compatible Programmable Interrupt Controller */
2761 	"PNP0100",	/* PC-class System Timer */
2762 	"PNP0103",	/* HPET System Timer */
2763 	"PNP0200",	/* PC-class DMA Controller */
2764 	"PNP0800",	/* Microsoft Sound System Compatible Device */
2765 	"PNP0A03",	/* PCI Bus */
2766 	"PNP0A08",	/* PCI Express Bus */
2767 	"PNP0B00",	/* AT Real-Time Clock */
2768 	"PNP0C01",	/* System Board */
2769 	"PNP0C02",	/* PNP Motherboard Resources */
2770 	"PNP0C04",	/* x87-compatible Floating Point Processing Unit */
2771 	"PNP0C09",	/* Embedded Controller Device */
2772 	"PNP0C0F",	/* PCI Interrupt Link Device */
2773 	NULL
2774 };
2775 
2776 void
2777 acpi_attach_deps(struct acpi_softc *sc, struct aml_node *node)
2778 {
2779 	struct aml_value res;
2780 	struct aml_node *dep;
2781 	int i;
2782 
2783 	if (aml_evalname(sc, node, "_DEP", 0, NULL, &res))
2784 		return;
2785 
2786 	if (res.type != AML_OBJTYPE_PACKAGE)
2787 		return;
2788 
2789 	for (i = 0; i < res.length; i++) {
2790 		if (res.v_package[i]->type != AML_OBJTYPE_STRING)
2791 			continue;
2792 		dep = aml_searchrel(node, res.v_package[i]->v_string);
2793 		if (dep == NULL || dep->attached)
2794 			continue;
2795 		dep = aml_searchname(dep, "_HID");
2796 		if (dep)
2797 			acpi_foundhid(dep, sc);
2798 	}
2799 
2800 	aml_freevalue(&res);
2801 }
2802 
2803 int
2804 acpi_foundhid(struct aml_node *node, void *arg)
2805 {
2806 	struct acpi_softc	*sc = (struct acpi_softc *)arg;
2807 	struct device		*self = (struct device *)arg;
2808 	char		 	 cdev[16];
2809 	char		 	 dev[16];
2810 	struct acpi_attach_args	 aaa;
2811 	int64_t			 sta;
2812 #ifndef SMALL_KERNEL
2813 	int			 i;
2814 #endif
2815 
2816 	if (acpi_parsehid(node, arg, cdev, dev, 16) != 0)
2817 		return (0);
2818 
2819 	if (aml_evalinteger(sc, node->parent, "_STA", 0, NULL, &sta))
2820 		sta = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000;
2821 
2822 	if ((sta & STA_PRESENT) == 0)
2823 		return (0);
2824 
2825 	acpi_attach_deps(sc, node->parent);
2826 
2827 	memset(&aaa, 0, sizeof(aaa));
2828 	aaa.aaa_iot = sc->sc_iot;
2829 	aaa.aaa_memt = sc->sc_memt;
2830 	aaa.aaa_node = node->parent;
2831 	aaa.aaa_dev = dev;
2832 
2833 	if (acpi_matchhids(&aaa, acpi_skip_hids, "none"))
2834 		return (0);
2835 
2836 #ifndef SMALL_KERNEL
2837 	if (!strcmp(cdev, ACPI_DEV_MOUSE)) {
2838 		for (i = 0; i < nitems(sbtn_pnp); i++) {
2839 			if (!strcmp(dev, sbtn_pnp[i])) {
2840 				mouse_has_softbtn = 1;
2841 				break;
2842 			}
2843 		}
2844 	}
2845 #endif
2846 
2847 	if (!node->parent->attached) {
2848 		config_found(self, &aaa, acpi_print);
2849 		node->parent->attached = 1;
2850 	}
2851 
2852 	return (0);
2853 }
2854 
2855 #ifndef SMALL_KERNEL
2856 int
2857 acpi_founddock(struct aml_node *node, void *arg)
2858 {
2859 	struct acpi_softc	*sc = (struct acpi_softc *)arg;
2860 	struct device		*self = (struct device *)arg;
2861 	struct acpi_attach_args	aaa;
2862 
2863 	dnprintf(10, "found dock entry: %s\n", node->parent->name);
2864 
2865 	memset(&aaa, 0, sizeof(aaa));
2866 	aaa.aaa_iot = sc->sc_iot;
2867 	aaa.aaa_memt = sc->sc_memt;
2868 	aaa.aaa_node = node->parent;
2869 	aaa.aaa_name = "acpidock";
2870 
2871 	config_found(self, &aaa, acpi_print);
2872 
2873 	return 0;
2874 }
2875 
2876 int
2877 acpi_foundvideo(struct aml_node *node, void *arg)
2878 {
2879 	struct acpi_softc *sc = (struct acpi_softc *)arg;
2880 	struct device *self = (struct device *)arg;
2881 	struct acpi_attach_args	aaa;
2882 
2883 	memset(&aaa, 0, sizeof(aaa));
2884 	aaa.aaa_iot = sc->sc_iot;
2885 	aaa.aaa_memt = sc->sc_memt;
2886 	aaa.aaa_node = node->parent;
2887 	aaa.aaa_name = "acpivideo";
2888 
2889 	config_found(self, &aaa, acpi_print);
2890 
2891 	return (0);
2892 }
2893 
2894 int
2895 acpiopen(dev_t dev, int flag, int mode, struct proc *p)
2896 {
2897 	int error = 0;
2898 	struct acpi_softc *sc;
2899 	int s;
2900 
2901 	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
2902 	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
2903 		return (ENXIO);
2904 
2905 	s = spltty();
2906 	switch (APMDEV(dev)) {
2907 	case APMDEV_CTL:
2908 		if (!(flag & FWRITE)) {
2909 			error = EINVAL;
2910 			break;
2911 		}
2912 		if (sc->sc_flags & SCFLAG_OWRITE) {
2913 			error = EBUSY;
2914 			break;
2915 		}
2916 		sc->sc_flags |= SCFLAG_OWRITE;
2917 		break;
2918 	case APMDEV_NORMAL:
2919 		if (!(flag & FREAD) || (flag & FWRITE)) {
2920 			error = EINVAL;
2921 			break;
2922 		}
2923 		sc->sc_flags |= SCFLAG_OREAD;
2924 		break;
2925 	default:
2926 		error = ENXIO;
2927 		break;
2928 	}
2929 	splx(s);
2930 	return (error);
2931 }
2932 
2933 int
2934 acpiclose(dev_t dev, int flag, int mode, struct proc *p)
2935 {
2936 	int error = 0;
2937 	struct acpi_softc *sc;
2938 	int s;
2939 
2940 	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
2941 	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
2942 		return (ENXIO);
2943 
2944 	s = spltty();
2945 	switch (APMDEV(dev)) {
2946 	case APMDEV_CTL:
2947 		sc->sc_flags &= ~SCFLAG_OWRITE;
2948 		break;
2949 	case APMDEV_NORMAL:
2950 		sc->sc_flags &= ~SCFLAG_OREAD;
2951 		break;
2952 	default:
2953 		error = ENXIO;
2954 		break;
2955 	}
2956 	splx(s);
2957 	return (error);
2958 }
2959 
2960 int
2961 acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
2962 {
2963 	int error = 0;
2964 	struct acpi_softc *sc;
2965 	struct acpi_ac *ac;
2966 	struct acpi_bat *bat;
2967 	struct apm_power_info *pi = (struct apm_power_info *)data;
2968 	int bats;
2969 	unsigned int remaining, rem, minutes, rate;
2970 	int s;
2971 
2972 	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
2973 	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
2974 		return (ENXIO);
2975 
2976 	s = spltty();
2977 	/* fake APM */
2978 	switch (cmd) {
2979 	case APM_IOC_SUSPEND:
2980 	case APM_IOC_STANDBY:
2981 		if ((flag & FWRITE) == 0) {
2982 			error = EBADF;
2983 			break;
2984 		}
2985 		acpi_addtask(sc, acpi_sleep_task, sc, ACPI_STATE_S3);
2986 		acpi_wakeup(sc);
2987 		break;
2988 #ifdef HIBERNATE
2989 	case APM_IOC_HIBERNATE:
2990 		if ((error = suser(p, 0)) != 0)
2991 			break;
2992 		if ((flag & FWRITE) == 0) {
2993 			error = EBADF;
2994 			break;
2995 		}
2996 		if (get_hibernate_io_function(swdevt[0].sw_dev) == NULL) {
2997 			error = EOPNOTSUPP;
2998 			break;
2999 		}
3000 		acpi_addtask(sc, acpi_sleep_task, sc, ACPI_STATE_S4);
3001 		acpi_wakeup(sc);
3002 		break;
3003 #endif
3004 	case APM_IOC_GETPOWER:
3005 		/* A/C */
3006 		pi->ac_state = APM_AC_UNKNOWN;
3007 		SLIST_FOREACH(ac, &sc->sc_ac, aac_link) {
3008 			if (ac->aac_softc->sc_ac_stat == PSR_ONLINE)
3009 				pi->ac_state = APM_AC_ON;
3010 			else if (ac->aac_softc->sc_ac_stat == PSR_OFFLINE)
3011 				if (pi->ac_state == APM_AC_UNKNOWN)
3012 					pi->ac_state = APM_AC_OFF;
3013 		}
3014 
3015 		/* battery */
3016 		pi->battery_state = APM_BATT_UNKNOWN;
3017 		pi->battery_life = 0;
3018 		pi->minutes_left = 0;
3019 		bats = 0;
3020 		remaining = rem = 0;
3021 		minutes = 0;
3022 		rate = 0;
3023 		SLIST_FOREACH(bat, &sc->sc_bat, aba_link) {
3024 			if (bat->aba_softc->sc_bat_present == 0)
3025 				continue;
3026 
3027 			if (bat->aba_softc->sc_bif.bif_last_capacity == 0)
3028 				continue;
3029 
3030 			bats++;
3031 			rem = (bat->aba_softc->sc_bst.bst_capacity * 100) /
3032 			    bat->aba_softc->sc_bif.bif_last_capacity;
3033 			if (rem > 100)
3034 				rem = 100;
3035 			remaining += rem;
3036 
3037 			if (bat->aba_softc->sc_bst.bst_rate == BST_UNKNOWN)
3038 				continue;
3039 			else if (bat->aba_softc->sc_bst.bst_rate > 1)
3040 				rate = bat->aba_softc->sc_bst.bst_rate;
3041 
3042 			minutes += bat->aba_softc->sc_bst.bst_capacity;
3043 		}
3044 
3045 		if (bats == 0) {
3046 			pi->battery_state = APM_BATTERY_ABSENT;
3047 			pi->battery_life = 0;
3048 			pi->minutes_left = (unsigned int)-1;
3049 			break;
3050 		}
3051 
3052 		if (pi->ac_state == APM_AC_ON || rate == 0)
3053 			pi->minutes_left = (unsigned int)-1;
3054 		else
3055 			pi->minutes_left = 60 * minutes / rate;
3056 
3057 		/* running on battery */
3058 		pi->battery_life = remaining / bats;
3059 		if (pi->battery_life > 50)
3060 			pi->battery_state = APM_BATT_HIGH;
3061 		else if (pi->battery_life > 25)
3062 			pi->battery_state = APM_BATT_LOW;
3063 		else
3064 			pi->battery_state = APM_BATT_CRITICAL;
3065 
3066 		break;
3067 
3068 	default:
3069 		error = ENOTTY;
3070 	}
3071 
3072 	splx(s);
3073 	return (error);
3074 }
3075 
3076 void	acpi_filtdetach(struct knote *);
3077 int	acpi_filtread(struct knote *, long);
3078 
3079 struct filterops acpiread_filtops = {
3080 	1, NULL, acpi_filtdetach, acpi_filtread
3081 };
3082 
3083 int acpi_evindex;
3084 
3085 int
3086 acpi_record_event(struct acpi_softc *sc, u_int type)
3087 {
3088 	if ((sc->sc_flags & SCFLAG_OPEN) == 0)
3089 		return (1);
3090 
3091 	acpi_evindex++;
3092 	KNOTE(sc->sc_note, APM_EVENT_COMPOSE(type, acpi_evindex));
3093 	return (0);
3094 }
3095 
3096 void
3097 acpi_filtdetach(struct knote *kn)
3098 {
3099 	struct acpi_softc *sc = kn->kn_hook;
3100 	int s;
3101 
3102 	s = spltty();
3103 	SLIST_REMOVE(sc->sc_note, kn, knote, kn_selnext);
3104 	splx(s);
3105 }
3106 
3107 int
3108 acpi_filtread(struct knote *kn, long hint)
3109 {
3110 	/* XXX weird kqueue_scan() semantics */
3111 	if (hint && !kn->kn_data)
3112 		kn->kn_data = hint;
3113 	return (1);
3114 }
3115 
3116 int
3117 acpikqfilter(dev_t dev, struct knote *kn)
3118 {
3119 	struct acpi_softc *sc;
3120 	int s;
3121 
3122 	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
3123 	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
3124 		return (ENXIO);
3125 
3126 	switch (kn->kn_filter) {
3127 	case EVFILT_READ:
3128 		kn->kn_fop = &acpiread_filtops;
3129 		break;
3130 	default:
3131 		return (EINVAL);
3132 	}
3133 
3134 	kn->kn_hook = sc;
3135 
3136 	s = spltty();
3137 	SLIST_INSERT_HEAD(sc->sc_note, kn, kn_selnext);
3138 	splx(s);
3139 
3140 	return (0);
3141 }
3142 
3143 #else /* SMALL_KERNEL */
3144 
3145 int
3146 acpiopen(dev_t dev, int flag, int mode, struct proc *p)
3147 {
3148 	return (ENXIO);
3149 }
3150 
3151 int
3152 acpiclose(dev_t dev, int flag, int mode, struct proc *p)
3153 {
3154 	return (ENXIO);
3155 }
3156 
3157 int
3158 acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
3159 {
3160 	return (ENXIO);
3161 }
3162 
3163 int
3164 acpikqfilter(dev_t dev, struct knote *kn)
3165 {
3166 	return (ENXIO);
3167 }
3168 #endif /* SMALL_KERNEL */
3169