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