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