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