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