Thu Oct 28 21:45:02 2010 UTC ()
Simplify the sysctl variable for BIOS switch policy, and document it
in acpivga(4).  The previous hw.acpi.acpivga0.policy variable is
renamed into bios_policy for consistency, and is for ACPI_DEBUG only.

ok jruoho@


(gsutre)
diff -r1.2 -r1.3 src/share/man/man4/acpivga.4
diff -r1.3 -r1.4 src/sys/dev/acpi/acpi_display.c

cvs diff -r1.2 -r1.3 src/share/man/man4/acpivga.4 (switch to unified diff)

--- src/share/man/man4/acpivga.4 2010/10/28 14:36:04 1.2
+++ src/share/man/man4/acpivga.4 2010/10/28 21:45:02 1.3
@@ -1,107 +1,124 @@ @@ -1,107 +1,124 @@
1.\" $NetBSD: acpivga.4,v 1.2 2010/10/28 14:36:04 jruoho Exp $ 1.\" $NetBSD: acpivga.4,v 1.3 2010/10/28 21:45:02 gsutre Exp $
2.\" 2.\"
3.\" Copyright (c) 2010 The NetBSD Foundation, Inc. 3.\" Copyright (c) 2010 The NetBSD Foundation, Inc.
4.\" All rights reserved. 4.\" All rights reserved.
5.\" 5.\"
6.\" Redistribution and use in source and binary forms, with or without 6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions 7.\" modification, are permitted provided that the following conditions
8.\" are met: 8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright 9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer. 10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 14.\"
15.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 15.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 16.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 18.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25.\" POSSIBILITY OF SUCH DAMAGE. 25.\" POSSIBILITY OF SUCH DAMAGE.
26.\" 26.\"
27.Dd October 28, 2010 27.Dd October 28, 2010
28.Dt ACPIVGA 4 28.Dt ACPIVGA 4
29.Os 29.Os
30.Sh NAME 30.Sh NAME
31.Nm acpivga 31.Nm acpivga
32.Nd ACPI Display Adapter and Output Devices 32.Nd ACPI Display Adapter and Output Devices
33.Sh SYNOPSIS 33.Sh SYNOPSIS
34.Cd "acpivga* at acpi?" 34.Cd "acpivga* at acpi?"
35.Cd "acpiout* at acpivga?" 35.Cd "acpiout* at acpivga?"
36.Sh DESCRIPTION 36.Sh DESCRIPTION
37The 37The
38.Nm 38.Nm
39driver provides generic support for brightness control and output switching, 39driver provides generic support for brightness control and output switching,
40through 40through
41.Tn ACPI 41.Tn ACPI
42video extensions. 42video extensions.
43The 43The
44.Tn ACPI 44.Tn ACPI
45specification requires that systems containing a built-in display adapter 45specification requires that systems containing a built-in display adapter
46implement these extensions in their 46implement these extensions in their
47.Tn ACPI 47.Tn ACPI
48BIOS. 48BIOS.
49.Pp 49.Pp
50The driver handles brightness hotkeys and output switch hotkeys. 50The driver handles brightness hotkeys and display switch hotkeys.
51In addition, the following 51In addition, the following
52.Xr sysctl 8 52.Xr sysctl 8
53read/write variables are provided (when hardware support is available): 53read/write variables are provided (when hardware support is available):
54.Bl -tag -width Ds 54.Bl -tag -width Ds
55.It Va hw.acpi.acpivga0.policy 55.It Va hw.acpi.acpivga0.bios_switch
56BIOS switch policy. 56BIOS output switching policy.
57Accepted values range from 0 to 7. 57This boolean variable controls the behavior of the BIOS when a display
58For more information, refer to the documentation of the _DOS method, 58switch hotkey is pressed.
59in Section B.4.1 of the 59.Bl -tag -width xxx -compact
60.Tn ACPI 60.It Sy 1
61specification (revision 4.0a). 61the BIOS should automatically switch outputs, with no interaction from
 62.Nm .
 63.It Sy 0
 64the BIOS should only notify
 65.Nm
 66of the desired output state changes.
 67.El
62.It Va hw.acpi.acpiout0.brightness 68.It Va hw.acpi.acpiout0.brightness
63Brightness level. 69Brightness level.
64Typical values range from 0 to 100, but any integer value is accepted (the 70This integer variable typically ranges from 0 to 100, but any integer value
65driver uses the closest brightness level supported by the device). 71is accepted (the driver uses the closest brightness level supported by the
 72device).
