Mon Aug 9 09:36:42 2010 UTC ()
acpi_pcidev_scan: attach PCI information only to working devices.

ok jruoho@


(gsutre)
diff -r1.214 -r1.215 src/sys/dev/acpi/acpi.c
diff -r1.13 -r1.14 src/sys/dev/acpi/acpi_pci.c

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

--- src/sys/dev/acpi/acpi.c 2010/08/07 20:07:25 1.214
+++ src/sys/dev/acpi/acpi.c 2010/08/09 09:36:42 1.215
@@ -1,1819 +1,1821 @@ @@ -1,1819 +1,1821 @@
1/* $NetBSD: acpi.c,v 1.214 2010/08/07 20:07:25 jruoho Exp $ */ 1/* $NetBSD: acpi.c,v 1.215 2010/08/09 09:36:42 gsutre 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 (c) 2003 Wasabi Systems, Inc. 33 * Copyright (c) 2003 Wasabi Systems, Inc.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Written by Frank van der Linden for Wasabi Systems, Inc. 36 * Written by Frank van der Linden 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/* 67/*
68 * Copyright 2001, 2003 Wasabi Systems, Inc. 68 * Copyright 2001, 2003 Wasabi Systems, Inc.
69 * All rights reserved. 69 * All rights reserved.
70 * 70 *
71 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 71 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
72 * 72 *
73 * Redistribution and use in source and binary forms, with or without 73 * Redistribution and use in source and binary forms, with or without
74 * modification, are permitted provided that the following conditions 74 * modification, are permitted provided that the following conditions
75 * are met: 75 * are met:
76 * 1. Redistributions of source code must retain the above copyright 76 * 1. Redistributions of source code must retain the above copyright
77 * notice, this list of conditions and the following disclaimer. 77 * notice, this list of conditions and the following disclaimer.
78 * 2. Redistributions in binary form must reproduce the above copyright 78 * 2. Redistributions in binary form must reproduce the above copyright
79 * notice, this list of conditions and the following disclaimer in the 79 * notice, this list of conditions and the following disclaimer in the
80 * documentation and/or other materials provided with the distribution. 80 * documentation and/or other materials provided with the distribution.
81 * 3. All advertising materials mentioning features or use of this software 81 * 3. All advertising materials mentioning features or use of this software
82 * must display the following acknowledgement: 82 * must display the following acknowledgement:
83 * This product includes software developed for the NetBSD Project by 83 * This product includes software developed for the NetBSD Project by
84 * Wasabi Systems, Inc. 84 * Wasabi Systems, Inc.
85 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 85 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
86 * or promote products derived from this software without specific prior 86 * or promote products derived from this software without specific prior
87 * written permission. 87 * written permission.
88 * 88 *
89 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 89 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
90 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 90 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
91 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 91 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
92 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 92 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
93 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 93 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
94 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 94 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
95 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 95 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
96 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 96 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
97 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 97 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
98 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 98 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
99 * POSSIBILITY OF SUCH DAMAGE. 99 * POSSIBILITY OF SUCH DAMAGE.
100 */ 100 */
101 101
102#include <sys/cdefs.h> 102#include <sys/cdefs.h>
103__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.214 2010/08/07 20:07:25 jruoho Exp $"); 103__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.215 2010/08/09 09:36:42 gsutre Exp $");
104 104
105#include "opt_acpi.h" 105#include "opt_acpi.h"
106#include "opt_pcifixup.h" 106#include "opt_pcifixup.h"
107 107
108#include <sys/param.h> 108#include <sys/param.h>
109#include <sys/device.h> 109#include <sys/device.h>
110#include <sys/kernel.h> 110#include <sys/kernel.h>
111#include <sys/malloc.h> 111#include <sys/malloc.h>
112#include <sys/module.h> 112#include <sys/module.h>
113#include <sys/mutex.h> 113#include <sys/mutex.h>
114#include <sys/sysctl.h> 114#include <sys/sysctl.h>
115#include <sys/systm.h> 115#include <sys/systm.h>
116#include <sys/timetc.h> 116#include <sys/timetc.h>
117 117
118#include <dev/acpi/acpireg.h> 118#include <dev/acpi/acpireg.h>
119#include <dev/acpi/acpivar.h> 119#include <dev/acpi/acpivar.h>
120#include <dev/acpi/acpi_osd.h> 120#include <dev/acpi/acpi_osd.h>
121#include <dev/acpi/acpi_pci.h> 121#include <dev/acpi/acpi_pci.h>
122#include <dev/acpi/acpi_power.h> 122#include <dev/acpi/acpi_power.h>
123#include <dev/acpi/acpi_timer.h> 123#include <dev/acpi/acpi_timer.h>
124#include <dev/acpi/acpi_wakedev.h> 124#include <dev/acpi/acpi_wakedev.h>
125 125
126#define _COMPONENT ACPI_BUS_COMPONENT 126#define _COMPONENT ACPI_BUS_COMPONENT
127ACPI_MODULE_NAME ("acpi") 127ACPI_MODULE_NAME ("acpi")
128 128
129#if defined(ACPI_PCI_FIXUP) 129#if defined(ACPI_PCI_FIXUP)
130#error The option ACPI_PCI_FIXUP has been obsoleted by PCI_INTR_FIXUP_DISABLED. Please adjust your kernel configuration file. 130#error The option ACPI_PCI_FIXUP has been obsoleted by PCI_INTR_FIXUP_DISABLED. Please adjust your kernel configuration file.
131#endif 131#endif
132 132
133#ifdef PCI_INTR_FIXUP_DISABLED 133#ifdef PCI_INTR_FIXUP_DISABLED
134#include <dev/pci/pcidevs.h> 134#include <dev/pci/pcidevs.h>
135#endif 135#endif
136 136
137MALLOC_DECLARE(M_ACPI); 137MALLOC_DECLARE(M_ACPI);
138 138
139#include <machine/acpi_machdep.h> 139#include <machine/acpi_machdep.h>
140 140
141#ifdef ACPI_DEBUGGER 141#ifdef ACPI_DEBUGGER
142#define ACPI_DBGR_INIT 0x01 142#define ACPI_DBGR_INIT 0x01
143#define ACPI_DBGR_TABLES 0x02 143#define ACPI_DBGR_TABLES 0x02
144#define ACPI_DBGR_ENABLE 0x04 144#define ACPI_DBGR_ENABLE 0x04
145#define ACPI_DBGR_PROBE 0x08 145#define ACPI_DBGR_PROBE 0x08
146#define ACPI_DBGR_RUNNING 0x10 146#define ACPI_DBGR_RUNNING 0x10
147 147
148static int acpi_dbgr = 0x00; 148static int acpi_dbgr = 0x00;
149#endif 149#endif
150 150
151/* 151/*
152 * This is a flag we set when the ACPI subsystem is active. Machine 152 * This is a flag we set when the ACPI subsystem is active. Machine
153 * dependent code may wish to skip other steps (such as attaching 153 * dependent code may wish to skip other steps (such as attaching
154 * subsystems that ACPI supercedes) when ACPI is active. 154 * subsystems that ACPI supercedes) when ACPI is active.
155 */ 155 */
156int acpi_active; 156int acpi_active;
157int acpi_force_load; 157int acpi_force_load;
158int acpi_suspended = 0; 158int acpi_suspended = 0;
159int acpi_verbose_loaded = 0; 159int acpi_verbose_loaded = 0;
160 160
161struct acpi_softc *acpi_softc; 161struct acpi_softc *acpi_softc;
162static uint64_t acpi_root_pointer; 162static uint64_t acpi_root_pointer;
163extern kmutex_t acpi_interrupt_list_mtx; 163extern kmutex_t acpi_interrupt_list_mtx;
164extern struct cfdriver acpi_cd; 164extern struct cfdriver acpi_cd;
165static ACPI_HANDLE acpi_scopes[4]; 165static ACPI_HANDLE acpi_scopes[4];
166ACPI_TABLE_HEADER *madt_header; 166ACPI_TABLE_HEADER *madt_header;
167 167
168/* 168/*
169 * This structure provides a context for the ACPI 169 * This structure provides a context for the ACPI
170 * namespace walk performed in acpi_build_tree(). 170 * namespace walk performed in acpi_build_tree().
171 */ 171 */
172struct acpi_walkcontext { 172struct acpi_walkcontext {
173 struct acpi_softc *aw_sc; 173 struct acpi_softc *aw_sc;
174 struct acpi_devnode *aw_parent; 174 struct acpi_devnode *aw_parent;
175}; 175};
176 176
177/* 177/*
178 * Ignored HIDs. 178 * Ignored HIDs.
179 */ 179 */
180static const char * const acpi_ignored_ids[] = { 180static const char * const acpi_ignored_ids[] = {
181#if defined(i386) || defined(x86_64) 181#if defined(i386) || defined(x86_64)
182 "PNP0000", /* AT interrupt controller is handled internally */ 182 "PNP0000", /* AT interrupt controller is handled internally */
183 "PNP0200", /* AT DMA controller is handled internally */ 183 "PNP0200", /* AT DMA controller is handled internally */
184 "PNP0A??", /* PCI Busses are handled internally */ 184 "PNP0A??", /* PCI Busses are handled internally */
185 "PNP0B00", /* AT RTC is handled internally */ 185 "PNP0B00", /* AT RTC is handled internally */
186 "PNP0C0B", /* No need for "ACPI fan" driver */ 186 "PNP0C0B", /* No need for "ACPI fan" driver */
187 "PNP0C0F", /* ACPI PCI link devices are handled internally */ 187 "PNP0C0F", /* ACPI PCI link devices are handled internally */
188 "IFX0102", /* No driver for Infineon TPM */ 188 "IFX0102", /* No driver for Infineon TPM */
189 "INT0800", /* No driver for Intel Firmware Hub device */ 189 "INT0800", /* No driver for Intel Firmware Hub device */
190#endif 190#endif
191#if defined(x86_64) 191#if defined(x86_64)
192 "PNP0C04", /* FPU is handled internally */ 192 "PNP0C04", /* FPU is handled internally */
193#endif 193#endif
194 NULL 194 NULL
195}; 195};
196 196
197static int acpi_match(device_t, cfdata_t, void *); 197static int acpi_match(device_t, cfdata_t, void *);
198static int acpi_submatch(device_t, cfdata_t, const int *, void *); 198static int acpi_submatch(device_t, cfdata_t, const int *, void *);
199static void acpi_attach(device_t, device_t, void *); 199static void acpi_attach(device_t, device_t, void *);
200static int acpi_detach(device_t, int); 200static int acpi_detach(device_t, int);
201static void acpi_childdet(device_t, device_t); 201static void acpi_childdet(device_t, device_t);
202static bool acpi_suspend(device_t, const pmf_qual_t *); 202static bool acpi_suspend(device_t, const pmf_qual_t *);
203static bool acpi_resume(device_t, const pmf_qual_t *); 203static bool acpi_resume(device_t, const pmf_qual_t *);
204 204
205static void acpi_build_tree(struct acpi_softc *); 205static void acpi_build_tree(struct acpi_softc *);
206static ACPI_STATUS acpi_make_devnode(ACPI_HANDLE, uint32_t, 206static ACPI_STATUS acpi_make_devnode(ACPI_HANDLE, uint32_t,
207 void *, void **); 207 void *, void **);
208static ACPI_STATUS acpi_make_devnode_post(ACPI_HANDLE, uint32_t, 208static ACPI_STATUS acpi_make_devnode_post(ACPI_HANDLE, uint32_t,
209 void *, void **); 209 void *, void **);
210 210
211#ifdef ACPI_ACTIVATE_DEV 211#ifdef ACPI_ACTIVATE_DEV
212static void acpi_activate_device(ACPI_HANDLE, ACPI_DEVICE_INFO **); 212static void acpi_activate_device(ACPI_HANDLE, ACPI_DEVICE_INFO **);
213static ACPI_STATUS acpi_allocate_resources(ACPI_HANDLE); 213static ACPI_STATUS acpi_allocate_resources(ACPI_HANDLE);
214#endif 214#endif
215 215
216static int acpi_rescan(device_t, const char *, const int *); 216static int acpi_rescan(device_t, const char *, const int *);
217static void acpi_rescan_nodes(struct acpi_softc *); 217static void acpi_rescan_nodes(struct acpi_softc *);
218static void acpi_rescan_capabilities(struct acpi_softc *); 218static void acpi_rescan_capabilities(struct acpi_softc *);
219static int acpi_print(void *aux, const char *); 219static int acpi_print(void *aux, const char *);
220 220
221static void acpi_notify_handler(ACPI_HANDLE, uint32_t, void *); 221static void acpi_notify_handler(ACPI_HANDLE, uint32_t, void *);
222 222
223static void acpi_register_fixed_button(struct acpi_softc *, int); 223static void acpi_register_fixed_button(struct acpi_softc *, int);
224static void acpi_deregister_fixed_button(struct acpi_softc *, int); 224static void acpi_deregister_fixed_button(struct acpi_softc *, int);
225static uint32_t acpi_fixed_button_handler(void *); 225static uint32_t acpi_fixed_button_handler(void *);
226static void acpi_fixed_button_pressed(void *); 226static void acpi_fixed_button_pressed(void *);
227 227
228static void acpi_sleep_init(struct acpi_softc *); 228static void acpi_sleep_init(struct acpi_softc *);
229 229
230static int sysctl_hw_acpi_fixedstats(SYSCTLFN_PROTO); 230static int sysctl_hw_acpi_fixedstats(SYSCTLFN_PROTO);
231static int sysctl_hw_acpi_sleepstate(SYSCTLFN_PROTO); 231static int sysctl_hw_acpi_sleepstate(SYSCTLFN_PROTO);
232static int sysctl_hw_acpi_sleepstates(SYSCTLFN_PROTO); 232static int sysctl_hw_acpi_sleepstates(SYSCTLFN_PROTO);
233 233
234static bool acpi_is_scope(struct acpi_devnode *); 234static bool acpi_is_scope(struct acpi_devnode *);
235static ACPI_TABLE_HEADER *acpi_map_rsdt(void); 235static ACPI_TABLE_HEADER *acpi_map_rsdt(void);
236static void acpi_unmap_rsdt(ACPI_TABLE_HEADER *); 236static void acpi_unmap_rsdt(ACPI_TABLE_HEADER *);
237 237
238void acpi_print_verbose_stub(struct acpi_softc *); 238void acpi_print_verbose_stub(struct acpi_softc *);
239void acpi_print_dev_stub(const char *); 239void acpi_print_dev_stub(const char *);
240 240
241void (*acpi_print_verbose)(struct acpi_softc *) = acpi_print_verbose_stub; 241void (*acpi_print_verbose)(struct acpi_softc *) = acpi_print_verbose_stub;
242void (*acpi_print_dev)(const char *) = acpi_print_dev_stub; 242void (*acpi_print_dev)(const char *) = acpi_print_dev_stub;
243 243
244CFATTACH_DECL2_NEW(acpi, sizeof(struct acpi_softc), 244CFATTACH_DECL2_NEW(acpi, sizeof(struct acpi_softc),
245 acpi_match, acpi_attach, acpi_detach, NULL, acpi_rescan, acpi_childdet); 245 acpi_match, acpi_attach, acpi_detach, NULL, acpi_rescan, acpi_childdet);
246 246
247/* 247/*
248 * Probe for ACPI support. 248 * Probe for ACPI support.
249 * 249 *
250 * This is called by the machine-dependent ACPI front-end. 250 * This is called by the machine-dependent ACPI front-end.
251 * Note: this is not an autoconfiguration interface function. 251 * Note: this is not an autoconfiguration interface function.
252 */ 252 */
253int 253int
254acpi_probe(void) 254acpi_probe(void)
255{ 255{
256 ACPI_TABLE_HEADER *rsdt; 256 ACPI_TABLE_HEADER *rsdt;
257 const char *func; 257 const char *func;
258 static int once; 258 static int once;
259 bool initialized; 259 bool initialized;
260 ACPI_STATUS rv; 260 ACPI_STATUS rv;
261 261
262 if (once != 0) 262 if (once != 0)
263 panic("%s: already probed", __func__); 263 panic("%s: already probed", __func__);
264 264
265 once = 1; 265 once = 1;
266 func = NULL; 266 func = NULL;
267 initialized = false; 267 initialized = false;
268 268
269 mutex_init(&acpi_interrupt_list_mtx, MUTEX_DEFAULT, IPL_NONE); 269 mutex_init(&acpi_interrupt_list_mtx, MUTEX_DEFAULT, IPL_NONE);
270 270
271 /* 271 /*
272 * Start up ACPICA. 272 * Start up ACPICA.
273 */ 273 */
274#ifdef ACPI_DEBUGGER 274#ifdef ACPI_DEBUGGER
275 if (acpi_dbgr & ACPI_DBGR_INIT) 275 if (acpi_dbgr & ACPI_DBGR_INIT)
276 acpi_osd_debugger(); 276 acpi_osd_debugger();
277#endif 277#endif
278 278
279 CTASSERT(TRUE == true); 279 CTASSERT(TRUE == true);
280 CTASSERT(FALSE == false); 280 CTASSERT(FALSE == false);
281 281
282 AcpiGbl_AllMethodsSerialized = false; 282 AcpiGbl_AllMethodsSerialized = false;
283 AcpiGbl_EnableInterpreterSlack = true; 283 AcpiGbl_EnableInterpreterSlack = true;
284 284
285 rv = AcpiInitializeSubsystem(); 285 rv = AcpiInitializeSubsystem();
286 286
287 if (ACPI_SUCCESS(rv)) 287 if (ACPI_SUCCESS(rv))
288 initialized = true; 288 initialized = true;
289 else { 289 else {
290 func = "AcpiInitializeSubsystem()"; 290 func = "AcpiInitializeSubsystem()";
291 goto fail; 291 goto fail;
292 } 292 }
293 293
294 /* 294 /*
295 * Allocate space for RSDT/XSDT and DSDT, 295 * Allocate space for RSDT/XSDT and DSDT,
296 * but allow resizing if more tables exist. 296 * but allow resizing if more tables exist.
297 */ 297 */
298 rv = AcpiInitializeTables(NULL, 2, true); 298 rv = AcpiInitializeTables(NULL, 2, true);
299 299
300 if (ACPI_FAILURE(rv)) { 300 if (ACPI_FAILURE(rv)) {
301 func = "AcpiInitializeTables()"; 301 func = "AcpiInitializeTables()";
302 goto fail; 302 goto fail;
303 } 303 }
304 304
305#ifdef ACPI_DEBUGGER 305#ifdef ACPI_DEBUGGER
306 if (acpi_dbgr & ACPI_DBGR_TABLES) 306 if (acpi_dbgr & ACPI_DBGR_TABLES)
307 acpi_osd_debugger(); 307 acpi_osd_debugger();
308#endif 308#endif
309 309
310 rv = AcpiLoadTables(); 310 rv = AcpiLoadTables();
311 311
312 if (ACPI_FAILURE(rv)) { 312 if (ACPI_FAILURE(rv)) {
313 func = "AcpiLoadTables()"; 313 func = "AcpiLoadTables()";
314 goto fail; 314 goto fail;
315 } 315 }
316 316
317 rsdt = acpi_map_rsdt(); 317 rsdt = acpi_map_rsdt();
318 318
319 if (rsdt == NULL) { 319 if (rsdt == NULL) {
320 func = "acpi_map_rsdt()"; 320 func = "acpi_map_rsdt()";
321 rv = AE_ERROR; 321 rv = AE_ERROR;
322 goto fail; 322 goto fail;
323 } 323 }
324 324
325 if (acpi_force_load == 0 && (acpi_find_quirks() & ACPI_QUIRK_BROKEN)) { 325 if (acpi_force_load == 0 && (acpi_find_quirks() & ACPI_QUIRK_BROKEN)) {
326 aprint_normal("ACPI: BIOS is listed as broken:\n"); 326 aprint_normal("ACPI: BIOS is listed as broken:\n");
327 aprint_normal("ACPI: X/RSDT: OemId <%6.6s,%8.8s,%08x>, " 327 aprint_normal("ACPI: X/RSDT: OemId <%6.6s,%8.8s,%08x>, "
328 "AslId <%4.4s,%08x>\n", 328 "AslId <%4.4s,%08x>\n",
329 rsdt->OemId, rsdt->OemTableId, 329 rsdt->OemId, rsdt->OemTableId,
330 rsdt->OemRevision, 330 rsdt->OemRevision,
331 rsdt->AslCompilerId, 331 rsdt->AslCompilerId,
332 rsdt->AslCompilerRevision); 332 rsdt->AslCompilerRevision);
333 aprint_normal("ACPI: Not used. Set acpi_force_load to use.\n"); 333 aprint_normal("ACPI: Not used. Set acpi_force_load to use.\n");
334 acpi_unmap_rsdt(rsdt); 334 acpi_unmap_rsdt(rsdt);
335 AcpiTerminate(); 335 AcpiTerminate();
336 return 0; 336 return 0;
337 } 337 }
338 338
339 acpi_unmap_rsdt(rsdt); 339 acpi_unmap_rsdt(rsdt);
340 340
341 rv = AcpiEnableSubsystem(~(ACPI_NO_HARDWARE_INIT|ACPI_NO_ACPI_ENABLE)); 341 rv = AcpiEnableSubsystem(~(ACPI_NO_HARDWARE_INIT|ACPI_NO_ACPI_ENABLE));
342 342
343 if (ACPI_FAILURE(rv)) { 343 if (ACPI_FAILURE(rv)) {
344 func = "AcpiEnableSubsystem()"; 344 func = "AcpiEnableSubsystem()";
345 goto fail; 345 goto fail;
346 } 346 }
347 347
348 /* 348 /*
349 * Looks like we have ACPI! 349 * Looks like we have ACPI!
350 */ 350 */
351 return 1; 351 return 1;
352 352
353fail: 353fail:
354 KASSERT(rv != AE_OK); 354 KASSERT(rv != AE_OK);
355 KASSERT(func != NULL); 355 KASSERT(func != NULL);
356 356
357 aprint_error("%s: failed to probe ACPI: %s\n", 357 aprint_error("%s: failed to probe ACPI: %s\n",
358 func, AcpiFormatException(rv)); 358 func, AcpiFormatException(rv));
359 359
360 if (initialized != false) 360 if (initialized != false)
361 (void)AcpiTerminate(); 361 (void)AcpiTerminate();
362 362
363 return 0; 363 return 0;
364} 364}
365 365
366void 366void
367acpi_disable(void) 367acpi_disable(void)
368{ 368{
369 369
370 if (AcpiGbl_FADT.SmiCommand != 0) 370 if (AcpiGbl_FADT.SmiCommand != 0)
371 AcpiDisable(); 371 AcpiDisable();
372} 372}
373 373
374int 374int
375acpi_check(device_t parent, const char *ifattr) 375acpi_check(device_t parent, const char *ifattr)
376{ 376{
377 return (config_search_ia(acpi_submatch, parent, ifattr, NULL) != NULL); 377 return (config_search_ia(acpi_submatch, parent, ifattr, NULL) != NULL);
378} 378}
379 379
380/* 380/*
381 * Autoconfiguration. 381 * Autoconfiguration.
382 */ 382 */
383static int 383static int
384acpi_match(device_t parent, cfdata_t match, void *aux) 384acpi_match(device_t parent, cfdata_t match, void *aux)
385{ 385{
386 /* 386 /*
387 * XXX: Nada; MD code has called acpi_probe(). 387 * XXX: Nada; MD code has called acpi_probe().
388 */ 388 */
389 return 1; 389 return 1;
390} 390}
391 391
392static int 392static int
393acpi_submatch(device_t parent, cfdata_t cf, const int *locs, void *aux) 393acpi_submatch(device_t parent, cfdata_t cf, const int *locs, void *aux)
394{ 394{
395 struct cfattach *ca; 395 struct cfattach *ca;
396 396
397 ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname); 397 ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname);
398 398
399 return (ca == &acpi_ca); 399 return (ca == &acpi_ca);
400} 400}
401 401
402static void 402static void
403acpi_attach(device_t parent, device_t self, void *aux) 403acpi_attach(device_t parent, device_t self, void *aux)
404{ 404{
405 struct acpi_softc *sc = device_private(self); 405 struct acpi_softc *sc = device_private(self);
406 struct acpibus_attach_args *aa = aux; 406 struct acpibus_attach_args *aa = aux;
407 ACPI_TABLE_HEADER *rsdt; 407 ACPI_TABLE_HEADER *rsdt;
408 ACPI_STATUS rv; 408 ACPI_STATUS rv;
409 409
410 aprint_naive("\n"); 410 aprint_naive("\n");
411 aprint_normal(": Intel ACPICA %08x\n", ACPI_CA_VERSION); 411 aprint_normal(": Intel ACPICA %08x\n", ACPI_CA_VERSION);
412 412
413 if (acpi_softc != NULL) 413 if (acpi_softc != NULL)
414 panic("%s: already attached", __func__); 414 panic("%s: already attached", __func__);
415 415
416 rsdt = acpi_map_rsdt(); 416 rsdt = acpi_map_rsdt();
417 417
418 if (rsdt == NULL) 418 if (rsdt == NULL)
419 aprint_error_dev(self, "X/RSDT: Not found\n"); 419 aprint_error_dev(self, "X/RSDT: Not found\n");
420 else { 420 else {
421 aprint_verbose_dev(self, 421 aprint_verbose_dev(self,
422 "X/RSDT: OemId <%6.6s,%8.8s,%08x>, AslId <%4.4s,%08x>\n", 422 "X/RSDT: OemId <%6.6s,%8.8s,%08x>, AslId <%4.4s,%08x>\n",
423 rsdt->OemId, rsdt->OemTableId, 423 rsdt->OemId, rsdt->OemTableId,
424 rsdt->OemRevision, 424 rsdt->OemRevision,
425 rsdt->AslCompilerId, rsdt->AslCompilerRevision); 425 rsdt->AslCompilerId, rsdt->AslCompilerRevision);
426 } 426 }
427 427
428 acpi_unmap_rsdt(rsdt); 428 acpi_unmap_rsdt(rsdt);
429 429
430 sc->sc_dev = self; 430 sc->sc_dev = self;
431 sc->sc_root = NULL; 431 sc->sc_root = NULL;
432 432
433 sc->sc_sleepstate = ACPI_STATE_S0; 433 sc->sc_sleepstate = ACPI_STATE_S0;
434 sc->sc_quirks = acpi_find_quirks(); 434 sc->sc_quirks = acpi_find_quirks();
435 435
436 sysmon_power_settype("acpi"); 436 sysmon_power_settype("acpi");
437 437
438 sc->sc_iot = aa->aa_iot; 438 sc->sc_iot = aa->aa_iot;
439 sc->sc_memt = aa->aa_memt; 439 sc->sc_memt = aa->aa_memt;
440 sc->sc_pc = aa->aa_pc; 440 sc->sc_pc = aa->aa_pc;
441 sc->sc_pciflags = aa->aa_pciflags; 441 sc->sc_pciflags = aa->aa_pciflags;
442 sc->sc_ic = aa->aa_ic; 442 sc->sc_ic = aa->aa_ic;
443 443
444 SIMPLEQ_INIT(&sc->ad_head); 444 SIMPLEQ_INIT(&sc->ad_head);
445 445
446 acpi_softc = sc; 446 acpi_softc = sc;
447 447
448 if (pmf_device_register(self, acpi_suspend, acpi_resume) != true) 448 if (pmf_device_register(self, acpi_suspend, acpi_resume) != true)
449 aprint_error_dev(self, "couldn't establish power handler\n"); 449 aprint_error_dev(self, "couldn't establish power handler\n");
450 450
451 /* 451 /*
452 * Bring ACPI on-line. 452 * Bring ACPI on-line.
453 */ 453 */
454#ifdef ACPI_DEBUGGER 454#ifdef ACPI_DEBUGGER
455 if (acpi_dbgr & ACPI_DBGR_ENABLE) 455 if (acpi_dbgr & ACPI_DBGR_ENABLE)
456 acpi_osd_debugger(); 456 acpi_osd_debugger();
457#endif 457#endif
458 458
459#define ACPI_ENABLE_PHASE1 \ 459#define ACPI_ENABLE_PHASE1 \
460 (ACPI_NO_HANDLER_INIT | ACPI_NO_EVENT_INIT) 460 (ACPI_NO_HANDLER_INIT | ACPI_NO_EVENT_INIT)
461#define ACPI_ENABLE_PHASE2 \ 461#define ACPI_ENABLE_PHASE2 \
462 (ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE | \ 462 (ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE | \
463 ACPI_NO_ADDRESS_SPACE_INIT) 463 ACPI_NO_ADDRESS_SPACE_INIT)
464 464
465 rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE1); 465 rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE1);
466 466
467 if (ACPI_FAILURE(rv)) 467 if (ACPI_FAILURE(rv))
468 goto fail; 468 goto fail;
469 469
470 acpi_md_callback(); 470 acpi_md_callback();
471 471
472 rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE2); 472 rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE2);
473 473
474 if (ACPI_FAILURE(rv)) 474 if (ACPI_FAILURE(rv))
475 goto fail; 475 goto fail;
476 476
477 /* 477 /*
478 * Early EC handler initialization if ECDT table is available. 478 * Early EC handler initialization if ECDT table is available.
479 */ 479 */
480 config_found_ia(self, "acpiecdtbus", aa, NULL); 480 config_found_ia(self, "acpiecdtbus", aa, NULL);
481 481
482 rv = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION); 482 rv = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
483 483
484 if (ACPI_FAILURE(rv)) 484 if (ACPI_FAILURE(rv))
485 goto fail; 485 goto fail;
486 486
487 /* 487 /*
488 * Install global notify handlers. 488 * Install global notify handlers.
489 */ 489 */
490 rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT, 490 rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT,
491 ACPI_SYSTEM_NOTIFY, acpi_notify_handler, NULL); 491 ACPI_SYSTEM_NOTIFY, acpi_notify_handler, NULL);
492 492
493 if (ACPI_FAILURE(rv)) 493 if (ACPI_FAILURE(rv))
494 goto fail; 494 goto fail;
495 495
496 rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT, 496 rv = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT,
497 ACPI_DEVICE_NOTIFY, acpi_notify_handler, NULL); 497 ACPI_DEVICE_NOTIFY, acpi_notify_handler, NULL);
498 498
499 if (ACPI_FAILURE(rv)) 499 if (ACPI_FAILURE(rv))
500 goto fail; 500 goto fail;
501 501
502 acpi_active = 1; 502 acpi_active = 1;
503 503
504 /* Show SCI interrupt. */ 504 /* Show SCI interrupt. */
505 aprint_verbose_dev(self, "SCI interrupting at int %u\n", 505 aprint_verbose_dev(self, "SCI interrupting at int %u\n",
506 AcpiGbl_FADT.SciInterrupt); 506 AcpiGbl_FADT.SciInterrupt);
507 507
508 /* 508 /*
509 * Install fixed-event handlers. 509 * Install fixed-event handlers.
510 */ 510 */
511 acpi_register_fixed_button(sc, ACPI_EVENT_POWER_BUTTON); 511 acpi_register_fixed_button(sc, ACPI_EVENT_POWER_BUTTON);
512 acpi_register_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON); 512 acpi_register_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON);
513 513
514 acpitimer_init(sc); 514 acpitimer_init(sc);
515 515
516#ifdef ACPI_DEBUGGER 516#ifdef ACPI_DEBUGGER
517 if (acpi_dbgr & ACPI_DBGR_PROBE) 517 if (acpi_dbgr & ACPI_DBGR_PROBE)
518 acpi_osd_debugger(); 518 acpi_osd_debugger();
519#endif 519#endif
520 520
521 /* 521 /*
522 * Scan the namespace and build our device tree. 522 * Scan the namespace and build our device tree.
523 */ 523 */
524 acpi_build_tree(sc); 524 acpi_build_tree(sc);
525 acpi_sleep_init(sc); 525 acpi_sleep_init(sc);
526 526
527#ifdef ACPI_DEBUGGER 527#ifdef ACPI_DEBUGGER
528 if (acpi_dbgr & ACPI_DBGR_RUNNING) 528 if (acpi_dbgr & ACPI_DBGR_RUNNING)
529 acpi_osd_debugger(); 529 acpi_osd_debugger();
530#endif 530#endif
531 531
532#ifdef ACPI_DEBUG 532#ifdef ACPI_DEBUG
533 acpi_debug_init(); 533 acpi_debug_init();
534#endif 534#endif
535 535
536 /* 536 /*
537 * Print debug information. 537 * Print debug information.
538 */ 538 */
539 acpi_print_verbose(sc); 539 acpi_print_verbose(sc);
540 540
541 return; 541 return;
542 542
543fail: 543fail:
544 aprint_error("%s: failed to initialize ACPI: %s\n", 544 aprint_error("%s: failed to initialize ACPI: %s\n",
545 __func__, AcpiFormatException(rv)); 545 __func__, AcpiFormatException(rv));
546} 546}
547 547
548/* 548/*
549 * XXX: This is incomplete. 549 * XXX: This is incomplete.
550 */ 550 */
551static int 551static int
552acpi_detach(device_t self, int flags) 552acpi_detach(device_t self, int flags)
553{ 553{
554 struct acpi_softc *sc = device_private(self); 554 struct acpi_softc *sc = device_private(self);
555 ACPI_STATUS rv; 555 ACPI_STATUS rv;
556 int rc; 556 int rc;
557 557
558 rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT, 558 rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT,
559 ACPI_SYSTEM_NOTIFY, acpi_notify_handler); 559 ACPI_SYSTEM_NOTIFY, acpi_notify_handler);
560 560
561 if (ACPI_FAILURE(rv)) 561 if (ACPI_FAILURE(rv))
562 return EBUSY; 562 return EBUSY;
563 563
564 rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT, 564 rv = AcpiRemoveNotifyHandler(ACPI_ROOT_OBJECT,
565 ACPI_DEVICE_NOTIFY, acpi_notify_handler); 565 ACPI_DEVICE_NOTIFY, acpi_notify_handler);
566 566
567 if (ACPI_FAILURE(rv)) 567 if (ACPI_FAILURE(rv))
568 return EBUSY; 568 return EBUSY;
569 569
570 if ((rc = config_detach_children(self, flags)) != 0) 570 if ((rc = config_detach_children(self, flags)) != 0)
571 return rc; 571 return rc;
572 572
573 if ((rc = acpitimer_detach()) != 0) 573 if ((rc = acpitimer_detach()) != 0)
574 return rc; 574 return rc;
575 575
576 acpi_deregister_fixed_button(sc, ACPI_EVENT_POWER_BUTTON); 576 acpi_deregister_fixed_button(sc, ACPI_EVENT_POWER_BUTTON);
577 acpi_deregister_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON); 577 acpi_deregister_fixed_button(sc, ACPI_EVENT_SLEEP_BUTTON);
578 578
579 pmf_device_deregister(self); 579 pmf_device_deregister(self);
580 580
581 acpi_softc = NULL; 581 acpi_softc = NULL;
582 582
583 return 0; 583 return 0;
584} 584}
585 585
586/* 586/*
587 * XXX: Need to reclaim any resources? Yes. 587 * XXX: Need to reclaim any resources? Yes.
588 */ 588 */
589static void 589static void
590acpi_childdet(device_t self, device_t child) 590acpi_childdet(device_t self, device_t child)
591{ 591{
592 struct acpi_softc *sc = device_private(self); 592 struct acpi_softc *sc = device_private(self);
593 struct acpi_devnode *ad; 593 struct acpi_devnode *ad;
594 594
595 if (sc->sc_apmbus == child) 595 if (sc->sc_apmbus == child)
596 sc->sc_apmbus = NULL; 596 sc->sc_apmbus = NULL;
597 597
598 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 598 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
599 599
600 if (ad->ad_device == child) 600 if (ad->ad_device == child)
601 ad->ad_device = NULL; 601 ad->ad_device = NULL;
602 } 602 }
603} 603}
604 604
605static bool 605static bool
606acpi_suspend(device_t dv, const pmf_qual_t *qual) 606acpi_suspend(device_t dv, const pmf_qual_t *qual)
607{ 607{
608 608
609 acpi_suspended = 1; 609 acpi_suspended = 1;
610 610
611 return true; 611 return true;
612} 612}
613 613
614static bool 614static bool
615acpi_resume(device_t dv, const pmf_qual_t *qual) 615acpi_resume(device_t dv, const pmf_qual_t *qual)
616{ 616{
617 617
618 acpi_suspended = 0; 618 acpi_suspended = 0;
619 619
620 return true; 620 return true;
621} 621}
622 622
623/* 623/*
624 * Namespace scan. 624 * Namespace scan.
625 */ 625 */
626static void 626static void
627acpi_build_tree(struct acpi_softc *sc) 627acpi_build_tree(struct acpi_softc *sc)
628{ 628{
629 struct acpi_walkcontext awc; 629 struct acpi_walkcontext awc;
630 630
631 /* 631 /*
632 * Get the root scope handles. 632 * Get the root scope handles.
633 */ 633 */
634 KASSERT(__arraycount(acpi_scopes) == 4); 634 KASSERT(__arraycount(acpi_scopes) == 4);
635 635
636 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_PR_", &acpi_scopes[0]); 636 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_PR_", &acpi_scopes[0]);
637 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &acpi_scopes[1]); 637 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SB_", &acpi_scopes[1]);
638 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SI_", &acpi_scopes[2]); 638 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_SI_", &acpi_scopes[2]);
639 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_TZ_", &acpi_scopes[3]); 639 (void)AcpiGetHandle(ACPI_ROOT_OBJECT, "\\_TZ_", &acpi_scopes[3]);
640 640
641 /* 641 /*
642 * Make the root node. 642 * Make the root node.
643 */ 643 */
644 awc.aw_sc = sc; 644 awc.aw_sc = sc;
645 awc.aw_parent = NULL; 645 awc.aw_parent = NULL;
646 646
647 (void)acpi_make_devnode(ACPI_ROOT_OBJECT, 0, &awc, NULL); 647 (void)acpi_make_devnode(ACPI_ROOT_OBJECT, 0, &awc, NULL);
648 648
649 KASSERT(sc->sc_root == NULL); 649 KASSERT(sc->sc_root == NULL);
650 KASSERT(awc.aw_parent != NULL); 650 KASSERT(awc.aw_parent != NULL);
651 651
652 sc->sc_root = awc.aw_parent; 652 sc->sc_root = awc.aw_parent;
653 653
654 /* 654 /*
655 * Build the internal namespace. 655 * Build the internal namespace.
656 */ 656 */
657 (void)AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, UINT32_MAX, 657 (void)AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, UINT32_MAX,
658 acpi_make_devnode, acpi_make_devnode_post, &awc, NULL); 658 acpi_make_devnode, acpi_make_devnode_post, &awc, NULL);
659 659
660 /* 660 /*
661 * Scan the internal namespace. 661 * Scan the internal namespace.
662 */ 662 */
663 (void)acpi_rescan(sc->sc_dev, NULL, NULL); 663 (void)acpi_rescan(sc->sc_dev, NULL, NULL);
664 664
665 acpi_rescan_capabilities(sc); 665 acpi_rescan_capabilities(sc);
666 666
667 (void)acpi_pcidev_scan(sc->sc_root); 667 (void)acpi_pcidev_scan(sc->sc_root);
668} 668}
669 669
670static ACPI_STATUS 670static ACPI_STATUS
671acpi_make_devnode(ACPI_HANDLE handle, uint32_t level, 671acpi_make_devnode(ACPI_HANDLE handle, uint32_t level,
672 void *context, void **status) 672 void *context, void **status)
673{ 673{
674 struct acpi_walkcontext *awc = context; 674 struct acpi_walkcontext *awc = context;
675 struct acpi_softc *sc = awc->aw_sc; 675 struct acpi_softc *sc = awc->aw_sc;
676 struct acpi_devnode *ad; 676 struct acpi_devnode *ad;
677 ACPI_DEVICE_INFO *devinfo; 677 ACPI_DEVICE_INFO *devinfo;
678 ACPI_OBJECT_TYPE type; 678 ACPI_OBJECT_TYPE type;
679 ACPI_NAME_UNION *anu; 679 ACPI_NAME_UNION *anu;
680 ACPI_STATUS rv; 680 ACPI_STATUS rv;
681 int clear, i; 681 int clear, i;
682 682
683 rv = AcpiGetObjectInfo(handle, &devinfo); 683 rv = AcpiGetObjectInfo(handle, &devinfo);
684 684
685 if (ACPI_FAILURE(rv)) 685 if (ACPI_FAILURE(rv))
686 return AE_OK; /* Do not terminate the walk. */ 686 return AE_OK; /* Do not terminate the walk. */
687 687
688 type = devinfo->Type; 688 type = devinfo->Type;
689 689
690 switch (type) { 690 switch (type) {
691 691
692 case ACPI_TYPE_DEVICE: 692 case ACPI_TYPE_DEVICE:
693 693
694#ifdef ACPI_ACTIVATE_DEV 694#ifdef ACPI_ACTIVATE_DEV
695 acpi_activate_device(handle, &devinfo); 695 acpi_activate_device(handle, &devinfo);
696#endif 696#endif
697 697
698 case ACPI_TYPE_PROCESSOR: 698 case ACPI_TYPE_PROCESSOR:
699 case ACPI_TYPE_THERMAL: 699 case ACPI_TYPE_THERMAL:
700 case ACPI_TYPE_POWER: 700 case ACPI_TYPE_POWER:
701 701
702 ad = malloc(sizeof(*ad), M_ACPI, M_NOWAIT | M_ZERO); 702 ad = malloc(sizeof(*ad), M_ACPI, M_NOWAIT | M_ZERO);
703 703
704 if (ad == NULL) 704 if (ad == NULL)
705 return AE_NO_MEMORY; 705 return AE_NO_MEMORY;
706 706
707 ad->ad_device = NULL; 707 ad->ad_device = NULL;
708 ad->ad_notify = NULL; 708 ad->ad_notify = NULL;
709 ad->ad_pciinfo = NULL; 709 ad->ad_pciinfo = NULL;
710 710
711 ad->ad_type = type; 711 ad->ad_type = type;
712 ad->ad_handle = handle; 712 ad->ad_handle = handle;
713 ad->ad_devinfo = devinfo; 713 ad->ad_devinfo = devinfo;
714 714
715 ad->ad_root = sc->sc_dev; 715 ad->ad_root = sc->sc_dev;
716 ad->ad_parent = awc->aw_parent; 716 ad->ad_parent = awc->aw_parent;
717 717
718 anu = (ACPI_NAME_UNION *)&devinfo->Name; 718 anu = (ACPI_NAME_UNION *)&devinfo->Name;
719 ad->ad_name[4] = '\0'; 719 ad->ad_name[4] = '\0';
720 720
721 for (i = 3, clear = 0; i >= 0; i--) { 721 for (i = 3, clear = 0; i >= 0; i--) {
722 722
723 if (clear == 0 && anu->Ascii[i] == '_') 723 if (clear == 0 && anu->Ascii[i] == '_')
724 ad->ad_name[i] = '\0'; 724 ad->ad_name[i] = '\0';
725 else { 725 else {
726 ad->ad_name[i] = anu->Ascii[i]; 726 ad->ad_name[i] = anu->Ascii[i];
727 clear = 1; 727 clear = 1;
728 } 728 }
729 } 729 }
730 730
731 if (ad->ad_name[0] == '\0') 731 if (ad->ad_name[0] == '\0')
732 ad->ad_name[0] = '_'; 732 ad->ad_name[0] = '_';
733 733
734 SIMPLEQ_INIT(&ad->ad_child_head); 734 SIMPLEQ_INIT(&ad->ad_child_head);
735 SIMPLEQ_INSERT_TAIL(&sc->ad_head, ad, ad_list); 735 SIMPLEQ_INSERT_TAIL(&sc->ad_head, ad, ad_list);
736 736
737 acpi_set_node(ad); 737 acpi_set_node(ad);
738 738
739 if (ad->ad_parent != NULL) { 739 if (ad->ad_parent != NULL) {
740 740
741 SIMPLEQ_INSERT_TAIL(&ad->ad_parent->ad_child_head, 741 SIMPLEQ_INSERT_TAIL(&ad->ad_parent->ad_child_head,
742 ad, ad_child_list); 742 ad, ad_child_list);
743 } 743 }
744 744
745 awc->aw_parent = ad; 745 awc->aw_parent = ad;
746 } 746 }
747 747
748 return AE_OK; 748 return AE_OK;
749} 749}
750 750
751static ACPI_STATUS 751static ACPI_STATUS
752acpi_make_devnode_post(ACPI_HANDLE handle, uint32_t level, 752acpi_make_devnode_post(ACPI_HANDLE handle, uint32_t level,
753 void *context, void **status) 753 void *context, void **status)
754{ 754{
755 struct acpi_walkcontext *awc = context; 755 struct acpi_walkcontext *awc = context;
756 756
757 KASSERT(awc != NULL); 757 KASSERT(awc != NULL);
758 KASSERT(awc->aw_parent != NULL); 758 KASSERT(awc->aw_parent != NULL);
759 759
760 if (handle == awc->aw_parent->ad_handle) 760 if (handle == awc->aw_parent->ad_handle)
761 awc->aw_parent = awc->aw_parent->ad_parent; 761 awc->aw_parent = awc->aw_parent->ad_parent;
762 762
763 return AE_OK; 763 return AE_OK;
764} 764}
765 765
766#ifdef ACPI_ACTIVATE_DEV 766#ifdef ACPI_ACTIVATE_DEV
767static void 767static void
768acpi_activate_device(ACPI_HANDLE handle, ACPI_DEVICE_INFO **di) 768acpi_activate_device(ACPI_HANDLE handle, ACPI_DEVICE_INFO **di)
769{ 769{
770 static const int valid = ACPI_VALID_STA | ACPI_VALID_HID; 770 static const int valid = ACPI_VALID_STA | ACPI_VALID_HID;
771 ACPI_DEVICE_INFO *newdi; 771 ACPI_DEVICE_INFO *newdi;
772 ACPI_STATUS rv; 772 ACPI_STATUS rv;
773 uint32_t old; 773 uint32_t old;
774 774
775 /* 775 /*
776 * If the device is valid and present, 776 * If the device is valid and present,
777 * but not enabled, try to activate it. 777 * but not enabled, try to activate it.
778 */ 778 */
779 if (((*di)->Valid & valid) != valid) 779 if (((*di)->Valid & valid) != valid)
780 return; 780 return;
781 781
782 old = (*di)->CurrentStatus; 782 old = (*di)->CurrentStatus;
783 783
784 if ((old & (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED)) != 784 if ((old & (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED)) !=
785 ACPI_STA_DEVICE_PRESENT) 785 ACPI_STA_DEVICE_PRESENT)
786 return; 786 return;
787 787
788 rv = acpi_allocate_resources(handle); 788 rv = acpi_allocate_resources(handle);
789 789
790 if (ACPI_FAILURE(rv)) 790 if (ACPI_FAILURE(rv))
791 goto fail; 791 goto fail;
792 792
793 rv = AcpiGetObjectInfo(handle, &newdi); 793 rv = AcpiGetObjectInfo(handle, &newdi);
794 794
795 if (ACPI_FAILURE(rv)) 795 if (ACPI_FAILURE(rv))
796 goto fail; 796 goto fail;
797 797
798 ACPI_FREE(*di); 798 ACPI_FREE(*di);
799 *di = newdi; 799 *di = newdi;
800 800
801 aprint_verbose_dev(acpi_softc->sc_dev, 801 aprint_verbose_dev(acpi_softc->sc_dev,
802 "%s activated, STA 0x%08X -> STA 0x%08X\n", 802 "%s activated, STA 0x%08X -> STA 0x%08X\n",
803 (*di)->HardwareId.String, old, (*di)->CurrentStatus); 803 (*di)->HardwareId.String, old, (*di)->CurrentStatus);
804 804
805 return; 805 return;
806 806
807fail: 807fail:
808 aprint_error_dev(acpi_softc->sc_dev, "failed to " 808 aprint_error_dev(acpi_softc->sc_dev, "failed to "
809 "activate %s\n", (*di)->HardwareId.String); 809 "activate %s\n", (*di)->HardwareId.String);
810} 810}
811 811
812/* 812/*
813 * XXX: This very incomplete. 813 * XXX: This very incomplete.
814 */ 814 */
815ACPI_STATUS 815ACPI_STATUS
816acpi_allocate_resources(ACPI_HANDLE handle) 816acpi_allocate_resources(ACPI_HANDLE handle)
817{ 817{
818 ACPI_BUFFER bufp, bufc, bufn; 818 ACPI_BUFFER bufp, bufc, bufn;
819 ACPI_RESOURCE *resp, *resc, *resn; 819 ACPI_RESOURCE *resp, *resc, *resn;
820 ACPI_RESOURCE_IRQ *irq; 820 ACPI_RESOURCE_IRQ *irq;
821 ACPI_RESOURCE_EXTENDED_IRQ *xirq; 821 ACPI_RESOURCE_EXTENDED_IRQ *xirq;
822 ACPI_STATUS rv; 822 ACPI_STATUS rv;
823 uint delta; 823 uint delta;
824 824
825 rv = acpi_get(handle, &bufp, AcpiGetPossibleResources); 825 rv = acpi_get(handle, &bufp, AcpiGetPossibleResources);
826 if (ACPI_FAILURE(rv)) 826 if (ACPI_FAILURE(rv))
827 goto out; 827 goto out;
828 rv = acpi_get(handle, &bufc, AcpiGetCurrentResources); 828 rv = acpi_get(handle, &bufc, AcpiGetCurrentResources);
829 if (ACPI_FAILURE(rv)) { 829 if (ACPI_FAILURE(rv)) {
830 goto out1; 830 goto out1;
831 } 831 }
832 832
833 bufn.Length = 1000; 833 bufn.Length = 1000;
834 bufn.Pointer = resn = malloc(bufn.Length, M_ACPI, M_WAITOK); 834 bufn.Pointer = resn = malloc(bufn.Length, M_ACPI, M_WAITOK);
835 resp = bufp.Pointer; 835 resp = bufp.Pointer;
836 resc = bufc.Pointer; 836 resc = bufc.Pointer;
837 while (resc->Type != ACPI_RESOURCE_TYPE_END_TAG && 837 while (resc->Type != ACPI_RESOURCE_TYPE_END_TAG &&
838 resp->Type != ACPI_RESOURCE_TYPE_END_TAG) { 838 resp->Type != ACPI_RESOURCE_TYPE_END_TAG) {
839 while (resc->Type != resp->Type && resp->Type != ACPI_RESOURCE_TYPE_END_TAG) 839 while (resc->Type != resp->Type && resp->Type != ACPI_RESOURCE_TYPE_END_TAG)
840 resp = ACPI_NEXT_RESOURCE(resp); 840 resp = ACPI_NEXT_RESOURCE(resp);
841 if (resp->Type == ACPI_RESOURCE_TYPE_END_TAG) 841 if (resp->Type == ACPI_RESOURCE_TYPE_END_TAG)
842 break; 842 break;
843 /* Found identical Id */ 843 /* Found identical Id */
844 resn->Type = resc->Type; 844 resn->Type = resc->Type;
845 switch (resc->Type) { 845 switch (resc->Type) {
846 case ACPI_RESOURCE_TYPE_IRQ: 846 case ACPI_RESOURCE_TYPE_IRQ:
847 memcpy(&resn->Data, &resp->Data, 847 memcpy(&resn->Data, &resp->Data,
848 sizeof(ACPI_RESOURCE_IRQ)); 848 sizeof(ACPI_RESOURCE_IRQ));
849 irq = (ACPI_RESOURCE_IRQ *)&resn->Data; 849 irq = (ACPI_RESOURCE_IRQ *)&resn->Data;
850 irq->Interrupts[0] = 850 irq->Interrupts[0] =
851 ((ACPI_RESOURCE_IRQ *)&resp->Data)-> 851 ((ACPI_RESOURCE_IRQ *)&resp->Data)->
852 Interrupts[irq->InterruptCount-1]; 852 Interrupts[irq->InterruptCount-1];
853 irq->InterruptCount = 1; 853 irq->InterruptCount = 1;
854 resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_IRQ); 854 resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_IRQ);
855 break; 855 break;
856 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 856 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
857 memcpy(&resn->Data, &resp->Data, 857 memcpy(&resn->Data, &resp->Data,
858 sizeof(ACPI_RESOURCE_EXTENDED_IRQ)); 858 sizeof(ACPI_RESOURCE_EXTENDED_IRQ));
859 xirq = (ACPI_RESOURCE_EXTENDED_IRQ *)&resn->Data; 859 xirq = (ACPI_RESOURCE_EXTENDED_IRQ *)&resn->Data;
860#if 0 860#if 0
861 /* 861 /*
862 * XXX: Not duplicating the interrupt logic above 862 * XXX: Not duplicating the interrupt logic above
863 * because its not clear what it accomplishes. 863 * because its not clear what it accomplishes.
864 */ 864 */
865 xirq->Interrupts[0] = 865 xirq->Interrupts[0] =
866 ((ACPI_RESOURCE_EXT_IRQ *)&resp->Data)-> 866 ((ACPI_RESOURCE_EXT_IRQ *)&resp->Data)->
867 Interrupts[irq->NumberOfInterrupts-1]; 867 Interrupts[irq->NumberOfInterrupts-1];
868 xirq->NumberOfInterrupts = 1; 868 xirq->NumberOfInterrupts = 1;
869#endif 869#endif
870 resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_EXTENDED_IRQ); 870 resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_EXTENDED_IRQ);
871 break; 871 break;
872 case ACPI_RESOURCE_TYPE_IO: 872 case ACPI_RESOURCE_TYPE_IO:
873 memcpy(&resn->Data, &resp->Data, 873 memcpy(&resn->Data, &resp->Data,
874 sizeof(ACPI_RESOURCE_IO)); 874 sizeof(ACPI_RESOURCE_IO));
875 resn->Length = resp->Length; 875 resn->Length = resp->Length;
876 break; 876 break;
877 default: 877 default:
878 aprint_error_dev(acpi_softc->sc_dev, 878 aprint_error_dev(acpi_softc->sc_dev,
879 "%s: invalid type %u\n", __func__, resc->Type); 879 "%s: invalid type %u\n", __func__, resc->Type);
880 rv = AE_BAD_DATA; 880 rv = AE_BAD_DATA;
881 goto out2; 881 goto out2;
882 } 882 }
883 resc = ACPI_NEXT_RESOURCE(resc); 883 resc = ACPI_NEXT_RESOURCE(resc);
884 resn = ACPI_NEXT_RESOURCE(resn); 884 resn = ACPI_NEXT_RESOURCE(resn);
885 resp = ACPI_NEXT_RESOURCE(resp); 885 resp = ACPI_NEXT_RESOURCE(resp);
886 delta = (uint8_t *)resn - (uint8_t *)bufn.Pointer; 886 delta = (uint8_t *)resn - (uint8_t *)bufn.Pointer;
887 if (delta >= 887 if (delta >=
888 bufn.Length-ACPI_RS_SIZE(ACPI_RESOURCE_DATA)) { 888 bufn.Length-ACPI_RS_SIZE(ACPI_RESOURCE_DATA)) {
889 bufn.Length *= 2; 889 bufn.Length *= 2;
890 bufn.Pointer = realloc(bufn.Pointer, bufn.Length, 890 bufn.Pointer = realloc(bufn.Pointer, bufn.Length,
891 M_ACPI, M_WAITOK); 891 M_ACPI, M_WAITOK);
892 resn = (ACPI_RESOURCE *)((uint8_t *)bufn.Pointer + 892 resn = (ACPI_RESOURCE *)((uint8_t *)bufn.Pointer +
893 delta); 893 delta);
894 } 894 }
895 } 895 }
896 896
897 if (resc->Type != ACPI_RESOURCE_TYPE_END_TAG) { 897 if (resc->Type != ACPI_RESOURCE_TYPE_END_TAG) {
898 aprint_error_dev(acpi_softc->sc_dev, 898 aprint_error_dev(acpi_softc->sc_dev,
899 "%s: resc not exhausted\n", __func__); 899 "%s: resc not exhausted\n", __func__);
900 rv = AE_BAD_DATA; 900 rv = AE_BAD_DATA;
901 goto out3; 901 goto out3;
902 } 902 }
903 903
904 resn->Type = ACPI_RESOURCE_TYPE_END_TAG; 904 resn->Type = ACPI_RESOURCE_TYPE_END_TAG;
905 rv = AcpiSetCurrentResources(handle, &bufn); 905 rv = AcpiSetCurrentResources(handle, &bufn);
906 906
907 if (ACPI_FAILURE(rv)) 907 if (ACPI_FAILURE(rv))
908 aprint_error_dev(acpi_softc->sc_dev, "%s: failed to set " 908 aprint_error_dev(acpi_softc->sc_dev, "%s: failed to set "
909 "resources: %s\n", __func__, AcpiFormatException(rv)); 909 "resources: %s\n", __func__, AcpiFormatException(rv));
910 910
911out3: 911out3:
912 free(bufn.Pointer, M_ACPI); 912 free(bufn.Pointer, M_ACPI);
913out2: 913out2:
914 ACPI_FREE(bufc.Pointer); 914 ACPI_FREE(bufc.Pointer);
915out1: 915out1:
916 ACPI_FREE(bufp.Pointer); 916 ACPI_FREE(bufp.Pointer);
917out: 917out:
918 return rv; 918 return rv;
919} 919}
920#endif /* ACPI_ACTIVATE_DEV */ 920#endif /* ACPI_ACTIVATE_DEV */
921 921
922/* 922/*
923 * Device attachment. 923 * Device attachment.
924 */ 924 */
925static int 925static int
926acpi_rescan(device_t self, const char *ifattr, const int *locators) 926acpi_rescan(device_t self, const char *ifattr, const int *locators)
927{ 927{
928 struct acpi_softc *sc = device_private(self); 928 struct acpi_softc *sc = device_private(self);
929 929
930 if (ifattr_match(ifattr, "acpinodebus")) 930 if (ifattr_match(ifattr, "acpinodebus"))
931 acpi_rescan_nodes(sc); 931 acpi_rescan_nodes(sc);
932 932
933 if (ifattr_match(ifattr, "acpiapmbus") && sc->sc_apmbus == NULL) 933 if (ifattr_match(ifattr, "acpiapmbus") && sc->sc_apmbus == NULL)
934 sc->sc_apmbus = config_found_ia(sc->sc_dev, 934 sc->sc_apmbus = config_found_ia(sc->sc_dev,
935 "acpiapmbus", NULL, NULL); 935 "acpiapmbus", NULL, NULL);
936 936
937 return 0; 937 return 0;
938} 938}
939 939
940static void 940static void
941acpi_rescan_nodes(struct acpi_softc *sc) 941acpi_rescan_nodes(struct acpi_softc *sc)
942{ 942{
943 struct acpi_attach_args aa; 943 struct acpi_attach_args aa;
944 struct acpi_devnode *ad; 944 struct acpi_devnode *ad;
945 ACPI_DEVICE_INFO *di; 945 ACPI_DEVICE_INFO *di;
946 946
947 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 947 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
948 948
949 if (ad->ad_device != NULL) 949 if (ad->ad_device != NULL)
950 continue; 950 continue;
951 951
952 /* 952 /*
953 * There is a bug in ACPICA: it defines the type 953 * There is a bug in ACPICA: it defines the type
954 * of the scopes incorrectly for its own reasons. 954 * of the scopes incorrectly for its own reasons.
955 */ 955 */
956 if (acpi_is_scope(ad) != false) 956 if (acpi_is_scope(ad) != false)
957 continue; 957 continue;
958 958
959 di = ad->ad_devinfo; 959 di = ad->ad_devinfo;
960 960
961 /* 961 /*
962 * We only attach devices which are present, enabled, and 962 * We only attach devices which are present, enabled, and
963 * functioning properly. However, if a device is enabled, 963 * functioning properly. However, if a device is enabled,
964 * it is decoding resources and we should claim these, 964 * it is decoding resources and we should claim these,
965 * if possible. This requires changes to bus_space(9). 965 * if possible. This requires changes to bus_space(9).
 966 * Note: there is a possible race condition, because _STA
 967 * may have changed since di->CurrentStatus was set.
966 */ 968 */
967 if (di->Type == ACPI_TYPE_DEVICE) { 969 if (di->Type == ACPI_TYPE_DEVICE) {
968 970
969 if ((di->Valid & ACPI_VALID_STA) != 0 && 971 if ((di->Valid & ACPI_VALID_STA) != 0 &&
970 (di->CurrentStatus & ACPI_STA_OK) != ACPI_STA_OK) 972 (di->CurrentStatus & ACPI_STA_OK) != ACPI_STA_OK)
971 continue; 973 continue;
972 } 974 }
973 975
974 /* 976 /*
975 * The same problem as above. As for example 977 * The same problem as above. As for example
976 * thermal zones and power resources do not 978 * thermal zones and power resources do not
977 * have a valid HID, only evaluate devices. 979 * have a valid HID, only evaluate devices.
978 */ 980 */
979 if (di->Type == ACPI_TYPE_DEVICE && 981 if (di->Type == ACPI_TYPE_DEVICE &&
980 (di->Valid & ACPI_VALID_HID) == 0) 982 (di->Valid & ACPI_VALID_HID) == 0)
981 continue; 983 continue;
982 984
983 /* 985 /*
984 * Handled internally. 986 * Handled internally.
985 */ 987 */
986 if (di->Type == ACPI_TYPE_POWER) 988 if (di->Type == ACPI_TYPE_POWER)
987 continue; 989 continue;
988 990
989 /* 991 /*
990 * Skip ignored HIDs. 992 * Skip ignored HIDs.
991 */ 993 */
992 if (acpi_match_hid(di, acpi_ignored_ids)) 994 if (acpi_match_hid(di, acpi_ignored_ids))
993 continue; 995 continue;
994 996
995 aa.aa_node = ad; 997 aa.aa_node = ad;
996 aa.aa_iot = sc->sc_iot; 998 aa.aa_iot = sc->sc_iot;
997 aa.aa_memt = sc->sc_memt; 999 aa.aa_memt = sc->sc_memt;
998 aa.aa_pc = sc->sc_pc; 1000 aa.aa_pc = sc->sc_pc;
999 aa.aa_pciflags = sc->sc_pciflags; 1001 aa.aa_pciflags = sc->sc_pciflags;
1000 aa.aa_ic = sc->sc_ic; 1002 aa.aa_ic = sc->sc_ic;
1001 1003
1002 ad->ad_device = config_found_ia(sc->sc_dev, 1004 ad->ad_device = config_found_ia(sc->sc_dev,
1003 "acpinodebus", &aa, acpi_print); 1005 "acpinodebus", &aa, acpi_print);
1004 } 1006 }
1005} 1007}
1006 1008
1007static void 1009static void
1008acpi_rescan_capabilities(struct acpi_softc *sc) 1010acpi_rescan_capabilities(struct acpi_softc *sc)
1009{ 1011{
1010 struct acpi_devnode *ad; 1012 struct acpi_devnode *ad;
1011 ACPI_HANDLE tmp; 1013 ACPI_HANDLE tmp;
1012 ACPI_STATUS rv; 1014 ACPI_STATUS rv;
1013 1015
1014 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 1016 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
1015 1017
1016 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE) 1018 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE)
1017 continue; 1019 continue;
1018 1020
1019 /* 1021 /*
1020 * Scan power resource capabilities. 1022 * Scan power resource capabilities.
1021 * 1023 *
1022 * If any power states are supported, 1024 * If any power states are supported,
1023 * at least _PR0 and _PR3 must be present. 1025 * at least _PR0 and _PR3 must be present.
1024 */ 1026 */
1025 rv = AcpiGetHandle(ad->ad_handle, "_PR0", &tmp); 1027 rv = AcpiGetHandle(ad->ad_handle, "_PR0", &tmp);
1026 1028
1027 if (ACPI_SUCCESS(rv)) { 1029 if (ACPI_SUCCESS(rv)) {
1028 ad->ad_flags |= ACPI_DEVICE_POWER; 1030 ad->ad_flags |= ACPI_DEVICE_POWER;
1029 acpi_power_add(ad); 1031 acpi_power_add(ad);
1030 } 1032 }
1031 1033
1032 /* 1034 /*
1033 * Scan wake-up capabilities. 1035 * Scan wake-up capabilities.
1034 */ 1036 */
1035 rv = AcpiGetHandle(ad->ad_handle, "_PRW", &tmp); 1037 rv = AcpiGetHandle(ad->ad_handle, "_PRW", &tmp);
1036 1038
1037 if (ACPI_SUCCESS(rv)) { 1039 if (ACPI_SUCCESS(rv)) {
1038 ad->ad_flags |= ACPI_DEVICE_WAKEUP; 1040 ad->ad_flags |= ACPI_DEVICE_WAKEUP;
1039 acpi_wakedev_add(ad); 1041 acpi_wakedev_add(ad);
1040 } 1042 }
1041 } 1043 }
1042} 1044}
1043 1045
1044static int 1046static int
1045acpi_print(void *aux, const char *pnp) 1047acpi_print(void *aux, const char *pnp)
1046{ 1048{
1047 struct acpi_attach_args *aa = aux; 1049 struct acpi_attach_args *aa = aux;
1048 ACPI_STATUS rv; 1050 ACPI_STATUS rv;
1049 1051
1050 if (pnp) { 1052 if (pnp) {
1051 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) { 1053 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) {
1052 char *pnpstr = 1054 char *pnpstr =
1053 aa->aa_node->ad_devinfo->HardwareId.String; 1055 aa->aa_node->ad_devinfo->HardwareId.String;
1054 ACPI_BUFFER buf; 1056 ACPI_BUFFER buf;
1055 1057
1056 aprint_normal("%s (%s) ", aa->aa_node->ad_name, 1058 aprint_normal("%s (%s) ", aa->aa_node->ad_name,
1057 pnpstr); 1059 pnpstr);
1058 1060
1059 rv = acpi_eval_struct(aa->aa_node->ad_handle, 1061 rv = acpi_eval_struct(aa->aa_node->ad_handle,
1060 "_STR", &buf); 1062 "_STR", &buf);
1061 if (ACPI_SUCCESS(rv)) { 1063 if (ACPI_SUCCESS(rv)) {
1062 ACPI_OBJECT *obj = buf.Pointer; 1064 ACPI_OBJECT *obj = buf.Pointer;
1063 switch (obj->Type) { 1065 switch (obj->Type) {
1064 case ACPI_TYPE_STRING: 1066 case ACPI_TYPE_STRING:
1065 aprint_normal("[%s] ", obj->String.Pointer); 1067 aprint_normal("[%s] ", obj->String.Pointer);
1066 break; 1068 break;
1067 case ACPI_TYPE_BUFFER: 1069 case ACPI_TYPE_BUFFER:
1068 aprint_normal("buffer %p ", obj->Buffer.Pointer); 1070 aprint_normal("buffer %p ", obj->Buffer.Pointer);
1069 break; 1071 break;
1070 default: 1072 default:
1071 aprint_normal("type %u ",obj->Type); 1073 aprint_normal("type %u ",obj->Type);
1072 break; 1074 break;
1073 } 1075 }
1074 ACPI_FREE(buf.Pointer); 1076 ACPI_FREE(buf.Pointer);
1075 } 1077 }
1076 else 1078 else
1077 acpi_print_dev(pnpstr); 1079 acpi_print_dev(pnpstr);
1078 1080
1079 aprint_normal("at %s", pnp); 1081 aprint_normal("at %s", pnp);
1080 } else if (aa->aa_node->ad_devinfo->Type != ACPI_TYPE_DEVICE) { 1082 } else if (aa->aa_node->ad_devinfo->Type != ACPI_TYPE_DEVICE) {
1081 aprint_normal("%s (ACPI Object Type '%s' " 1083 aprint_normal("%s (ACPI Object Type '%s' "
1082 "[0x%02x]) ", aa->aa_node->ad_name, 1084 "[0x%02x]) ", aa->aa_node->ad_name,
1083 AcpiUtGetTypeName(aa->aa_node->ad_devinfo->Type), 1085 AcpiUtGetTypeName(aa->aa_node->ad_devinfo->Type),
1084 aa->aa_node->ad_devinfo->Type); 1086 aa->aa_node->ad_devinfo->Type);
1085 aprint_normal("at %s", pnp); 1087 aprint_normal("at %s", pnp);
1086 } else 1088 } else
1087 return 0; 1089 return 0;
1088 } else { 1090 } else {
1089 aprint_normal(" (%s", aa->aa_node->ad_name); 1091 aprint_normal(" (%s", aa->aa_node->ad_name);
1090 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) { 1092 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) {
1091 aprint_normal(", %s", aa->aa_node->ad_devinfo->HardwareId.String); 1093 aprint_normal(", %s", aa->aa_node->ad_devinfo->HardwareId.String);
1092 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_UID) { 1094 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_UID) {
1093 const char *uid; 1095 const char *uid;
1094 1096
1095 uid = aa->aa_node->ad_devinfo->UniqueId.String; 1097 uid = aa->aa_node->ad_devinfo->UniqueId.String;
1096 if (uid[0] == '\0') 1098 if (uid[0] == '\0')
1097 uid = "<null>"; 1099 uid = "<null>";
1098 aprint_normal("-%s", uid); 1100 aprint_normal("-%s", uid);
1099 } 1101 }
1100 } 1102 }
1101 aprint_normal(")"); 1103 aprint_normal(")");
1102 } 1104 }
1103 1105
1104 return UNCONF; 1106 return UNCONF;
1105} 1107}
1106 1108
1107/* 1109/*
1108 * Notify. 1110 * Notify.
1109 */ 1111 */
1110static void 1112static void
1111acpi_notify_handler(ACPI_HANDLE handle, uint32_t event, void *aux) 1113acpi_notify_handler(ACPI_HANDLE handle, uint32_t event, void *aux)
1112{ 1114{
1113 struct acpi_softc *sc = acpi_softc; 1115 struct acpi_softc *sc = acpi_softc;
1114 struct acpi_devnode *ad; 1116 struct acpi_devnode *ad;
1115 1117
1116 KASSERT(sc != NULL); 1118 KASSERT(sc != NULL);
1117 KASSERT(aux == NULL); 1119 KASSERT(aux == NULL);
1118 KASSERT(acpi_active != 0); 1120 KASSERT(acpi_active != 0);
1119 1121
1120 if (acpi_suspended != 0) 1122 if (acpi_suspended != 0)
1121 return; 1123 return;
1122 1124
1123 /* 1125 /*
1124 * System: 0x00 - 0x7F. 1126 * System: 0x00 - 0x7F.
1125 * Device: 0x80 - 0xFF. 1127 * Device: 0x80 - 0xFF.
1126 */ 1128 */
1127 switch (event) { 1129 switch (event) {
1128 1130
1129 case ACPI_NOTIFY_BUS_CHECK: 1131 case ACPI_NOTIFY_BUS_CHECK:
1130 case ACPI_NOTIFY_DEVICE_CHECK: 1132 case ACPI_NOTIFY_DEVICE_CHECK:
1131 case ACPI_NOTIFY_DEVICE_WAKE: 1133 case ACPI_NOTIFY_DEVICE_WAKE:
1132 case ACPI_NOTIFY_EJECT_REQUEST: 1134 case ACPI_NOTIFY_EJECT_REQUEST:
1133 case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: 1135 case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
1134 case ACPI_NOTIFY_FREQUENCY_MISMATCH: 1136 case ACPI_NOTIFY_FREQUENCY_MISMATCH:
1135 case ACPI_NOTIFY_BUS_MODE_MISMATCH: 1137 case ACPI_NOTIFY_BUS_MODE_MISMATCH:
1136 case ACPI_NOTIFY_POWER_FAULT: 1138 case ACPI_NOTIFY_POWER_FAULT:
1137 case ACPI_NOTIFY_CAPABILITIES_CHECK: 1139 case ACPI_NOTIFY_CAPABILITIES_CHECK:
1138 case ACPI_NOTIFY_DEVICE_PLD_CHECK: 1140 case ACPI_NOTIFY_DEVICE_PLD_CHECK:
1139 case ACPI_NOTIFY_RESERVED: 1141 case ACPI_NOTIFY_RESERVED:
1140 case ACPI_NOTIFY_LOCALITY_UPDATE: 1142 case ACPI_NOTIFY_LOCALITY_UPDATE:
1141 break; 1143 break;
1142 } 1144 }
1143 1145
1144 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "notification 0x%02X for " 1146 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "notification 0x%02X for "
1145 "%s (%p)\n", event, acpi_name(handle), handle)); 1147 "%s (%p)\n", event, acpi_name(handle), handle));
1146 1148
1147 /* 1149 /*
1148 * We deliver notifications only to drivers 1150 * We deliver notifications only to drivers
1149 * that have been succesfully attached and 1151 * that have been succesfully attached and
1150 * that have registered a handler with us. 1152 * that have registered a handler with us.
1151 * The opaque pointer is always the device_t. 1153 * The opaque pointer is always the device_t.
1152 */ 1154 */
1153 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 1155 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
1154 1156
1155 if (ad->ad_device == NULL) 1157 if (ad->ad_device == NULL)
1156 continue; 1158 continue;
1157 1159
1158 if (ad->ad_notify == NULL) 1160 if (ad->ad_notify == NULL)
1159 continue; 1161 continue;
1160 1162
1161 if (ad->ad_handle != handle) 1163 if (ad->ad_handle != handle)
1162 continue; 1164 continue;
1163 1165
1164 (*ad->ad_notify)(ad->ad_handle, event, ad->ad_device); 1166 (*ad->ad_notify)(ad->ad_handle, event, ad->ad_device);
1165 1167
1166 return; 1168 return;
1167 } 1169 }
1168 1170
1169 aprint_debug_dev(sc->sc_dev, "unhandled notify 0x%02X " 1171 aprint_debug_dev(sc->sc_dev, "unhandled notify 0x%02X "
1170 "for %s (%p)\n", event, acpi_name(handle), handle); 1172 "for %s (%p)\n", event, acpi_name(handle), handle);
1171} 1173}
1172 1174
1173bool 1175bool
1174acpi_register_notify(struct acpi_devnode *ad, ACPI_NOTIFY_HANDLER notify) 1176acpi_register_notify(struct acpi_devnode *ad, ACPI_NOTIFY_HANDLER notify)
1175{ 1177{
1176 struct acpi_softc *sc = acpi_softc; 1178 struct acpi_softc *sc = acpi_softc;
1177 1179
1178 KASSERT(sc != NULL); 1180 KASSERT(sc != NULL);
1179 KASSERT(acpi_active != 0); 1181 KASSERT(acpi_active != 0);
1180 1182
1181 if (acpi_suspended != 0) 1183 if (acpi_suspended != 0)
1182 goto fail; 1184 goto fail;
1183 1185
1184 if (ad == NULL || notify == NULL) 1186 if (ad == NULL || notify == NULL)
1185 goto fail; 1187 goto fail;
1186 1188
1187 ad->ad_notify = notify; 1189 ad->ad_notify = notify;
1188 1190
1189 return true; 1191 return true;
1190 1192
1191fail: 1193fail:
1192 aprint_error_dev(sc->sc_dev, "failed to register notify " 1194 aprint_error_dev(sc->sc_dev, "failed to register notify "
1193 "handler for %s (%p)\n", ad->ad_name, ad->ad_handle); 1195 "handler for %s (%p)\n", ad->ad_name, ad->ad_handle);
1194 1196
1195 return false; 1197 return false;
1196} 1198}
1197 1199
1198void 1200void
1199acpi_deregister_notify(struct acpi_devnode *ad) 1201acpi_deregister_notify(struct acpi_devnode *ad)
1200{ 1202{
1201 1203
1202 ad->ad_notify = NULL; 1204 ad->ad_notify = NULL;
1203} 1205}
1204 1206
1205/* 1207/*
1206 * Fixed buttons. 1208 * Fixed buttons.
1207 */ 1209 */
1208static void 1210static void
1209acpi_register_fixed_button(struct acpi_softc *sc, int event) 1211acpi_register_fixed_button(struct acpi_softc *sc, int event)
1210{ 1212{
1211 struct sysmon_pswitch *smpsw; 1213 struct sysmon_pswitch *smpsw;
1212 ACPI_STATUS rv; 1214 ACPI_STATUS rv;
1213 int type; 1215 int type;
1214 1216
1215 switch (event) { 1217 switch (event) {
1216 1218
1217 case ACPI_EVENT_POWER_BUTTON: 1219 case ACPI_EVENT_POWER_BUTTON:
1218 1220
1219 if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) != 0) 1221 if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) != 0)
1220 return; 1222 return;
1221 1223
1222 type = PSWITCH_TYPE_POWER; 1224 type = PSWITCH_TYPE_POWER;
1223 smpsw = &sc->sc_smpsw_power; 1225 smpsw = &sc->sc_smpsw_power;
1224 break; 1226 break;
1225 1227
1226 case ACPI_EVENT_SLEEP_BUTTON: 1228 case ACPI_EVENT_SLEEP_BUTTON:
1227 1229
1228 if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) != 0) 1230 if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) != 0)
1229 return; 1231 return;
1230 1232
1231 type = PSWITCH_TYPE_SLEEP; 1233 type = PSWITCH_TYPE_SLEEP;
1232 smpsw = &sc->sc_smpsw_sleep; 1234 smpsw = &sc->sc_smpsw_sleep;
1233 break; 1235 break;
1234 1236
1235 default: 1237 default:
1236 rv = AE_TYPE; 1238 rv = AE_TYPE;
1237 goto fail; 1239 goto fail;
1238 } 1240 }
1239 1241
1240 smpsw->smpsw_type = type; 1242 smpsw->smpsw_type = type;
1241 smpsw->smpsw_name = device_xname(sc->sc_dev); 1243 smpsw->smpsw_name = device_xname(sc->sc_dev);
1242 1244
1243 if (sysmon_pswitch_register(smpsw) != 0) { 1245 if (sysmon_pswitch_register(smpsw) != 0) {
1244 rv = AE_ERROR; 1246 rv = AE_ERROR;
1245 goto fail; 1247 goto fail;
1246 } 1248 }
1247 1249
1248 rv = AcpiInstallFixedEventHandler(event, 1250 rv = AcpiInstallFixedEventHandler(event,
1249 acpi_fixed_button_handler, smpsw); 1251 acpi_fixed_button_handler, smpsw);
1250 1252
1251 if (ACPI_FAILURE(rv)) { 1253 if (ACPI_FAILURE(rv)) {
1252 sysmon_pswitch_unregister(smpsw); 1254 sysmon_pswitch_unregister(smpsw);
1253 goto fail; 1255 goto fail;
1254 } 1256 }
1255 1257
1256 aprint_debug_dev(sc->sc_dev, "fixed %s button present\n", 1258 aprint_debug_dev(sc->sc_dev, "fixed %s button present\n",
1257 (type != ACPI_EVENT_SLEEP_BUTTON) ? "power" : "sleep"); 1259 (type != ACPI_EVENT_SLEEP_BUTTON) ? "power" : "sleep");
1258 1260
1259 return; 1261 return;
1260 1262
1261fail: 1263fail:
1262 aprint_error_dev(sc->sc_dev, "failed to register " 1264 aprint_error_dev(sc->sc_dev, "failed to register "
1263 "fixed event: %s\n", AcpiFormatException(rv)); 1265 "fixed event: %s\n", AcpiFormatException(rv));
1264} 1266}
1265 1267
1266static void 1268static void
1267acpi_deregister_fixed_button(struct acpi_softc *sc, int event) 1269acpi_deregister_fixed_button(struct acpi_softc *sc, int event)
1268{ 1270{
1269 struct sysmon_pswitch *smpsw; 1271 struct sysmon_pswitch *smpsw;
1270 ACPI_STATUS rv; 1272 ACPI_STATUS rv;
1271 1273
1272 switch (event) { 1274 switch (event) {
1273 1275
1274 case ACPI_EVENT_POWER_BUTTON: 1276 case ACPI_EVENT_POWER_BUTTON:
1275 smpsw = &sc->sc_smpsw_power; 1277 smpsw = &sc->sc_smpsw_power;
1276 1278
1277 if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) != 0) { 1279 if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) != 0) {
1278 KASSERT(smpsw->smpsw_type != PSWITCH_TYPE_POWER); 1280 KASSERT(smpsw->smpsw_type != PSWITCH_TYPE_POWER);
1279 return; 1281 return;
1280 } 1282 }
1281 1283
1282 break; 1284 break;
1283 1285
1284 case ACPI_EVENT_SLEEP_BUTTON: 1286 case ACPI_EVENT_SLEEP_BUTTON:
1285 smpsw = &sc->sc_smpsw_sleep; 1287 smpsw = &sc->sc_smpsw_sleep;
1286 1288
1287 if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) != 0) { 1289 if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) != 0) {
1288 KASSERT(smpsw->smpsw_type != PSWITCH_TYPE_SLEEP); 1290 KASSERT(smpsw->smpsw_type != PSWITCH_TYPE_SLEEP);
1289 return; 1291 return;
1290 } 1292 }
1291 1293
1292 break; 1294 break;
1293 1295
1294 default: 1296 default:
1295 rv = AE_TYPE; 1297 rv = AE_TYPE;
1296 goto fail; 1298 goto fail;
1297 } 1299 }
1298 1300
1299 rv = AcpiRemoveFixedEventHandler(event, acpi_fixed_button_handler); 1301 rv = AcpiRemoveFixedEventHandler(event, acpi_fixed_button_handler);
1300 1302
1301 if (ACPI_SUCCESS(rv)) { 1303 if (ACPI_SUCCESS(rv)) {
1302 sysmon_pswitch_unregister(smpsw); 1304 sysmon_pswitch_unregister(smpsw);
1303 return; 1305 return;
1304 } 1306 }
1305 1307
1306fail: 1308fail:
1307 aprint_error_dev(sc->sc_dev, "failed to deregister " 1309 aprint_error_dev(sc->sc_dev, "failed to deregister "
1308 "fixed event: %s\n", AcpiFormatException(rv)); 1310 "fixed event: %s\n", AcpiFormatException(rv));
1309} 1311}
1310 1312
1311static uint32_t 1313static uint32_t
1312acpi_fixed_button_handler(void *context) 1314acpi_fixed_button_handler(void *context)
1313{ 1315{
1314 static const int handler = OSL_NOTIFY_HANDLER; 1316 static const int handler = OSL_NOTIFY_HANDLER;
1315 struct sysmon_pswitch *smpsw = context; 1317 struct sysmon_pswitch *smpsw = context;
1316 1318
1317 (void)AcpiOsExecute(handler, acpi_fixed_button_pressed, smpsw); 1319 (void)AcpiOsExecute(handler, acpi_fixed_button_pressed, smpsw);
1318 1320
1319 return ACPI_INTERRUPT_HANDLED; 1321 return ACPI_INTERRUPT_HANDLED;
1320} 1322}
1321 1323
1322static void 1324static void
1323acpi_fixed_button_pressed(void *context) 1325acpi_fixed_button_pressed(void *context)
1324{ 1326{
1325 struct sysmon_pswitch *smpsw = context; 1327 struct sysmon_pswitch *smpsw = context;
1326 1328
1327 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s fixed button pressed\n", 1329 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s fixed button pressed\n",
1328 (smpsw->smpsw_type != ACPI_EVENT_SLEEP_BUTTON) ? 1330 (smpsw->smpsw_type != ACPI_EVENT_SLEEP_BUTTON) ?
1329 "power" : "sleep")); 1331 "power" : "sleep"));
1330 1332
1331 sysmon_pswitch_event(smpsw, PSWITCH_EVENT_PRESSED); 1333 sysmon_pswitch_event(smpsw, PSWITCH_EVENT_PRESSED);
1332} 1334}
1333 1335
1334/* 1336/*
1335 * Sleep. 1337 * Sleep.
1336 */ 1338 */
1337static void 1339static void
1338acpi_sleep_init(struct acpi_softc *sc) 1340acpi_sleep_init(struct acpi_softc *sc)
1339{ 1341{
1340 uint8_t a, b, i; 1342 uint8_t a, b, i;
1341 ACPI_STATUS rv; 1343 ACPI_STATUS rv;
1342 1344
1343 CTASSERT(ACPI_STATE_S0 == 0 && ACPI_STATE_S1 == 1); 1345 CTASSERT(ACPI_STATE_S0 == 0 && ACPI_STATE_S1 == 1);
1344 CTASSERT(ACPI_STATE_S2 == 2 && ACPI_STATE_S3 == 3); 1346 CTASSERT(ACPI_STATE_S2 == 2 && ACPI_STATE_S3 == 3);
1345 CTASSERT(ACPI_STATE_S4 == 4 && ACPI_STATE_S5 == 5); 1347 CTASSERT(ACPI_STATE_S4 == 4 && ACPI_STATE_S5 == 5);
1346 1348
1347 /* 1349 /*
1348 * Evaluate supported sleep states. 1350 * Evaluate supported sleep states.
1349 */ 1351 */
1350 for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) { 1352 for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) {
1351 1353
1352 rv = AcpiGetSleepTypeData(i, &a, &b); 1354 rv = AcpiGetSleepTypeData(i, &a, &b);
1353 1355
1354 if (ACPI_SUCCESS(rv)) 1356 if (ACPI_SUCCESS(rv))
1355 sc->sc_sleepstates |= __BIT(i); 1357 sc->sc_sleepstates |= __BIT(i);
1356 } 1358 }
1357} 1359}
1358 1360
1359void 1361void
1360acpi_enter_sleep_state(struct acpi_softc *sc, int state) 1362acpi_enter_sleep_state(struct acpi_softc *sc, int state)
1361{ 1363{
1362 ACPI_STATUS rv; 1364 ACPI_STATUS rv;
1363 int err; 1365 int err;
1364 1366
1365 if (state == sc->sc_sleepstate) 1367 if (state == sc->sc_sleepstate)
1366 return; 1368 return;
1367 1369
1368 aprint_normal_dev(sc->sc_dev, "entering state S%d\n", state); 1370 aprint_normal_dev(sc->sc_dev, "entering state S%d\n", state);
1369 1371
1370 switch (state) { 1372 switch (state) {
1371 1373
1372 case ACPI_STATE_S0: 1374 case ACPI_STATE_S0:
1373 sc->sc_sleepstate = ACPI_STATE_S0; 1375 sc->sc_sleepstate = ACPI_STATE_S0;
1374 return; 1376 return;
1375 1377
1376 case ACPI_STATE_S1: 1378 case ACPI_STATE_S1:
1377 case ACPI_STATE_S2: 1379 case ACPI_STATE_S2:
1378 case ACPI_STATE_S3: 1380 case ACPI_STATE_S3:
1379 case ACPI_STATE_S4: 1381 case ACPI_STATE_S4:
1380 1382
1381 if ((sc->sc_sleepstates & __BIT(state)) == 0) { 1383 if ((sc->sc_sleepstates & __BIT(state)) == 0) {
1382 aprint_error_dev(sc->sc_dev, "sleep state " 1384 aprint_error_dev(sc->sc_dev, "sleep state "
1383 "S%d is not available\n", state); 1385 "S%d is not available\n", state);
1384 return; 1386 return;
1385 } 1387 }
1386 1388
1387 /* 1389 /*
1388 * Evaluate the _TTS method. This should be done before 1390 * Evaluate the _TTS method. This should be done before
1389 * pmf_system_suspend(9) and the evaluation of _PTS. 1391 * pmf_system_suspend(9) and the evaluation of _PTS.
1390 * We should also re-evaluate this once we return to 1392 * We should also re-evaluate this once we return to
1391 * S0 or if we abort the sleep state transition in the 1393 * S0 or if we abort the sleep state transition in the
1392 * middle (see ACPI 3.0, section 7.3.6). In reality, 1394 * middle (see ACPI 3.0, section 7.3.6). In reality,
1393 * however, the _TTS method is seldom seen in the field. 1395 * however, the _TTS method is seldom seen in the field.
1394 */ 1396 */
1395 rv = acpi_eval_set_integer(NULL, "\\_TTS", state); 1397 rv = acpi_eval_set_integer(NULL, "\\_TTS", state);
1396 1398
1397 if (ACPI_SUCCESS(rv)) 1399 if (ACPI_SUCCESS(rv))
1398 aprint_debug_dev(sc->sc_dev, "evaluated _TTS\n"); 1400 aprint_debug_dev(sc->sc_dev, "evaluated _TTS\n");
1399 1401
1400 if (state != ACPI_STATE_S1 && 1402 if (state != ACPI_STATE_S1 &&
1401 pmf_system_suspend(PMF_Q_NONE) != true) { 1403 pmf_system_suspend(PMF_Q_NONE) != true) {
1402 aprint_error_dev(sc->sc_dev, "aborting suspend\n"); 1404 aprint_error_dev(sc->sc_dev, "aborting suspend\n");
1403 break; 1405 break;
1404 } 1406 }
1405 1407
1406 /* 1408 /*
1407 * This will evaluate the _PTS and _SST methods, 1409 * This will evaluate the _PTS and _SST methods,
1408 * but unlike the documentation claims, not _GTS, 1410 * but unlike the documentation claims, not _GTS,
1409 * which is evaluated in AcpiEnterSleepState(). 1411 * which is evaluated in AcpiEnterSleepState().
1410 * This must be called with interrupts enabled. 1412 * This must be called with interrupts enabled.
1411 */ 1413 */
1412 rv = AcpiEnterSleepStatePrep(state); 1414 rv = AcpiEnterSleepStatePrep(state);
1413 1415
1414 if (ACPI_FAILURE(rv)) { 1416 if (ACPI_FAILURE(rv)) {
1415 aprint_error_dev(sc->sc_dev, "failed to prepare " 1417 aprint_error_dev(sc->sc_dev, "failed to prepare "
1416 "S%d: %s\n", state, AcpiFormatException(rv)); 1418 "S%d: %s\n", state, AcpiFormatException(rv));
1417 break; 1419 break;
1418 } 1420 }
1419 1421
1420 /* 1422 /*
1421 * After the _PTS method has been evaluated, we can 1423 * After the _PTS method has been evaluated, we can
1422 * enable wake and evaluate _PSW (ACPI 4.0, p. 284). 1424 * enable wake and evaluate _PSW (ACPI 4.0, p. 284).
1423 */ 1425 */
1424 acpi_wakedev_commit(sc, state); 1426 acpi_wakedev_commit(sc, state);
1425 1427
1426 sc->sc_sleepstate = state; 1428 sc->sc_sleepstate = state;
1427 1429
1428 if (state == ACPI_STATE_S1) { 1430 if (state == ACPI_STATE_S1) {
1429 1431
1430 /* Just enter the state. */ 1432 /* Just enter the state. */
1431 acpi_md_OsDisableInterrupt(); 1433 acpi_md_OsDisableInterrupt();
1432 rv = AcpiEnterSleepState(state); 1434 rv = AcpiEnterSleepState(state);
1433 1435
1434 if (ACPI_FAILURE(rv)) 1436 if (ACPI_FAILURE(rv))
1435 aprint_error_dev(sc->sc_dev, "failed to " 1437 aprint_error_dev(sc->sc_dev, "failed to "
1436 "enter S1: %s\n", AcpiFormatException(rv)); 1438 "enter S1: %s\n", AcpiFormatException(rv));
1437 1439
1438 (void)AcpiLeaveSleepState(state); 1440 (void)AcpiLeaveSleepState(state);
1439 1441
1440 } else { 1442 } else {
1441 1443
1442 err = acpi_md_sleep(state); 1444 err = acpi_md_sleep(state);
1443 1445
1444 if (state == ACPI_STATE_S4) 1446 if (state == ACPI_STATE_S4)
1445 AcpiEnable(); 1447 AcpiEnable();
1446 1448
1447 pmf_system_bus_resume(PMF_Q_NONE); 1449 pmf_system_bus_resume(PMF_Q_NONE);
1448 (void)AcpiLeaveSleepState(state); 1450 (void)AcpiLeaveSleepState(state);
1449 pmf_system_resume(PMF_Q_NONE); 1451 pmf_system_resume(PMF_Q_NONE);
1450 } 1452 }
1451 1453
1452 break; 1454 break;
1453 1455
1454 case ACPI_STATE_S5: 1456 case ACPI_STATE_S5:
1455 1457
1456 (void)acpi_eval_set_integer(NULL, "\\_TTS", ACPI_STATE_S5); 1458 (void)acpi_eval_set_integer(NULL, "\\_TTS", ACPI_STATE_S5);
1457 1459
1458 rv = AcpiEnterSleepStatePrep(ACPI_STATE_S5); 1460 rv = AcpiEnterSleepStatePrep(ACPI_STATE_S5);
1459 1461
1460 if (ACPI_FAILURE(rv)) { 1462 if (ACPI_FAILURE(rv)) {
1461 aprint_error_dev(sc->sc_dev, "failed to prepare " 1463 aprint_error_dev(sc->sc_dev, "failed to prepare "
1462 "S%d: %s\n", state, AcpiFormatException(rv)); 1464 "S%d: %s\n", state, AcpiFormatException(rv));
1463 break; 1465 break;
1464 } 1466 }
1465 1467
1466 DELAY(1000000); 1468 DELAY(1000000);
1467 1469
1468 sc->sc_sleepstate = state; 1470 sc->sc_sleepstate = state;
1469 acpi_md_OsDisableInterrupt(); 1471 acpi_md_OsDisableInterrupt();
1470 1472
1471 (void)AcpiEnterSleepState(ACPI_STATE_S5); 1473 (void)AcpiEnterSleepState(ACPI_STATE_S5);
1472 1474
1473 aprint_error_dev(sc->sc_dev, "WARNING: powerdown failed!\n"); 1475 aprint_error_dev(sc->sc_dev, "WARNING: powerdown failed!\n");
1474 1476
1475 break; 1477 break;
1476 } 1478 }
1477 1479
1478 sc->sc_sleepstate = ACPI_STATE_S0; 1480 sc->sc_sleepstate = ACPI_STATE_S0;
1479 1481
1480 (void)acpi_eval_set_integer(NULL, "\\_TTS", ACPI_STATE_S0); 1482 (void)acpi_eval_set_integer(NULL, "\\_TTS", ACPI_STATE_S0);
1481} 1483}
1482 1484
1483/* 1485/*
1484 * Sysctl. 1486 * Sysctl.
1485 */ 1487 */
1486SYSCTL_SETUP(sysctl_acpi_setup, "sysctl hw.acpi subtree setup") 1488SYSCTL_SETUP(sysctl_acpi_setup, "sysctl hw.acpi subtree setup")
1487{ 1489{
1488 const struct sysctlnode *mnode, *rnode; 1490 const struct sysctlnode *mnode, *rnode;
1489 int err; 1491 int err;
1490 1492
1491 err = sysctl_createv(clog, 0, NULL, &rnode, 1493 err = sysctl_createv(clog, 0, NULL, &rnode,
1492 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", 1494 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw",
1493 NULL, NULL, 0, NULL, 0, 1495 NULL, NULL, 0, NULL, 0,
1494 CTL_HW, CTL_EOL); 1496 CTL_HW, CTL_EOL);
1495 1497
1496 if (err != 0) 1498 if (err != 0)
1497 return; 1499 return;
1498 1500
1499 err = sysctl_createv(clog, 0, &rnode, &rnode, 1501 err = sysctl_createv(clog, 0, &rnode, &rnode,
1500 CTLFLAG_PERMANENT, CTLTYPE_NODE, 1502 CTLFLAG_PERMANENT, CTLTYPE_NODE,
1501 "acpi", SYSCTL_DESCR("ACPI subsystem parameters"), 1503 "acpi", SYSCTL_DESCR("ACPI subsystem parameters"),
1502 NULL, 0, NULL, 0, 1504 NULL, 0, NULL, 0,
1503 CTL_CREATE, CTL_EOL); 1505 CTL_CREATE, CTL_EOL);
1504 1506
1505 if (err != 0) 1507 if (err != 0)
1506 return; 1508 return;
1507 1509
1508 (void)sysctl_createv(NULL, 0, &rnode, NULL, 1510 (void)sysctl_createv(NULL, 0, &rnode, NULL,
1509 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD, 1511 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1510 "root", SYSCTL_DESCR("ACPI root pointer"), 1512 "root", SYSCTL_DESCR("ACPI root pointer"),
1511 NULL, 0, &acpi_root_pointer, sizeof(acpi_root_pointer), 1513 NULL, 0, &acpi_root_pointer, sizeof(acpi_root_pointer),
1512 CTL_CREATE, CTL_EOL); 1514 CTL_CREATE, CTL_EOL);
1513 1515
1514 (void)sysctl_createv(NULL, 0, &rnode, NULL, 1516 (void)sysctl_createv(NULL, 0, &rnode, NULL,
1515 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_STRING, 1517 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_STRING,
1516 "supported_states", SYSCTL_DESCR("Supported system states"), 1518 "supported_states", SYSCTL_DESCR("Supported system states"),
1517 sysctl_hw_acpi_sleepstates, 0, NULL, 0, 1519 sysctl_hw_acpi_sleepstates, 0, NULL, 0,
1518 CTL_CREATE, CTL_EOL); 1520 CTL_CREATE, CTL_EOL);
1519 1521
1520 err = sysctl_createv(NULL, 0, NULL, &mnode, 1522 err = sysctl_createv(NULL, 0, NULL, &mnode,
1521 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", 1523 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep",
1522 NULL, NULL, 0, NULL, 0, 1524 NULL, NULL, 0, NULL, 0,
1523 CTL_MACHDEP, CTL_EOL); 1525 CTL_MACHDEP, CTL_EOL);
1524 1526
1525 if (err == 0) { 1527 if (err == 0) {
1526 1528
1527 (void)sysctl_createv(NULL, 0, &mnode, NULL, 1529 (void)sysctl_createv(NULL, 0, &mnode, NULL,
1528 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 1530 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
1529 "sleep_state", SYSCTL_DESCR("System sleep state"), 1531 "sleep_state", SYSCTL_DESCR("System sleep state"),
1530 sysctl_hw_acpi_sleepstate, 0, NULL, 0, 1532 sysctl_hw_acpi_sleepstate, 0, NULL, 0,
1531 CTL_CREATE, CTL_EOL); 1533 CTL_CREATE, CTL_EOL);
1532 } 1534 }
1533 1535
1534 err = sysctl_createv(clog, 0, &rnode, &rnode, 1536 err = sysctl_createv(clog, 0, &rnode, &rnode,
1535 CTLFLAG_PERMANENT, CTLTYPE_NODE, 1537 CTLFLAG_PERMANENT, CTLTYPE_NODE,
1536 "stat", SYSCTL_DESCR("ACPI statistics"), 1538 "stat", SYSCTL_DESCR("ACPI statistics"),
1537 NULL, 0, NULL, 0, 1539 NULL, 0, NULL, 0,
1538 CTL_CREATE, CTL_EOL); 1540 CTL_CREATE, CTL_EOL);
1539 1541
1540 if (err != 0) 1542 if (err != 0)
1541 return; 1543 return;
1542 1544
1543 (void)sysctl_createv(clog, 0, &rnode, NULL, 1545 (void)sysctl_createv(clog, 0, &rnode, NULL,
1544 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD, 1546 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1545 "gpe", SYSCTL_DESCR("Number of dispatched GPEs"), 1547 "gpe", SYSCTL_DESCR("Number of dispatched GPEs"),
1546 NULL, 0, &AcpiGpeCount, sizeof(AcpiGpeCount), 1548 NULL, 0, &AcpiGpeCount, sizeof(AcpiGpeCount),
1547 CTL_CREATE, CTL_EOL); 1549 CTL_CREATE, CTL_EOL);
1548 1550
1549 (void)sysctl_createv(clog, 0, &rnode, NULL, 1551 (void)sysctl_createv(clog, 0, &rnode, NULL,
1550 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD, 1552 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1551 "sci", SYSCTL_DESCR("Number of SCI interrupts"), 1553 "sci", SYSCTL_DESCR("Number of SCI interrupts"),
1552 NULL, 0, &AcpiSciCount, sizeof(AcpiSciCount), 1554 NULL, 0, &AcpiSciCount, sizeof(AcpiSciCount),
1553 CTL_CREATE, CTL_EOL); 1555 CTL_CREATE, CTL_EOL);
1554 1556
1555 (void)sysctl_createv(clog, 0, &rnode, NULL, 1557 (void)sysctl_createv(clog, 0, &rnode, NULL,
1556 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD, 1558 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1557 "fixed", SYSCTL_DESCR("Number of fixed events"), 1559 "fixed", SYSCTL_DESCR("Number of fixed events"),
1558 sysctl_hw_acpi_fixedstats, 0, NULL, 0, 1560 sysctl_hw_acpi_fixedstats, 0, NULL, 0,
1559 CTL_CREATE, CTL_EOL); 1561 CTL_CREATE, CTL_EOL);
1560 1562
1561 (void)sysctl_createv(clog, 0, &rnode, NULL, 1563 (void)sysctl_createv(clog, 0, &rnode, NULL,
1562 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD, 1564 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1563 "method", SYSCTL_DESCR("Number of methods executed"), 1565 "method", SYSCTL_DESCR("Number of methods executed"),
1564 NULL, 0, &AcpiMethodCount, sizeof(AcpiMethodCount), 1566 NULL, 0, &AcpiMethodCount, sizeof(AcpiMethodCount),
1565 CTL_CREATE, CTL_EOL); 1567 CTL_CREATE, CTL_EOL);
1566 1568
1567 CTASSERT(sizeof(AcpiGpeCount) == sizeof(uint64_t)); 1569 CTASSERT(sizeof(AcpiGpeCount) == sizeof(uint64_t));
1568 CTASSERT(sizeof(AcpiSciCount) == sizeof(uint64_t)); 1570 CTASSERT(sizeof(AcpiSciCount) == sizeof(uint64_t));
1569} 1571}
1570 1572
1571static int 1573static int
1572sysctl_hw_acpi_fixedstats(SYSCTLFN_ARGS) 1574sysctl_hw_acpi_fixedstats(SYSCTLFN_ARGS)
1573{ 1575{
1574 struct sysctlnode node; 1576 struct sysctlnode node;
1575 uint64_t t; 1577 uint64_t t;
1576 int err, i; 1578 int err, i;
1577 1579
1578 for (i = t = 0; i < __arraycount(AcpiFixedEventCount); i++) 1580 for (i = t = 0; i < __arraycount(AcpiFixedEventCount); i++)
1579 t += AcpiFixedEventCount[i]; 1581 t += AcpiFixedEventCount[i];
1580 1582
1581 node = *rnode; 1583 node = *rnode;
1582 node.sysctl_data = &t; 1584 node.sysctl_data = &t;
1583 1585
1584 err = sysctl_lookup(SYSCTLFN_CALL(&node)); 1586 err = sysctl_lookup(SYSCTLFN_CALL(&node));
1585 1587
1586 if (err || newp == NULL) 1588 if (err || newp == NULL)
1587 return err; 1589 return err;
1588 1590
1589 return 0; 1591 return 0;
1590} 1592}
1591 1593
1592static int 1594static int
1593sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS) 1595sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS)
1594{ 1596{
1595 struct acpi_softc *sc = acpi_softc; 1597 struct acpi_softc *sc = acpi_softc;
1596 struct sysctlnode node; 1598 struct sysctlnode node;
1597 int err, t; 1599 int err, t;
1598 1600
1599 if (acpi_softc == NULL) 1601 if (acpi_softc == NULL)
1600 return ENOSYS; 1602 return ENOSYS;
1601 1603
1602 node = *rnode; 1604 node = *rnode;
1603 t = sc->sc_sleepstate; 1605 t = sc->sc_sleepstate;
1604 node.sysctl_data = &t; 1606 node.sysctl_data = &t;
1605 1607
1606 err = sysctl_lookup(SYSCTLFN_CALL(&node)); 1608 err = sysctl_lookup(SYSCTLFN_CALL(&node));
1607 1609
1608 if (err || newp == NULL) 1610 if (err || newp == NULL)
1609 return err; 1611 return err;
1610 1612
1611 if (t < ACPI_STATE_S0 || t > ACPI_STATE_S5) 1613 if (t < ACPI_STATE_S0 || t > ACPI_STATE_S5)
1612 return EINVAL; 1614 return EINVAL;
1613 1615
1614 acpi_enter_sleep_state(sc, t); 1616 acpi_enter_sleep_state(sc, t);
1615 1617
1616 return 0; 1618 return 0;
1617} 1619}
1618 1620
1619static int 1621static int
1620sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS) 1622sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS)
1621{ 1623{
1622 struct acpi_softc *sc = acpi_softc; 1624 struct acpi_softc *sc = acpi_softc;
1623 struct sysctlnode node; 1625 struct sysctlnode node;
1624 char t[3 * 6 + 1]; 1626 char t[3 * 6 + 1];
1625 int err; 1627 int err;
1626 1628
1627 if (acpi_softc == NULL) 1629 if (acpi_softc == NULL)
1628 return ENOSYS; 1630 return ENOSYS;
1629 1631
1630 (void)memset(t, '\0', sizeof(t)); 1632 (void)memset(t, '\0', sizeof(t));
1631 1633
1632 (void)snprintf(t, sizeof(t), "%s%s%s%s%s%s", 1634 (void)snprintf(t, sizeof(t), "%s%s%s%s%s%s",
1633 ((sc->sc_sleepstates & __BIT(0)) != 0) ? "S0 " : "", 1635 ((sc->sc_sleepstates & __BIT(0)) != 0) ? "S0 " : "",
1634 ((sc->sc_sleepstates & __BIT(1)) != 0) ? "S1 " : "", 1636 ((sc->sc_sleepstates & __BIT(1)) != 0) ? "S1 " : "",
1635 ((sc->sc_sleepstates & __BIT(2)) != 0) ? "S2 " : "", 1637 ((sc->sc_sleepstates & __BIT(2)) != 0) ? "S2 " : "",
1636 ((sc->sc_sleepstates & __BIT(3)) != 0) ? "S3 " : "", 1638 ((sc->sc_sleepstates & __BIT(3)) != 0) ? "S3 " : "",
1637 ((sc->sc_sleepstates & __BIT(4)) != 0) ? "S4 " : "", 1639 ((sc->sc_sleepstates & __BIT(4)) != 0) ? "S4 " : "",
1638 ((sc->sc_sleepstates & __BIT(5)) != 0) ? "S5 " : ""); 1640 ((sc->sc_sleepstates & __BIT(5)) != 0) ? "S5 " : "");
1639 1641
1640 node = *rnode; 1642 node = *rnode;
1641 node.sysctl_data = &t; 1643 node.sysctl_data = &t;
1642 1644
1643 err = sysctl_lookup(SYSCTLFN_CALL(&node)); 1645 err = sysctl_lookup(SYSCTLFN_CALL(&node));
1644 1646
1645 if (err || newp == NULL) 1647 if (err || newp == NULL)
1646 return err; 1648 return err;
1647 1649
1648 return 0; 1650 return 0;
1649} 1651}
1650 1652
1651/* 1653/*
1652 * Tables. 1654 * Tables.
1653 */ 1655 */
1654ACPI_PHYSICAL_ADDRESS 1656ACPI_PHYSICAL_ADDRESS
1655acpi_OsGetRootPointer(void) 1657acpi_OsGetRootPointer(void)
1656{ 1658{
1657 ACPI_PHYSICAL_ADDRESS PhysicalAddress; 1659 ACPI_PHYSICAL_ADDRESS PhysicalAddress;
1658 1660
1659 /* 1661 /*
1660 * We let MD code handle this since there are multiple ways to do it: 1662 * We let MD code handle this since there are multiple ways to do it:
1661 * 1663 *
1662 * IA-32: Use AcpiFindRootPointer() to locate the RSDP. 1664 * IA-32: Use AcpiFindRootPointer() to locate the RSDP.
1663 * 1665 *
1664 * IA-64: Use the EFI. 1666 * IA-64: Use the EFI.
1665 */ 1667 */
1666 PhysicalAddress = acpi_md_OsGetRootPointer(); 1668 PhysicalAddress = acpi_md_OsGetRootPointer();
1667 1669
1668 if (acpi_root_pointer == 0) 1670 if (acpi_root_pointer == 0)
1669 acpi_root_pointer = PhysicalAddress; 1671 acpi_root_pointer = PhysicalAddress;
1670 1672
1671 return PhysicalAddress; 1673 return PhysicalAddress;
1672} 1674}
1673 1675
1674static ACPI_TABLE_HEADER * 1676static ACPI_TABLE_HEADER *
1675acpi_map_rsdt(void) 1677acpi_map_rsdt(void)
1676{ 1678{
1677 ACPI_PHYSICAL_ADDRESS paddr; 1679 ACPI_PHYSICAL_ADDRESS paddr;
1678 ACPI_TABLE_RSDP *rsdp; 1680 ACPI_TABLE_RSDP *rsdp;
1679 1681
1680 paddr = AcpiOsGetRootPointer(); 1682 paddr = AcpiOsGetRootPointer();
1681 1683
1682 if (paddr == 0) 1684 if (paddr == 0)
1683 return NULL; 1685 return NULL;
1684 1686
1685 rsdp = AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_RSDP)); 1687 rsdp = AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_RSDP));
1686 1688
1687 if (rsdp == NULL) 1689 if (rsdp == NULL)
1688 return NULL; 1690 return NULL;
1689 1691
1690 if (rsdp->Revision > 1 && rsdp->XsdtPhysicalAddress) 1692 if (rsdp->Revision > 1 && rsdp->XsdtPhysicalAddress)
1691 paddr = rsdp->XsdtPhysicalAddress; 1693 paddr = rsdp->XsdtPhysicalAddress;
1692 else 1694 else
1693 paddr = rsdp->RsdtPhysicalAddress; 1695 paddr = rsdp->RsdtPhysicalAddress;
1694 1696
1695 AcpiOsUnmapMemory(rsdp, sizeof(ACPI_TABLE_RSDP)); 1697 AcpiOsUnmapMemory(rsdp, sizeof(ACPI_TABLE_RSDP));
1696 1698
1697 return AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_HEADER)); 1699 return AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_HEADER));
1698} 1700}
1699 1701
1700static void 1702static void
1701acpi_unmap_rsdt(ACPI_TABLE_HEADER *rsdt) 1703acpi_unmap_rsdt(ACPI_TABLE_HEADER *rsdt)
1702{ 1704{
1703 1705
1704 if (rsdt == NULL) 1706 if (rsdt == NULL)
1705 return; 1707 return;
1706 1708
1707 AcpiOsUnmapMemory(rsdt, sizeof(ACPI_TABLE_HEADER)); 1709 AcpiOsUnmapMemory(rsdt, sizeof(ACPI_TABLE_HEADER));
1708} 1710}
1709 1711
1710/* 1712/*
1711 * XXX: Refactor to be a generic function that maps tables. 1713 * XXX: Refactor to be a generic function that maps tables.
1712 */ 1714 */
1713ACPI_STATUS 1715ACPI_STATUS
1714acpi_madt_map(void) 1716acpi_madt_map(void)
1715{ 1717{
1716 ACPI_STATUS rv; 1718 ACPI_STATUS rv;
1717 1719
1718 if (madt_header != NULL) 1720 if (madt_header != NULL)
1719 return AE_ALREADY_EXISTS; 1721 return AE_ALREADY_EXISTS;
1720 1722
1721 rv = AcpiGetTable(ACPI_SIG_MADT, 1, &madt_header); 1723 rv = AcpiGetTable(ACPI_SIG_MADT, 1, &madt_header);
1722 1724
1723 if (ACPI_FAILURE(rv)) 1725 if (ACPI_FAILURE(rv))
1724 return rv; 1726 return rv;
1725 1727
1726 return AE_OK; 1728 return AE_OK;
1727} 1729}
1728 1730
1729void 1731void
1730acpi_madt_unmap(void) 1732acpi_madt_unmap(void)
1731{ 1733{
1732 madt_header = NULL; 1734 madt_header = NULL;
1733} 1735}
1734 1736
1735/* 1737/*
1736 * XXX: Refactor to be a generic function that walks tables. 1738 * XXX: Refactor to be a generic function that walks tables.
1737 */ 1739 */
1738void 1740void
1739acpi_madt_walk(ACPI_STATUS (*func)(ACPI_SUBTABLE_HEADER *, void *), void *aux) 1741acpi_madt_walk(ACPI_STATUS (*func)(ACPI_SUBTABLE_HEADER *, void *), void *aux)
1740{ 1742{
1741 ACPI_SUBTABLE_HEADER *hdrp; 1743 ACPI_SUBTABLE_HEADER *hdrp;
1742 char *madtend, *where; 1744 char *madtend, *where;
1743 1745
1744 madtend = (char *)madt_header + madt_header->Length; 1746 madtend = (char *)madt_header + madt_header->Length;
1745 where = (char *)madt_header + sizeof (ACPI_TABLE_MADT); 1747 where = (char *)madt_header + sizeof (ACPI_TABLE_MADT);
1746 1748
1747 while (where < madtend) { 1749 while (where < madtend) {
1748 1750
1749 hdrp = (ACPI_SUBTABLE_HEADER *)where; 1751 hdrp = (ACPI_SUBTABLE_HEADER *)where;
1750 1752
1751 if (ACPI_FAILURE(func(hdrp, aux))) 1753 if (ACPI_FAILURE(func(hdrp, aux)))
1752 break; 1754 break;
1753 1755
1754 where += hdrp->Length; 1756 where += hdrp->Length;
1755 } 1757 }
1756} 1758}
1757 1759
1758/* 1760/*
1759 * Miscellaneous. 1761 * Miscellaneous.
1760 */ 1762 */
1761static bool 1763static bool
1762acpi_is_scope(struct acpi_devnode *ad) 1764acpi_is_scope(struct acpi_devnode *ad)
1763{ 1765{
1764 int i; 1766 int i;
1765 1767
1766 /* 1768 /*
1767 * Return true if the node is a root scope. 1769 * Return true if the node is a root scope.
1768 */ 1770 */
1769 if (ad->ad_parent == NULL) 1771 if (ad->ad_parent == NULL)
1770 return false; 1772 return false;
1771 1773
1772 if (ad->ad_parent->ad_handle != ACPI_ROOT_OBJECT) 1774 if (ad->ad_parent->ad_handle != ACPI_ROOT_OBJECT)
1773 return false; 1775 return false;
1774 1776
1775 for (i = 0; i < __arraycount(acpi_scopes); i++) { 1777 for (i = 0; i < __arraycount(acpi_scopes); i++) {
1776 1778
1777 if (acpi_scopes[i] == NULL) 1779 if (acpi_scopes[i] == NULL)
1778 continue; 1780 continue;
1779 1781
1780 if (ad->ad_handle == acpi_scopes[i]) 1782 if (ad->ad_handle == acpi_scopes[i])
1781 return true; 1783 return true;
1782 } 1784 }
1783 1785
1784 return false; 1786 return false;
1785} 1787}
1786 1788
1787/* 1789/*
1788 * ACPIVERBOSE. 1790 * ACPIVERBOSE.
1789 */ 1791 */
1790void 1792void
1791acpi_load_verbose(void) 1793acpi_load_verbose(void)
1792{ 1794{
1793 1795
1794 if (acpi_verbose_loaded == 0) { 1796 if (acpi_verbose_loaded == 0) {
1795 mutex_enter(&module_lock); 1797 mutex_enter(&module_lock);
1796 module_autoload("acpiverbose", MODULE_CLASS_MISC); 1798 module_autoload("acpiverbose", MODULE_CLASS_MISC);
1797 mutex_exit(&module_lock); 1799 mutex_exit(&module_lock);
1798 } 1800 }
1799} 1801}
1800 1802
1801void 1803void
1802acpi_print_verbose_stub(struct acpi_softc *sc) 1804acpi_print_verbose_stub(struct acpi_softc *sc)
1803{ 1805{
1804 1806
1805 acpi_load_verbose(); 1807 acpi_load_verbose();
1806 1808
1807 if (acpi_verbose_loaded != 0) 1809 if (acpi_verbose_loaded != 0)
1808 acpi_print_verbose(sc); 1810 acpi_print_verbose(sc);
1809} 1811}
1810 1812
1811void 1813void
1812acpi_print_dev_stub(const char *pnpstr) 1814acpi_print_dev_stub(const char *pnpstr)
1813{ 1815{
1814 1816
1815 acpi_load_verbose(); 1817 acpi_load_verbose();
1816 1818
1817 if (acpi_verbose_loaded != 0) 1819 if (acpi_verbose_loaded != 0)
1818 acpi_print_dev(pnpstr); 1820 acpi_print_dev(pnpstr);
1819} 1821}

