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