66.El 73.El
67.Pp 74.Pp
68Please note, however, that future versions of 75Please note, however, that future versions of
69.Nm 76.Nm
70may remove these 77may remove these
71.Xr sysctl 8 78.Xr sysctl 8
72variables without prior notice. 79variables without prior notice.
73.Sh SEE ALSO 80.Sh SEE ALSO
74.Xr acpi 4 , 81.Xr acpi 4 ,
75.Xr vga 4 , 82.Xr vga 4 ,
76.Xr sysctl 8 83.Xr sysctl 8
77.Rs 84.Rs
78.%A Microsoft Corporation 85.%A Microsoft Corporation
79.%D December 4, 2001 86.%D December 4, 2001
80.%T Mobile System Displays and Windows 87.%T Mobile System Displays and Windows
81.%N Version 1.2c 88.%N Version 1.2c
82.%U http://www.microsoft.com/whdc/archive/mobiledisplay.mspx 89.%U http://www.microsoft.com/whdc/archive/mobiledisplay.mspx
83.Re 90.Re
84.Sh HISTORY 91.Sh HISTORY
85The 92The
86.Nm 93.Nm
87driver appeared in 94driver appeared in
88.Nx 6.0 . 95.Nx 6.0 .
89.Sh AUTHORS 96.Sh AUTHORS
90.An Gr\('egoire Sutre 97.An Gr\('egoire Sutre
91.Aq gsutre@NetBSD.org 98.Aq gsutre@NetBSD.org
92.Sh CAVEATS 99.Sh CAVEATS
93The 100The
94.Nm 101.Nm
95driver only supports PCI/PCI-X/PCI-E display adapters. 102driver only supports PCI/PCI-X/PCI-E display adapters.
96.Pp 103.Pp
97Many 104Many
98.Tn ACPI 105.Tn ACPI
99BIOSes implement only part of the 106BIOSes implement only part of the
100.Tn ACPI 107.Tn ACPI
101video extensions. 108video extensions.
102In particular, display output switching often does not work. 109In particular, display output switching via these extensions often does not
 110work.
 111For this reason,
 112.Nm
 113enables
 114.Va hw.acpi.acpivga0.bios_switch
 115by default.
 116If the display switch hotkey does not work with this default setting, try
 117setting
 118.Va hw.acpi.acpivga0.bios_switch
 119to 0.
103.Pp 120.Pp
104Brightness level should be controlled via 121Brightness level should be controlled via
105.Xr wsconsctl 8 122.Xr wsconsctl 8
106instead of 123instead of
107.Xr sysctl 8 . 124.Xr sysctl 8 .

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

--- src/sys/dev/acpi/acpi_display.c 2010/10/26 22:27:44 1.3
+++ src/sys/dev/acpi/acpi_display.c 2010/10/28 21:45:02 1.4
@@ -1,2036 +1,2080 @@ @@ -1,2036 +1,2080 @@
1/* $NetBSD: acpi_display.c,v 1.3 2010/10/26 22:27:44 gsutre Exp $ */ 1/* $NetBSD: acpi_display.c,v 1.4 2010/10/28 21:45:02 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.3 2010/10/26 22:27:44 gsutre Exp $"); 69__KERNEL_RCSID(0, "$NetBSD: acpi_display.c,v 1.4 2010/10/28 21:45:02 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
350static int acpidisp_vga_sysctl_policy(SYSCTLFN_PROTO); 351static int acpidisp_vga_sysctl_policy(SYSCTLFN_PROTO);
 352#endif
 353static int acpidisp_vga_sysctl_policy_output(SYSCTLFN_PROTO);
351#ifdef ACPI_DISP_SWITCH_SYSCTLS 354#ifdef ACPI_DISP_SWITCH_SYSCTLS
352static int acpidisp_out_sysctl_status(SYSCTLFN_PROTO); 355static int acpidisp_out_sysctl_status(SYSCTLFN_PROTO);
353static int acpidisp_out_sysctl_state(SYSCTLFN_PROTO); 356static int acpidisp_out_sysctl_state(SYSCTLFN_PROTO);
354#endif 357#endif
355static int acpidisp_out_sysctl_brightness(SYSCTLFN_PROTO); 358static int acpidisp_out_sysctl_brightness(SYSCTLFN_PROTO);
356 359
357static struct acpidisp_odinfo * 360static struct acpidisp_odinfo *
358 acpidisp_init_odinfo(const struct acpidisp_vga_softc *); 361 acpidisp_init_odinfo(const struct acpidisp_vga_softc *);
359static void acpidisp_vga_bind_outdevs(struct acpidisp_vga_softc *); 362static void acpidisp_vga_bind_outdevs(struct acpidisp_vga_softc *);
360static struct acpidisp_brctl * 363static struct acpidisp_brctl *
361 acpidisp_init_brctl(const struct acpidisp_out_softc *); 364 acpidisp_init_brctl(const struct acpidisp_out_softc *);
362 365
363static int acpidisp_set_policy(const struct acpidisp_vga_softc *, 366static int acpidisp_set_policy(const struct acpidisp_vga_softc *,
364 uint8_t); 367 uint8_t);
365static int acpidisp_get_status(const struct acpidisp_out_softc *, 368static int acpidisp_get_status(const struct acpidisp_out_softc *,
366 uint32_t *); 369 uint32_t *);
367static int acpidisp_get_state(const struct acpidisp_out_softc *, 370static int acpidisp_get_state(const struct acpidisp_out_softc *,
368 uint32_t *); 371 uint32_t *);
369static int acpidisp_set_state(const struct acpidisp_out_softc *, 372static int acpidisp_set_state(const struct acpidisp_out_softc *,
370 uint32_t); 373 uint32_t);
371static int acpidisp_get_brightness(const struct acpidisp_out_softc *, 374static int acpidisp_get_brightness(const struct acpidisp_out_softc *,
372 uint8_t *); 375 uint8_t *);
373static int acpidisp_set_brightness(const struct acpidisp_out_softc *, 376static int acpidisp_set_brightness(const struct acpidisp_out_softc *,
374 uint8_t); 377 uint8_t);
375 378
376static void acpidisp_print_odinfo(device_t, const struct acpidisp_odinfo *); 379static void acpidisp_print_odinfo(device_t, const struct acpidisp_odinfo *);
377static void acpidisp_print_brctl(device_t, const struct acpidisp_brctl *); 380static void acpidisp_print_brctl(device_t, const struct acpidisp_brctl *);
378static void acpidisp_print_od_attrs(acpidisp_od_attrs_t); 381static void acpidisp_print_od_attrs(acpidisp_od_attrs_t);
379 382
380static bool acpidisp_has_method(ACPI_HANDLE, const char *, 383static bool acpidisp_has_method(ACPI_HANDLE, const char *,
381 ACPI_OBJECT_TYPE); 384 ACPI_OBJECT_TYPE);
382static ACPI_STATUS 385static ACPI_STATUS
383 acpidisp_eval_package(ACPI_HANDLE, const char *, ACPI_OBJECT **, 386 acpidisp_eval_package(ACPI_HANDLE, const char *, ACPI_OBJECT **,
384 unsigned int); 387 unsigned int);
385static 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 *,
386 uint8_t *); 389 uint8_t *);
387 390
388/* 391/*
389 * Autoconfiguration for the acpivga driver. 392 * Autoconfiguration for the acpivga driver.
390 */ 393 */
391 394
392static int 395static int
393acpidisp_vga_match(device_t parent, cfdata_t match, void *aux) 396acpidisp_vga_match(device_t parent, cfdata_t match, void *aux)
394{ 397{
395 struct acpi_attach_args *aa = aux; 398 struct acpi_attach_args *aa = aux;
396 struct acpi_devnode *ad = aa->aa_node; 399 struct acpi_devnode *ad = aa->aa_node;
397 struct acpi_softc *sc = device_private(ad->ad_root); 400 struct acpi_softc *sc = device_private(ad->ad_root);
398 struct acpi_pci_info *ap; 401 struct acpi_pci_info *ap;
399 pcitag_t tag; 402 pcitag_t tag;
400 pcireg_t id, class; 403 pcireg_t id, class;
401 404
402 /* 405 /*
403 * We match ACPI devices that correspond to PCI display controllers. 406 * We match ACPI devices that correspond to PCI display controllers.
404 */ 407 */
405 if (ad->ad_type != ACPI_TYPE_DEVICE) 408 if (ad->ad_type != ACPI_TYPE_DEVICE)
406 return 0; 409 return 0;
407 410
408 ap = ad->ad_pciinfo; 411 ap = ad->ad_pciinfo;
409 if ((ap == NULL) || 412 if ((ap == NULL) ||
410 !(ap->ap_flags & ACPI_PCI_INFO_DEVICE) || 413 !(ap->ap_flags & ACPI_PCI_INFO_DEVICE) ||
411 (ap->ap_function == 0xffff)) 414 (ap->ap_function == 0xffff))
412 return 0; 415 return 0;
413 416
414 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);
415 418
416 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,
417 ap->ap_function); 420 ap->ap_function);
418 421
419 /* Check that the PCI device is present. */ 422 /* Check that the PCI device is present. */
420 id = pci_conf_read(sc->sc_pc, tag, PCI_ID_REG); 423 id = pci_conf_read(sc->sc_pc, tag, PCI_ID_REG);
421 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID || 424 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID ||
422 PCI_VENDOR(id) == 0) 425 PCI_VENDOR(id) == 0)
423 return 0; 426 return 0;
424 427
425 /* Check the class of the PCI device. */ 428 /* Check the class of the PCI device. */
426 class = pci_conf_read(sc->sc_pc, tag, PCI_CLASS_REG); 429 class = pci_conf_read(sc->sc_pc, tag, PCI_CLASS_REG);
427 if (PCI_CLASS(class) != PCI_CLASS_DISPLAY) 430 if (PCI_CLASS(class) != PCI_CLASS_DISPLAY)
428 return 0; 431 return 0;
429 432
430 /* We match if the display adapter is capable of something... */ 433 /* We match if the display adapter is capable of something... */
431 if (acpidisp_vga_capabilities(ad) == 0) 434 if (acpidisp_vga_capabilities(ad) == 0)
432 return 0; 435 return 0;
433 436
434 return 1; 437 return 1;
435} 438}
436 439
437static void 440static void
438acpidisp_vga_attach(device_t parent, device_t self, void *aux) 441acpidisp_vga_attach(device_t parent, device_t self, void *aux)
439{ 442{
440 struct acpidisp_vga_softc *asc = device_private(self); 443 struct acpidisp_vga_softc *asc = device_private(self);
441 struct acpi_attach_args *aa = aux; 444 struct acpi_attach_args *aa = aux;
442 struct acpi_devnode *ad = aa->aa_node; 445 struct acpi_devnode *ad = aa->aa_node;
443 446
444 aprint_naive(": ACPI Display Adapter\n"); 447 aprint_naive(": ACPI Display Adapter\n");
445 aprint_normal(": ACPI Display Adapter\n"); 448 aprint_normal(": ACPI Display Adapter\n");
446 449
447 asc->sc_dev = self; 450 asc->sc_dev = self;
448 asc->sc_node = ad; 451 asc->sc_node = ad;
449 asc->sc_log = NULL; 452 asc->sc_log = NULL;
450 mutex_init(&asc->sc_mtx, MUTEX_DEFAULT, IPL_NONE); 453 mutex_init(&asc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);
451 asc->sc_caps = acpidisp_vga_capabilities(ad); 454 asc->sc_caps = acpidisp_vga_capabilities(ad);
452 asc->sc_policy = acpidisp_default_bios_policy; 455 asc->sc_policy = acpidisp_default_bios_policy;
453 asc->sc_odinfo = NULL; 456 asc->sc_odinfo = NULL;
454 457
455 acpidisp_vga_print_capabilities(self, asc->sc_caps); 458 acpidisp_vga_print_capabilities(self, asc->sc_caps);
456 459
457 /* Enumerate connected output devices. */ 460 /* Enumerate connected output devices. */
458 asc->sc_odinfo = acpidisp_init_odinfo(asc); 461 asc->sc_odinfo = acpidisp_init_odinfo(asc);
459 462
460 /* Attach (via autoconf(9)) ACPI display output devices. */ 463 /* Attach (via autoconf(9)) ACPI display output devices. */
461 acpidisp_vga_scan_outdevs(asc); 464 acpidisp_vga_scan_outdevs(asc);
462 465
463 /* Bind the attached output devices to the enumerated ones. */ 466 /* Bind the attached output devices to the enumerated ones. */
464 if (asc->sc_odinfo != NULL) { 467 if (asc->sc_odinfo != NULL) {
465 acpidisp_vga_bind_outdevs(asc); 468 acpidisp_vga_bind_outdevs(asc);
466 acpidisp_print_odinfo(self, asc->sc_odinfo); 469 acpidisp_print_odinfo(self, asc->sc_odinfo);
467 } 470 }
468 471
469 /* Install ACPI notify handler. */ 472 /* Install ACPI notify handler. */
470 (void)acpi_register_notify(asc->sc_node, acpidisp_vga_notify_handler); 473 (void)acpi_register_notify(asc->sc_node, acpidisp_vga_notify_handler);
471 474
472 /* 475 /*
473 * Set BIOS automatic switch policy. 476 * Set BIOS automatic switch policy.
474 * 477 *
475 * Many laptops do not support output device switching with the methods 478 * Many laptops do not support output device switching with the methods
476 * specified in the ACPI extensions for display adapters. Therefore, we 479 * specified in the ACPI extensions for display adapters. Therefore, we
477 * 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
478 * to ``normal''. 481 * to ``normal''.
479 */ 482 */
480 asc->sc_policy.fmt.output = ACPI_DISP_POLICY_OUTPUT_AUTO; 483 asc->sc_policy.fmt.output = ACPI_DISP_POLICY_OUTPUT_AUTO;
481 asc->sc_policy.fmt.brightness = ACPI_DISP_POLICY_BRIGHTNESS_NORMAL; 484 asc->sc_policy.fmt.brightness = ACPI_DISP_POLICY_BRIGHTNESS_NORMAL;
482 if (acpidisp_set_policy(asc, asc->sc_policy.raw)) 485 if (acpidisp_set_policy(asc, asc->sc_policy.raw))
483 asc->sc_policy = acpidisp_default_bios_policy; 486 asc->sc_policy = acpidisp_default_bios_policy;
484 487
485 /* Setup sysctl. */ 488 /* Setup sysctl. */
486 acpidisp_vga_sysctl_setup(asc); 489 acpidisp_vga_sysctl_setup(asc);
487 490
488 /* Power management. */ 491 /* Power management. */
489 if (!pmf_device_register(self, NULL, acpidisp_vga_resume)) 492 if (!pmf_device_register(self, NULL, acpidisp_vga_resume))
490 aprint_error_dev(self, "couldn't establish power handler\n"); 493 aprint_error_dev(self, "couldn't establish power handler\n");
491} 494}
492 495
493static int 496static int
494acpidisp_vga_detach(device_t self, int flags) 497acpidisp_vga_detach(device_t self, int flags)
495{ 498{
496 struct acpidisp_vga_softc *asc = device_private(self); 499 struct acpidisp_vga_softc *asc = device_private(self);
497 struct acpidisp_odinfo *oi = asc->sc_odinfo; 500 struct acpidisp_odinfo *oi = asc->sc_odinfo;
498 int rc; 501 int rc;
499 502
500 pmf_device_deregister(self); 503 pmf_device_deregister(self);
501 504
502 if (asc->sc_log != NULL) 505 if (asc->sc_log != NULL)
503 sysctl_teardown(&asc->sc_log); 506 sysctl_teardown(&asc->sc_log);
504 507
505 asc->sc_policy = acpidisp_default_bios_policy; 508 asc->sc_policy = acpidisp_default_bios_policy;
506 acpidisp_set_policy(asc, asc->sc_policy.raw); 509 acpidisp_set_policy(asc, asc->sc_policy.raw);
507 510
508 acpi_deregister_notify(asc->sc_node); 511 acpi_deregister_notify(asc->sc_node);
509 512
510 if ((rc = config_detach_children(self, flags)) != 0) 513 if ((rc = config_detach_children(self, flags)) != 0)
511 return rc; 514 return rc;
512 515
513 if (oi != NULL) { 516 if (oi != NULL) {
514 kmem_free(oi->oi_dev, 517 kmem_free(oi->oi_dev,
515 oi->oi_dev_count * sizeof(*oi->oi_dev)); 518 oi->oi_dev_count * sizeof(*oi->oi_dev));
516 kmem_free(oi, sizeof(*oi)); 519 kmem_free(oi, sizeof(*oi));
517 } 520 }
518 521
519 mutex_destroy(&asc->sc_mtx); 522 mutex_destroy(&asc->sc_mtx);
520 523
521 return 0; 524 return 0;
522} 525}
523 526
524void 527void
525acpidisp_vga_childdetached(device_t self, device_t child) 528acpidisp_vga_childdetached(device_t self, device_t child)
526{ 529{
527 struct acpidisp_vga_softc *asc = device_private(self); 530 struct acpidisp_vga_softc *asc = device_private(self);
528 struct acpidisp_odinfo *oi = asc->sc_odinfo; 531 struct acpidisp_odinfo *oi = asc->sc_odinfo;
529 struct acpidisp_outdev *od; 532 struct acpidisp_outdev *od;
530 struct acpi_devnode *ad; 533 struct acpi_devnode *ad;
531 uint32_t i; 534 uint32_t i;
532 535
533 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) {
534 537
535 if (ad->ad_device == child) 538 if (ad->ad_device == child)
536 ad->ad_device = NULL; 539 ad->ad_device = NULL;
537 } 540 }
538 541
539 if (oi == NULL) 542 if (oi == NULL)
540 return; 543 return;
541 544
542 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++) {
543 if (od->od_device == child) 546 if (od->od_device == child)
544 od->od_device = NULL; 547 od->od_device = NULL;
545 } 548 }
546} 549}
547 550
548/* 551/*
549 * Attachment of acpiout under acpivga. 552 * Attachment of acpiout under acpivga.
550 */ 553 */
551 554
552static void 555static void
553acpidisp_vga_scan_outdevs(struct acpidisp_vga_softc *asc) 556acpidisp_vga_scan_outdevs(struct acpidisp_vga_softc *asc)
554{ 557{
555 struct acpidisp_acpivga_attach_args aa; 558 struct acpidisp_acpivga_attach_args aa;
556 struct acpi_devnode *ad; 559 struct acpi_devnode *ad;
557 560
558 /* 561 /*
559 * Display output devices are ACPI children of the display adapter. 562 * Display output devices are ACPI children of the display adapter.
560 */ 563 */
561 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) {
562 565
563 if (ad->ad_device != NULL) /* This should not happen. */ 566 if (ad->ad_device != NULL) /* This should not happen. */
564 continue; 567 continue;
565 568
566 aa.aa_node = ad; 569 aa.aa_node = ad;
567 aa.aa_mtx = &asc->sc_mtx; 570 aa.aa_mtx = &asc->sc_mtx;
568 571
569 ad->ad_device = config_found_ia(asc->sc_dev, 572 ad->ad_device = config_found_ia(asc->sc_dev,
570 "acpivga", &aa, acpidisp_acpivga_print); 573 "acpivga", &aa, acpidisp_acpivga_print);
571 } 574 }
572} 575}
573 576
574static int 577static int
575acpidisp_acpivga_print(void *aux, const char *pnp) 578acpidisp_acpivga_print(void *aux, const char *pnp)
576{ 579{
577 struct acpidisp_acpivga_attach_args *aa = aux; 580 struct acpidisp_acpivga_attach_args *aa = aux;
578 struct acpi_devnode *ad = aa->aa_node; 581 struct acpi_devnode *ad = aa->aa_node;
579 582
580 if (pnp) { 583 if (pnp) {
581 aprint_normal("%s at %s", ad->ad_name, pnp); 584 aprint_normal("%s at %s", ad->ad_name, pnp);
582 } else { 585 } else {
583 aprint_normal(" (%s", ad->ad_name); 586 aprint_normal(" (%s", ad->ad_name);
584 if (ad->ad_devinfo->Valid & ACPI_VALID_ADR) 587 if (ad->ad_devinfo->Valid & ACPI_VALID_ADR)
585 aprint_normal(", 0x%04"PRIx64, ad->ad_devinfo->Address); 588 aprint_normal(", 0x%04"PRIx64, ad->ad_devinfo->Address);
586 aprint_normal(")"); 589 aprint_normal(")");
587 } 590 }
588 591
589 return UNCONF; 592 return UNCONF;
590} 593}
591 594
592/* 595/*
593 * Autoconfiguration for the acpiout driver. 596 * Autoconfiguration for the acpiout driver.
594 */ 597 */
595 598
596static int 599static int
597acpidisp_out_match(device_t parent, cfdata_t match, void *aux) 600acpidisp_out_match(device_t parent, cfdata_t match, void *aux)
598{ 601{
599 struct acpidisp_acpivga_attach_args *aa = aux; 602 struct acpidisp_acpivga_attach_args *aa = aux;
600 struct acpi_devnode *ad = aa->aa_node; 603 struct acpi_devnode *ad = aa->aa_node;
601 604
602 if (ad->ad_type != ACPI_TYPE_DEVICE) 605 if (ad->ad_type != ACPI_TYPE_DEVICE)
603 return 0; 606 return 0;
604 607
605 /* 608 /*
606 * The method _ADR is required for display output 609 * The method _ADR is required for display output
607 * devices (ACPI 4.0a, Sec. B.6.1). 610 * devices (ACPI 4.0a, Sec. B.6.1).
608 */ 611 */
609 if (!(acpidisp_has_method(ad->ad_handle, "_ADR", ACPI_TYPE_INTEGER))) 612 if (!(acpidisp_has_method(ad->ad_handle, "_ADR", ACPI_TYPE_INTEGER)))
610 return 0; 613 return 0;
611 614
612 return 1; 615 return 1;
613} 616}
614 617
615static void 618static void
616acpidisp_out_attach(device_t parent, device_t self, void *aux) 619acpidisp_out_attach(device_t parent, device_t self, void *aux)
617{ 620{
618 struct acpidisp_out_softc *osc = device_private(self); 621 struct acpidisp_out_softc *osc = device_private(self);
619 struct acpidisp_acpivga_attach_args *aa = aux; 622 struct acpidisp_acpivga_attach_args *aa = aux;
620 struct acpi_devnode *ad = aa->aa_node; 623 struct acpi_devnode *ad = aa->aa_node;
621 struct acpidisp_brctl *bc; 624 struct acpidisp_brctl *bc;
622 625
623 aprint_naive("\n"); 626 aprint_naive("\n");
624 aprint_normal(": ACPI Display Output Device\n"); 627 aprint_normal(": ACPI Display Output Device\n");
625 628
626 osc->sc_dev = self; 629 osc->sc_dev = self;
627 osc->sc_node = ad; 630 osc->sc_node = ad;
628 osc->sc_log = NULL; 631 osc->sc_log = NULL;
629 osc->sc_mtx = aa->aa_mtx; 632 osc->sc_mtx = aa->aa_mtx;
630 osc->sc_caps = acpidisp_out_capabilities(ad); 633 osc->sc_caps = acpidisp_out_capabilities(ad);
631 osc->sc_brctl = NULL; 634 osc->sc_brctl = NULL;
632 635
633 acpidisp_out_print_capabilities(self, osc->sc_caps); 636 acpidisp_out_print_capabilities(self, osc->sc_caps);
634 637
635 osc->sc_brctl = acpidisp_init_brctl(osc); 638 osc->sc_brctl = acpidisp_init_brctl(osc);
636 bc = osc->sc_brctl; 639 bc = osc->sc_brctl;
637 if (bc != NULL) { 640 if (bc != NULL) {
638 bc->bc_current = bc->bc_level[bc->bc_level_count - 1]; 641 bc->bc_current = bc->bc_level[bc->bc_level_count - 1];
639 642
640 /* 643 /*
641 * Synchronize ACPI and driver brightness levels, and 644 * Synchronize ACPI and driver brightness levels, and
642 * check that brightness control is working. 645 * check that brightness control is working.
643 */ 646 */
644 (void)acpidisp_get_brightness(osc, &bc->bc_current); 647 (void)acpidisp_get_brightness(osc, &bc->bc_current);
645 if (acpidisp_set_brightness(osc, bc->bc_current)) { 648 if (acpidisp_set_brightness(osc, bc->bc_current)) {
646 kmem_free(bc->bc_level, 649 kmem_free(bc->bc_level,
647 bc->bc_level_count * sizeof(*bc->bc_level)); 650 bc->bc_level_count * sizeof(*bc->bc_level));
648 kmem_free(bc, sizeof(*bc)); 651 kmem_free(bc, sizeof(*bc));
649 osc->sc_brctl = NULL; 652 osc->sc_brctl = NULL;
650 } else { 653 } else {
651 acpidisp_print_brctl(self, osc->sc_brctl); 654 acpidisp_print_brctl(self, osc->sc_brctl);
652 } 655 }
653 } 656 }
654 657
655 /* Install ACPI notify handler. */ 658 /* Install ACPI notify handler. */
656 (void)acpi_register_notify(osc->sc_node, acpidisp_out_notify_handler); 659 (void)acpi_register_notify(osc->sc_node, acpidisp_out_notify_handler);
657 660
658 /* Setup sysctl. */ 661 /* Setup sysctl. */
659 acpidisp_out_sysctl_setup(osc); 662 acpidisp_out_sysctl_setup(osc);
660 663
661 /* Power management. */ 664 /* Power management. */
662 if (!pmf_device_register(self, acpidisp_out_suspend, 665 if (!pmf_device_register(self, acpidisp_out_suspend,
663 acpidisp_out_resume)) 666 acpidisp_out_resume))
664 aprint_error_dev(self, "couldn't establish power handler\n"); 667 aprint_error_dev(self, "couldn't establish power handler\n");
665} 668}
666 669
667static int 670static int
668acpidisp_out_detach(device_t self, int flags) 671acpidisp_out_detach(device_t self, int flags)
669{ 672{
670 struct acpidisp_out_softc *osc = device_private(self); 673 struct acpidisp_out_softc *osc = device_private(self);
671 struct acpidisp_brctl *bc = osc->sc_brctl; 674 struct acpidisp_brctl *bc = osc->sc_brctl;
672 675
673 pmf_device_deregister(self); 676 pmf_device_deregister(self);
674 677
675 if (osc->sc_log != NULL) 678 if (osc->sc_log != NULL)
676 sysctl_teardown(&osc->sc_log); 679 sysctl_teardown(&osc->sc_log);
677 680
678 acpi_deregister_notify(osc->sc_node); 681 acpi_deregister_notify(osc->sc_node);
679 682
680 if (bc != NULL) { 683 if (bc != NULL) {
681 kmem_free(bc->bc_level, 684 kmem_free(bc->bc_level,
682 bc->bc_level_count * sizeof(*bc->bc_level)); 685 bc->bc_level_count * sizeof(*bc->bc_level));
683 kmem_free(bc, sizeof(*bc)); 686 kmem_free(bc, sizeof(*bc));
684 } 687 }
685 688
686 return 0; 689 return 0;
687} 690}
688 691
689/* 692/*
690 * Power management. 693 * Power management.
691 */ 694 */
692 695
693static bool 696static bool
694acpidisp_vga_resume(device_t self, const pmf_qual_t *qual) 697acpidisp_vga_resume(device_t self, const pmf_qual_t *qual)
695{ 698{
696 struct acpidisp_vga_softc *asc = device_private(self); 699 struct acpidisp_vga_softc *asc = device_private(self);
697 700
698 mutex_enter(&asc->sc_mtx); 701 mutex_enter(&asc->sc_mtx);
699 (void)acpidisp_set_policy(asc, asc->sc_policy.raw); 702 (void)acpidisp_set_policy(asc, asc->sc_policy.raw);
700 mutex_exit(&asc->sc_mtx); 703 mutex_exit(&asc->sc_mtx);
701 704
702 return true; 705 return true;
703} 706}
704 707
705static bool 708static bool
706acpidisp_out_suspend(device_t self, const pmf_qual_t *qual) 709acpidisp_out_suspend(device_t self, const pmf_qual_t *qual)
707{ 710{
708 struct acpidisp_out_softc *osc = device_private(self); 711 struct acpidisp_out_softc *osc = device_private(self);
709 712
710 mutex_enter(osc->sc_mtx); 713 mutex_enter(osc->sc_mtx);
711 if (osc->sc_brctl != NULL) 714 if (osc->sc_brctl != NULL)
712 (void)acpidisp_get_brightness(osc, &osc->sc_brctl->bc_current); 715 (void)acpidisp_get_brightness(osc, &osc->sc_brctl->bc_current);
713 mutex_exit(osc->sc_mtx); 716 mutex_exit(osc->sc_mtx);
714 717
715 return true; 718 return true;
716} 719}
717 720
718static bool 721static bool
719acpidisp_out_resume(device_t self, const pmf_qual_t *qual) 722acpidisp_out_resume(device_t self, const pmf_qual_t *qual)
720{ 723{
721 struct acpidisp_out_softc *osc = device_private(self); 724 struct acpidisp_out_softc *osc = device_private(self);
722 725
723 mutex_enter(osc->sc_mtx); 726 mutex_enter(osc->sc_mtx);
724 if (osc->sc_brctl != NULL) 727 if (osc->sc_brctl != NULL)
725 (void)acpidisp_set_brightness(osc, osc->sc_brctl->bc_current); 728 (void)acpidisp_set_brightness(osc, osc->sc_brctl->bc_current);
726 mutex_exit(osc->sc_mtx); 729 mutex_exit(osc->sc_mtx);
727 730
728 return true; 731 return true;
729} 732}
730 733
731/* 734/*
732 * Capabilities (available methods). 735 * Capabilities (available methods).
733 */ 736 */
734 737
735static uint16_t 738static uint16_t
736acpidisp_vga_capabilities(const struct acpi_devnode *ad) 739acpidisp_vga_capabilities(const struct acpi_devnode *ad)
737{ 740{
738 uint16_t cap; 741 uint16_t cap;
739 742
740 cap = 0; 743 cap = 0;
741 744
742 if (acpidisp_has_method(ad->ad_handle, "_DOS", ACPI_TYPE_METHOD)) 745 if (acpidisp_has_method(ad->ad_handle, "_DOS", ACPI_TYPE_METHOD))
743 cap |= ACPI_DISP_VGA_CAP__DOS; 746 cap |= ACPI_DISP_VGA_CAP__DOS;
744 747
745 if (acpidisp_has_method(ad->ad_handle, "_DOD", ACPI_TYPE_PACKAGE)) 748 if (acpidisp_has_method(ad->ad_handle, "_DOD", ACPI_TYPE_PACKAGE))
746 cap |= ACPI_DISP_VGA_CAP__DOD; 749 cap |= ACPI_DISP_VGA_CAP__DOD;
747 750
748 if (acpidisp_has_method(ad->ad_handle, "_ROM", ACPI_TYPE_BUFFER)) 751 if (acpidisp_has_method(ad->ad_handle, "_ROM", ACPI_TYPE_BUFFER))
749 cap |= ACPI_DISP_VGA_CAP__ROM; 752 cap |= ACPI_DISP_VGA_CAP__ROM;
750 753
751 if (acpidisp_has_method(ad->ad_handle, "_GPD", ACPI_TYPE_INTEGER)) 754 if (acpidisp_has_method(ad->ad_handle, "_GPD", ACPI_TYPE_INTEGER))
752 cap |= ACPI_DISP_VGA_CAP__GPD; 755 cap |= ACPI_DISP_VGA_CAP__GPD;
753 756
754 if (acpidisp_has_method(ad->ad_handle, "_SPD", ACPI_TYPE_METHOD)) 757 if (acpidisp_has_method(ad->ad_handle, "_SPD", ACPI_TYPE_METHOD))
755 cap |= ACPI_DISP_VGA_CAP__SPD; 758 cap |= ACPI_DISP_VGA_CAP__SPD;
756 759
757 if (acpidisp_has_method(ad->ad_handle, "_VPO", ACPI_TYPE_INTEGER)) 760 if (acpidisp_has_method(ad->ad_handle, "_VPO", ACPI_TYPE_INTEGER))
758 cap |= ACPI_DISP_VGA_CAP__VPO; 761 cap |= ACPI_DISP_VGA_CAP__VPO;
759 762
760 return cap; 763 return cap;
761} 764}
762 765
763static void 766static void
764acpidisp_vga_print_capabilities(device_t self, uint16_t cap) 767acpidisp_vga_print_capabilities(device_t self, uint16_t cap)
765{ 768{
766 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",
767 (cap & ACPI_DISP_VGA_CAP__DOS) ? " _DOS" : "", 770 (cap & ACPI_DISP_VGA_CAP__DOS) ? " _DOS" : "",
768 (cap & ACPI_DISP_VGA_CAP__DOD) ? " _DOD" : "", 771 (cap & ACPI_DISP_VGA_CAP__DOD) ? " _DOD" : "",
769 (cap & ACPI_DISP_VGA_CAP__ROM) ? " _ROM" : "", 772 (cap & ACPI_DISP_VGA_CAP__ROM) ? " _ROM" : "",
770 (cap & ACPI_DISP_VGA_CAP__GPD) ? " _GPD" : "", 773 (cap & ACPI_DISP_VGA_CAP__GPD) ? " _GPD" : "",
771 (cap & ACPI_DISP_VGA_CAP__SPD) ? " _SPD" : "", 774 (cap & ACPI_DISP_VGA_CAP__SPD) ? " _SPD" : "",
772 (cap & ACPI_DISP_VGA_CAP__VPO) ? " _VPO" : ""); 775 (cap & ACPI_DISP_VGA_CAP__VPO) ? " _VPO" : "");
773} 776}
774 777
775static uint16_t 778static uint16_t
776acpidisp_out_capabilities(const struct acpi_devnode *ad) 779acpidisp_out_capabilities(const struct acpi_devnode *ad)
777{ 780{
778 uint16_t cap; 781 uint16_t cap;
779 782
780 cap = 0; 783 cap = 0;
781 784
782 if (acpidisp_has_method(ad->ad_handle, "_BCL", ACPI_TYPE_PACKAGE)) 785 if (acpidisp_has_method(ad->ad_handle, "_BCL", ACPI_TYPE_PACKAGE))
783 cap |= ACPI_DISP_OUT_CAP__BCL; 786 cap |= ACPI_DISP_OUT_CAP__BCL;
784 787
785 if (acpidisp_has_method(ad->ad_handle, "_BCM", ACPI_TYPE_METHOD)) 788 if (acpidisp_has_method(ad->ad_handle, "_BCM", ACPI_TYPE_METHOD))
786 cap |= ACPI_DISP_OUT_CAP__BCM; 789 cap |= ACPI_DISP_OUT_CAP__BCM;
787 790
788 if (acpidisp_has_method(ad->ad_handle, "_BQC", ACPI_TYPE_INTEGER)) 791 if (acpidisp_has_method(ad->ad_handle, "_BQC", ACPI_TYPE_INTEGER))
789 cap |= ACPI_DISP_OUT_CAP__BQC; 792 cap |= ACPI_DISP_OUT_CAP__BQC;
790 793
791 if (acpidisp_has_method(ad->ad_handle, "_DDC", ACPI_TYPE_METHOD)) 794 if (acpidisp_has_method(ad->ad_handle, "_DDC", ACPI_TYPE_METHOD))
792 cap |= ACPI_DISP_OUT_CAP__DDC; 795 cap |= ACPI_DISP_OUT_CAP__DDC;
793 796
794 if (acpidisp_has_method(ad->ad_handle, "_DCS", ACPI_TYPE_INTEGER)) 797 if (acpidisp_has_method(ad->ad_handle, "_DCS", ACPI_TYPE_INTEGER))
795 cap |= ACPI_DISP_OUT_CAP__DCS; 798 cap |= ACPI_DISP_OUT_CAP__DCS;
796 799
797 if (acpidisp_has_method(ad->ad_handle, "_DGS", ACPI_TYPE_INTEGER)) 800 if (acpidisp_has_method(ad->ad_handle, "_DGS", ACPI_TYPE_INTEGER))
798 cap |= ACPI_DISP_OUT_CAP__DGS; 801 cap |= ACPI_DISP_OUT_CAP__DGS;
799 802
800 if (acpidisp_has_method(ad->ad_handle, "_DSS", ACPI_TYPE_METHOD)) 803 if (acpidisp_has_method(ad->ad_handle, "_DSS", ACPI_TYPE_METHOD))
801 cap |= ACPI_DISP_OUT_CAP__DSS; 804 cap |= ACPI_DISP_OUT_CAP__DSS;
802 805
803 return cap; 806 return cap;
804} 807}
805 808
806static void 809static void
807acpidisp_out_print_capabilities(device_t self, uint16_t cap) 810acpidisp_out_print_capabilities(device_t self, uint16_t cap)
808{ 811{
809 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",
810 (cap & ACPI_DISP_OUT_CAP__BCL) ? " _BCL" : "", 813 (cap & ACPI_DISP_OUT_CAP__BCL) ? " _BCL" : "",
811 (cap & ACPI_DISP_OUT_CAP__BCM) ? " _BCM" : "", 814 (cap & ACPI_DISP_OUT_CAP__BCM) ? " _BCM" : "",
812 (cap & ACPI_DISP_OUT_CAP__BQC) ? " _BQC" : "", 815 (cap & ACPI_DISP_OUT_CAP__BQC) ? " _BQC" : "",
813 (cap & ACPI_DISP_OUT_CAP__DDC) ? " _DDC" : "", 816 (cap & ACPI_DISP_OUT_CAP__DDC) ? " _DDC" : "",
814 (cap & ACPI_DISP_OUT_CAP__DCS) ? " _DCS" : "", 817 (cap & ACPI_DISP_OUT_CAP__DCS) ? " _DCS" : "",
815 (cap & ACPI_DISP_OUT_CAP__DGS) ? " _DGS" : "", 818 (cap & ACPI_DISP_OUT_CAP__DGS) ? " _DGS" : "",
816 (cap & ACPI_DISP_OUT_CAP__DSS) ? " _DSS" : ""); 819 (cap & ACPI_DISP_OUT_CAP__DSS) ? " _DSS" : "");
817} 820}
818 821
819/* 822/*
820 * ACPI notify handlers. 823 * ACPI notify handlers.
821 */ 824 */
822 825
823static void 826static void
824acpidisp_vga_notify_handler(ACPI_HANDLE handle, uint32_t notify, 827acpidisp_vga_notify_handler(ACPI_HANDLE handle, uint32_t notify,
825 void *context) 828 void *context)
826{ 829{
827 struct acpidisp_vga_softc *asc = device_private(context); 830 struct acpidisp_vga_softc *asc = device_private(context);
828 ACPI_OSD_EXEC_CALLBACK callback; 831 ACPI_OSD_EXEC_CALLBACK callback;
829 832
830 callback = NULL; 833 callback = NULL;
831 834
832 switch (notify) { 835 switch (notify) {
833 case ACPI_NOTIFY_CycleOutputDevice: 836 case ACPI_NOTIFY_CycleOutputDevice:
834 callback = acpidisp_vga_cycle_output_device_callback; 837 callback = acpidisp_vga_cycle_output_device_callback;
835 break; 838 break;
836 case ACPI_NOTIFY_OutputDeviceStatusChange: 839 case ACPI_NOTIFY_OutputDeviceStatusChange:
837 callback = acpidisp_vga_output_device_change_callback; 840 callback = acpidisp_vga_output_device_change_callback;
838 break; 841 break;
839 case ACPI_NOTIFY_CycleDisplayOutputHotkeyPressed: 842 case ACPI_NOTIFY_CycleDisplayOutputHotkeyPressed:
840 case ACPI_NOTIFY_NextDisplayOutputHotkeyPressed: 843 case ACPI_NOTIFY_NextDisplayOutputHotkeyPressed:
841 case ACPI_NOTIFY_PreviousDisplayOutputHotkeyPressed: 844 case ACPI_NOTIFY_PreviousDisplayOutputHotkeyPressed:
842 aprint_debug_dev(asc->sc_dev, 845 aprint_debug_dev(asc->sc_dev,
843 "unhandled notify: 0x%"PRIx32"\n", notify); 846 "unhandled notify: 0x%"PRIx32"\n", notify);
844 return; 847 return;
845 default: 848 default:
846 aprint_error_dev(asc->sc_dev, 849 aprint_error_dev(asc->sc_dev,
847 "unknown notify: 0x%"PRIx32"\n", notify); 850 "unknown notify: 0x%"PRIx32"\n", notify);
848 return; 851 return;
849 } 852 }
850 853
851 KASSERT(callback != NULL); 854 KASSERT(callback != NULL);
852 (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, callback, asc); 855 (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, callback, asc);
853} 856}
854 857
855static void 858static void
856acpidisp_out_notify_handler(ACPI_HANDLE handle, uint32_t notify, 859acpidisp_out_notify_handler(ACPI_HANDLE handle, uint32_t notify,
857 void *context) 860 void *context)
858{ 861{
859 struct acpidisp_out_softc *osc = device_private(context); 862 struct acpidisp_out_softc *osc = device_private(context);
860 ACPI_OSD_EXEC_CALLBACK callback; 863 ACPI_OSD_EXEC_CALLBACK callback;
861 864
862 callback = NULL; 865 callback = NULL;
863 866
864 switch (notify) { 867 switch (notify) {
865 case ACPI_NOTIFY_IncreaseBrightness: 868 case ACPI_NOTIFY_IncreaseBrightness:
866 callback = acpidisp_out_increase_brightness_callback; 869 callback = acpidisp_out_increase_brightness_callback;
867 break; 870 break;
868 case ACPI_NOTIFY_DecreaseBrightness: 871 case ACPI_NOTIFY_DecreaseBrightness:
869 callback = acpidisp_out_decrease_brightness_callback; 872 callback = acpidisp_out_decrease_brightness_callback;
870 break; 873 break;
871 case ACPI_NOTIFY_CycleBrightness: 874 case ACPI_NOTIFY_CycleBrightness:
872 callback = acpidisp_out_cycle_brightness_callback; 875 callback = acpidisp_out_cycle_brightness_callback;
873 break; 876 break;
874 case ACPI_NOTIFY_ZeroBrightness: 877 case ACPI_NOTIFY_ZeroBrightness:
875 callback = acpidisp_out_zero_brightness_callback; 878 callback = acpidisp_out_zero_brightness_callback;
876 break; 879 break;
877 case ACPI_NOTIFY_DisplayDeviceOff: 880 case ACPI_NOTIFY_DisplayDeviceOff:
878 aprint_debug_dev(osc->sc_dev, 881 aprint_debug_dev(osc->sc_dev,
879 "unhandled notify: 0x%"PRIx32"\n", notify); 882 "unhandled notify: 0x%"PRIx32"\n", notify);
880 return; 883 return;
881 default: 884 default:
882 aprint_error_dev(osc->sc_dev, 885 aprint_error_dev(osc->sc_dev,
883 "unknown notify: 0x%"PRIx32"\n", notify); 886 "unknown notify: 0x%"PRIx32"\n", notify);
884 return; 887 return;
885 } 888 }
886 889
887 KASSERT(callback != NULL); 890 KASSERT(callback != NULL);
888 (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, callback, osc); 891 (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, callback, osc);
889} 892}
890 893
891/* 894/*
892 * ACPI notify callbacks. 895 * ACPI notify callbacks.
893 * 896 *
894 * 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
895 * guaranteed since: 898 * guaranteed since:
896 * 899 *
897 * (a) this field is only used in ACPI display notify callbacks, 900 * (a) this field is only used in ACPI display notify callbacks,
898 * (b) ACPI display notify callbacks are scheduled with AcpiOsExecute, 901 * (b) ACPI display notify callbacks are scheduled with AcpiOsExecute,
899 * (c) callbacks scheduled with AcpiOsExecute are executed sequentially. 902 * (c) callbacks scheduled with AcpiOsExecute are executed sequentially.
900 */ 903 */
901 904
902static void 905static void
903acpidisp_vga_cycle_output_device_callback(void *arg) 906acpidisp_vga_cycle_output_device_callback(void *arg)
904{ 907{
905 struct acpidisp_vga_softc *asc = arg; 908 struct acpidisp_vga_softc *asc = arg;
906 struct acpidisp_odinfo *oi = asc->sc_odinfo; 909 struct acpidisp_odinfo *oi = asc->sc_odinfo;
907 struct acpidisp_outdev *od; 910 struct acpidisp_outdev *od;
908 struct acpidisp_out_softc *osc, *last_osc; 911 struct acpidisp_out_softc *osc, *last_osc;
909 acpidisp_od_state_t state, last_state; 912 acpidisp_od_state_t state, last_state;
910 acpidisp_od_status_t status; 913 acpidisp_od_status_t status;
911 uint32_t i; 914 uint32_t i;
912 915
913 if (oi == NULL) 916 if (oi == NULL)
914 return; 917 return;
915 918
916 /* Mutual exclusion with callbacks of connected output devices. */ 919 /* Mutual exclusion with callbacks of connected output devices. */
917 mutex_enter(&asc->sc_mtx); 920 mutex_enter(&asc->sc_mtx);
918 921
919 last_osc = NULL; 922 last_osc = NULL;
920 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) { 923 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) {
921 if (od->od_device == NULL) 924 if (od->od_device == NULL)
922 continue; 925 continue;
923 osc = device_private(od->od_device); 926 osc = device_private(od->od_device);
924 927
925 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DSS)) 928 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DSS))
926 continue; 929 continue;
927 if (acpidisp_get_state(osc, &state.raw)) 930 if (acpidisp_get_state(osc, &state.raw))
928 continue; 931 continue;
929 932
930 if (acpidisp_get_status(osc, &status.raw)) { 933 if (acpidisp_get_status(osc, &status.raw)) {
931 state.fmt.no_switch = 0; 934 state.fmt.no_switch = 0;
932 } else { 935 } else {
933 state.fmt.active &= status.fmt.ready; 936 state.fmt.active &= status.fmt.ready;
934 937
935 if (state.fmt.active == status.fmt.activated) 938 if (state.fmt.active == status.fmt.activated)
936 state.fmt.no_switch = 1; 939 state.fmt.no_switch = 1;
937 else 940 else
938 state.fmt.no_switch = 0; 941 state.fmt.no_switch = 0;
939 } 942 }
940 943
941 state.fmt.commit = 0; 944 state.fmt.commit = 0;
942 945
943 if (last_osc != NULL) 946 if (last_osc != NULL)
944 (void)acpidisp_set_state(last_osc, last_state.raw); 947 (void)acpidisp_set_state(last_osc, last_state.raw);
945 948
946 last_osc = osc; 949 last_osc = osc;
947 last_state = state; 950 last_state = state;
948 } 951 }
949 952
950 if (last_osc != NULL) { 953 if (last_osc != NULL) {
951 last_state.fmt.commit = 1; 954 last_state.fmt.commit = 1;
952 (void)acpidisp_set_state(last_osc, last_state.raw); 955 (void)acpidisp_set_state(last_osc, last_state.raw);
953 } 956 }
954 957
955 mutex_exit(&asc->sc_mtx); 958 mutex_exit(&asc->sc_mtx);
956} 959}
957 960
958static void 961static void
959acpidisp_vga_output_device_change_callback(void *arg) 962acpidisp_vga_output_device_change_callback(void *arg)
960{ 963{
961 struct acpidisp_vga_softc *asc = arg; 964 struct acpidisp_vga_softc *asc = arg;
962 struct acpidisp_odinfo *oi = asc->sc_odinfo; 965 struct acpidisp_odinfo *oi = asc->sc_odinfo;
963 bool switch_outputs; 966 bool switch_outputs;
964 967
965 if (oi != NULL) { 968 if (oi != NULL) {
966 kmem_free(oi->oi_dev, 969 kmem_free(oi->oi_dev,
967 oi->oi_dev_count * sizeof(*oi->oi_dev)); 970 oi->oi_dev_count * sizeof(*oi->oi_dev));
968 kmem_free(oi, sizeof(*oi)); 971 kmem_free(oi, sizeof(*oi));
969 } 972 }
970 973
971 asc->sc_odinfo = acpidisp_init_odinfo(asc); 974 asc->sc_odinfo = acpidisp_init_odinfo(asc);
972 if (asc->sc_odinfo != NULL) { 975 if (asc->sc_odinfo != NULL) {
973 acpidisp_vga_bind_outdevs(asc); 976 acpidisp_vga_bind_outdevs(asc);
974 acpidisp_print_odinfo(asc->sc_dev, asc->sc_odinfo); 977 acpidisp_print_odinfo(asc->sc_dev, asc->sc_odinfo);
975 } 978 }
976 979
977 /* Perform display output switch if needed. */ 980 /* Perform display output switch if needed. */
978 mutex_enter(&asc->sc_mtx); 981 mutex_enter(&asc->sc_mtx);
979 switch_outputs = 982 switch_outputs =
980 (asc->sc_policy.fmt.output == ACPI_DISP_POLICY_OUTPUT_NORMAL); 983 (asc->sc_policy.fmt.output == ACPI_DISP_POLICY_OUTPUT_NORMAL);
981 mutex_exit(&asc->sc_mtx); 984 mutex_exit(&asc->sc_mtx);
982 if (switch_outputs) 985 if (switch_outputs)
983 acpidisp_vga_cycle_output_device_callback(arg); 986 acpidisp_vga_cycle_output_device_callback(arg);
984} 987}
985 988
986static void 989static void
987acpidisp_out_increase_brightness_callback(void *arg) 990acpidisp_out_increase_brightness_callback(void *arg)
988{ 991{
989 struct acpidisp_out_softc *osc = arg; 992 struct acpidisp_out_softc *osc = arg;
990 struct acpidisp_brctl *bc = osc->sc_brctl; 993 struct acpidisp_brctl *bc = osc->sc_brctl;
991 uint8_t lo, up; 994 uint8_t lo, up;
992 995
993 if (bc == NULL) { 996 if (bc == NULL) {
994 /* Fallback to pmf(9). */ 997 /* Fallback to pmf(9). */
995 pmf_event_inject(NULL, PMFE_DISPLAY_BRIGHTNESS_UP); 998 pmf_event_inject(NULL, PMFE_DISPLAY_BRIGHTNESS_UP);
996 return; 999 return;
997 } 1000 }
998 1001
999 mutex_enter(osc->sc_mtx); 1002 mutex_enter(osc->sc_mtx);
1000 1003
1001 (void)acpidisp_get_brightness(osc, &bc->bc_current); 1004 (void)acpidisp_get_brightness(osc, &bc->bc_current);
1002 1005
1003 acpidisp_array_search(bc->bc_level, bc->bc_level_count, 1006 acpidisp_array_search(bc->bc_level, bc->bc_level_count,
1004 bc->bc_current + ACPI_DISP_BRCTL_STEP, &lo, &up); 1007 bc->bc_current + ACPI_DISP_BRCTL_STEP, &lo, &up);
1005 1008
1006 bc->bc_current = up; 1009 bc->bc_current = up;
1007 (void)acpidisp_set_brightness(osc, bc->bc_current); 1010 (void)acpidisp_set_brightness(osc, bc->bc_current);
1008 1011
1009 mutex_exit(osc->sc_mtx); 1012 mutex_exit(osc->sc_mtx);
1010} 1013}
1011 1014
1012static void 1015static void
1013acpidisp_out_decrease_brightness_callback(void *arg) 1016acpidisp_out_decrease_brightness_callback(void *arg)
1014{ 1017{
1015 struct acpidisp_out_softc *osc = arg; 1018 struct acpidisp_out_softc *osc = arg;
1016 struct acpidisp_brctl *bc = osc->sc_brctl; 1019 struct acpidisp_brctl *bc = osc->sc_brctl;
1017 uint8_t lo, up; 1020 uint8_t lo, up;
1018 1021
1019 if (bc == NULL) { 1022 if (bc == NULL) {
1020 /* Fallback to pmf(9). */ 1023 /* Fallback to pmf(9). */
1021 pmf_event_inject(NULL, PMFE_DISPLAY_BRIGHTNESS_DOWN); 1024 pmf_event_inject(NULL, PMFE_DISPLAY_BRIGHTNESS_DOWN);
1022 return; 1025 return;
1023 } 1026 }
1024 1027
1025 mutex_enter(osc->sc_mtx); 1028 mutex_enter(osc->sc_mtx);
1026 1029
1027 (void)acpidisp_get_brightness(osc, &bc->bc_current); 1030 (void)acpidisp_get_brightness(osc, &bc->bc_current);
1028 1031
1029 acpidisp_array_search(bc->bc_level, bc->bc_level_count, 1032 acpidisp_array_search(bc->bc_level, bc->bc_level_count,
1030 bc->bc_current - ACPI_DISP_BRCTL_STEP, &lo, &up); 1033 bc->bc_current - ACPI_DISP_BRCTL_STEP, &lo, &up);
1031 1034
1032 bc->bc_current = lo; 1035 bc->bc_current = lo;
1033 (void)acpidisp_set_brightness(osc, bc->bc_current); 1036 (void)acpidisp_set_brightness(osc, bc->bc_current);
1034 1037
1035 mutex_exit(osc->sc_mtx); 1038 mutex_exit(osc->sc_mtx);
1036} 1039}
1037 1040
1038static void 1041static void
1039acpidisp_out_cycle_brightness_callback(void *arg) 1042acpidisp_out_cycle_brightness_callback(void *arg)
1040{ 1043{
1041 struct acpidisp_out_softc *osc = arg; 1044 struct acpidisp_out_softc *osc = arg;
1042 struct acpidisp_brctl *bc = osc->sc_brctl; 1045 struct acpidisp_brctl *bc = osc->sc_brctl;
1043 uint8_t lo, up; 1046 uint8_t lo, up;
1044 1047
1045 if (bc == NULL) { 1048 if (bc == NULL) {
1046 /* No fallback. */ 1049 /* No fallback. */
1047 return; 1050 return;
1048 } 1051 }
1049 1052
1050 mutex_enter(osc->sc_mtx); 1053 mutex_enter(osc->sc_mtx);
1051 1054
1052 (void)acpidisp_get_brightness(osc, &bc->bc_current); 1055 (void)acpidisp_get_brightness(osc, &bc->bc_current);
1053 1056
1054 if (bc->bc_current >= bc->bc_level[bc->bc_level_count - 1]) { 1057 if (bc->bc_current >= bc->bc_level[bc->bc_level_count - 1]) {
1055 bc->bc_current = bc->bc_level[0]; 1058 bc->bc_current = bc->bc_level[0];
1056 } else { 1059 } else {
1057 acpidisp_array_search(bc->bc_level, bc->bc_level_count, 1060 acpidisp_array_search(bc->bc_level, bc->bc_level_count,
1058 bc->bc_current + 1, &lo, &up); 1061 bc->bc_current + 1, &lo, &up);
1059 bc->bc_current = up; 1062 bc->bc_current = up;
1060 } 1063 }
1061 1064
1062 (void)acpidisp_set_brightness(osc, bc->bc_current); 1065 (void)acpidisp_set_brightness(osc, bc->bc_current);
1063 1066
1064 mutex_exit(osc->sc_mtx); 1067 mutex_exit(osc->sc_mtx);
1065} 1068}
1066 1069
1067static void 1070static void
1068acpidisp_out_zero_brightness_callback(void *arg) 1071acpidisp_out_zero_brightness_callback(void *arg)
1069{ 1072{
1070 struct acpidisp_out_softc *osc = arg; 1073 struct acpidisp_out_softc *osc = arg;
1071 struct acpidisp_brctl *bc = osc->sc_brctl; 1074 struct acpidisp_brctl *bc = osc->sc_brctl;
1072 1075
1073 if (bc == NULL) { 1076 if (bc == NULL) {
1074 /* Fallback to pmf(9). */ 1077 /* Fallback to pmf(9). */
1075 /* XXX Is this the intended meaning of PMFE_DISPLAY_REDUCED? */ 1078 /* XXX Is this the intended meaning of PMFE_DISPLAY_REDUCED? */
1076 pmf_event_inject(NULL, PMFE_DISPLAY_REDUCED); 1079 pmf_event_inject(NULL, PMFE_DISPLAY_REDUCED);
1077 return; 1080 return;
1078 } 1081 }
1079 1082
1080 mutex_enter(osc->sc_mtx); 1083 mutex_enter(osc->sc_mtx);
1081 1084
1082 bc->bc_current = bc->bc_level[0]; 1085 bc->bc_current = bc->bc_level[0];
1083 (void)acpidisp_set_brightness(osc, bc->bc_current); 1086 (void)acpidisp_set_brightness(osc, bc->bc_current);
1084 1087
1085 mutex_exit(osc->sc_mtx); 1088 mutex_exit(osc->sc_mtx);
1086} 1089}
1087 1090
1088/* 1091/*
1089 * Sysctl setup. 1092 * Sysctl setup.
1090 */ 1093 */
1091 1094
1092static void 1095static void
1093acpidisp_vga_sysctl_setup(struct acpidisp_vga_softc *asc) 1096acpidisp_vga_sysctl_setup(struct acpidisp_vga_softc *asc)
1094{ 1097{
1095 const struct sysctlnode *rnode; 1098 const struct sysctlnode *rnode;
1096 1099
1097 if (asc->sc_caps & ACPI_DISP_VGA_CAP__DOS) { 1100 if (asc->sc_caps & ACPI_DISP_VGA_CAP__DOS) {
1098 if ((sysctl_createv(&asc->sc_log, 0, NULL, &rnode, 1101 if ((sysctl_createv(&asc->sc_log, 0, NULL, &rnode,
1099 0, CTLTYPE_NODE, "hw", NULL, 1102 0, CTLTYPE_NODE, "hw", NULL,
1100 NULL, 0, NULL, 0, 1103 NULL, 0, NULL, 0,
1101 CTL_HW, CTL_EOL)) != 0) 1104 CTL_HW, CTL_EOL)) != 0)
1102 goto fail; 1105 goto fail;
1103 1106
1104 if ((sysctl_createv(&asc->sc_log, 0, &rnode, &rnode, 1107 if ((sysctl_createv(&asc->sc_log, 0, &rnode, &rnode,
1105 0, CTLTYPE_NODE, "acpi", NULL, 1108 0, CTLTYPE_NODE, "acpi", NULL,
1106 NULL, 0, NULL, 0, 1109 NULL, 0, NULL, 0,
1107 CTL_CREATE, CTL_EOL)) != 0) 1110 CTL_CREATE, CTL_EOL)) != 0)
1108 goto fail; 1111 goto fail;
1109 1112
1110 if ((sysctl_createv(&asc->sc_log, 0, &rnode, &rnode, 1113 if ((sysctl_createv(&asc->sc_log, 0, &rnode, &rnode,
1111 0, CTLTYPE_NODE, device_xname(asc->sc_dev), 1114 0, CTLTYPE_NODE, device_xname(asc->sc_dev),
1112 SYSCTL_DESCR("ACPI display adapter controls"), 1115 SYSCTL_DESCR("ACPI display adapter controls"),
1113 NULL, 0, NULL, 0, 1116 NULL, 0, NULL, 0,
1114 CTL_CREATE, CTL_EOL)) != 0) 1117 CTL_CREATE, CTL_EOL)) != 0)
1115 goto fail; 1118 goto fail;
1116 1119
 1120#ifdef ACPI_DEBUG
1117 (void)sysctl_createv(&asc->sc_log, 0, &rnode, NULL, 1121 (void)sysctl_createv(&asc->sc_log, 0, &rnode, NULL,
1118 CTLFLAG_READWRITE | CTLFLAG_HEX, CTLTYPE_INT, "policy", 1122 CTLFLAG_READWRITE | CTLFLAG_HEX, CTLTYPE_INT, "bios_policy",
1119 SYSCTL_DESCR("Current BIOS switch policy"), 1123 SYSCTL_DESCR("Current BIOS switch policies (debug)"),
1120 acpidisp_vga_sysctl_policy, 0, asc, 0, 1124 acpidisp_vga_sysctl_policy, 0, asc, 0,
1121 CTL_CREATE, CTL_EOL); 1125 CTL_CREATE, CTL_EOL);
 1126#endif
 1127
 1128 (void)sysctl_createv(&asc->sc_log, 0, &rnode, NULL,
 1129 CTLFLAG_READWRITE, CTLTYPE_BOOL, "bios_switch",
 1130 SYSCTL_DESCR("Current BIOS output switching policy"),
 1131 acpidisp_vga_sysctl_policy_output, 0, asc, 0,
 1132 CTL_CREATE, CTL_EOL);
1122 } 1133 }
1123 1134
1124 return; 1135 return;
1125 1136
1126 fail: 1137 fail:
1127 aprint_error_dev(asc->sc_dev, "couldn't add sysctl nodes\n"); 1138 aprint_error_dev(asc->sc_dev, "couldn't add sysctl nodes\n");
1128} 1139}
1129 1140
1130static void 1141static void
1131acpidisp_out_sysctl_setup(struct acpidisp_out_softc *osc) 1142acpidisp_out_sysctl_setup(struct acpidisp_out_softc *osc)
1132{ 1143{
1133 const struct sysctlnode *rnode; 1144 const struct sysctlnode *rnode;
1134 1145
1135#ifdef ACPI_DISP_SWITCH_SYSCTLS 1146#ifdef ACPI_DISP_SWITCH_SYSCTLS
1136 if ((osc->sc_brctl != NULL) || 1147 if ((osc->sc_brctl != NULL) ||
1137 (osc->sc_caps & ACPI_DISP_OUT_CAP__DCS) || 1148 (osc->sc_caps & ACPI_DISP_OUT_CAP__DCS) ||
1138 (osc->sc_caps & ACPI_DISP_OUT_CAP__DGS)) { 1149 (osc->sc_caps & ACPI_DISP_OUT_CAP__DGS)) {
1139#else 1150#else
1140 if (osc->sc_brctl != NULL) { 1151 if (osc->sc_brctl != NULL) {
1141#endif 1152#endif
1142 if ((sysctl_createv(&osc->sc_log, 0, NULL, &rnode, 1153 if ((sysctl_createv(&osc->sc_log, 0, NULL, &rnode,
1143 0, CTLTYPE_NODE, "hw", NULL, 1154 0, CTLTYPE_NODE, "hw", NULL,
1144 NULL, 0, NULL, 0, 1155 NULL, 0, NULL, 0,
1145 CTL_HW, CTL_EOL)) != 0) 1156 CTL_HW, CTL_EOL)) != 0)
1146 goto fail; 1157 goto fail;
1147 1158
1148 if ((sysctl_createv(&osc->sc_log, 0, &rnode, &rnode, 1159 if ((sysctl_createv(&osc->sc_log, 0, &rnode, &rnode,
1149 0, CTLTYPE_NODE, "acpi", NULL, 1160 0, CTLTYPE_NODE, "acpi", NULL,
1150 NULL, 0, NULL, 0, 1161 NULL, 0, NULL, 0,
1151 CTL_CREATE, CTL_EOL)) != 0) 1162 CTL_CREATE, CTL_EOL)) != 0)
1152 goto fail; 1163 goto fail;
1153 1164
1154 if ((sysctl_createv(&osc->sc_log, 0, &rnode, &rnode, 1165 if ((sysctl_createv(&osc->sc_log, 0, &rnode, &rnode,
1155 0, CTLTYPE_NODE, device_xname(osc->sc_dev), 1166 0, CTLTYPE_NODE, device_xname(osc->sc_dev),
1156 SYSCTL_DESCR("ACPI display output device controls"), 1167 SYSCTL_DESCR("ACPI display output device controls"),
1157 NULL, 0, NULL, 0, 1168 NULL, 0, NULL, 0,
1158 CTL_CREATE, CTL_EOL)) != 0) 1169 CTL_CREATE, CTL_EOL)) != 0)
1159 goto fail; 1170 goto fail;
1160 } 1171 }
1161 1172
1162 if (osc->sc_brctl != NULL) { 1173 if (osc->sc_brctl != NULL) {
1163 (void)sysctl_createv(&osc->sc_log, 0, &rnode, NULL, 1174 (void)sysctl_createv(&osc->sc_log, 0, &rnode, NULL,
1164 CTLFLAG_READWRITE, CTLTYPE_INT, "brightness", 1175 CTLFLAG_READWRITE, CTLTYPE_INT, "brightness",
1165 SYSCTL_DESCR("Current brightness level"), 1176 SYSCTL_DESCR("Current brightness level"),
1166 acpidisp_out_sysctl_brightness, 0, osc, 0, 1177 acpidisp_out_sysctl_brightness, 0, osc, 0,
1167 CTL_CREATE, CTL_EOL); 1178 CTL_CREATE, CTL_EOL);
1168 } 1179 }
1169 1180
1170#ifdef ACPI_DISP_SWITCH_SYSCTLS 1181#ifdef ACPI_DISP_SWITCH_SYSCTLS
1171 if (osc->sc_caps & ACPI_DISP_OUT_CAP__DCS) { 1182 if (osc->sc_caps & ACPI_DISP_OUT_CAP__DCS) {
1172 (void)sysctl_createv(&osc->sc_log, 0, &rnode, NULL, 1183 (void)sysctl_createv(&osc->sc_log, 0, &rnode, NULL,
1173 CTLFLAG_READONLY | CTLFLAG_HEX, CTLTYPE_INT, "status", 1184 CTLFLAG_READONLY | CTLFLAG_HEX, CTLTYPE_INT, "status",
1174 SYSCTL_DESCR("Current status"), 1185 SYSCTL_DESCR("Current status"),
1175 acpidisp_out_sysctl_status, 0, osc, 0, 1186 acpidisp_out_sysctl_status, 0, osc, 0,
1176 CTL_CREATE, CTL_EOL); 1187 CTL_CREATE, CTL_EOL);
1177 } 1188 }
1178 1189
1179 if (osc->sc_caps & ACPI_DISP_OUT_CAP__DGS) { 1190 if (osc->sc_caps & ACPI_DISP_OUT_CAP__DGS) {
1180 int access; 1191 int access;
1181 1192
1182 if (osc->sc_caps & ACPI_DISP_OUT_CAP__DSS) 1193 if (osc->sc_caps & ACPI_DISP_OUT_CAP__DSS)
1183 access = CTLFLAG_READWRITE; 1194 access = CTLFLAG_READWRITE;
1184 else 1195 else
1185 access = CTLFLAG_READONLY; 1196 access = CTLFLAG_READONLY;
1186 1197
1187 (void)sysctl_createv(&osc->sc_log, 0, &rnode, NULL, 1198 (void)sysctl_createv(&osc->sc_log, 0, &rnode, NULL,
1188 access | CTLFLAG_HEX, CTLTYPE_INT, "state", 1199 access | CTLFLAG_HEX, CTLTYPE_INT, "state",
1189 SYSCTL_DESCR("Next state (active or inactive)"), 1200 SYSCTL_DESCR("Next state (active or inactive)"),
1190 acpidisp_out_sysctl_state, 0, osc, 0, 1201 acpidisp_out_sysctl_state, 0, osc, 0,
1191 CTL_CREATE, CTL_EOL); 1202 CTL_CREATE, CTL_EOL);
1192 } 1203 }
1193#endif 1204#endif
1194 1205
1195 return; 1206 return;
1196 1207
1197 fail: 1208 fail:
1198 aprint_error_dev(osc->sc_dev, "couldn't add sysctl nodes\n"); 1209 aprint_error_dev(osc->sc_dev, "couldn't add sysctl nodes\n");
1199} 1210}
1200 1211
1201/* 1212/*
1202 * Sysctl callbacks. 1213 * Sysctl callbacks.
1203 */ 1214 */
1204 1215
 1216#ifdef ACPI_DEBUG
1205static int 1217static int
1206acpidisp_vga_sysctl_policy(SYSCTLFN_ARGS) 1218acpidisp_vga_sysctl_policy(SYSCTLFN_ARGS)
1207{ 1219{
1208 struct sysctlnode node; 1220 struct sysctlnode node;
1209 struct acpidisp_vga_softc *asc; 1221 struct acpidisp_vga_softc *asc;
1210 uint32_t val; 1222 uint32_t val;
1211 int error; 1223 int error;
1212 1224
1213 node = *rnode; 1225 node = *rnode;
1214 asc = (struct acpidisp_vga_softc *)node.sysctl_data; 1226 asc = (struct acpidisp_vga_softc *)node.sysctl_data;
1215 1227
1216 mutex_enter(&asc->sc_mtx); 1228 mutex_enter(&asc->sc_mtx);
1217 val = (uint32_t)asc->sc_policy.raw; 1229 val = (uint32_t)asc->sc_policy.raw;
1218 mutex_exit(&asc->sc_mtx); 1230 mutex_exit(&asc->sc_mtx);
1219 1231
1220 node.sysctl_data = &val; 1232 node.sysctl_data = &val;
1221 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1233 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1222 if (error || newp == NULL) 1234 if (error || newp == NULL)
1223 return error; 1235 return error;
1224 1236
1225 if (val > 0x7) 1237 if (val > 0x7)
1226 return EINVAL; 1238 return EINVAL;
1227 1239
1228 mutex_enter(&asc->sc_mtx); 1240 mutex_enter(&asc->sc_mtx);
1229 asc->sc_policy.raw = (uint8_t)val; 1241 asc->sc_policy.raw = (uint8_t)val;
1230 error = acpidisp_set_policy(asc, asc->sc_policy.raw); 1242 error = acpidisp_set_policy(asc, asc->sc_policy.raw);
1231 mutex_exit(&asc->sc_mtx); 1243 mutex_exit(&asc->sc_mtx);
1232 1244
1233 return error; 1245 return error;
1234} 1246}
 1247#endif
 1248
 1249static int
 1250acpidisp_vga_sysctl_policy_output(SYSCTLFN_ARGS)
 1251{
 1252 struct sysctlnode node;
 1253 struct acpidisp_vga_softc *asc;
 1254 bool val;
 1255 int error;
 1256
 1257 node = *rnode;
 1258 asc = (struct acpidisp_vga_softc *)node.sysctl_data;
 1259
 1260 mutex_enter(&asc->sc_mtx);
 1261 val = (asc->sc_policy.fmt.output == ACPI_DISP_POLICY_OUTPUT_AUTO);
 1262 mutex_exit(&asc->sc_mtx);
 1263
 1264 node.sysctl_data = &val;
 1265 error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1266 if (error || newp == NULL)
 1267 return error;
 1268
 1269 mutex_enter(&asc->sc_mtx);
 1270 if (val)
 1271 asc->sc_policy.fmt.output = ACPI_DISP_POLICY_OUTPUT_AUTO;
 1272 else
 1273 asc->sc_policy.fmt.output = ACPI_DISP_POLICY_OUTPUT_NORMAL;
 1274 error = acpidisp_set_policy(asc, asc->sc_policy.raw);
 1275 mutex_exit(&asc->sc_mtx);
 1276
 1277 return error;
 1278}
1235 1279
1236#ifdef ACPI_DISP_SWITCH_SYSCTLS 1280#ifdef ACPI_DISP_SWITCH_SYSCTLS
1237static int 1281static int
1238acpidisp_out_sysctl_status(SYSCTLFN_ARGS) 1282acpidisp_out_sysctl_status(SYSCTLFN_ARGS)
1239{ 1283{
1240 struct sysctlnode node; 1284 struct sysctlnode node;
1241 struct acpidisp_out_softc *osc; 1285 struct acpidisp_out_softc *osc;
1242 uint32_t val; 1286 uint32_t val;
1243 int error; 1287 int error;
1244 1288
1245 node = *rnode; 1289 node = *rnode;
1246 osc = (struct acpidisp_out_softc *)node.sysctl_data; 1290 osc = (struct acpidisp_out_softc *)node.sysctl_data;
1247 1291
1248 mutex_enter(osc->sc_mtx); 1292 mutex_enter(osc->sc_mtx);
1249 error = acpidisp_get_status(osc, &val); 1293 error = acpidisp_get_status(osc, &val);
1250 mutex_exit(osc->sc_mtx); 1294 mutex_exit(osc->sc_mtx);
1251 1295
1252 if (error) 1296 if (error)
1253 return error; 1297 return error;
1254 1298
1255 node.sysctl_data = &val; 1299 node.sysctl_data = &val;
1256 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1300 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1257 if (error || newp == NULL) 1301 if (error || newp == NULL)
1258 return error; 1302 return error;
1259 1303
1260 return 0; 1304 return 0;
1261} 1305}
1262 1306
1263static int 1307static int
1264acpidisp_out_sysctl_state(SYSCTLFN_ARGS) 1308acpidisp_out_sysctl_state(SYSCTLFN_ARGS)
1265{ 1309{
1266 struct sysctlnode node; 1310 struct sysctlnode node;
1267 struct acpidisp_out_softc *osc; 1311 struct acpidisp_out_softc *osc;
1268 uint32_t val; 1312 uint32_t val;
1269 int error; 1313 int error;
1270 1314
1271 node = *rnode; 1315 node = *rnode;
1272 osc = (struct acpidisp_out_softc *)node.sysctl_data; 1316 osc = (struct acpidisp_out_softc *)node.sysctl_data;
1273 1317
1274 mutex_enter(osc->sc_mtx); 1318 mutex_enter(osc->sc_mtx);
1275 error = acpidisp_get_state(osc, &val); 1319 error = acpidisp_get_state(osc, &val);
1276 mutex_exit(osc->sc_mtx); 1320 mutex_exit(osc->sc_mtx);
1277 1321
1278 if (error) 1322 if (error)
1279 return error; 1323 return error;
1280 1324
1281 node.sysctl_data = &val; 1325 node.sysctl_data = &val;
1282 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1326 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1283 if (error || newp == NULL) 1327 if (error || newp == NULL)
1284 return error; 1328 return error;
1285 1329
1286 mutex_enter(osc->sc_mtx); 1330 mutex_enter(osc->sc_mtx);
1287 error = acpidisp_set_state(osc, val); 1331 error = acpidisp_set_state(osc, val);
1288 mutex_exit(osc->sc_mtx); 1332 mutex_exit(osc->sc_mtx);
1289 1333
1290 return error; 1334 return error;
1291} 1335}
1292#endif 1336#endif
1293 1337
1294static int 1338static int
1295acpidisp_out_sysctl_brightness(SYSCTLFN_ARGS) 1339acpidisp_out_sysctl_brightness(SYSCTLFN_ARGS)
1296{ 1340{
1297 struct sysctlnode node; 1341 struct sysctlnode node;
1298 struct acpidisp_out_softc *osc; 1342 struct acpidisp_out_softc *osc;
1299 struct acpidisp_brctl *bc; 1343 struct acpidisp_brctl *bc;
1300 int val, error; 1344 int val, error;
1301 uint8_t lo, up, level; 1345 uint8_t lo, up, level;
1302 1346
1303 node = *rnode; 1347 node = *rnode;
1304 osc = (struct acpidisp_out_softc *)node.sysctl_data; 1348 osc = (struct acpidisp_out_softc *)node.sysctl_data;
1305 bc = osc->sc_brctl; 1349 bc = osc->sc_brctl;
1306 1350
1307 KASSERT(bc != NULL); 1351 KASSERT(bc != NULL);
1308 1352
1309 mutex_enter(osc->sc_mtx); 1353 mutex_enter(osc->sc_mtx);
1310 (void)acpidisp_get_brightness(osc, &bc->bc_current); 1354 (void)acpidisp_get_brightness(osc, &bc->bc_current);
1311 val = (int)bc->bc_current; 1355 val = (int)bc->bc_current;
1312 mutex_exit(osc->sc_mtx); 1356 mutex_exit(osc->sc_mtx);
1313 1357
1314 node.sysctl_data = &val; 1358 node.sysctl_data = &val;
1315 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 1359 error = sysctl_lookup(SYSCTLFN_CALL(&node));
1316 if (error || newp == NULL) 1360 if (error || newp == NULL)
1317 return error; 1361 return error;
1318 1362
1319 acpidisp_array_search(bc->bc_level, bc->bc_level_count, val, &lo, &up); 1363 acpidisp_array_search(bc->bc_level, bc->bc_level_count, val, &lo, &up);
1320 if ((lo != up) && (val - lo) < (up - val)) 1364 if ((lo != up) && (val - lo) < (up - val))
1321 level = lo; 1365 level = lo;
1322 else 1366 else
1323 level = up; 1367 level = up;
1324 1368
1325 mutex_enter(osc->sc_mtx); 1369 mutex_enter(osc->sc_mtx);
1326 bc->bc_current = level; 1370 bc->bc_current = level;
1327 error = acpidisp_set_brightness(osc, bc->bc_current); 1371 error = acpidisp_set_brightness(osc, bc->bc_current);
1328 mutex_exit(osc->sc_mtx); 1372 mutex_exit(osc->sc_mtx);
1329 1373
1330 return error; 1374 return error;
1331} 1375}
1332 1376
1333/* 1377/*
1334 * Initialization of acpidisp_odinfo (_DOD) and acpidisp_brctl (_BCL). 1378 * Initialization of acpidisp_odinfo (_DOD) and acpidisp_brctl (_BCL).
1335 */ 1379 */
1336 1380
1337/* 1381/*
1338 * Regarding _DOD (ACPI 4.0a, Sec. B.4.2): 1382 * Regarding _DOD (ACPI 4.0a, Sec. B.4.2):
1339 * 1383 *
1340 * "The _DOD method returns a list of devices attached to the graphics adapter, 1384 * "The _DOD method returns a list of devices attached to the graphics adapter,
1341 * along with device-specific configuration information." 1385 * along with device-specific configuration information."
1342 * 1386 *
1343 * "Every child device enumerated in the ACPI namespace under the graphics 1387 * "Every child device enumerated in the ACPI namespace under the graphics
1344 * adapter must be specified in this list of devices. Each display device 1388 * adapter must be specified in this list of devices. Each display device
1345 * must have its own ID, which is unique with respect to any other attachable 1389 * must have its own ID, which is unique with respect to any other attachable
1346 * devices enumerated." 1390 * devices enumerated."
1347 * 1391 *
1348 * "Return value: a package containing a variable-length list of integers, 1392 * "Return value: a package containing a variable-length list of integers,
1349 * each of which contains the 32-bit device attribute of a child device." 1393 * each of which contains the 32-bit device attribute of a child device."
1350 */ 1394 */
1351 1395
1352static struct acpidisp_odinfo * 1396static struct acpidisp_odinfo *
1353acpidisp_init_odinfo(const struct acpidisp_vga_softc *asc) 1397acpidisp_init_odinfo(const struct acpidisp_vga_softc *asc)
1354{ 1398{
1355 ACPI_HANDLE hdl = asc->sc_node->ad_handle; 1399 ACPI_HANDLE hdl = asc->sc_node->ad_handle;
1356 ACPI_STATUS rv; 1400 ACPI_STATUS rv;
1357 ACPI_OBJECT *pkg; 1401 ACPI_OBJECT *pkg;
1358 struct acpidisp_odinfo *oi; 1402 struct acpidisp_odinfo *oi;
1359 struct acpidisp_outdev *devp; 1403 struct acpidisp_outdev *devp;
1360 uint32_t count, i; 1404 uint32_t count, i;
1361 1405
1362 if (!(asc->sc_caps & ACPI_DISP_VGA_CAP__DOD)) 1406 if (!(asc->sc_caps & ACPI_DISP_VGA_CAP__DOD))
1363 return NULL; 1407 return NULL;
1364 1408
1365 oi = NULL; 1409 oi = NULL;
1366 1410
1367 rv = acpidisp_eval_package(hdl, "_DOD", &pkg, 1); 1411 rv = acpidisp_eval_package(hdl, "_DOD", &pkg, 1);
1368 if (ACPI_FAILURE(rv)) 1412 if (ACPI_FAILURE(rv))
1369 goto fail; 1413 goto fail;
1370 1414
1371 /* 1415 /*
1372 * Allocate and fill the struct acpidisp_odinfo to be returned. 1416 * Allocate and fill the struct acpidisp_odinfo to be returned.
1373 */ 1417 */
1374 oi = kmem_zalloc(sizeof(*oi), KM_SLEEP); 1418 oi = kmem_zalloc(sizeof(*oi), KM_SLEEP);
1375 if (oi == NULL) { 1419 if (oi == NULL) {
1376 rv = AE_NO_MEMORY; 1420 rv = AE_NO_MEMORY;
1377 goto fail; 1421 goto fail;
1378 } 1422 }
1379 1423
1380 oi->oi_dev_count = pkg->Package.Count; 1424 oi->oi_dev_count = pkg->Package.Count;
1381 1425
1382 oi->oi_dev = kmem_zalloc(oi->oi_dev_count * sizeof(*oi->oi_dev), 1426 oi->oi_dev = kmem_zalloc(oi->oi_dev_count * sizeof(*oi->oi_dev),
1383 KM_SLEEP); 1427 KM_SLEEP);
1384 if (oi->oi_dev == NULL) { 1428 if (oi->oi_dev == NULL) {
1385 rv = AE_NO_MEMORY; 1429 rv = AE_NO_MEMORY;
1386 goto fail; 1430 goto fail;
1387 } 1431 }
1388 1432
1389 /* 1433 /*
1390 * Fill the array oi->oi_dev. 1434 * Fill the array oi->oi_dev.
1391 */ 1435 */
1392 for (count = 0, i = 0; i < pkg->Package.Count; i++) { 1436 for (count = 0, i = 0; i < pkg->Package.Count; i++) {
1393 /* List of 32-bit integers (ACPI 4.0a, Sec. B.4.2). */ 1437 /* List of 32-bit integers (ACPI 4.0a, Sec. B.4.2). */
1394 if (pkg->Package.Elements[i].Type != ACPI_TYPE_INTEGER || 1438 if (pkg->Package.Elements[i].Type != ACPI_TYPE_INTEGER ||
1395 pkg->Package.Elements[i].Integer.Value > UINT32_MAX) 1439 pkg->Package.Elements[i].Integer.Value > UINT32_MAX)
1396 continue; 1440 continue;
1397 1441
1398 oi->oi_dev[count].od_attrs.raw = 1442 oi->oi_dev[count].od_attrs.raw =
1399 (uint32_t)pkg->Package.Elements[i].Integer.Value; 1443 (uint32_t)pkg->Package.Elements[i].Integer.Value;
1400 count++; 1444 count++;
1401 } 1445 }
1402 1446
1403 if (count == 0) { 1447 if (count == 0) {
1404 rv = AE_BAD_DATA; 1448 rv = AE_BAD_DATA;
1405 goto fail; 1449 goto fail;
1406 } 1450 }
1407 1451
1408 ACPI_FREE(pkg); 1452 ACPI_FREE(pkg);
1409 pkg = NULL; 1453 pkg = NULL;
1410 1454
1411 /* 1455 /*
1412 * Resize the array oi->oi_dev if needed. 1456 * Resize the array oi->oi_dev if needed.
1413 */ 1457 */
1414 if (count < oi->oi_dev_count) { 1458 if (count < oi->oi_dev_count) {
1415 devp = kmem_alloc(count * sizeof(*devp), KM_SLEEP); 1459 devp = kmem_alloc(count * sizeof(*devp), KM_SLEEP);
1416 if (devp == NULL) { 1460 if (devp == NULL) {
1417 rv = AE_NO_MEMORY; 1461 rv = AE_NO_MEMORY;
1418 goto fail; 1462 goto fail;
1419 } 1463 }
1420 1464
1421 (void)memcpy(devp, oi->oi_dev, count * sizeof(*devp)); 1465 (void)memcpy(devp, oi->oi_dev, count * sizeof(*devp));
1422 kmem_free(oi->oi_dev, oi->oi_dev_count * sizeof(*oi->oi_dev)); 1466 kmem_free(oi->oi_dev, oi->oi_dev_count * sizeof(*oi->oi_dev));
1423 1467
1424 oi->oi_dev = devp; 1468 oi->oi_dev = devp;
1425 oi->oi_dev_count = count; 1469 oi->oi_dev_count = count;
1426 } 1470 }
1427 1471
1428 return oi; 1472 return oi;
1429 1473
1430 fail: 1474 fail:
1431 aprint_error_dev(asc->sc_dev, "failed to evaluate %s.%s: %s\n", 1475 aprint_error_dev(asc->sc_dev, "failed to evaluate %s.%s: %s\n",
1432 acpi_name(hdl), "_DOD", AcpiFormatException(rv)); 1476 acpi_name(hdl), "_DOD", AcpiFormatException(rv));
1433 if (pkg != NULL) 1477 if (pkg != NULL)
1434 ACPI_FREE(pkg); 1478 ACPI_FREE(pkg);
1435 if (oi != NULL) { 1479 if (oi != NULL) {
1436 if (oi->oi_dev != NULL) 1480 if (oi->oi_dev != NULL)
1437 kmem_free(oi->oi_dev, 1481 kmem_free(oi->oi_dev,
1438 oi->oi_dev_count * sizeof(*oi->oi_dev)); 1482 oi->oi_dev_count * sizeof(*oi->oi_dev));
1439 kmem_free(oi, sizeof(*oi)); 1483 kmem_free(oi, sizeof(*oi));
1440 } 1484 }
1441 return NULL; 1485 return NULL;
1442} 1486}
1443 1487
1444/* 1488/*
1445 * acpidisp_vga_bind_outdevs: 1489 * acpidisp_vga_bind_outdevs:
1446 * 1490 *
1447 * Bind each acpiout device attached under an acpivga device to the 1491 * Bind each acpiout device attached under an acpivga device to the
1448 * corresponding (_DOD enumerated) connected output device. 1492 * corresponding (_DOD enumerated) connected output device.
1449 */ 1493 */
1450static void 1494static void
1451acpidisp_vga_bind_outdevs(struct acpidisp_vga_softc *asc) 1495acpidisp_vga_bind_outdevs(struct acpidisp_vga_softc *asc)
1452{ 1496{
1453 struct acpidisp_odinfo *oi = asc->sc_odinfo; 1497 struct acpidisp_odinfo *oi = asc->sc_odinfo;
1454 struct acpidisp_out_softc *osc; 1498 struct acpidisp_out_softc *osc;
1455 struct acpidisp_outdev *od; 1499 struct acpidisp_outdev *od;
1456 struct acpi_devnode *ad; 1500 struct acpi_devnode *ad;
1457 ACPI_HANDLE hdl; 1501 ACPI_HANDLE hdl;
1458 ACPI_UINT64 val; 1502 ACPI_UINT64 val;
1459 ACPI_STATUS rv; 1503 ACPI_STATUS rv;
1460 uint16_t devid; 1504 uint16_t devid;
1461 uint32_t i; 1505 uint32_t i;
1462 1506
1463 KASSERT(oi != NULL); 1507 KASSERT(oi != NULL);
1464 1508
1465 /* Reset all bindings. */ 1509 /* Reset all bindings. */
1466 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) 1510 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++)
1467 od->od_device = NULL; 1511 od->od_device = NULL;
1468 1512
1469 /* 1513 /*
1470 * Iterate over all ACPI children that have been attached under this 1514 * Iterate over all ACPI children that have been attached under this
1471 * acpivga device (as acpiout devices). 1515 * acpivga device (as acpiout devices).
1472 */ 1516 */
1473 SIMPLEQ_FOREACH(ad, &asc->sc_node->ad_child_head, ad_child_list) { 1517 SIMPLEQ_FOREACH(ad, &asc->sc_node->ad_child_head, ad_child_list) {
1474 if ((ad->ad_device == NULL) || 1518 if ((ad->ad_device == NULL) ||
1475 (device_parent(ad->ad_device) != asc->sc_dev)) 1519 (device_parent(ad->ad_device) != asc->sc_dev))
1476 continue; 1520 continue;
1477 1521
1478 KASSERT(device_is_a(ad->ad_device, "acpiout")); 1522 KASSERT(device_is_a(ad->ad_device, "acpiout"));
1479 1523
1480 osc = device_private(ad->ad_device); 1524 osc = device_private(ad->ad_device);
1481 1525
1482 /* 1526 /*
1483 * For display output devices, the method _ADR returns 1527 * For display output devices, the method _ADR returns
1484 * the device's ID (ACPI 4.0a, Sec. B.6.1). We do not 1528 * the device's ID (ACPI 4.0a, Sec. B.6.1). We do not
1485 * cache the result of _ADR since it may vary. 1529 * cache the result of _ADR since it may vary.
1486 */ 1530 */
1487 hdl = osc->sc_node->ad_handle; 1531 hdl = osc->sc_node->ad_handle;
1488 rv = acpi_eval_integer(hdl, "_ADR", &val); 1532 rv = acpi_eval_integer(hdl, "_ADR", &val);
1489 if (ACPI_FAILURE(rv)) { 1533 if (ACPI_FAILURE(rv)) {
1490 aprint_error_dev(asc->sc_dev, 1534 aprint_error_dev(asc->sc_dev,
1491 "failed to evaluate %s.%s: %s\n", 1535 "failed to evaluate %s.%s: %s\n",
1492 acpi_name(hdl), "_ADR", AcpiFormatException(rv)); 1536 acpi_name(hdl), "_ADR", AcpiFormatException(rv));
1493 continue; 1537 continue;
1494 } 1538 }
1495 1539
1496 /* The device ID is a 16-bit integer (ACPI 4.0a, Table B-2). */ 1540 /* The device ID is a 16-bit integer (ACPI 4.0a, Table B-2). */
1497 devid = (uint16_t)val; 1541 devid = (uint16_t)val;
1498 1542
1499 /* 1543 /*
1500 * The device ID must be unique (among output devices), and must 1544 * The device ID must be unique (among output devices), and must
1501 * appear in the list returned by _DOD (ACPI 4.0a, Sec. B.6.1). 1545 * appear in the list returned by _DOD (ACPI 4.0a, Sec. B.6.1).
1502 */ 1546 */
1503 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) { 1547 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) {
1504 if (devid == od->od_attrs.device_id) { 1548 if (devid == od->od_attrs.device_id) {
1505 if (od->od_device != NULL) 1549 if (od->od_device != NULL)
1506 aprint_error_dev(asc->sc_dev, 1550 aprint_error_dev(asc->sc_dev,
1507 "%s has same device ID as %s\n", 1551 "%s has same device ID as %s\n",
1508 device_xname(osc->sc_dev), 1552 device_xname(osc->sc_dev),
1509 device_xname(od->od_device)); 1553 device_xname(od->od_device));
1510 else 1554 else
1511 od->od_device = osc->sc_dev; 1555 od->od_device = osc->sc_dev;
1512 break; 1556 break;
1513 } 1557 }
1514 } 1558 }
1515 if (i == oi->oi_dev_count) 1559 if (i == oi->oi_dev_count)
1516 aprint_error_dev(asc->sc_dev, 1560 aprint_error_dev(asc->sc_dev,
1517 "unknown output device %s\n", 1561 "unknown output device %s\n",
1518 device_xname(osc->sc_dev)); 1562 device_xname(osc->sc_dev));
1519 } 1563 }
1520} 1564}
1521 1565
1522/* 1566/*
1523 * Regarding _BCL (ACPI 4.0a, Sec. B.6.2): 1567 * Regarding _BCL (ACPI 4.0a, Sec. B.6.2):
1524 * 1568 *
1525 * "This method allows the OS to query a list of brightness levels supported by 1569 * "This method allows the OS to query a list of brightness levels supported by
1526 * built-in display output devices." 1570 * built-in display output devices."
1527 * 1571 *
1528 * "Return value: a variable-length package containing a list of integers 1572 * "Return value: a variable-length package containing a list of integers
1529 * representing the supported brightness levels. Each integer has 8 bits of 1573 * representing the supported brightness levels. Each integer has 8 bits of
1530 * significant data." 1574 * significant data."
1531 */ 1575 */
1532 1576
1533static struct acpidisp_brctl * 1577static struct acpidisp_brctl *
1534acpidisp_init_brctl(const struct acpidisp_out_softc *osc) 1578acpidisp_init_brctl(const struct acpidisp_out_softc *osc)
1535{ 1579{
1536 ACPI_HANDLE hdl = osc->sc_node->ad_handle; 1580 ACPI_HANDLE hdl = osc->sc_node->ad_handle;
1537 ACPI_STATUS rv; 1581 ACPI_STATUS rv;
1538 ACPI_OBJECT *pkg; 1582 ACPI_OBJECT *pkg;
1539 struct acpidisp_brctl *bc; 1583 struct acpidisp_brctl *bc;
1540 uint8_t *levelp; 1584 uint8_t *levelp;
1541 uint32_t i; 1585 uint32_t i;
1542 int32_t j; 1586 int32_t j;
1543 uint16_t count, k; 1587 uint16_t count, k;
1544 uint8_t level; 1588 uint8_t level;
1545 1589
1546 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__BCL)) 1590 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__BCL))
1547 return NULL; 1591 return NULL;
1548 1592
1549 bc = NULL; 1593 bc = NULL;
1550 1594
1551 rv = acpidisp_eval_package(hdl, "_BCL", &pkg, 2); 1595 rv = acpidisp_eval_package(hdl, "_BCL", &pkg, 2);
1552 if (ACPI_FAILURE(rv)) 1596 if (ACPI_FAILURE(rv))
1553 goto fail; 1597 goto fail;
1554 1598
1555 /* 1599 /*
1556 * Allocate and fill the struct acpidisp_brctl to be returned. 1600 * Allocate and fill the struct acpidisp_brctl to be returned.
1557 */ 1601 */
1558 bc = kmem_zalloc(sizeof(*bc), KM_SLEEP); 1602 bc = kmem_zalloc(sizeof(*bc), KM_SLEEP);
1559 if (bc == NULL) { 1603 if (bc == NULL) {
1560 rv = AE_NO_MEMORY; 1604 rv = AE_NO_MEMORY;
1561 goto fail; 1605 goto fail;
1562 } 1606 }
1563 1607
1564 /* At most 256 brightness levels (8-bit integers). */ 1608 /* At most 256 brightness levels (8-bit integers). */
1565 if (pkg->Package.Count > 256) 1609 if (pkg->Package.Count > 256)
1566 bc->bc_level_count = 256; 1610 bc->bc_level_count = 256;
1567 else 1611 else
1568 bc->bc_level_count = (uint16_t)pkg->Package.Count; 1612 bc->bc_level_count = (uint16_t)pkg->Package.Count;
1569 1613
1570 bc->bc_level = kmem_zalloc(bc->bc_level_count * sizeof(*bc->bc_level), 1614 bc->bc_level = kmem_zalloc(bc->bc_level_count * sizeof(*bc->bc_level),
1571 KM_SLEEP); 1615 KM_SLEEP);
1572 if (bc->bc_level == NULL) { 1616 if (bc->bc_level == NULL) {
1573 rv = AE_NO_MEMORY; 1617 rv = AE_NO_MEMORY;
1574 goto fail; 1618 goto fail;
1575 } 1619 }
1576 1620
1577 /* 1621 /*
1578 * Fill the array bc->bc_level with an insertion sort. 1622 * Fill the array bc->bc_level with an insertion sort.
1579 */ 1623 */
1580 for (count = 0, i = 0; i < pkg->Package.Count; i++) { 1624 for (count = 0, i = 0; i < pkg->Package.Count; i++) {
1581 /* List of 8-bit integers (ACPI 4.0a, Sec. B.6.2). */ 1625 /* List of 8-bit integers (ACPI 4.0a, Sec. B.6.2). */
1582 if (pkg->Package.Elements[i].Type != ACPI_TYPE_INTEGER || 1626 if (pkg->Package.Elements[i].Type != ACPI_TYPE_INTEGER ||
1583 pkg->Package.Elements[i].Integer.Value > UINT8_MAX) 1627 pkg->Package.Elements[i].Integer.Value > UINT8_MAX)
1584 continue; 1628 continue;
1585 1629
1586 level = (uint8_t)pkg->Package.Elements[i].Integer.Value; 1630 level = (uint8_t)pkg->Package.Elements[i].Integer.Value;
1587 1631
1588 /* Find the correct slot but do not modify the array yet. */ 1632 /* Find the correct slot but do not modify the array yet. */
1589 for (j = count; --j >= 0 && bc->bc_level[j] > level; ); 1633 for (j = count; --j >= 0 && bc->bc_level[j] > level; );
1590 if (j >= 0 && bc->bc_level[j] == level) 1634 if (j >= 0 && bc->bc_level[j] == level)
1591 continue; 1635 continue;
1592 j++; 1636 j++;
1593 1637
1594 /* Make room for the new level. */ 1638 /* Make room for the new level. */
1595 for (k = count; k > j; k--) 1639 for (k = count; k > j; k--)
1596 bc->bc_level[k] = bc->bc_level[k-1]; 1640 bc->bc_level[k] = bc->bc_level[k-1];
1597 1641
1598 /* Insert the new level. */ 1642 /* Insert the new level. */
1599 bc->bc_level[j] = level; 1643 bc->bc_level[j] = level;
1600 count++; 1644 count++;
1601 } 1645 }
1602 1646
1603 if (count == 0) { 1647 if (count == 0) {
1604 rv = AE_BAD_DATA; 1648 rv = AE_BAD_DATA;
1605 goto fail; 1649 goto fail;
1606 } 1650 }
1607 1651
1608 ACPI_FREE(pkg); 1652 ACPI_FREE(pkg);
1609 pkg = NULL; 1653 pkg = NULL;
1610 1654
1611 /* 1655 /*
1612 * Resize the array bc->bc_level if needed. 1656 * Resize the array bc->bc_level if needed.
1613 */ 1657 */
1614 if (count < bc->bc_level_count) { 1658 if (count < bc->bc_level_count) {
1615 levelp = kmem_alloc(count * sizeof(*levelp), KM_SLEEP); 1659 levelp = kmem_alloc(count * sizeof(*levelp), KM_SLEEP);
1616 if (levelp == NULL) { 1660 if (levelp == NULL) {
1617 rv = AE_NO_MEMORY; 1661 rv = AE_NO_MEMORY;
1618 goto fail; 1662 goto fail;
1619 } 1663 }
1620 1664
1621 (void)memcpy(levelp, bc->bc_level, count * sizeof(*levelp)); 1665 (void)memcpy(levelp, bc->bc_level, count * sizeof(*levelp));
1622 kmem_free(bc->bc_level, 1666 kmem_free(bc->bc_level,
1623 bc->bc_level_count * sizeof(*bc->bc_level)); 1667 bc->bc_level_count * sizeof(*bc->bc_level));
1624 1668
1625 bc->bc_level = levelp; 1669 bc->bc_level = levelp;
1626 bc->bc_level_count = count; 1670 bc->bc_level_count = count;
1627 } 1671 }
1628 1672
1629 return bc; 1673 return bc;
1630 1674
1631 fail: 1675 fail:
1632 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n", 1676 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n",
1633 acpi_name(hdl), "_BCL", AcpiFormatException(rv)); 1677 acpi_name(hdl), "_BCL", AcpiFormatException(rv));
1634 if (pkg != NULL) 1678 if (pkg != NULL)
1635 ACPI_FREE(pkg); 1679 ACPI_FREE(pkg);
1636 if (bc != NULL) { 1680 if (bc != NULL) {
1637 if (bc->bc_level != NULL) 1681 if (bc->bc_level != NULL)
1638 kmem_free(bc->bc_level, 1682 kmem_free(bc->bc_level,
1639 bc->bc_level_count * sizeof(*bc->bc_level)); 1683 bc->bc_level_count * sizeof(*bc->bc_level));
1640 kmem_free(bc, sizeof(*bc)); 1684 kmem_free(bc, sizeof(*bc));
1641 } 1685 }
1642 return NULL; 1686 return NULL;
1643} 1687}
1644 1688
1645/* 1689/*
1646 * Evaluation of simple ACPI display methods. 1690 * Evaluation of simple ACPI display methods.
1647 */ 1691 */
1648 1692
1649static int 1693static int
1650acpidisp_set_policy(const struct acpidisp_vga_softc *asc, uint8_t value) 1694acpidisp_set_policy(const struct acpidisp_vga_softc *asc, uint8_t value)
1651{ 1695{
1652 ACPI_HANDLE hdl = asc->sc_node->ad_handle; 1696 ACPI_HANDLE hdl = asc->sc_node->ad_handle;
1653 ACPI_UINT64 val; 1697 ACPI_UINT64 val;
1654 ACPI_STATUS rv; 1698 ACPI_STATUS rv;
1655 1699
1656 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: set %s: 0x%"PRIx8"\n", 1700 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: set %s: 0x%"PRIx8"\n",
1657 device_xname(asc->sc_dev), "policy", value)); 1701 device_xname(asc->sc_dev), "policy", value));
1658 1702
1659 if (!(asc->sc_caps & ACPI_DISP_VGA_CAP__DOS)) 1703 if (!(asc->sc_caps & ACPI_DISP_VGA_CAP__DOS))
1660 return ENODEV; 1704 return ENODEV;
1661 1705
1662 val = (ACPI_UINT64)value; 1706 val = (ACPI_UINT64)value;
1663 rv = acpi_eval_set_integer(hdl, "_DOS", val); 1707 rv = acpi_eval_set_integer(hdl, "_DOS", val);
1664 if (ACPI_FAILURE(rv)) { 1708 if (ACPI_FAILURE(rv)) {
1665 aprint_error_dev(asc->sc_dev, "failed to evaluate %s.%s: %s\n", 1709 aprint_error_dev(asc->sc_dev, "failed to evaluate %s.%s: %s\n",
1666 acpi_name(hdl), "_DOS", AcpiFormatException(rv)); 1710 acpi_name(hdl), "_DOS", AcpiFormatException(rv));
1667 return EIO; 1711 return EIO;
1668 } 1712 }
1669 1713
1670 return 0; 1714 return 0;
1671} 1715}
1672 1716
1673static int 1717static int
1674acpidisp_get_status(const struct acpidisp_out_softc *osc, uint32_t *valuep) 1718acpidisp_get_status(const struct acpidisp_out_softc *osc, uint32_t *valuep)
1675{ 1719{
1676 ACPI_HANDLE hdl = osc->sc_node->ad_handle; 1720 ACPI_HANDLE hdl = osc->sc_node->ad_handle;
1677 ACPI_UINT64 val; 1721 ACPI_UINT64 val;
1678 ACPI_STATUS rv; 1722 ACPI_STATUS rv;
1679 1723
1680 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DCS)) 1724 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DCS))
1681 return ENODEV; 1725 return ENODEV;
1682 1726
1683 rv = acpi_eval_integer(hdl, "_DCS", &val); 1727 rv = acpi_eval_integer(hdl, "_DCS", &val);
1684 if (ACPI_FAILURE(rv)) { 1728 if (ACPI_FAILURE(rv)) {
1685 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n", 1729 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n",
1686 acpi_name(hdl), "_DCS", AcpiFormatException(rv)); 1730 acpi_name(hdl), "_DCS", AcpiFormatException(rv));
1687 return EIO; 1731 return EIO;
1688 } 1732 }
1689 1733
1690 if (val > UINT32_MAX) 1734 if (val > UINT32_MAX)
1691 return ERANGE; 1735 return ERANGE;
1692 1736
1693 *valuep = (uint32_t)val; 1737 *valuep = (uint32_t)val;
1694 1738
1695 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: get %s: 0x%"PRIx32"\n", 1739 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: get %s: 0x%"PRIx32"\n",
1696 device_xname(osc->sc_dev), "status", *valuep)); 1740 device_xname(osc->sc_dev), "status", *valuep));
1697 1741
1698 return 0; 1742 return 0;
1699} 1743}
1700 1744
1701static int 1745static int
1702acpidisp_get_state(const struct acpidisp_out_softc *osc, uint32_t *valuep) 1746acpidisp_get_state(const struct acpidisp_out_softc *osc, uint32_t *valuep)
1703{ 1747{
1704 ACPI_HANDLE hdl = osc->sc_node->ad_handle; 1748 ACPI_HANDLE hdl = osc->sc_node->ad_handle;
1705 ACPI_UINT64 val; 1749 ACPI_UINT64 val;
1706 ACPI_STATUS rv; 1750 ACPI_STATUS rv;
1707 1751
1708 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DGS)) 1752 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DGS))
1709 return ENODEV; 1753 return ENODEV;
1710 1754
1711 rv = acpi_eval_integer(hdl, "_DGS", &val); 1755 rv = acpi_eval_integer(hdl, "_DGS", &val);
1712 if (ACPI_FAILURE(rv)) { 1756 if (ACPI_FAILURE(rv)) {
1713 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n", 1757 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n",
1714 acpi_name(hdl), "_DGS", AcpiFormatException(rv)); 1758 acpi_name(hdl), "_DGS", AcpiFormatException(rv));
1715 return EIO; 1759 return EIO;
1716 } 1760 }
1717 1761
1718 if (val > UINT32_MAX) 1762 if (val > UINT32_MAX)
1719 return ERANGE; 1763 return ERANGE;
1720 1764
1721 *valuep = (uint32_t)val; 1765 *valuep = (uint32_t)val;
1722 1766
1723 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: get %s: 0x%"PRIx32"\n", 1767 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: get %s: 0x%"PRIx32"\n",
1724 device_xname(osc->sc_dev), "state", *valuep)); 1768 device_xname(osc->sc_dev), "state", *valuep));
1725 1769
1726 return 0; 1770 return 0;
1727} 1771}
1728 1772
1729static int 1773static int
1730acpidisp_set_state(const struct acpidisp_out_softc *osc, uint32_t value) 1774acpidisp_set_state(const struct acpidisp_out_softc *osc, uint32_t value)
1731{ 1775{
1732 ACPI_HANDLE hdl = osc->sc_node->ad_handle; 1776 ACPI_HANDLE hdl = osc->sc_node->ad_handle;
1733 ACPI_UINT64 val; 1777 ACPI_UINT64 val;
1734 ACPI_STATUS rv; 1778 ACPI_STATUS rv;
1735 1779
1736 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: set %s: 0x%"PRIx32"\n", 1780 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: set %s: 0x%"PRIx32"\n",
1737 device_xname(osc->sc_dev), "state", value)); 1781 device_xname(osc->sc_dev), "state", value));
1738 1782
1739 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DSS)) 1783 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__DSS))
1740 return ENODEV; 1784 return ENODEV;
1741 1785
1742 val = (ACPI_UINT64)value; 1786 val = (ACPI_UINT64)value;
1743 rv = acpi_eval_set_integer(hdl, "_DSS", val); 1787 rv = acpi_eval_set_integer(hdl, "_DSS", val);
1744 if (ACPI_FAILURE(rv)) { 1788 if (ACPI_FAILURE(rv)) {
1745 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n", 1789 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n",
1746 acpi_name(hdl), "_DSS", AcpiFormatException(rv)); 1790 acpi_name(hdl), "_DSS", AcpiFormatException(rv));
1747 return EIO; 1791 return EIO;
1748 } 1792 }
1749 1793
1750 return 0; 1794 return 0;
1751} 1795}
1752 1796
1753static int 1797static int
1754acpidisp_get_brightness(const struct acpidisp_out_softc *osc, uint8_t *valuep) 1798acpidisp_get_brightness(const struct acpidisp_out_softc *osc, uint8_t *valuep)
1755{ 1799{
1756 ACPI_HANDLE hdl = osc->sc_node->ad_handle; 1800 ACPI_HANDLE hdl = osc->sc_node->ad_handle;
1757 ACPI_UINT64 val; 1801 ACPI_UINT64 val;
1758 ACPI_STATUS rv; 1802 ACPI_STATUS rv;
1759 1803
1760 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__BQC)) 1804 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__BQC))
1761 return ENODEV; 1805 return ENODEV;
1762 1806
1763 rv = acpi_eval_integer(hdl, "_BQC", &val); 1807 rv = acpi_eval_integer(hdl, "_BQC", &val);
1764 if (ACPI_FAILURE(rv)) { 1808 if (ACPI_FAILURE(rv)) {
1765 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n", 1809 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n",
1766 acpi_name(hdl), "_BQC", AcpiFormatException(rv)); 1810 acpi_name(hdl), "_BQC", AcpiFormatException(rv));
1767 return EIO; 1811 return EIO;
1768 } 1812 }
1769 1813
1770 if (val > UINT8_MAX) 1814 if (val > UINT8_MAX)
1771 return ERANGE; 1815 return ERANGE;
1772 1816
1773 *valuep = (uint8_t)val; 1817 *valuep = (uint8_t)val;
1774 1818
1775 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: get %s: %"PRIu8"\n", 1819 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: get %s: %"PRIu8"\n",
1776 device_xname(osc->sc_dev), "brightness", *valuep)); 1820 device_xname(osc->sc_dev), "brightness", *valuep));
1777 1821
1778 return 0; 1822 return 0;
1779} 1823}
1780 1824
1781static int 1825static int
1782acpidisp_set_brightness(const struct acpidisp_out_softc *osc, uint8_t value) 1826acpidisp_set_brightness(const struct acpidisp_out_softc *osc, uint8_t value)
1783{ 1827{
1784 ACPI_HANDLE hdl = osc->sc_node->ad_handle; 1828 ACPI_HANDLE hdl = osc->sc_node->ad_handle;
1785 ACPI_UINT64 val; 1829 ACPI_UINT64 val;
1786 ACPI_STATUS rv; 1830 ACPI_STATUS rv;
1787 1831
1788 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: set %s: %"PRIu8"\n", 1832 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: set %s: %"PRIu8"\n",
1789 device_xname(osc->sc_dev), "brightness", value)); 1833 device_xname(osc->sc_dev), "brightness", value));
1790 1834
1791 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__BCM)) 1835 if (!(osc->sc_caps & ACPI_DISP_OUT_CAP__BCM))
1792 return ENODEV; 1836 return ENODEV;
1793 1837
1794 val = (ACPI_UINT64)value; 1838 val = (ACPI_UINT64)value;
1795 rv = acpi_eval_set_integer(hdl, "_BCM", val); 1839 rv = acpi_eval_set_integer(hdl, "_BCM", val);
1796 if (ACPI_FAILURE(rv)) { 1840 if (ACPI_FAILURE(rv)) {
1797 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n", 1841 aprint_error_dev(osc->sc_dev, "failed to evaluate %s.%s: %s\n",
1798 acpi_name(hdl), "_BCM", AcpiFormatException(rv)); 1842 acpi_name(hdl), "_BCM", AcpiFormatException(rv));
1799 return EIO; 1843 return EIO;
1800 } 1844 }
1801 1845
1802 return 0; 1846 return 0;
1803} 1847}
1804 1848
1805/* 1849/*
1806 * Pretty printing. 1850 * Pretty printing.
1807 */ 1851 */
1808 1852
1809static void 1853static void
1810acpidisp_print_odinfo(device_t self, const struct acpidisp_odinfo *oi) 1854acpidisp_print_odinfo(device_t self, const struct acpidisp_odinfo *oi)
1811{ 1855{
1812 struct acpidisp_outdev *od; 1856 struct acpidisp_outdev *od;
1813 uint32_t i; 1857 uint32_t i;
1814 1858
1815 KASSERT(oi != NULL); 1859 KASSERT(oi != NULL);
1816 1860
1817 aprint_verbose_dev(self, "connected output devices:\n"); 1861 aprint_verbose_dev(self, "connected output devices:\n");
1818 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) { 1862 for (i = 0, od = oi->oi_dev; i < oi->oi_dev_count; i++, od++) {
1819 aprint_verbose_dev(self, " 0x%04"PRIx16, od->od_attrs.device_id); 1863 aprint_verbose_dev(self, " 0x%04"PRIx16, od->od_attrs.device_id);
1820 if (od->od_device != NULL) 1864 if (od->od_device != NULL)
1821 aprint_verbose(" (%s)", device_xname(od->od_device)); 1865 aprint_verbose(" (%s)", device_xname(od->od_device));
1822 aprint_verbose(": "); 1866 aprint_verbose(": ");
1823 acpidisp_print_od_attrs(od->od_attrs); 1867 acpidisp_print_od_attrs(od->od_attrs);
1824 aprint_verbose("\n"); 1868 aprint_verbose("\n");
1825 } 1869 }
1826} 1870}
1827 1871
1828static void 1872static void
1829acpidisp_print_brctl(device_t self, const struct acpidisp_brctl *bc) 1873acpidisp_print_brctl(device_t self, const struct acpidisp_brctl *bc)
1830{ 1874{
1831 uint16_t i; 1875 uint16_t i;
1832 1876
1833 KASSERT(bc != NULL); 1877 KASSERT(bc != NULL);
1834 1878
1835 aprint_verbose_dev(self, "brightness levels:"); 1879 aprint_verbose_dev(self, "brightness levels:");
1836 for (i = 0; i < bc->bc_level_count; i++) 1880 for (i = 0; i < bc->bc_level_count; i++)
1837 aprint_verbose(" %"PRIu8, bc->bc_level[i]); 1881 aprint_verbose(" %"PRIu8, bc->bc_level[i]);
1838 aprint_verbose("\n"); 1882 aprint_verbose("\n");
1839} 1883}
1840 1884
1841static void 1885static void
1842acpidisp_print_od_attrs(acpidisp_od_attrs_t oda) 1886acpidisp_print_od_attrs(acpidisp_od_attrs_t oda)
1843{ 1887{
1844 const char *type; 1888 const char *type;
1845 1889
1846 if (oda.fmt.device_id_scheme == 1) { 1890 if (oda.fmt.device_id_scheme == 1) {
1847 /* Uses the device ID scheme introduced in ACPI 3.0. */ 1891 /* Uses the device ID scheme introduced in ACPI 3.0. */
1848 switch (oda.fmt.type) { 1892 switch (oda.fmt.type) {
1849 case ACPI_DISP_OUT_ATTR_TYPE_OTHER: 1893 case ACPI_DISP_OUT_ATTR_TYPE_OTHER:
1850 type = "Other"; 1894 type = "Other";
1851 break; 1895 break;
1852 case ACPI_DISP_OUT_ATTR_TYPE_VGA: 1896 case ACPI_DISP_OUT_ATTR_TYPE_VGA:
1853 type = "VGA Analog Monitor"; 1897 type = "VGA Analog Monitor";
1854 break; 1898 break;
1855 case ACPI_DISP_OUT_ATTR_TYPE_TV: 1899 case ACPI_DISP_OUT_ATTR_TYPE_TV:
1856 type = "TV/HDTV Monitor"; 1900 type = "TV/HDTV Monitor";
1857 break; 1901 break;
1858 case ACPI_DISP_OUT_ATTR_TYPE_EXTDIG: 1902 case ACPI_DISP_OUT_ATTR_TYPE_EXTDIG:
1859 type = "Ext. Digital Monitor"; 1903 type = "Ext. Digital Monitor";
1860 break; 1904 break;
1861 case ACPI_DISP_OUT_ATTR_TYPE_INTDFP: 1905 case ACPI_DISP_OUT_ATTR_TYPE_INTDFP:
1862 type = "Int. Digital Flat Panel"; 1906 type = "Int. Digital Flat Panel";
1863 break; 1907 break;
1864 default: 1908 default:
1865 type = "Invalid"; 1909 type = "Invalid";
1866 break; 1910 break;
1867 } 1911 }
1868 1912
1869 aprint_verbose("%s, index %d, port %d", 1913 aprint_verbose("%s, index %d, port %d",
1870 type, oda.fmt.index, oda.fmt.port); 1914 type, oda.fmt.index, oda.fmt.port);
1871 } else { 1915 } else {
1872 /* Uses vendor-specific device IDs. */ 1916 /* Uses vendor-specific device IDs. */
1873 switch (oda.device_id) { 1917 switch (oda.device_id) {
1874 case ACPI_DISP_OUT_LEGACY_DEVID_MONITOR: 1918 case ACPI_DISP_OUT_LEGACY_DEVID_MONITOR:
1875 type = "Ext. Monitor"; 1919 type = "Ext. Monitor";
1876 break; 1920 break;
1877 case ACPI_DISP_OUT_LEGACY_DEVID_PANEL: 1921 case ACPI_DISP_OUT_LEGACY_DEVID_PANEL:
1878 type = "LCD Panel"; 1922 type = "LCD Panel";
1879 break; 1923 break;
1880 case ACPI_DISP_OUT_LEGACY_DEVID_TV: 1924 case ACPI_DISP_OUT_LEGACY_DEVID_TV:
1881 type = "TV"; 1925 type = "TV";
1882 break; 1926 break;
1883 default: 1927 default:
1884 type = "Unknown Output Device"; 1928 type = "Unknown Output Device";
1885 break; 1929 break;
1886 } 1930 }
1887 1931
1888 aprint_verbose("%s", type); 1932 aprint_verbose("%s", type);
1889 } 1933 }
1890 1934
1891 aprint_verbose(", head %d", oda.fmt.head_id); 1935 aprint_verbose(", head %d", oda.fmt.head_id);
1892 if (oda.fmt.bios_detect) 1936 if (oda.fmt.bios_detect)
1893 aprint_verbose(", bios detect"); 1937 aprint_verbose(", bios detect");
1894 if (oda.fmt.non_vga) 1938 if (oda.fmt.non_vga)
1895 aprint_verbose(", non vga"); 1939 aprint_verbose(", non vga");
1896} 1940}
1897 1941
1898/* 1942/*
1899 * General-purpose utility functions. 1943 * General-purpose utility functions.
1900 */ 1944 */
1901 1945
1902/* 1946/*
1903 * acpidisp_has_method: 1947 * acpidisp_has_method:
1904 * 1948 *
1905 * Returns true if and only if (a) the object handle.path exists and 1949 * Returns true if and only if (a) the object handle.path exists and
1906 * (b) this object is a method or has the given type. 1950 * (b) this object is a method or has the given type.
1907 */ 1951 */
1908static bool 1952static bool
1909acpidisp_has_method(ACPI_HANDLE handle, const char *path, ACPI_OBJECT_TYPE type) 1953acpidisp_has_method(ACPI_HANDLE handle, const char *path, ACPI_OBJECT_TYPE type)
1910{ 1954{
1911 ACPI_HANDLE hdl; 1955 ACPI_HANDLE hdl;
1912 ACPI_OBJECT_TYPE typ; 1956 ACPI_OBJECT_TYPE typ;
1913 1957
1914 KASSERT(handle != NULL); 1958 KASSERT(handle != NULL);
1915 1959
1916 if (ACPI_FAILURE(AcpiGetHandle(handle, path, &hdl))) 1960 if (ACPI_FAILURE(AcpiGetHandle(handle, path, &hdl)))
1917 return false; 1961 return false;
1918 1962
1919 if (ACPI_FAILURE(AcpiGetType(hdl, &typ))) 1963 if (ACPI_FAILURE(AcpiGetType(hdl, &typ)))
1920 return false; 1964 return false;
1921 1965
1922 if (typ != ACPI_TYPE_METHOD && typ != type) 1966 if (typ != ACPI_TYPE_METHOD && typ != type)
1923 return false; 1967 return false;
1924 1968
1925 return true; 1969 return true;
1926} 1970}
1927 1971
1928/* 1972/*
1929 * acpidisp_eval_package: 1973 * acpidisp_eval_package:
1930 * 1974 *
1931 * Evaluate a package (with an expected minimum number of elements). 1975 * Evaluate a package (with an expected minimum number of elements).
1932 * Caller must free *pkg by ACPI_FREE(). 1976 * Caller must free *pkg by ACPI_FREE().
1933 */ 1977 */
1934static ACPI_STATUS 1978static ACPI_STATUS
1935acpidisp_eval_package(ACPI_HANDLE handle, const char *path, ACPI_OBJECT **pkg, 1979acpidisp_eval_package(ACPI_HANDLE handle, const char *path, ACPI_OBJECT **pkg,
1936 unsigned int mincount) 1980 unsigned int mincount)
1937{ 1981{
1938 ACPI_BUFFER buf; 1982 ACPI_BUFFER buf;
1939 ACPI_OBJECT *obj; 1983 ACPI_OBJECT *obj;
1940 ACPI_STATUS rv; 1984 ACPI_STATUS rv;
1941 1985
1942 rv = acpi_eval_struct(handle, path, &buf); 1986 rv = acpi_eval_struct(handle, path, &buf);
1943 if (ACPI_FAILURE(rv)) 1987 if (ACPI_FAILURE(rv))
1944 return rv; 1988 return rv;
1945 1989
1946 if (buf.Length == 0 || buf.Pointer == NULL) 1990 if (buf.Length == 0 || buf.Pointer == NULL)
1947 return AE_NULL_OBJECT; 1991 return AE_NULL_OBJECT;
1948 1992
1949 obj = buf.Pointer; 1993 obj = buf.Pointer;
1950 1994
1951 if (obj->Type != ACPI_TYPE_PACKAGE) { 1995 if (obj->Type != ACPI_TYPE_PACKAGE) {
1952 ACPI_FREE(obj); 1996 ACPI_FREE(obj);
1953 return AE_TYPE; 1997 return AE_TYPE;
1954 } 1998 }
1955 1999
1956 if (obj->Package.Count < mincount) { 2000 if (obj->Package.Count < mincount) {
1957 ACPI_FREE(obj); 2001 ACPI_FREE(obj);
1958 return AE_BAD_DATA; 2002 return AE_BAD_DATA;
1959 } 2003 }
1960 2004
1961 *pkg = obj; 2005 *pkg = obj;
1962 return rv; 2006 return rv;
1963} 2007}
1964 2008
1965/* 2009/*
1966 * acpidisp_array_search: 2010 * acpidisp_array_search:
1967 * 2011 *
1968 * Look for a value v in a sorted array a of n integers (n > 0). Fill *l 2012 * Look for a value v in a sorted array a of n integers (n > 0). Fill *l
1969 * and *u as follows: 2013 * and *u as follows:
1970 * 2014 *
1971 * *l = Max {a[i] | a[i] <= v or i = 0} 2015 * *l = Max {a[i] | a[i] <= v or i = 0}
1972 * *u = Min {a[i] | a[i] >= v or i = n-1} 2016 * *u = Min {a[i] | a[i] >= v or i = n-1}
1973 */ 2017 */
1974static void 2018static void
1975acpidisp_array_search(const uint8_t *a, uint16_t n, int v, uint8_t *l, uint8_t *u) 2019acpidisp_array_search(const uint8_t *a, uint16_t n, int v, uint8_t *l, uint8_t *u)
1976{ 2020{
1977 uint16_t i, j, m; 2021 uint16_t i, j, m;
1978 2022
1979 if (v <= a[0]) { 2023 if (v <= a[0]) {
1980 *l = a[0]; 2024 *l = a[0];
1981 *u = a[0]; 2025 *u = a[0];
1982 return; 2026 return;
1983 } 2027 }
1984 if (v >= a[n-1]) { 2028 if (v >= a[n-1]) {
1985 *l = a[n-1]; 2029 *l = a[n-1];
1986 *u = a[n-1]; 2030 *u = a[n-1];
1987 return; 2031 return;
1988 } 2032 }
1989 2033
1990 for (i = 0, j = n - 1; j - i > 1; ) { 2034 for (i = 0, j = n - 1; j - i > 1; ) {
1991 m = (i + j) / 2; 2035 m = (i + j) / 2;
1992 2036
1993 if (a[m] == v) { 2037 if (a[m] == v) {
1994 *l = v; 2038 *l = v;
1995 *u = v; 2039 *u = v;
1996 return; 2040 return;
1997 } 2041 }
1998 2042
1999 if (a[m] < v) 2043 if (a[m] < v)
2000 i = m; 2044 i = m;
2001 else 2045 else
2002 j = m; 2046 j = m;
2003 } 2047 }
2004 2048
2005 /* Here a[i] < v < a[j] and j = i + 1. */ 2049 /* Here a[i] < v < a[j] and j = i + 1. */
2006 *l = a[i]; 2050 *l = a[i];
2007 *u = a[j]; 2051 *u = a[j];
2008 return; 2052 return;
2009} 2053}
2010 2054
2011#ifdef _MODULE 2055#ifdef _MODULE
2012 2056
2013MODULE(MODULE_CLASS_DRIVER, acpivga, NULL); 2057MODULE(MODULE_CLASS_DRIVER, acpivga, NULL);
2014 2058
2015#include "ioconf.c" 2059#include "ioconf.c"
2016 2060
2017static int 2061static int
2018acpivga_modcmd(modcmd_t cmd, void *context) 2062acpivga_modcmd(modcmd_t cmd, void *context)
2019{ 2063{
2020 2064
2021 switch (cmd) { 2065 switch (cmd) {
2022 2066
2023 case MODULE_CMD_INIT: 2067 case MODULE_CMD_INIT:
2024 return config_init_component(cfdriver_ioconf_acpivga, 2068 return config_init_component(cfdriver_ioconf_acpivga,
2025 cfattach_ioconf_acpivga, cfdata_ioconf_acpivga); 2069 cfattach_ioconf_acpivga, cfdata_ioconf_acpivga);
2026 2070
2027 case MODULE_CMD_FINI: 2071 case MODULE_CMD_FINI:
2028 return config_fini_component(cfdriver_ioconf_acpivga, 2072 return config_fini_component(cfdriver_ioconf_acpivga,
2029 cfattach_ioconf_acpivga, cfdata_ioconf_acpivga); 2073 cfattach_ioconf_acpivga, cfdata_ioconf_acpivga);
2030 2074
2031 default: 2075 default:
2032 return ENOTTY; 2076 return ENOTTY;
2033 } 2077 }
2034} 2078}
2035 2079
2036#endif /* _MODULE */ 2080#endif /* _MODULE */