Fri Aug 6 18:10:40 2010 UTC ()
Fix prototypes; SYSCTLFN_ARGS -> SYSCTLFN_PROTO.
(These things really only obscure the code.)


(jruoho)
diff -r1.208 -r1.209 src/sys/dev/acpi/acpi.c
diff -r1.21 -r1.22 src/sys/dev/acpi/acpi_power.c

cvs diff -r1.208 -r1.209 src/sys/dev/acpi/acpi.c (switch to unified diff)

--- src/sys/dev/acpi/acpi.c 2010/07/25 12:54:46 1.208
+++ src/sys/dev/acpi/acpi.c 2010/08/06 18:10:40 1.209
@@ -1,1193 +1,1193 @@ @@ -1,1193 +1,1193 @@
1/* $NetBSD: acpi.c,v 1.208 2010/07/25 12:54:46 pgoyette Exp $ */ 1/* $NetBSD: acpi.c,v 1.209 2010/08/06 18:10:40 jruoho Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum of By Noon Software, Inc. 8 * by Charles M. Hannum of By Noon Software, Inc.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright 2001, 2003 Wasabi Systems, Inc. 33 * Copyright 2001, 2003 Wasabi Systems, Inc.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 36 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
37 * 37 *
38 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions 39 * modification, are permitted provided that the following conditions
40 * are met: 40 * are met:
41 * 1. Redistributions of source code must retain the above copyright 41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer. 42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright 43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the 44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution. 45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software 46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement: 47 * must display the following acknowledgement:
48 * This product includes software developed for the NetBSD Project by 48 * This product includes software developed for the NetBSD Project by
49 * Wasabi Systems, Inc. 49 * Wasabi Systems, Inc.
50 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 50 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
51 * or promote products derived from this software without specific prior 51 * or promote products derived from this software without specific prior
52 * written permission. 52 * written permission.
53 * 53 *
54 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 54 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 57 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
64 * POSSIBILITY OF SUCH DAMAGE. 64 * POSSIBILITY OF SUCH DAMAGE.
65 */ 65 */
66 66
67#include <sys/cdefs.h> 67#include <sys/cdefs.h>
68__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.208 2010/07/25 12:54:46 pgoyette Exp $"); 68__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.209 2010/08/06 18:10:40 jruoho Exp $");
69 69
70#include "opt_acpi.h" 70#include "opt_acpi.h"
71#include "opt_pcifixup.h" 71#include "opt_pcifixup.h"
72 72
73#include <sys/param.h> 73#include <sys/param.h>
74#include <sys/device.h> 74#include <sys/device.h>
75#include <sys/kernel.h> 75#include <sys/kernel.h>
76#include <sys/malloc.h> 76#include <sys/malloc.h>
77#include <sys/module.h> 77#include <sys/module.h>
78#include <sys/mutex.h> 78#include <sys/mutex.h>
79#include <sys/sysctl.h> 79#include <sys/sysctl.h>
80#include <sys/systm.h> 80#include <sys/systm.h>
81#include <sys/timetc.h> 81#include <sys/timetc.h>
82 82
83#include <dev/acpi/acpireg.h> 83#include <dev/acpi/acpireg.h>
84#include <dev/acpi/acpivar.h> 84#include <dev/acpi/acpivar.h>
85#include <dev/acpi/acpi_osd.h> 85#include <dev/acpi/acpi_osd.h>
86#include <dev/acpi/acpi_pci.h> 86#include <dev/acpi/acpi_pci.h>
87#include <dev/acpi/acpi_power.h> 87#include <dev/acpi/acpi_power.h>
88#include <dev/acpi/acpi_timer.h> 88#include <dev/acpi/acpi_timer.h>
89#include <dev/acpi/acpi_wakedev.h> 89#include <dev/acpi/acpi_wakedev.h>
90 90
91#define _COMPONENT ACPI_BUS_COMPONENT 91#define _COMPONENT ACPI_BUS_COMPONENT
92ACPI_MODULE_NAME ("acpi") 92ACPI_MODULE_NAME ("acpi")
93 93
94#if defined(ACPI_PCI_FIXUP) 94#if defined(ACPI_PCI_FIXUP)
95#error The option ACPI_PCI_FIXUP has been obsoleted by PCI_INTR_FIXUP_DISABLED. Please adjust your kernel configuration file. 95#error The option ACPI_PCI_FIXUP has been obsoleted by PCI_INTR_FIXUP_DISABLED. Please adjust your kernel configuration file.
96#endif 96#endif
97 97
98#ifdef PCI_INTR_FIXUP_DISABLED 98#ifdef PCI_INTR_FIXUP_DISABLED
99#include <dev/pci/pcidevs.h> 99#include <dev/pci/pcidevs.h>
100#endif 100#endif
101 101
102MALLOC_DECLARE(M_ACPI); 102MALLOC_DECLARE(M_ACPI);
103 103
104#include <machine/acpi_machdep.h> 104#include <machine/acpi_machdep.h>
105 105
106#ifdef ACPI_DEBUGGER 106#ifdef ACPI_DEBUGGER
107#define ACPI_DBGR_INIT 0x01 107#define ACPI_DBGR_INIT 0x01
108#define ACPI_DBGR_TABLES 0x02 108#define ACPI_DBGR_TABLES 0x02
109#define ACPI_DBGR_ENABLE 0x04 109#define ACPI_DBGR_ENABLE 0x04
110#define ACPI_DBGR_PROBE 0x08 110#define ACPI_DBGR_PROBE 0x08
111#define ACPI_DBGR_RUNNING 0x10 111#define ACPI_DBGR_RUNNING 0x10
112 112
113static int acpi_dbgr = 0x00; 113static int acpi_dbgr = 0x00;
114#endif 114#endif
115 115
116/* 116/*
117 * This is a flag we set when the ACPI subsystem is active. Machine 117 * This is a flag we set when the ACPI subsystem is active. Machine
118 * dependent code may wish to skip other steps (such as attaching 118 * dependent code may wish to skip other steps (such as attaching
119 * subsystems that ACPI supercedes) when ACPI is active. 119 * subsystems that ACPI supercedes) when ACPI is active.
120 */ 120 */
121int acpi_active; 121int acpi_active;
122int acpi_force_load; 122int acpi_force_load;
123int acpi_suspended = 0; 123int acpi_suspended = 0;
124 124
125struct acpi_softc *acpi_softc; 125struct acpi_softc *acpi_softc;
126static uint64_t acpi_root_pointer; 126static uint64_t acpi_root_pointer;
127extern kmutex_t acpi_interrupt_list_mtx; 127extern kmutex_t acpi_interrupt_list_mtx;
128static ACPI_HANDLE acpi_scopes[4]; 128static ACPI_HANDLE acpi_scopes[4];
129 129
130/* 130/*
131 * This structure provides a context for the ACPI 131 * This structure provides a context for the ACPI
132 * namespace walk performed in acpi_build_tree(). 132 * namespace walk performed in acpi_build_tree().
133 */ 133 */
134struct acpi_walkcontext { 134struct acpi_walkcontext {
135 struct acpi_softc *aw_sc; 135 struct acpi_softc *aw_sc;
136 struct acpi_devnode *aw_parent; 136 struct acpi_devnode *aw_parent;
137}; 137};
138 138
139/* 139/*
140 * Ignored HIDs. 140 * Ignored HIDs.
141 */ 141 */
142static const char * const acpi_ignored_ids[] = { 142static const char * const acpi_ignored_ids[] = {
143#if defined(i386) || defined(x86_64) 143#if defined(i386) || defined(x86_64)
144 "PNP0000", /* AT interrupt controller is handled internally */ 144 "PNP0000", /* AT interrupt controller is handled internally */
145 "PNP0200", /* AT DMA controller is handled internally */ 145 "PNP0200", /* AT DMA controller is handled internally */
146 "PNP0A??", /* PCI Busses are handled internally */ 146 "PNP0A??", /* PCI Busses are handled internally */
147 "PNP0B00", /* AT RTC is handled internally */ 147 "PNP0B00", /* AT RTC is handled internally */
148 "PNP0C0B", /* No need for "ACPI fan" driver */ 148 "PNP0C0B", /* No need for "ACPI fan" driver */
149 "PNP0C0F", /* ACPI PCI link devices are handled internally */ 149 "PNP0C0F", /* ACPI PCI link devices are handled internally */
150 "IFX0102", /* No driver for Infineon TPM */ 150 "IFX0102", /* No driver for Infineon TPM */
151 "INT0800", /* No driver for Intel Firmware Hub device */ 151 "INT0800", /* No driver for Intel Firmware Hub device */
152#endif 152#endif
153#if defined(x86_64) 153#if defined(x86_64)
154 "PNP0C04", /* FPU is handled internally */ 154 "PNP0C04", /* FPU is handled internally */
155#endif 155#endif
156 NULL 156 NULL
157}; 157};
158 158
159static int acpi_match(device_t, cfdata_t, void *); 159static int acpi_match(device_t, cfdata_t, void *);
160static int acpi_submatch(device_t, cfdata_t, const int *, void *); 160static int acpi_submatch(device_t, cfdata_t, const int *, void *);
161static void acpi_attach(device_t, device_t, void *); 161static void acpi_attach(device_t, device_t, void *);
162static int acpi_detach(device_t, int); 162static int acpi_detach(device_t, int);
163static void acpi_childdet(device_t, device_t); 163static void acpi_childdet(device_t, device_t);
164static bool acpi_suspend(device_t, const pmf_qual_t *); 164static bool acpi_suspend(device_t, const pmf_qual_t *);
165static bool acpi_resume(device_t, const pmf_qual_t *); 165static bool acpi_resume(device_t, const pmf_qual_t *);
166 166
167static void acpi_build_tree(struct acpi_softc *); 167static void acpi_build_tree(struct acpi_softc *);
168static ACPI_STATUS acpi_make_devnode(ACPI_HANDLE, uint32_t, 168static ACPI_STATUS acpi_make_devnode(ACPI_HANDLE, uint32_t,
169 void *, void **); 169 void *, void **);
170static ACPI_STATUS acpi_make_devnode_post(ACPI_HANDLE, uint32_t, 170static ACPI_STATUS acpi_make_devnode_post(ACPI_HANDLE, uint32_t,
171 void *, void **); 171 void *, void **);
172 172
173#ifdef ACPI_ACTIVATE_DEV 173#ifdef ACPI_ACTIVATE_DEV
174static void acpi_activate_device(ACPI_HANDLE, ACPI_DEVICE_INFO **); 174static void acpi_activate_device(ACPI_HANDLE, ACPI_DEVICE_INFO **);
175static ACPI_STATUS acpi_allocate_resources(ACPI_HANDLE); 175static ACPI_STATUS acpi_allocate_resources(ACPI_HANDLE);
176#endif 176#endif
177 177
178static int acpi_rescan(device_t, const char *, const int *); 178static int acpi_rescan(device_t, const char *, const int *);
179static void acpi_rescan_nodes(struct acpi_softc *); 179static void acpi_rescan_nodes(struct acpi_softc *);
180static void acpi_rescan_capabilities(struct acpi_softc *); 180static void acpi_rescan_capabilities(struct acpi_softc *);
181static int acpi_print(void *aux, const char *); 181static int acpi_print(void *aux, const char *);
182 182
183static void acpi_notify_handler(ACPI_HANDLE, uint32_t, void *); 183static void acpi_notify_handler(ACPI_HANDLE, uint32_t, void *);
184 184
185static void acpi_register_fixed_button(struct acpi_softc *, int); 185static void acpi_register_fixed_button(struct acpi_softc *, int);
186static void acpi_deregister_fixed_button(struct acpi_softc *, int); 186static void acpi_deregister_fixed_button(struct acpi_softc *, int);
187static uint32_t acpi_fixed_button_handler(void *); 187static uint32_t acpi_fixed_button_handler(void *);
188static void acpi_fixed_button_pressed(void *); 188static void acpi_fixed_button_pressed(void *);
189 189
190static void acpi_sleep_init(struct acpi_softc *); 190static void acpi_sleep_init(struct acpi_softc *);
191 191
192static int sysctl_hw_acpi_fixedstats(SYSCTLFN_ARGS); 192static int sysctl_hw_acpi_fixedstats(SYSCTLFN_PROTO);
193static int sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS); 193static int sysctl_hw_acpi_sleepstate(SYSCTLFN_PROTO);
194static int sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS); 194static int sysctl_hw_acpi_sleepstates(SYSCTLFN_PROTO);
195 195
196static bool acpi_is_scope(struct acpi_devnode *); 196static bool acpi_is_scope(struct acpi_devnode *);
197static ACPI_TABLE_HEADER *acpi_map_rsdt(void); 197static ACPI_TABLE_HEADER *acpi_map_rsdt(void);
198static void acpi_unmap_rsdt(ACPI_TABLE_HEADER *); 198static void acpi_unmap_rsdt(ACPI_TABLE_HEADER *);
199 199
200extern struct cfdriver acpi_cd; 200extern struct cfdriver acpi_cd;
201 201
202/* Handle routine vectors and loading for acpiverbose module */ 202/* Handle routine vectors and loading for acpiverbose module */
203void acpi_null(void); 203void acpi_null(void);
204 204
205void acpi_print_devnodes_stub(struct acpi_softc *); 205void acpi_print_devnodes_stub(struct acpi_softc *);
206void acpi_print_tree_stub(struct acpi_devnode *, uint32_t); 206void acpi_print_tree_stub(struct acpi_devnode *, uint32_t);
207void acpi_print_dev_stub(const char *); 207void acpi_print_dev_stub(const char *);
208void acpi_wmidump_stub(void *); 208void acpi_wmidump_stub(void *);
209 209
210void (*acpi_print_devnodes)(struct acpi_softc *) = acpi_print_devnodes_stub; 210void (*acpi_print_devnodes)(struct acpi_softc *) = acpi_print_devnodes_stub;
211void (*acpi_print_tree)(struct acpi_devnode *, uint32_t) = acpi_print_tree_stub; 211void (*acpi_print_tree)(struct acpi_devnode *, uint32_t) = acpi_print_tree_stub;
212void (*acpi_print_dev)(const char *) = acpi_print_dev_stub; 212void (*acpi_print_dev)(const char *) = acpi_print_dev_stub;
213void (*acpi_wmidump)(void *) = acpi_wmidump_stub; 213void (*acpi_wmidump)(void *) = acpi_wmidump_stub;
214 214
215int acpi_verbose_loaded = 0; 215int acpi_verbose_loaded = 0;
216 216
217/* 217/*
218 * Support for ACPIVERBOSE. 218 * Support for ACPIVERBOSE.
219 */ 219 */
220void 220void
221acpi_null(void) 221acpi_null(void)
222{ 222{
223 /* Nothing to do. */ 223 /* Nothing to do. */
224} 224}
225 225
226void 226void
227acpi_load_verbose(void) 227acpi_load_verbose(void)
228{ 228{
229 if (acpi_verbose_loaded == 0) { 229 if (acpi_verbose_loaded == 0) {
230 mutex_enter(&module_lock); 230 mutex_enter(&module_lock);
231 module_autoload("acpiverbose", MODULE_CLASS_MISC); 231 module_autoload("acpiverbose", MODULE_CLASS_MISC);
232 mutex_exit(&module_lock); 232 mutex_exit(&module_lock);
233 } 233 }
234} 234}
235 235
236void 236void
237acpi_print_devnodes_stub(struct acpi_softc *sc) 237acpi_print_devnodes_stub(struct acpi_softc *sc)
238{ 238{
239 acpi_load_verbose(); 239 acpi_load_verbose();
240 if (acpi_verbose_loaded) 240 if (acpi_verbose_loaded)
241 acpi_print_devnodes(sc); 241 acpi_print_devnodes(sc);
242} 242}
243 243
244void 244void
245acpi_print_tree_stub(struct acpi_devnode *ad, uint32_t level) 245acpi_print_tree_stub(struct acpi_devnode *ad, uint32_t level)
246{ 246{
247 acpi_load_verbose(); 247 acpi_load_verbose();
248 if (acpi_verbose_loaded) 248 if (acpi_verbose_loaded)
249 acpi_print_tree(ad, level); 249 acpi_print_tree(ad, level);
250} 250}
251 251
252void 252void
253acpi_print_dev_stub(const char *pnpstr) 253acpi_print_dev_stub(const char *pnpstr)
254{ 254{
255 acpi_load_verbose(); 255 acpi_load_verbose();
256 if (acpi_verbose_loaded) 256 if (acpi_verbose_loaded)
257 acpi_print_dev(pnpstr); 257 acpi_print_dev(pnpstr);
258} 258}
259 259
260void 260void
261acpi_wmidump_stub(void *arg) 261acpi_wmidump_stub(void *arg)
262{ 262{
263 acpi_load_verbose(); 263 acpi_load_verbose();
264 if (acpi_verbose_loaded) 264 if (acpi_verbose_loaded)
265 acpi_wmidump(arg); 265 acpi_wmidump(arg);
266} 266}
267 267
268CFATTACH_DECL2_NEW(acpi, sizeof(struct acpi_softc), 268CFATTACH_DECL2_NEW(acpi, sizeof(struct acpi_softc),
269 acpi_match, acpi_attach, acpi_detach, NULL, acpi_rescan, acpi_childdet); 269 acpi_match, acpi_attach, acpi_detach, NULL, acpi_rescan, acpi_childdet);
270 270
271/* 271/*
272 * Probe for ACPI support. 272 * Probe for ACPI support.
273 * 273 *
274 * This is called by the machine-dependent ACPI front-end. 274 * This is called by the machine-dependent ACPI front-end.
275 * Note: this is not an autoconfiguration interface function. 275 * Note: this is not an autoconfiguration interface function.
276 */ 276 */
277int 277int
278acpi_probe(void) 278acpi_probe(void)
279{ 279{
280 ACPI_TABLE_HEADER *rsdt; 280 ACPI_TABLE_HEADER *rsdt;
281 const char *func; 281 const char *func;
282 static int once; 282 static int once;
283 bool initialized; 283 bool initialized;
284 ACPI_STATUS rv; 284 ACPI_STATUS rv;
285 285
286 if (once != 0) 286 if (once != 0)
287 panic("%s: already probed", __func__); 287 panic("%s: already probed", __func__);
288 288
289 once = 1; 289 once = 1;
290 func = NULL; 290 func = NULL;
291 initialized = false; 291 initialized = false;
292 292
293 mutex_init(&acpi_interrupt_list_mtx, MUTEX_DEFAULT, IPL_NONE); 293 mutex_init(&acpi_interrupt_list_mtx, MUTEX_DEFAULT, IPL_NONE);
294 294
295 /* 295 /*
296 * Start up ACPICA. 296 * Start up ACPICA.
297 */ 297 */
298#ifdef ACPI_DEBUGGER 298#ifdef ACPI_DEBUGGER
299 if (acpi_dbgr & ACPI_DBGR_INIT) 299 if (acpi_dbgr & ACPI_DBGR_INIT)
300 acpi_osd_debugger(); 300 acpi_osd_debugger();
301#endif 301#endif
302 302
303 CTASSERT(TRUE == true); 303 CTASSERT(TRUE == true);
304 CTASSERT(FALSE == false); 304 CTASSERT(FALSE == false);
305 305
306 AcpiGbl_AllMethodsSerialized = false; 306 AcpiGbl_AllMethodsSerialized = false;
307 AcpiGbl_EnableInterpreterSlack = true; 307 AcpiGbl_EnableInterpreterSlack = true;
308 308
309 rv = AcpiInitializeSubsystem(); 309 rv = AcpiInitializeSubsystem();
310 310
311 if (ACPI_SUCCESS(rv)) 311 if (ACPI_SUCCESS(rv))
312 initialized = true; 312 initialized = true;
313 else { 313 else {
314 func = "AcpiInitializeSubsystem()"; 314 func = "AcpiInitializeSubsystem()";
315 goto fail; 315 goto fail;
316 } 316 }
317 317
318 /* 318 /*
319 * Allocate space for RSDT/XSDT and DSDT, 319 * Allocate space for RSDT/XSDT and DSDT,
320 * but allow resizing if more tables exist. 320 * but allow resizing if more tables exist.
321 */ 321 */
322 rv = AcpiInitializeTables(NULL, 2, true); 322 rv = AcpiInitializeTables(NULL, 2, true);
323 323
324 if (ACPI_FAILURE(rv)) { 324 if (ACPI_FAILURE(rv)) {
325 func = "AcpiInitializeTables()"; 325 func = "AcpiInitializeTables()";
326 goto fail; 326 goto fail;
327 } 327 }
328 328
329#ifdef ACPI_DEBUGGER 329#ifdef ACPI_DEBUGGER
330 if (acpi_dbgr & ACPI_DBGR_TABLES) 330 if (acpi_dbgr & ACPI_DBGR_TABLES)
331 acpi_osd_debugger(); 331 acpi_osd_debugger();
332#endif 332#endif
333 333
334 rv = AcpiLoadTables(); 334 rv = AcpiLoadTables();
335 335
336 if (ACPI_FAILURE(rv)) { 336 if (ACPI_FAILURE(rv)) {
337 func = "AcpiLoadTables()"; 337 func = "AcpiLoadTables()";
338 goto fail; 338 goto fail;
339 } 339 }
340 340
341 rsdt = acpi_map_rsdt(); 341 rsdt = acpi_map_rsdt();
342 342
343 if (rsdt == NULL) { 343 if (rsdt == NULL) {
344 func = "acpi_map_rsdt()"; 344 func = "acpi_map_rsdt()";
345 rv = AE_ERROR; 345 rv = AE_ERROR;
346 goto fail; 346 goto fail;
347 } 347 }
348 348
349 if (acpi_force_load == 0 && (acpi_find_quirks() & ACPI_QUIRK_BROKEN)) { 349 if (acpi_force_load == 0 && (acpi_find_quirks() & ACPI_QUIRK_BROKEN)) {
350 aprint_normal("ACPI: BIOS is listed as broken:\n"); 350 aprint_normal("ACPI: BIOS is listed as broken:\n");
351 aprint_normal("ACPI: X/RSDT: OemId <%6.6s,%8.8s,%08x>, " 351 aprint_normal("ACPI: X/RSDT: OemId <%6.6s,%8.8s,%08x>, "
352 "AslId <%4.4s,%08x>\n", 352 "AslId <%4.4s,%08x>\n",
353 rsdt->OemId, rsdt->OemTableId, 353 rsdt->OemId, rsdt->OemTableId,
354 rsdt->OemRevision, 354 rsdt->OemRevision,
355 rsdt->AslCompilerId, 355 rsdt->AslCompilerId,
356 rsdt->AslCompilerRevision); 356 rsdt->AslCompilerRevision);
357 aprint_normal("ACPI: Not used. Set acpi_force_load to use.\n"); 357 aprint_normal("ACPI: Not used. Set acpi_force_load to use.\n");
358 acpi_unmap_rsdt(rsdt); 358 acpi_unmap_rsdt(rsdt);
359 AcpiTerminate(); 359 AcpiTerminate();
360 return 0; 360 return 0;
361 } 361 }
362 362
363 acpi_unmap_rsdt(rsdt); 363 acpi_unmap_rsdt(rsdt);
364 364
365 rv = AcpiEnableSubsystem(~(ACPI_NO_HARDWARE_INIT|ACPI_NO_ACPI_ENABLE)); 365 rv = AcpiEnableSubsystem(~(ACPI_NO_HARDWARE_INIT|ACPI_NO_ACPI_ENABLE));
366 366
367 if (ACPI_FAILURE(rv)) { 367 if (ACPI_FAILURE(rv)) {
368 func = "AcpiEnableSubsystem()"; 368 func = "AcpiEnableSubsystem()";
369 goto fail; 369 goto fail;
370 } 370 }
371 371
372 /* 372 /*
373 * Looks like we have ACPI! 373 * Looks like we have ACPI!
374 */ 374 */
375 return 1; 375 return 1;
376 376
377fail: 377fail:
378 KASSERT(rv != AE_OK); 378 KASSERT(rv != AE_OK);
379 KASSERT(func != NULL); 379 KASSERT(func != NULL);
380 380
381 aprint_error("%s: failed to probe ACPI: %s\n", 381 aprint_error("%s: failed to probe ACPI: %s\n",
382 func, AcpiFormatException(rv)); 382 func, AcpiFormatException(rv));
383 383
384 if (initialized != false) 384 if (initialized != false)
385 (void)AcpiTerminate(); 385 (void)AcpiTerminate();
386 386
387 return 0; 387 return 0;
388} 388}
389 389
390int 390int
391acpi_check(device_t parent, const char *ifattr) 391acpi_check(device_t parent, const char *ifattr)
392{ 392{
393 return (config_search_ia(acpi_submatch, parent, ifattr, NULL) != NULL); 393 return (config_search_ia(acpi_submatch, parent, ifattr, NULL) != NULL);
394} 394}
395 395
396/* 396/*
397 * Autoconfiguration. 397 * Autoconfiguration.
398 */ 398 */
399static int 399static int
400acpi_match(device_t parent, cfdata_t match, void *aux) 400acpi_match(device_t parent, cfdata_t match, void *aux)
401{ 401{
402 /* 402 /*
403 * XXX: Nada; MD code has called acpi_probe(). 403 * XXX: Nada; MD code has called acpi_probe().
404 */ 404 */
405 return 1; 405 return 1;
406} 406}
407 407
408static int 408static int
409acpi_submatch(device_t parent, cfdata_t cf, const int *locs, void *aux) 409acpi_submatch(device_t parent, cfdata_t cf, const int *locs, void *aux)
410{ 410{
411 struct cfattach *ca; 411 struct cfattach *ca;
412 412
413 ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname); 413 ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname);
414 414
415 return (ca == &acpi_ca); 415 return (ca == &acpi_ca);
416} 416}
417 417
418static void 418static void
419acpi_attach(device_t parent, device_t self, void *aux) 419acpi_attach(device_t parent, device_t self, void *aux)
420{ 420{
421 struct acpi_softc *sc = device_private(self); 421 struct acpi_softc *sc = device_private(self);
422 struct acpibus_attach_args *aa = aux; 422 struct acpibus_attach_args *aa = aux;
423 ACPI_TABLE_HEADER *rsdt; 423 ACPI_TABLE_HEADER *rsdt;
424 ACPI_STATUS rv; 424 ACPI_STATUS rv;
425 425
426 aprint_naive("\n"); 426 aprint_naive("\n");
427 aprint_normal(": Intel ACPICA %08x\n", ACPI_CA_VERSION); 427 aprint_normal(": Intel ACPICA %08x\n", ACPI_CA_VERSION);
428 428
429 if (acpi_softc != NULL) 429 if (acpi_softc != NULL)
430 panic("%s: already attached", __func__); 430 panic("%s: already attached", __func__);
431 431
432 rsdt = acpi_map_rsdt(); 432 rsdt = acpi_map_rsdt();
433 433
434 if (rsdt == NULL) 434 if (rsdt == NULL)
435 aprint_error_dev(self, "X/RSDT: Not found\n"); 435 aprint_error_dev(self, "X/RSDT: Not found\n");
436 else { 436 else {
437 aprint_verbose_dev(self, 437 aprint_verbose_dev(self,
438 "X/RSDT: OemId <%6.6s,%8.8s,%08x>, AslId <%4.4s,%08x>\n", 438 "X/RSDT: OemId <%6.6s,%8.8s,%08x>, AslId <%4.4s,%08x>\n",
439 rsdt->OemId, rsdt->OemTableId, 439 rsdt->OemId, rsdt->OemTableId,
440 rsdt->OemRevision, 440 rsdt->OemRevision,
441 rsdt->AslCompilerId, rsdt->AslCompilerRevision); 441 rsdt->AslCompilerId, rsdt->AslCompilerRevision);
442 } 442 }
443 443
444 acpi_unmap_rsdt(rsdt); 444 acpi_unmap_rsdt(rsdt);
445 445
446 sc->sc_dev = self; 446 sc->sc_dev = self;
447 sc->sc_root = NULL; 447 sc->sc_root = NULL;
448 448
449 sc->sc_sleepstate = ACPI_STATE_S0; 449 sc->sc_sleepstate = ACPI_STATE_S0;
450 sc->sc_quirks = acpi_find_quirks(); 450 sc->sc_quirks = acpi_find_quirks();
451 451
452 sysmon_power_settype("acpi"); 452 sysmon_power_settype("acpi");
453 453
454 sc->sc_iot = aa->aa_iot; 454 sc->sc_iot = aa->aa_iot;
455 sc->sc_memt = aa->aa_memt; 455 sc->sc_memt = aa->aa_memt;
456 sc->sc_pc = aa->aa_pc; 456 sc->sc_pc = aa->aa_pc;
457 sc->sc_pciflags = aa->aa_pciflags; 457 sc->sc_pciflags = aa->aa_pciflags;
458 sc->sc_ic = aa->aa_ic; 458 sc->sc_ic = aa->aa_ic;
459 459
460 SIMPLEQ_INIT(&sc->ad_head); 460 SIMPLEQ_INIT(&sc->ad_head);
461 461
462 acpi_softc = sc; 462 acpi_softc = sc;
463 463
464 if (pmf_device_register(self, acpi_suspend, acpi_resume) != true) 464 if (pmf_device_register(self, acpi_suspend, acpi_resume) != true)
465 aprint_error_dev(self, "couldn't establish power handler\n"); 465 aprint_error_dev(self, "couldn't establish power handler\n");
466 466
467 /* 467 /*
468 * Bring ACPI on-line. 468 * Bring ACPI on-line.
469 */ 469 */
470#ifdef ACPI_DEBUGGER 470#ifdef ACPI_DEBUGGER
471 if (acpi_dbgr & ACPI_DBGR_ENABLE) 471 if (acpi_dbgr & ACPI_DBGR_ENABLE)
472 acpi_osd_debugger(); 472 acpi_osd_debugger();
473#endif 473#endif
474 474
475#define ACPI_ENABLE_PHASE1 \ 475#define ACPI_ENABLE_PHASE1 \
476 (ACPI_NO_HANDLER_INIT | ACPI_NO_EVENT_INIT) 476 (ACPI_NO_HANDLER_INIT | ACPI_NO_EVENT_INIT)
477#define ACPI_ENABLE_PHASE2 \ 477#define ACPI_ENABLE_PHASE2 \
478 (ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE | \ 478 (ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE | \
479 ACPI_NO_ADDRESS_SPACE_INIT) 479 ACPI_NO_ADDRESS_SPACE_INIT)
480 480
481 rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE1); 481 rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE1);
482 482
483 if (ACPI_FAILURE(rv)) 483 if (ACPI_FAILURE(rv))
484 goto fail; 484 goto fail;
485 485
486 acpi_md_callback(); 486 acpi_md_callback();
487 487
488 rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE2); 488 rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE2);
489 489
490 if (ACPI_FAILURE(rv)) 490 if (ACPI_FAILURE(rv))
491 goto fail; 491 goto fail;
492 492
493 /* 493 /*
494 * Early EC handler initialization if ECDT table is available. 494 * Early EC handler initialization if ECDT table is available.
495 */ 495 */
496 config_found_ia(self, "acpiecdtbus", aa, NULL); 496 config_found_ia(self, "acpiecdtbus", aa, NULL);
497 497
498 rv = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION); 498 rv = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
499 499
500 if (ACPI_FAILURE(rv)) 500 if (ACPI_FAILURE(rv))
501 goto fail; 501 goto fail;
502 502
503 /* 503 /*
504 * Install global notify handlers. 504 * Install global notify handlers.
505 */ 505 */
506 rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT, 506 rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT,
507 ACPI_SYSTEM_NOTIFY, acpi_notify_handler, NULL); 507 ACPI_SYSTEM_NOTIFY, acpi_notify_handler, NULL);
508 508
509 if (ACPI_FAILURE(rv)) 509 if (ACPI_FAILURE(rv))
510 goto fail; 510 goto fail;
511 511
512 rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT, 512 rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT,
513 ACPI_DEVICE_NOTIFY, acpi_notify_handler, NULL); 513 ACPI_DEVICE_NOTIFY, acpi_notify_handler, NULL);
514 514
515 if (ACPI_FAILURE(rv)) 515 if (ACPI_FAILURE(rv))
516 goto fail; 516 goto fail;
517 517
518 acpi_active = 1; 518 acpi_active = 1;
519 519
520 /* Show SCI interrupt. */ 520 /* Show SCI interrupt. */
521 aprint_verbose_dev(self, "SCI interrupting at int %u\n", 521 aprint_verbose_dev(self, "SCI interrupting at int %u\n",
522 AcpiGbl_FADT.SciInterrupt); 522 AcpiGbl_FADT.SciInterrupt);
523 523
524 /* 524 /*
525 * Install fixed-event handlers. 525 * Install fixed-event handlers.
526 */ 526 */
527 acpi_register_fixed_button(sc, ACPI_EVENT_POWER_BUTTON); 527 acpi_register_fixed_button(sc, ACPI_EVENT_POWER_BUTTON);
528 acpi_register_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON); 528 acpi_register_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON);
529 529
530 acpitimer_init(sc); 530 acpitimer_init(sc);
531 531
532#ifdef ACPI_DEBUGGER 532#ifdef ACPI_DEBUGGER
533 if (acpi_dbgr & ACPI_DBGR_PROBE) 533 if (acpi_dbgr & ACPI_DBGR_PROBE)
534 acpi_osd_debugger(); 534 acpi_osd_debugger();
535#endif 535#endif
536 536
537 /* 537 /*
538 * Scan the namespace and build our device tree. 538 * Scan the namespace and build our device tree.
539 */ 539 */
540 acpi_build_tree(sc); 540 acpi_build_tree(sc);
541 acpi_sleep_init(sc); 541 acpi_sleep_init(sc);
542 542
543#ifdef ACPI_DEBUGGER 543#ifdef ACPI_DEBUGGER
544 if (acpi_dbgr & ACPI_DBGR_RUNNING) 544 if (acpi_dbgr & ACPI_DBGR_RUNNING)
545 acpi_osd_debugger(); 545 acpi_osd_debugger();
546#endif 546#endif
547 547
548#ifdef ACPI_DEBUG 548#ifdef ACPI_DEBUG
549 acpi_debug_init(); 549 acpi_debug_init();
550#endif 550#endif
551 551
552 return; 552 return;
553 553
554fail: 554fail:
555 KASSERT(rv != AE_OK); 555 KASSERT(rv != AE_OK);
556 556
557 aprint_error("%s: failed to initialize ACPI: %s\n", 557 aprint_error("%s: failed to initialize ACPI: %s\n",
558 __func__, AcpiFormatException(rv)); 558 __func__, AcpiFormatException(rv));
559} 559}
560 560
561/* 561/*
562 * XXX: This is incomplete. 562 * XXX: This is incomplete.
563 */ 563 */
564static int 564static int
565acpi_detach(device_t self, int flags) 565acpi_detach(device_t self, int flags)
566{ 566{
567 struct acpi_softc *sc = device_private(self); 567 struct acpi_softc *sc = device_private(self);
568 ACPI_STATUS rv; 568 ACPI_STATUS rv;
569 int rc; 569 int rc;
570 570
571 rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT, 571 rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT,
572 ACPI_SYSTEM_NOTIFY, acpi_notify_handler); 572 ACPI_SYSTEM_NOTIFY, acpi_notify_handler);
573 573
574 if (ACPI_FAILURE(rv)) 574 if (ACPI_FAILURE(rv))
575 return EBUSY; 575 return EBUSY;
576 576
577 rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT, 577 rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT,
578 ACPI_DEVICE_NOTIFY, acpi_notify_handler); 578 ACPI_DEVICE_NOTIFY, acpi_notify_handler);
579 579
580 if (ACPI_FAILURE(rv)) 580 if (ACPI_FAILURE(rv))
581 return EBUSY; 581 return EBUSY;
582 582
583 if ((rc = config_detach_children(self, flags)) != 0) 583 if ((rc = config_detach_children(self, flags)) != 0)
584 return rc; 584 return rc;
585 585
586 if ((rc = acpitimer_detach()) != 0) 586 if ((rc = acpitimer_detach()) != 0)
587 return rc; 587 return rc;
588 588
589 acpi_deregister_fixed_button(sc, ACPI_EVENT_POWER_BUTTON); 589 acpi_deregister_fixed_button(sc, ACPI_EVENT_POWER_BUTTON);
590 acpi_deregister_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON); 590 acpi_deregister_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON);
591 591
592 pmf_device_deregister(self); 592 pmf_device_deregister(self);
593 593
594 acpi_softc = NULL; 594 acpi_softc = NULL;
595 595
596 return 0; 596 return 0;
597} 597}
598 598
599/* 599/*
600 * XXX: Need to reclaim any resources? Yes. 600 * XXX: Need to reclaim any resources? Yes.
601 */ 601 */
602static void 602static void
603acpi_childdet(device_t self, device_t child) 603acpi_childdet(device_t self, device_t child)
604{ 604{
605 struct acpi_softc *sc = device_private(self); 605 struct acpi_softc *sc = device_private(self);
606 struct acpi_devnode *ad; 606 struct acpi_devnode *ad;
607 607
608 if (sc->sc_apmbus == child) 608 if (sc->sc_apmbus == child)
609 sc->sc_apmbus = NULL; 609 sc->sc_apmbus = NULL;
610 610
611 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 611 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
612 612
613 if (ad->ad_device == child) 613 if (ad->ad_device == child)
614 ad->ad_device = NULL; 614 ad->ad_device = NULL;
615 } 615 }
616} 616}
617 617
618static bool 618static bool
619acpi_suspend(device_t dv, const pmf_qual_t *qual) 619acpi_suspend(device_t dv, const pmf_qual_t *qual)
620{ 620{
621 621
622 acpi_suspended = 1; 622 acpi_suspended = 1;
623 623
624 return true; 624 return true;
625} 625}
626 626
627static bool 627static bool
628acpi_resume(device_t dv, const pmf_qual_t *qual) 628acpi_resume(device_t dv, const pmf_qual_t *qual)
629{ 629{
630 630
631 acpi_suspended = 0; 631 acpi_suspended = 0;
632 632
633 return true; 633 return true;
634} 634}
635 635
636/* 636/*
637 * Namespace scan. 637 * Namespace scan.
638 */ 638 */
639static void 639static void
640acpi_build_tree(struct acpi_softc *sc) 640acpi_build_tree(struct acpi_softc *sc)
641{ 641{
642 struct acpi_walkcontext awc; 642 struct acpi_walkcontext awc;
643 643
644 /* 644 /*
645 * Get the root scope handles. 645 * Get the root scope handles.
646 */ 646 */
647 KASSERT(__arraycount(acpi_scopes) == 4); 647 KASSERT(__arraycount(acpi_scopes) == 4);
648 648
649 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_PR_", &acpi_scopes[0]); 649 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_PR_", &acpi_scopes[0]);
650 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &acpi_scopes[1]); 650 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &acpi_scopes[1]);
651 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SI_", &acpi_scopes[2]); 651 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SI_", &acpi_scopes[2]);
652 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_TZ_", &acpi_scopes[3]); 652 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_TZ_", &acpi_scopes[3]);
653 653
654 /* 654 /*
655 * Make the root node. 655 * Make the root node.
656 */ 656 */
657 awc.aw_sc = sc; 657 awc.aw_sc = sc;
658 awc.aw_parent = NULL; 658 awc.aw_parent = NULL;
659 659
660 (void)acpi_make_devnode(ACPI_ROOT_OBJECT, 0, &awc, NULL); 660 (void)acpi_make_devnode(ACPI_ROOT_OBJECT, 0, &awc, NULL);
661 661
662 KASSERT(sc->sc_root == NULL); 662 KASSERT(sc->sc_root == NULL);
663 KASSERT(awc.aw_parent != NULL); 663 KASSERT(awc.aw_parent != NULL);
664 664
665 sc->sc_root = awc.aw_parent; 665 sc->sc_root = awc.aw_parent;
666 666
667 /* 667 /*
668 * Build the internal namespace. 668 * Build the internal namespace.
669 */ 669 */
670 (void)AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, UINT32_MAX, 670 (void)AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, UINT32_MAX,
671 acpi_make_devnode, acpi_make_devnode_post, &awc, NULL); 671 acpi_make_devnode, acpi_make_devnode_post, &awc, NULL);
672 672
673 /* 673 /*
674 * Scan the internal namespace. 674 * Scan the internal namespace.
675 */ 675 */
676 (void)acpi_rescan(sc->sc_dev, NULL, NULL); 676 (void)acpi_rescan(sc->sc_dev, NULL, NULL);
677 677
678 acpi_rescan_capabilities(sc); 678 acpi_rescan_capabilities(sc);
679 679
680 (void)acpi_pcidev_scan(sc->sc_root); 680 (void)acpi_pcidev_scan(sc->sc_root);
681 681
682 acpi_print_devnodes(sc); 682 acpi_print_devnodes(sc);
683 acpi_print_tree(sc->sc_root, 0); 683 acpi_print_tree(sc->sc_root, 0);
684} 684}
685 685
686static ACPI_STATUS 686static ACPI_STATUS
687acpi_make_devnode(ACPI_HANDLE handle, uint32_t level, 687acpi_make_devnode(ACPI_HANDLE handle, uint32_t level,
688 void *context, void **status) 688 void *context, void **status)
689{ 689{
690 struct acpi_walkcontext *awc = context; 690 struct acpi_walkcontext *awc = context;
691 struct acpi_softc *sc = awc->aw_sc; 691 struct acpi_softc *sc = awc->aw_sc;
692 struct acpi_devnode *ad; 692 struct acpi_devnode *ad;
693 ACPI_DEVICE_INFO *devinfo; 693 ACPI_DEVICE_INFO *devinfo;
694 ACPI_OBJECT_TYPE type; 694 ACPI_OBJECT_TYPE type;
695 ACPI_NAME_UNION *anu; 695 ACPI_NAME_UNION *anu;
696 ACPI_STATUS rv; 696 ACPI_STATUS rv;
697 int clear, i; 697 int clear, i;
698 698
699 rv = AcpiGetObjectInfo(handle, &devinfo); 699 rv = AcpiGetObjectInfo(handle, &devinfo);
700 700
701 if (ACPI_FAILURE(rv)) 701 if (ACPI_FAILURE(rv))
702 return AE_OK; /* Do not terminate the walk. */ 702 return AE_OK; /* Do not terminate the walk. */
703 703
704 type = devinfo->Type; 704 type = devinfo->Type;
705 705
706 switch (type) { 706 switch (type) {
707 707
708 case ACPI_TYPE_DEVICE: 708 case ACPI_TYPE_DEVICE:
709 709
710#ifdef ACPI_ACTIVATE_DEV 710#ifdef ACPI_ACTIVATE_DEV
711 acpi_activate_device(handle, &devinfo); 711 acpi_activate_device(handle, &devinfo);
712#endif 712#endif
713 713
714 case ACPI_TYPE_PROCESSOR: 714 case ACPI_TYPE_PROCESSOR:
715 case ACPI_TYPE_THERMAL: 715 case ACPI_TYPE_THERMAL:
716 case ACPI_TYPE_POWER: 716 case ACPI_TYPE_POWER:
717 717
718 ad = malloc(sizeof(*ad), M_ACPI, M_NOWAIT | M_ZERO); 718 ad = malloc(sizeof(*ad), M_ACPI, M_NOWAIT | M_ZERO);
719 719
720 if (ad == NULL) 720 if (ad == NULL)
721 return AE_NO_MEMORY; 721 return AE_NO_MEMORY;
722 722
723 ad->ad_device = NULL; 723 ad->ad_device = NULL;
724 ad->ad_notify = NULL; 724 ad->ad_notify = NULL;
725 ad->ad_pciinfo = NULL; 725 ad->ad_pciinfo = NULL;
726 726
727 ad->ad_type = type; 727 ad->ad_type = type;
728 ad->ad_handle = handle; 728 ad->ad_handle = handle;
729 ad->ad_devinfo = devinfo; 729 ad->ad_devinfo = devinfo;
730 730
731 ad->ad_root = sc->sc_dev; 731 ad->ad_root = sc->sc_dev;
732 ad->ad_parent = awc->aw_parent; 732 ad->ad_parent = awc->aw_parent;
733 733
734 anu = (ACPI_NAME_UNION *)&devinfo->Name; 734 anu = (ACPI_NAME_UNION *)&devinfo->Name;
735 ad->ad_name[4] = '\0'; 735 ad->ad_name[4] = '\0';
736 736
737 for (i = 3, clear = 0; i >= 0; i--) { 737 for (i = 3, clear = 0; i >= 0; i--) {
738 738
739 if (clear == 0 && anu->Ascii[i] == '_') 739 if (clear == 0 && anu->Ascii[i] == '_')
740 ad->ad_name[i] = '\0'; 740 ad->ad_name[i] = '\0';
741 else { 741 else {
742 ad->ad_name[i] = anu->Ascii[i]; 742 ad->ad_name[i] = anu->Ascii[i];
743 clear = 1; 743 clear = 1;
744 } 744 }
745 } 745 }
746 746
747 if (ad->ad_name[0] == '\0') 747 if (ad->ad_name[0] == '\0')
748 ad->ad_name[0] = '_'; 748 ad->ad_name[0] = '_';
749 749
750 SIMPLEQ_INIT(&ad->ad_child_head); 750 SIMPLEQ_INIT(&ad->ad_child_head);
751 SIMPLEQ_INSERT_TAIL(&sc->ad_head, ad, ad_list); 751 SIMPLEQ_INSERT_TAIL(&sc->ad_head, ad, ad_list);
752 752
753 acpi_set_node(ad); 753 acpi_set_node(ad);
754 754
755 if (ad->ad_parent != NULL) { 755 if (ad->ad_parent != NULL) {
756 756
757 SIMPLEQ_INSERT_TAIL(&ad->ad_parent->ad_child_head, 757 SIMPLEQ_INSERT_TAIL(&ad->ad_parent->ad_child_head,
758 ad, ad_child_list); 758 ad, ad_child_list);
759 } 759 }
760 760
761 awc->aw_parent = ad; 761 awc->aw_parent = ad;
762 } 762 }
763 763
764 return AE_OK; 764 return AE_OK;
765} 765}
766 766
767static ACPI_STATUS 767static ACPI_STATUS
768acpi_make_devnode_post(ACPI_HANDLE handle, uint32_t level, 768acpi_make_devnode_post(ACPI_HANDLE handle, uint32_t level,
769 void *context, void **status) 769 void *context, void **status)
770{ 770{
771 struct acpi_walkcontext *awc = context; 771 struct acpi_walkcontext *awc = context;
772 772
773 KASSERT(awc != NULL); 773 KASSERT(awc != NULL);
774 KASSERT(awc->aw_parent != NULL); 774 KASSERT(awc->aw_parent != NULL);
775 775
776 if (handle == awc->aw_parent->ad_handle) 776 if (handle == awc->aw_parent->ad_handle)
777 awc->aw_parent = awc->aw_parent->ad_parent; 777 awc->aw_parent = awc->aw_parent->ad_parent;
778 778
779 return AE_OK; 779 return AE_OK;
780} 780}
781 781
782#ifdef ACPI_ACTIVATE_DEV 782#ifdef ACPI_ACTIVATE_DEV
783static void 783static void
784acpi_activate_device(ACPI_HANDLE handle, ACPI_DEVICE_INFO **di) 784acpi_activate_device(ACPI_HANDLE handle, ACPI_DEVICE_INFO **di)
785{ 785{
786 static const int valid = ACPI_VALID_STA | ACPI_VALID_HID; 786 static const int valid = ACPI_VALID_STA | ACPI_VALID_HID;
787 ACPI_DEVICE_INFO *newdi; 787 ACPI_DEVICE_INFO *newdi;
788 ACPI_STATUS rv; 788 ACPI_STATUS rv;
789 uint32_t old; 789 uint32_t old;
790 790
791 /* 791 /*
792 * If the device is valid and present, 792 * If the device is valid and present,
793 * but not enabled, try to activate it. 793 * but not enabled, try to activate it.
794 */ 794 */
795 if (((*di)->Valid & valid) != valid) 795 if (((*di)->Valid & valid) != valid)
796 return; 796 return;
797 797
798 old = (*di)->CurrentStatus; 798 old = (*di)->CurrentStatus;
799 799
800 if ((old & (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED)) != 800 if ((old & (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED)) !=
801 ACPI_STA_DEVICE_PRESENT) 801 ACPI_STA_DEVICE_PRESENT)
802 return; 802 return;
803 803
804 rv = acpi_allocate_resources(handle); 804 rv = acpi_allocate_resources(handle);
805 805
806 if (ACPI_FAILURE(rv)) 806 if (ACPI_FAILURE(rv))
807 goto fail; 807 goto fail;
808 808
809 rv = AcpiGetObjectInfo(handle, &newdi); 809 rv = AcpiGetObjectInfo(handle, &newdi);
810 810
811 if (ACPI_FAILURE(rv)) 811 if (ACPI_FAILURE(rv))
812 goto fail; 812 goto fail;
813 813
814 ACPI_FREE(*di); 814 ACPI_FREE(*di);
815 *di = newdi; 815 *di = newdi;
816 816
817 aprint_verbose_dev(acpi_softc->sc_dev, 817 aprint_verbose_dev(acpi_softc->sc_dev,
818 "%s activated, STA 0x%08X -> STA 0x%08X\n", 818 "%s activated, STA 0x%08X -> STA 0x%08X\n",
819 (*di)->HardwareId.String, old, (*di)->CurrentStatus); 819 (*di)->HardwareId.String, old, (*di)->CurrentStatus);
820 820
821 return; 821 return;
822 822
823fail: 823fail:
824 aprint_error_dev(acpi_softc->sc_dev, "failed to " 824 aprint_error_dev(acpi_softc->sc_dev, "failed to "
825 "activate %s\n", (*di)->HardwareId.String); 825 "activate %s\n", (*di)->HardwareId.String);
826} 826}
827 827
828/* 828/*
829 * XXX: This very incomplete. 829 * XXX: This very incomplete.
830 */ 830 */
831ACPI_STATUS 831ACPI_STATUS
832acpi_allocate_resources(ACPI_HANDLE handle) 832acpi_allocate_resources(ACPI_HANDLE handle)
833{ 833{
834 ACPI_BUFFER bufp, bufc, bufn; 834 ACPI_BUFFER bufp, bufc, bufn;
835 ACPI_RESOURCE *resp, *resc, *resn; 835 ACPI_RESOURCE *resp, *resc, *resn;
836 ACPI_RESOURCE_IRQ *irq; 836 ACPI_RESOURCE_IRQ *irq;
837 ACPI_RESOURCE_EXTENDED_IRQ *xirq; 837 ACPI_RESOURCE_EXTENDED_IRQ *xirq;
838 ACPI_STATUS rv; 838 ACPI_STATUS rv;
839 uint delta; 839 uint delta;
840 840
841 rv = acpi_get(handle, &bufp, AcpiGetPossibleResources); 841 rv = acpi_get(handle, &bufp, AcpiGetPossibleResources);
842 if (ACPI_FAILURE(rv)) 842 if (ACPI_FAILURE(rv))
843 goto out; 843 goto out;
844 rv = acpi_get(handle, &bufc, AcpiGetCurrentResources); 844 rv = acpi_get(handle, &bufc, AcpiGetCurrentResources);
845 if (ACPI_FAILURE(rv)) { 845 if (ACPI_FAILURE(rv)) {
846 goto out1; 846 goto out1;
847 } 847 }
848 848
849 bufn.Length = 1000; 849 bufn.Length = 1000;
850 bufn.Pointer = resn = malloc(bufn.Length, M_ACPI, M_WAITOK); 850 bufn.Pointer = resn = malloc(bufn.Length, M_ACPI, M_WAITOK);
851 resp = bufp.Pointer; 851 resp = bufp.Pointer;
852 resc = bufc.Pointer; 852 resc = bufc.Pointer;
853 while (resc->Type != ACPI_RESOURCE_TYPE_END_TAG && 853 while (resc->Type != ACPI_RESOURCE_TYPE_END_TAG &&
854 resp->Type != ACPI_RESOURCE_TYPE_END_TAG) { 854 resp->Type != ACPI_RESOURCE_TYPE_END_TAG) {
855 while (resc->Type != resp->Type && resp->Type != ACPI_RESOURCE_TYPE_END_TAG) 855 while (resc->Type != resp->Type && resp->Type != ACPI_RESOURCE_TYPE_END_TAG)
856 resp = ACPI_NEXT_RESOURCE(resp); 856 resp = ACPI_NEXT_RESOURCE(resp);
857 if (resp->Type == ACPI_RESOURCE_TYPE_END_TAG) 857 if (resp->Type == ACPI_RESOURCE_TYPE_END_TAG)
858 break; 858 break;
859 /* Found identical Id */ 859 /* Found identical Id */
860 resn->Type = resc->Type; 860 resn->Type = resc->Type;
861 switch (resc->Type) { 861 switch (resc->Type) {
862 case ACPI_RESOURCE_TYPE_IRQ: 862 case ACPI_RESOURCE_TYPE_IRQ:
863 memcpy(&resn->Data, &resp->Data, 863 memcpy(&resn->Data, &resp->Data,
864 sizeof(ACPI_RESOURCE_IRQ)); 864 sizeof(ACPI_RESOURCE_IRQ));
865 irq = (ACPI_RESOURCE_IRQ *)&resn->Data; 865 irq = (ACPI_RESOURCE_IRQ *)&resn->Data;
866 irq->Interrupts[0] = 866 irq->Interrupts[0] =
867 ((ACPI_RESOURCE_IRQ *)&resp->Data)-> 867 ((ACPI_RESOURCE_IRQ *)&resp->Data)->
868 Interrupts[irq->InterruptCount-1]; 868 Interrupts[irq->InterruptCount-1];
869 irq->InterruptCount = 1; 869 irq->InterruptCount = 1;
870 resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_IRQ); 870 resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_IRQ);
871 break; 871 break;
872 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 872 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
873 memcpy(&resn->Data, &resp->Data, 873 memcpy(&resn->Data, &resp->Data,
874 sizeof(ACPI_RESOURCE_EXTENDED_IRQ)); 874 sizeof(ACPI_RESOURCE_EXTENDED_IRQ));
875 xirq = (ACPI_RESOURCE_EXTENDED_IRQ *)&resn->Data; 875 xirq = (ACPI_RESOURCE_EXTENDED_IRQ *)&resn->Data;
876#if 0 876#if 0
877 /* 877 /*
878 * XXX: Not duplicating the interrupt logic above 878 * XXX: Not duplicating the interrupt logic above
879 * because its not clear what it accomplishes. 879 * because its not clear what it accomplishes.
880 */ 880 */
881 xirq->Interrupts[0] = 881 xirq->Interrupts[0] =
882 ((ACPI_RESOURCE_EXT_IRQ *)&resp->Data)-> 882 ((ACPI_RESOURCE_EXT_IRQ *)&resp->Data)->
883 Interrupts[irq->NumberOfInterrupts-1]; 883 Interrupts[irq->NumberOfInterrupts-1];
884 xirq->NumberOfInterrupts = 1; 884 xirq->NumberOfInterrupts = 1;
885#endif 885#endif
886 resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_EXTENDED_IRQ); 886 resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_EXTENDED_IRQ);
887 break; 887 break;
888 case ACPI_RESOURCE_TYPE_IO: 888 case ACPI_RESOURCE_TYPE_IO:
889 memcpy(&resn->Data, &resp->Data, 889 memcpy(&resn->Data, &resp->Data,
890 sizeof(ACPI_RESOURCE_IO)); 890 sizeof(ACPI_RESOURCE_IO));
891 resn->Length = resp->Length; 891 resn->Length = resp->Length;
892 break; 892 break;
893 default: 893 default:
894 aprint_error_dev(acpi_softc->sc_dev, 894 aprint_error_dev(acpi_softc->sc_dev,
895 "%s: invalid type %u\n", __func__, resc->Type); 895 "%s: invalid type %u\n", __func__, resc->Type);
896 rv = AE_BAD_DATA; 896 rv = AE_BAD_DATA;
897 goto out2; 897 goto out2;
898 } 898 }
899 resc = ACPI_NEXT_RESOURCE(resc); 899 resc = ACPI_NEXT_RESOURCE(resc);
900 resn = ACPI_NEXT_RESOURCE(resn); 900 resn = ACPI_NEXT_RESOURCE(resn);
901 resp = ACPI_NEXT_RESOURCE(resp); 901 resp = ACPI_NEXT_RESOURCE(resp);
902 delta = (uint8_t *)resn - (uint8_t *)bufn.Pointer; 902 delta = (uint8_t *)resn - (uint8_t *)bufn.Pointer;
903 if (delta >= 903 if (delta >=
904 bufn.Length-ACPI_RS_SIZE(ACPI_RESOURCE_DATA)) { 904 bufn.Length-ACPI_RS_SIZE(ACPI_RESOURCE_DATA)) {
905 bufn.Length *= 2; 905 bufn.Length *= 2;
906 bufn.Pointer = realloc(bufn.Pointer, bufn.Length, 906 bufn.Pointer = realloc(bufn.Pointer, bufn.Length,
907 M_ACPI, M_WAITOK); 907 M_ACPI, M_WAITOK);
908 resn = (ACPI_RESOURCE *)((uint8_t *)bufn.Pointer + 908 resn = (ACPI_RESOURCE *)((uint8_t *)bufn.Pointer +
909 delta); 909 delta);
910 } 910 }
911 } 911 }
912 912
913 if (resc->Type != ACPI_RESOURCE_TYPE_END_TAG) { 913 if (resc->Type != ACPI_RESOURCE_TYPE_END_TAG) {
914 aprint_error_dev(acpi_softc->sc_dev, 914 aprint_error_dev(acpi_softc->sc_dev,
915 "%s: resc not exhausted\n", __func__); 915 "%s: resc not exhausted\n", __func__);
916 rv = AE_BAD_DATA; 916 rv = AE_BAD_DATA;
917 goto out3; 917 goto out3;
918 } 918 }
919 919
920 resn->Type = ACPI_RESOURCE_TYPE_END_TAG; 920 resn->Type = ACPI_RESOURCE_TYPE_END_TAG;
921 rv = AcpiSetCurrentResources(handle, &bufn); 921 rv = AcpiSetCurrentResources(handle, &bufn);
922 922
923 if (ACPI_FAILURE(rv)) 923 if (ACPI_FAILURE(rv))
924 aprint_error_dev(acpi_softc->sc_dev, "%s: failed to set " 924 aprint_error_dev(acpi_softc->sc_dev, "%s: failed to set "
925 "resources: %s\n", __func__, AcpiFormatException(rv)); 925 "resources: %s\n", __func__, AcpiFormatException(rv));
926 926
927out3: 927out3:
928 free(bufn.Pointer, M_ACPI); 928 free(bufn.Pointer, M_ACPI);
929out2: 929out2:
930 ACPI_FREE(bufc.Pointer); 930 ACPI_FREE(bufc.Pointer);
931out1: 931out1:
932 ACPI_FREE(bufp.Pointer); 932 ACPI_FREE(bufp.Pointer);
933out: 933out:
934 return rv; 934 return rv;
935} 935}
936#endif /* ACPI_ACTIVATE_DEV */ 936#endif /* ACPI_ACTIVATE_DEV */
937 937
938/* 938/*
939 * Device attachment. 939 * Device attachment.
940 */ 940 */
941static int 941static int
942acpi_rescan(device_t self, const char *ifattr, const int *locators) 942acpi_rescan(device_t self, const char *ifattr, const int *locators)
943{ 943{
944 struct acpi_softc *sc = device_private(self); 944 struct acpi_softc *sc = device_private(self);
945 945
946 if (ifattr_match(ifattr, "acpinodebus")) 946 if (ifattr_match(ifattr, "acpinodebus"))
947 acpi_rescan_nodes(sc); 947 acpi_rescan_nodes(sc);
948 948
949 if (ifattr_match(ifattr, "acpiapmbus") && sc->sc_apmbus == NULL) 949 if (ifattr_match(ifattr, "acpiapmbus") && sc->sc_apmbus == NULL)
950 sc->sc_apmbus = config_found_ia(sc->sc_dev, 950 sc->sc_apmbus = config_found_ia(sc->sc_dev,
951 "acpiapmbus", NULL, NULL); 951 "acpiapmbus", NULL, NULL);
952 952
953 return 0; 953 return 0;
954} 954}
955 955
956static void 956static void
957acpi_rescan_nodes(struct acpi_softc *sc) 957acpi_rescan_nodes(struct acpi_softc *sc)
958{ 958{
959 struct acpi_attach_args aa; 959 struct acpi_attach_args aa;
960 struct acpi_devnode *ad; 960 struct acpi_devnode *ad;
961 ACPI_DEVICE_INFO *di; 961 ACPI_DEVICE_INFO *di;
962 962
963 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 963 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
964 964
965 if (ad->ad_device != NULL) 965 if (ad->ad_device != NULL)
966 continue; 966 continue;
967 967
968 /* 968 /*
969 * There is a bug in ACPICA: it defines the type 969 * There is a bug in ACPICA: it defines the type
970 * of the scopes incorrectly for its own reasons. 970 * of the scopes incorrectly for its own reasons.
971 */ 971 */
972 if (acpi_is_scope(ad) != false) 972 if (acpi_is_scope(ad) != false)
973 continue; 973 continue;
974 974
975 di = ad->ad_devinfo; 975 di = ad->ad_devinfo;
976 976
977 /* 977 /*
978 * We only attach devices which are present, enabled, and 978 * We only attach devices which are present, enabled, and
979 * functioning properly. However, if a device is enabled, 979 * functioning properly. However, if a device is enabled,
980 * it is decoding resources and we should claim these, 980 * it is decoding resources and we should claim these,
981 * if possible. This requires changes to bus_space(9). 981 * if possible. This requires changes to bus_space(9).
982 */ 982 */
983 if (di->Type == ACPI_TYPE_DEVICE) { 983 if (di->Type == ACPI_TYPE_DEVICE) {
984 984
985 if ((di->Valid & ACPI_VALID_STA) != 0 && 985 if ((di->Valid & ACPI_VALID_STA) != 0 &&
986 (di->CurrentStatus & ACPI_STA_OK) != ACPI_STA_OK) 986 (di->CurrentStatus & ACPI_STA_OK) != ACPI_STA_OK)
987 continue; 987 continue;
988 } 988 }
989 989
990 /* 990 /*
991 * The same problem as above. As for example 991 * The same problem as above. As for example
992 * thermal zones and power resources do not 992 * thermal zones and power resources do not
993 * have a valid HID, only evaluate devices. 993 * have a valid HID, only evaluate devices.
994 */ 994 */
995 if (di->Type == ACPI_TYPE_DEVICE && 995 if (di->Type == ACPI_TYPE_DEVICE &&
996 (di->Valid & ACPI_VALID_HID) == 0) 996 (di->Valid & ACPI_VALID_HID) == 0)
997 continue; 997 continue;
998 998
999 /* 999 /*
1000 * Handled internally. 1000 * Handled internally.
1001 */ 1001 */
1002 if (di->Type == ACPI_TYPE_POWER) 1002 if (di->Type == ACPI_TYPE_POWER)
1003 continue; 1003 continue;
1004 1004
1005 /* 1005 /*
1006 * Skip ignored HIDs. 1006 * Skip ignored HIDs.
1007 */ 1007 */
1008 if (acpi_match_hid(di, acpi_ignored_ids)) 1008 if (acpi_match_hid(di, acpi_ignored_ids))
1009 continue; 1009 continue;
1010 1010
1011 aa.aa_node = ad; 1011 aa.aa_node = ad;
1012 aa.aa_iot = sc->sc_iot; 1012 aa.aa_iot = sc->sc_iot;
1013 aa.aa_memt = sc->sc_memt; 1013 aa.aa_memt = sc->sc_memt;
1014 aa.aa_pc = sc->sc_pc; 1014 aa.aa_pc = sc->sc_pc;
1015 aa.aa_pciflags = sc->sc_pciflags; 1015 aa.aa_pciflags = sc->sc_pciflags;
1016 aa.aa_ic = sc->sc_ic; 1016 aa.aa_ic = sc->sc_ic;
1017 1017
1018 ad->ad_device = config_found_ia(sc->sc_dev, 1018 ad->ad_device = config_found_ia(sc->sc_dev,
1019 "acpinodebus", &aa, acpi_print); 1019 "acpinodebus", &aa, acpi_print);
1020 } 1020 }
1021} 1021}
1022 1022
1023static void 1023static void
1024acpi_rescan_capabilities(struct acpi_softc *sc) 1024acpi_rescan_capabilities(struct acpi_softc *sc)
1025{ 1025{
1026 struct acpi_devnode *ad; 1026 struct acpi_devnode *ad;
1027 ACPI_HANDLE tmp; 1027 ACPI_HANDLE tmp;
1028 ACPI_STATUS rv; 1028 ACPI_STATUS rv;
1029 1029
1030 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 1030 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
1031 1031
1032 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE) 1032 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE)
1033 continue; 1033 continue;
1034 1034
1035 /* 1035 /*
1036 * Scan power resource capabilities. 1036 * Scan power resource capabilities.
1037 * 1037 *
1038 * If any power states are supported, 1038 * If any power states are supported,
1039 * at least _PR0 and _PR3 must be present. 1039 * at least _PR0 and _PR3 must be present.
1040 */ 1040 */
1041 rv = AcpiGetHandle(ad->ad_handle, "_PR0", &tmp); 1041 rv = AcpiGetHandle(ad->ad_handle, "_PR0", &tmp);
1042 1042
1043 if (ACPI_SUCCESS(rv)) { 1043 if (ACPI_SUCCESS(rv)) {
1044 ad->ad_flags |= ACPI_DEVICE_POWER; 1044 ad->ad_flags |= ACPI_DEVICE_POWER;
1045 acpi_power_add(ad); 1045 acpi_power_add(ad);
1046 } 1046 }
1047 1047
1048 /* 1048 /*
1049 * Scan wake-up capabilities. 1049 * Scan wake-up capabilities.
1050 */ 1050 */
1051 rv = AcpiGetHandle(ad->ad_handle, "_PRW", &tmp); 1051 rv = AcpiGetHandle(ad->ad_handle, "_PRW", &tmp);
1052 1052
1053 if (ACPI_SUCCESS(rv)) { 1053 if (ACPI_SUCCESS(rv)) {
1054 ad->ad_flags |= ACPI_DEVICE_WAKEUP; 1054 ad->ad_flags |= ACPI_DEVICE_WAKEUP;
1055 acpi_wakedev_add(ad); 1055 acpi_wakedev_add(ad);
1056 } 1056 }
1057 } 1057 }
1058} 1058}
1059 1059
1060static int 1060static int
1061acpi_print(void *aux, const char *pnp) 1061acpi_print(void *aux, const char *pnp)
1062{ 1062{
1063 struct acpi_attach_args *aa = aux; 1063 struct acpi_attach_args *aa = aux;
1064 ACPI_STATUS rv; 1064 ACPI_STATUS rv;
1065 1065
1066 if (pnp) { 1066 if (pnp) {
1067 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) { 1067 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) {
1068 char *pnpstr = 1068 char *pnpstr =
1069 aa->aa_node->ad_devinfo->HardwareId.String; 1069 aa->aa_node->ad_devinfo->HardwareId.String;
1070 ACPI_BUFFER buf; 1070 ACPI_BUFFER buf;
1071 1071
1072 aprint_normal("%s (%s) ", aa->aa_node->ad_name, 1072 aprint_normal("%s (%s) ", aa->aa_node->ad_name,
1073 pnpstr); 1073 pnpstr);
1074 1074
1075 rv = acpi_eval_struct(aa->aa_node->ad_handle, 1075 rv = acpi_eval_struct(aa->aa_node->ad_handle,
1076 "_STR", &buf); 1076 "_STR", &buf);
1077 if (ACPI_SUCCESS(rv)) { 1077 if (ACPI_SUCCESS(rv)) {
1078 ACPI_OBJECT *obj = buf.Pointer; 1078 ACPI_OBJECT *obj = buf.Pointer;
1079 switch (obj->Type) { 1079 switch (obj->Type) {
1080 case ACPI_TYPE_STRING: 1080 case ACPI_TYPE_STRING:
1081 aprint_normal("[%s] ", obj->String.Pointer); 1081 aprint_normal("[%s] ", obj->String.Pointer);
1082 break; 1082 break;
1083 case ACPI_TYPE_BUFFER: 1083 case ACPI_TYPE_BUFFER:
1084 aprint_normal("buffer %p ", obj->Buffer.Pointer); 1084 aprint_normal("buffer %p ", obj->Buffer.Pointer);
1085 break; 1085 break;
1086 default: 1086 default:
1087 aprint_normal("type %u ",obj->Type); 1087 aprint_normal("type %u ",obj->Type);
1088 break; 1088 break;
1089 } 1089 }
1090 ACPI_FREE(buf.Pointer); 1090 ACPI_FREE(buf.Pointer);
1091 } 1091 }
1092 else 1092 else
1093 acpi_print_dev(pnpstr); 1093 acpi_print_dev(pnpstr);
1094 1094
1095 aprint_normal("at %s", pnp); 1095 aprint_normal("at %s", pnp);
1096 } else if (aa->aa_node->ad_devinfo->Type != ACPI_TYPE_DEVICE) { 1096 } else if (aa->aa_node->ad_devinfo->Type != ACPI_TYPE_DEVICE) {
1097 aprint_normal("%s (ACPI Object Type '%s' " 1097 aprint_normal("%s (ACPI Object Type '%s' "
1098 "[0x%02x]) ", aa->aa_node->ad_name, 1098 "[0x%02x]) ", aa->aa_node->ad_name,
1099 AcpiUtGetTypeName(aa->aa_node->ad_devinfo->Type), 1099 AcpiUtGetTypeName(aa->aa_node->ad_devinfo->Type),
1100 aa->aa_node->ad_devinfo->Type); 1100 aa->aa_node->ad_devinfo->Type);
1101 aprint_normal("at %s", pnp); 1101 aprint_normal("at %s", pnp);
1102 } else 1102 } else
1103 return 0; 1103 return 0;
1104 } else { 1104 } else {
1105 aprint_normal(" (%s", aa->aa_node->ad_name); 1105 aprint_normal(" (%s", aa->aa_node->ad_name);
1106 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) { 1106 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) {
1107 aprint_normal(", %s", aa->aa_node->ad_devinfo->HardwareId.String); 1107 aprint_normal(", %s", aa->aa_node->ad_devinfo->HardwareId.String);
1108 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_UID) { 1108 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_UID) {
1109 const char *uid; 1109 const char *uid;
1110 1110
1111 uid = aa->aa_node->ad_devinfo->UniqueId.String; 1111 uid = aa->aa_node->ad_devinfo->UniqueId.String;
1112 if (uid[0] == '\0') 1112 if (uid[0] == '\0')
1113 uid = "<null>"; 1113 uid = "<null>";
1114 aprint_normal("-%s", uid); 1114 aprint_normal("-%s", uid);
1115 } 1115 }
1116 } 1116 }
1117 aprint_normal(")"); 1117 aprint_normal(")");
1118 } 1118 }
1119 1119
1120 return UNCONF; 1120 return UNCONF;
1121} 1121}
1122 1122
1123/* 1123/*
1124 * Notify. 1124 * Notify.
1125 */ 1125 */
1126static void 1126static void
1127acpi_notify_handler(ACPI_HANDLE handle, uint32_t event, void *aux) 1127acpi_notify_handler(ACPI_HANDLE handle, uint32_t event, void *aux)
1128{ 1128{
1129 struct acpi_softc *sc = acpi_softc; 1129 struct acpi_softc *sc = acpi_softc;
1130 struct acpi_devnode *ad; 1130 struct acpi_devnode *ad;
1131 1131
1132 KASSERT(sc != NULL); 1132 KASSERT(sc != NULL);
1133 KASSERT(aux == NULL); 1133 KASSERT(aux == NULL);
1134 KASSERT(acpi_active != 0); 1134 KASSERT(acpi_active != 0);
1135 1135
1136 if (acpi_suspended != 0) 1136 if (acpi_suspended != 0)
1137 return; 1137 return;
1138 1138
1139 /* 1139 /*
1140 * System: 0x00 - 0x7F. 1140 * System: 0x00 - 0x7F.
1141 * Device: 0x80 - 0xFF. 1141 * Device: 0x80 - 0xFF.
1142 */ 1142 */
1143 switch (event) { 1143 switch (event) {
1144 1144
1145 case ACPI_NOTIFY_BUS_CHECK: 1145 case ACPI_NOTIFY_BUS_CHECK:
1146 case ACPI_NOTIFY_DEVICE_CHECK: 1146 case ACPI_NOTIFY_DEVICE_CHECK:
1147 case ACPI_NOTIFY_DEVICE_WAKE: 1147 case ACPI_NOTIFY_DEVICE_WAKE:
1148 case ACPI_NOTIFY_EJECT_REQUEST: 1148 case ACPI_NOTIFY_EJECT_REQUEST:
1149 case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: 1149 case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
1150 case ACPI_NOTIFY_FREQUENCY_MISMATCH: 1150 case ACPI_NOTIFY_FREQUENCY_MISMATCH:
1151 case ACPI_NOTIFY_BUS_MODE_MISMATCH: 1151 case ACPI_NOTIFY_BUS_MODE_MISMATCH:
1152 case ACPI_NOTIFY_POWER_FAULT: 1152 case ACPI_NOTIFY_POWER_FAULT:
1153 case ACPI_NOTIFY_CAPABILITIES_CHECK: 1153 case ACPI_NOTIFY_CAPABILITIES_CHECK:
1154 case ACPI_NOTIFY_DEVICE_PLD_CHECK: 1154 case ACPI_NOTIFY_DEVICE_PLD_CHECK:
1155 case ACPI_NOTIFY_RESERVED: 1155 case ACPI_NOTIFY_RESERVED:
1156 case ACPI_NOTIFY_LOCALITY_UPDATE: 1156 case ACPI_NOTIFY_LOCALITY_UPDATE:
1157 break; 1157 break;
1158 } 1158 }
1159 1159
1160 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "notification 0x%02X for " 1160 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "notification 0x%02X for "
1161 "%s (%p)\n", event, acpi_name(handle), handle)); 1161 "%s (%p)\n", event, acpi_name(handle), handle));
1162 1162
1163 /* 1163 /*
1164 * We deliver notifications only to drivers 1164 * We deliver notifications only to drivers
1165 * that have been succesfully attached and 1165 * that have been succesfully attached and
1166 * that have registered a handler with us. 1166 * that have registered a handler with us.
1167 * The opaque pointer is always the device_t. 1167 * The opaque pointer is always the device_t.
1168 */ 1168 */
1169 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 1169 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
1170 1170
1171 if (ad->ad_device == NULL) 1171 if (ad->ad_device == NULL)
1172 continue; 1172 continue;
1173 1173
1174 if (ad->ad_notify == NULL) 1174 if (ad->ad_notify == NULL)
1175 continue; 1175 continue;
1176 1176
1177 if (ad->ad_handle != handle) 1177 if (ad->ad_handle != handle)
1178 continue; 1178 continue;
1179 1179
1180 (*ad->ad_notify)(ad->ad_handle, event, ad->ad_device); 1180 (*ad->ad_notify)(ad->ad_handle, event, ad->ad_device);
1181 1181
1182 return; 1182 return;
1183 } 1183 }
1184 1184
1185 aprint_debug_dev(sc->sc_dev, "unhandled notify 0x%02X " 1185 aprint_debug_dev(sc->sc_dev, "unhandled notify 0x%02X "
1186 "for %s (%p)\n", event, acpi_name(handle), handle); 1186 "for %s (%p)\n", event, acpi_name(handle), handle);
1187} 1187}
1188 1188
1189bool 1189bool
1190acpi_register_notify(struct acpi_devnode *ad, ACPI_NOTIFY_HANDLER notify) 1190acpi_register_notify(struct acpi_devnode *ad, ACPI_NOTIFY_HANDLER notify)
1191{ 1191{
1192 struct acpi_softc *sc = acpi_softc; 1192 struct acpi_softc *sc = acpi_softc;
1193 1193

cvs diff -r1.21 -r1.22 src/sys/dev/acpi/acpi_power.c (switch to unified diff)

--- src/sys/dev/acpi/acpi_power.c 2010/07/01 09:28:37 1.21
+++ src/sys/dev/acpi/acpi_power.c 2010/08/06 18:10:40 1.22
@@ -1,800 +1,800 @@ @@ -1,800 +1,800 @@
1/* $NetBSD: acpi_power.c,v 1.21 2010/07/01 09:28:37 jruoho Exp $ */ 1/* $NetBSD: acpi_power.c,v 1.22 2010/08/06 18:10:40 jruoho Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jukka Ruohonen. 8 * by Jukka Ruohonen.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/*- 32/*-
33 * Copyright (c) 2001 Michael Smith 33 * Copyright (c) 2001 Michael Smith
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 44 *
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE. 55 * SUCH DAMAGE.
56 */ 56 */
57 57
58#include <sys/cdefs.h> 58#include <sys/cdefs.h>
59__KERNEL_RCSID(0, "$NetBSD: acpi_power.c,v 1.21 2010/07/01 09:28:37 jruoho Exp $"); 59__KERNEL_RCSID(0, "$NetBSD: acpi_power.c,v 1.22 2010/08/06 18:10:40 jruoho Exp $");
60 60
61#include <sys/param.h> 61#include <sys/param.h>
62#include <sys/kmem.h> 62#include <sys/kmem.h>
63#include <sys/mutex.h> 63#include <sys/mutex.h>
64#include <sys/sysctl.h> 64#include <sys/sysctl.h>
65 65
66#include <dev/acpi/acpireg.h> 66#include <dev/acpi/acpireg.h>
67#include <dev/acpi/acpivar.h> 67#include <dev/acpi/acpivar.h>
68#include <dev/acpi/acpi_power.h> 68#include <dev/acpi/acpi_power.h>
69 69
70#define _COMPONENT ACPI_BUS_COMPONENT 70#define _COMPONENT ACPI_BUS_COMPONENT
71ACPI_MODULE_NAME ("acpi_power") 71ACPI_MODULE_NAME ("acpi_power")
72 72
73#define ACPI_STA_POW_OFF 0x00 73#define ACPI_STA_POW_OFF 0x00
74#define ACPI_STA_POW_ON 0x01 74#define ACPI_STA_POW_ON 0x01
75 75
76/* 76/*
77 * References. 77 * References.
78 */ 78 */
79struct acpi_power_ref { 79struct acpi_power_ref {
80 ACPI_HANDLE ref_handle; 80 ACPI_HANDLE ref_handle;
81 81
82 SIMPLEQ_ENTRY(acpi_power_ref) ref_list; 82 SIMPLEQ_ENTRY(acpi_power_ref) ref_list;
83}; 83};
84 84
85/* 85/*
86 * Resources. 86 * Resources.
87 */ 87 */
88struct acpi_power_res { 88struct acpi_power_res {
89 ACPI_HANDLE res_handle; 89 ACPI_HANDLE res_handle;
90 ACPI_INTEGER res_level; 90 ACPI_INTEGER res_level;
91 ACPI_INTEGER res_order; 91 ACPI_INTEGER res_order;
92 char res_name[5]; 92 char res_name[5];
93 kmutex_t res_mutex; 93 kmutex_t res_mutex;
94 94
95 TAILQ_ENTRY(acpi_power_res) res_list; 95 TAILQ_ENTRY(acpi_power_res) res_list;
96 SIMPLEQ_HEAD(, acpi_power_ref) ref_head; 96 SIMPLEQ_HEAD(, acpi_power_ref) ref_head;
97}; 97};
98 98
99static TAILQ_HEAD(, acpi_power_res) res_head = 99static TAILQ_HEAD(, acpi_power_res) res_head =
100 TAILQ_HEAD_INITIALIZER(res_head); 100 TAILQ_HEAD_INITIALIZER(res_head);
101 101
102static const struct sysctlnode *anode = NULL; 102static const struct sysctlnode *anode = NULL;
103 103
104static struct acpi_power_res *acpi_power_res_init(ACPI_HANDLE); 104static struct acpi_power_res *acpi_power_res_init(ACPI_HANDLE);
105static struct acpi_power_res *acpi_power_res_get(ACPI_HANDLE); 105static struct acpi_power_res *acpi_power_res_get(ACPI_HANDLE);
106 106
107static ACPI_STATUS acpi_power_get_direct(struct acpi_devnode *); 107static ACPI_STATUS acpi_power_get_direct(struct acpi_devnode *);
108static ACPI_STATUS acpi_power_get_indirect(struct acpi_devnode *); 108static ACPI_STATUS acpi_power_get_indirect(struct acpi_devnode *);
109static ACPI_STATUS acpi_power_switch(struct acpi_devnode *, 109static ACPI_STATUS acpi_power_switch(struct acpi_devnode *,
110 int, bool); 110 int, bool);
111static ACPI_STATUS acpi_power_res_ref(struct acpi_power_res *, 111static ACPI_STATUS acpi_power_res_ref(struct acpi_power_res *,
112 ACPI_HANDLE); 112 ACPI_HANDLE);
113static ACPI_STATUS acpi_power_res_deref(struct acpi_power_res *, 113static ACPI_STATUS acpi_power_res_deref(struct acpi_power_res *,
114 ACPI_HANDLE); 114 ACPI_HANDLE);
115static ACPI_STATUS acpi_power_res_sta(ACPI_OBJECT *, void *); 115static ACPI_STATUS acpi_power_res_sta(ACPI_OBJECT *, void *);
116 116
117static ACPI_OBJECT *acpi_power_pkg_get(ACPI_HANDLE, int); 117static ACPI_OBJECT *acpi_power_pkg_get(ACPI_HANDLE, int);
118static int acpi_power_sysctl(SYSCTLFN_ARGS); 118static int acpi_power_sysctl(SYSCTLFN_PROTO);
119static const char *acpi_xname(ACPI_HANDLE); 119static const char *acpi_xname(ACPI_HANDLE);
120 120
121static struct acpi_power_res * 121static struct acpi_power_res *
122acpi_power_res_init(ACPI_HANDLE hdl) 122acpi_power_res_init(ACPI_HANDLE hdl)
123{ 123{
124 struct acpi_power_res *tmp = NULL; 124 struct acpi_power_res *tmp = NULL;
125 struct acpi_power_res *res = NULL; 125 struct acpi_power_res *res = NULL;
126 ACPI_OBJECT *obj; 126 ACPI_OBJECT *obj;
127 ACPI_BUFFER buf; 127 ACPI_BUFFER buf;
128 ACPI_STATUS rv; 128 ACPI_STATUS rv;
129 129
130 rv = acpi_eval_struct(hdl, NULL, &buf); 130 rv = acpi_eval_struct(hdl, NULL, &buf);
131 131
132 if (ACPI_FAILURE(rv)) 132 if (ACPI_FAILURE(rv))
133 goto out; 133 goto out;
134 134
135 obj = buf.Pointer; 135 obj = buf.Pointer;
136 136
137 if (obj->Type != ACPI_TYPE_POWER) { 137 if (obj->Type != ACPI_TYPE_POWER) {
138 rv = AE_TYPE; 138 rv = AE_TYPE;
139 goto out; 139 goto out;
140 } 140 }
141 141
142 res = kmem_zalloc(sizeof(*res), KM_SLEEP); 142 res = kmem_zalloc(sizeof(*res), KM_SLEEP);
143 143
144 if (res == NULL) { 144 if (res == NULL) {
145 rv = AE_NO_MEMORY; 145 rv = AE_NO_MEMORY;
146 goto out; 146 goto out;
147 } 147 }
148 148
149 res->res_handle = hdl; 149 res->res_handle = hdl;
150 res->res_level = obj->PowerResource.SystemLevel; 150 res->res_level = obj->PowerResource.SystemLevel;
151 res->res_order = obj->PowerResource.ResourceOrder; 151 res->res_order = obj->PowerResource.ResourceOrder;
152 152
153 (void)strlcpy(res->res_name, 153 (void)strlcpy(res->res_name,
154 acpi_xname(hdl), sizeof(res->res_name)); 154 acpi_xname(hdl), sizeof(res->res_name));
155 155
156 SIMPLEQ_INIT(&res->ref_head); 156 SIMPLEQ_INIT(&res->ref_head);
157 mutex_init(&res->res_mutex, MUTEX_DEFAULT, IPL_NONE); 157 mutex_init(&res->res_mutex, MUTEX_DEFAULT, IPL_NONE);
158 158
159 /* 159 /*
160 * Power resources should be ordered. 160 * Power resources should be ordered.
161 * 161 *
162 * These *should* be enabled from low values to high 162 * These *should* be enabled from low values to high
163 * values and disabled from high values to low values. 163 * values and disabled from high values to low values.
164 */ 164 */
165 TAILQ_FOREACH(tmp, &res_head, res_list) { 165 TAILQ_FOREACH(tmp, &res_head, res_list) {
166 166
167 if (res->res_order < tmp->res_order) { 167 if (res->res_order < tmp->res_order) {
168 TAILQ_INSERT_BEFORE(tmp, res, res_list); 168 TAILQ_INSERT_BEFORE(tmp, res, res_list);
169 break; 169 break;
170 } 170 }
171 } 171 }
172 172
173 if (tmp == NULL) 173 if (tmp == NULL)
174 TAILQ_INSERT_TAIL(&res_head, res, res_list); 174 TAILQ_INSERT_TAIL(&res_head, res, res_list);
175 175
176 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s added to the " 176 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s added to the "
177 "power resource queue\n", res->res_name)); 177 "power resource queue\n", res->res_name));
178 178
179out: 179out:
180 if (buf.Pointer != NULL) 180 if (buf.Pointer != NULL)
181 ACPI_FREE(buf.Pointer); 181 ACPI_FREE(buf.Pointer);
182 182
183 return res; 183 return res;
184} 184}
185 185
186static struct acpi_power_res * 186static struct acpi_power_res *
187acpi_power_res_get(ACPI_HANDLE hdl) 187acpi_power_res_get(ACPI_HANDLE hdl)
188{ 188{
189 struct acpi_power_res *res; 189 struct acpi_power_res *res;
190 190
191 TAILQ_FOREACH(res, &res_head, res_list) { 191 TAILQ_FOREACH(res, &res_head, res_list) {
192 192
193 if (res->res_handle == hdl) 193 if (res->res_handle == hdl)
194 return res; 194 return res;
195 } 195 }
196 196
197 return acpi_power_res_init(hdl); 197 return acpi_power_res_init(hdl);
198} 198}
199 199
200bool 200bool
201acpi_power_register(ACPI_HANDLE hdl) 201acpi_power_register(ACPI_HANDLE hdl)
202{ 202{
203 struct acpi_devnode *ad = acpi_get_node(hdl); 203 struct acpi_devnode *ad = acpi_get_node(hdl);
204 204
205 if (ad == NULL) 205 if (ad == NULL)
206 return false; 206 return false;
207 207
208 if ((ad->ad_flags & ACPI_DEVICE_POWER) == 0) 208 if ((ad->ad_flags & ACPI_DEVICE_POWER) == 0)
209 return false; 209 return false;
210 210
211 return true; 211 return true;
212} 212}
213 213
214void 214void
215acpi_power_deregister(ACPI_HANDLE hdl) 215acpi_power_deregister(ACPI_HANDLE hdl)
216{ 216{
217 struct acpi_devnode *ad = acpi_get_node(hdl); 217 struct acpi_devnode *ad = acpi_get_node(hdl);
218 struct acpi_power_res *res; 218 struct acpi_power_res *res;
219 219
220 if (ad == NULL) 220 if (ad == NULL)
221 return; 221 return;
222 222
223 if ((ad->ad_flags & ACPI_DEVICE_POWER) == 0) 223 if ((ad->ad_flags & ACPI_DEVICE_POWER) == 0)
224 return; 224 return;
225 225
226 /* 226 /*
227 * Remove all references in each resource. 227 * Remove all references in each resource.
228 */ 228 */
229 TAILQ_FOREACH(res, &res_head, res_list) 229 TAILQ_FOREACH(res, &res_head, res_list)
230 (void)acpi_power_res_deref(res, ad->ad_handle); 230 (void)acpi_power_res_deref(res, ad->ad_handle);
231} 231}
232 232
233/* 233/*
234 * Get the D-state of an ACPI device node. 234 * Get the D-state of an ACPI device node.
235 */ 235 */
236bool 236bool
237acpi_power_get(ACPI_HANDLE hdl, int *state) 237acpi_power_get(ACPI_HANDLE hdl, int *state)
238{ 238{
239 struct acpi_devnode *ad = acpi_get_node(hdl); 239 struct acpi_devnode *ad = acpi_get_node(hdl);
240 ACPI_STATUS rv; 240 ACPI_STATUS rv;
241 241
242 if (ad == NULL) 242 if (ad == NULL)
243 return false; 243 return false;
244 244
245 if ((ad->ad_flags & ACPI_DEVICE_POWER) == 0) { 245 if ((ad->ad_flags & ACPI_DEVICE_POWER) == 0) {
246 rv = AE_SUPPORT; 246 rv = AE_SUPPORT;
247 goto fail; 247 goto fail;
248 } 248 }
249 249
250 /* 250 /*
251 * Because the _PSC control method, like _STA, 251 * Because the _PSC control method, like _STA,
252 * is known to be implemented incorrectly in 252 * is known to be implemented incorrectly in
253 * some systems, we first try to retrieve the 253 * some systems, we first try to retrieve the
254 * power state indirectly via power resources. 254 * power state indirectly via power resources.
255 */ 255 */
256 rv = acpi_power_get_indirect(ad); 256 rv = acpi_power_get_indirect(ad);
257 257
258 if (ACPI_FAILURE(rv)) 258 if (ACPI_FAILURE(rv))
259 rv = acpi_power_get_direct(ad); 259 rv = acpi_power_get_direct(ad);
260 260
261 if (ACPI_FAILURE(rv)) 261 if (ACPI_FAILURE(rv))
262 goto fail; 262 goto fail;
263 263
264 KASSERT(ad->ad_state != ACPI_STATE_ERROR); 264 KASSERT(ad->ad_state != ACPI_STATE_ERROR);
265 265
266 if (ad->ad_state < ACPI_STATE_D0 || ad->ad_state > ACPI_STATE_D3) { 266 if (ad->ad_state < ACPI_STATE_D0 || ad->ad_state > ACPI_STATE_D3) {
267 rv = AE_BAD_VALUE; 267 rv = AE_BAD_VALUE;
268 goto fail; 268 goto fail;
269 } 269 }
270 270
271 if (state != NULL) 271 if (state != NULL)
272 *state = ad->ad_state; 272 *state = ad->ad_state;
273 273
274 return true; 274 return true;
275 275
276fail: 276fail:
277 ad->ad_state = ACPI_STATE_ERROR; 277 ad->ad_state = ACPI_STATE_ERROR;
278 278
279 if (state != NULL) 279 if (state != NULL)
280 *state = ad->ad_state; 280 *state = ad->ad_state;
281 281
282 aprint_error_dev(ad->ad_root, "failed to get power state " 282 aprint_error_dev(ad->ad_root, "failed to get power state "
283 "for %s: %s\n", ad->ad_name, AcpiFormatException(rv)); 283 "for %s: %s\n", ad->ad_name, AcpiFormatException(rv));
284 284
285 return false; 285 return false;
286} 286}
287 287
288static ACPI_STATUS 288static ACPI_STATUS
289acpi_power_get_direct(struct acpi_devnode *ad) 289acpi_power_get_direct(struct acpi_devnode *ad)
290{ 290{
291 ACPI_INTEGER val = 0; 291 ACPI_INTEGER val = 0;
292 ACPI_STATUS rv; 292 ACPI_STATUS rv;
293 293
294 rv = acpi_eval_integer(ad->ad_handle, "_PSC", &val); 294 rv = acpi_eval_integer(ad->ad_handle, "_PSC", &val);
295 295
296 KDASSERT((uint64_t)val < INT_MAX); 296 KDASSERT((uint64_t)val < INT_MAX);
297 297
298 ad->ad_state = (int)val; 298 ad->ad_state = (int)val;
299 299
300 return rv; 300 return rv;
301} 301}
302 302
303static ACPI_STATUS 303static ACPI_STATUS
304acpi_power_get_indirect(struct acpi_devnode *ad) 304acpi_power_get_indirect(struct acpi_devnode *ad)
305{ 305{
306 ACPI_OBJECT *pkg; 306 ACPI_OBJECT *pkg;
307 ACPI_STATUS rv; 307 ACPI_STATUS rv;
308 int i; 308 int i;
309 309
310 CTASSERT(ACPI_STATE_D0 == 0 && ACPI_STATE_D1 == 1); 310 CTASSERT(ACPI_STATE_D0 == 0 && ACPI_STATE_D1 == 1);
311 CTASSERT(ACPI_STATE_D2 == 2 && ACPI_STATE_D3 == 3); 311 CTASSERT(ACPI_STATE_D2 == 2 && ACPI_STATE_D3 == 3);
312 312
313 /* 313 /*
314 * The device is in a given D-state if all resources are on. 314 * The device is in a given D-state if all resources are on.
315 * To derive this, evaluate all elements in each _PRx package 315 * To derive this, evaluate all elements in each _PRx package
316 * (x = 0 ... 3) and break if the noted condition becomes true. 316 * (x = 0 ... 3) and break if the noted condition becomes true.
317 */ 317 */
318 for (ad->ad_state = ACPI_STATE_D3, i = 0; i < ACPI_STATE_D3; i++) { 318 for (ad->ad_state = ACPI_STATE_D3, i = 0; i < ACPI_STATE_D3; i++) {
319 319
320 pkg = acpi_power_pkg_get(ad->ad_handle, i); 320 pkg = acpi_power_pkg_get(ad->ad_handle, i);
321 321
322 if (pkg == NULL) 322 if (pkg == NULL)
323 continue; 323 continue;
324 324
325 /* 325 /*
326 * For each element in the _PRx package, evaluate _STA 326 * For each element in the _PRx package, evaluate _STA
327 * and return AE_OK only if all power resources are on. 327 * and return AE_OK only if all power resources are on.
328 */ 328 */
329 rv = acpi_foreach_package_object(pkg, acpi_power_res_sta, ad); 329 rv = acpi_foreach_package_object(pkg, acpi_power_res_sta, ad);
330 330
331 if (ACPI_FAILURE(rv) && rv != AE_CTRL_FALSE) 331 if (ACPI_FAILURE(rv) && rv != AE_CTRL_FALSE)
332 goto out; 332 goto out;
333 333
334 if (ACPI_SUCCESS(rv)) { 334 if (ACPI_SUCCESS(rv)) {
335 ad->ad_state = i; 335 ad->ad_state = i;
336 goto out; 336 goto out;
337 } 337 }
338 338
339 ACPI_FREE(pkg); pkg = NULL; 339 ACPI_FREE(pkg); pkg = NULL;
340 } 340 }
341 341
342 KASSERT(ad->ad_state == ACPI_STATE_D3); 342 KASSERT(ad->ad_state == ACPI_STATE_D3);
343 343
344 return AE_OK; 344 return AE_OK;
345 345
346out: 346out:
347 ACPI_FREE(pkg); 347 ACPI_FREE(pkg);
348 348
349 return rv; 349 return rv;
350} 350}
351 351
352/* 352/*
353 * Set the D-state of an ACPI device node. 353 * Set the D-state of an ACPI device node.
354 */ 354 */
355bool 355bool
356acpi_power_set(ACPI_HANDLE hdl, int state) 356acpi_power_set(ACPI_HANDLE hdl, int state)
357{ 357{
358 struct acpi_devnode *ad = acpi_get_node(hdl); 358 struct acpi_devnode *ad = acpi_get_node(hdl);
359 ACPI_STATUS rv; 359 ACPI_STATUS rv;
360 char path[5]; 360 char path[5];
361 int old; 361 int old;
362 362
363 if (ad == NULL) 363 if (ad == NULL)
364 return false; 364 return false;
365 365
366 if ((ad->ad_flags & ACPI_DEVICE_POWER) == 0) { 366 if ((ad->ad_flags & ACPI_DEVICE_POWER) == 0) {
367 rv = AE_SUPPORT; 367 rv = AE_SUPPORT;
368 goto fail; 368 goto fail;
369 } 369 }
370 370
371 if (state < ACPI_STATE_D0 || state > ACPI_STATE_D3) { 371 if (state < ACPI_STATE_D0 || state > ACPI_STATE_D3) {
372 rv = AE_BAD_PARAMETER; 372 rv = AE_BAD_PARAMETER;
373 goto fail; 373 goto fail;
374 } 374 }
375 375
376 if (acpi_power_get(ad->ad_handle, &old) != true) { 376 if (acpi_power_get(ad->ad_handle, &old) != true) {
377 rv = AE_NOT_FOUND; 377 rv = AE_NOT_FOUND;
378 goto fail; 378 goto fail;
379 } 379 }
380 380
381 KASSERT(ad->ad_state == old); 381 KASSERT(ad->ad_state == old);
382 KASSERT(ad->ad_state != ACPI_STATE_ERROR); 382 KASSERT(ad->ad_state != ACPI_STATE_ERROR);
383 383
384 if (ad->ad_state == state) { 384 if (ad->ad_state == state) {
385 rv = AE_ALREADY_EXISTS; 385 rv = AE_ALREADY_EXISTS;
386 goto fail; 386 goto fail;
387 } 387 }
388 388
389 /* 389 /*
390 * It is only possible to go to D0 ("on") from D3 ("off"). 390 * It is only possible to go to D0 ("on") from D3 ("off").
391 */ 391 */
392 if (ad->ad_state == ACPI_STATE_D3 && state != ACPI_STATE_D0) { 392 if (ad->ad_state == ACPI_STATE_D3 && state != ACPI_STATE_D0) {
393 rv = AE_BAD_PARAMETER; 393 rv = AE_BAD_PARAMETER;
394 goto fail; 394 goto fail;
395 } 395 }
396 396
397 /* 397 /*
398 * As noted in ACPI 4.0 (appendix A.2.1), the bus power state 398 * As noted in ACPI 4.0 (appendix A.2.1), the bus power state
399 * should never be lower than the highest state of one of its 399 * should never be lower than the highest state of one of its
400 * devices. Consequently, we cannot set the state to a lower 400 * devices. Consequently, we cannot set the state to a lower
401 * (i.e. higher power) state than the parent device's state. 401 * (i.e. higher power) state than the parent device's state.
402 */ 402 */
403 if ((ad->ad_parent != NULL) && 403 if ((ad->ad_parent != NULL) &&
404 (ad->ad_parent->ad_flags & ACPI_DEVICE_POWER) != 0) { 404 (ad->ad_parent->ad_flags & ACPI_DEVICE_POWER) != 0) {
405 405
406 if (ad->ad_parent->ad_state > state) { 406 if (ad->ad_parent->ad_state > state) {
407 rv = AE_ABORT_METHOD; 407 rv = AE_ABORT_METHOD;
408 goto fail; 408 goto fail;
409 } 409 }
410 } 410 }
411 411
412 /* 412 /*
413 * We first sweep through the resources required for the target 413 * We first sweep through the resources required for the target
414 * state, turning things on and building references. After this 414 * state, turning things on and building references. After this
415 * we dereference the resources required for the current state, 415 * we dereference the resources required for the current state,
416 * turning the resources off as we go. 416 * turning the resources off as we go.
417 */ 417 */
418 rv = acpi_power_switch(ad, state, true); 418 rv = acpi_power_switch(ad, state, true);
419 419
420 if (ACPI_FAILURE(rv) && rv != AE_CTRL_CONTINUE) 420 if (ACPI_FAILURE(rv) && rv != AE_CTRL_CONTINUE)
421 goto fail; 421 goto fail;
422 422
423 rv = acpi_power_switch(ad, ad->ad_state, false); 423 rv = acpi_power_switch(ad, ad->ad_state, false);
424 424
425 if (ACPI_FAILURE(rv) && rv != AE_CTRL_CONTINUE) 425 if (ACPI_FAILURE(rv) && rv != AE_CTRL_CONTINUE)
426 goto fail; 426 goto fail;
427 427
428 /* 428 /*
429 * Last but not least, invoke the power state switch method, 429 * Last but not least, invoke the power state switch method,
430 * if available. Because some systems use only _PSx for the 430 * if available. Because some systems use only _PSx for the
431 * power state transitions, we do this even if there is no _PRx. 431 * power state transitions, we do this even if there is no _PRx.
432 */ 432 */
433 (void)snprintf(path, sizeof(path), "_PS%d", state); 433 (void)snprintf(path, sizeof(path), "_PS%d", state);
434 (void)AcpiEvaluateObject(ad->ad_handle, path, NULL, NULL); 434 (void)AcpiEvaluateObject(ad->ad_handle, path, NULL, NULL);
435 435
436 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s turned from " 436 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s turned from "
437 "D%d to D%d\n", ad->ad_name, old, state)); 437 "D%d to D%d\n", ad->ad_name, old, state));
438 438
439 ad->ad_state = state; 439 ad->ad_state = state;
440 440
441 return true; 441 return true;
442 442
443fail: 443fail:
444 ad->ad_state = ACPI_STATE_ERROR; 444 ad->ad_state = ACPI_STATE_ERROR;
445 445
446 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "failed to set power state to D%d " 446 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "failed to set power state to D%d "
447 "for %s: %s\n", state, ad->ad_name, AcpiFormatException(rv))); 447 "for %s: %s\n", state, ad->ad_name, AcpiFormatException(rv)));
448 448
449 return false; 449 return false;
450} 450}
451 451
452static ACPI_STATUS 452static ACPI_STATUS
453acpi_power_switch(struct acpi_devnode *ad, int state, bool on) 453acpi_power_switch(struct acpi_devnode *ad, int state, bool on)
454{ 454{
455 ACPI_OBJECT *elm, *pkg; 455 ACPI_OBJECT *elm, *pkg;
456 ACPI_STATUS rv = AE_OK; 456 ACPI_STATUS rv = AE_OK;
457 ACPI_HANDLE hdl; 457 ACPI_HANDLE hdl;
458 uint32_t i, n; 458 uint32_t i, n;
459 459
460 /* 460 /*
461 * For each element in the _PRx package, fetch 461 * For each element in the _PRx package, fetch
462 * the reference handle, search for this handle 462 * the reference handle, search for this handle
463 * from the power resource queue, and turn the 463 * from the power resource queue, and turn the
464 * resource behind the handle on or off. 464 * resource behind the handle on or off.
465 */ 465 */
466 pkg = acpi_power_pkg_get(ad->ad_handle, state); 466 pkg = acpi_power_pkg_get(ad->ad_handle, state);
467 467
468 if (pkg == NULL) 468 if (pkg == NULL)
469 return AE_CTRL_CONTINUE; 469 return AE_CTRL_CONTINUE;
470 470
471 n = pkg->Package.Count; 471 n = pkg->Package.Count;
472 472
473 for (i = 0; i < n; i++) { 473 for (i = 0; i < n; i++) {
474 474
475 elm = &pkg->Package.Elements[i]; 475 elm = &pkg->Package.Elements[i];
476 rv = acpi_eval_reference_handle(elm, &hdl); 476 rv = acpi_eval_reference_handle(elm, &hdl);
477 477
478 if (ACPI_FAILURE(rv)) 478 if (ACPI_FAILURE(rv))
479 continue; 479 continue;
480 480
481 (void)acpi_power_res(hdl, ad->ad_handle, on); 481 (void)acpi_power_res(hdl, ad->ad_handle, on);
482 } 482 }
483 483
484 ACPI_FREE(pkg); 484 ACPI_FREE(pkg);
485 485
486 return rv; 486 return rv;
487} 487}
488 488
489ACPI_STATUS 489ACPI_STATUS
490acpi_power_res(ACPI_HANDLE hdl, ACPI_HANDLE ref, bool on) 490acpi_power_res(ACPI_HANDLE hdl, ACPI_HANDLE ref, bool on)
491{ 491{
492 struct acpi_power_res *res; 492 struct acpi_power_res *res;
493 const char *str; 493 const char *str;
494 ACPI_STATUS rv; 494 ACPI_STATUS rv;
495 495
496 /* 496 /*
497 * Search for the resource. 497 * Search for the resource.
498 */ 498 */
499 res = acpi_power_res_get(hdl); 499 res = acpi_power_res_get(hdl);
500 500
501 if (res == NULL) 501 if (res == NULL)
502 return AE_NOT_FOUND; 502 return AE_NOT_FOUND;
503 503
504 /* 504 /*
505 * (De)reference the resource. 505 * (De)reference the resource.
506 */ 506 */
507 switch (on) { 507 switch (on) {
508 508
509 case true: 509 case true:
510 rv = acpi_power_res_ref(res, ref); 510 rv = acpi_power_res_ref(res, ref);
511 str = "_ON"; 511 str = "_ON";
512 break; 512 break;
513 513
514 case false: 514 case false:
515 rv = acpi_power_res_deref(res, ref); 515 rv = acpi_power_res_deref(res, ref);
516 str = "_OFF"; 516 str = "_OFF";
517 break; 517 break;
518 518
519 default: 519 default:
520 return AE_BAD_PARAMETER; 520 return AE_BAD_PARAMETER;
521 } 521 }
522 522
523 if (ACPI_FAILURE(rv)) 523 if (ACPI_FAILURE(rv))
524 return rv; 524 return rv;
525 525
526 /* 526 /*
527 * Turn the resource on or off. 527 * Turn the resource on or off.
528 */ 528 */
529 return AcpiEvaluateObject(res->res_handle, str, NULL, NULL); 529 return AcpiEvaluateObject(res->res_handle, str, NULL, NULL);
530} 530}
531 531
532static ACPI_STATUS 532static ACPI_STATUS
533acpi_power_res_ref(struct acpi_power_res *res, ACPI_HANDLE hdl) 533acpi_power_res_ref(struct acpi_power_res *res, ACPI_HANDLE hdl)
534{ 534{
535 struct acpi_power_ref *ref, *tmp; 535 struct acpi_power_ref *ref, *tmp;
536 536
537 ref = kmem_zalloc(sizeof(*ref), KM_SLEEP); 537 ref = kmem_zalloc(sizeof(*ref), KM_SLEEP);
538 538
539 if (ref == NULL) 539 if (ref == NULL)
540 return AE_NO_MEMORY; 540 return AE_NO_MEMORY;
541 541
542 mutex_enter(&res->res_mutex); 542 mutex_enter(&res->res_mutex);
543 543
544 SIMPLEQ_FOREACH(tmp, &res->ref_head, ref_list) { 544 SIMPLEQ_FOREACH(tmp, &res->ref_head, ref_list) {
545 545
546 if (tmp->ref_handle == hdl) 546 if (tmp->ref_handle == hdl)
547 goto out; 547 goto out;
548 } 548 }
549 549
550 ref->ref_handle = hdl; 550 ref->ref_handle = hdl;
551 SIMPLEQ_INSERT_TAIL(&res->ref_head, ref, ref_list); 551 SIMPLEQ_INSERT_TAIL(&res->ref_head, ref, ref_list);
552 mutex_exit(&res->res_mutex); 552 mutex_exit(&res->res_mutex);
553 553
554 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s referenced " 554 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s referenced "
555 "by %s\n", res->res_name, acpi_xname(hdl))); 555 "by %s\n", res->res_name, acpi_xname(hdl)));
556 556
557 return AE_OK; 557 return AE_OK;
558 558
559out: 559out:
560 mutex_exit(&res->res_mutex); 560 mutex_exit(&res->res_mutex);
561 kmem_free(ref, sizeof(*ref)); 561 kmem_free(ref, sizeof(*ref));
562 562
563 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s already referenced " 563 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s already referenced "
564 "by %s?\n", res->res_name, acpi_xname(hdl))); 564 "by %s?\n", res->res_name, acpi_xname(hdl)));
565 565
566 return AE_OK; 566 return AE_OK;
567} 567}
568 568
569static ACPI_STATUS 569static ACPI_STATUS
570acpi_power_res_deref(struct acpi_power_res *res, ACPI_HANDLE hdl) 570acpi_power_res_deref(struct acpi_power_res *res, ACPI_HANDLE hdl)
571{ 571{
572 struct acpi_power_ref *ref; 572 struct acpi_power_ref *ref;
573 573
574 mutex_enter(&res->res_mutex); 574 mutex_enter(&res->res_mutex);
575 575
576 if (SIMPLEQ_EMPTY(&res->ref_head) != 0) { 576 if (SIMPLEQ_EMPTY(&res->ref_head) != 0) {
577 mutex_exit(&res->res_mutex); 577 mutex_exit(&res->res_mutex);
578 return AE_OK; 578 return AE_OK;
579 } 579 }
580 580
581 SIMPLEQ_FOREACH(ref, &res->ref_head, ref_list) { 581 SIMPLEQ_FOREACH(ref, &res->ref_head, ref_list) {
582 582
583 if (ref->ref_handle == hdl) { 583 if (ref->ref_handle == hdl) {
584 SIMPLEQ_REMOVE(&res->ref_head, 584 SIMPLEQ_REMOVE(&res->ref_head,
585 ref, acpi_power_ref, ref_list); 585 ref, acpi_power_ref, ref_list);
586 mutex_exit(&res->res_mutex); 586 mutex_exit(&res->res_mutex);
587 kmem_free(ref, sizeof(*ref)); 587 kmem_free(ref, sizeof(*ref));
588 mutex_enter(&res->res_mutex); 588 mutex_enter(&res->res_mutex);
589 break; 589 break;
590 } 590 }
591 } 591 }
592 592
593 /* 593 /*
594 * If the queue remains non-empty, 594 * If the queue remains non-empty,
595 * something else is using the resource 595 * something else is using the resource
596 * and hence it can not be turned off. 596 * and hence it can not be turned off.
597 */ 597 */
598 if (SIMPLEQ_EMPTY(&res->ref_head) == 0) { 598 if (SIMPLEQ_EMPTY(&res->ref_head) == 0) {
599 mutex_exit(&res->res_mutex); 599 mutex_exit(&res->res_mutex);
600 return AE_ABORT_METHOD; 600 return AE_ABORT_METHOD;
601 } 601 }
602 602
603 mutex_exit(&res->res_mutex); 603 mutex_exit(&res->res_mutex);
604 604
605 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s dereferenced " 605 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s dereferenced "
606 "by %s\n", res->res_name, acpi_xname(hdl))); 606 "by %s\n", res->res_name, acpi_xname(hdl)));
607 607
608 return AE_OK; 608 return AE_OK;
609} 609}
610 610
611static ACPI_STATUS 611static ACPI_STATUS
612acpi_power_res_sta(ACPI_OBJECT *elm, void *arg) 612acpi_power_res_sta(ACPI_OBJECT *elm, void *arg)
613{ 613{
614 ACPI_INTEGER val; 614 ACPI_INTEGER val;
615 ACPI_HANDLE hdl; 615 ACPI_HANDLE hdl;
616 ACPI_STATUS rv; 616 ACPI_STATUS rv;
617 617
618 rv = acpi_eval_reference_handle(elm, &hdl); 618 rv = acpi_eval_reference_handle(elm, &hdl);
619 619
620 if (ACPI_FAILURE(rv)) 620 if (ACPI_FAILURE(rv))
621 goto fail; 621 goto fail;
622 622
623 rv = acpi_eval_integer(hdl, "_STA", &val); 623 rv = acpi_eval_integer(hdl, "_STA", &val);
624 624
625 if (ACPI_FAILURE(rv)) 625 if (ACPI_FAILURE(rv))
626 goto fail; 626 goto fail;
627 627
628 KDASSERT((uint64_t)val < INT_MAX); 628 KDASSERT((uint64_t)val < INT_MAX);
629 629
630 if ((int)val != ACPI_STA_POW_ON && (int)val != ACPI_STA_POW_OFF) 630 if ((int)val != ACPI_STA_POW_ON && (int)val != ACPI_STA_POW_OFF)
631 return AE_BAD_VALUE; 631 return AE_BAD_VALUE;
632 632
633 if ((int)val != ACPI_STA_POW_ON) 633 if ((int)val != ACPI_STA_POW_ON)
634 return AE_CTRL_FALSE; /* XXX: Not an error. */ 634 return AE_CTRL_FALSE; /* XXX: Not an error. */
635 635
636 return AE_OK; 636 return AE_OK;
637 637
638fail: 638fail:
639 if (rv == AE_CTRL_FALSE) 639 if (rv == AE_CTRL_FALSE)
640 rv = AE_ERROR; 640 rv = AE_ERROR;
641 641
642 ACPI_DEBUG_PRINT((ACPI_DB_DEBUG_OBJECT, "failed to evaluate _STA " 642 ACPI_DEBUG_PRINT((ACPI_DB_DEBUG_OBJECT, "failed to evaluate _STA "
643 "for %s: %s\n", acpi_xname(hdl), AcpiFormatException(rv))); 643 "for %s: %s\n", acpi_xname(hdl), AcpiFormatException(rv)));
644 644
645 return rv; 645 return rv;
646} 646}
647 647
648static ACPI_OBJECT * 648static ACPI_OBJECT *
649acpi_power_pkg_get(ACPI_HANDLE hdl, int state) 649acpi_power_pkg_get(ACPI_HANDLE hdl, int state)
650{ 650{
651 char path[5] = "_PR?"; 651 char path[5] = "_PR?";
652 ACPI_OBJECT *obj; 652 ACPI_OBJECT *obj;
653 ACPI_BUFFER buf; 653 ACPI_BUFFER buf;
654 ACPI_STATUS rv; 654 ACPI_STATUS rv;
655 655
656 path[3] = '0' + state; 656 path[3] = '0' + state;
657 657
658 rv = acpi_eval_struct(hdl, path, &buf); 658 rv = acpi_eval_struct(hdl, path, &buf);
659 659
660 if (ACPI_FAILURE(rv)) 660 if (ACPI_FAILURE(rv))
661 goto fail; 661 goto fail;
662 662
663 if (buf.Length == 0) { 663 if (buf.Length == 0) {
664 rv = AE_LIMIT; 664 rv = AE_LIMIT;
665 goto fail; 665 goto fail;
666 } 666 }
667 667
668 obj = buf.Pointer; 668 obj = buf.Pointer;
669 669
670 if (obj->Type != ACPI_TYPE_PACKAGE) { 670 if (obj->Type != ACPI_TYPE_PACKAGE) {
671 rv = AE_TYPE; 671 rv = AE_TYPE;
672 goto fail; 672 goto fail;
673 } 673 }
674 674
675 if (obj->Package.Count == 0) { 675 if (obj->Package.Count == 0) {
676 rv = AE_LIMIT; 676 rv = AE_LIMIT;
677 goto fail; 677 goto fail;
678 } 678 }
679 679
680 return obj; 680 return obj;
681 681
682fail: 682fail:
683 if (buf.Pointer != NULL) 683 if (buf.Pointer != NULL)
684 ACPI_FREE(buf.Pointer); 684 ACPI_FREE(buf.Pointer);
685 685
686 ACPI_DEBUG_PRINT((ACPI_DB_DEBUG_OBJECT, "failed to evaluate %s for " 686 ACPI_DEBUG_PRINT((ACPI_DB_DEBUG_OBJECT, "failed to evaluate %s for "
687 "%s: %s\n", path, acpi_xname(hdl), AcpiFormatException(rv))); 687 "%s: %s\n", path, acpi_xname(hdl), AcpiFormatException(rv)));
688 688
689 return NULL; 689 return NULL;
690} 690}
691 691
692SYSCTL_SETUP(sysctl_acpi_power_setup, "sysctl hw.acpi.power subtree setup") 692SYSCTL_SETUP(sysctl_acpi_power_setup, "sysctl hw.acpi.power subtree setup")
693{ 693{
694 int err; 694 int err;
695 695
696 err = sysctl_createv(NULL, 0, NULL, &anode, 696 err = sysctl_createv(NULL, 0, NULL, &anode,
697 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", 697 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw",
698 NULL, NULL, 0, NULL, 0, 698 NULL, NULL, 0, NULL, 0,
699 CTL_HW, CTL_EOL); 699 CTL_HW, CTL_EOL);
700 700
701 if (err != 0) 701 if (err != 0)
702 goto fail; 702 goto fail;
703 703
704 err = sysctl_createv(NULL, 0, &anode, &anode, 704 err = sysctl_createv(NULL, 0, &anode, &anode,
705 CTLFLAG_PERMANENT, CTLTYPE_NODE, "acpi", 705 CTLFLAG_PERMANENT, CTLTYPE_NODE, "acpi",
706 NULL, NULL, 0, NULL, 0, 706 NULL, NULL, 0, NULL, 0,
707 CTL_CREATE, CTL_EOL); 707 CTL_CREATE, CTL_EOL);
708 708
709 if (err != 0) 709 if (err != 0)
710 goto fail; 710 goto fail;
711 711
712 err = sysctl_createv(NULL, 0, &anode, &anode, 712 err = sysctl_createv(NULL, 0, &anode, &anode,
713 CTLFLAG_PERMANENT, CTLTYPE_NODE, 713 CTLFLAG_PERMANENT, CTLTYPE_NODE,
714 "power", SYSCTL_DESCR("ACPI device power states"), 714 "power", SYSCTL_DESCR("ACPI device power states"),
715 NULL, 0, NULL, 0, 715 NULL, 0, NULL, 0,
716 CTL_CREATE, CTL_EOL); 716 CTL_CREATE, CTL_EOL);
717 717
718 if (err != 0) 718 if (err != 0)
719 goto fail; 719 goto fail;
720 720
721 return; 721 return;
722 722
723fail: 723fail:
724 anode = NULL; 724 anode = NULL;
725} 725}
726 726
727void 727void
728acpi_power_add(struct acpi_devnode *ad) 728acpi_power_add(struct acpi_devnode *ad)
729{ 729{
730 int err; 730 int err;
731 731
732 KASSERT(ad != NULL && ad->ad_root != NULL); 732 KASSERT(ad != NULL && ad->ad_root != NULL);
733 KASSERT((ad->ad_flags & ACPI_DEVICE_POWER) != 0); 733 KASSERT((ad->ad_flags & ACPI_DEVICE_POWER) != 0);
734 734
735 if (anode == NULL) 735 if (anode == NULL)
736 return; 736 return;
737 737
738 /* 738 /*
739 * Make this read-only: because a single power resource 739 * Make this read-only: because a single power resource
740 * may power multiple devices, it is unclear whether 740 * may power multiple devices, it is unclear whether
741 * power resources should be controllable by an user. 741 * power resources should be controllable by an user.
742 */ 742 */
743 err = sysctl_createv(NULL, 0, &anode, NULL, 743 err = sysctl_createv(NULL, 0, &anode, NULL,
744 CTLFLAG_READONLY, CTLTYPE_STRING, ad->ad_name, 744 CTLFLAG_READONLY, CTLTYPE_STRING, ad->ad_name,
745 NULL, acpi_power_sysctl, 0, ad, 0, 745 NULL, acpi_power_sysctl, 0, ad, 0,
746 CTL_CREATE, CTL_EOL); 746 CTL_CREATE, CTL_EOL);
747 747
748 if (err != 0) 748 if (err != 0)
749 aprint_error_dev(ad->ad_root, "sysctl_createv" 749 aprint_error_dev(ad->ad_root, "sysctl_createv"
750 "(hw.acpi.power.%s) failed (err %d)\n", ad->ad_name, err); 750 "(hw.acpi.power.%s) failed (err %d)\n", ad->ad_name, err);
751} 751}
752 752
753static int 753static int
754acpi_power_sysctl(SYSCTLFN_ARGS) 754acpi_power_sysctl(SYSCTLFN_ARGS)
755{ 755{
756 struct acpi_devnode *ad; 756 struct acpi_devnode *ad;
757 struct sysctlnode node; 757 struct sysctlnode node;
758 int err, state; 758 int err, state;
759 char t[3]; 759 char t[3];
760 760
761 node = *rnode; 761 node = *rnode;
762 ad = rnode->sysctl_data; 762 ad = rnode->sysctl_data;
763 763
764 if (acpi_power_get(ad->ad_handle, &state) != true) 764 if (acpi_power_get(ad->ad_handle, &state) != true)
765 state = 0; 765 state = 0;
766 766
767 (void)memset(t, '\0', sizeof(t)); 767 (void)memset(t, '\0', sizeof(t));
768 (void)snprintf(t, sizeof(t), "D%d", state); 768 (void)snprintf(t, sizeof(t), "D%d", state);
769 769
770 node.sysctl_data = &t; 770 node.sysctl_data = &t;
771 771
772 err = sysctl_lookup(SYSCTLFN_CALL(&node)); 772 err = sysctl_lookup(SYSCTLFN_CALL(&node));
773 773
774 if (err || newp == NULL) 774 if (err || newp == NULL)
775 return err; 775 return err;
776 776
777 return 0; 777 return 0;
778} 778}
779 779
780/* 780/*
781 * XXX: Move this to acpi_util.c by refactoring 781 * XXX: Move this to acpi_util.c by refactoring
782 * acpi_name() to optionally return a single name. 782 * acpi_name() to optionally return a single name.
783 */ 783 */
784static const char * 784static const char *
785acpi_xname(ACPI_HANDLE hdl) 785acpi_xname(ACPI_HANDLE hdl)
786{ 786{
787 static char str[5]; 787 static char str[5];
788 ACPI_BUFFER buf; 788 ACPI_BUFFER buf;
789 ACPI_STATUS rv; 789 ACPI_STATUS rv;
790 790
791 buf.Pointer = str; 791 buf.Pointer = str;
792 buf.Length = sizeof(str); 792 buf.Length = sizeof(str);
793 793
794 rv = AcpiGetName(hdl, ACPI_SINGLE_NAME, &buf); 794 rv = AcpiGetName(hdl, ACPI_SINGLE_NAME, &buf);
795 795
796 if (ACPI_FAILURE(rv)) 796 if (ACPI_FAILURE(rv))
797 return "????"; 797 return "????";
798 798
799 return str; 799 return str;
800} 800}