cvs diff -r1.13 -r1.14 src/sys/dev/acpi/acpi_pci.c (switch to unified diff)

--- src/sys/dev/acpi/acpi_pci.c 2010/08/08 16:26:47 1.13
+++ src/sys/dev/acpi/acpi_pci.c 2010/08/09 09:36:42 1.14
@@ -1,343 +1,353 @@ @@ -1,343 +1,353 @@
1/* $NetBSD: acpi_pci.c,v 1.13 2010/08/08 16:26:47 gsutre Exp $ */ 1/* $NetBSD: acpi_pci.c,v 1.14 2010/08/09 09:36:42 gsutre 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 Christoph Egger and Gregoire Sutre. 8 * by Christoph Egger and Gregoire Sutre.
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. The name of the author may not be used to endorse or promote products 15 * 2. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission. 16 * derived from this software without specific prior written permission.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE. 28 * SUCH DAMAGE.
29 */ 29 */
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: acpi_pci.c,v 1.13 2010/08/08 16:26:47 gsutre Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: acpi_pci.c,v 1.14 2010/08/09 09:36:42 gsutre Exp $");
33 33
34#include <sys/param.h> 34#include <sys/param.h>
35#include <sys/device.h> 35#include <sys/device.h>
36#include <sys/kmem.h> 36#include <sys/kmem.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38 38
39#include <dev/pci/pcireg.h> 39#include <dev/pci/pcireg.h>
40#include <dev/pci/pcidevs.h> 40#include <dev/pci/pcidevs.h>
41#include <dev/pci/ppbreg.h> 41#include <dev/pci/ppbreg.h>
42 42
43#include <dev/acpi/acpireg.h> 43#include <dev/acpi/acpireg.h>
44#include <dev/acpi/acpivar.h> 44#include <dev/acpi/acpivar.h>
45#include <dev/acpi/acpi_pci.h> 45#include <dev/acpi/acpi_pci.h>
46 46
47#define _COMPONENT ACPI_BUS_COMPONENT 47#define _COMPONENT ACPI_BUS_COMPONENT
48ACPI_MODULE_NAME ("acpi_pci") 48ACPI_MODULE_NAME ("acpi_pci")
49 49
50#define ACPI_HILODWORD(x) ACPI_HIWORD(ACPI_LODWORD((x))) 50#define ACPI_HILODWORD(x) ACPI_HIWORD(ACPI_LODWORD((x)))
51#define ACPI_LOLODWORD(x) ACPI_LOWORD(ACPI_LODWORD((x))) 51#define ACPI_LOLODWORD(x) ACPI_LOWORD(ACPI_LODWORD((x)))
52 52
53static ACPI_STATUS acpi_pcidev_pciroot_bus(ACPI_HANDLE, uint16_t *); 53static ACPI_STATUS acpi_pcidev_pciroot_bus(ACPI_HANDLE, uint16_t *);
54static ACPI_STATUS acpi_pcidev_pciroot_bus_callback(ACPI_RESOURCE *, 54static ACPI_STATUS acpi_pcidev_pciroot_bus_callback(ACPI_RESOURCE *,
55 void *); 55 void *);
56 56
57/* 57/*
58 * Regarding PCI Segment Groups (ACPI 4.0, p. 277): 58 * Regarding PCI Segment Groups (ACPI 4.0, p. 277):
59 * 59 *
60 * "The optional _SEG object is located under a PCI host bridge and 60 * "The optional _SEG object is located under a PCI host bridge and
61 * evaluates to an integer that describes the PCI Segment Group (see PCI 61 * evaluates to an integer that describes the PCI Segment Group (see PCI
62 * Firmware Specification v3.0)." 62 * Firmware Specification v3.0)."
63 * 63 *
64 * "PCI Segment Group is purely a software concept managed by system 64 * "PCI Segment Group is purely a software concept managed by system
65 * firmware and used by OSPM. It is a logical collection of PCI buses 65 * firmware and used by OSPM. It is a logical collection of PCI buses
66 * (or bus segments). It is a way to logically group the PCI bus segments 66 * (or bus segments). It is a way to logically group the PCI bus segments
67 * and PCI Express Hierarchies. _SEG is a level higher than _BBN." 67 * and PCI Express Hierarchies. _SEG is a level higher than _BBN."
68 * 68 *
69 * "PCI Segment Group supports more than 256 buses in a system by allowing 69 * "PCI Segment Group supports more than 256 buses in a system by allowing
70 * the reuse of the PCI bus numbers. Within each PCI Segment Group, the bus 70 * the reuse of the PCI bus numbers. Within each PCI Segment Group, the bus
71 * numbers for the PCI buses must be unique. PCI buses in different PCI 71 * numbers for the PCI buses must be unique. PCI buses in different PCI
72 * Segment Group are permitted to have the same bus number." 72 * Segment Group are permitted to have the same bus number."
73 */ 73 */
74 74
75/* 75/*
76 * Regarding PCI Base Bus Numbers (ACPI 4.0, p. 277): 76 * Regarding PCI Base Bus Numbers (ACPI 4.0, p. 277):
77 * 77 *
78 * "For multi-root PCI platforms, the _BBN object evaluates to the PCI bus 78 * "For multi-root PCI platforms, the _BBN object evaluates to the PCI bus
79 * number that the BIOS assigns. This is needed to access a PCI_Config 79 * number that the BIOS assigns. This is needed to access a PCI_Config
80 * operation region for the specified bus. The _BBN object is located under 80 * operation region for the specified bus. The _BBN object is located under
81 * a PCI host bridge and must be unique for every host bridge within a 81 * a PCI host bridge and must be unique for every host bridge within a
82 * segment since it is the PCI bus number." 82 * segment since it is the PCI bus number."
83 * 83 *
84 * Moreover, the ACPI FAQ (http://www.acpi.info/acpi_faq.htm) says: 84 * Moreover, the ACPI FAQ (http://www.acpi.info/acpi_faq.htm) says:
85 * 85 *
86 * "For a multiple root bus machine, _BBN is required for each bus. _BBN 86 * "For a multiple root bus machine, _BBN is required for each bus. _BBN
87 * should provide the bus number assigned to this bus by the BIOS at boot 87 * should provide the bus number assigned to this bus by the BIOS at boot
88 * time." 88 * time."
89 */ 89 */
90 90
91/* 91/*
92 * acpi_pcidev_pciroot_bus: 92 * acpi_pcidev_pciroot_bus:
93 * 93 *
94 * Derive the PCI bus number of a PCI root bridge from its resources. 94 * Derive the PCI bus number of a PCI root bridge from its resources.
95 * If successful, return AE_OK and fill *busp. Otherwise, return an 95 * If successful, return AE_OK and fill *busp. Otherwise, return an
96 * exception code and leave *busp unchanged. 96 * exception code and leave *busp unchanged.
97 */ 97 */
98static ACPI_STATUS 98static ACPI_STATUS
99acpi_pcidev_pciroot_bus(ACPI_HANDLE handle, uint16_t *busp) 99acpi_pcidev_pciroot_bus(ACPI_HANDLE handle, uint16_t *busp)
100{ 100{
101 ACPI_STATUS rv; 101 ACPI_STATUS rv;
102 int32_t bus; 102 int32_t bus;
103 103
104 bus = -1; 104 bus = -1;
105 105
106 /* 106 /*
107 * XXX: Use the ACPI resource parsing functions (acpi_resource.c) 107 * XXX: Use the ACPI resource parsing functions (acpi_resource.c)
108 * once bus number ranges have been implemented there. 108 * once bus number ranges have been implemented there.
109 */ 109 */
110 rv = AcpiWalkResources(handle, "_CRS", 110 rv = AcpiWalkResources(handle, "_CRS",
111 acpi_pcidev_pciroot_bus_callback, &bus); 111 acpi_pcidev_pciroot_bus_callback, &bus);
112 112
113 if (ACPI_FAILURE(rv)) 113 if (ACPI_FAILURE(rv))
114 return rv; 114 return rv;
115 115
116 if (bus < 0 || bus > 0xFFFF) 116 if (bus < 0 || bus > 0xFFFF)
117 return AE_NOT_EXIST; 117 return AE_NOT_EXIST;
118 118
119 *busp = (uint16_t)bus; 119 *busp = (uint16_t)bus;
120 120
121 return rv; 121 return rv;
122} 122}
123 123
124static ACPI_STATUS 124static ACPI_STATUS
125acpi_pcidev_pciroot_bus_callback(ACPI_RESOURCE *res, void *context) 125acpi_pcidev_pciroot_bus_callback(ACPI_RESOURCE *res, void *context)
126{ 126{
127 ACPI_RESOURCE_ADDRESS64 addr64; 127 ACPI_RESOURCE_ADDRESS64 addr64;
128 int32_t *bus = context; 128 int32_t *bus = context;
129 129
130 /* Always continue the walk by returning AE_OK. */ 130 /* Always continue the walk by returning AE_OK. */
131 if ((res->Type != ACPI_RESOURCE_TYPE_ADDRESS16) && 131 if ((res->Type != ACPI_RESOURCE_TYPE_ADDRESS16) &&
132 (res->Type != ACPI_RESOURCE_TYPE_ADDRESS32) && 132 (res->Type != ACPI_RESOURCE_TYPE_ADDRESS32) &&
133 (res->Type != ACPI_RESOURCE_TYPE_ADDRESS64)) 133 (res->Type != ACPI_RESOURCE_TYPE_ADDRESS64))
134 return AE_OK; 134 return AE_OK;
135 135
136 if (ACPI_FAILURE(AcpiResourceToAddress64(res, &addr64))) 136 if (ACPI_FAILURE(AcpiResourceToAddress64(res, &addr64)))
137 return AE_OK; 137 return AE_OK;
138 138
139 if (addr64.ResourceType != ACPI_BUS_NUMBER_RANGE) 139 if (addr64.ResourceType != ACPI_BUS_NUMBER_RANGE)
140 return AE_OK; 140 return AE_OK;
141 141
142 if (*bus != -1) 142 if (*bus != -1)
143 return AE_ALREADY_EXISTS; 143 return AE_ALREADY_EXISTS;
144 144
145 *bus = addr64.Minimum; 145 *bus = addr64.Minimum;
146 146
147 return AE_OK; 147 return AE_OK;
148} 148}
149 149
150/* 150/*
151 * acpi_pcidev_scan: 151 * acpi_pcidev_scan:
152 * 152 *
153 * Scan the ACPI device tree for PCI devices. A node is detected as a 153 * Scan the ACPI device tree for PCI devices. A node is detected as a
154 * PCI device if it has an ancestor that is a PCI root bridge and such 154 * PCI device if it has an ancestor that is a PCI root bridge and such
155 * that all intermediate nodes are PCI-to-PCI bridges. Depth-first 155 * that all intermediate nodes are PCI-to-PCI bridges. Depth-first
156 * recursive implementation. 156 * recursive implementation.
157 */ 157 */
158ACPI_STATUS 158ACPI_STATUS
159acpi_pcidev_scan(struct acpi_devnode *ad) 159acpi_pcidev_scan(struct acpi_devnode *ad)
160{ 160{
161 struct acpi_devnode *child; 161 struct acpi_devnode *child;
162 struct acpi_pci_info *ap; 162 struct acpi_pci_info *ap;
163 ACPI_INTEGER val; 163 ACPI_INTEGER val;
164 ACPI_STATUS rv; 164 ACPI_STATUS rv;
165 165
166 ad->ad_pciinfo = NULL; 166 ad->ad_pciinfo = NULL;
167 167
168 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE || 168 if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE ||
169 !(ad->ad_devinfo->Valid & ACPI_VALID_ADR)) 169 !(ad->ad_devinfo->Valid & ACPI_VALID_ADR))
170 goto rec; 170 goto rec;
171 171
 172 /*
 173 * We attach PCI information only to devices that are present,
 174 * enabled, and functioning properly.
 175 * Note: there is a possible race condition, because _STA may
 176 * have changed since ad->ad_devinfo->CurrentStatus was set.
 177 */
 178 if ((ad->ad_devinfo->Valid & ACPI_VALID_STA) != 0 &&
 179 (ad->ad_devinfo->CurrentStatus & ACPI_STA_OK) != ACPI_STA_OK)
 180 goto rec;
 181
