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