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