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