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