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