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