acpi.c revision 108345
1/*-
2 * Copyright (c) 2000 Takanori Watanabe <takawata@jp.freebsd.org>
3 * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
4 * Copyright (c) 2000, 2001 Michael Smith
5 * Copyright (c) 2000 BSDi
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 *	$FreeBSD: head/sys/dev/acpica/acpi.c 108345 2002-12-28 14:58:50Z rwatson $
30 */
31
32#include "opt_acpi.h"
33#include <sys/param.h>
34#include <sys/kernel.h>
35#include <sys/proc.h>
36#include <sys/malloc.h>
37#include <sys/bus.h>
38#include <sys/conf.h>
39#include <sys/ioccom.h>
40#include <sys/reboot.h>
41#include <sys/sysctl.h>
42#include <sys/ctype.h>
43#include <sys/linker.h>
44#include <sys/power.h>
45
46#include <machine/clock.h>
47#include <machine/resource.h>
48
49#include <isa/isavar.h>
50
51#include "acpi.h"
52
53#include <dev/acpica/acpica_support.h>
54
55#include <dev/acpica/acpivar.h>
56#include <dev/acpica/acpiio.h>
57
58MALLOC_DEFINE(M_ACPIDEV, "acpidev", "ACPI devices");
59
60/*
61 * Hooks for the ACPI CA debugging infrastructure
62 */
63#define _COMPONENT	ACPI_BUS
64ACPI_MODULE_NAME("ACPI")
65
66/*
67 * Character device
68 */
69
70static d_open_t		acpiopen;
71static d_close_t	acpiclose;
72static d_ioctl_t	acpiioctl;
73
74#define CDEV_MAJOR 152
75static struct cdevsw acpi_cdevsw = {
76    acpiopen,
77    acpiclose,
78    noread,
79    nowrite,
80    acpiioctl,
81    nopoll,
82    nommap,
83    nostrategy,
84    "acpi",
85    CDEV_MAJOR,
86    nodump,
87    nopsize,
88    0
89};
90
91static const char* sleep_state_names[] = {
92    "S0", "S1", "S2", "S3", "S4", "S5", "NONE"};
93
94/* this has to be static, as the softc is gone when we need it */
95static int acpi_off_state = ACPI_STATE_S5;
96
97#if __FreeBSD_version >= 500000
98struct mtx	acpi_mutex;
99#endif
100
101static int	acpi_modevent(struct module *mod, int event, void *junk);
102static void	acpi_identify(driver_t *driver, device_t parent);
103static int	acpi_probe(device_t dev);
104static int	acpi_attach(device_t dev);
105static device_t	acpi_add_child(device_t bus, int order, const char *name, int unit);
106static int	acpi_print_child(device_t bus, device_t child);
107static int	acpi_read_ivar(device_t dev, device_t child, int index, uintptr_t *result);
108static int	acpi_write_ivar(device_t dev, device_t child, int index, uintptr_t value);
109static int	acpi_set_resource(device_t dev, device_t child, int type, int rid, u_long start,
110				  u_long count);
111static int	acpi_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp,
112				  u_long *countp);
113static struct resource *acpi_alloc_resource(device_t bus, device_t child, int type, int *rid,
114					    u_long start, u_long end, u_long count, u_int flags);
115static int	acpi_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r);
116static u_int32_t acpi_isa_get_logicalid(device_t dev);
117static int	acpi_isa_pnp_probe(device_t bus, device_t child, struct isa_pnp_id *ids);
118
119static void	acpi_probe_children(device_t bus);
120static ACPI_STATUS acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status);
121
122static void	acpi_shutdown_pre_sync(void *arg, int howto);
123static void	acpi_shutdown_final(void *arg, int howto);
124
125static void	acpi_enable_fixed_events(struct acpi_softc *sc);
126
127static void	acpi_system_eventhandler_sleep(void *arg, int state);
128static void	acpi_system_eventhandler_wakeup(void *arg, int state);
129static int	acpi_sleep_state_sysctl(SYSCTL_HANDLER_ARGS);
130
131static int	acpi_pm_func(u_long cmd, void *arg, ...);
132
133static device_method_t acpi_methods[] = {
134    /* Device interface */
135    DEVMETHOD(device_identify,		acpi_identify),
136    DEVMETHOD(device_probe,		acpi_probe),
137    DEVMETHOD(device_attach,		acpi_attach),
138    DEVMETHOD(device_shutdown,		bus_generic_shutdown),
139    DEVMETHOD(device_suspend,		bus_generic_suspend),
140    DEVMETHOD(device_resume,		bus_generic_resume),
141
142    /* Bus interface */
143    DEVMETHOD(bus_add_child,		acpi_add_child),
144    DEVMETHOD(bus_print_child,		acpi_print_child),
145    DEVMETHOD(bus_read_ivar,		acpi_read_ivar),
146    DEVMETHOD(bus_write_ivar,		acpi_write_ivar),
147    DEVMETHOD(bus_set_resource,		acpi_set_resource),
148    DEVMETHOD(bus_get_resource,		acpi_get_resource),
149    DEVMETHOD(bus_alloc_resource,	acpi_alloc_resource),
150    DEVMETHOD(bus_release_resource,	acpi_release_resource),
151    DEVMETHOD(bus_driver_added,		bus_generic_driver_added),
152    DEVMETHOD(bus_activate_resource,	bus_generic_activate_resource),
153    DEVMETHOD(bus_deactivate_resource,	bus_generic_deactivate_resource),
154    DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
155    DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
156
157    /* ISA emulation */
158    DEVMETHOD(isa_pnp_probe,		acpi_isa_pnp_probe),
159
160    {0, 0}
161};
162
163static driver_t acpi_driver = {
164    "acpi",
165    acpi_methods,
166    sizeof(struct acpi_softc),
167};
168
169static devclass_t acpi_devclass;
170DRIVER_MODULE(acpi, nexus, acpi_driver, acpi_devclass, acpi_modevent, 0);
171MODULE_VERSION(acpi, 100);
172
173SYSCTL_INT(_debug, OID_AUTO, acpi_debug_layer, CTLFLAG_RW, &AcpiDbgLayer, 0, "");
174SYSCTL_INT(_debug, OID_AUTO, acpi_debug_level, CTLFLAG_RW, &AcpiDbgLevel, 0, "");
175static int acpi_ca_version = ACPI_CA_VERSION;
176SYSCTL_INT(_debug, OID_AUTO, acpi_ca_version, CTLFLAG_RD, &acpi_ca_version, 0, "");
177
178/*
179 * ACPI can only be loaded as a module by the loader; activating it after
180 * system bootstrap time is not useful, and can be fatal to the system.
181 * It also cannot be unloaded, since the entire system bus heirarchy hangs off it.
182 */
183static int
184acpi_modevent(struct module *mod, int event, void *junk)
185{
186    switch(event) {
187    case MOD_LOAD:
188	if (!cold) {
189	    printf("The ACPI driver cannot be loaded after boot.\n");
190	    return(EPERM);
191	}
192	break;
193    case MOD_UNLOAD:
194	if (!cold && power_pm_get_type() == POWER_PM_TYPE_ACPI)
195	    return(EBUSY);
196	break;
197    default:
198	break;
199    }
200    return(0);
201}
202
203/*
204 * Detect ACPI, perform early initialisation
205 */
206static void
207acpi_identify(driver_t *driver, device_t parent)
208{
209    device_t			child;
210    int				error;
211#ifdef ACPI_DEBUGGER
212    char			*debugpoint;
213#endif
214
215    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
216
217    if (!cold)
218	return_VOID;
219
220    /*
221     * Check that we haven't been disabled with a hint.
222     */
223    if (!resource_int_value("acpi", 0, "disabled", &error) &&
224	(error != 0))
225	return_VOID;
226
227    /*
228     * Make sure we're not being doubly invoked.
229     */
230    if (device_find_child(parent, "acpi", 0) != NULL)
231	return_VOID;
232
233#if __FreeBSD_version >= 500000
234    /* initialise the ACPI mutex */
235    mtx_init(&acpi_mutex, "ACPI global lock", NULL, MTX_DEF);
236#endif
237
238    /*
239     * Start up the ACPI CA subsystem.
240     */
241#ifdef ACPI_DEBUGGER
242    debugpoint = getenv("debug.acpi.debugger");
243    if (debugpoint) {
244	if (!strcmp(debugpoint, "init"))
245	    acpi_EnterDebugger();
246        freeenv(debugpoint);
247    }
248#endif
249    if (ACPI_FAILURE(error = AcpiInitializeSubsystem())) {
250	printf("ACPI: initialisation failed: %s\n", AcpiFormatException(error));
251	return_VOID;
252    }
253#ifdef ACPI_DEBUGGER
254    debugpoint = getenv("debug.acpi.debugger");
255    if (debugpoint) {
256	if (!strcmp(debugpoint, "tables"))
257	    acpi_EnterDebugger();
258        freeenv(debugpoint);
259    }
260#endif
261
262    if (ACPI_FAILURE(error = AcpiLoadTables())) {
263	printf("ACPI: table load failed: %s\n", AcpiFormatException(error));
264	return_VOID;
265    }
266
267    /*
268     * Attach the actual ACPI device.
269     */
270    if ((child = BUS_ADD_CHILD(parent, 0, "acpi", 0)) == NULL) {
271	    device_printf(parent, "ACPI: could not attach\n");
272	    return_VOID;
273    }
274}
275
276/*
277 * Fetch some descriptive data from ACPI to put in our attach message
278 */
279static int
280acpi_probe(device_t dev)
281{
282    ACPI_TABLE_HEADER	th;
283    char		buf[20];
284    ACPI_STATUS		status;
285    int			error;
286    ACPI_LOCK_DECL;
287
288    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
289
290    if (power_pm_get_type() != POWER_PM_TYPE_NONE &&
291        power_pm_get_type() != POWER_PM_TYPE_ACPI) {
292	device_printf(dev, "Other PM system enabled.\n");
293	return_VALUE(ENXIO);
294    }
295
296    ACPI_LOCK;
297
298    if (ACPI_FAILURE(status = AcpiGetTableHeader(ACPI_TABLE_XSDT, 1, &th))) {
299	device_printf(dev, "couldn't get XSDT header: %s\n", AcpiFormatException(status));
300	error = ENXIO;
301    } else {
302	sprintf(buf, "%.6s %.8s", th.OemId, th.OemTableId);
303	device_set_desc_copy(dev, buf);
304	error = 0;
305    }
306    ACPI_UNLOCK;
307    return_VALUE(error);
308}
309
310static int
311acpi_attach(device_t dev)
312{
313    struct acpi_softc	*sc;
314    ACPI_STATUS		status;
315    int			error;
316    UINT32		flags;
317    char		*env;
318#ifdef ACPI_DEBUGGER
319    char		*debugpoint;
320#endif
321    ACPI_LOCK_DECL;
322
323    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
324    ACPI_LOCK;
325    sc = device_get_softc(dev);
326    bzero(sc, sizeof(*sc));
327    sc->acpi_dev = dev;
328
329#ifdef ACPI_DEBUGGER
330    debugpoint = getenv("debug.acpi.debugger");
331    if (debugpoint) {
332	if (!strcmp(debugpoint, "spaces"))
333	    acpi_EnterDebugger();
334        freeenv(debugpoint);
335    }
336#endif
337
338    /*
339     * Install the default address space handlers.
340     */
341    error = ENXIO;
342    if (ACPI_FAILURE(status = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
343						ACPI_ADR_SPACE_SYSTEM_MEMORY,
344						ACPI_DEFAULT_HANDLER,
345						NULL, NULL))) {
346	device_printf(dev, "could not initialise SystemMemory handler: %s\n", AcpiFormatException(status));
347	goto out;
348    }
349    if (ACPI_FAILURE(status = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
350						ACPI_ADR_SPACE_SYSTEM_IO,
351						ACPI_DEFAULT_HANDLER,
352						NULL, NULL))) {
353	device_printf(dev, "could not initialise SystemIO handler: %s\n", AcpiFormatException(status));
354	goto out;
355    }
356    if (ACPI_FAILURE(status = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
357						ACPI_ADR_SPACE_PCI_CONFIG,
358						ACPI_DEFAULT_HANDLER,
359						NULL, NULL))) {
360	device_printf(dev, "could not initialise PciConfig handler: %s\n", AcpiFormatException(status));
361	goto out;
362    }
363
364    /*
365     * Bring ACPI fully online.
366     *
367     * Note that some systems (specifically, those with namespace evaluation issues
368     * that require the avoidance of parts of the namespace) must avoid running _INI
369     * and _STA on everything, as well as dodging the final object init pass.
370     *
371     * For these devices, we set ACPI_NO_DEVICE_INIT and ACPI_NO_OBJECT_INIT).
372     *
373     * XXX We should arrange for the object init pass after we have attached all our
374     *     child devices, but on many systems it works here.
375     */
376#ifdef ACPI_DEBUGGER
377    debugpoint = getenv("debug.acpi.debugger");
378    if (debugpoint) {
379	if (!strcmp(debugpoint, "enable"))
380	    acpi_EnterDebugger();
381        freeenv(debugpoint);
382    }
383#endif
384    flags = 0;
385    if (testenv("debug.acpi.avoid"))
386	flags = ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT;
387    if (ACPI_FAILURE(status = AcpiEnableSubsystem(flags))) {
388	device_printf(dev, "could not enable ACPI: %s\n", AcpiFormatException(status));
389	goto out;
390    }
391
392    if (ACPI_FAILURE(status = AcpiInitializeObjects(flags))) {
393	device_printf(dev, "could not initialize ACPI objects: %s\n", AcpiFormatException(status));
394	goto out;
395    }
396
397    /*
398     * Setup our sysctl tree.
399     *
400     * XXX: This doesn't check to make sure that none of these fail.
401     */
402    sysctl_ctx_init(&sc->acpi_sysctl_ctx);
403    sc->acpi_sysctl_tree = SYSCTL_ADD_NODE(&sc->acpi_sysctl_ctx,
404			       SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO,
405			       device_get_name(dev), CTLFLAG_RD, 0, "");
406    SYSCTL_ADD_PROC(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
407	OID_AUTO, "power_button_state", CTLTYPE_STRING | CTLFLAG_RW,
408	&sc->acpi_power_button_sx, 0, acpi_sleep_state_sysctl, "A", "");
409    SYSCTL_ADD_PROC(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
410	OID_AUTO, "sleep_button_state", CTLTYPE_STRING | CTLFLAG_RW,
411	&sc->acpi_sleep_button_sx, 0, acpi_sleep_state_sysctl, "A", "");
412    SYSCTL_ADD_PROC(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
413	OID_AUTO, "lid_switch_state", CTLTYPE_STRING | CTLFLAG_RW,
414	&sc->acpi_lid_switch_sx, 0, acpi_sleep_state_sysctl, "A", "");
415    SYSCTL_ADD_PROC(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
416	OID_AUTO, "standby_state", CTLTYPE_STRING | CTLFLAG_RW,
417	&sc->acpi_standby_sx, 0, acpi_sleep_state_sysctl, "A", "");
418    SYSCTL_ADD_PROC(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
419	OID_AUTO, "suspend_state", CTLTYPE_STRING | CTLFLAG_RW,
420	&sc->acpi_suspend_sx, 0, acpi_sleep_state_sysctl, "A", "");
421    SYSCTL_ADD_INT(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
422	OID_AUTO, "sleep_delay", CTLFLAG_RD | CTLFLAG_RW,
423	&sc->acpi_sleep_delay, 0, "sleep delay");
424    SYSCTL_ADD_INT(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
425	OID_AUTO, "s4bios", CTLFLAG_RD | CTLFLAG_RW,
426	&sc->acpi_s4bios, 0, "S4BIOS mode");
427    SYSCTL_ADD_INT(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
428	OID_AUTO, "verbose", CTLFLAG_RD | CTLFLAG_RW,
429	&sc->acpi_verbose, 0, "verbose mode");
430    SYSCTL_ADD_INT(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree),
431		   OID_AUTO, "disable_on_poweroff", CTLFLAG_RD | CTLFLAG_RW,
432		   &sc->acpi_disable_on_poweroff, 0, "ACPI subsystem disable on poweroff");
433    sc->acpi_disable_on_poweroff = 1;
434    sc->acpi_sleep_delay = 0;
435    sc->acpi_s4bios = 1;
436    if (bootverbose)
437	sc->acpi_verbose = 1;
438    if ((env = getenv("hw.acpi.verbose")) && strcmp(env, "0")) {
439	sc->acpi_verbose = 1;
440	freeenv(env);
441    }
442
443    /*
444     * Dispatch the default sleep state to devices.
445     * TBD: should be configured from userland policy manager.
446     */
447    sc->acpi_power_button_sx = ACPI_POWER_BUTTON_DEFAULT_SX;
448    sc->acpi_sleep_button_sx = ACPI_SLEEP_BUTTON_DEFAULT_SX;
449    sc->acpi_lid_switch_sx = ACPI_LID_SWITCH_DEFAULT_SX;
450    sc->acpi_standby_sx = ACPI_STATE_S1;
451    sc->acpi_suspend_sx = ACPI_STATE_S3;
452
453    acpi_enable_fixed_events(sc);
454
455    /*
456     * Scan the namespace and attach/initialise children.
457     */
458#ifdef ACPI_DEBUGGER
459    debugpoint = getenv("debug.acpi.debugger");
460    if (debugpoint) {
461	if (!strcmp(debugpoint, "probe"))
462	    acpi_EnterDebugger();
463	freeenv(debugpoint);
464    }
465#endif
466
467    /*
468     * Register our shutdown handlers
469     */
470    EVENTHANDLER_REGISTER(shutdown_pre_sync, acpi_shutdown_pre_sync, sc, SHUTDOWN_PRI_LAST);
471    EVENTHANDLER_REGISTER(shutdown_final, acpi_shutdown_final, sc, SHUTDOWN_PRI_LAST);
472
473    /*
474     * Register our acpi event handlers.
475     * XXX should be configurable eg. via userland policy manager.
476     */
477    EVENTHANDLER_REGISTER(acpi_sleep_event, acpi_system_eventhandler_sleep, sc, ACPI_EVENT_PRI_LAST);
478    EVENTHANDLER_REGISTER(acpi_wakeup_event, acpi_system_eventhandler_wakeup, sc, ACPI_EVENT_PRI_LAST);
479
480    /*
481     * Flag our initial states.
482     */
483    sc->acpi_enabled = 1;
484    sc->acpi_sstate = ACPI_STATE_S0;
485    sc->acpi_sleep_disabled = 0;
486
487    /*
488     * Create the control device
489     */
490    sc->acpi_dev_t = make_dev(&acpi_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
491	"acpi");
492    sc->acpi_dev_t->si_drv1 = sc;
493
494#ifdef ACPI_DEBUGGER
495    debugpoint = getenv("debug.acpi.debugger");
496    if (debugpoint) {
497	if (!strcmp(debugpoint, "running"))
498	    acpi_EnterDebugger();
499	freeenv(debugpoint);
500    }
501#endif
502
503#ifdef ACPI_USE_THREADS
504    if ((error = acpi_task_thread_init())) {
505	goto out;
506    }
507#endif
508
509    if ((error = acpi_machdep_init(dev))) {
510	goto out;
511    }
512
513    /* Register ACPI again to pass the correct argument of pm_func. */
514    power_pm_register(POWER_PM_TYPE_ACPI, acpi_pm_func, sc);
515
516    if (!acpi_disabled("bus"))
517	acpi_probe_children(dev);
518
519    error = 0;
520
521 out:
522    ACPI_UNLOCK;
523    return_VALUE(error);
524}
525
526/*
527 * Handle a new device being added
528 */
529static device_t
530acpi_add_child(device_t bus, int order, const char *name, int unit)
531{
532    struct acpi_device	*ad;
533    device_t		child;
534
535    if ((ad = malloc(sizeof(*ad), M_ACPIDEV, M_NOWAIT)) == NULL)
536	return(NULL);
537    bzero(ad, sizeof(*ad));
538
539    resource_list_init(&ad->ad_rl);
540
541    child = device_add_child_ordered(bus, order, name, unit);
542    if (child != NULL)
543	device_set_ivars(child, ad);
544    return(child);
545}
546
547static int
548acpi_print_child(device_t bus, device_t child)
549{
550    struct acpi_device		*adev = device_get_ivars(child);
551    struct resource_list	*rl = &adev->ad_rl;
552    int retval = 0;
553
554    retval += bus_print_child_header(bus, child);
555    retval += resource_list_print_type(rl, "port",  SYS_RES_IOPORT, "%#lx");
556    retval += resource_list_print_type(rl, "iomem", SYS_RES_MEMORY, "%#lx");
557    retval += resource_list_print_type(rl, "irq",   SYS_RES_IRQ,    "%ld");
558    retval += resource_list_print_type(rl, "drq",   SYS_RES_DRQ,    "%ld");
559    retval += bus_print_child_footer(bus, child);
560
561    return(retval);
562}
563
564
565/*
566 * Handle per-device ivars
567 */
568static int
569acpi_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
570{
571    struct acpi_device	*ad;
572
573    if ((ad = device_get_ivars(child)) == NULL) {
574	printf("device has no ivars\n");
575	return(ENOENT);
576    }
577
578    switch(index) {
579	/* ACPI ivars */
580    case ACPI_IVAR_HANDLE:
581	*(ACPI_HANDLE *)result = ad->ad_handle;
582	break;
583    case ACPI_IVAR_MAGIC:
584	*(int *)result = ad->ad_magic;
585	break;
586    case ACPI_IVAR_PRIVATE:
587	*(void **)result = ad->ad_private;
588	break;
589
590	/* ISA compatibility */
591    case ISA_IVAR_VENDORID:
592    case ISA_IVAR_SERIAL:
593    case ISA_IVAR_COMPATID:
594	*(int *)result = -1;
595	break;
596
597    case ISA_IVAR_LOGICALID:
598	*(int *)result = acpi_isa_get_logicalid(child);
599	break;
600
601    default:
602	return(ENOENT);
603    }
604    return(0);
605}
606
607static int
608acpi_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
609{
610    struct acpi_device	*ad;
611
612    if ((ad = device_get_ivars(child)) == NULL) {
613	printf("device has no ivars\n");
614	return(ENOENT);
615    }
616
617    switch(index) {
618	/* ACPI ivars */
619    case ACPI_IVAR_HANDLE:
620	ad->ad_handle = (ACPI_HANDLE)value;
621	break;
622    case ACPI_IVAR_MAGIC:
623	ad->ad_magic = (int )value;
624	break;
625    case ACPI_IVAR_PRIVATE:
626	ad->ad_private = (void *)value;
627	break;
628
629    default:
630	panic("bad ivar write request (%d)", index);
631	return(ENOENT);
632    }
633    return(0);
634}
635
636/*
637 * Handle child resource allocation/removal
638 */
639static int
640acpi_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count)
641{
642    struct acpi_device		*ad = device_get_ivars(child);
643    struct resource_list	*rl = &ad->ad_rl;
644
645    resource_list_add(rl, type, rid, start, start + count -1, count);
646
647    return(0);
648}
649
650static int
651acpi_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, u_long *countp)
652{
653    struct acpi_device		*ad = device_get_ivars(child);
654    struct resource_list	*rl = &ad->ad_rl;
655    struct resource_list_entry	*rle;
656
657    rle = resource_list_find(rl, type, rid);
658    if (!rle)
659	return(ENOENT);
660
661    if (startp)
662	*startp = rle->start;
663    if (countp)
664	*countp = rle->count;
665
666    return(0);
667}
668
669static struct resource *
670acpi_alloc_resource(device_t bus, device_t child, int type, int *rid,
671		    u_long start, u_long end, u_long count, u_int flags)
672{
673    struct acpi_device *ad = device_get_ivars(child);
674    struct resource_list *rl = &ad->ad_rl;
675
676    return(resource_list_alloc(rl, bus, child, type, rid, start, end, count, flags));
677}
678
679static int
680acpi_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r)
681{
682    struct acpi_device *ad = device_get_ivars(child);
683    struct resource_list *rl = &ad->ad_rl;
684
685    return(resource_list_release(rl, bus, child, type, rid, r));
686}
687
688/*
689 * Handle ISA-like devices probing for a PnP ID to match.
690 */
691#define PNP_EISAID(s)				\
692	((((s[0] - '@') & 0x1f) << 2)		\
693	 | (((s[1] - '@') & 0x18) >> 3)		\
694	 | (((s[1] - '@') & 0x07) << 13)	\
695	 | (((s[2] - '@') & 0x1f) << 8)		\
696	 | (PNP_HEXTONUM(s[4]) << 16)		\
697	 | (PNP_HEXTONUM(s[3]) << 20)		\
698	 | (PNP_HEXTONUM(s[6]) << 24)		\
699	 | (PNP_HEXTONUM(s[5]) << 28))
700
701static u_int32_t
702acpi_isa_get_logicalid(device_t dev)
703{
704    ACPI_HANDLE		h;
705    ACPI_DEVICE_INFO	devinfo;
706    ACPI_STATUS		error;
707    u_int32_t		pnpid;
708    ACPI_LOCK_DECL;
709
710    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
711
712    pnpid = 0;
713    ACPI_LOCK;
714
715    /* fetch and validate the HID */
716    if ((h = acpi_get_handle(dev)) == NULL)
717	goto out;
718    if (ACPI_FAILURE(error = AcpiGetObjectInfo(h, &devinfo)))
719	goto out;
720    if (!(devinfo.Valid & ACPI_VALID_HID))
721	goto out;
722
723    pnpid = PNP_EISAID(devinfo.HardwareId);
724out:
725    ACPI_UNLOCK;
726    return_VALUE(pnpid);
727}
728
729static int
730acpi_isa_pnp_probe(device_t bus, device_t child, struct isa_pnp_id *ids)
731{
732    int			result;
733    u_int32_t		pnpid;
734
735    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
736
737    /*
738     * ISA-style drivers attached to ACPI may persist and
739     * probe manually if we return ENOENT.  We never want
740     * that to happen, so don't ever return it.
741     */
742    result = ENXIO;
743
744    /* scan the supplied IDs for a match */
745    pnpid = acpi_isa_get_logicalid(child);
746    while (ids && ids->ip_id) {
747	if (pnpid == ids->ip_id) {
748	    result = 0;
749	    goto out;
750	}
751	ids++;
752    }
753 out:
754    return_VALUE(result);
755}
756
757/*
758 * Scan relevant portions of the ACPI namespace and attach child devices.
759 *
760 * Note that we only expect to find devices in the \_PR_, \_TZ_, \_SI_ and \_SB_ scopes,
761 * and \_PR_ and \_TZ_ become obsolete in the ACPI 2.0 spec.
762 */
763static void
764acpi_probe_children(device_t bus)
765{
766    ACPI_HANDLE		parent;
767    static char		*scopes[] = {"\\_PR_", "\\_TZ_", "\\_SI", "\\_SB_", NULL};
768    int			i;
769
770    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
771    ACPI_ASSERTLOCK;
772
773    /*
774     * Create any static children by calling device identify methods.
775     */
776    ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "device identify routines\n"));
777    bus_generic_probe(bus);
778
779    /*
780     * Scan the namespace and insert placeholders for all the devices that
781     * we find.
782     *
783     * Note that we use AcpiWalkNamespace rather than AcpiGetDevices because
784     * we want to create nodes for all devices, not just those that are currently
785     * present. (This assumes that we don't want to create/remove devices as they
786     * appear, which might be smarter.)
787     */
788    ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "namespace scan\n"));
789    for (i = 0; scopes[i] != NULL; i++)
790	if (ACPI_SUCCESS(AcpiGetHandle(ACPI_ROOT_OBJECT, scopes[i], &parent)))
791	    AcpiWalkNamespace(ACPI_TYPE_ANY, parent, 100, acpi_probe_child, bus, NULL);
792
793    /*
794     * Scan all of the child devices we have created and let them probe/attach.
795     */
796    ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "first bus_generic_attach\n"));
797    bus_generic_attach(bus);
798
799    /*
800     * Some of these children may have attached others as part of their attach
801     * process (eg. the root PCI bus driver), so rescan.
802     */
803    ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "second bus_generic_attach\n"));
804    bus_generic_attach(bus);
805
806    ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "done attaching children\n"));
807    return_VOID;
808}
809
810/*
811 * Evaluate a child device and determine whether we might attach a device to
812 * it.
813 */
814static ACPI_STATUS
815acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
816{
817    ACPI_OBJECT_TYPE	type;
818    device_t		child, bus = (device_t)context;
819
820    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
821
822    /*
823     * Skip this device if we think we'll have trouble with it.
824     */
825    if (acpi_avoid(handle))
826	return_ACPI_STATUS(AE_OK);
827
828    if (ACPI_SUCCESS(AcpiGetType(handle, &type))) {
829	switch(type) {
830	case ACPI_TYPE_DEVICE:
831	case ACPI_TYPE_PROCESSOR:
832	case ACPI_TYPE_THERMAL:
833	case ACPI_TYPE_POWER:
834	    if (acpi_disabled("children"))
835		break;
836	    /*
837	     * Create a placeholder device for this node.  Sort the placeholder
838	     * so that the probe/attach passes will run breadth-first.
839	     */
840	    ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "scanning '%s'\n", acpi_name(handle)));
841	    child = BUS_ADD_CHILD(bus, level * 10, NULL, -1);
842	    if (child == NULL)
843		break;
844	    acpi_set_handle(child, handle);
845
846	    /*
847	     * Check that the device is present.  If it's not present,
848	     * leave it disabled (so that we have a device_t attached to
849	     * the handle, but we don't probe it).
850	     */
851	    if ((type == ACPI_TYPE_DEVICE) && (!acpi_DeviceIsPresent(child))) {
852		device_disable(child);
853		break;
854	    }
855
856	    /*
857	     * Get the device's resource settings and attach them.
858	     * Note that if the device has _PRS but no _CRS, we need
859	     * to decide when it's appropriate to try to configure the
860	     * device.  Ignore the return value here; it's OK for the
861	     * device not to have any resources.
862	     */
863	    acpi_parse_resources(child, handle, &acpi_res_parse_set);
864
865	    /* if we're debugging, probe/attach now rather than later */
866	    ACPI_DEBUG_EXEC(device_probe_and_attach(child));
867	    break;
868	}
869    }
870    return_ACPI_STATUS(AE_OK);
871}
872
873static void
874acpi_shutdown_pre_sync(void *arg, int howto)
875{
876
877    struct acpi_softc *sc = arg;
878
879    ACPI_ASSERTLOCK;
880
881    /*
882     * Disable all ACPI events before soft off, otherwise the system
883     * will be turned on again on some laptops.
884     *
885     * XXX this should probably be restricted to masking some events just
886     *     before powering down, since we may still need ACPI during the
887     *     shutdown process.
888     */
889    if (sc->acpi_disable_on_poweroff)
890	acpi_Disable(sc);
891}
892
893static void
894acpi_shutdown_final(void *arg, int howto)
895{
896    ACPI_STATUS	status;
897
898    ACPI_ASSERTLOCK;
899
900    if (howto & RB_POWEROFF) {
901	printf("Power system off using ACPI...\n");
902	if (ACPI_FAILURE(status = AcpiEnterSleepStatePrep(acpi_off_state))) {
903	    printf("AcpiEnterSleepStatePrep failed - %s\n",
904		   AcpiFormatException(status));
905	    return;
906	}
907	if (ACPI_FAILURE(status = AcpiEnterSleepState(acpi_off_state))) {
908	    printf("ACPI power-off failed - %s\n", AcpiFormatException(status));
909	} else {
910	    DELAY(1000000);
911	    printf("ACPI power-off failed - timeout\n");
912	}
913    } else {
914	printf("Terminate ACPI\n");
915	AcpiTerminate();
916    }
917}
918
919static void
920acpi_enable_fixed_events(struct acpi_softc *sc)
921{
922    static int	first_time = 1;
923#define MSGFORMAT "%s button is handled as a fixed feature programming model.\n"
924
925    ACPI_ASSERTLOCK;
926
927    /* Enable and clear fixed events and install handlers. */
928    if ((AcpiGbl_FADT != NULL) && (AcpiGbl_FADT->PwrButton == 0)) {
929	AcpiEnableEvent(ACPI_EVENT_POWER_BUTTON, ACPI_EVENT_FIXED, 0);
930	AcpiClearEvent(ACPI_EVENT_POWER_BUTTON, ACPI_EVENT_FIXED);
931	AcpiInstallFixedEventHandler(ACPI_EVENT_POWER_BUTTON,
932				     acpi_eventhandler_power_button_for_sleep, sc);
933	if (first_time) {
934	    device_printf(sc->acpi_dev, MSGFORMAT, "power");
935	}
936    }
937    if ((AcpiGbl_FADT != NULL) && (AcpiGbl_FADT->SleepButton == 0)) {
938	AcpiEnableEvent(ACPI_EVENT_SLEEP_BUTTON, ACPI_EVENT_FIXED, 0);
939	AcpiClearEvent(ACPI_EVENT_SLEEP_BUTTON, ACPI_EVENT_FIXED);
940	AcpiInstallFixedEventHandler(ACPI_EVENT_SLEEP_BUTTON,
941				     acpi_eventhandler_sleep_button_for_sleep, sc);
942	if (first_time) {
943	    device_printf(sc->acpi_dev, MSGFORMAT, "sleep");
944	}
945    }
946
947    first_time = 0;
948}
949
950/*
951 * Returns true if the device is actually present and should
952 * be attached to.  This requires the present, enabled, UI-visible
953 * and diagnostics-passed bits to be set.
954 */
955BOOLEAN
956acpi_DeviceIsPresent(device_t dev)
957{
958    ACPI_HANDLE		h;
959    ACPI_DEVICE_INFO	devinfo;
960    ACPI_STATUS		error;
961
962    ACPI_ASSERTLOCK;
963
964    if ((h = acpi_get_handle(dev)) == NULL)
965	return(FALSE);
966    if (ACPI_FAILURE(error = AcpiGetObjectInfo(h, &devinfo)))
967	return(FALSE);
968    /* if no _STA method, must be present */
969    if (!(devinfo.Valid & ACPI_VALID_STA))
970	return(TRUE);
971    /* return true for 'present' and 'functioning' */
972    if ((devinfo.CurrentStatus & 0x9) == 0x9)
973	return(TRUE);
974    return(FALSE);
975}
976
977/*
978 * Returns true if the battery is actually present and inserted.
979 */
980BOOLEAN
981acpi_BatteryIsPresent(device_t dev)
982{
983    ACPI_HANDLE		h;
984    ACPI_DEVICE_INFO	devinfo;
985    ACPI_STATUS		error;
986
987    ACPI_ASSERTLOCK;
988
989    if ((h = acpi_get_handle(dev)) == NULL)
990	return(FALSE);
991    if (ACPI_FAILURE(error = AcpiGetObjectInfo(h, &devinfo)))
992	return(FALSE);
993    /* if no _STA method, must be present */
994    if (!(devinfo.Valid & ACPI_VALID_STA))
995	return(TRUE);
996    /* return true for 'present' and 'functioning' */
997    if ((devinfo.CurrentStatus & 0x19) == 0x19)
998	return(TRUE);
999    return(FALSE);
1000}
1001
1002/*
1003 * Match a HID string against a device
1004 */
1005BOOLEAN
1006acpi_MatchHid(device_t dev, char *hid)
1007{
1008    ACPI_HANDLE		h;
1009    ACPI_DEVICE_INFO	devinfo;
1010    ACPI_STATUS		error;
1011    int			cid;
1012
1013    ACPI_ASSERTLOCK;
1014
1015    if (hid == NULL)
1016	return(FALSE);
1017    if ((h = acpi_get_handle(dev)) == NULL)
1018	return(FALSE);
1019    if (ACPI_FAILURE(error = AcpiGetObjectInfo(h, &devinfo)))
1020	return(FALSE);
1021    if ((devinfo.Valid & ACPI_VALID_HID) && !strcmp(hid, devinfo.HardwareId))
1022	return(TRUE);
1023    if (ACPI_FAILURE(error = acpi_EvaluateInteger(h, "_CID", &cid)))
1024	return(FALSE);
1025    if (cid == PNP_EISAID(hid))
1026	return(TRUE);
1027    return(FALSE);
1028}
1029
1030/*
1031 * Return the handle of a named object within our scope, ie. that of (parent)
1032 * or one if its parents.
1033 */
1034ACPI_STATUS
1035acpi_GetHandleInScope(ACPI_HANDLE parent, char *path, ACPI_HANDLE *result)
1036{
1037    ACPI_HANDLE		r;
1038    ACPI_STATUS		status;
1039
1040    ACPI_ASSERTLOCK;
1041
1042    /* walk back up the tree to the root */
1043    for (;;) {
1044	if (ACPI_SUCCESS(status = AcpiGetHandle(parent, path, &r))) {
1045	    *result = r;
1046	    return(AE_OK);
1047	}
1048	if (status != AE_NOT_FOUND)
1049	    return(AE_OK);
1050	if (ACPI_FAILURE(AcpiGetParent(parent, &r)))
1051	    return(AE_NOT_FOUND);
1052	parent = r;
1053    }
1054}
1055
1056/*
1057 * Allocate a buffer with a preset data size.
1058 */
1059ACPI_BUFFER *
1060acpi_AllocBuffer(int size)
1061{
1062    ACPI_BUFFER	*buf;
1063
1064    if ((buf = malloc(size + sizeof(*buf), M_ACPIDEV, M_NOWAIT)) == NULL)
1065	return(NULL);
1066    buf->Length = size;
1067    buf->Pointer = (void *)(buf + 1);
1068    return(buf);
1069}
1070
1071/*
1072 * Evaluate a path that should return an integer.
1073 */
1074ACPI_STATUS
1075acpi_EvaluateInteger(ACPI_HANDLE handle, char *path, int *number)
1076{
1077    ACPI_STATUS	error;
1078    ACPI_BUFFER	buf;
1079    ACPI_OBJECT	param;
1080
1081    ACPI_ASSERTLOCK;
1082
1083    if (handle == NULL)
1084	handle = ACPI_ROOT_OBJECT;
1085
1086    /*
1087     * Assume that what we've been pointed at is an Integer object, or
1088     * a method that will return an Integer.
1089     */
1090    buf.Pointer = &param;
1091    buf.Length = sizeof(param);
1092    if (ACPI_SUCCESS(error = AcpiEvaluateObject(handle, path, NULL, &buf))) {
1093	if (param.Type == ACPI_TYPE_INTEGER) {
1094	    *number = param.Integer.Value;
1095	} else {
1096	    error = AE_TYPE;
1097	}
1098    }
1099
1100    /*
1101     * In some applications, a method that's expected to return an Integer
1102     * may instead return a Buffer (probably to simplify some internal
1103     * arithmetic).  We'll try to fetch whatever it is, and if it's a Buffer,
1104     * convert it into an Integer as best we can.
1105     *
1106     * This is a hack.
1107     */
1108    if (error == AE_BUFFER_OVERFLOW) {
1109	if ((buf.Pointer = AcpiOsAllocate(buf.Length)) == NULL) {
1110	    error = AE_NO_MEMORY;
1111	} else {
1112	    if (ACPI_SUCCESS(error = AcpiEvaluateObject(handle, path, NULL, &buf))) {
1113		error = acpi_ConvertBufferToInteger(&buf, number);
1114	    }
1115	}
1116	AcpiOsFree(buf.Pointer);
1117    }
1118    return(error);
1119}
1120
1121ACPI_STATUS
1122acpi_ConvertBufferToInteger(ACPI_BUFFER *bufp, int *number)
1123{
1124    ACPI_OBJECT	*p;
1125    int		i;
1126
1127    p = (ACPI_OBJECT *)bufp->Pointer;
1128    if (p->Type == ACPI_TYPE_INTEGER) {
1129	*number = p->Integer.Value;
1130	return(AE_OK);
1131    }
1132    if (p->Type != ACPI_TYPE_BUFFER)
1133	return(AE_TYPE);
1134    if (p->Buffer.Length > sizeof(int))
1135	return(AE_BAD_DATA);
1136    *number = 0;
1137    for (i = 0; i < p->Buffer.Length; i++)
1138	*number += (*(p->Buffer.Pointer + i) << (i * 8));
1139    return(AE_OK);
1140}
1141
1142/*
1143 * Iterate over the elements of an a package object, calling the supplied
1144 * function for each element.
1145 *
1146 * XXX possible enhancement might be to abort traversal on error.
1147 */
1148ACPI_STATUS
1149acpi_ForeachPackageObject(ACPI_OBJECT *pkg, void (* func)(ACPI_OBJECT *comp, void *arg), void *arg)
1150{
1151    ACPI_OBJECT	*comp;
1152    int		i;
1153
1154    if ((pkg == NULL) || (pkg->Type != ACPI_TYPE_PACKAGE))
1155	return(AE_BAD_PARAMETER);
1156
1157    /* iterate over components */
1158    for (i = 0, comp = pkg->Package.Elements; i < pkg->Package.Count; i++, comp++)
1159	func(comp, arg);
1160
1161    return(AE_OK);
1162}
1163
1164/*
1165 * Find the (index)th resource object in a set.
1166 */
1167ACPI_STATUS
1168acpi_FindIndexedResource(ACPI_BUFFER *buf, int index, ACPI_RESOURCE **resp)
1169{
1170    ACPI_RESOURCE	*rp;
1171    int			i;
1172
1173    rp = (ACPI_RESOURCE *)buf->Pointer;
1174    i = index;
1175    while (i-- > 0) {
1176	/* range check */
1177	if (rp > (ACPI_RESOURCE *)((u_int8_t *)buf->Pointer + buf->Length))
1178	    return(AE_BAD_PARAMETER);
1179	/* check for terminator */
1180	if ((rp->Id == ACPI_RSTYPE_END_TAG) ||
1181	    (rp->Length == 0))
1182	    return(AE_NOT_FOUND);
1183	rp = ACPI_RESOURCE_NEXT(rp);
1184    }
1185    if (resp != NULL)
1186	*resp = rp;
1187    return(AE_OK);
1188}
1189
1190/*
1191 * Append an ACPI_RESOURCE to an ACPI_BUFFER.
1192 *
1193 * Given a pointer to an ACPI_RESOURCE structure, expand the ACPI_BUFFER
1194 * provided to contain it.  If the ACPI_BUFFER is empty, allocate a sensible
1195 * backing block.  If the ACPI_RESOURCE is NULL, return an empty set of
1196 * resources.
1197 */
1198#define ACPI_INITIAL_RESOURCE_BUFFER_SIZE	512
1199
1200ACPI_STATUS
1201acpi_AppendBufferResource(ACPI_BUFFER *buf, ACPI_RESOURCE *res)
1202{
1203    ACPI_RESOURCE	*rp;
1204    void		*newp;
1205
1206    /*
1207     * Initialise the buffer if necessary.
1208     */
1209    if (buf->Pointer == NULL) {
1210	buf->Length = ACPI_INITIAL_RESOURCE_BUFFER_SIZE;
1211	if ((buf->Pointer = AcpiOsAllocate(buf->Length)) == NULL)
1212	    return(AE_NO_MEMORY);
1213	rp = (ACPI_RESOURCE *)buf->Pointer;
1214	rp->Id = ACPI_RSTYPE_END_TAG;
1215	rp->Length = 0;
1216    }
1217    if (res == NULL)
1218	return(AE_OK);
1219
1220    /*
1221     * Scan the current buffer looking for the terminator.
1222     * This will either find the terminator or hit the end
1223     * of the buffer and return an error.
1224     */
1225    rp = (ACPI_RESOURCE *)buf->Pointer;
1226    for (;;) {
1227	/* range check, don't go outside the buffer */
1228	if (rp >= (ACPI_RESOURCE *)((u_int8_t *)buf->Pointer + buf->Length))
1229	    return(AE_BAD_PARAMETER);
1230	if ((rp->Id == ACPI_RSTYPE_END_TAG) ||
1231	    (rp->Length == 0)) {
1232	    break;
1233	}
1234	rp = ACPI_RESOURCE_NEXT(rp);
1235    }
1236
1237    /*
1238     * Check the size of the buffer and expand if required.
1239     *
1240     * Required size is:
1241     *	size of existing resources before terminator +
1242     *	size of new resource and header +
1243     * 	size of terminator.
1244     *
1245     * Note that this loop should really only run once, unless
1246     * for some reason we are stuffing a *really* huge resource.
1247     */
1248    while ((((u_int8_t *)rp - (u_int8_t *)buf->Pointer) +
1249	    res->Length + ACPI_RESOURCE_LENGTH_NO_DATA +
1250	    ACPI_RESOURCE_LENGTH) >= buf->Length) {
1251	if ((newp = AcpiOsAllocate(buf->Length * 2)) == NULL)
1252	    return(AE_NO_MEMORY);
1253	bcopy(buf->Pointer, newp, buf->Length);
1254        rp = (ACPI_RESOURCE *)((u_int8_t *)newp +
1255			       ((u_int8_t *)rp - (u_int8_t *)buf->Pointer));
1256	AcpiOsFree(buf->Pointer);
1257	buf->Pointer = newp;
1258	buf->Length += buf->Length;
1259    }
1260
1261    /*
1262     * Insert the new resource.
1263     */
1264    bcopy(res, rp, res->Length + ACPI_RESOURCE_LENGTH_NO_DATA);
1265
1266    /*
1267     * And add the terminator.
1268     */
1269    rp = ACPI_RESOURCE_NEXT(rp);
1270    rp->Id = ACPI_RSTYPE_END_TAG;
1271    rp->Length = 0;
1272
1273    return(AE_OK);
1274}
1275
1276/*
1277 * Set interrupt model.
1278 */
1279ACPI_STATUS
1280acpi_SetIntrModel(int model)
1281{
1282	ACPI_OBJECT_LIST ArgList;
1283	ACPI_OBJECT Arg;
1284
1285	Arg.Type = ACPI_TYPE_INTEGER;
1286	Arg.Integer.Value = model;
1287	ArgList.Count = 1;
1288	ArgList.Pointer = &Arg;
1289	return (AcpiEvaluateObject(ACPI_ROOT_OBJECT, "_PIC", &ArgList, NULL));
1290}
1291
1292#define ACPI_MINIMUM_AWAKETIME	5
1293
1294static void
1295acpi_sleep_enable(void *arg)
1296{
1297    ((struct acpi_softc *)arg)->acpi_sleep_disabled = 0;
1298}
1299
1300/*
1301 * Set the system sleep state
1302 *
1303 * Currently we only support S1 and S5
1304 */
1305ACPI_STATUS
1306acpi_SetSleepState(struct acpi_softc *sc, int state)
1307{
1308    ACPI_STATUS	status = AE_OK;
1309    UINT8	TypeA;
1310    UINT8	TypeB;
1311
1312    ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state);
1313    ACPI_ASSERTLOCK;
1314
1315    if (sc->acpi_sstate != ACPI_STATE_S0)
1316	return_ACPI_STATUS(AE_BAD_PARAMETER);	/* avoid reentry */
1317
1318    if (sc->acpi_sleep_disabled)
1319	return_ACPI_STATUS(AE_OK);
1320
1321    switch (state) {
1322    case ACPI_STATE_S0:	/* XXX only for testing */
1323	if (ACPI_FAILURE(status = AcpiEnterSleepState((UINT8)state))) {
1324	    device_printf(sc->acpi_dev, "AcpiEnterSleepState failed - %s\n", AcpiFormatException(status));
1325	}
1326	break;
1327
1328    case ACPI_STATE_S1:
1329    case ACPI_STATE_S2:
1330    case ACPI_STATE_S3:
1331    case ACPI_STATE_S4:
1332	if (ACPI_FAILURE(status = AcpiGetSleepTypeData((UINT8)state, &TypeA, &TypeB))) {
1333	    device_printf(sc->acpi_dev, "AcpiGetSleepTypeData failed - %s\n", AcpiFormatException(status));
1334	    break;
1335	}
1336
1337	sc->acpi_sstate = state;
1338	sc->acpi_sleep_disabled = 1;
1339
1340	/*
1341	 * Inform all devices that we are going to sleep.
1342	 */
1343	if (DEVICE_SUSPEND(root_bus) != 0) {
1344	    /*
1345	     * Re-wake the system.
1346	     *
1347	     * XXX note that a better two-pass approach with a 'veto' pass
1348	     *     followed by a "real thing" pass would be better, but the
1349	     *     current bus interface does not provide for this.
1350	     */
1351	    DEVICE_RESUME(root_bus);
1352	    return_ACPI_STATUS(AE_ERROR);
1353	}
1354
1355	if (ACPI_FAILURE(status = AcpiEnterSleepStatePrep(state))) {
1356	    device_printf(sc->acpi_dev, "AcpiEnterSleepStatePrep failed - %s\n",
1357			  AcpiFormatException(status));
1358	    break;
1359	}
1360
1361	if (sc->acpi_sleep_delay > 0) {
1362	    DELAY(sc->acpi_sleep_delay * 1000000);
1363	}
1364
1365	if (state != ACPI_STATE_S1) {
1366	    acpi_sleep_machdep(sc, state);
1367
1368	    /* AcpiEnterSleepState() maybe incompleted, unlock here if locked. */
1369	    if (AcpiGbl_AcpiMutexInfo[ACPI_MTX_HARDWARE].OwnerId != ACPI_MUTEX_NOT_ACQUIRED) {
1370		AcpiUtReleaseMutex(ACPI_MTX_HARDWARE);
1371	    }
1372
1373	    /* Re-enable ACPI hardware on wakeup from sleep state 4. */
1374	    if (state == ACPI_STATE_S4) {
1375		AcpiEnable();
1376	    }
1377	} else {
1378	    if (ACPI_FAILURE(status = AcpiEnterSleepState((UINT8)state))) {
1379		device_printf(sc->acpi_dev, "AcpiEnterSleepState failed - %s\n", AcpiFormatException(status));
1380		break;
1381	    }
1382	}
1383	AcpiLeaveSleepState((UINT8)state);
1384	DEVICE_RESUME(root_bus);
1385	sc->acpi_sstate = ACPI_STATE_S0;
1386	acpi_enable_fixed_events(sc);
1387	break;
1388
1389    case ACPI_STATE_S5:
1390	/*
1391	 * Shut down cleanly and power off.  This will call us back through the
1392	 * shutdown handlers.
1393	 */
1394	shutdown_nice(RB_POWEROFF);
1395	break;
1396
1397    default:
1398	status = AE_BAD_PARAMETER;
1399	break;
1400    }
1401
1402    if (sc->acpi_sleep_disabled)
1403	timeout(acpi_sleep_enable, (caddr_t)sc, hz * ACPI_MINIMUM_AWAKETIME);
1404
1405    return_ACPI_STATUS(status);
1406}
1407
1408/*
1409 * Enable/Disable ACPI
1410 */
1411ACPI_STATUS
1412acpi_Enable(struct acpi_softc *sc)
1413{
1414    ACPI_STATUS	status;
1415    u_int32_t	flags;
1416
1417    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
1418    ACPI_ASSERTLOCK;
1419
1420    flags = ACPI_NO_ADDRESS_SPACE_INIT | ACPI_NO_HARDWARE_INIT |
1421            ACPI_NO_DEVICE_INIT | ACPI_NO_OBJECT_INIT;
1422    if (!sc->acpi_enabled) {
1423	status = AcpiEnableSubsystem(flags);
1424    } else {
1425	status = AE_OK;
1426    }
1427    if (status == AE_OK)
1428	sc->acpi_enabled = 1;
1429    return_ACPI_STATUS(status);
1430}
1431
1432ACPI_STATUS
1433acpi_Disable(struct acpi_softc *sc)
1434{
1435    ACPI_STATUS	status;
1436
1437    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
1438    ACPI_ASSERTLOCK;
1439
1440    if (sc->acpi_enabled) {
1441	status = AcpiDisable();
1442    } else {
1443	status = AE_OK;
1444    }
1445    if (status == AE_OK)
1446	sc->acpi_enabled = 0;
1447    return_ACPI_STATUS(status);
1448}
1449
1450/*
1451 * ACPI Event Handlers
1452 */
1453
1454/* System Event Handlers (registered by EVENTHANDLER_REGISTER) */
1455
1456static void
1457acpi_system_eventhandler_sleep(void *arg, int state)
1458{
1459    ACPI_LOCK_DECL;
1460    ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state);
1461
1462    ACPI_LOCK;
1463    if (state >= ACPI_STATE_S0 && state <= ACPI_S_STATES_MAX)
1464	acpi_SetSleepState((struct acpi_softc *)arg, state);
1465    ACPI_UNLOCK;
1466    return_VOID;
1467}
1468
1469static void
1470acpi_system_eventhandler_wakeup(void *arg, int state)
1471{
1472    ACPI_LOCK_DECL;
1473    ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state);
1474
1475    /* Well, what to do? :-) */
1476
1477    ACPI_LOCK;
1478    ACPI_UNLOCK;
1479
1480    return_VOID;
1481}
1482
1483/*
1484 * ACPICA Event Handlers (FixedEvent, also called from button notify handler)
1485 */
1486UINT32
1487acpi_eventhandler_power_button_for_sleep(void *context)
1488{
1489    struct acpi_softc	*sc = (struct acpi_softc *)context;
1490
1491    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
1492
1493    EVENTHANDLER_INVOKE(acpi_sleep_event, sc->acpi_power_button_sx);
1494
1495    return_VALUE(ACPI_INTERRUPT_HANDLED);
1496}
1497
1498UINT32
1499acpi_eventhandler_power_button_for_wakeup(void *context)
1500{
1501    struct acpi_softc	*sc = (struct acpi_softc *)context;
1502
1503    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
1504
1505    EVENTHANDLER_INVOKE(acpi_wakeup_event, sc->acpi_power_button_sx);
1506
1507    return_VALUE(ACPI_INTERRUPT_HANDLED);
1508}
1509
1510UINT32
1511acpi_eventhandler_sleep_button_for_sleep(void *context)
1512{
1513    struct acpi_softc	*sc = (struct acpi_softc *)context;
1514
1515    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
1516
1517    EVENTHANDLER_INVOKE(acpi_sleep_event, sc->acpi_sleep_button_sx);
1518
1519    return_VALUE(ACPI_INTERRUPT_HANDLED);
1520}
1521
1522UINT32
1523acpi_eventhandler_sleep_button_for_wakeup(void *context)
1524{
1525    struct acpi_softc	*sc = (struct acpi_softc *)context;
1526
1527    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
1528
1529    EVENTHANDLER_INVOKE(acpi_wakeup_event, sc->acpi_sleep_button_sx);
1530
1531    return_VALUE(ACPI_INTERRUPT_HANDLED);
1532}
1533
1534/*
1535 * XXX This is kinda ugly, and should not be here.
1536 */
1537struct acpi_staticbuf {
1538    ACPI_BUFFER	buffer;
1539    char	data[512];
1540};
1541
1542char *
1543acpi_name(ACPI_HANDLE handle)
1544{
1545    static struct acpi_staticbuf	buf;
1546
1547    ACPI_ASSERTLOCK;
1548
1549    buf.buffer.Length = 512;
1550    buf.buffer.Pointer = &buf.data[0];
1551
1552    if (ACPI_SUCCESS(AcpiGetName(handle, ACPI_FULL_PATHNAME, &buf.buffer)))
1553	return(buf.buffer.Pointer);
1554    return("(unknown path)");
1555}
1556
1557/*
1558 * Debugging/bug-avoidance.  Avoid trying to fetch info on various
1559 * parts of the namespace.
1560 */
1561int
1562acpi_avoid(ACPI_HANDLE handle)
1563{
1564    char	*cp, *env, *np;
1565    int		len;
1566
1567    np = acpi_name(handle);
1568    if (*np == '\\')
1569	np++;
1570    if ((env = getenv("debug.acpi.avoid")) == NULL)
1571	return(0);
1572
1573    /* scan the avoid list checking for a match */
1574    cp = env;
1575    for (;;) {
1576	while ((*cp != 0) && isspace(*cp))
1577	    cp++;
1578	if (*cp == 0)
1579	    break;
1580	len = 0;
1581	while ((cp[len] != 0) && !isspace(cp[len]))
1582	    len++;
1583	if (!strncmp(cp, np, len)) {
1584	    freeenv(env);
1585	    return(1);
1586	}
1587	cp += len;
1588    }
1589    freeenv(env);
1590    return(0);
1591}
1592
1593/*
1594 * Debugging/bug-avoidance.  Disable ACPI subsystem components.
1595 */
1596int
1597acpi_disabled(char *subsys)
1598{
1599    char	*cp, *env;
1600    int		len;
1601
1602    if ((env = getenv("debug.acpi.disable")) == NULL)
1603	return(0);
1604    if (!strcmp(env, "all")) {
1605	freeenv(env);
1606	return(1);
1607    }
1608
1609    /* scan the disable list checking for a match */
1610    cp = env;
1611    for (;;) {
1612	while ((*cp != 0) && isspace(*cp))
1613	    cp++;
1614	if (*cp == 0)
1615	    break;
1616	len = 0;
1617	while ((cp[len] != 0) && !isspace(cp[len]))
1618	    len++;
1619	if (!strncmp(cp, subsys, len)) {
1620	    freeenv(env);
1621	    return(1);
1622	}
1623	cp += len;
1624    }
1625    freeenv(env);
1626    return(0);
1627}
1628
1629/*
1630 * Device wake capability enable/disable.
1631 */
1632void
1633acpi_device_enable_wake_capability(ACPI_HANDLE h, int enable)
1634{
1635    ACPI_OBJECT_LIST		ArgList;
1636    ACPI_OBJECT			Arg;
1637
1638    /*
1639     * TBD: All Power Resources referenced by elements 2 through N
1640     *      of the _PRW object are put into the ON state.
1641     */
1642
1643    /*
1644     * enable/disable device wake function.
1645     */
1646
1647    ArgList.Count = 1;
1648    ArgList.Pointer = &Arg;
1649
1650    Arg.Type = ACPI_TYPE_INTEGER;
1651    Arg.Integer.Value = enable;
1652
1653    (void)AcpiEvaluateObject(h, "_PSW", &ArgList, NULL);
1654}
1655
1656void
1657acpi_device_enable_wake_event(ACPI_HANDLE h)
1658{
1659    struct acpi_softc		*sc;
1660    ACPI_STATUS			status;
1661    ACPI_BUFFER			prw_buffer;
1662    ACPI_OBJECT			*res;
1663
1664    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
1665
1666    if ((sc = devclass_get_softc(acpi_devclass, 0)) == NULL) {
1667	return;
1668    }
1669
1670    /*
1671     * _PRW object is only required for devices that have the ability
1672     * to wake the system from a system sleeping state.
1673     */
1674    prw_buffer.Length = ACPI_ALLOCATE_BUFFER;
1675    status = AcpiEvaluateObject(h, "_PRW", NULL, &prw_buffer);
1676    if (ACPI_FAILURE(status)) {
1677	return;
1678    }
1679
1680    res = (ACPI_OBJECT *)prw_buffer.Pointer;
1681    if (res == NULL) {
1682	return;
1683    }
1684
1685    if ((res->Type != ACPI_TYPE_PACKAGE) || (res->Package.Count < 2)) {
1686	goto out;
1687    }
1688
1689    /*
1690     * The element 1 of the _PRW object:
1691     * The lowest power system sleeping state that can be entered
1692     * while still providing wake functionality.
1693     * The sleeping state being entered must be greater or equal to
1694     * the power state declared in element 1 of the _PRW object.
1695     */
1696    if (res->Package.Elements[1].Type != ACPI_TYPE_INTEGER) {
1697	goto out;
1698    }
1699
1700    if (sc->acpi_sstate > res->Package.Elements[1].Integer.Value) {
1701	goto out;
1702    }
1703
1704    /*
1705     * The element 0 of the _PRW object:
1706     */
1707    switch(res->Package.Elements[0].Type) {
1708    case ACPI_TYPE_INTEGER:
1709	/*
1710	 * If the data type of this package element is numeric, then this
1711	 * _PRW package element is the bit index in the GPEx_EN, in the
1712	 * GPE blocks described in the FADT, of the enable bit that is
1713	 * enabled for the wake event.
1714	 */
1715
1716	status = AcpiEnableEvent(res->Package.Elements[0].Integer.Value,
1717				 ACPI_EVENT_GPE, ACPI_EVENT_WAKE_ENABLE);
1718	if (ACPI_FAILURE(status))
1719            printf("%s: EnableEvent Failed\n", __func__);
1720	break;
1721
1722    case ACPI_TYPE_PACKAGE:
1723	/* XXX TBD */
1724
1725	/*
1726	 * If the data type of this package element is a package, then this
1727	 * _PRW package element is itself a package containing two
1728	 * elements. The first is an object reference to the GPE Block
1729	 * device that contains the GPE that will be triggered by the wake
1730	 * event. The second element is numeric and it contains the bit
1731	 * index in the GPEx_EN, in the GPE Block referenced by the
1732	 * first element in the package, of the enable bit that is enabled for
1733	 * the wake event.
1734	 * For example, if this field is a package then it is of the form:
1735	 * Package() {\_SB.PCI0.ISA.GPE, 2}
1736	 */
1737
1738	break;
1739
1740    default:
1741	break;
1742    }
1743
1744out:
1745    if (prw_buffer.Pointer != NULL)
1746	AcpiOsFree(prw_buffer.Pointer);
1747    return;
1748}
1749
1750/*
1751 * Control interface.
1752 *
1753 * We multiplex ioctls for all participating ACPI devices here.  Individual
1754 * drivers wanting to be accessible via /dev/acpi should use the register/deregister
1755 * interface to make their handlers visible.
1756 */
1757struct acpi_ioctl_hook
1758{
1759    TAILQ_ENTRY(acpi_ioctl_hook)	link;
1760    u_long				cmd;
1761    int					(* fn)(u_long cmd, caddr_t addr, void *arg);
1762    void				*arg;
1763};
1764
1765static TAILQ_HEAD(,acpi_ioctl_hook)	acpi_ioctl_hooks;
1766static int				acpi_ioctl_hooks_initted;
1767
1768/*
1769 * Register an ioctl handler.
1770 */
1771int
1772acpi_register_ioctl(u_long cmd, int (* fn)(u_long cmd, caddr_t addr, void *arg), void *arg)
1773{
1774    struct acpi_ioctl_hook	*hp;
1775
1776    if ((hp = malloc(sizeof(*hp), M_ACPIDEV, M_NOWAIT)) == NULL)
1777	return(ENOMEM);
1778    hp->cmd = cmd;
1779    hp->fn = fn;
1780    hp->arg = arg;
1781    if (acpi_ioctl_hooks_initted == 0) {
1782	TAILQ_INIT(&acpi_ioctl_hooks);
1783	acpi_ioctl_hooks_initted = 1;
1784    }
1785    TAILQ_INSERT_TAIL(&acpi_ioctl_hooks, hp, link);
1786    return(0);
1787}
1788
1789/*
1790 * Deregister an ioctl handler.
1791 */
1792void
1793acpi_deregister_ioctl(u_long cmd, int (* fn)(u_long cmd, caddr_t addr, void *arg))
1794{
1795    struct acpi_ioctl_hook	*hp;
1796
1797    TAILQ_FOREACH(hp, &acpi_ioctl_hooks, link)
1798	if ((hp->cmd == cmd) && (hp->fn == fn))
1799	    break;
1800
1801    if (hp != NULL) {
1802	TAILQ_REMOVE(&acpi_ioctl_hooks, hp, link);
1803	free(hp, M_ACPIDEV);
1804    }
1805}
1806
1807static int
1808acpiopen(dev_t dev, int flag, int fmt, d_thread_t *td)
1809{
1810    return(0);
1811}
1812
1813static int
1814acpiclose(dev_t dev, int flag, int fmt, d_thread_t *td)
1815{
1816    return(0);
1817}
1818
1819static int
1820acpiioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, d_thread_t *td)
1821{
1822    struct acpi_softc		*sc;
1823    struct acpi_ioctl_hook	*hp;
1824    int				error, xerror, state;
1825    ACPI_LOCK_DECL;
1826
1827    ACPI_LOCK;
1828
1829    error = state = 0;
1830    sc = dev->si_drv1;
1831
1832    /*
1833     * Scan the list of registered ioctls, looking for handlers.
1834     */
1835    if (acpi_ioctl_hooks_initted) {
1836	TAILQ_FOREACH(hp, &acpi_ioctl_hooks, link) {
1837	    if (hp->cmd == cmd) {
1838		xerror = hp->fn(cmd, addr, hp->arg);
1839		if (xerror != 0)
1840		    error = xerror;
1841		goto out;
1842	    }
1843	}
1844    }
1845
1846    /*
1847     * Core system ioctls.
1848     */
1849    switch (cmd) {
1850    case ACPIIO_ENABLE:
1851	if (ACPI_FAILURE(acpi_Enable(sc)))
1852	    error = ENXIO;
1853	break;
1854
1855    case ACPIIO_DISABLE:
1856	if (ACPI_FAILURE(acpi_Disable(sc)))
1857	    error = ENXIO;
1858	break;
1859
1860    case ACPIIO_SETSLPSTATE:
1861	if (!sc->acpi_enabled) {
1862	    error = ENXIO;
1863	    break;
1864	}
1865	state = *(int *)addr;
1866	if (state >= ACPI_STATE_S0  && state <= ACPI_S_STATES_MAX) {
1867	    acpi_SetSleepState(sc, state);
1868	} else {
1869	    error = EINVAL;
1870	}
1871	break;
1872
1873    default:
1874	if (error == 0)
1875	    error = EINVAL;
1876	break;
1877    }
1878
1879out:
1880    ACPI_UNLOCK;
1881    return(error);
1882}
1883
1884static int
1885acpi_sleep_state_sysctl(SYSCTL_HANDLER_ARGS)
1886{
1887    char sleep_state[10];
1888    int error;
1889    u_int new_state, old_state;
1890
1891    old_state = *(u_int *)oidp->oid_arg1;
1892    if (old_state > ACPI_S_STATES_MAX+1) {
1893	strcpy(sleep_state, "unknown");
1894    } else {
1895	bzero(sleep_state, sizeof(sleep_state));
1896	strncpy(sleep_state, sleep_state_names[old_state],
1897		sizeof(sleep_state_names[old_state]));
1898    }
1899    error = sysctl_handle_string(oidp, sleep_state, sizeof(sleep_state), req);
1900    if (error == 0 && req->newptr != NULL) {
1901	for (new_state = ACPI_STATE_S0; new_state <= ACPI_S_STATES_MAX+1; new_state++) {
1902	    if (strncmp(sleep_state, sleep_state_names[new_state],
1903			sizeof(sleep_state)) == 0)
1904		break;
1905	}
1906	if (new_state <= ACPI_S_STATES_MAX+1) {
1907	    if (new_state != old_state) {
1908		*(u_int *)oidp->oid_arg1 = new_state;
1909	    }
1910	} else {
1911	    error = EINVAL;
1912	}
1913    }
1914    return(error);
1915}
1916
1917#ifdef ACPI_DEBUG
1918/*
1919 * Support for parsing debug options from the kernel environment.
1920 *
1921 * Bits may be set in the AcpiDbgLayer and AcpiDbgLevel debug registers
1922 * by specifying the names of the bits in the debug.acpi.layer and
1923 * debug.acpi.level environment variables.  Bits may be unset by
1924 * prefixing the bit name with !.
1925 */
1926struct debugtag
1927{
1928    char	*name;
1929    UINT32	value;
1930};
1931
1932static struct debugtag	dbg_layer[] = {
1933    {"ACPI_UTILITIES",		ACPI_UTILITIES},
1934    {"ACPI_HARDWARE",		ACPI_HARDWARE},
1935    {"ACPI_EVENTS",		ACPI_EVENTS},
1936    {"ACPI_TABLES",		ACPI_TABLES},
1937    {"ACPI_NAMESPACE",		ACPI_NAMESPACE},
1938    {"ACPI_PARSER",		ACPI_PARSER},
1939    {"ACPI_DISPATCHER",		ACPI_DISPATCHER},
1940    {"ACPI_EXECUTER",		ACPI_EXECUTER},
1941    {"ACPI_RESOURCES",		ACPI_RESOURCES},
1942    {"ACPI_CA_DEBUGGER",	ACPI_CA_DEBUGGER},
1943    {"ACPI_OS_SERVICES",	ACPI_OS_SERVICES},
1944    {"ACPI_CA_DISASSEMBLER",	ACPI_CA_DISASSEMBLER},
1945
1946    {"ACPI_BUS",		ACPI_BUS},
1947    {"ACPI_SYSTEM",		ACPI_SYSTEM},
1948    {"ACPI_POWER",		ACPI_POWER},
1949    {"ACPI_EC", 		ACPI_EC},
1950    {"ACPI_AC_ADAPTER",		ACPI_AC_ADAPTER},
1951    {"ACPI_BATTERY",		ACPI_BATTERY},
1952    {"ACPI_BUTTON",		ACPI_BUTTON},
1953    {"ACPI_PROCESSOR",		ACPI_PROCESSOR},
1954    {"ACPI_THERMAL",		ACPI_THERMAL},
1955    {"ACPI_FAN",		ACPI_FAN},
1956
1957    {"ACPI_ALL_DRIVERS",	ACPI_ALL_DRIVERS},
1958    {"ACPI_ALL_COMPONENTS",	ACPI_ALL_COMPONENTS},
1959    {NULL, 0}
1960};
1961
1962static struct debugtag dbg_level[] = {
1963    {"ACPI_LV_OK",		ACPI_LV_OK},
1964    {"ACPI_LV_INFO",		ACPI_LV_INFO},
1965    {"ACPI_LV_WARN",		ACPI_LV_WARN},
1966    {"ACPI_LV_ERROR",		ACPI_LV_ERROR},
1967    {"ACPI_LV_FATAL",		ACPI_LV_FATAL},
1968    {"ACPI_LV_DEBUG_OBJECT",	ACPI_LV_DEBUG_OBJECT},
1969    {"ACPI_LV_ALL_EXCEPTIONS",	ACPI_LV_ALL_EXCEPTIONS},
1970
1971    /* Trace verbosity level 1 [Standard Trace Level] */
1972    {"ACPI_LV_PARSE",		ACPI_LV_PARSE},
1973    {"ACPI_LV_LOAD",		ACPI_LV_LOAD},
1974    {"ACPI_LV_DISPATCH",	ACPI_LV_DISPATCH},
1975    {"ACPI_LV_EXEC",		ACPI_LV_EXEC},
1976    {"ACPI_LV_NAMES",		ACPI_LV_NAMES},
1977    {"ACPI_LV_OPREGION",	ACPI_LV_OPREGION},
1978    {"ACPI_LV_BFIELD",		ACPI_LV_BFIELD},
1979    {"ACPI_LV_TABLES",		ACPI_LV_TABLES},
1980    {"ACPI_LV_VALUES",		ACPI_LV_VALUES},
1981    {"ACPI_LV_OBJECTS",		ACPI_LV_OBJECTS},
1982    {"ACPI_LV_RESOURCES",	ACPI_LV_RESOURCES},
1983    {"ACPI_LV_USER_REQUESTS",	ACPI_LV_USER_REQUESTS},
1984    {"ACPI_LV_PACKAGE",		ACPI_LV_PACKAGE},
1985    {"ACPI_LV_INIT",		ACPI_LV_INIT},
1986    {"ACPI_LV_VERBOSITY1",	ACPI_LV_VERBOSITY1},
1987
1988    /* Trace verbosity level 2 [Function tracing and memory allocation] */
1989    {"ACPI_LV_ALLOCATIONS",	ACPI_LV_ALLOCATIONS},
1990    {"ACPI_LV_FUNCTIONS",	ACPI_LV_FUNCTIONS},
1991    {"ACPI_LV_OPTIMIZATIONS",	ACPI_LV_OPTIMIZATIONS},
1992    {"ACPI_LV_VERBOSITY2",	ACPI_LV_VERBOSITY2},
1993    {"ACPI_LV_ALL",		ACPI_LV_ALL},
1994
1995    /* Trace verbosity level 3 [Threading, I/O, and Interrupts] */
1996    {"ACPI_LV_MUTEX",		ACPI_LV_MUTEX},
1997    {"ACPI_LV_THREADS",		ACPI_LV_THREADS},
1998    {"ACPI_LV_IO",		ACPI_LV_IO},
1999    {"ACPI_LV_INTERRUPTS",	ACPI_LV_INTERRUPTS},
2000    {"ACPI_LV_VERBOSITY3",	ACPI_LV_VERBOSITY3},
2001
2002    /* Exceptionally verbose output -- also used in the global "DebugLevel"  */
2003    {"ACPI_LV_AML_DISASSEMBLE",	ACPI_LV_AML_DISASSEMBLE},
2004    {"ACPI_LV_VERBOSE_INFO",	ACPI_LV_VERBOSE_INFO},
2005    {"ACPI_LV_FULL_TABLES",	ACPI_LV_FULL_TABLES},
2006    {"ACPI_LV_EVENTS",		ACPI_LV_EVENTS},
2007    {"ACPI_LV_VERBOSE",		ACPI_LV_VERBOSE},
2008    {NULL, 0}
2009};
2010
2011static void
2012acpi_parse_debug(char *cp, struct debugtag *tag, UINT32 *flag)
2013{
2014    char	*ep;
2015    int		i, l;
2016    int		set;
2017
2018    while (*cp) {
2019	if (isspace(*cp)) {
2020	    cp++;
2021	    continue;
2022	}
2023	ep = cp;
2024	while (*ep && !isspace(*ep))
2025	    ep++;
2026	if (*cp == '!') {
2027	    set = 0;
2028	    cp++;
2029	    if (cp == ep)
2030		continue;
2031	} else {
2032	    set = 1;
2033	}
2034	l = ep - cp;
2035	for (i = 0; tag[i].name != NULL; i++) {
2036	    if (!strncmp(cp, tag[i].name, l)) {
2037		if (set) {
2038		    *flag |= tag[i].value;
2039		} else {
2040		    *flag &= ~tag[i].value;
2041		}
2042		printf("ACPI_DEBUG: set '%s'\n", tag[i].name);
2043	    }
2044	}
2045	cp = ep;
2046    }
2047}
2048
2049static void
2050acpi_set_debugging(void *junk)
2051{
2052    char	*cp;
2053
2054    if (!cold)
2055	return;
2056
2057    AcpiDbgLayer = 0;
2058    AcpiDbgLevel = 0;
2059    if ((cp = getenv("debug.acpi.layer")) != NULL) {
2060	acpi_parse_debug(cp, &dbg_layer[0], &AcpiDbgLayer);
2061	freeenv(cp);
2062    }
2063    if ((cp = getenv("debug.acpi.level")) != NULL) {
2064	acpi_parse_debug(cp, &dbg_level[0], &AcpiDbgLevel);
2065	freeenv(cp);
2066    }
2067
2068    printf("ACPI debug layer 0x%x  debug level 0x%x\n", AcpiDbgLayer, AcpiDbgLevel);
2069}
2070SYSINIT(acpi_debugging, SI_SUB_TUNABLES, SI_ORDER_ANY, acpi_set_debugging, NULL);
2071#endif
2072
2073static int
2074acpi_pm_func(u_long cmd, void *arg, ...)
2075{
2076	int	state, acpi_state;
2077	int	error;
2078	struct	acpi_softc *sc;
2079	va_list	ap;
2080
2081	error = 0;
2082	switch (cmd) {
2083	case POWER_CMD_SUSPEND:
2084		sc = (struct acpi_softc *)arg;
2085		if (sc == NULL) {
2086			error = EINVAL;
2087			goto out;
2088		}
2089
2090		va_start(ap, arg);
2091		state = va_arg(ap, int);
2092		va_end(ap);
2093
2094		switch (state) {
2095		case POWER_SLEEP_STATE_STANDBY:
2096			acpi_state = sc->acpi_standby_sx;
2097			break;
2098		case POWER_SLEEP_STATE_SUSPEND:
2099			acpi_state = sc->acpi_suspend_sx;
2100			break;
2101		case POWER_SLEEP_STATE_HIBERNATE:
2102			acpi_state = ACPI_STATE_S4;
2103			break;
2104		default:
2105			error = EINVAL;
2106			goto out;
2107		}
2108
2109		acpi_SetSleepState(sc, acpi_state);
2110		break;
2111
2112	default:
2113		error = EINVAL;
2114		goto out;
2115	}
2116
2117out:
2118	return (error);
2119}
2120
2121static void
2122acpi_pm_register(void *arg)
2123{
2124    int	error;
2125
2126    if (!cold)
2127	return;
2128
2129    if (!resource_int_value("acpi", 0, "disabled", &error) &&
2130       (error != 0))
2131		return;
2132
2133    power_pm_register(POWER_PM_TYPE_ACPI, acpi_pm_func, NULL);
2134}
2135
2136SYSINIT(power, SI_SUB_KLD, SI_ORDER_ANY, acpi_pm_register, 0);
2137
2138