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