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