Fri Oct 29 09:04:39 2010 UTC ()
Lock the _DGS values (desired output state) during the display
output switch.

ok jruoho@


(gsutre)
diff -r1.4 -r1.5 src/sys/dev/acpi/acpi_display.c

cvs diff -r1.4 -r1.5 src/sys/dev/acpi/acpi_display.c (switch to unified diff)

--- src/sys/dev/acpi/acpi_display.c 2010/10/28 21:45:02 1.4
+++ src/sys/dev/acpi/acpi_display.c 2010/10/29 09:04:38 1.5
@@ -1,1956 +1,1965 @@ @@ -1,1956 +1,1965 @@
1/* $NetBSD: acpi_display.c,v 1.4 2010/10/28 21:45:02 gsutre Exp $ */ 1/* $NetBSD: acpi_display.c,v 1.5 2010/10/29 09:04:38 gsutre Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2010 The NetBSD Foundation, Inc. 4 * Copyright (c) 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 Gregoire Sutre. 8 * by 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. 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 * ACPI Display Adapter Driver. 33 * ACPI Display Adapter Driver.
34 * 34 *
35 * Appendix B of the ACPI specification presents ACPI extensions for display 35 * Appendix B of the ACPI specification presents ACPI extensions for display
36 * adapters. Systems containing a built-in display adapter are required to 36 * adapters. Systems containing a built-in display adapter are required to
37 * implement these extensions (in their ACPI BIOS). This driver uses these 37 * implement these extensions (in their ACPI BIOS). This driver uses these
38 * extensions to provide generic support for brightness control and display 38 * extensions to provide generic support for brightness control and display
39 * switching. 39 * switching.
40 * 40 *
41 * If brightness control methods are absent or non-functional, ACPI brightness 41 * If brightness control methods are absent or non-functional, ACPI brightness
42 * notifications are relayed to the PMF framework. 42 * notifications are relayed to the PMF framework.
43 * 43 *
44 * This driver sets the BIOS switch policy (_DOS method) as follows: 44 * This driver sets the BIOS switch policy (_DOS method) as follows:
45 * - The BIOS should automatically switch the active display output, with no 45 * - The BIOS should automatically switch the active display output, with no
46 * interaction required on the OS part. 46 * interaction required on the OS part.
47 * - The BIOS should not automatically control the brightness levels. 47 * - The BIOS should not automatically control the brightness levels.
48 * 48 *
49 * Brightness and BIOS switch policy can be adjusted from userland, via the 49 * Brightness and BIOS switch policy can be adjusted from userland, via the
50 * sysctl variables acpivga<n>.policy and acpiout<n>.brightness under hw.acpi. 50 * sysctl variables acpivga<n>.policy and acpiout<n>.brightness under hw.acpi.
51 */ 51 */
52 52
53/* 53/*
54 * The driver uses mutex(9) protection since changes to the hardware/software 54 * The driver uses mutex(9) protection since changes to the hardware/software
55 * state may be initiated both by the BIOS (ACPI notifications) and by the user 55 * state may be initiated both by the BIOS (ACPI notifications) and by the user
56 * (sysctl). The ACPI display adapter's mutex is shared with all ACPI display 56 * (sysctl). The ACPI display adapter's mutex is shared with all ACPI display
57 * output devices attached to it. 57 * output devices attached to it.
58 * 58 *
59 * The mutex only prevents undesired interleavings of ACPI notify handlers, 59 * The mutex only prevents undesired interleavings of ACPI notify handlers,
60 * sysctl callbacks, and pmf(9) suspend/resume routines. Race conditions with 60 * sysctl callbacks, and pmf(9) suspend/resume routines. Race conditions with
61 * autoconf(9) detachment routines could, in theory, still occur. 61 * autoconf(9) detachment routines could, in theory, still occur.
62 * 62 *
63 * The array of connected output devices (sc_odinfo) is, after attachment, only 63 * The array of connected output devices (sc_odinfo) is, after attachment, only
64 * used in ACPI notify handler callbacks. Since two such callbacks cannot be 64 * used in ACPI notify handler callbacks. Since two such callbacks cannot be
65 * running simultaneously, this information does not need protection. 65 * running simultaneously, this information does not need protection.
66 */ 66 */
67 67
68#include <sys/cdefs.h> 68#include <sys/cdefs.h>
69__KERNEL_RCSID(0, "$NetBSD: acpi_display.c,v 1.4 2010/10/28 21:45:02 gsutre Exp $"); 69__KERNEL_RCSID(0, "$NetBSD: acpi_display.c,v 1.5 2010/10/29 09:04:38 gsutre Exp $");
70 70
71#include <sys/param.h> 71#include <sys/param.h>
72#include <sys/device.h> 72#include <sys/device.h>
73#include <sys/kmem.h> 73#include <sys/kmem.h>
74#include <sys/module.h> 74#include <sys/module.h>
75#include <sys/mutex.h> 75#include <sys/mutex.h>
76#include <sys/sysctl.h> 76#include <sys/sysctl.h>
77#include <sys/systm.h> 77#include <sys/systm.h>
78 78
79#include <dev/pci/pcireg.h> 79#include <dev/pci/pcireg.h>
80#include <dev/pci/pcidevs.h> 80#include <dev/pci/pcidevs.h>
81 81
82#include <dev/acpi/acpireg.h> 82#include <dev/acpi/acpireg.h>
83#include <dev/acpi/acpivar.h> 83#include <dev/acpi/acpivar.h>
84 84
85#define _COMPONENT ACPI_DISPLAY_COMPONENT 85#define _COMPONENT ACPI_DISPLAY_COMPONENT
86ACPI_MODULE_NAME ("acpi_display") 86ACPI_MODULE_NAME ("acpi_display")
87 87
88/* Type for integer values that are passed to/from ACPICA. */ 88/* Type for integer values that are passed to/from ACPICA. */
89#define ACPI_UINT64 uint64_t 89#define ACPI_UINT64 uint64_t
90 90
91/* Notifications specific to display adapter devices (ACPI 4.0a, Sec. B.5). */ 91/* Notifications specific to display adapter devices (ACPI 4.0a, Sec. B.5). */
92#define ACPI_NOTIFY_CycleOutputDevice 0x80 92#define ACPI_NOTIFY_CycleOutputDevice 0x80
93#define ACPI_NOTIFY_OutputDeviceStatusChange 0x81 93#define ACPI_NOTIFY_OutputDeviceStatusChange 0x81
94#define ACPI_NOTIFY_CycleDisplayOutputHotkeyPressed 0x82 94#define ACPI_NOTIFY_CycleDisplayOutputHotkeyPressed 0x82
95#define ACPI_NOTIFY_NextDisplayOutputHotkeyPressed 0x83 95#define ACPI_NOTIFY_NextDisplayOutputHotkeyPressed 0x83
96#define ACPI_NOTIFY_PreviousDisplayOutputHotkeyPressed 0x84 96#define ACPI_NOTIFY_PreviousDisplayOutputHotkeyPressed 0x84
97 97
98/* Notifications specific to display output devices (ACPI 4.0a, Sec. B.7). */ 98/* Notifications specific to display output devices (ACPI 4.0a, Sec. B.7). */
99#define ACPI_NOTIFY_CycleBrightness 0x85 99#define ACPI_NOTIFY_CycleBrightness 0x85
100#define ACPI_NOTIFY_IncreaseBrightness 0x86 100#define ACPI_NOTIFY_IncreaseBrightness 0x86
101#define ACPI_NOTIFY_DecreaseBrightness 0x87 101#define ACPI_NOTIFY_DecreaseBrightness 0x87
102#define ACPI_NOTIFY_ZeroBrightness 0x88 102#define ACPI_NOTIFY_ZeroBrightness 0x88
103#define ACPI_NOTIFY_DisplayDeviceOff 0x89 103#define ACPI_NOTIFY_DisplayDeviceOff 0x89
104 104
105/* Format of the BIOS switch policy set by _DOS (ACPI 4.0a, Sec. B.4.1). */ 105/* Format of the BIOS switch policy set by _DOS (ACPI 4.0a, Sec. B.4.1). */
106typedef union acpidisp_bios_policy_t { 106typedef union acpidisp_bios_policy_t {
107 uint8_t raw; 107 uint8_t raw;
108 struct { 108 struct {
109 uint8_t output:2; 109 uint8_t output:2;
110 uint8_t brightness:1; 110 uint8_t brightness:1;
111 uint8_t reserved:5; 111 uint8_t reserved:5;
112 } __packed fmt; 112 } __packed fmt;
113} acpidisp_bios_policy_t; 113} acpidisp_bios_policy_t;
114 114
115/* Default BIOS switch policy (ACPI 4.0a, Sec. B.4.1). */ 115/* Default BIOS switch policy (ACPI 4.0a, Sec. B.4.1). */
116static const acpidisp_bios_policy_t acpidisp_default_bios_policy = { 116static const acpidisp_bios_policy_t acpidisp_default_bios_policy = {
117 .raw = 0x1 117 .raw = 0x1
118}; 118};
119 119
120/* BIOS output switch policies (ACPI 4.0a, Sec. B.4.1). */ 120/* BIOS output switch policies (ACPI 4.0a, Sec. B.4.1). */
121#define ACPI_DISP_POLICY_OUTPUT_NORMAL 0x0 121#define ACPI_DISP_POLICY_OUTPUT_NORMAL 0x0
122#define ACPI_DISP_POLICY_OUTPUT_AUTO 0x1 122#define ACPI_DISP_POLICY_OUTPUT_AUTO 0x1
123#define ACPI_DISP_POLICY_OUTPUT_LOCKED 0x2 123#define ACPI_DISP_POLICY_OUTPUT_LOCKED 0x2
124#define ACPI_DISP_POLICY_OUTPUT_HOTKEY 0x3 124#define ACPI_DISP_POLICY_OUTPUT_HOTKEY 0x3
125 125
126/* BIOS brightness switch policies (ACPI 4.0a, Sec. B.4.1). */ 126/* BIOS brightness switch policies (ACPI 4.0a, Sec. B.4.1). */
127#define ACPI_DISP_POLICY_BRIGHTNESS_AUTO 0x0 127#define ACPI_DISP_POLICY_BRIGHTNESS_AUTO 0x0
128#define ACPI_DISP_POLICY_BRIGHTNESS_NORMAL 0x1 128#define ACPI_DISP_POLICY_BRIGHTNESS_NORMAL 0x1
129 129
130/* Format of output device attributes (ACPI 4.0a, Table B-2). */ 130/* Format of output device attributes (ACPI 4.0a, Table B-2). */
131typedef union acpidisp_od_attrs_t { 131typedef union acpidisp_od_attrs_t {
132 uint16_t device_id; 132 uint16_t device_id;
133 uint32_t raw; 133 uint32_t raw;
134 struct { 134 struct {
135 uint8_t index:4; 135 uint8_t index:4;
136 uint8_t port:4; 136 uint8_t port:4;
137 uint8_t type:4; 137 uint8_t type:4;
138 uint8_t vendor_specific:4; 138 uint8_t vendor_specific:4;
139 uint8_t bios_detect:1; 139 uint8_t bios_detect:1;
140 uint8_t non_vga:1; 140 uint8_t non_vga:1;
141 uint8_t head_id:3; 141 uint8_t head_id:3;
142 uint16_t reserved:10; 142 uint16_t reserved:10;
143 uint8_t device_id_scheme:1; 143 uint8_t device_id_scheme:1;
144 } __packed fmt; 144 } __packed fmt;
145} acpidisp_od_attrs_t; 145} acpidisp_od_attrs_t;
146 146
147/* Common legacy output device IDs (ACPI 2.0c, Table B-3). */ 147/* Common legacy output device IDs (ACPI 2.0c, Table B-3). */
148#define ACPI_DISP_OUT_LEGACY_DEVID_MONITOR 0x0100 148#define ACPI_DISP_OUT_LEGACY_DEVID_MONITOR 0x0100
149#define ACPI_DISP_OUT_LEGACY_DEVID_PANEL 0x0110 149#define ACPI_DISP_OUT_LEGACY_DEVID_PANEL 0x0110
150#define ACPI_DISP_OUT_LEGACY_DEVID_TV 0x0200 150#define ACPI_DISP_OUT_LEGACY_DEVID_TV 0x0200
151 151
152/* Output device display types (ACPI 4.0a, Table B-2). */ 152/* Output device display types (ACPI 4.0a, Table B-2). */
153#define ACPI_DISP_OUT_ATTR_TYPE_OTHER 0x0 153#define ACPI_DISP_OUT_ATTR_TYPE_OTHER 0x0
154#define ACPI_DISP_OUT_ATTR_TYPE_VGA 0x1 154#define ACPI_DISP_OUT_ATTR_TYPE_VGA 0x1
155#define ACPI_DISP_OUT_ATTR_TYPE_TV 0x2 155#define ACPI_DISP_OUT_ATTR_TYPE_TV 0x2
156#define ACPI_DISP_OUT_ATTR_TYPE_EXTDIG 0x3 156#define ACPI_DISP_OUT_ATTR_TYPE_EXTDIG 0x3
157#define ACPI_DISP_OUT_ATTR_TYPE_INTDFP 0x4 157#define ACPI_DISP_OUT_ATTR_TYPE_INTDFP 0x4
158 158
159/* Format of output device status (ACPI 4.0a, Table B-4). */ 159/* Format of output device status (ACPI 4.0a, Table B-4). */
160typedef union acpidisp_od_status_t { 160typedef union acpidisp_od_status_t {
161 uint32_t raw; 161 uint32_t raw;
162 struct { 162 struct {
163 uint8_t exists:1; 163 uint8_t exists:1;
164 uint8_t activated:1; 164 uint8_t activated:1;
165 uint8_t ready:1; 165 uint8_t ready:1;
166 uint8_t not_defective:1; 166 uint8_t not_defective:1;
167 uint8_t attached:1; 167 uint8_t attached:1;
168 uint32_t reserved:27; 168 uint32_t reserved:27;
169 } __packed fmt; 169 } __packed fmt;
170} acpidisp_od_status_t; 170} acpidisp_od_status_t;
171 171
172/* Format of output device state (ACPI 4.0a, Table B-6). */ 172/* Format of output device state (ACPI 4.0a, Table B-6). */
173typedef union acpidisp_od_state_t { 173typedef union acpidisp_od_state_t {
174 uint32_t raw; 174 uint32_t raw;
175 struct { 175 struct {
176 uint8_t active:1; 176 uint8_t active:1;
177 uint32_t reserved:29; 177 uint32_t reserved:29;
178 uint8_t no_switch:1; 178 uint8_t no_switch:1;
179 uint8_t commit:1; 179 uint8_t commit:1;
180 } __packed fmt; 180 } __packed fmt;
181} acpidisp_od_state_t; 181} acpidisp_od_state_t;
182 182
183/* 183/*
184 * acpidisp_outdev: 184 * acpidisp_outdev:
185 * 185 *
186 * Description of an ACPI display output device. This structure groups 186 * Description of an ACPI display output device. This structure groups
187 * together: 187 * together:
188 * - the output device attributes, given in the display adapter's _DOD 188 * - the output device attributes, given in the display adapter's _DOD
189 * method (ACPI 4.0a, Sec. B.4.2). 189 * method (ACPI 4.0a, Sec. B.4.2).
190 * - the corresponding instance of the acpiout driver (if any). 190 * - the corresponding instance of the acpiout driver (if any).
191 */ 191 */
192struct acpidisp_outdev { 192struct acpidisp_outdev {
193 acpidisp_od_attrs_t od_attrs; /* Attributes */ 193 acpidisp_od_attrs_t od_attrs; /* Attributes */
194 device_t od_device; /* Matching base device */ 194 device_t od_device; /* Matching base device */
195}; 195};
196 196
197/* 197/*
198 * acpidisp_odinfo: 198 * acpidisp_odinfo:
199 * 199 *
200 * Information on connected output devices (ACPI 4.0a, Sec. B.4.2). This 200 * Information on connected output devices (ACPI 4.0a, Sec. B.4.2). This
201 * structure enumerates all devices (_DOD package) connected to a display 201 * structure enumerates all devices (_DOD package) connected to a display
202 * adapter. Currently, this information is only used for display output 202 * adapter. Currently, this information is only used for display output
203 * switching via hotkey. 203 * switching via hotkey.
204 * 204 *
205 * Invariants (after initialization): 205 * Invariants (after initialization):
206 * 206 *
207 * (oi_dev != NULL) && (oi_dev_count > 0) 207 * (oi_dev != NULL) && (oi_dev_count > 0)
208 */ 208 */
209struct acpidisp_odinfo { 209struct acpidisp_odinfo {
210 struct acpidisp_outdev *oi_dev; /* Array of output devices */ 210 struct acpidisp_outdev *oi_dev; /* Array of output devices */
211 uint32_t oi_dev_count; /* Number of output devices */ 211 uint32_t oi_dev_count; /* Number of output devices */
212}; 212};
213 213
214/* 214/*
215 * acpidisp_vga_softc: 215 * acpidisp_vga_softc:
216 * 216 *
217 * Software state of an ACPI display adapter. 217 * Software state of an ACPI display adapter.
218 * 218 *
219 * Invariants (after attachment): 219 * Invariants (after attachment):
220 * 220 *
221 * ((sc_caps & ACPI_DISP_VGA_CAP__DOD) == 0) => (sc_odinfo == NULL) 221 * ((sc_caps & ACPI_DISP_VGA_CAP__DOD) == 0) => (sc_odinfo == NULL)
222 */ 222 */
223struct acpidisp_vga_softc { 223struct acpidisp_vga_softc {
224 device_t sc_dev; /* Base device info */ 224 device_t sc_dev; /* Base device info */
225 struct acpi_devnode *sc_node; /* ACPI device node */ 225 struct acpi_devnode *sc_node; /* ACPI device node */
226 struct sysctllog *sc_log; /* Sysctl log */ 226 struct sysctllog *sc_log; /* Sysctl log */
227 kmutex_t sc_mtx; /* Mutex (shared w/ outputs) */ 227 kmutex_t sc_mtx; /* Mutex (shared w/ outputs) */
228 uint16_t sc_caps; /* Capabilities (methods) */ 228 uint16_t sc_caps; /* Capabilities (methods) */
229 acpidisp_bios_policy_t sc_policy; /* BIOS switch policy (_DOS) */ 229 acpidisp_bios_policy_t sc_policy; /* BIOS switch policy (_DOS) */
230 struct acpidisp_odinfo *sc_odinfo; /* Connected output devices */ 230 struct acpidisp_odinfo *sc_odinfo; /* Connected output devices */
231}; 231};
232 232
233/* 233/*
234 * ACPI display adapter capabilities (methods). 234 * ACPI display adapter capabilities (methods).
235 */ 235 */
236#define ACPI_DISP_VGA_CAP__DOS __BIT(0) 236#define ACPI_DISP_VGA_CAP__DOS __BIT(0)
237#define ACPI_DISP_VGA_CAP__DOD __BIT(1) 237#define ACPI_DISP_VGA_CAP__DOD __BIT(1)
238#define ACPI_DISP_VGA_CAP__ROM __BIT(2) 238#define ACPI_DISP_VGA_CAP__ROM __BIT(2)
239#define ACPI_DISP_VGA_CAP__GPD __BIT(3) 239#define ACPI_DISP_VGA_CAP__GPD __BIT(3)
240#define ACPI_DISP_VGA_CAP__SPD __BIT(4) 240#define ACPI_DISP_VGA_CAP__SPD __BIT(4)
241#define ACPI_DISP_VGA_CAP__VPO __BIT(5) 241#define ACPI_DISP_VGA_CAP__VPO __BIT(5)
242 242
243/* 243/*
244 * acpidisp_acpivga_attach_args: 244 * acpidisp_acpivga_attach_args:
245 * 245 *
246 * Attachment structure for the acpivga interface. Used to attach display 246 * Attachment structure for the acpivga interface. Used to attach display
247 * output devices under a display adapter. 247 * output devices under a display adapter.
248 */ 248 */
249struct acpidisp_acpivga_attach_args { 249struct acpidisp_acpivga_attach_args {
250 struct acpi_devnode *aa_node; /* ACPI device node */ 250 struct acpi_devnode *aa_node; /* ACPI device node */
251 kmutex_t *aa_mtx; /* Shared mutex */ 251 kmutex_t *aa_mtx; /* Shared mutex */
252}; 252};
253 253
254/* 254/*
255 * acpidisp_brctl: 255 * acpidisp_brctl:
256 * 256 *
257 * Brightness control (ACPI 4.0a, Sec. B.6.2 to B.6.4). This structure 257 * Brightness control (ACPI 4.0a, Sec. B.6.2 to B.6.4). This structure
258 * contains the supported brightness levels (_BCL package) and the current 258 * contains the supported brightness levels (_BCL package) and the current
259 * level. Following Windows 7 brightness control, we ignore the fullpower 259 * level. Following Windows 7 brightness control, we ignore the fullpower
260 * and battery levels (as it simplifies the code). 260 * and battery levels (as it simplifies the code).
261 * 261 *
262 * The array bc_level is sorted in strictly ascending order. 262 * The array bc_level is sorted in strictly ascending order.
263 * 263 *
264 * Invariants (after initialization): 264 * Invariants (after initialization):
265 * 265 *
266 * (bc_level != NULL) && (bc_level_count > 0) 266 * (bc_level != NULL) && (bc_level_count > 0)
267 */ 267 */
268struct acpidisp_brctl { 268struct acpidisp_brctl {
269 uint8_t *bc_level; /* Array of levels */ 269 uint8_t *bc_level; /* Array of levels */
270 uint16_t bc_level_count; /* Number of levels */ 270 uint16_t bc_level_count; /* Number of levels */
271 uint8_t bc_current; /* Current level */ 271 uint8_t bc_current; /* Current level */
272}; 272};
273 273
274/* 274/*
275 * Minimum brightness increment/decrement in response to increase/decrease 275 * Minimum brightness increment/decrement in response to increase/decrease
276 * brightness hotkey notifications. Must be strictly positive. 276 * brightness hotkey notifications. Must be strictly positive.
277 */ 277 */
278#define ACPI_DISP_BRCTL_STEP 5 278#define ACPI_DISP_BRCTL_STEP 5
279 279
280/* 280/*
281 * acpidisp_out_softc: 281 * acpidisp_out_softc:
282 * 282 *
283 * Software state of an ACPI display output device. 283 * Software state of an ACPI display output device.
284 * 284 *
285 * Invariants (after attachment): 285 * Invariants (after attachment):
286 * 286 *
287 * ((sc_caps & ACPI_DISP_OUT_CAP__BCL) == 0) => (sc_brctl == NULL) 287 * ((sc_caps & ACPI_DISP_OUT_CAP__BCL) == 0) => (sc_brctl == NULL)
288 * ((sc_caps & ACPI_DISP_OUT_CAP__BCM) == 0) => (sc_brctl == NULL) 288 * ((sc_caps & ACPI_DISP_OUT_CAP__BCM) == 0) => (sc_brctl == NULL)
289 */ 289 */
290struct acpidisp_out_softc { 290struct acpidisp_out_softc {
291 device_t sc_dev; /* Base device info */ 291 device_t sc_dev; /* Base device info */
292 struct acpi_devnode *sc_node; /* ACPI device node */ 292 struct acpi_devnode *sc_node; /* ACPI device node */
293 struct sysctllog *sc_log; /* Sysctl log */ 293 struct sysctllog *sc_log; /* Sysctl log */
294 kmutex_t *sc_mtx; /* Mutex (shared w/ adapter) */ 294 kmutex_t *sc_mtx; /* Mutex (shared w/ adapter) */
295 uint16_t sc_caps; /* Capabilities (methods) */ 295 uint16_t sc_caps; /* Capabilities (methods) */
296 struct acpidisp_brctl *sc_brctl; /* Brightness control */ 296 struct acpidisp_brctl *sc_brctl; /* Brightness control */
297}; 297};
298 298
299/* 299/*
300 * ACPI display output device capabilities (methods). 300 * ACPI display output device capabilities (methods).
301 */ 301 */
302#define ACPI_DISP_OUT_CAP__BCL __BIT(0) 302#define ACPI_DISP_OUT_CAP__BCL __BIT(0)
303#define ACPI_DISP_OUT_CAP__BCM __BIT(1) 303#define ACPI_DISP_OUT_CAP__BCM __BIT(1)
304#define ACPI_DISP_OUT_CAP__BQC __BIT(2) 304#define ACPI_DISP_OUT_CAP__BQC __BIT(2)
305#define ACPI_DISP_OUT_CAP__DDC __BIT(3) 305#define ACPI_DISP_OUT_CAP__DDC __BIT(3)
306#define ACPI_DISP_OUT_CAP__DCS __BIT(4) 306#define ACPI_DISP_OUT_CAP__DCS __BIT(4)
307#define ACPI_DISP_OUT_CAP__DGS __BIT(5) 307#define ACPI_DISP_OUT_CAP__DGS __BIT(5)
308#define ACPI_DISP_OUT_CAP__DSS __BIT(6) 308#define ACPI_DISP_OUT_CAP__DSS __BIT(6)
309 309
310static int acpidisp_vga_match(device_t, cfdata_t, void *); 310static int acpidisp_vga_match(device_t, cfdata_t, void *);
311static void acpidisp_vga_attach(device_t, device_t, void *); 311static void acpidisp_vga_attach(device_t, device_t, void *);
312static int acpidisp_vga_detach(device_t, int); 312static int acpidisp_vga_detach(device_t, int);
313static void acpidisp_vga_childdetached(device_t, device_t); 313static void acpidisp_vga_childdetached(device_t, device_t);
314 314
315static void acpidisp_vga_scan_outdevs(struct acpidisp_vga_softc *); 315static void acpidisp_vga_scan_outdevs(struct acpidisp_vga_softc *);
316static int acpidisp_acpivga_print(void *, const char *); 316static int acpidisp_acpivga_print(void *, const char *);
317 317
318static int acpidisp_out_match(device_t, cfdata_t, void *); 318static int acpidisp_out_match(device_t, cfdata_t, void *);
319static void acpidisp_out_attach(device_t, device_t, void *); 319static void acpidisp_out_attach(device_t, device_t, void *);
320static int acpidisp_out_detach(device_t, int); 320static int acpidisp_out_detach(device_t, int);
321 321
322CFATTACH_DECL2_NEW(acpivga, sizeof(struct acpidisp_vga_softc), 322CFATTACH_DECL2_NEW(acpivga, sizeof(struct acpidisp_vga_softc),
323 acpidisp_vga_match, acpidisp_vga_attach, acpidisp_vga_detach, NULL, 323 acpidisp_vga_match, acpidisp_vga_attach, acpidisp_vga_detach, NULL,
324 NULL, acpidisp_vga_childdetached); 324 NULL, acpidisp_vga_childdetached);
325 325
326CFATTACH_DECL_NEW(acpiout, sizeof(struct acpidisp_out_softc), 326CFATTACH_DECL_NEW(acpiout, sizeof(struct acpidisp_out_softc),
327 acpidisp_out_match, acpidisp_out_attach, acpidisp_out_detach, NULL); 327 acpidisp_out_match, acpidisp_out_attach, acpidisp_out_detach, NULL);
328 328
329static bool acpidisp_vga_resume(device_t, const pmf_qual_t *); 329static bool acpidisp_vga_resume(device_t, const pmf_qual_t *);
330static bool acpidisp_out_suspend(device_t, const pmf_qual_t *); 330static bool acpidisp_out_suspend(device_t, const pmf_qual_t *);
331static bool acpidisp_out_resume(device_t, const pmf_qual_t *); 331static bool acpidisp_out_resume(device_t, const pmf_qual_t *);
332 332
333static uint16_t acpidisp_vga_capabilities(const struct acpi_devnode *); 333static uint16_t acpidisp_vga_capabilities(const struct acpi_devnode *);
334static uint16_t acpidisp_out_capabilities(const struct acpi_devnode *); 334static uint16_t acpidisp_out_capabilities(const struct acpi_devnode *);
335static void acpidisp_vga_print_capabilities(device_t, uint16_t); 335static void acpidisp_vga_print_capabilities(device_t, uint16_t);
336static void acpidisp_out_print_capabilities(device_t, uint16_t); 336static void acpidisp_out_print_capabilities(device_t, uint16_t);
337 337
338static void acpidisp_vga_notify_handler(ACPI_HANDLE, uint32_t, void *); 338static void acpidisp_vga_notify_handler(ACPI_HANDLE, uint32_t, void *);
339static void acpidisp_out_notify_handler(ACPI_HANDLE, uint32_t, void *); 339static void acpidisp_out_notify_handler(ACPI_HANDLE, uint32_t, void *);
340 340
341static void acpidisp_vga_cycle_output_device_callback(void *); 341static void acpidisp_vga_cycle_output_device_callback(void *);
342static void acpidisp_vga_output_device_change_callback(void *); 342static void acpidisp_vga_output_device_change_callback(void *);
343static void acpidisp_out_increase_brightness_callback(void *); 343static void acpidisp_out_increase_brightness_callback(void *);
344static void acpidisp_out_decrease_brightness_callback(void *); 344static void acpidisp_out_decrease_brightness_callback(void *);
345static void acpidisp_out_cycle_brightness_callback(void *); 345static void acpidisp_out_cycle_brightness_callback(void *);
346static void acpidisp_out_zero_brightness_callback(void *); 346static void acpidisp_out_zero_brightness_callback(void *);
347 347
348static void acpidisp_vga_sysctl_setup(struct acpidisp_vga_softc *); 348static void acpidisp_vga_sysctl_setup(struct acpidisp_vga_softc *);
349static void acpidisp_out_sysctl_setup(struct acpidisp_out_softc *); 349static void acpidisp_out_sysctl_setup(struct acpidisp_out_softc *);
350#ifdef ACPI_DEBUG 350#ifdef ACPI_DEBUG
351static int acpidisp_vga_sysctl_policy(SYSCTLFN_PROTO); 351static int acpidisp_vga_sysctl_policy(SYSCTLFN_PROTO);
352#endif 352#endif
353static int acpidisp_vga_sysctl_policy_output(SYSCTLFN_PROTO); 353static int acpidisp_vga_sysctl_policy_output(SYSCTLFN_PROTO);
354#ifdef ACPI_DISP_SWITCH_SYSCTLS 354#ifdef ACPI_DISP_SWITCH_SYSCTLS
355static int acpidisp_out_sysctl_status(SYSCTLFN_PROTO); 355static int acpidisp_out_sysctl_status(SYSCTLFN_PROTO);
356static int acpidisp_out_sysctl_state(SYSCTLFN_PROTO); 356static int acpidisp_out_sysctl_state(SYSCTLFN_PROTO);
357#endif 357#endif
358static int acpidisp_out_sysctl_brightness(SYSCTLFN_PROTO); 358static int acpidisp_out_sysctl_brightness(SYSCTLFN_PROTO);
359 359
360static struct acpidisp_odinfo * 360static struct acpidisp_odinfo *
361 acpidisp_init_odinfo(const struct acpidisp_vga_softc *); 361 acpidisp_init_odinfo(const struct acpidisp_vga_softc *);
362static void acpidisp_vga_bind_outdevs(struct acpidisp_vga_softc *); 362static void acpidisp_vga_bind_outdevs(struct acpidisp_vga_softc *);
363static struct acpidisp_brctl * 363static struct acpidisp_brctl *
364 acpidisp_init_brctl(const struct acpidisp_out_softc *); 364 acpidisp_init_brctl(const struct acpidisp_out_softc *);
365 365
366static int acpidisp_set_policy(const struct acpidisp_vga_softc *, 366static int acpidisp_set_policy(const struct acpidisp_vga_softc *,
367 uint8_t); 367 uint8_t);
368static int acpidisp_get_status(const struct acpidisp_out_softc *, 368static int acpidisp_get_status(const struct acpidisp_out_softc *,
369 uint32_t *); 369 uint32_t *);
370static int acpidisp_get_state(const struct acpidisp_out_softc *, 370static int acpidisp_get_state(const struct acpidisp_out_softc *,
371 uint32_t *); 371 uint32_t *);
372static int acpidisp_set_state(const struct acpidisp_out_softc *, 372static int acpidisp_set_state(const struct acpidisp_out_softc *,
373 uint32_t); 373 uint32_t);
374static int acpidisp_get_brightness(const struct acpidisp_out_softc *, 374static int acpidisp_get_brightness(const struct acpidisp_out_softc *,
375 uint8_t *); 375 uint8_t *);
376static int acpidisp_set_brightness(const struct acpidisp_out_softc *, 376static int acpidisp_set_brightness(const struct acpidisp_out_softc *,
377 uint8_t); 377 uint8_t);
378 378
379static void acpidisp_print_odinfo(device_t, const struct acpidisp_odinfo *); 379static void acpidisp_print_odinfo(device_t, const struct acpidisp_odinfo *);
380static void acpidisp_print_brctl(device_t, const struct acpidisp_brctl *); 380static void acpidisp_print_brctl(device_t, const struct acpidisp_brctl *);
381static void acpidisp_print_od_attrs(acpidisp_od_attrs_t); 381static void acpidisp_print_od_attrs(acpidisp_od_attrs_t);
382 382
383static bool acpidisp_has_method(ACPI_HANDLE, const char *, 383static bool acpidisp_has_method(ACPI_HANDLE, const char *,
384 ACPI_OBJECT_TYPE); 384 ACPI_OBJECT_TYPE);
385static ACPI_STATUS 385static ACPI_STATUS
386 acpidisp_eval_package(ACPI_HANDLE, const char *, ACPI_OBJECT **, 386 acpidisp_eval_package(ACPI_HANDLE, const char *, ACPI_OBJECT **,
387 unsigned int); 387 unsigned int);
388static void acpidisp_array_search(const uint8_t *, uint16_t, int, uint8_t *, 388static void acpidisp_array_search(const uint8_t *, uint16_t, int, uint8_t *,
389 uint8_t *); 389 uint8_t *);
390 390
391/* 391/*
392 * Autoconfiguration for the acpivga driver. 392 * Autoconfiguration for the acpivga driver.
393 */ 393 */
394 394
395static int 395static int
396acpidisp_vga_match(device_t parent, cfdata_t match, void *aux) 396acpidisp_vga_match(device_t parent, cfdata_t match, void *aux)
397{ 397{
398 struct acpi_attach_args *aa = aux; 398 struct acpi_attach_args *aa = aux;
399 struct acpi_devnode *ad = aa->aa_node; 399 struct acpi_devnode *ad = aa->aa_node;
400 struct acpi_softc *sc = device_private(ad->ad_root); 400 struct acpi_softc *sc = device_private(ad->ad_root);
401 struct acpi_pci_info *ap; 401 struct acpi_pci_info *ap;
402 pcitag_t tag; 402 pcitag_t tag;
403 pcireg_t id, class; 403 pcireg_t id, class;
404 404
405 /* 405 /*
406 * We match ACPI devices that correspond to PCI display controllers. 406 * We match ACPI devices that correspond to PCI display controllers.
407 */ 407 */
408 if (ad->ad_type != ACPI_TYPE_DEVICE) 408 if (ad->ad_type != ACPI_TYPE_DEVICE)
409 return 0; 409 return 0;
410 410
411 ap = ad->ad_pciinfo; 411 ap = ad->ad_pciinfo;
412 if ((ap == NULL) || 412 if ((ap == NULL) ||
413 !(ap->ap_flags & ACPI_PCI_INFO_DEVICE) || 413 !(ap->ap_flags & ACPI_PCI_INFO_DEVICE) ||
414 (ap->ap_function == 0xffff)) 414 (ap->ap_function == 0xffff))
415 return 0; 415 return 0;
416 416
417 KASSERT(ap->ap_bus < 256 && ap->ap_device < 32 && ap->ap_function < 8); 417 KASSERT(ap->ap_bus < 256 && ap->ap_device < 32 && ap->ap_function < 8);
418 418
419 tag = pci_make_tag(sc->sc_pc, ap->ap_bus, ap->ap_device, 419 tag = pci_make_tag(sc->sc_pc, ap->ap_bus, ap->ap_device,
420 ap->ap_function); 420 ap->ap_function);
421 421
422 /* Check that the PCI device is present. */ 422 /* Check that the PCI device is present. */
423 id = pci_conf_read(sc->sc_pc, tag, PCI_ID_REG); 423 id = pci_conf_read(sc->sc_pc, tag, PCI_ID_REG);
424 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID || 424 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID ||
425 PCI_VENDOR(id) == 0) 425 PCI_VENDOR(id) == 0)
426 return 0; 426 return 0;
427 427
428 /* Check the class of the PCI device. */ 428 /* Check the class of the PCI device. */
429 class = pci_conf_read(sc->sc_pc, tag, PCI_CLASS_REG); 429 class = pci_conf_read(sc->sc_pc, tag, PCI_CLASS_REG);
430 if (PCI_CLASS(class) != PCI_CLASS_DISPLAY) 430 if (PCI_CLASS(class) != PCI_CLASS_DISPLAY)
431 return 0; 431 return 0;
432 432
433 /* We match if the display adapter is capable of something... */ 433 /* We match if the display adapter is capable of something... */
434 if (acpidisp_vga_capabilities(ad) == 0) 434 if (acpidisp_vga_capabilities(ad) == 0)
435 return 0; 435 return 0;
436 436
437 return 1; 437 return 1;
438} 438}
439 439
440static void 440static void
441acpidisp_vga_attach(device_t parent, device_t self, void *aux) 441acpidisp_vga_attach(device_t parent, device_t self, void *aux)
442{ 442{
443 struct acpidisp_vga_softc *asc = device_private(self); 443 struct acpidisp_vga_softc *asc = device_private(self);
444 struct acpi_attach_args *aa = aux; 444 struct acpi_attach_args *aa = aux;
445 struct acpi_devnode *ad = aa->aa_node; 445 struct acpi_devnode *ad = aa->aa_node;
446 446
447 aprint_naive(": ACPI Display Adapter\n"); 447 aprint_naive(": ACPI Display Adapter\n");
448 aprint_normal(": ACPI Display Adapter\n"); 448 aprint_normal(": ACPI Display Adapter\n");
449 449
450 asc->sc_dev = self; 450 asc->sc_dev = self;
451 asc->sc_node = ad; 451 asc->sc_node = ad;
452 asc->sc_log = NULL; 452 asc->sc_log = NULL;
453 mutex_init(&asc->sc_mtx, MUTEX_DEFAULT, IPL_NONE); 453 mutex_init(&asc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);
454 asc->sc_caps = acpidisp_vga_capabilities(ad); 454 asc->sc_caps = acpidisp_vga_capabilities(ad);
455 asc->sc_policy = acpidisp_default_bios_policy; 455 asc->sc_policy = acpidisp_default_bios_policy;
456 asc->sc_odinfo = NULL; 456 asc->sc_odinfo = NULL;
457 457
458 acpidisp_vga_print_capabilities(self, asc->sc_caps); 458 acpidisp_vga_print_capabilities(self, asc->sc_caps);
459 459
460 /* Enumerate connected output devices. */ 460 /* Enumerate connected output devices. */
461 asc->sc_odinfo = acpidisp_init_odinfo(asc); 461 asc->sc_odinfo = acpidisp_init_odinfo(asc);
462 462
463 /* Attach (via autoconf(9)) ACPI display output devices. */ 463 /* Attach (via autoconf(9)) ACPI display output devices. */
464 acpidisp_vga_scan_outdevs(asc); 464 acpidisp_vga_scan_outdevs(asc);
465 465
466 /* Bind the attached output devices to the enumerated ones. */ 466 /* Bind the attached output devices to the enumerated ones. */
467 if (asc->sc_odinfo != NULL) { 467 if (asc->sc_odinfo != NULL) {
468 acpidisp_vga_bind_outdevs(asc); 468 acpidisp_vga_bind_outdevs(asc);
469 acpidisp_print_odinfo(self, asc->sc_odinfo); 469 acpidisp_print_odinfo(self, asc->sc_odinfo);
470 } 470 }
471 471
472 /* Install ACPI notify handler. */ 472 /* Install ACPI notify handler. */
473 (void)acpi_register_notify(asc->sc_node, acpidisp_vga_notify_handler); 473 (void)acpi_register_notify(asc->sc_node, acpidisp_vga_notify_handler);
474 474
475 /* 475 /*
476 * Set BIOS automatic switch policy. 476 * Set BIOS automatic switch policy.
477 * 477 *
478 * Many laptops do not support output device switching with the methods 478 * Many laptops do not support output device switching with the methods
479 * specified in the ACPI extensions for display adapters. Therefore, we 479 * specified in the ACPI extensions for display adapters. Therefore, we
480 * leave the BIOS output switch policy on ``auto'' instead of setting it 480 * leave the BIOS output switch policy on ``auto'' instead of setting it
481 * to ``normal''. 481 * to ``normal''.
482 */ 482 */
483 asc->sc_policy.fmt.output = ACPI_DISP_POLICY_OUTPUT_AUTO; 483 asc->sc_policy.fmt.output = ACPI_DISP_POLICY_OUTPUT_AUTO;
484 asc->sc_policy.fmt.brightness = ACPI_DISP_POLICY_BRIGHTNESS_NORMAL; 484 asc->sc_policy.fmt.brightness = ACPI_DISP_POLICY_BRIGHTNESS_NORMAL;
485 if (acpidisp_set_policy(asc, asc->sc_policy.raw)) 485 if (acpidisp_set_policy(asc, asc->sc_policy.raw))
486 asc->sc_policy = acpidisp_default_bios_policy; 486 asc->sc_policy = acpidisp_default_bios_policy;
487 487
488 /* Setup sysctl. */ 488 /* Setup sysctl. */
489 acpidisp_vga_sysctl_setup(asc); 489 acpidisp_vga_sysctl_setup(asc);
490 490
491 /* Power management. */ 491 /* Power management. */
492 if (!pmf_device_register(self, NULL, acpidisp_vga_resume)) 492 if (!pmf_device_register(self, NULL, acpidisp_vga_resume))
493 aprint_error_dev(self, "couldn't establish power handler\n"); 493 aprint_error_dev(self, "couldn't establish power handler\n");
494} 494}
495 495
496static int 496static int
497acpidisp_vga_detach(device_t self, int flags) 497acpidisp_vga_detach(device_t self, int flags)
498{ 498{
499 struct acpidisp_vga_softc *asc = device_private(self); 499 struct acpidisp_vga_softc *asc = device_private(self);
500 struct acpidisp_odinfo *oi = asc->sc_odinfo; 500 struct acpidisp_odinfo *oi = asc->sc_odinfo;
501 int rc; 501 int rc;
502 502
503 pmf_device_deregister(self); 503 pmf_device_deregister(self);
504 504
505 if (asc->sc_log != NULL) 505 if (asc->sc_log != NULL)
506 sysctl_teardown(&asc->sc_log); 506 sysctl_teardown(&asc->sc_log);
507 507
508 asc->sc_policy = acpidisp_default_bios_policy; 508 asc->sc_policy = acpidisp_default_bios_policy;
509 acpidisp_set_policy(asc, asc->sc_policy.raw); 509 acpidisp_set_policy(asc, asc->sc_policy.raw);
510 510
511 acpi_deregister_notify(asc->sc_node); 511 acpi_deregister_notify(asc->sc_node);
512 512
513 if ((rc = config_detach_children(self, flags)) != 0) 513 if ((rc = config_detach_children(self, flags)) != 0)
514 return rc; 514 return rc;
515 515
516 if (oi != NULL) { 516 if (oi != NULL) {
517 kmem_free(oi->oi_dev, 517 kmem_free(oi->oi_dev,
518 oi->oi_dev_count * sizeof(*oi->oi_dev)); 518 oi->oi_dev_count * sizeof(*oi->oi_dev));
519 kmem_free(oi, sizeof(*oi)); 519 kmem_free(oi, sizeof(*oi));
520 } 520 }
521 521
522 mutex_destroy(&asc->sc_mtx); 522 mutex_destroy(&asc->sc_mtx);
523 523
524 return 0; 524 return 0;
525} 525}
526 526
527void 527void
528acpidisp_vga_childdetached(device_t self, device_t child) 528acpidisp_vga_childdetached(device_t self, device_t child)
529{ 529{
530 struct acpidisp_vga_softc *asc = device_private(self); 530 struct acpidisp_vga_softc *asc = device_private(self);
531 struct acpidisp_odinfo *oi = asc->sc_odinfo; 531 struct acpidisp_odinfo *oi = asc->sc_odinfo;
532 struct acpidisp_outdev *od; 532 struct acpidisp_outdev *od;
533 struct acpi_devnode *ad; 533 struct acpi_devnode *ad;
534 uint32_t i; 534 uint32_t i;
535 535
536 SIMPLEQ_FOREACH(ad, &asc->sc_node->ad_child_head, ad_child_list) { 536 SIMPLEQ_FOREACH(ad, &asc->sc_node->ad_child_head, ad_child_list) {
537 537
538 if (ad->ad_device == child) 538 if (ad->ad_device == child)
539 ad->ad_device = NULL; 539 ad->ad_device = NULL;
540 } 540 }
541 541
542 if (oi == NULL) 542 if (oi == NULL)
543 return; 543 return;
544 544
545 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) { 545 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) {
546 if (od->od_device == child) 546 if (od->od_device == child)
547 od->od_device = NULL; 547 od->od_device = NULL;
548 } 548 }
549} 549}
550 550
551/* 551/*
552 * Attachment of acpiout under acpivga. 552 * Attachment of acpiout under acpivga.
553 */ 553 */
554 554
555static void 555static void
556acpidisp_vga_scan_outdevs(struct acpidisp_vga_softc *asc) 556acpidisp_vga_scan_outdevs(struct acpidisp_vga_softc *asc)
557{ 557{
558 struct acpidisp_acpivga_attach_args aa; 558 struct acpidisp_acpivga_attach_args aa;
559 struct acpi_devnode *ad; 559 struct acpi_devnode *ad;
560 560
561 /* 561 /*
562 * Display output devices are ACPI children of the display adapter. 562 * Display output devices are ACPI children of the display adapter.
563 */ 563 */
564 SIMPLEQ_FOREACH(ad, &asc->sc_node->ad_child_head, ad_child_list) { 564 SIMPLEQ_FOREACH(ad, &asc->sc_node->ad_child_head, ad_child_list) {
565 565
566 if (ad->ad_device != NULL) /* This should not happen. */ 566 if (ad->ad_device != NULL) /* This should not happen. */
567 continue; 567 continue;
568 568
569 aa.aa_node = ad; 569 aa.aa_node = ad;
570 aa.aa_mtx = &asc->sc_mtx; 570 aa.aa_mtx = &asc->sc_mtx;
571 571
572 ad->ad_device = config_found_ia(asc->sc_dev, 572 ad->ad_device = config_found_ia(asc->sc_dev,
573 "acpivga", &aa, acpidisp_acpivga_print); 573 "acpivga", &aa, acpidisp_acpivga_print);
574 } 574 }
575} 575}
576 576
577static int 577static int
578acpidisp_acpivga_print(void *aux, const char *pnp) 578acpidisp_acpivga_print(void *aux, const char *pnp)
579{ 579{
580 struct acpidisp_acpivga_attach_args *aa = aux; 580 struct acpidisp_acpivga_attach_args *aa = aux;
581 struct acpi_devnode *ad = aa->aa_node; 581 struct acpi_devnode *ad = aa->aa_node;
582 582
583 if (pnp) { 583 if (pnp) {
584 aprint_normal("%s at %s", ad->ad_name, pnp); 584 aprint_normal("%s at %s", ad->ad_name, pnp);
585 } else { 585 } else {
586 aprint_normal(" (%s", ad->ad_name); 586 aprint_normal(" (%s", ad->ad_name);
587 if (ad->ad_devinfo->Valid & ACPI_VALID_ADR) 587 if (ad->ad_devinfo->Valid & ACPI_VALID_ADR)
588 aprint_normal(", 0x%04"PRIx64, ad->ad_devinfo->Address); 588 aprint_normal(", 0x%04"PRIx64, ad->ad_devinfo->Address);
589 aprint_normal(")"); 589 aprint_normal(")");
590 } 590 }
591 591
592 return UNCONF; 592 return UNCONF;
593} 593}
594 594
595/* 595/*
596 * Autoconfiguration for the acpiout driver. 596 * Autoconfiguration for the acpiout driver.
597 */ 597 */
598 598
599static int 599static int
600acpidisp_out_match(device_t parent, cfdata_t match, void *aux) 600acpidisp_out_match(device_t parent, cfdata_t match, void *aux)
601{ 601{
602 struct acpidisp_acpivga_attach_args *aa = aux; 602 struct acpidisp_acpivga_attach_args *aa = aux;
603 struct acpi_devnode *ad = aa->aa_node; 603 struct acpi_devnode *ad = aa->aa_node;
604 604
605 if (ad->ad_type != ACPI_TYPE_DEVICE) 605 if (ad->ad_type != ACPI_TYPE_DEVICE)
606 return 0; 606 return 0;
607 607
608 /* 608 /*
609 * The method _ADR is required for display output 609 * The method _ADR is required for display output
610 * devices (ACPI 4.0a, Sec. B.6.1). 610 * devices (ACPI 4.0a, Sec. B.6.1).
611 */ 611 */
612 if (!(acpidisp_has_method(ad->ad_handle, "_ADR", ACPI_TYPE_INTEGER))) 612 if (!(acpidisp_has_method(ad->ad_handle, "_ADR", ACPI_TYPE_INTEGER)))
613 return 0; 613 return 0;
614 614
615 return 1; 615 return 1;
616} 616}
617 617
618static void 618static void
619acpidisp_out_attach(device_t parent, device_t self, void *aux) 619acpidisp_out_attach(device_t parent, device_t self, void *aux)
620{ 620{
621 struct acpidisp_out_softc *osc = device_private(self); 621 struct acpidisp_out_softc *osc = device_private(self);
622 struct acpidisp_acpivga_attach_args *aa = aux; 622 struct acpidisp_acpivga_attach_args *aa = aux;
623 struct acpi_devnode *ad = aa->aa_node; 623 struct acpi_devnode *ad = aa->aa_node;
624 struct acpidisp_brctl *bc; 624 struct acpidisp_brctl *bc;
625 625
626 aprint_naive("\n"); 626 aprint_naive("\n");
627 aprint_normal(": ACPI Display Output Device\n"); 627 aprint_normal(": ACPI Display Output Device\n");
628 628
629 osc->sc_dev = self; 629 osc->sc_dev = self;
630 osc->sc_node = ad; 630 osc->sc_node = ad;
631 osc->sc_log = NULL; 631 osc->sc_log = NULL;
632 osc->sc_mtx = aa->aa_mtx; 632 osc->sc_mtx = aa->aa_mtx;
633 osc->sc_caps = acpidisp_out_capabilities(ad); 633 osc->sc_caps = acpidisp_out_capabilities(ad);
634 osc->sc_brctl = NULL; 634 osc->sc_brctl = NULL;
635 635
636 acpidisp_out_print_capabilities(self, osc->sc_caps); 636 acpidisp_out_print_capabilities(self, osc->sc_caps);
637 637
638 osc->sc_brctl = acpidisp_init_brctl(osc); 638 osc->sc_brctl = acpidisp_init_brctl(osc);
639 bc = osc->sc_brctl; 639 bc = osc->sc_brctl;
640 if (bc != NULL) { 640 if (bc != NULL) {
641 bc->bc_current = bc->bc_level[bc->bc_level_count - 1]; 641 bc->bc_current = bc->bc_level[bc->bc_level_count - 1];
642 642
643 /* 643 /*
644 * Synchronize ACPI and driver brightness levels, and 644 * Synchronize ACPI and driver brightness levels, and
645 * check that brightness control is working. 645 * check that brightness control is working.
646 */ 646 */
647 (void)acpidisp_get_brightness(osc, &bc->bc_current); 647 (void)acpidisp_get_brightness(osc, &bc->bc_current);
648 if (acpidisp_set_brightness(osc, bc->bc_current)) { 648 if (acpidisp_set_brightness(osc, bc->bc_current)) {
649 kmem_free(bc->bc_level, 649 kmem_free(bc->bc_level,
650 bc->bc_level_count * sizeof(*bc->bc_level)); 650 bc->bc_level_count * sizeof(*bc->bc_level));
651 kmem_free(bc, sizeof(*bc)); 651 kmem_free(bc, sizeof(*bc));
652 osc->sc_brctl = NULL; 652 osc->sc_brctl = NULL;
653 } else { 653 } else {
654 acpidisp_print_brctl(self, osc->sc_brctl); 654 acpidisp_print_brctl(self, osc->sc_brctl);
655 } 655 }
656 } 656 }
657 657
658 /* Install ACPI notify handler. */ 658 /* Install ACPI notify handler. */
659 (void)acpi_register_notify(osc->sc_node, acpidisp_out_notify_handler); 659 (void)acpi_register_notify(osc->sc_node, acpidisp_out_notify_handler);
660 660
661 /* Setup sysctl. */ 661 /* Setup sysctl. */
662 acpidisp_out_sysctl_setup(osc); 662 acpidisp_out_sysctl_setup(osc);
663 663
664 /* Power management. */ 664 /* Power management. */
665 if (!pmf_device_register(self, acpidisp_out_suspend, 665 if (!pmf_device_register(self, acpidisp_out_suspend,
666 acpidisp_out_resume)) 666 acpidisp_out_resume))
667 aprint_error_dev(self, "couldn't establish power handler\n"); 667 aprint_error_dev(self, "couldn't establish power handler\n");
668} 668}
669 669
670static int 670static int
671acpidisp_out_detach(device_t self, int flags) 671acpidisp_out_detach(device_t self, int flags)
672{ 672{
673 struct acpidisp_out_softc *osc = device_private(self); 673 struct acpidisp_out_softc *osc = device_private(self);
674 struct acpidisp_brctl *bc = osc->sc_brctl; 674 struct acpidisp_brctl *bc = osc->sc_brctl;
675 675
676 pmf_device_deregister(self); 676 pmf_device_deregister(self);
677 677
678 if (osc->sc_log != NULL) 678 if (osc->sc_log != NULL)
679 sysctl_teardown(&osc->sc_log); 679 sysctl_teardown(&osc->sc_log);
680 680
681 acpi_deregister_notify(osc->sc_node); 681 acpi_deregister_notify(osc->sc_node);
682 682
683 if (bc != NULL) { 683 if (bc != NULL) {
684 kmem_free(bc->bc_level, 684 kmem_free(bc->bc_level,
685 bc->bc_level_count * sizeof(*bc->bc_level)); 685 bc->bc_level_count * sizeof(*bc->bc_level));
686 kmem_free(bc, sizeof(*bc)); 686 kmem_free(bc, sizeof(*bc));
687 } 687 }
688 688
689 return 0; 689 return 0;
690} 690}
691 691
692/* 692/*
693 * Power management. 693 * Power management.
694 */ 694 */
695 695
696static bool 696static bool
697acpidisp_vga_resume(device_t self, const pmf_qual_t *qual) 697acpidisp_vga_resume(device_t self, const pmf_qual_t *qual)
698{ 698{
699 struct acpidisp_vga_softc *asc = device_private(self); 699 struct acpidisp_vga_softc *asc = device_private(self);
700 700
701 mutex_enter(&asc->sc_mtx); 701 mutex_enter(&asc->sc_mtx);
702 (void)acpidisp_set_policy(asc, asc->sc_policy.raw); 702 (void)acpidisp_set_policy(asc, asc->sc_policy.raw);
703 mutex_exit(&asc->sc_mtx); 703 mutex_exit(&asc->sc_mtx);
704 704
705 return true; 705 return true;
706} 706}
707 707
708static bool 708static bool
709acpidisp_out_suspend(device_t self, const pmf_qual_t *qual) 709acpidisp_out_suspend(device_t self, const pmf_qual_t *qual)
710{ 710{
711 struct acpidisp_out_softc *osc = device_private(self); 711 struct acpidisp_out_softc *osc = device_private(self);
712 712
713 mutex_enter(osc->sc_mtx); 713 mutex_enter(osc->sc_mtx);
714 if (osc->sc_brctl != NULL) 714 if (osc->sc_brctl != NULL)
715 (void)acpidisp_get_brightness(osc, &osc->sc_brctl->bc_current); 715 (void)acpidisp_get_brightness(osc, &osc->sc_brctl->bc_current);
716 mutex_exit(osc->sc_mtx); 716 mutex_exit(osc->sc_mtx);
717 717
718 return true; 718 return true;
719} 719}
720 720
721static bool 721static bool
722acpidisp_out_resume(device_t self, const pmf_qual_t *qual) 722acpidisp_out_resume(device_t self, const pmf_qual_t *qual)
723{ 723{
724 struct acpidisp_out_softc *osc = device_private(self); 724 struct acpidisp_out_softc *osc = device_private(self);
725 725
726 mutex_enter(osc->sc_mtx); 726 mutex_enter(osc->sc_mtx);
727 if (osc->sc_brctl != NULL) 727 if (osc->sc_brctl != NULL)
728 (void)acpidisp_set_brightness(osc, osc->sc_brctl->bc_current); 728 (void)acpidisp_set_brightness(osc, osc->sc_brctl->bc_current);
729 mutex_exit(osc->sc_mtx); 729 mutex_exit(osc->sc_mtx);
730 730
731 return true; 731 return true;
732} 732}
733 733
734/* 734/*
735 * Capabilities (available methods). 735 * Capabilities (available methods).
736 */ 736 */
737 737
738static uint16_t 738static uint16_t
739acpidisp_vga_capabilities(const struct acpi_devnode *ad) 739acpidisp_vga_capabilities(const struct acpi_devnode *ad)
740{ 740{
741 uint16_t cap; 741 uint16_t cap;
742 742
743 cap = 0; 743 cap = 0;
744 744
745 if (acpidisp_has_method(ad->ad_handle, "_DOS", ACPI_TYPE_METHOD)) 745 if (acpidisp_has_method(ad->ad_handle, "_DOS", ACPI_TYPE_METHOD))
746 cap |= ACPI_DISP_VGA_CAP__DOS; 746 cap |= ACPI_DISP_VGA_CAP__DOS;
747 747
748 if (acpidisp_has_method(ad->ad_handle, "_DOD", ACPI_TYPE_PACKAGE)) 748 if (acpidisp_has_method(ad->ad_handle, "_DOD", ACPI_TYPE_PACKAGE))
749 cap |= ACPI_DISP_VGA_CAP__DOD; 749 cap |= ACPI_DISP_VGA_CAP__DOD;
750 750
751 if (acpidisp_has_method(ad->ad_handle, "_ROM", ACPI_TYPE_BUFFER)) 751 if (acpidisp_has_method(ad->ad_handle, "_ROM", ACPI_TYPE_BUFFER))
752 cap |= ACPI_DISP_VGA_CAP__ROM; 752 cap |= ACPI_DISP_VGA_CAP__ROM;
753 753
754 if (acpidisp_has_method(ad->ad_handle, "_GPD", ACPI_TYPE_INTEGER)) 754 if (acpidisp_has_method(ad->ad_handle, "_GPD", ACPI_TYPE_INTEGER))
755 cap |= ACPI_DISP_VGA_CAP__GPD; 755 cap |= ACPI_DISP_VGA_CAP__GPD;
756 756
757 if (acpidisp_has_method(ad->ad_handle, "_SPD", ACPI_TYPE_METHOD)) 757 if (acpidisp_has_method(ad->ad_handle, "_SPD", ACPI_TYPE_METHOD))
758 cap |= ACPI_DISP_VGA_CAP__SPD; 758 cap |= ACPI_DISP_VGA_CAP__SPD;
759 759
760 if (acpidisp_has_method(ad->ad_handle, "_VPO", ACPI_TYPE_INTEGER)) 760 if (acpidisp_has_method(ad->ad_handle, "_VPO", ACPI_TYPE_INTEGER))
761 cap |= ACPI_DISP_VGA_CAP__VPO; 761 cap |= ACPI_DISP_VGA_CAP__VPO;
762 762
763 return cap; 763 return cap;
764} 764}
765 765
766static void 766static void
767acpidisp_vga_print_capabilities(device_t self, uint16_t cap) 767acpidisp_vga_print_capabilities(device_t self, uint16_t cap)
768{ 768{
769 aprint_debug_dev(self, "capabilities:%s%s%s%s%s%s\n", 769 aprint_debug_dev(self, "capabilities:%s%s%s%s%s%s\n",
770 (cap & ACPI_DISP_VGA_CAP__DOS) ? " _DOS" : "", 770 (cap & ACPI_DISP_VGA_CAP__DOS) ? " _DOS" : "",
771 (cap & ACPI_DISP_VGA_CAP__DOD) ? " _DOD" : "", 771 (cap & ACPI_DISP_VGA_CAP__DOD) ? " _DOD" : "",
772 (cap & ACPI_DISP_VGA_CAP__ROM) ? " _ROM" : "", 772 (cap & ACPI_DISP_VGA_CAP__ROM) ? " _ROM" : "",
773 (cap & ACPI_DISP_VGA_CAP__GPD) ? " _GPD" : "", 773 (cap & ACPI_DISP_VGA_CAP__GPD) ? " _GPD" : "",
774 (cap & ACPI_DISP_VGA_CAP__SPD) ? " _SPD" : "", 774 (cap & ACPI_DISP_VGA_CAP__SPD) ? " _SPD" : "",
775 (cap & ACPI_DISP_VGA_CAP__VPO) ? " _VPO" : ""); 775 (cap & ACPI_DISP_VGA_CAP__VPO) ? " _VPO" : "");
776} 776}
777 777
778static uint16_t 778static uint16_t
779acpidisp_out_capabilities(const struct acpi_devnode *ad) 779acpidisp_out_capabilities(const struct acpi_devnode *ad)
780{ 780{
781 uint16_t cap; 781 uint16_t cap;
782 782
783 cap = 0; 783 cap = 0;
784 784
785 if (acpidisp_has_method(ad->ad_handle, "_BCL", ACPI_TYPE_PACKAGE)) 785 if (acpidisp_has_method(ad->ad_handle, "_BCL", ACPI_TYPE_PACKAGE))
786 cap |= ACPI_DISP_OUT_CAP__BCL; 786 cap |= ACPI_DISP_OUT_CAP__BCL;
787 787
788 if (acpidisp_has_method(ad->ad_handle, "_BCM", ACPI_TYPE_METHOD)) 788 if (acpidisp_has_method(ad->ad_handle, "_BCM", ACPI_TYPE_METHOD))
789 cap |= ACPI_DISP_OUT_CAP__BCM; 789 cap |= ACPI_DISP_OUT_CAP__BCM;
790 790
791 if (acpidisp_has_method(ad->ad_handle, "_BQC", ACPI_TYPE_INTEGER)) 791 if (acpidisp_has_method(ad->ad_handle, "_BQC", ACPI_TYPE_INTEGER))
792 cap |= ACPI_DISP_OUT_CAP__BQC; 792 cap |= ACPI_DISP_OUT_CAP__BQC;
793 793
794 if (acpidisp_has_method(ad->ad_handle, "_DDC", ACPI_TYPE_METHOD)) 794 if (acpidisp_has_method(ad->ad_handle, "_DDC", ACPI_TYPE_METHOD))
795 cap |= ACPI_DISP_OUT_CAP__DDC; 795 cap |= ACPI_DISP_OUT_CAP__DDC;
796 796
797 if (acpidisp_has_method(ad->ad_handle, "_DCS", ACPI_TYPE_INTEGER)) 797 if (acpidisp_has_method(ad->ad_handle, "_DCS", ACPI_TYPE_INTEGER))
798 cap |= ACPI_DISP_OUT_CAP__DCS; 798 cap |= ACPI_DISP_OUT_CAP__DCS;
799 799
800 if (acpidisp_has_method(ad->ad_handle, "_DGS", ACPI_TYPE_INTEGER)) 800 if (acpidisp_has_method(ad->ad_handle, "_DGS", ACPI_TYPE_INTEGER))
801 cap |= ACPI_DISP_OUT_CAP__DGS; 801 cap |= ACPI_DISP_OUT_CAP__DGS;
802 802
803 if (acpidisp_has_method(ad->ad_handle, "_DSS", ACPI_TYPE_METHOD)) 803 if (acpidisp_has_method(ad->ad_handle, "_DSS", ACPI_TYPE_METHOD))
804 cap |= ACPI_DISP_OUT_CAP__DSS; 804 cap |= ACPI_DISP_OUT_CAP__DSS;
805 805
806 return cap; 806 return cap;
807} 807}
808 808
809static void 809static void
810acpidisp_out_print_capabilities(device_t self, uint16_t cap) 810acpidisp_out_print_capabilities(device_t self, uint16_t cap)
811{ 811{
812 aprint_debug_dev(self, "capabilities:%s%s%s%s%s%s%s\n", 812 aprint_debug_dev(self, "capabilities:%s%s%s%s%s%s%s\n",
813 (cap & ACPI_DISP_OUT_CAP__BCL) ? " _BCL" : "", 813 (cap & ACPI_DISP_OUT_CAP__BCL) ? " _BCL" : "",
814 (cap & ACPI_DISP_OUT_CAP__BCM) ? " _BCM" : "", 814 (cap & ACPI_DISP_OUT_CAP__BCM) ? " _BCM" : "",
815 (cap & ACPI_DISP_OUT_CAP__BQC) ? " _BQC" : "", 815 (cap & ACPI_DISP_OUT_CAP__BQC) ? " _BQC" : "",
816 (cap & ACPI_DISP_OUT_CAP__DDC) ? " _DDC" : "", 816 (cap & ACPI_DISP_OUT_CAP__DDC) ? " _DDC" : "",
817 (cap & ACPI_DISP_OUT_CAP__DCS) ? " _DCS" : "", 817 (cap & ACPI_DISP_OUT_CAP__DCS) ? " _DCS" : "",
818 (cap & ACPI_DISP_OUT_CAP__DGS) ? " _DGS" : "", 818 (cap & ACPI_DISP_OUT_CAP__DGS) ? " _DGS" : "",
819 (cap & ACPI_DISP_OUT_CAP__DSS) ? " _DSS" : ""); 819 (cap & ACPI_DISP_OUT_CAP__DSS) ? " _DSS" : "");
820} 820}
821 821
822/* 822/*
823 * ACPI notify handlers. 823 * ACPI notify handlers.
824 */ 824 */
825 825
826static void 826static void
827acpidisp_vga_notify_handler(ACPI_HANDLE handle, uint32_t notify, 827acpidisp_vga_notify_handler(ACPI_HANDLE handle, uint32_t notify,
828 void *context) 828 void *context)
829{ 829{
830 struct acpidisp_vga_softc *asc = device_private(context); 830 struct acpidisp_vga_softc *asc = device_private(context);
831 ACPI_OSD_EXEC_CALLBACK callback; 831 ACPI_OSD_EXEC_CALLBACK callback;
832 832
833 callback = NULL; 833 callback = NULL;
834 834
835 switch (notify) { 835 switch (notify) {
836 case ACPI_NOTIFY_CycleOutputDevice: 836 case ACPI_NOTIFY_CycleOutputDevice:
837 callback = acpidisp_vga_cycle_output_device_callback; 837 callback = acpidisp_vga_cycle_output_device_callback;
838 break; 838 break;
839 case ACPI_NOTIFY_OutputDeviceStatusChange: 839 case ACPI_NOTIFY_OutputDeviceStatusChange:
840 callback = acpidisp_vga_output_device_change_callback; 840 callback = acpidisp_vga_output_device_change_callback;
841 break; 841 break;
842 case ACPI_NOTIFY_CycleDisplayOutputHotkeyPressed: 842 case ACPI_NOTIFY_CycleDisplayOutputHotkeyPressed:
843 case ACPI_NOTIFY_NextDisplayOutputHotkeyPressed: 843 case ACPI_NOTIFY_NextDisplayOutputHotkeyPressed:
844 case ACPI_NOTIFY_PreviousDisplayOutputHotkeyPressed: 844 case ACPI_NOTIFY_PreviousDisplayOutputHotkeyPressed:
845 aprint_debug_dev(asc->sc_dev, 845 aprint_debug_dev(asc->sc_dev,
846 "unhandled notify: 0x%"PRIx32"\n", notify); 846 "unhandled notify: 0x%"PRIx32"\n", notify);
847 return; 847 return;
848 default: 848 default:
849 aprint_error_dev(asc->sc_dev, 849 aprint_error_dev(asc->sc_dev,
850 "unknown notify: 0x%"PRIx32"\n", notify); 850 "unknown notify: 0x%"PRIx32"\n", notify);
851 return; 851 return;
852 } 852 }
853 853
854 KASSERT(callback != NULL); 854 KASSERT(callback != NULL);
855 (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, callback, asc); 855 (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, callback, asc);
856} 856}
857 857
858static void 858static void
859acpidisp_out_notify_handler(ACPI_HANDLE handle, uint32_t notify, 859acpidisp_out_notify_handler(ACPI_HANDLE handle, uint32_t notify,
860 void *context) 860 void *context)
861{ 861{
862 struct acpidisp_out_softc *osc = device_private(context); 862 struct acpidisp_out_softc *osc = device_private(context);
863 ACPI_OSD_EXEC_CALLBACK callback; 863 ACPI_OSD_EXEC_CALLBACK callback;
864 864
865 callback = NULL; 865 callback = NULL;
866 866
867 switch (notify) { 867 switch (notify) {
868 case ACPI_NOTIFY_IncreaseBrightness: 868 case ACPI_NOTIFY_IncreaseBrightness:
869 callback = acpidisp_out_increase_brightness_callback; 869 callback = acpidisp_out_increase_brightness_callback;
870 break; 870 break;
871 case ACPI_NOTIFY_DecreaseBrightness: 871 case ACPI_NOTIFY_DecreaseBrightness:
872 callback = acpidisp_out_decrease_brightness_callback; 872 callback = acpidisp_out_decrease_brightness_callback;
873 break; 873 break;
874 case ACPI_NOTIFY_CycleBrightness: 874 case ACPI_NOTIFY_CycleBrightness:
875 callback = acpidisp_out_cycle_brightness_callback; 875 callback = acpidisp_out_cycle_brightness_callback;
876 break; 876 break;
877 case ACPI_NOTIFY_ZeroBrightness: 877 case ACPI_NOTIFY_ZeroBrightness:
878 callback = acpidisp_out_zero_brightness_callback; 878 callback = acpidisp_out_zero_brightness_callback;
879 break; 879 break;
880 case ACPI_NOTIFY_DisplayDeviceOff: 880 case ACPI_NOTIFY_DisplayDeviceOff:
881 aprint_debug_dev(osc->sc_dev, 881 aprint_debug_dev(osc->sc_dev,
882 "unhandled notify: 0x%"PRIx32"\n", notify); 882 "unhandled notify: 0x%"PRIx32"\n", notify);
883 return; 883 return;
884 default: 884 default:
885 aprint_error_dev(osc->sc_dev, 885 aprint_error_dev(osc->sc_dev,
886 "unknown notify: 0x%"PRIx32"\n", notify); 886 "unknown notify: 0x%"PRIx32"\n", notify);
887 return; 887 return;
888 } 888 }
889 889
890 KASSERT(callback != NULL); 890 KASSERT(callback != NULL);
891 (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, callback, osc); 891 (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, callback, osc);
892} 892}
893 893
894/* 894/*
895 * ACPI notify callbacks. 895 * ACPI notify callbacks.
896 * 896 *
897 * Exclusive access to the sc_odinfo field of struct acpidisp_vga_softc is 897 * Exclusive access to the sc_odinfo field of struct acpidisp_vga_softc is
898 * guaranteed since: 898 * guaranteed since:
899 * 899 *
900 * (a) this field is only used in ACPI display notify callbacks, 900 * (a) this field is only used in ACPI display notify callbacks,
901 * (b) ACPI display notify callbacks are scheduled with AcpiOsExecute, 901 * (b) ACPI display notify callbacks are scheduled with AcpiOsExecute,
902 * (c) callbacks scheduled with AcpiOsExecute are executed sequentially. 902 * (c) callbacks scheduled with AcpiOsExecute are executed sequentially.
903 */ 903 */
904 904
905static void 905static void
906acpidisp_vga_cycle_output_device_callback(void *arg) 906acpidisp_vga_cycle_output_device_callback(void *arg)
907{ 907{
908 struct acpidisp_vga_softc *asc = arg; 908 struct acpidisp_vga_softc *asc = arg;
909 struct acpidisp_odinfo *oi = asc->sc_odinfo; 909 struct acpidisp_odinfo *oi = asc->sc_odinfo;
910 struct acpidisp_outdev *od; 910 struct acpidisp_outdev *od;
911 struct acpidisp_out_softc *osc, *last_osc; 911 struct acpidisp_out_softc *osc, *last_osc;
912 acpidisp_od_state_t state, last_state; 912 acpidisp_od_state_t state, last_state;
913 acpidisp_od_status_t status; 913 acpidisp_od_status_t status;
 914 acpidisp_bios_policy_t lock_policy;
914 uint32_t i; 915 uint32_t i;
915 916
916 if (oi == NULL) 917 if (oi == NULL)
917 return; 918 return;
918 919
919 /* Mutual exclusion with callbacks of connected output devices. */ 920 /* Mutual exclusion with callbacks of connected output devices. */
920 mutex_enter(&asc->sc_mtx); 921 mutex_enter(&asc->sc_mtx);
921 922
 923 /* Lock the _DGS values. */
 924 lock_policy = asc->sc_policy;
 925 lock_policy.fmt.output = ACPI_DISP_POLICY_OUTPUT_LOCKED;
 926 (void)acpidisp_set_policy(asc, lock_policy.raw);
 927
922 last_osc = NULL; 928 last_osc = NULL;
923 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) { 929 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) {
924 if (od->od_device == NULL) 930 if (od->od_device == NULL)
925 continue; 931 continue;
926 osc = device_private(od->od_device); 932 osc = device_private(od->od_device);
927 933
928 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DSS)) 934 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DSS))
929 continue; 935 continue;
930 if (acpidisp_get_state(osc, &state.raw)) 936 if (acpidisp_get_state(osc, &state.raw))
931 continue; 937 continue;
932 938
933 if (acpidisp_get_status(osc, &status.raw)) { 939 if (acpidisp_get_status(osc, &status.raw)) {
934 state.fmt.no_switch = 0; 940 state.fmt.no_switch = 0;
935 } else { 941 } else {
936 state.fmt.active &= status.fmt.ready; 942 state.fmt.active &= status.fmt.ready;
937 943
938 if (state.fmt.active == status.fmt.activated) 944 if (state.fmt.active == status.fmt.activated)
939 state.fmt.no_switch = 1; 945 state.fmt.no_switch = 1;
940 else 946 else
941 state.fmt.no_switch = 0; 947 state.fmt.no_switch = 0;
942 } 948 }
943 949
944 state.fmt.commit = 0; 950 state.fmt.commit = 0;
945 951
946 if (last_osc != NULL) 952 if (last_osc != NULL)
947 (void)acpidisp_set_state(last_osc, last_state.raw); 953 (void)acpidisp_set_state(last_osc, last_state.raw);
948 954
949 last_osc = osc; 955 last_osc = osc;
950 last_state = state; 956 last_state = state;
951 } 957 }
952 958
953 if (last_osc != NULL) { 959 if (last_osc != NULL) {
954 last_state.fmt.commit = 1; 960 last_state.fmt.commit = 1;
955 (void)acpidisp_set_state(last_osc, last_state.raw); 961 (void)acpidisp_set_state(last_osc, last_state.raw);
956 } 962 }
957 963
 964 /* Restore the original BIOS policy. */
 965 (void)acpidisp_set_policy(asc, asc->sc_policy.raw);
 966
