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