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