958 mutex_exit(&asc->sc_mtx); 967 mutex_exit(&asc->sc_mtx);
959} 968}
960 969
961static void 970static void
962acpidisp_vga_output_device_change_callback(void *arg) 971acpidisp_vga_output_device_change_callback(void *arg)
963{ 972{
964 struct acpidisp_vga_softc *asc = arg; 973 struct acpidisp_vga_softc *asc = arg;
965 struct acpidisp_odinfo *oi = asc->sc_odinfo; 974 struct acpidisp_odinfo *oi = asc->sc_odinfo;
966 bool switch_outputs; 975 bool switch_outputs;
967 976
968 if (oi != NULL) { 977 if (oi != NULL) {
969 kmem_free(oi->oi_dev, 978 kmem_free(oi->oi_dev,
970 oi->oi_dev_count * sizeof(*oi->oi_dev)); 979 oi->oi_dev_count * sizeof(*oi->oi_dev));
971 kmem_free(oi, sizeof(*oi)); 980 kmem_free(oi, sizeof(*oi));
972 } 981 }
973 982
974 asc->sc_odinfo = acpidisp_init_odinfo(asc); 983 asc->sc_odinfo = acpidisp_init_odinfo(asc);
975 if (asc->sc_odinfo != NULL) { 984 if (asc->sc_odinfo != NULL) {
976 acpidisp_vga_bind_outdevs(asc); 985 acpidisp_vga_bind_outdevs(asc);
977 acpidisp_print_odinfo(asc->sc_dev, asc->sc_odinfo); 986 acpidisp_print_odinfo(asc->sc_dev, asc->sc_odinfo);
978 } 987 }
979 988
980 /* Perform display output switch if needed. */ 989 /* Perform display output switch if needed. */
981 mutex_enter(&asc->sc_mtx); 990 mutex_enter(&asc->sc_mtx);
982 switch_outputs = 991 switch_outputs =
983 (asc->sc_policy.fmt.output == ACPI_DISP_POLICY_OUTPUT_NORMAL); 992 (asc->sc_policy.fmt.output == ACPI_DISP_POLICY_OUTPUT_NORMAL);
984 mutex_exit(&asc->sc_mtx); 993 mutex_exit(&asc->sc_mtx);
985 if (switch_outputs) 994 if (switch_outputs)
986 acpidisp_vga_cycle_output_device_callback(arg); 995 acpidisp_vga_cycle_output_device_callback(arg);
987} 996}
988 997
989static void 998static void
990acpidisp_out_increase_brightness_callback(void *arg) 999acpidisp_out_increase_brightness_callback(void *arg)
991{ 1000{
992 struct acpidisp_out_softc *osc = arg; 1001 struct acpidisp_out_softc *osc = arg;
993 struct acpidisp_brctl *bc = osc->sc_brctl; 1002 struct acpidisp_brctl *bc = osc->sc_brctl;
994 uint8_t lo, up; 1003 uint8_t lo, up;
995 1004
996 if (bc == NULL) { 1005 if (bc == NULL) {
997 /* Fallback to pmf(9). */ 1006 /* Fallback to pmf(9). */
998 pmf_event_inject(NULL, PMFE_DISPLAY_BRIGHTNESS_UP); 1007 pmf_event_inject(NULL, PMFE_DISPLAY_BRIGHTNESS_UP);
999 return; 1008 return;
1000 } 1009 }
1001 1010
1002 mutex_enter(osc->sc_mtx); 1011 mutex_enter(osc->sc_mtx);
1003 1012
1004 (void)acpidisp_get_brightness(osc, &bc->bc_current); 1013 (void)acpidisp_get_brightness(osc, &bc->bc_current);
1005 1014
1006 acpidisp_array_search(bc->bc_level, bc->bc_level_count, 1015 acpidisp_array_search(bc->bc_level, bc->bc_level_count,
1007 bc->bc_current + ACPI_DISP_BRCTL_STEP, &lo, &up); 1016 bc->bc_current + ACPI_DISP_BRCTL_STEP, &lo, &up);
1008 1017
1009 bc->bc_current = up; 1018 bc->bc_current = up;
1010 (void)acpidisp_set_brightness(osc, bc->bc_current); 1019 (void)acpidisp_set_brightness(osc, bc->bc_current);
1011 1020
1012 mutex_exit(osc->sc_mtx); 1021 mutex_exit(osc->sc_mtx);
1013} 1022}
1014 1023
1015static void 1024static void
1016acpidisp_out_decrease_brightness_callback(void *arg) 1025acpidisp_out_decrease_brightness_callback(void *arg)
1017{ 1026{
1018 struct acpidisp_out_softc *osc = arg; 1027 struct acpidisp_out_softc *osc = arg;
1019 struct acpidisp_brctl *bc = osc->sc_brctl; 1028 struct acpidisp_brctl *bc = osc->sc_brctl;
1020 uint8_t lo, up; 1029 uint8_t lo, up;
1021 1030
1022 if (bc == NULL) { 1031 if (bc == NULL) {
1023 /* Fallback to pmf(9). */ 1032 /* Fallback to pmf(9). */
1024 pmf_event_inject(NULL, PMFE_DISPLAY_BRIGHTNESS_DOWN); 1033 pmf_event_inject(NULL, PMFE_DISPLAY_BRIGHTNESS_DOWN);
1025 return; 1034 return;
1026 } 1035 }
1027 1036
1028 mutex_enter(osc->sc_mtx); 1037 mutex_enter(osc->sc_mtx);
1029 1038
1030 (void)acpidisp_get_brightness(osc, &bc->bc_current); 1039 (void)acpidisp_get_brightness(osc, &bc->bc_current);
1031 1040
1032 acpidisp_array_search(bc->bc_level, bc->bc_level_count, 1041 acpidisp_array_search(bc->bc_level, bc->bc_level_count,
1033 bc->bc_current - ACPI_DISP_BRCTL_STEP, &lo, &up); 1042 bc->bc_current - ACPI_DISP_BRCTL_STEP, &lo, &up);
1034 1043
1035 bc->bc_current = lo; 1044 bc->bc_current = lo;
1036 (void)acpidisp_set_brightness(osc, bc->bc_current); 1045 (void)acpidisp_set_brightness(osc, bc->bc_current);
1037 1046
1038 mutex_exit(osc->sc_mtx); 1047 mutex_exit(osc->sc_mtx);
1039} 1048}
1040 1049
1041static void 1050static void
1042acpidisp_out_cycle_brightness_callback(void *arg) 1051acpidisp_out_cycle_brightness_callback(void *arg)
1043{ 1052{
1044 struct acpidisp_out_softc *osc = arg; 1053 struct acpidisp_out_softc *osc = arg;
1045 struct acpidisp_brctl *bc = osc->sc_brctl; 1054 struct acpidisp_brctl *bc = osc->sc_brctl;
1046 uint8_t lo, up; 1055 uint8_t lo, up;
1047 1056
1048 if (bc == NULL) { 1057 if (bc == NULL) {
1049 /* No fallback. */ 1058 /* No fallback. */
1050 return; 1059 return;
1051 } 1060 }
1052 1061
1053 mutex_enter(osc->sc_mtx); 1062 mutex_enter(osc->sc_mtx);
1054 1063
1055 (void)acpidisp_get_brightness(osc, &bc->bc_current); 1064 (void)acpidisp_get_brightness(osc, &bc->bc_current);
1056 1065
1057 if (bc->bc_current >= bc->bc_level[bc->bc_level_count - 1]) { 1066 if (bc->bc_current >= bc->bc_level[bc->bc_level_count - 1]) {
1058 bc->bc_current = bc->bc_level[0]; 1067 bc->bc_current = bc->bc_level[0];
1059 } else { 1068 } else {
1060 acpidisp_array_search(bc->bc_level, bc->bc_level_count, 1069 acpidisp_array_search(bc->bc_level, bc->bc_level_count,
1061 bc->bc_current + 1, &lo, &up); 1070 bc->bc_current + 1, &lo, &up);
1062 bc->bc_current = up; 1071 bc->bc_current = up;
1063 } 1072 }
1064 1073
1065 (void)acpidisp_set_brightness(osc, bc->bc_current); 1074 (void)acpidisp_set_brightness(osc, bc->bc_current);
1066 1075
1067 mutex_exit(osc->sc_mtx); 1076 mutex_exit(osc->sc_mtx);
1068} 1077}
1069 1078
1070static void 1079static void
1071acpidisp_out_zero_brightness_callback(void *arg) 1080acpidisp_out_zero_brightness_callback(void *arg)
1072{ 1081{
1073 struct acpidisp_out_softc *osc = arg; 1082 struct acpidisp_out_softc *osc = arg;
1074 struct acpidisp_brctl *bc = osc->sc_brctl; 1083 struct acpidisp_brctl *bc = osc->sc_brctl;
1075 1084
1076 if (bc == NULL) { 1085 if (bc == NULL) {
1077 /* Fallback to pmf(9). */ 1086 /* Fallback to pmf(9). */
1078 /* XXX Is this the intended meaning of PMFE_DISPLAY_REDUCED? */ 1087 /* XXX Is this the intended meaning of PMFE_DISPLAY_REDUCED? */
1079 pmf_event_inject(NULL, PMFE_DISPLAY_REDUCED); 1088 pmf_event_inject(NULL, PMFE_DISPLAY_REDUCED);
1080 return; 1089 return;
1081 } 1090 }
1082 1091
1083 mutex_enter(osc->sc_mtx); 1092 mutex_enter(osc->sc_mtx);
1084 1093
1085 bc->bc_current = bc->bc_level[0]; 1094 bc->bc_current = bc->bc_level[0];
1086 (void)acpidisp_set_brightness(osc, bc->bc_current); 1095 (void)acpidisp_set_brightness(osc, bc->bc_current);
1087 1096
1088 mutex_exit(osc->sc_mtx); 1097 mutex_exit(osc->sc_mtx);
1089} 1098}
1090 1099
1091/* 1100/*
1092 * Sysctl setup. 1101 * Sysctl setup.
1093 */ 1102 */
1094 1103
1095static void 1104static void
1096acpidisp_vga_sysctl_setup(struct acpidisp_vga_softc *asc) 1105acpidisp_vga_sysctl_setup(struct acpidisp_vga_softc *asc)
1097{ 1106{
1098 const struct sysctlnode *rnode; 1107 const struct sysctlnode *rnode;
1099 1108
1100 if (asc->sc_caps & ACPI_DISP_VGA_CAP__DOS) { 1109 if (asc->sc_caps & ACPI_DISP_VGA_CAP__DOS) {
1101 if ((sysctl_createv(&asc->sc_log, 0, NULL, &rnode, 1110 if ((sysctl_createv(&asc->sc_log, 0, NULL, &rnode,
1102 0, CTLTYPE_NODE, "hw", NULL, 1111 0, CTLTYPE_NODE, "hw", NULL,
1103 NULL, 0, NULL, 0, 1112 NULL, 0, NULL, 0,
1104 CTL_HW, CTL_EOL)) != 0) 1113 CTL_HW, CTL_EOL)) != 0)
1105 goto fail; 1114 goto fail;
1106 1115
1107 if ((sysctl_createv(&asc->sc_log, 0, &rnode, &rnode, 1116 if ((sysctl_createv(&asc->sc_log, 0, &rnode, &rnode,
1108 0, CTLTYPE_NODE, "acpi", NULL, 1117 0, CTLTYPE_NODE, "acpi", NULL,
1109 NULL, 0, NULL, 0, 1118 NULL, 0, NULL, 0,
1110 CTL_CREATE, CTL_EOL)) != 0) 1119 CTL_CREATE, CTL_EOL)) != 0)
1111 goto fail; 1120 goto fail;
1112 1121
1113 if ((sysctl_createv(&asc->sc_log, 0, &rnode, &rnode, 1122 if ((sysctl_createv(&asc->sc_log, 0, &rnode, &rnode,
1114 0, CTLTYPE_NODE, device_xname(asc->sc_dev), 1123 0, CTLTYPE_NODE, device_xname(asc->sc_dev),
1115 SYSCTL_DESCR("ACPI display adapter controls"), 1124 SYSCTL_DESCR("ACPI display adapter controls"),
1116 NULL, 0, NULL, 0, 1125 NULL, 0, NULL, 0,
1117 CTL_CREATE, CTL_EOL)) != 0) 1126 CTL_CREATE, CTL_EOL)) != 0)
1118 goto fail; 1127 goto fail;
1119 1128
1120#ifdef ACPI_DEBUG 1129#ifdef ACPI_DEBUG
1121 (void)sysctl_createv(&asc->sc_log, 0, &rnode, NULL, 1130 (void)sysctl_createv(&asc->sc_log, 0, &rnode, NULL,
1122 CTLFLAG_READWRITE | CTLFLAG_HEX, CTLTYPE_INT, "bios_policy", 1131 CTLFLAG_READWRITE | CTLFLAG_HEX, CTLTYPE_INT, "bios_policy",
1123 SYSCTL_DESCR("Current BIOS switch policies (debug)"), 1132 SYSCTL_DESCR("Current BIOS switch policies (debug)"),
1124 acpidisp_vga_sysctl_policy, 0, asc, 0, 1133 acpidisp_vga_sysctl_policy, 0, asc, 0,
1125 CTL_CREATE, CTL_EOL); 1134 CTL_CREATE, CTL_EOL);
1126#endif 1135#endif
1127 1136
1128 (void)sysctl_createv(&asc->sc_log, 0, &rnode, NULL, 1137 (void)sysctl_createv(&asc->sc_log, 0, &rnode, NULL,
1129 CTLFLAG_READWRITE, CTLTYPE_BOOL, "bios_switch", 1138 CTLFLAG_READWRITE, CTLTYPE_BOOL, "bios_switch",
1130 SYSCTL_DESCR("Current BIOS output switching policy"), 1139 SYSCTL_DESCR("Current BIOS output switching policy"),
1131 acpidisp_vga_sysctl_policy_output, 0, asc, 0, 1140 acpidisp_vga_sysctl_policy_output, 0, asc, 0,
1132 CTL_CREATE, CTL_EOL); 1141 CTL_CREATE, CTL_EOL);
1133 } 1142 }
1134 1143
1135 return; 1144 return;
1136 1145
1137 fail: 1146 fail:
1138 aprint_error_dev(asc->sc_dev, "couldn't add sysctl nodes\n"); 1147 aprint_error_dev(asc->sc_dev, "couldn't add sysctl nodes\n");
1139} 1148}
1140 1149
1141static void 1150static void
1142acpidisp_out_sysctl_setup(struct acpidisp_out_softc *osc) 1151acpidisp_out_sysctl_setup(struct acpidisp_out_softc *osc)
1143{ 1152{
1144 const struct sysctlnode *rnode; 1153 const struct sysctlnode *rnode;
1145 1154
1146#ifdef ACPI_DISP_SWITCH_SYSCTLS 1155#ifdef ACPI_DISP_SWITCH_SYSCTLS
1147 if ((osc->sc_brctl != NULL) || 1156 if ((osc->sc_brctl != NULL) ||
1148 (osc->sc_caps & ACPI_DISP_OUT_CAP__DCS) || 1157 (osc->sc_caps & ACPI_DISP_OUT_CAP__DCS) ||
1149 (osc->sc_caps & ACPI_DISP_OUT_CAP__DGS)) { 1158 (osc->sc_caps & ACPI_DISP_OUT_CAP__DGS)) {
1150#else 1159#else
1151 if (osc->sc_brctl != NULL) { 1160 if (osc->sc_brctl != NULL) {
1152#endif 1161#endif
1153 if ((sysctl_createv(&osc->sc_log, 0, NULL, &rnode, 1162 if ((sysctl_createv(&osc->sc_log, 0, NULL, &rnode,
1154 0, CTLTYPE_NODE, "hw", NULL, 1163 0, CTLTYPE_NODE, "hw", NULL,
1155 NULL, 0, NULL, 0, 1164 NULL, 0, NULL, 0,
1156 CTL_HW, CTL_EOL)) != 0) 1165 CTL_HW, CTL_EOL)) != 0)
1157 goto fail; 1166 goto fail;
1158 1167
1159 if ((sysctl_createv(&osc->sc_log, 0, &rnode, &rnode, 1168 if ((sysctl_createv(&osc->sc_log, 0, &rnode, &rnode,
1160 0, CTLTYPE_NODE, "acpi", NULL, 1169 0, CTLTYPE_NODE, "acpi", NULL,
1161 NULL, 0, NULL, 0, 1170 NULL, 0, NULL, 0,
1162 CTL_CREATE, CTL_EOL)) != 0) 1171 CTL_CREATE, CTL_EOL)) != 0)
1163 goto fail; 1172 goto fail;
1164 1173
1165 if ((sysctl_createv(&osc->sc_log, 0, &rnode, &rnode, 1174 if ((sysctl_createv(&osc->sc_log, 0, &rnode, &rnode,
1166 0, CTLTYPE_NODE, device_xname(osc->sc_dev), 1175 0, CTLTYPE_NODE, device_xname(osc->sc_dev),
1167 SYSCTL_DESCR("ACPI display output device controls"), 1176 SYSCTL_DESCR("ACPI display output device controls"),
1168 NULL, 0, NULL, 0, 1177 NULL, 0, NULL, 0,
1169 CTL_CREATE, CTL_EOL)) != 0) 1178 CTL_CREATE, CTL_EOL)) != 0)
1170 goto fail; 1179 goto fail;
1171 } 1180 }
1172 1181
1173 if (osc->sc_brctl != NULL) { 1182 if (osc->sc_brctl != NULL) {
1174 (void)sysctl_createv(&osc->sc_log, 0, &rnode, NULL, 1183 (void)sysctl_createv(&osc->sc_log, 0, &rnode, NULL,
1175 CTLFLAG_READWRITE, CTLTYPE_INT, "brightness", 1184 CTLFLAG_READWRITE, CTLTYPE_INT, "brightness",
1176 SYSCTL_DESCR("Current brightness level"), 1185 SYSCTL_DESCR("Current brightness level"),
1177 acpidisp_out_sysctl_brightness, 0, osc, 0, 1186 acpidisp_out_sysctl_brightness, 0, osc, 0,
1178 CTL_CREATE, CTL_EOL); 1187 CTL_CREATE, CTL_EOL);
1179 } 1188 }
1180 1189
1181#ifdef ACPI_DISP_SWITCH_SYSCTLS 1190#ifdef ACPI_DISP_SWITCH_SYSCTLS
1182 if (osc->sc_caps & ACPI_DISP_OUT_CAP__DCS) { 1191 if (osc->sc_caps & ACPI_DISP_OUT_CAP__DCS) {
1183 (void)sysctl_createv(&osc->sc_log, 0, &rnode, NULL, 1192 (void)sysctl_createv(&osc->sc_log, 0, &rnode, NULL,
1184 CTLFLAG_READONLY | CTLFLAG_HEX, CTLTYPE_INT, "status", 1193 CTLFLAG_READONLY | CTLFLAG_HEX, CTLTYPE_INT, "status",
1185 SYSCTL_DESCR("Current status"), 1194 SYSCTL_DESCR("Current status"),
1186 acpidisp_out_sysctl_status, 0, osc, 0, 1195 acpidisp_out_sysctl_status, 0, osc, 0,
1187 CTL_CREATE, CTL_EOL); 1196 CTL_CREATE, CTL_EOL);
1188 } 1197 }
1189 1198
1190 if (osc->sc_caps & ACPI_DISP_OUT_CAP__DGS) { 1199 if (osc->sc_caps & ACPI_DISP_OUT_CAP__DGS) {
1191 int access; 1200 int access;
1192 1201
1193 if (osc->sc_caps & ACPI_DISP_OUT_CAP__DSS) 1202 if (osc->sc_caps & ACPI_DISP_OUT_CAP__DSS)
1194 access = CTLFLAG_READWRITE; 1203 access = CTLFLAG_READWRITE;
1195 else 1204 else
1196 access = CTLFLAG_READONLY; 1205 access = CTLFLAG_READONLY;
1197 1206
1198 (void)sysctl_createv(&osc->sc_log, 0, &rnode, NULL, 1207 (void)sysctl_createv(&osc->sc_log, 0, &rnode, NULL,
1199 access | CTLFLAG_HEX, CTLTYPE_INT, "state", 1208 access | CTLFLAG_HEX, CTLTYPE_INT, "state",
1200 SYSCTL_DESCR("Next state (active or inactive)"), 1209 SYSCTL_DESCR("Next state (active or inactive)"),
1201 acpidisp_out_sysctl_state, 0, osc, 0, 1210 acpidisp_out_sysctl_state, 0, osc, 0,
1202 CTL_CREATE, CTL_EOL); 1211 CTL_CREATE, CTL_EOL);
1203 } 1212 }
1204#endif 1213#endif
1205 1214
1206 return; 1215 return;
1207 1216
1208 fail: 1217 fail:
1209 aprint_error_dev(osc->sc_dev, "couldn't add sysctl nodes\n"); 1218 aprint_error_dev(osc->sc_dev, "couldn't add sysctl nodes\n");
1210} 1219}
1211 1220
1212/* 1221/*
1213 * Sysctl callbacks. 1222 * Sysctl callbacks.
1214 */ 1223 */
1215 1224
1216#ifdef ACPI_DEBUG 1225#ifdef ACPI_DEBUG
1217static int 1226static int
1218acpidisp_vga_sysctl_policy(SYSCTLFN_ARGS) 1227acpidisp_vga_sysctl_policy(SYSCTLFN_ARGS)
1219{ 1228{
1220 struct sysctlnode node; 1229 struct sysctlnode node;
1221 struct acpidisp_vga_softc *asc; 1230 struct acpidisp_vga_softc *asc;
1222 uint32_t val; 1231 uint32_t val;
1223 int error; 1232 int error;
1224 1233
1225 node = *rnode; 1234 node = *rnode;
1226 asc = (struct acpidisp_vga_softc *)node.sysctl_data; 1235 asc = (struct acpidisp_vga_softc *)node.sysctl_data;
1227 1236
1228 mutex_enter(&asc->sc_mtx); 1237 mutex_enter(&asc->sc_mtx);
1229 val = (uint32_t)asc->sc_policy.raw; 1238 val = (uint32_t)asc->sc_policy.raw;
1230 mutex_exit(&asc->sc_mtx); 1239 mutex_exit(&asc->sc_mtx);
1231 1240
1232 node.sysctl_data = &val; 1241 node.sysctl_data = &val;
1233 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1242 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1234 if (error || newp == NULL) 1243 if (error || newp == NULL)
1235 return error; 1244 return error;
1236 1245
1237 if (val > 0x7) 1246 if (val > 0x7)
1238 return EINVAL; 1247 return EINVAL;
1239 1248
1240 mutex_enter(&asc->sc_mtx); 1249 mutex_enter(&asc->sc_mtx);
1241 asc->sc_policy.raw = (uint8_t)val; 1250 asc->sc_policy.raw = (uint8_t)val;
1242 error = acpidisp_set_policy(asc, asc->sc_policy.raw); 1251 error = acpidisp_set_policy(asc, asc->sc_policy.raw);
1243 mutex_exit(&asc->sc_mtx); 1252 mutex_exit(&asc->sc_mtx);
1244 1253
1245 return error; 1254 return error;
1246} 1255}
1247#endif 1256#endif
1248 1257
1249static int 1258static int
1250acpidisp_vga_sysctl_policy_output(SYSCTLFN_ARGS) 1259acpidisp_vga_sysctl_policy_output(SYSCTLFN_ARGS)
1251{ 1260{
1252 struct sysctlnode node; 1261 struct sysctlnode node;
1253 struct acpidisp_vga_softc *asc; 1262 struct acpidisp_vga_softc *asc;
1254 bool val; 1263 bool val;
1255 int error; 1264 int error;
1256 1265
1257 node = *rnode; 1266 node = *rnode;
1258 asc = (struct acpidisp_vga_softc *)node.sysctl_data; 1267 asc = (struct acpidisp_vga_softc *)node.sysctl_data;
1259 1268
1260 mutex_enter(&asc->sc_mtx); 1269 mutex_enter(&asc->sc_mtx);
1261 val = (asc->sc_policy.fmt.output == ACPI_DISP_POLICY_OUTPUT_AUTO); 1270 val = (asc->sc_policy.fmt.output == ACPI_DISP_POLICY_OUTPUT_AUTO);
1262 mutex_exit(&asc->sc_mtx); 1271 mutex_exit(&asc->sc_mtx);
1263 1272
1264 node.sysctl_data = &val; 1273 node.sysctl_data = &val;
1265 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1274 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1266 if (error || newp == NULL) 1275 if (error || newp == NULL)
1267 return error; 1276 return error;
1268 1277
1269 mutex_enter(&asc->sc_mtx); 1278 mutex_enter(&asc->sc_mtx);
1270 if (val) 1279 if (val)
1271 asc->sc_policy.fmt.output = ACPI_DISP_POLICY_OUTPUT_AUTO; 1280 asc->sc_policy.fmt.output = ACPI_DISP_POLICY_OUTPUT_AUTO;
1272 else 1281 else
1273 asc->sc_policy.fmt.output = ACPI_DISP_POLICY_OUTPUT_NORMAL; 1282 asc->sc_policy.fmt.output = ACPI_DISP_POLICY_OUTPUT_NORMAL;
1274 error = acpidisp_set_policy(asc, asc->sc_policy.raw); 1283 error = acpidisp_set_policy(asc, asc->sc_policy.raw);
1275 mutex_exit(&asc->sc_mtx); 1284 mutex_exit(&asc->sc_mtx);
1276 1285
1277 return error; 1286 return error;
1278} 1287}
1279 1288
1280#ifdef ACPI_DISP_SWITCH_SYSCTLS 1289#ifdef ACPI_DISP_SWITCH_SYSCTLS
1281static int 1290static int
1282acpidisp_out_sysctl_status(SYSCTLFN_ARGS) 1291acpidisp_out_sysctl_status(SYSCTLFN_ARGS)
1283{ 1292{
1284 struct sysctlnode node; 1293 struct sysctlnode node;
1285 struct acpidisp_out_softc *osc; 1294 struct acpidisp_out_softc *osc;
1286 uint32_t val; 1295 uint32_t val;
1287 int error; 1296 int error;
1288 1297
1289 node = *rnode; 1298 node = *rnode;
1290 osc = (struct acpidisp_out_softc *)node.sysctl_data; 1299 osc = (struct acpidisp_out_softc *)node.sysctl_data;
1291 1300
1292 mutex_enter(osc->sc_mtx); 1301 mutex_enter(osc->sc_mtx);
1293 error = acpidisp_get_status(osc, &val); 1302 error = acpidisp_get_status(osc, &val);
1294 mutex_exit(osc->sc_mtx); 1303 mutex_exit(osc->sc_mtx);
1295 1304
1296 if (error) 1305 if (error)
1297 return error; 1306 return error;
1298 1307
1299 node.sysctl_data = &val; 1308 node.sysctl_data = &val;
1300 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1309 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1301 if (error || newp == NULL) 1310 if (error || newp == NULL)
1302 return error; 1311 return error;
1303 1312
1304 return 0; 1313 return 0;
1305} 1314}
1306 1315
1307static int 1316static int
1308acpidisp_out_sysctl_state(SYSCTLFN_ARGS) 1317acpidisp_out_sysctl_state(SYSCTLFN_ARGS)
1309{ 1318{
1310 struct sysctlnode node; 1319 struct sysctlnode node;
1311 struct acpidisp_out_softc *osc; 1320 struct acpidisp_out_softc *osc;
1312 uint32_t val; 1321 uint32_t val;
1313 int error; 1322 int error;
1314 1323
1315 node = *rnode; 1324 node = *rnode;
1316 osc = (struct acpidisp_out_softc *)node.sysctl_data; 1325 osc = (struct acpidisp_out_softc *)node.sysctl_data;
1317 1326
1318 mutex_enter(osc->sc_mtx); 1327 mutex_enter(osc->sc_mtx);
1319 error = acpidisp_get_state(osc, &val); 1328 error = acpidisp_get_state(osc, &val);
1320 mutex_exit(osc->sc_mtx); 1329 mutex_exit(osc->sc_mtx);
1321 1330
1322 if (error) 1331 if (error)
1323 return error; 1332 return error;
1324 1333
1325 node.sysctl_data = &val; 1334 node.sysctl_data = &val;
1326 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1335 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1327 if (error || newp == NULL) 1336 if (error || newp == NULL)
1328 return error; 1337 return error;
1329 1338
1330 mutex_enter(osc->sc_mtx); 1339 mutex_enter(osc->sc_mtx);
1331 error = acpidisp_set_state(osc, val); 1340 error = acpidisp_set_state(osc, val);
1332 mutex_exit(osc->sc_mtx); 1341 mutex_exit(osc->sc_mtx);
1333 1342
1334 return error; 1343 return error;
1335} 1344}
1336#endif 1345#endif
1337 1346
1338static int 1347static int
1339acpidisp_out_sysctl_brightness(SYSCTLFN_ARGS) 1348acpidisp_out_sysctl_brightness(SYSCTLFN_ARGS)
1340{ 1349{
1341 struct sysctlnode node; 1350 struct sysctlnode node;
1342 struct acpidisp_out_softc *osc; 1351 struct acpidisp_out_softc *osc;
1343 struct acpidisp_brctl *bc; 1352 struct acpidisp_brctl *bc;
1344 int val, error; 1353 int val, error;
1345 uint8_t lo, up, level; 1354 uint8_t lo, up, level;
1346 1355
1347 node = *rnode; 1356 node = *rnode;
1348 osc = (struct acpidisp_out_softc *)node.sysctl_data; 1357 osc = (struct acpidisp_out_softc *)node.sysctl_data;
1349 bc = osc->sc_brctl; 1358 bc = osc->sc_brctl;
1350 1359
1351 KASSERT(bc != NULL); 1360 KASSERT(bc != NULL);
1352 1361
1353 mutex_enter(osc->sc_mtx); 1362 mutex_enter(osc->sc_mtx);
1354 (void)acpidisp_get_brightness(osc, &bc->bc_current); 1363 (void)acpidisp_get_brightness(osc, &bc->bc_current);
1355 val = (int)bc->bc_current; 1364 val = (int)bc->bc_current;
1356 mutex_exit(osc->sc_mtx); 1365 mutex_exit(osc->sc_mtx);
1357 1366
1358 node.sysctl_data = &val; 1367 node.sysctl_data = &val;
1359 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1368 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1360 if (error || newp == NULL) 1369 if (error || newp == NULL)
1361 return error; 1370 return error;
1362 1371
1363 acpidisp_array_search(bc->bc_level, bc->bc_level_count, val, &lo, &up); 1372 acpidisp_array_search(bc->bc_level, bc->bc_level_count, val, &lo, &up);
1364 if ((lo != up) && (val - lo) < (up - val)) 1373 if ((lo != up) && (val - lo) < (up - val))
1365 level = lo; 1374 level = lo;
1366 else 1375 else
1367 level = up; 1376 level = up;
1368 1377
1369 mutex_enter(osc->sc_mtx); 1378 mutex_enter(osc->sc_mtx);
1370 bc->bc_current = level; 1379 bc->bc_current = level;
1371 error = acpidisp_set_brightness(osc, bc->bc_current); 1380 error = acpidisp_set_brightness(osc, bc->bc_current);
1372 mutex_exit(osc->sc_mtx); 1381 mutex_exit(osc->sc_mtx);
1373 1382
1374 return error; 1383 return error;
1375} 1384}
1376 1385
1377/* 1386/*
1378 * Initialization of acpidisp_odinfo (_DOD) and acpidisp_brctl (_BCL). 1387 * Initialization of acpidisp_odinfo (_DOD) and acpidisp_brctl (_BCL).
1379 */ 1388 */
1380 1389
1381/* 1390/*
1382 * Regarding _DOD (ACPI 4.0a, Sec. B.4.2): 1391 * Regarding _DOD (ACPI 4.0a, Sec. B.4.2):
1383 * 1392 *
1384 * "The _DOD method returns a list of devices attached to the graphics adapter, 1393 * "The _DOD method returns a list of devices attached to the graphics adapter,
1385 * along with device-specific configuration information." 1394 * along with device-specific configuration information."
1386 * 1395 *
1387 * "Every child device enumerated in the ACPI namespace under the graphics 1396 * "Every child device enumerated in the ACPI namespace under the graphics
1388 * adapter must be specified in this list of devices. Each display device 1397 * adapter must be specified in this list of devices. Each display device
1389 * must have its own ID, which is unique with respect to any other attachable 1398 * must have its own ID, which is unique with respect to any other attachable
1390 * devices enumerated." 1399 * devices enumerated."
1391 * 1400 *
1392 * "Return value: a package containing a variable-length list of integers, 1401 * "Return value: a package containing a variable-length list of integers,
1393 * each of which contains the 32-bit device attribute of a child device." 1402 * each of which contains the 32-bit device attribute of a child device."
1394 */ 1403 */
1395 1404
1396static struct acpidisp_odinfo * 1405static struct acpidisp_odinfo *
1397acpidisp_init_odinfo(const struct acpidisp_vga_softc *asc) 1406acpidisp_init_odinfo(const struct acpidisp_vga_softc *asc)
1398{ 1407{
1399 ACPI_HANDLE hdl = asc->sc_node->ad_handle; 1408 ACPI_HANDLE hdl = asc->sc_node->ad_handle;
1400 ACPI_STATUS rv; 1409 ACPI_STATUS rv;
1401 ACPI_OBJECT *pkg; 1410 ACPI_OBJECT *pkg;
1402 struct acpidisp_odinfo *oi; 1411 struct acpidisp_odinfo *oi;
1403 struct acpidisp_outdev *devp; 1412 struct acpidisp_outdev *devp;
1404 uint32_t count, i; 1413 uint32_t count, i;
1405 1414
1406 if (!(asc->sc_caps & ACPI_DISP_VGA_CAP__DOD)) 1415 if (!(asc->sc_caps & ACPI_DISP_VGA_CAP__DOD))
1407 return NULL; 1416 return NULL;
1408 1417
1409 oi = NULL; 1418 oi = NULL;
1410 1419
1411 rv = acpidisp_eval_package(hdl, "_DOD", &pkg, 1); 1420 rv = acpidisp_eval_package(hdl, "_DOD", &pkg, 1);
1412 if (ACPI_FAILURE(rv)) 1421 if (ACPI_FAILURE(rv))
1413 goto fail; 1422 goto fail;
1414 1423
1415 /* 1424 /*
1416 * Allocate and fill the struct acpidisp_odinfo to be returned. 1425 * Allocate and fill the struct acpidisp_odinfo to be returned.
1417 */ 1426 */
1418 oi = kmem_zalloc(sizeof(*oi), KM_SLEEP); 1427 oi = kmem_zalloc(sizeof(*oi), KM_SLEEP);
1419 if (oi == NULL) { 1428 if (oi == NULL) {
1420 rv = AE_NO_MEMORY; 1429 rv = AE_NO_MEMORY;
1421 goto fail; 1430 goto fail;
1422 } 1431 }
1423 1432
1424 oi->oi_dev_count = pkg->Package.Count; 1433 oi->oi_dev_count = pkg->Package.Count;
1425 1434
1426 oi->oi_dev = kmem_zalloc(oi->oi_dev_count * sizeof(*oi->oi_dev), 1435 oi->oi_dev = kmem_zalloc(oi->oi_dev_count * sizeof(*oi->oi_dev),
1427 KM_SLEEP); 1436 KM_SLEEP);
1428 if (oi->oi_dev == NULL) { 1437 if (oi->oi_dev == NULL) {
1429 rv = AE_NO_MEMORY; 1438 rv = AE_NO_MEMORY;
1430 goto fail; 1439 goto fail;
1431 } 1440 }
1432 1441
1433 /* 1442 /*
1434 * Fill the array oi->oi_dev. 1443 * Fill the array oi->oi_dev.
1435 */ 1444 */
1436 for (count = 0, i = 0; i < pkg->Package.Count; i++) { 1445 for (count = 0, i = 0; i < pkg->Package.Count; i++) {
1437 /* List of 32-bit integers (ACPI 4.0a, Sec. B.4.2). */ 1446 /* List of 32-bit integers (ACPI 4.0a, Sec. B.4.2). */
1438 if (pkg->Package.Elements[i].Type != ACPI_TYPE_INTEGER || 1447 if (pkg->Package.Elements[i].Type != ACPI_TYPE_INTEGER ||
1439 pkg->Package.Elements[i].Integer.Value > UINT32_MAX) 1448 pkg->Package.Elements[i].Integer.Value > UINT32_MAX)
1440 continue; 1449 continue;
1441 1450
1442 oi->oi_dev[count].od_attrs.raw = 1451 oi->oi_dev[count].od_attrs.raw =
1443 (uint32_t)pkg->Package.Elements[i].Integer.Value; 1452 (uint32_t)pkg->Package.Elements[i].Integer.Value;
1444 count++; 1453 count++;
1445 } 1454 }
1446 1455
1447 if (count == 0) { 1456 if (count == 0) {
1448 rv = AE_BAD_DATA; 1457 rv = AE_BAD_DATA;
1449 goto fail; 1458 goto fail;
1450 } 1459 }
1451 1460
1452 ACPI_FREE(pkg); 1461 ACPI_FREE(pkg);
1453 pkg = NULL; 1462 pkg = NULL;
1454 1463
1455 /* 1464 /*
1456 * Resize the array oi->oi_dev if needed. 1465 * Resize the array oi->oi_dev if needed.
1457 */ 1466 */
1458 if (count < oi->oi_dev_count) { 1467 if (count < oi->oi_dev_count) {
1459 devp = kmem_alloc(count * sizeof(*devp), KM_SLEEP); 1468 devp = kmem_alloc(count * sizeof(*devp), KM_SLEEP);
1460 if (devp == NULL) { 1469 if (devp == NULL) {
1461 rv = AE_NO_MEMORY; 1470 rv = AE_NO_MEMORY;
1462 goto fail; 1471 goto fail;
1463 } 1472 }
1464 1473
1465 (void)memcpy(devp, oi->oi_dev, count * sizeof(*devp)); 1474 (void)memcpy(devp, oi->oi_dev, count * sizeof(*devp));
1466 kmem_free(oi->oi_dev, oi->oi_dev_count * sizeof(*oi->oi_dev)); 1475 kmem_free(oi->oi_dev, oi->oi_dev_count * sizeof(*oi->oi_dev));
1467 1476
1468 oi->oi_dev = devp; 1477 oi->oi_dev = devp;
1469 oi->oi_dev_count = count; 1478 oi->oi_dev_count = count;
1470 } 1479 }
1471 1480
1472 return oi; 1481 return oi;
1473 1482
1474 fail: 1483 fail:
1475 aprint_error_dev(asc->sc_dev, "failed to evaluate %s.%s: %s\n", 1484 aprint_error_dev(asc->sc_dev, "failed to evaluate %s.%s: %s\n",
1476 acpi_name(hdl), "_DOD", AcpiFormatException(rv)); 1485 acpi_name(hdl), "_DOD", AcpiFormatException(rv));
1477 if (pkg != NULL) 1486 if (pkg != NULL)
1478 ACPI_FREE(pkg); 1487 ACPI_FREE(pkg);
1479 if (oi != NULL) { 1488 if (oi != NULL) {
1480 if (oi->oi_dev != NULL) 1489 if (oi->oi_dev != NULL)
1481 kmem_free(oi->oi_dev, 1490 kmem_free(oi->oi_dev,
1482 oi->oi_dev_count * sizeof(*oi->oi_dev)); 1491 oi->oi_dev_count * sizeof(*oi->oi_dev));
1483 kmem_free(oi, sizeof(*oi)); 1492 kmem_free(oi, sizeof(*oi));
1484 } 1493 }
1485 return NULL; 1494 return NULL;
1486} 1495}
1487 1496
1488/* 1497/*
1489 * acpidisp_vga_bind_outdevs: 1498 * acpidisp_vga_bind_outdevs:
1490 * 1499 *
1491 * Bind each acpiout device attached under an acpivga device to the 1500 * Bind each acpiout device attached under an acpivga device to the
1492 * corresponding (_DOD enumerated) connected output device. 1501 * corresponding (_DOD enumerated) connected output device.
1493 */ 1502 */
1494static void 1503static void
1495acpidisp_vga_bind_outdevs(struct acpidisp_vga_softc *asc) 1504acpidisp_vga_bind_outdevs(struct acpidisp_vga_softc *asc)
1496{ 1505{
1497 struct acpidisp_odinfo *oi = asc->sc_odinfo; 1506 struct acpidisp_odinfo *oi = asc->sc_odinfo;
1498 struct acpidisp_out_softc *osc; 1507 struct acpidisp_out_softc *osc;
1499 struct acpidisp_outdev *od; 1508 struct acpidisp_outdev *od;
1500 struct acpi_devnode *ad; 1509 struct acpi_devnode *ad;
1501 ACPI_HANDLE hdl; 1510 ACPI_HANDLE hdl;
1502 ACPI_UINT64 val; 1511 ACPI_UINT64 val;
1503 ACPI_STATUS rv; 1512 ACPI_STATUS rv;
1504 uint16_t devid; 1513 uint16_t devid;
1505 uint32_t i; 1514 uint32_t i;
1506 1515
1507 KASSERT(oi != NULL); 1516 KASSERT(oi != NULL);
1508 1517
1509 /* Reset all bindings. */ 1518 /* Reset all bindings. */
1510 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) 1519 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++)
1511 od->od_device = NULL; 1520 od->od_device = NULL;
1512 1521
1513 /* 1522 /*
1514 * Iterate over all ACPI children that have been attached under this 1523 * Iterate over all ACPI children that have been attached under this
1515 * acpivga device (as acpiout devices). 1524 * acpivga device (as acpiout devices).
1516 */ 1525 */
1517 SIMPLEQ_FOREACH(ad, &asc->sc_node->ad_child_head, ad_child_list) { 1526 SIMPLEQ_FOREACH(ad, &asc->sc_node->ad_child_head, ad_child_list) {
1518 if ((ad->ad_device == NULL) || 1527 if ((ad->ad_device == NULL) ||
1519 (device_parent(ad->ad_device) != asc->sc_dev)) 1528 (device_parent(ad->ad_device) != asc->sc_dev))
1520 continue; 1529 continue;
1521 1530
1522 KASSERT(device_is_a(ad->ad_device, "acpiout")); 1531 KASSERT(device_is_a(ad->ad_device, "acpiout"));
1523 1532
1524 osc = device_private(ad->ad_device); 1533 osc = device_private(ad->ad_device);
1525 1534
1526 /* 1535 /*
1527 * For display output devices, the method _ADR returns 1536 * For display output devices, the method _ADR returns
1528 * the device's ID (ACPI 4.0a, Sec. B.6.1). We do not 1537 * the device's ID (ACPI 4.0a, Sec. B.6.1). We do not
1529 * cache the result of _ADR since it may vary. 1538 * cache the result of _ADR since it may vary.
1530 */ 1539 */
1531 hdl = osc->sc_node->ad_handle; 1540 hdl = osc->sc_node->ad_handle;
1532 rv = acpi_eval_integer(hdl, "_ADR", &val); 1541 rv = acpi_eval_integer(hdl, "_ADR", &val);
1533 if (ACPI_FAILURE(rv)) { 1542 if (ACPI_FAILURE(rv)) {
1534 aprint_error_dev(asc->sc_dev, 1543 aprint_error_dev(asc->sc_dev,
1535 "failed to evaluate %s.%s: %s\n", 1544 "failed to evaluate %s.%s: %s\n",
1536 acpi_name(hdl), "_ADR", AcpiFormatException(rv)); 1545 acpi_name(hdl), "_ADR", AcpiFormatException(rv));
1537 continue; 1546 continue;
1538 } 1547 }
1539 1548
1540 /* The device ID is a 16-bit integer (ACPI 4.0a, Table B-2). */ 1549 /* The device ID is a 16-bit integer (ACPI 4.0a, Table B-2). */
1541 devid = (uint16_t)val; 1550 devid = (uint16_t)val;
1542 1551
1543 /* 1552 /*
1544 * The device ID must be unique (among output devices), and must 1553 * The device ID must be unique (among output devices), and must
1545 * appear in the list returned by _DOD (ACPI 4.0a, Sec. B.6.1). 1554 * appear in the list returned by _DOD (ACPI 4.0a, Sec. B.6.1).
1546 */ 1555 */
1547 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) { 1556 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) {
1548 if (devid == od->od_attrs.device_id) { 1557 if (devid == od->od_attrs.device_id) {
1549 if (od->od_device != NULL) 1558 if (od->od_device != NULL)
1550 aprint_error_dev(asc->sc_dev, 1559 aprint_error_dev(asc->sc_dev,
1551 "%s has same device ID as %s\n", 1560 "%s has same device ID as %s\n",
1552 device_xname(osc->sc_dev), 1561 device_xname(osc->sc_dev),
1553 device_xname(od->od_device)); 1562 device_xname(od->od_device));
1554 else 1563 else
1555 od->od_device = osc->sc_dev; 1564 od->od_device = osc->sc_dev;
1556 break; 1565 break;
1557 } 1566 }
1558 } 1567 }
1559 if (i == oi->oi_dev_count) 1568 if (i == oi->oi_dev_count)
1560 aprint_error_dev(asc->sc_dev, 1569 aprint_error_dev(asc->sc_dev,
1561 "unknown output device %s\n", 1570 "unknown output device %s\n",
1562 device_xname(osc->sc_dev)); 1571 device_xname(osc->sc_dev));
1563 } 1572 }
1564} 1573}
1565 1574
1566/* 1575/*
1567 * Regarding _BCL (ACPI 4.0a, Sec. B.6.2): 1576 * Regarding _BCL (ACPI 4.0a, Sec. B.6.2):
1568 * 1577 *
1569 * "This method allows the OS to query a list of brightness levels supported by 1578 * "This method allows the OS to query a list of brightness levels supported by
1570 * built-in display output devices." 1579 * built-in display output devices."
1571 * 1580 *
1572 * "Return value: a variable-length package containing a list of integers 1581 * "Return value: a variable-length package containing a list of integers
1573 * representing the supported brightness levels. Each integer has 8 bits of 1582 * representing the supported brightness levels. Each integer has 8 bits of
1574 * significant data." 1583 * significant data."
1575 */ 1584 */
1576 1585
1577static struct acpidisp_brctl * 1586static struct acpidisp_brctl *
1578acpidisp_init_brctl(const struct acpidisp_out_softc *osc) 1587acpidisp_init_brctl(const struct acpidisp_out_softc *osc)
1579{ 1588{
1580 ACPI_HANDLE hdl = osc->sc_node->ad_handle; 1589 ACPI_HANDLE hdl = osc->sc_node->ad_handle;
1581 ACPI_STATUS rv; 1590 ACPI_STATUS rv;
1582 ACPI_OBJECT *pkg; 1591 ACPI_OBJECT *pkg;
1583 struct acpidisp_brctl *bc; 1592 struct acpidisp_brctl *bc;
1584 uint8_t *levelp; 1593 uint8_t *levelp;
1585 uint32_t i; 1594 uint32_t i;
1586 int32_t j; 1595 int32_t j;
1587 uint16_t count, k; 1596 uint16_t count, k;
1588 uint8_t level; 1597 uint8_t level;
1589 1598
1590 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__BCL)) 1599 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__BCL))
1591 return NULL; 1600 return NULL;
1592 1601
1593 bc = NULL; 1602 bc = NULL;
1594 1603
1595 rv = acpidisp_eval_package(hdl, "_BCL", &pkg, 2); 1604 rv = acpidisp_eval_package(hdl, "_BCL", &pkg, 2);
1596 if (ACPI_FAILURE(rv)) 1605 if (ACPI_FAILURE(rv))
1597 goto fail; 1606 goto fail;
1598 1607
1599 /* 1608 /*
1600 * Allocate and fill the struct acpidisp_brctl to be returned. 1609 * Allocate and fill the struct acpidisp_brctl to be returned.
1601 */ 1610 */
1602 bc = kmem_zalloc(sizeof(*bc), KM_SLEEP); 1611 bc = kmem_zalloc(sizeof(*bc), KM_SLEEP);
1603 if (bc == NULL) { 1612 if (bc == NULL) {
1604 rv = AE_NO_MEMORY; 1613 rv = AE_NO_MEMORY;
1605 goto fail; 1614 goto fail;
1606 } 1615 }
1607 1616
1608 /* At most 256 brightness levels (8-bit integers). */ 1617 /* At most 256 brightness levels (8-bit integers). */
1609 if (pkg->Package.Count > 256) 1618 if (pkg->Package.Count > 256)
1610 bc->bc_level_count = 256; 1619 bc->bc_level_count = 256;
1611 else 1620 else
1612 bc->bc_level_count = (uint16_t)pkg->Package.Count; 1621 bc->bc_level_count = (uint16_t)pkg->Package.Count;
1613 1622
1614 bc->bc_level = kmem_zalloc(bc->bc_level_count * sizeof(*bc->bc_level), 1623 bc->bc_level = kmem_zalloc(bc->bc_level_count * sizeof(*bc->bc_level),
1615 KM_SLEEP); 1624 KM_SLEEP);
1616 if (bc->bc_level == NULL) { 1625 if (bc->bc_level == NULL) {
1617 rv = AE_NO_MEMORY; 1626 rv = AE_NO_MEMORY;
1618 goto fail; 1627 goto fail;
1619 } 1628 }
1620 1629
1621 /* 1630 /*
1622 * Fill the array bc->bc_level with an insertion sort. 1631 * Fill the array bc->bc_level with an insertion sort.
1623 */ 1632 */
1624 for (count = 0, i = 0; i < pkg->Package.Count; i++) { 1633 for (count = 0, i = 0; i < pkg->Package.Count; i++) {
1625 /* List of 8-bit integers (ACPI 4.0a, Sec. B.6.2). */ 1634 /* List of 8-bit integers (ACPI 4.0a, Sec. B.6.2). */
1626 if (pkg->Package.Elements[i].Type != ACPI_TYPE_INTEGER || 1635 if (pkg->Package.Elements[i].Type != ACPI_TYPE_INTEGER ||
1627 pkg->Package.Elements[i].Integer.Value > UINT8_MAX) 1636 pkg->Package.Elements[i].Integer.Value > UINT8_MAX)
1628 continue; 1637 continue;
1629 1638
1630 level = (uint8_t)pkg->Package.Elements[i].Integer.Value; 1639 level = (uint8_t)pkg->Package.Elements[i].Integer.Value;
1631 1640
1632 /* Find the correct slot but do not modify the array yet. */ 1641 /* Find the correct slot but do not modify the array yet. */
1633 for (j = count; --j >= 0 && bc->bc_level[j] > level; ); 1642 for (j = count; --j >= 0 && bc->bc_level[j] > level; );
1634 if (j >= 0 && bc->bc_level[j] == level) 1643 if (j >= 0 && bc->bc_level[j] == level)
1635 continue; 1644 continue;
1636 j++; 1645 j++;
1637 1646
1638 /* Make room for the new level. */ 1647 /* Make room for the new level. */
1639 for (k = count; k > j; k--) 1648 for (k = count; k > j; k--)
1640 bc->bc_level[k] = bc->bc_level[k-1]; 1649 bc->bc_level[k] = bc->bc_level[k-1];
1641 1650
1642 /* Insert the new level. */ 1651 /* Insert the new level. */
1643 bc->bc_level[j] = level; 1652 bc->bc_level[j] = level;
1644 count++; 1653 count++;
1645 } 1654 }
1646 1655
1647 if (count == 0) { 1656 if (count == 0) {
1648 rv = AE_BAD_DATA; 1657 rv = AE_BAD_DATA;
1649 goto fail; 1658 goto fail;
1650 } 1659 }
1651 1660
1652 ACPI_FREE(pkg); 1661 ACPI_FREE(pkg);
1653 pkg = NULL; 1662 pkg = NULL;
1654 1663
1655 /* 1664 /*
1656 * Resize the array bc->bc_level if needed. 1665 * Resize the array bc->bc_level if needed.
1657 */ 1666 */
1658 if (count < bc->bc_level_count) { 1667 if (count < bc->bc_level_count) {
1659 levelp = kmem_alloc(count * sizeof(*levelp), KM_SLEEP); 1668 levelp = kmem_alloc(count * sizeof(*levelp), KM_SLEEP);
1660 if (levelp == NULL) { 1669 if (levelp == NULL) {
1661 rv = AE_NO_MEMORY; 1670 rv = AE_NO_MEMORY;
1662 goto fail; 1671 goto fail;
1663 } 1672 }
1664 1673
1665 (void)memcpy(levelp, bc->bc_level, count * sizeof(*levelp)); 1674 (void)memcpy(levelp, bc->bc_level, count * sizeof(*levelp));
1666 kmem_free(bc->bc_level, 1675 kmem_free(bc->bc_level,
1667 bc->bc_level_count * sizeof(*bc->bc_level)); 1676 bc->bc_level_count * sizeof(*bc->bc_level));
1668 1677
1669 bc->bc_level = levelp; 1678 bc->bc_level = levelp;
1670 bc->bc_level_count = count; 1679 bc->bc_level_count = count;
1671 } 1680 }
1672 1681
1673 return bc; 1682 return bc;
1674 1683
1675 fail: 1684 fail:
1676 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n", 1685 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n",
1677 acpi_name(hdl), "_BCL", AcpiFormatException(rv)); 1686 acpi_name(hdl), "_BCL", AcpiFormatException(rv));
1678 if (pkg != NULL) 1687 if (pkg != NULL)
1679 ACPI_FREE(pkg); 1688 ACPI_FREE(pkg);
1680 if (bc != NULL) { 1689 if (bc != NULL) {
1681 if (bc->bc_level != NULL) 1690 if (bc->bc_level != NULL)
1682 kmem_free(bc->bc_level, 1691 kmem_free(bc->bc_level,
1683 bc->bc_level_count * sizeof(*bc->bc_level)); 1692 bc->bc_level_count * sizeof(*bc->bc_level));
1684 kmem_free(bc, sizeof(*bc)); 1693 kmem_free(bc, sizeof(*bc));
1685 } 1694 }
1686 return NULL; 1695 return NULL;
1687} 1696}
1688 1697
1689/* 1698/*
1690 * Evaluation of simple ACPI display methods. 1699 * Evaluation of simple ACPI display methods.
1691 */ 1700 */
1692 1701
1693static int 1702static int
1694acpidisp_set_policy(const struct acpidisp_vga_softc *asc, uint8_t value) 1703acpidisp_set_policy(const struct acpidisp_vga_softc *asc, uint8_t value)
1695{ 1704{
1696 ACPI_HANDLE hdl = asc->sc_node->ad_handle; 1705 ACPI_HANDLE hdl = asc->sc_node->ad_handle;
1697 ACPI_UINT64 val; 1706 ACPI_UINT64 val;
1698 ACPI_STATUS rv; 1707 ACPI_STATUS rv;
1699 1708
1700 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: set %s: 0x%"PRIx8"\n", 1709 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: set %s: 0x%"PRIx8"\n",
1701 device_xname(asc->sc_dev), "policy", value)); 1710 device_xname(asc->sc_dev), "policy", value));
1702 1711
1703 if (!(asc->sc_caps & ACPI_DISP_VGA_CAP__DOS)) 1712 if (!(asc->sc_caps & ACPI_DISP_VGA_CAP__DOS))
1704 return ENODEV; 1713 return ENODEV;
1705 1714
1706 val = (ACPI_UINT64)value; 1715 val = (ACPI_UINT64)value;
1707 rv = acpi_eval_set_integer(hdl, "_DOS", val); 1716 rv = acpi_eval_set_integer(hdl, "_DOS", val);
1708 if (ACPI_FAILURE(rv)) { 1717 if (ACPI_FAILURE(rv)) {
1709 aprint_error_dev(asc->sc_dev, "failed to evaluate %s.%s: %s\n", 1718 aprint_error_dev(asc->sc_dev, "failed to evaluate %s.%s: %s\n",
1710 acpi_name(hdl), "_DOS", AcpiFormatException(rv)); 1719 acpi_name(hdl), "_DOS", AcpiFormatException(rv));
1711 return EIO; 1720 return EIO;
1712 } 1721 }
1713 1722
1714 return 0; 1723 return 0;
1715} 1724}
1716 1725
1717static int 1726static int
1718acpidisp_get_status(const struct acpidisp_out_softc *osc, uint32_t *valuep) 1727acpidisp_get_status(const struct acpidisp_out_softc *osc, uint32_t *valuep)
1719{ 1728{
1720 ACPI_HANDLE hdl = osc->sc_node->ad_handle; 1729 ACPI_HANDLE hdl = osc->sc_node->ad_handle;
1721 ACPI_UINT64 val; 1730 ACPI_UINT64 val;
1722 ACPI_STATUS rv; 1731 ACPI_STATUS rv;
1723 1732
1724 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DCS)) 1733 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DCS))
1725 return ENODEV; 1734 return ENODEV;
1726 1735
1727 rv = acpi_eval_integer(hdl, "_DCS", &val); 1736 rv = acpi_eval_integer(hdl, "_DCS", &val);
1728 if (ACPI_FAILURE(rv)) { 1737 if (ACPI_FAILURE(rv)) {
1729 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n", 1738 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n",
1730 acpi_name(hdl), "_DCS", AcpiFormatException(rv)); 1739 acpi_name(hdl), "_DCS", AcpiFormatException(rv));
1731 return EIO; 1740 return EIO;
1732 } 1741 }
1733 1742
1734 if (val > UINT32_MAX) 1743 if (val > UINT32_MAX)
1735 return ERANGE; 1744 return ERANGE;
1736 1745
1737 *valuep = (uint32_t)val; 1746 *valuep = (uint32_t)val;
1738 1747
1739 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: get %s: 0x%"PRIx32"\n", 1748 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: get %s: 0x%"PRIx32"\n",
1740 device_xname(osc->sc_dev), "status", *valuep)); 1749 device_xname(osc->sc_dev), "status", *valuep));
1741 1750
1742 return 0; 1751 return 0;
1743} 1752}
1744 1753
1745static int 1754static int
1746acpidisp_get_state(const struct acpidisp_out_softc *osc, uint32_t *valuep) 1755acpidisp_get_state(const struct acpidisp_out_softc *osc, uint32_t *valuep)
1747{ 1756{
1748 ACPI_HANDLE hdl = osc->sc_node->ad_handle; 1757 ACPI_HANDLE hdl = osc->sc_node->ad_handle;
1749 ACPI_UINT64 val; 1758 ACPI_UINT64 val;
1750 ACPI_STATUS rv; 1759 ACPI_STATUS rv;
1751 1760
1752 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DGS)) 1761 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DGS))
1753 return ENODEV; 1762 return ENODEV;
1754 1763
1755 rv = acpi_eval_integer(hdl, "_DGS", &val); 1764 rv = acpi_eval_integer(hdl, "_DGS", &val);
1756 if (ACPI_FAILURE(rv)) { 1765 if (ACPI_FAILURE(rv)) {
1757 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n", 1766 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n",
1758 acpi_name(hdl), "_DGS", AcpiFormatException(rv)); 1767 acpi_name(hdl), "_DGS", AcpiFormatException(rv));
1759 return EIO; 1768 return EIO;
1760 } 1769 }
1761 1770
1762 if (val > UINT32_MAX) 1771 if (val > UINT32_MAX)
1763 return ERANGE; 1772 return ERANGE;
1764 1773
1765 *valuep = (uint32_t)val; 1774 *valuep = (uint32_t)val;
1766 1775
1767 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: get %s: 0x%"PRIx32"\n", 1776 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: get %s: 0x%"PRIx32"\n",
1768 device_xname(osc->sc_dev), "state", *valuep)); 1777 device_xname(osc->sc_dev), "state", *valuep));
1769 1778
1770 return 0; 1779 return 0;
1771} 1780}
1772 1781
1773static int 1782static int
1774acpidisp_set_state(const struct acpidisp_out_softc *osc, uint32_t value) 1783acpidisp_set_state(const struct acpidisp_out_softc *osc, uint32_t value)
1775{ 1784{
1776 ACPI_HANDLE hdl = osc->sc_node->ad_handle; 1785 ACPI_HANDLE hdl = osc->sc_node->ad_handle;
1777 ACPI_UINT64 val; 1786 ACPI_UINT64 val;
1778 ACPI_STATUS rv; 1787 ACPI_STATUS rv;
1779 1788
1780 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: set %s: 0x%"PRIx32"\n", 1789 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: set %s: 0x%"PRIx32"\n",
1781 device_xname(osc->sc_dev), "state", value)); 1790 device_xname(osc->sc_dev), "state", value));
1782 1791
1783 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DSS)) 1792 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DSS))
1784 return ENODEV; 1793 return ENODEV;
1785 1794
1786 val = (ACPI_UINT64)value; 1795 val = (ACPI_UINT64)value;
1787 rv = acpi_eval_set_integer(hdl, "_DSS", val); 1796 rv = acpi_eval_set_integer(hdl, "_DSS", val);
1788 if (ACPI_FAILURE(rv)) { 1797 if (ACPI_FAILURE(rv)) {
1789 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n", 1798 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n",
1790 acpi_name(hdl), "_DSS", AcpiFormatException(rv)); 1799 acpi_name(hdl), "_DSS", AcpiFormatException(rv));
1791 return EIO; 1800 return EIO;
1792 } 1801 }
1793 1802
1794 return 0; 1803 return 0;
1795} 1804}
1796 1805
1797static int 1806static int
1798acpidisp_get_brightness(const struct acpidisp_out_softc *osc, uint8_t *valuep) 1807acpidisp_get_brightness(const struct acpidisp_out_softc *osc, uint8_t *valuep)
1799{ 1808{
1800 ACPI_HANDLE hdl = osc->sc_node->ad_handle; 1809 ACPI_HANDLE hdl = osc->sc_node->ad_handle;
1801 ACPI_UINT64 val; 1810 ACPI_UINT64 val;
1802 ACPI_STATUS rv; 1811 ACPI_STATUS rv;
1803 1812
1804 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__BQC)) 1813 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__BQC))
1805 return ENODEV; 1814 return ENODEV;
1806 1815
1807 rv = acpi_eval_integer(hdl, "_BQC", &val); 1816 rv = acpi_eval_integer(hdl, "_BQC", &val);
1808 if (ACPI_FAILURE(rv)) { 1817 if (ACPI_FAILURE(rv)) {
1809 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n", 1818 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n",
1810 acpi_name(hdl), "_BQC", AcpiFormatException(rv)); 1819 acpi_name(hdl), "_BQC", AcpiFormatException(rv));
1811 return EIO; 1820 return EIO;
1812 } 1821 }
1813 1822
1814 if (val > UINT8_MAX) 1823 if (val > UINT8_MAX)
1815 return ERANGE; 1824 return ERANGE;
1816 1825
1817 *valuep = (uint8_t)val; 1826 *valuep = (uint8_t)val;
1818 1827
1819 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: get %s: %"PRIu8"\n", 1828 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: get %s: %"PRIu8"\n",
1820 device_xname(osc->sc_dev), "brightness", *valuep)); 1829 device_xname(osc->sc_dev), "brightness", *valuep));
1821 1830
1822 return 0; 1831 return 0;
1823} 1832}
1824 1833
1825static int 1834static int
1826acpidisp_set_brightness(const struct acpidisp_out_softc *osc, uint8_t value) 1835acpidisp_set_brightness(const struct acpidisp_out_softc *osc, uint8_t value)
1827{ 1836{
1828 ACPI_HANDLE hdl = osc->sc_node->ad_handle; 1837 ACPI_HANDLE hdl = osc->sc_node->ad_handle;
1829 ACPI_UINT64 val; 1838 ACPI_UINT64 val;
1830 ACPI_STATUS rv; 1839 ACPI_STATUS rv;
1831 1840
1832 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: set %s: %"PRIu8"\n", 1841 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: set %s: %"PRIu8"\n",
1833 device_xname(osc->sc_dev), "brightness", value)); 1842 device_xname(osc->sc_dev), "brightness", value));
1834 1843
1835 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__BCM)) 1844 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__BCM))
1836 return ENODEV; 1845 return ENODEV;
1837 1846
1838 val = (ACPI_UINT64)value; 1847 val = (ACPI_UINT64)value;
1839 rv = acpi_eval_set_integer(hdl, "_BCM", val); 1848 rv = acpi_eval_set_integer(hdl, "_BCM", val);
1840 if (ACPI_FAILURE(rv)) { 1849 if (ACPI_FAILURE(rv)) {
1841 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n", 1850 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n",
1842 acpi_name(hdl), "_BCM", AcpiFormatException(rv)); 1851 acpi_name(hdl), "_BCM", AcpiFormatException(rv));
1843 return EIO; 1852 return EIO;
1844 } 1853 }
1845 1854
1846 return 0; 1855 return 0;
1847} 1856}
1848 1857
1849/* 1858/*
1850 * Pretty printing. 1859 * Pretty printing.
1851 */ 1860 */
1852 1861
1853static void 1862static void
1854acpidisp_print_odinfo(device_t self, const struct acpidisp_odinfo *oi) 1863acpidisp_print_odinfo(device_t self, const struct acpidisp_odinfo *oi)
1855{ 1864{
1856 struct acpidisp_outdev *od; 1865 struct acpidisp_outdev *od;
1857 uint32_t i; 1866 uint32_t i;
1858 1867
1859 KASSERT(oi != NULL); 1868 KASSERT(oi != NULL);
1860 1869
1861 aprint_verbose_dev(self, "connected output devices:\n"); 1870 aprint_verbose_dev(self, "connected output devices:\n");
1862 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) { 1871 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) {
1863 aprint_verbose_dev(self, " 0x%04"PRIx16, od->od_attrs.device_id); 1872 aprint_verbose_dev(self, " 0x%04"PRIx16, od->od_attrs.device_id);
1864 if (od->od_device != NULL) 1873 if (od->od_device != NULL)
1865 aprint_verbose(" (%s)", device_xname(od->od_device)); 1874 aprint_verbose(" (%s)", device_xname(od->od_device));
1866 aprint_verbose(": "); 1875 aprint_verbose(": ");
1867 acpidisp_print_od_attrs(od->od_attrs); 1876 acpidisp_print_od_attrs(od->od_attrs);
1868 aprint_verbose("\n"); 1877 aprint_verbose("\n");
1869 } 1878 }
1870} 1879}
1871 1880
1872static void 1881static void
1873acpidisp_print_brctl(device_t self, const struct acpidisp_brctl *bc) 1882acpidisp_print_brctl(device_t self, const struct acpidisp_brctl *bc)
1874{ 1883{
1875 uint16_t i; 1884 uint16_t i;
1876 1885
1877 KASSERT(bc != NULL); 1886 KASSERT(bc != NULL);
1878 1887
1879 aprint_verbose_dev(self, "brightness levels:"); 1888 aprint_verbose_dev(self, "brightness levels:");
1880 for (i = 0; i < bc->bc_level_count; i++) 1889 for (i = 0; i < bc->bc_level_count; i++)
1881 aprint_verbose(" %"PRIu8, bc->bc_level[i]); 1890 aprint_verbose(" %"PRIu8, bc->bc_level[i]);
1882 aprint_verbose("\n"); 1891 aprint_verbose("\n");
1883} 1892}
1884 1893
1885static void 1894static void
1886acpidisp_print_od_attrs(acpidisp_od_attrs_t oda) 1895acpidisp_print_od_attrs(acpidisp_od_attrs_t oda)
1887{ 1896{
1888 const char *type; 1897 const char *type;
1889 1898
1890 if (oda.fmt.device_id_scheme == 1) { 1899 if (oda.fmt.device_id_scheme == 1) {
1891 /* Uses the device ID scheme introduced in ACPI 3.0. */ 1900 /* Uses the device ID scheme introduced in ACPI 3.0. */
1892 switch (oda.fmt.type) { 1901 switch (oda.fmt.type) {
1893 case ACPI_DISP_OUT_ATTR_TYPE_OTHER: 1902 case ACPI_DISP_OUT_ATTR_TYPE_OTHER:
1894 type = "Other"; 1903 type = "Other";
1895 break; 1904 break;
1896 case ACPI_DISP_OUT_ATTR_TYPE_VGA: 1905 case ACPI_DISP_OUT_ATTR_TYPE_VGA:
1897 type = "VGA Analog Monitor"; 1906 type = "VGA Analog Monitor";
1898 break; 1907 break;
1899 case ACPI_DISP_OUT_ATTR_TYPE_TV: 1908 case ACPI_DISP_OUT_ATTR_TYPE_TV:
1900 type = "TV/HDTV Monitor"; 1909 type = "TV/HDTV Monitor";
1901 break; 1910 break;
1902 case ACPI_DISP_OUT_ATTR_TYPE_EXTDIG: 1911 case ACPI_DISP_OUT_ATTR_TYPE_EXTDIG:
1903 type = "Ext. Digital Monitor"; 1912 type = "Ext. Digital Monitor";
1904 break; 1913 break;
1905 case ACPI_DISP_OUT_ATTR_TYPE_INTDFP: 1914 case ACPI_DISP_OUT_ATTR_TYPE_INTDFP:
1906 type = "Int. Digital Flat Panel"; 1915 type = "Int. Digital Flat Panel";
1907 break; 1916 break;
1908 default: 1917 default:
1909 type = "Invalid"; 1918 type = "Invalid";
1910 break; 1919 break;
1911 } 1920 }
1912 1921
1913 aprint_verbose("%s, index %d, port %d", 1922 aprint_verbose("%s, index %d, port %d",
1914 type, oda.fmt.index, oda.fmt.port); 1923 type, oda.fmt.index, oda.fmt.port);
1915 } else { 1924 } else {
1916 /* Uses vendor-specific device IDs. */ 1925 /* Uses vendor-specific device IDs. */
1917 switch (oda.device_id) { 1926 switch (oda.device_id) {
1918 case ACPI_DISP_OUT_LEGACY_DEVID_MONITOR: 1927 case ACPI_DISP_OUT_LEGACY_DEVID_MONITOR:
1919 type = "Ext. Monitor"; 1928 type = "Ext. Monitor";
1920 break; 1929 break;
1921 case ACPI_DISP_OUT_LEGACY_DEVID_PANEL: 1930 case ACPI_DISP_OUT_LEGACY_DEVID_PANEL:
1922 type = "LCD Panel"; 1931 type = "LCD Panel";
1923 break; 1932 break;
1924 case ACPI_DISP_OUT_LEGACY_DEVID_TV: 1933 case ACPI_DISP_OUT_LEGACY_DEVID_TV:
1925 type = "TV"; 1934 type = "TV";
1926 break; 1935 break;
1927 default: 1936 default:
1928 type = "Unknown Output Device"; 1937 type = "Unknown Output Device";
1929 break; 1938 break;
1930 } 1939 }
1931 1940
1932 aprint_verbose("%s", type); 1941 aprint_verbose("%s", type);
1933 } 1942 }
1934 1943
1935 aprint_verbose(", head %d", oda.fmt.head_id); 1944 aprint_verbose(", head %d", oda.fmt.head_id);
1936 if (oda.fmt.bios_detect) 1945 if (oda.fmt.bios_detect)
1937 aprint_verbose(", bios detect"); 1946 aprint_verbose(", bios detect");
1938 if (oda.fmt.non_vga) 1947 if (oda.fmt.non_vga)
1939 aprint_verbose(", non vga"); 1948 aprint_verbose(", non vga");
1940} 1949}
1941 1950
1942/* 1951/*
1943 * General-purpose utility functions. 1952 * General-purpose utility functions.
1944 */ 1953 */
1945 1954
1946/* 1955/*
1947 * acpidisp_has_method: 1956 * acpidisp_has_method:
1948 * 1957 *
1949 * Returns true if and only if (a) the object handle.path exists and 1958 * Returns true if and only if (a) the object handle.path exists and
1950 * (b) this object is a method or has the given type. 1959 * (b) this object is a method or has the given type.
1951 */ 1960 */
1952static bool 1961static bool
1953acpidisp_has_method(ACPI_HANDLE handle, const char *path, ACPI_OBJECT_TYPE type) 1962acpidisp_has_method(ACPI_HANDLE handle, const char *path, ACPI_OBJECT_TYPE type)
1954{ 1963{
1955 ACPI_HANDLE hdl; 1964 ACPI_HANDLE hdl;
1956 ACPI_OBJECT_TYPE typ; 1965 ACPI_OBJECT_TYPE typ;