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