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