172 if (ad->ad_devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) { 182 if (ad->ad_devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) {
173 183
174 ap = kmem_zalloc(sizeof(*ap), KM_SLEEP); 184 ap = kmem_zalloc(sizeof(*ap), KM_SLEEP);
175 185
176 if (ap == NULL) 186 if (ap == NULL)
177 return AE_NO_MEMORY; 187 return AE_NO_MEMORY;
178 188
179 /* 189 /*
180 * If no _SEG exist, all PCI bus segments are assumed 190 * If no _SEG exist, all PCI bus segments are assumed
181 * to be in the PCI segment group 0 (ACPI 4.0, p. 277). 191 * to be in the PCI segment group 0 (ACPI 4.0, p. 277).
182 * The segment group number is conveyed in the lower 192 * The segment group number is conveyed in the lower
183 * 16 bits of _SEG (the other bits are all reserved). 193 * 16 bits of _SEG (the other bits are all reserved).
184 */ 194 */
185 rv = acpi_eval_integer(ad->ad_handle, "_SEG", &val); 195 rv = acpi_eval_integer(ad->ad_handle, "_SEG", &val);
186 196
187 if (ACPI_SUCCESS(rv)) 197 if (ACPI_SUCCESS(rv))
188 ap->ap_segment = ACPI_LOWORD(val); 198 ap->ap_segment = ACPI_LOWORD(val);
189 199
190 /* Try to get bus number using _CRS first. */ 200 /* Try to get bus number using _CRS first. */
191 rv = acpi_pcidev_pciroot_bus(ad->ad_handle, &ap->ap_bus); 201 rv = acpi_pcidev_pciroot_bus(ad->ad_handle, &ap->ap_bus);
192 202
193 if (ACPI_FAILURE(rv)) { 203 if (ACPI_FAILURE(rv)) {
194 rv = acpi_eval_integer(ad->ad_handle, "_BBN", &val); 204 rv = acpi_eval_integer(ad->ad_handle, "_BBN", &val);
195 205
196 if (ACPI_SUCCESS(rv)) 206 if (ACPI_SUCCESS(rv))
197 ap->ap_bus = ACPI_LOWORD(val); 207 ap->ap_bus = ACPI_LOWORD(val);
198 } 208 }
199 209
200 ap->ap_device = ACPI_HILODWORD(ad->ad_devinfo->Address); 210 ap->ap_device = ACPI_HILODWORD(ad->ad_devinfo->Address);
201 ap->ap_function = ACPI_LOLODWORD(ad->ad_devinfo->Address); 211 ap->ap_function = ACPI_LOLODWORD(ad->ad_devinfo->Address);
202 212
203 if (ap->ap_bus > 255 || ap->ap_device > 31 || 213 if (ap->ap_bus > 255 || ap->ap_device > 31 ||
204 ap->ap_function > 7) { 214 ap->ap_function > 7) {
205 aprint_error_dev(ad->ad_root, 215 aprint_error_dev(ad->ad_root,
206 "invalid PCI address for %s\n", ad->ad_name); 216 "invalid PCI address for %s\n", ad->ad_name);
207 kmem_free(ap, sizeof(*ap)); 217 kmem_free(ap, sizeof(*ap));
208 goto rec; 218 goto rec;
209 } 219 }
210 220
211 ap->ap_bridge = true; 221 ap->ap_bridge = true;
212 ap->ap_downbus = ap->ap_bus; 222 ap->ap_downbus = ap->ap_bus;
213 223
214 ad->ad_pciinfo = ap; 224 ad->ad_pciinfo = ap;
215 225
216 goto rec; 226 goto rec;
217 } 227 }
218 228
219 if ((ad->ad_parent != NULL) && 229 if ((ad->ad_parent != NULL) &&
220 (ad->ad_parent->ad_pciinfo != NULL) && 230 (ad->ad_parent->ad_pciinfo != NULL) &&
221 (ad->ad_parent->ad_pciinfo->ap_bridge)) { 231 (ad->ad_parent->ad_pciinfo->ap_bridge)) {
222 232
223 /* 233 /*
224 * Our parent is a PCI root bridge or a PCI-to-PCI 234 * Our parent is a PCI root bridge or a PCI-to-PCI
225 * bridge. We have the same PCI segment number, and 235 * bridge. We have the same PCI segment number, and
226 * our bus number is its downstream bus number. 236 * our bus number is its downstream bus number.
227 */ 237 */
228 ap = kmem_zalloc(sizeof(*ap), KM_SLEEP); 238 ap = kmem_zalloc(sizeof(*ap), KM_SLEEP);
229 239
230 if (ap == NULL) 240 if (ap == NULL)
231 return AE_NO_MEMORY; 241 return AE_NO_MEMORY;
232 242
233 ap->ap_segment = ad->ad_parent->ad_pciinfo->ap_segment; 243 ap->ap_segment = ad->ad_parent->ad_pciinfo->ap_segment;
234 ap->ap_bus = ad->ad_parent->ad_pciinfo->ap_downbus; 244 ap->ap_bus = ad->ad_parent->ad_pciinfo->ap_downbus;
235 245
236 ap->ap_device = ACPI_HILODWORD(ad->ad_devinfo->Address); 246 ap->ap_device = ACPI_HILODWORD(ad->ad_devinfo->Address);
237 ap->ap_function = ACPI_LOLODWORD(ad->ad_devinfo->Address); 247 ap->ap_function = ACPI_LOLODWORD(ad->ad_devinfo->Address);
238 248
239 if (ap->ap_device > 31 || ap->ap_function > 7) { 249 if (ap->ap_device > 31 || ap->ap_function > 7) {
240 aprint_error_dev(ad->ad_root, 250 aprint_error_dev(ad->ad_root,
241 "invalid PCI address for %s\n", ad->ad_name); 251 "invalid PCI address for %s\n", ad->ad_name);
242 kmem_free(ap, sizeof(*ap)); 252 kmem_free(ap, sizeof(*ap));
243 goto rec; 253 goto rec;
244 } 254 }
245 255
246 /* 256 /*
247 * Check whether this device is a PCI-to-PCI 257 * Check whether this device is a PCI-to-PCI
248 * bridge and get its secondary bus number. 258 * bridge and get its secondary bus number.
249 */ 259 */
250 rv = acpi_pcidev_ppb_downbus(ap->ap_segment, ap->ap_bus, 260 rv = acpi_pcidev_ppb_downbus(ap->ap_segment, ap->ap_bus,
251 ap->ap_device, ap->ap_function, &ap->ap_downbus); 261 ap->ap_device, ap->ap_function, &ap->ap_downbus);
252 262
253 ap->ap_bridge = (rv != AE_OK) ? false : true; 263 ap->ap_bridge = (rv != AE_OK) ? false : true;
254 ad->ad_pciinfo = ap; 264 ad->ad_pciinfo = ap;
255 265
256 goto rec; 266 goto rec;
257 } 267 }
258 268
259rec: 269rec:
260 SIMPLEQ_FOREACH(child, &ad->ad_child_head, ad_child_list) { 270 SIMPLEQ_FOREACH(child, &ad->ad_child_head, ad_child_list) {
261 rv = acpi_pcidev_scan(child); 271 rv = acpi_pcidev_scan(child);
262 272
263 if (ACPI_FAILURE(rv)) 273 if (ACPI_FAILURE(rv))
264 return rv; 274 return rv;
265 } 275 }
266 276
267 return AE_OK; 277 return AE_OK;
268} 278}
269 279
270/* 280/*
271 * acpi_pcidev_ppb_downbus: 281 * acpi_pcidev_ppb_downbus:
272 * 282 *
273 * Retrieve the secondary bus number of the PCI-to-PCI bridge having the 283 * Retrieve the secondary bus number of the PCI-to-PCI bridge having the
274 * given PCI id. If successful, return AE_OK and fill *downbus. 284 * given PCI id. If successful, return AE_OK and fill *downbus.
275 * Otherwise, return an exception code and leave *downbus unchanged. 285 * Otherwise, return an exception code and leave *downbus unchanged.
276 * 286 *
277 * XXX Need to deal with PCI segment groups (see also acpica/OsdHardware.c). 287 * XXX Need to deal with PCI segment groups (see also acpica/OsdHardware.c).
278 */ 288 */
279ACPI_STATUS 289ACPI_STATUS
280acpi_pcidev_ppb_downbus(uint16_t segment, uint16_t bus, uint16_t device, 290acpi_pcidev_ppb_downbus(uint16_t segment, uint16_t bus, uint16_t device,
281 uint16_t function, uint16_t *downbus) 291 uint16_t function, uint16_t *downbus)
282{ 292{
283 struct acpi_softc *sc = acpi_softc; 293 struct acpi_softc *sc = acpi_softc;
284 pci_chipset_tag_t pc; 294 pci_chipset_tag_t pc;
285 pcitag_t tag; 295 pcitag_t tag;
286 pcireg_t val; 296 pcireg_t val;
287 297
288 if (bus > 255 || device > 31 || function > 7) 298 if (bus > 255 || device > 31 || function > 7)
289 return AE_BAD_PARAMETER; 299 return AE_BAD_PARAMETER;
290 300
291 pc = sc->sc_pc; 301 pc = sc->sc_pc;
292 302
293 tag = pci_make_tag(pc, bus, device, function); 303 tag = pci_make_tag(pc, bus, device, function);
294 304
295 /* Check that this device exists. */ 305 /* Check that this device exists. */
296 val = pci_conf_read(pc, tag, PCI_ID_REG); 306 val = pci_conf_read(pc, tag, PCI_ID_REG);
297 307
298 if (PCI_VENDOR(val) == PCI_VENDOR_INVALID || 308 if (PCI_VENDOR(val) == PCI_VENDOR_INVALID ||
299 PCI_VENDOR(val) == 0) 309 PCI_VENDOR(val) == 0)
300 return AE_NOT_EXIST; 310 return AE_NOT_EXIST;
301 311
302 /* Check that this device is a PCI-to-PCI bridge. */ 312 /* Check that this device is a PCI-to-PCI bridge. */
303 val = pci_conf_read(pc, tag, PCI_BHLC_REG); 313 val = pci_conf_read(pc, tag, PCI_BHLC_REG);
304 314
305 if (PCI_HDRTYPE_TYPE(val) != PCI_HDRTYPE_PPB) 315 if (PCI_HDRTYPE_TYPE(val) != PCI_HDRTYPE_PPB)
306 return AE_TYPE; 316 return AE_TYPE;
307 317
308 /* This is a PCI-to-PCI bridge. Get its secondary bus#. */ 318 /* This is a PCI-to-PCI bridge. Get its secondary bus#. */
309 val = pci_conf_read(pc, tag, PPB_REG_BUSINFO); 319 val = pci_conf_read(pc, tag, PPB_REG_BUSINFO);
310 *downbus = PPB_BUSINFO_SECONDARY(val); 320 *downbus = PPB_BUSINFO_SECONDARY(val);
311 321
312 return AE_OK; 322 return AE_OK;
313} 323}
314 324
315/* 325/*
316 * acpi_pcidev_find: 326 * acpi_pcidev_find:
317 * 327 *
318 * Finds a PCI device in the ACPI name space. 328 * Finds a PCI device in the ACPI name space.
319 * 329 *
320 * Returns an ACPI device node on success and NULL on failure. 330 * Returns an ACPI device node on success and NULL on failure.
321 */ 331 */
322struct acpi_devnode * 332struct acpi_devnode *
323acpi_pcidev_find(uint16_t segment, uint16_t bus, 333acpi_pcidev_find(uint16_t segment, uint16_t bus,
324 uint16_t device, uint16_t function) 334 uint16_t device, uint16_t function)
325{ 335{
326 struct acpi_softc *sc = acpi_softc; 336 struct acpi_softc *sc = acpi_softc;
327 struct acpi_devnode *ad; 337 struct acpi_devnode *ad;
328 338
329 if (sc == NULL) 339 if (sc == NULL)
330 return NULL; 340 return NULL;
331 341
332 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) { 342 SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
333 343
334 if (ad->ad_pciinfo != NULL && 344 if (ad->ad_pciinfo != NULL &&
335 ad->ad_pciinfo->ap_segment == segment && 345 ad->ad_pciinfo->ap_segment == segment &&
336 ad->ad_pciinfo->ap_bus == bus && 346 ad->ad_pciinfo->ap_bus == bus &&
337 ad->ad_pciinfo->ap_device == device && 347 ad->ad_pciinfo->ap_device == device &&
338 ad->ad_pciinfo->ap_function == function) 348 ad->ad_pciinfo->ap_function == function)
339 return ad; 349 return ad;
340 } 350 }
341 351
342 return NULL; 352 return NULL;
343} 353}