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