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