Mon Nov 14 02:44:59 2011 UTC ()
add a machdep.dmi sysctl tree with the following read-only keys:
 system-vendor, system-product, system-version, system-serial, system-uuid
 bios-vendor, bios-version
 board-vendor, board-product, board-version, board-serial
the *-serial and *-uuid keys are marked with CTLFLAG_PRIVATE

a few of the pmf platform key names changed so update callers to match


(jmcneill)
diff -r1.11 -r1.12 src/sys/arch/x86/x86/platform.c
diff -r1.251 -r1.252 src/sys/dev/acpi/acpi.c
diff -r1.47 -r1.48 src/sys/dev/acpi/acpi_cpu.c
diff -r1.19 -r1.20 src/sys/dev/acpi/acpi_quirks.c

cvs diff -r1.11 -r1.12 src/sys/arch/x86/x86/Attic/platform.c (switch to unified diff)

--- src/sys/arch/x86/x86/Attic/platform.c 2011/01/18 07:47:16 1.11
+++ src/sys/arch/x86/x86/Attic/platform.c 2011/11/14 02:44:59 1.12
@@ -1,176 +1,302 @@ @@ -1,176 +1,302 @@
1/* $NetBSD: platform.c,v 1.11 2011/01/18 07:47:16 jmmv Exp $ */ 1/* $NetBSD: platform.c,v 1.12 2011/11/14 02:44:59 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include "isa.h" 29#include "isa.h"
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: platform.c,v 1.11 2011/01/18 07:47:16 jmmv Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: platform.c,v 1.12 2011/11/14 02:44:59 jmcneill Exp $");
33 33
34#include <sys/types.h> 34#include <sys/types.h>
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/kernel.h> 36#include <sys/kernel.h>
 37#include <sys/sysctl.h>
 38#include <sys/uuid.h>
37#include <sys/pmf.h> 39#include <sys/pmf.h>
38 40
39#include <dev/isa/isavar.h> 41#include <dev/isa/isavar.h>
40 42
41#include <arch/x86/include/smbiosvar.h> 43#include <arch/x86/include/smbiosvar.h>
42 44
 45static int platform_dminode = CTL_EOL;
 46
43void platform_init(void); /* XXX */ 47void platform_init(void); /* XXX */
44static void platform_add(struct smbtable *, const char *, int); 48static void platform_add(struct smbtable *, const char *, int);
45static void platform_add_date(struct smbtable *, const char *, int); 49static void platform_add_date(struct smbtable *, const char *, int);
 50static void platform_add_uuid(struct smbtable *, const char *,
 51 const uint8_t *);
 52static int platform_dmi_sysctl(SYSCTLFN_PROTO);
46static void platform_print(void); 53static void platform_print(void);
47 54
 55/* list of private DMI sysctl nodes */
 56static const char *platform_private_nodes[] = {
 57 "board-serial",
 58 "system-serial",
 59 "system-uuid",
 60 NULL
 61};
 62
48void 63void
49platform_init(void) 64platform_init(void)
50{ 65{
51 struct smbtable smbios; 66 struct smbtable smbios;
52 struct smbios_sys *psys; 67 struct smbios_sys *psys;
53 struct smbios_struct_bios *pbios; 68 struct smbios_struct_bios *pbios;
 69 struct smbios_board *pboard;
54 struct smbios_slot *pslot; 70 struct smbios_slot *pslot;
55 int nisa, nother; 71 int nisa, nother;
56 72
57 smbios.cookie = 0; 73 smbios.cookie = 0;
58 if (smbios_find_table(SMBIOS_TYPE_SYSTEM, &smbios)) { 74 if (smbios_find_table(SMBIOS_TYPE_SYSTEM, &smbios)) {
59 psys = smbios.tblhdr; 75 psys = smbios.tblhdr;
60 76
61 platform_add(&smbios, "system-manufacturer", psys->vendor); 77 platform_add(&smbios, "system-vendor", psys->vendor);
62 platform_add(&smbios, "system-product-name", psys->product); 78 platform_add(&smbios, "system-product", psys->product);
63 platform_add(&smbios, "system-version", psys->version); 79 platform_add(&smbios, "system-version", psys->version);
64 platform_add(&smbios, "system-serial-number", psys->serial); 80 platform_add(&smbios, "system-serial", psys->serial);
 81 platform_add_uuid(&smbios, "system-uuid", psys->uuid);
65 } 82 }
66 83
67 smbios.cookie = 0; 84 smbios.cookie = 0;
68 if (smbios_find_table(SMBIOS_TYPE_BIOS, &smbios)) { 85 if (smbios_find_table(SMBIOS_TYPE_BIOS, &smbios)) {
69 pbios = smbios.tblhdr; 86 pbios = smbios.tblhdr;
70 87
71 platform_add(&smbios, "firmware-vendor", pbios->vendor); 88 platform_add(&smbios, "bios-vendor", pbios->vendor);
72 platform_add(&smbios, "firmware-version", pbios->version); 89 platform_add(&smbios, "bios-version", pbios->version);
73 platform_add_date(&smbios, "firmware-date", pbios->release); 90 platform_add_date(&smbios, "bios-date", pbios->release);
 91 }
 92
 93 smbios.cookie = 0;
 94 if (smbios_find_table(SMBIOS_TYPE_BASEBOARD, &smbios)) {
 95 pboard = smbios.tblhdr;
 96
 97 platform_add(&smbios, "board-vendor", pboard->vendor);
 98 platform_add(&smbios, "board-product", pboard->product);
 99 platform_add(&smbios, "board-version", pboard->version);
 100 platform_add(&smbios, "board-serial", pboard->serial);
 101 platform_add(&smbios, "board-asset-tag", pboard->asset);
74 } 102 }
75 103
76 smbios.cookie = 0; 104 smbios.cookie = 0;
77 nisa = 0; 105 nisa = 0;
78 nother = 0; 106 nother = 0;
79 while (smbios_find_table(SMBIOS_TYPE_SLOTS, &smbios)) { 107 while (smbios_find_table(SMBIOS_TYPE_SLOTS, &smbios)) {
80 pslot = smbios.tblhdr; 108 pslot = smbios.tblhdr;
81 switch (pslot->type) { 109 switch (pslot->type) {
82 case SMBIOS_SLOT_ISA: 110 case SMBIOS_SLOT_ISA:
83 case SMBIOS_SLOT_EISA: 111 case SMBIOS_SLOT_EISA:
84 nisa++; 112 nisa++;
85 break; 113 break;
86 default: 114 default:
87 nother++; 115 nother++;
88 break; 116 break;
89 } 117 }
90 } 118 }
91 119
92#if NISA > 0 120#if NISA > 0
93 if ((nother | nisa) != 0) { 121 if ((nother | nisa) != 0) {
94 /* Only if there seems to be good expansion slot info. */ 122 /* Only if there seems to be good expansion slot info. */
95 isa_set_slotcount(nisa); 123 isa_set_slotcount(nisa);
96 } 124 }
97#endif 125#endif
98 126
99 platform_print(); 127 platform_print();
100} 128}
101 129
102static void 130static void
103platform_print(void) 131platform_print(void)
104{ 132{
105 const char *manuf, *prod, *ver; 133 const char *vend, *prod, *ver;
106 134
107 manuf = pmf_get_platform("system-manufacturer"); 135 vend = pmf_get_platform("system-vendor");
108 prod = pmf_get_platform("system-product-name"); 136 prod = pmf_get_platform("system-product");
109 ver = pmf_get_platform("system-version"); 137 ver = pmf_get_platform("system-version");
110 138
111 if (manuf == NULL) 139 if (vend == NULL)
112 aprint_verbose("Generic"); 140 aprint_verbose("Generic");
113 else 141 else
114 aprint_verbose("%s", manuf); 142 aprint_verbose("%s", vend);
115 if (prod == NULL) 143 if (prod == NULL)
116 aprint_verbose(" PC"); 144 aprint_verbose(" PC");
117 else 145 else
118 aprint_verbose(" %s", prod); 146 aprint_verbose(" %s", prod);
119 if (ver != NULL) 147 if (ver != NULL)
120 aprint_verbose(" (%s)", ver); 148 aprint_verbose(" (%s)", ver);
121 aprint_verbose("\n"); 149 aprint_verbose("\n");
122} 150}
123 151
 152static bool
 153platform_sysctl_is_private(const char *key)
 154{
 155 unsigned int n;
 156
 157 for (n = 0; platform_private_nodes[n] != NULL; n++) {
 158 if (strcmp(key, platform_private_nodes[n]) == 0) {
 159 return true;
 160 }
 161 }
 162
 163 return false;
 164}
 165
 166static void
 167platform_create_sysctl(const char *key)
 168{
 169 int flags = 0, err;
 170
 171 if (pmf_get_platform(key) == NULL)
 172 return;
 173
 174 /* If the key is marked private, set CTLFLAG_PRIVATE flag */
 175 if (platform_sysctl_is_private(key))
 176 flags |= CTLFLAG_PRIVATE;
 177
 178 err = sysctl_createv(NULL, 0, NULL, NULL,
 179 CTLFLAG_READONLY | flags, CTLTYPE_STRING,
 180 key, NULL, platform_dmi_sysctl, 0, NULL, 0,
 181 CTL_MACHDEP, platform_dminode, CTL_CREATE, CTL_EOL);
 182 if (err != 0)
 183 printf("platform: sysctl_createv "
 184 "(machdep.dmi.%s) failed, err = %d\n",
 185 key, err);
 186}
 187
124static void 188static void
125platform_add(struct smbtable *tbl, const char *key, int idx) 189platform_add(struct smbtable *tbl, const char *key, int idx)
126{ 190{
127 char tmpbuf[128]; /* XXX is this long enough? */ 191 char tmpbuf[128]; /* XXX is this long enough? */
128 192
129 if (smbios_get_string(tbl, idx, tmpbuf, 128) != NULL) 193 if (smbios_get_string(tbl, idx, tmpbuf, 128) != NULL) {
 194 /* add to platform dictionary */
130 pmf_set_platform(key, tmpbuf); 195 pmf_set_platform(key, tmpbuf);
 196
 197 /* create sysctl node */
 198 platform_create_sysctl(key);
 199 }
131} 200}
132 201
133static int 202static int
134platform_scan_date(char *buf, unsigned int *month, unsigned int *day, 203platform_scan_date(char *buf, unsigned int *month, unsigned int *day,
135 unsigned int *year) 204 unsigned int *year)
136{ 205{
137 char *p, *s; 206 char *p, *s;
138 207
139 s = buf; 208 s = buf;
140 p = strchr(s, '/'); 209 p = strchr(s, '/');
141 if (p) *p = '\0'; 210 if (p) *p = '\0';
142 *month = strtoul(s, NULL, 10); 211 *month = strtoul(s, NULL, 10);
143 if (!p) return 1; 212 if (!p) return 1;
144 213
145 s = p + 1; 214 s = p + 1;
146 p = strchr(s, '/'); 215 p = strchr(s, '/');
147 if (p) *p = '\0'; 216 if (p) *p = '\0';
148 *day = strtoul(s, NULL, 10); 217 *day = strtoul(s, NULL, 10);
149 if (!p) return 2; 218 if (!p) return 2;
150 219
151 s = p + 1; 220 s = p + 1;
152 *year = strtoul(s, NULL, 10); 221 *year = strtoul(s, NULL, 10);
153 return 3; 222 return 3;
154} 223}
155 224
156static void 225static void
157platform_add_date(struct smbtable *tbl, const char *key, int idx) 226platform_add_date(struct smbtable *tbl, const char *key, int idx)
158{ 227{
159 unsigned int month, day, year; 228 unsigned int month, day, year;
160 char tmpbuf[128], datestr[9]; 229 char tmpbuf[128], datestr[9];
161 230
162 if (smbios_get_string(tbl, idx, tmpbuf, 128) == NULL) 231 if (smbios_get_string(tbl, idx, tmpbuf, 128) == NULL)
163 return; 232 return;
164 if (platform_scan_date(tmpbuf, &month, &day, &year) != 3) 233 if (platform_scan_date(tmpbuf, &month, &day, &year) != 3)
165 return; 234 return;
166 if (month == 0 || month > 12 || day == 0 || day > 31) 235 if (month == 0 || month > 12 || day == 0 || day > 31)
167 return; 236 return;
168 if (year > 9999) 237 if (year > 9999)
169 return; 238 return;
170 if (year < 70) 239 if (year < 70)
171 year += 2000; 240 year += 2000;
172 else if (year < 100) 241 else if (year < 100)
173 year += 1900; 242 year += 1900;
174 sprintf(datestr, "%04u%02u%02u", year, month, day); 243 sprintf(datestr, "%04u%02u%02u", year, month, day);
175 pmf_set_platform(key, datestr); 244 pmf_set_platform(key, datestr);
176} 245}
 246
 247static void
 248platform_add_uuid(struct smbtable *tbl, const char *key, const uint8_t *buf)
 249{
 250 struct uuid uuid;
 251 char tmpbuf[UUID_STR_LEN];
 252
 253 uuid_dec_le(buf, &uuid);
 254 uuid_snprintf(tmpbuf, sizeof(tmpbuf), &uuid);
 255
 256 pmf_set_platform(key, tmpbuf);
 257 platform_create_sysctl(key);
 258}
 259
 260static int
 261platform_dmi_sysctl(SYSCTLFN_ARGS)
 262{
 263 struct sysctlnode node;
 264 const char *v;
 265 int err = 0;
 266
 267 node = *rnode;
 268
 269 v = pmf_get_platform(node.sysctl_name);
 270 if (v == NULL)
 271 return ENOENT;
 272
 273 node.sysctl_data = __UNCONST(v);
 274 err = sysctl_lookup(SYSCTLFN_CALL(&node));
 275 if (err || newp == NULL)
 276 return err;
 277
 278 return 0;
 279}
 280
 281SYSCTL_SETUP(sysctl_dmi_setup, "sysctl machdep.dmi subtree setup")
 282{
 283 const struct sysctlnode *rnode;
 284 int err;
 285
 286 err = sysctl_createv(clog, 0, NULL, &rnode,
 287 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep",
 288 NULL, NULL, 0, NULL, 0,
 289 CTL_MACHDEP, CTL_EOL);
 290 if (err)
 291 return;
 292
 293 err = sysctl_createv(clog, 0, &rnode, &rnode,
 294 CTLFLAG_PERMANENT, CTLTYPE_NODE, "dmi",
 295 SYSCTL_DESCR("DMI table information"),
 296 NULL, 0, NULL, 0,
 297 CTL_CREATE, CTL_EOL);
 298 if (err)
 299 return;
 300
 301 platform_dminode = rnode->sysctl_num;
 302}

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

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

cvs diff -r1.47 -r1.48 src/sys/dev/acpi/acpi_cpu.c (switch to unified diff)

--- src/sys/dev/acpi/acpi_cpu.c 2011/10/27 05:25:07 1.47
+++ src/sys/dev/acpi/acpi_cpu.c 2011/11/14 02:44:59 1.48
@@ -1,918 +1,918 @@ @@ -1,918 +1,918 @@
1/* $NetBSD: acpi_cpu.c,v 1.47 2011/10/27 05:25:07 jruoho Exp $ */ 1/* $NetBSD: acpi_cpu.c,v 1.48 2011/11/14 02:44:59 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2010, 2011 Jukka Ruohonen <jruohonen@iki.fi> 4 * Copyright (c) 2010, 2011 Jukka Ruohonen <jruohonen@iki.fi>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 10 *
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE. 27 * SUCH DAMAGE.
28 */ 28 */
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v 1.47 2011/10/27 05:25:07 jruoho Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v 1.48 2011/11/14 02:44:59 jmcneill Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/cpu.h> 33#include <sys/cpu.h>
34#include <sys/evcnt.h> 34#include <sys/evcnt.h>
35#include <sys/kernel.h> 35#include <sys/kernel.h>
36#include <sys/kmem.h> 36#include <sys/kmem.h>
37#include <sys/module.h> 37#include <sys/module.h>
38#include <sys/mutex.h> 38#include <sys/mutex.h>
39#include <sys/sysctl.h> 39#include <sys/sysctl.h>
40#include <sys/cpufreq.h> 40#include <sys/cpufreq.h>
41 41
42#include <dev/acpi/acpireg.h> 42#include <dev/acpi/acpireg.h>
43#include <dev/acpi/acpivar.h> 43#include <dev/acpi/acpivar.h>
44#include <dev/acpi/acpi_cpu.h> 44#include <dev/acpi/acpi_cpu.h>
45 45
46#include <machine/acpi_machdep.h> 46#include <machine/acpi_machdep.h>
47#include <machine/cpuvar.h> 47#include <machine/cpuvar.h>
48 48
49#define _COMPONENT ACPI_BUS_COMPONENT 49#define _COMPONENT ACPI_BUS_COMPONENT
50ACPI_MODULE_NAME ("acpi_cpu") 50ACPI_MODULE_NAME ("acpi_cpu")
51 51
52static int acpicpu_match(device_t, cfdata_t, void *); 52static int acpicpu_match(device_t, cfdata_t, void *);
53static void acpicpu_attach(device_t, device_t, void *); 53static void acpicpu_attach(device_t, device_t, void *);
54static int acpicpu_detach(device_t, int); 54static int acpicpu_detach(device_t, int);
55static int acpicpu_once_attach(void); 55static int acpicpu_once_attach(void);
56static int acpicpu_once_detach(void); 56static int acpicpu_once_detach(void);
57static void acpicpu_start(device_t); 57static void acpicpu_start(device_t);
58static void acpicpu_sysctl(device_t); 58static void acpicpu_sysctl(device_t);
59 59
60static ACPI_STATUS acpicpu_object(ACPI_HANDLE, struct acpicpu_object *); 60static ACPI_STATUS acpicpu_object(ACPI_HANDLE, struct acpicpu_object *);
61static uint32_t acpicpu_cap(struct acpicpu_softc *); 61static uint32_t acpicpu_cap(struct acpicpu_softc *);
62static ACPI_STATUS acpicpu_cap_osc(struct acpicpu_softc *, 62static ACPI_STATUS acpicpu_cap_osc(struct acpicpu_softc *,
63 uint32_t, uint32_t *); 63 uint32_t, uint32_t *);
64static void acpicpu_notify(ACPI_HANDLE, uint32_t, void *); 64static void acpicpu_notify(ACPI_HANDLE, uint32_t, void *);
65static bool acpicpu_suspend(device_t, const pmf_qual_t *); 65static bool acpicpu_suspend(device_t, const pmf_qual_t *);
66static bool acpicpu_resume(device_t, const pmf_qual_t *); 66static bool acpicpu_resume(device_t, const pmf_qual_t *);
67static void acpicpu_evcnt_attach(device_t); 67static void acpicpu_evcnt_attach(device_t);
68static void acpicpu_evcnt_detach(device_t); 68static void acpicpu_evcnt_detach(device_t);
69static void acpicpu_debug_print(device_t); 69static void acpicpu_debug_print(device_t);
70static const char *acpicpu_debug_print_method_c(uint8_t); 70static const char *acpicpu_debug_print_method_c(uint8_t);
71static const char *acpicpu_debug_print_method_pt(uint8_t); 71static const char *acpicpu_debug_print_method_pt(uint8_t);
72static const char *acpicpu_debug_print_dep(uint32_t); 72static const char *acpicpu_debug_print_dep(uint32_t);
73 73
74static uint32_t acpicpu_count = 0; 74static uint32_t acpicpu_count = 0;
75struct acpicpu_softc **acpicpu_sc = NULL; 75struct acpicpu_softc **acpicpu_sc = NULL;
76static struct sysctllog *acpicpu_log = NULL; 76static struct sysctllog *acpicpu_log = NULL;
77static bool acpicpu_dynamic = true; 77static bool acpicpu_dynamic = true;
78static bool acpicpu_passive = true; 78static bool acpicpu_passive = true;
79 79
80static const struct { 80static const struct {
81 const char *manu; 81 const char *manu;
82 const char *prod; 82 const char *prod;
83 const char *vers; 83 const char *vers;
84} acpicpu_quirks[] = { 84} acpicpu_quirks[] = {
85 { "Supermicro", "PDSMi-LN4", "0123456789" }, 85 { "Supermicro", "PDSMi-LN4", "0123456789" },
86}; 86};
87 87
88CFATTACH_DECL_NEW(acpicpu, sizeof(struct acpicpu_softc), 88CFATTACH_DECL_NEW(acpicpu, sizeof(struct acpicpu_softc),
89 acpicpu_match, acpicpu_attach, acpicpu_detach, NULL); 89 acpicpu_match, acpicpu_attach, acpicpu_detach, NULL);
90 90
91static int 91static int
92acpicpu_match(device_t parent, cfdata_t match, void *aux) 92acpicpu_match(device_t parent, cfdata_t match, void *aux)
93{ 93{
94 const char *manu, *prod, *vers; 94 const char *manu, *prod, *vers;
95 struct cpu_info *ci; 95 struct cpu_info *ci;
96 size_t i; 96 size_t i;
97 97
98 if (acpi_softc == NULL) 98 if (acpi_softc == NULL)
99 return 0; 99 return 0;
100 100
101 manu = pmf_get_platform("system-manufacturer"); 101 manu = pmf_get_platform("system-vendor");
102 prod = pmf_get_platform("system-product-name"); 102 prod = pmf_get_platform("system-product");
103 vers = pmf_get_platform("system-version"); 103 vers = pmf_get_platform("system-version");
104 104
105 if (manu != NULL && prod != NULL && vers != NULL) { 105 if (manu != NULL && prod != NULL && vers != NULL) {
106 106
107 for (i = 0; i < __arraycount(acpicpu_quirks); i++) { 107 for (i = 0; i < __arraycount(acpicpu_quirks); i++) {
108 108
109 if (strcasecmp(acpicpu_quirks[i].manu, manu) == 0 && 109 if (strcasecmp(acpicpu_quirks[i].manu, manu) == 0 &&
110 strcasecmp(acpicpu_quirks[i].prod, prod) == 0 && 110 strcasecmp(acpicpu_quirks[i].prod, prod) == 0 &&
111 strcasecmp(acpicpu_quirks[i].vers, vers) == 0) 111 strcasecmp(acpicpu_quirks[i].vers, vers) == 0)
112 return 0; 112 return 0;
113 } 113 }
114 } 114 }
115 115
116 ci = acpicpu_md_match(parent, match, aux); 116 ci = acpicpu_md_match(parent, match, aux);
117 117
118 if (ci == NULL) 118 if (ci == NULL)
119 return 0; 119 return 0;
120 120
121 if (acpi_match_cpu_info(ci) == NULL) 121 if (acpi_match_cpu_info(ci) == NULL)
122 return 0; 122 return 0;
123 123
124 return 10; 124 return 10;
125} 125}
126 126
127static void 127static void
128acpicpu_attach(device_t parent, device_t self, void *aux) 128acpicpu_attach(device_t parent, device_t self, void *aux)
129{ 129{
130 struct acpicpu_softc *sc = device_private(self); 130 struct acpicpu_softc *sc = device_private(self);
131 struct cpu_info *ci; 131 struct cpu_info *ci;
132 ACPI_HANDLE hdl; 132 ACPI_HANDLE hdl;
133 cpuid_t id; 133 cpuid_t id;
134 int rv; 134 int rv;
135 135
136 ci = acpicpu_md_attach(parent, self, aux); 136 ci = acpicpu_md_attach(parent, self, aux);
137 137
138 if (ci == NULL) 138 if (ci == NULL)
139 return; 139 return;
140 140
141 sc->sc_ci = ci; 141 sc->sc_ci = ci;
142 sc->sc_dev = self; 142 sc->sc_dev = self;
143 sc->sc_cold = true; 143 sc->sc_cold = true;
144 144
145 hdl = acpi_match_cpu_info(ci); 145 hdl = acpi_match_cpu_info(ci);
146 146
147 if (hdl == NULL) { 147 if (hdl == NULL) {
148 aprint_normal(": failed to match processor\n"); 148 aprint_normal(": failed to match processor\n");
149 return; 149 return;
150 } 150 }
151 151
152 sc->sc_node = acpi_match_node(hdl); 152 sc->sc_node = acpi_match_node(hdl);
153 153
154 if (acpicpu_once_attach() != 0) { 154 if (acpicpu_once_attach() != 0) {
155 aprint_normal(": failed to initialize\n"); 155 aprint_normal(": failed to initialize\n");
156 return; 156 return;
157 } 157 }
158 158
159 KASSERT(acpi_softc != NULL); 159 KASSERT(acpi_softc != NULL);
160 KASSERT(acpicpu_sc != NULL); 160 KASSERT(acpicpu_sc != NULL);
161 KASSERT(sc->sc_node != NULL); 161 KASSERT(sc->sc_node != NULL);
162 162
163 id = sc->sc_ci->ci_acpiid; 163 id = sc->sc_ci->ci_acpiid;
164 164
165 if (acpicpu_sc[id] != NULL) { 165 if (acpicpu_sc[id] != NULL) {
166 aprint_normal(": already attached\n"); 166 aprint_normal(": already attached\n");
167 return; 167 return;
168 } 168 }
169 169
170 aprint_naive("\n"); 170 aprint_naive("\n");
171 aprint_normal(": ACPI CPU\n"); 171 aprint_normal(": ACPI CPU\n");
172 172
173 rv = acpicpu_object(sc->sc_node->ad_handle, &sc->sc_object); 173 rv = acpicpu_object(sc->sc_node->ad_handle, &sc->sc_object);
174 174
175 if (ACPI_FAILURE(rv)) 175 if (ACPI_FAILURE(rv))
176 aprint_verbose_dev(self, "failed to obtain CPU object\n"); 176 aprint_verbose_dev(self, "failed to obtain CPU object\n");
177 177
178 acpicpu_count++; 178 acpicpu_count++;
179 acpicpu_sc[id] = sc; 179 acpicpu_sc[id] = sc;
180 180
181 sc->sc_cap = acpicpu_cap(sc); 181 sc->sc_cap = acpicpu_cap(sc);
182 sc->sc_ncpus = acpi_md_ncpus(); 182 sc->sc_ncpus = acpi_md_ncpus();
183 sc->sc_flags = acpicpu_md_flags(); 183 sc->sc_flags = acpicpu_md_flags();
184 184
185 KASSERT(acpicpu_count <= sc->sc_ncpus); 185 KASSERT(acpicpu_count <= sc->sc_ncpus);
186 KASSERT(sc->sc_node->ad_device == NULL); 186 KASSERT(sc->sc_node->ad_device == NULL);
187 187
188 sc->sc_node->ad_device = self; 188 sc->sc_node->ad_device = self;
189 mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE); 189 mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);
190 190
191 acpicpu_cstate_attach(self); 191 acpicpu_cstate_attach(self);
192 acpicpu_pstate_attach(self); 192 acpicpu_pstate_attach(self);
193 acpicpu_tstate_attach(self); 193 acpicpu_tstate_attach(self);
194 194
195 acpicpu_debug_print(self); 195 acpicpu_debug_print(self);
196 acpicpu_evcnt_attach(self); 196 acpicpu_evcnt_attach(self);
197 197
198 (void)config_interrupts(self, acpicpu_start); 198 (void)config_interrupts(self, acpicpu_start);
199 (void)acpi_register_notify(sc->sc_node, acpicpu_notify); 199 (void)acpi_register_notify(sc->sc_node, acpicpu_notify);
200 (void)pmf_device_register(self, acpicpu_suspend, acpicpu_resume); 200 (void)pmf_device_register(self, acpicpu_suspend, acpicpu_resume);
201} 201}
202 202
203static int 203static int
204acpicpu_detach(device_t self, int flags) 204acpicpu_detach(device_t self, int flags)
205{ 205{
206 struct acpicpu_softc *sc = device_private(self); 206 struct acpicpu_softc *sc = device_private(self);
207 207
208 sc->sc_cold = true; 208 sc->sc_cold = true;
209 209
210 acpicpu_evcnt_detach(self); 210 acpicpu_evcnt_detach(self);
211 acpi_deregister_notify(sc->sc_node); 211 acpi_deregister_notify(sc->sc_node);
212 212
213 acpicpu_cstate_detach(self); 213 acpicpu_cstate_detach(self);
214 acpicpu_pstate_detach(self); 214 acpicpu_pstate_detach(self);
215 acpicpu_tstate_detach(self); 215 acpicpu_tstate_detach(self);
216 216
217 mutex_destroy(&sc->sc_mtx); 217 mutex_destroy(&sc->sc_mtx);
218 sc->sc_node->ad_device = NULL; 218 sc->sc_node->ad_device = NULL;
219 219
220 acpicpu_count--; 220 acpicpu_count--;
221 acpicpu_once_detach(); 221 acpicpu_once_detach();
222 222
223 return 0; 223 return 0;
224} 224}
225 225
226static int 226static int
227acpicpu_once_attach(void) 227acpicpu_once_attach(void)
228{ 228{
229 struct acpicpu_softc *sc; 229 struct acpicpu_softc *sc;
230 unsigned int i; 230 unsigned int i;
231 231
232 if (acpicpu_count != 0) 232 if (acpicpu_count != 0)
233 return 0; 233 return 0;
234 234
235 KASSERT(acpicpu_sc == NULL); 235 KASSERT(acpicpu_sc == NULL);
236 KASSERT(acpicpu_log == NULL); 236 KASSERT(acpicpu_log == NULL);
237 237
238 acpicpu_sc = kmem_zalloc(maxcpus * sizeof(*sc), KM_SLEEP); 238 acpicpu_sc = kmem_zalloc(maxcpus * sizeof(*sc), KM_SLEEP);
239 239
240 if (acpicpu_sc == NULL) 240 if (acpicpu_sc == NULL)
241 return ENOMEM; 241 return ENOMEM;
242 242
243 for (i = 0; i < maxcpus; i++) 243 for (i = 0; i < maxcpus; i++)
244 acpicpu_sc[i] = NULL; 244 acpicpu_sc[i] = NULL;
245 245
246 return 0; 246 return 0;
247} 247}
248 248
249static int 249static int
250acpicpu_once_detach(void) 250acpicpu_once_detach(void)
251{ 251{
252 struct acpicpu_softc *sc; 252 struct acpicpu_softc *sc;
253 253
254 if (acpicpu_count != 0) 254 if (acpicpu_count != 0)
255 return EDEADLK; 255 return EDEADLK;
256 256
257 cpufreq_deregister(); 257 cpufreq_deregister();
258 258
259 if (acpicpu_log != NULL) 259 if (acpicpu_log != NULL)
260 sysctl_teardown(&acpicpu_log); 260 sysctl_teardown(&acpicpu_log);
261 261
262 if (acpicpu_sc != NULL) 262 if (acpicpu_sc != NULL)
263 kmem_free(acpicpu_sc, maxcpus * sizeof(*sc)); 263 kmem_free(acpicpu_sc, maxcpus * sizeof(*sc));
264 264
265 return 0; 265 return 0;
266} 266}
267 267
268static void 268static void
269acpicpu_start(device_t self) 269acpicpu_start(device_t self)
270{ 270{
271 struct acpicpu_softc *sc = device_private(self); 271 struct acpicpu_softc *sc = device_private(self);
272 static uint32_t count = 0; 272 static uint32_t count = 0;
273 struct cpufreq cf; 273 struct cpufreq cf;
274 uint32_t i; 274 uint32_t i;
275 275
276 /* 276 /*
277 * Run the state-specific initialization routines. These 277 * Run the state-specific initialization routines. These
278 * must run only once, after interrupts have been enabled, 278 * must run only once, after interrupts have been enabled,
279 * all CPUs are running, and all ACPI CPUs have attached. 279 * all CPUs are running, and all ACPI CPUs have attached.
280 */ 280 */
281 if (++count != acpicpu_count || acpicpu_count != sc->sc_ncpus) { 281 if (++count != acpicpu_count || acpicpu_count != sc->sc_ncpus) {
282 sc->sc_cold = false; 282 sc->sc_cold = false;
283 return; 283 return;
284 } 284 }
285 285
286 /* 286 /*
287 * Set the last ACPI CPU as non-cold 287 * Set the last ACPI CPU as non-cold
288 * only after C-states are enabled. 288 * only after C-states are enabled.
289 */ 289 */
290 if ((sc->sc_flags & ACPICPU_FLAG_C) != 0) 290 if ((sc->sc_flags & ACPICPU_FLAG_C) != 0)
291 acpicpu_cstate_start(self); 291 acpicpu_cstate_start(self);
292 292
293 sc->sc_cold = false; 293 sc->sc_cold = false;
294 294
295 if ((sc->sc_flags & ACPICPU_FLAG_P) != 0) 295 if ((sc->sc_flags & ACPICPU_FLAG_P) != 0)
296 acpicpu_pstate_start(self); 296 acpicpu_pstate_start(self);
297 297
298 if ((sc->sc_flags & ACPICPU_FLAG_T) != 0) 298 if ((sc->sc_flags & ACPICPU_FLAG_T) != 0)
299 acpicpu_tstate_start(self); 299 acpicpu_tstate_start(self);
300 300
301 acpicpu_sysctl(self); 301 acpicpu_sysctl(self);
302 aprint_debug_dev(self, "ACPI CPUs started\n"); 302 aprint_debug_dev(self, "ACPI CPUs started\n");
303 303
304 /* 304 /*
305 * Register with cpufreq(9). 305 * Register with cpufreq(9).
306 */ 306 */
307 if ((sc->sc_flags & ACPICPU_FLAG_P) != 0) { 307 if ((sc->sc_flags & ACPICPU_FLAG_P) != 0) {
308 308
309 (void)memset(&cf, 0, sizeof(struct cpufreq)); 309 (void)memset(&cf, 0, sizeof(struct cpufreq));
310 310
311 cf.cf_mp = false; 311 cf.cf_mp = false;
312 cf.cf_cookie = NULL; 312 cf.cf_cookie = NULL;
313 cf.cf_get_freq = acpicpu_pstate_get; 313 cf.cf_get_freq = acpicpu_pstate_get;
314 cf.cf_set_freq = acpicpu_pstate_set; 314 cf.cf_set_freq = acpicpu_pstate_set;
315 cf.cf_state_count = sc->sc_pstate_count; 315 cf.cf_state_count = sc->sc_pstate_count;
316 316
317 (void)strlcpy(cf.cf_name, "acpicpu", sizeof(cf.cf_name)); 317 (void)strlcpy(cf.cf_name, "acpicpu", sizeof(cf.cf_name));
318 318
319 for (i = 0; i < sc->sc_pstate_count; i++) { 319 for (i = 0; i < sc->sc_pstate_count; i++) {
320 320
321 if (sc->sc_pstate[i].ps_freq == 0) 321 if (sc->sc_pstate[i].ps_freq == 0)
322 continue; 322 continue;
323 323
324 cf.cf_state[i].cfs_freq = sc->sc_pstate[i].ps_freq; 324 cf.cf_state[i].cfs_freq = sc->sc_pstate[i].ps_freq;
325 cf.cf_state[i].cfs_power = sc->sc_pstate[i].ps_power; 325 cf.cf_state[i].cfs_power = sc->sc_pstate[i].ps_power;
326 } 326 }
327 327
328 if (cpufreq_register(&cf) != 0) 328 if (cpufreq_register(&cf) != 0)
329 aprint_error_dev(self, "failed to register cpufreq\n"); 329 aprint_error_dev(self, "failed to register cpufreq\n");
330 } 330 }
331} 331}
332 332
333static void 333static void
334acpicpu_sysctl(device_t self) 334acpicpu_sysctl(device_t self)
335{ 335{
336 const struct sysctlnode *node; 336 const struct sysctlnode *node;
337 int err; 337 int err;
338 338
339 KASSERT(acpicpu_log == NULL); 339 KASSERT(acpicpu_log == NULL);
340 340
341 err = sysctl_createv(&acpicpu_log, 0, NULL, &node, 341 err = sysctl_createv(&acpicpu_log, 0, NULL, &node,
342 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL, 342 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
343 NULL, 0, NULL, 0, CTL_HW, CTL_EOL); 343 NULL, 0, NULL, 0, CTL_HW, CTL_EOL);
344 344
345 if (err != 0) 345 if (err != 0)
346 goto fail; 346 goto fail;
347 347
348 err = sysctl_createv(&acpicpu_log, 0, &node, &node, 348 err = sysctl_createv(&acpicpu_log, 0, &node, &node,
349 CTLFLAG_PERMANENT, CTLTYPE_NODE, "acpi", NULL, 349 CTLFLAG_PERMANENT, CTLTYPE_NODE, "acpi", NULL,
350 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 350 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
351 351
352 if (err != 0) 352 if (err != 0)
353 goto fail; 353 goto fail;
354 354
355 err = sysctl_createv(&acpicpu_log, 0, &node, &node, 355 err = sysctl_createv(&acpicpu_log, 0, &node, &node,
356 0, CTLTYPE_NODE, "cpu", SYSCTL_DESCR("ACPI CPU"), 356 0, CTLTYPE_NODE, "cpu", SYSCTL_DESCR("ACPI CPU"),
357 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 357 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
358 358
359 if (err != 0) 359 if (err != 0)
360 goto fail; 360 goto fail;
361 361
362 err = sysctl_createv(&acpicpu_log, 0, &node, NULL, 362 err = sysctl_createv(&acpicpu_log, 0, &node, NULL,
363 CTLFLAG_READWRITE, CTLTYPE_BOOL, "dynamic", 363 CTLFLAG_READWRITE, CTLTYPE_BOOL, "dynamic",
364 SYSCTL_DESCR("Dynamic states"), NULL, 0, 364 SYSCTL_DESCR("Dynamic states"), NULL, 0,
365 &acpicpu_dynamic, 0, CTL_CREATE, CTL_EOL); 365 &acpicpu_dynamic, 0, CTL_CREATE, CTL_EOL);
366 366
367 if (err != 0) 367 if (err != 0)
368 goto fail; 368 goto fail;
369 369
370 err = sysctl_createv(&acpicpu_log, 0, &node, NULL, 370 err = sysctl_createv(&acpicpu_log, 0, &node, NULL,
371 CTLFLAG_READWRITE, CTLTYPE_BOOL, "passive", 371 CTLFLAG_READWRITE, CTLTYPE_BOOL, "passive",
372 SYSCTL_DESCR("Passive cooling"), NULL, 0, 372 SYSCTL_DESCR("Passive cooling"), NULL, 0,
373 &acpicpu_passive, 0, CTL_CREATE, CTL_EOL); 373 &acpicpu_passive, 0, CTL_CREATE, CTL_EOL);
374 374
375 if (err != 0) 375 if (err != 0)
376 goto fail; 376 goto fail;
377 377
378 return; 378 return;
379 379
380fail: 380fail:
381 aprint_error_dev(self, "failed to initialize sysctl (err %d)\n", err); 381 aprint_error_dev(self, "failed to initialize sysctl (err %d)\n", err);
382} 382}
383 383
384static ACPI_STATUS 384static ACPI_STATUS
385acpicpu_object(ACPI_HANDLE hdl, struct acpicpu_object *ao) 385acpicpu_object(ACPI_HANDLE hdl, struct acpicpu_object *ao)
386{ 386{
387 ACPI_OBJECT *obj; 387 ACPI_OBJECT *obj;
388 ACPI_BUFFER buf; 388 ACPI_BUFFER buf;
389 ACPI_STATUS rv; 389 ACPI_STATUS rv;
390 390
391 rv = acpi_eval_struct(hdl, NULL, &buf); 391 rv = acpi_eval_struct(hdl, NULL, &buf);
392 392
393 if (ACPI_FAILURE(rv)) 393 if (ACPI_FAILURE(rv))
394 goto out; 394 goto out;
395 395
396 obj = buf.Pointer; 396 obj = buf.Pointer;
397 397
398 if (obj->Type != ACPI_TYPE_PROCESSOR) { 398 if (obj->Type != ACPI_TYPE_PROCESSOR) {
399 rv = AE_TYPE; 399 rv = AE_TYPE;
400 goto out; 400 goto out;
401 } 401 }
402 402
403 if (obj->Processor.ProcId > (uint32_t)maxcpus) { 403 if (obj->Processor.ProcId > (uint32_t)maxcpus) {
404 rv = AE_LIMIT; 404 rv = AE_LIMIT;
405 goto out; 405 goto out;
406 } 406 }
407 407
408 KDASSERT((uint64_t)obj->Processor.PblkAddress < UINT32_MAX); 408 KDASSERT((uint64_t)obj->Processor.PblkAddress < UINT32_MAX);
409 409
410 if (ao != NULL) { 410 if (ao != NULL) {
411 ao->ao_procid = obj->Processor.ProcId; 411 ao->ao_procid = obj->Processor.ProcId;
412 ao->ao_pblklen = obj->Processor.PblkLength; 412 ao->ao_pblklen = obj->Processor.PblkLength;
413 ao->ao_pblkaddr = obj->Processor.PblkAddress; 413 ao->ao_pblkaddr = obj->Processor.PblkAddress;
414 } 414 }
415 415
416out: 416out:
417 if (buf.Pointer != NULL) 417 if (buf.Pointer != NULL)
418 ACPI_FREE(buf.Pointer); 418 ACPI_FREE(buf.Pointer);
419 419
420 return rv; 420 return rv;
421} 421}
422 422
423static uint32_t 423static uint32_t
424acpicpu_cap(struct acpicpu_softc *sc) 424acpicpu_cap(struct acpicpu_softc *sc)
425{ 425{
426 uint32_t flags, cap = 0; 426 uint32_t flags, cap = 0;
427 ACPI_STATUS rv; 427 ACPI_STATUS rv;
428 428
429 /* 429 /*
430 * Query and set machine-dependent capabilities. 430 * Query and set machine-dependent capabilities.
431 * Note that the Intel-specific _PDC method has 431 * Note that the Intel-specific _PDC method has
432 * already been evaluated. It was furthermore 432 * already been evaluated. It was furthermore
433 * deprecated in the ACPI 3.0 in favor of _OSC. 433 * deprecated in the ACPI 3.0 in favor of _OSC.
434 */ 434 */
435 flags = acpi_md_pdc(); 435 flags = acpi_md_pdc();
436 rv = acpicpu_cap_osc(sc, flags, &cap); 436 rv = acpicpu_cap_osc(sc, flags, &cap);
437 437
438 if (ACPI_FAILURE(rv) && rv != AE_NOT_FOUND) { 438 if (ACPI_FAILURE(rv) && rv != AE_NOT_FOUND) {
439 439
440 aprint_error_dev(sc->sc_dev, "failed to evaluate " 440 aprint_error_dev(sc->sc_dev, "failed to evaluate "
441 "_OSC: %s\n", AcpiFormatException(rv)); 441 "_OSC: %s\n", AcpiFormatException(rv));
442 } 442 }
443 443
444 return (cap != 0) ? cap : flags; 444 return (cap != 0) ? cap : flags;
445} 445}
446 446
447static ACPI_STATUS 447static ACPI_STATUS
448acpicpu_cap_osc(struct acpicpu_softc *sc, uint32_t flags, uint32_t *val) 448acpicpu_cap_osc(struct acpicpu_softc *sc, uint32_t flags, uint32_t *val)
449{ 449{
450 ACPI_OBJECT_LIST arg; 450 ACPI_OBJECT_LIST arg;
451 ACPI_OBJECT obj[4]; 451 ACPI_OBJECT obj[4];
452 ACPI_OBJECT *osc; 452 ACPI_OBJECT *osc;
453 ACPI_BUFFER buf; 453 ACPI_BUFFER buf;
454 ACPI_STATUS rv; 454 ACPI_STATUS rv;
455 uint32_t cap[2]; 455 uint32_t cap[2];
456 uint32_t *ptr; 456 uint32_t *ptr;
457 int i = 5; 457 int i = 5;
458 458
459 static uint8_t intel_uuid[16] = { 459 static uint8_t intel_uuid[16] = {
460 0x16, 0xA6, 0x77, 0x40, 0x0C, 0x29, 0xBE, 0x47, 460 0x16, 0xA6, 0x77, 0x40, 0x0C, 0x29, 0xBE, 0x47,
461 0x9E, 0xBD, 0xD8, 0x70, 0x58, 0x71, 0x39, 0x53 461 0x9E, 0xBD, 0xD8, 0x70, 0x58, 0x71, 0x39, 0x53
462 }; 462 };
463 463
464 cap[0] = ACPI_OSC_QUERY; 464 cap[0] = ACPI_OSC_QUERY;
465 cap[1] = flags; 465 cap[1] = flags;
466 466
467again: 467again:
468 arg.Count = 4; 468 arg.Count = 4;
469 arg.Pointer = obj; 469 arg.Pointer = obj;
470 470
471 obj[0].Type = ACPI_TYPE_BUFFER; 471 obj[0].Type = ACPI_TYPE_BUFFER;
472 obj[0].Buffer.Length = sizeof(intel_uuid); 472 obj[0].Buffer.Length = sizeof(intel_uuid);
473 obj[0].Buffer.Pointer = intel_uuid; 473 obj[0].Buffer.Pointer = intel_uuid;
474 474
475 obj[1].Type = ACPI_TYPE_INTEGER; 475 obj[1].Type = ACPI_TYPE_INTEGER;
476 obj[1].Integer.Value = ACPICPU_PDC_REVID; 476 obj[1].Integer.Value = ACPICPU_PDC_REVID;
477 477
478 obj[2].Type = ACPI_TYPE_INTEGER; 478 obj[2].Type = ACPI_TYPE_INTEGER;
479 obj[2].Integer.Value = __arraycount(cap); 479 obj[2].Integer.Value = __arraycount(cap);
480 480
481 obj[3].Type = ACPI_TYPE_BUFFER; 481 obj[3].Type = ACPI_TYPE_BUFFER;
482 obj[3].Buffer.Length = sizeof(cap); 482 obj[3].Buffer.Length = sizeof(cap);
483 obj[3].Buffer.Pointer = (void *)cap; 483 obj[3].Buffer.Pointer = (void *)cap;
484 484
485 buf.Pointer = NULL; 485 buf.Pointer = NULL;
486 buf.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 486 buf.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
487 487
488 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "_OSC", &arg, &buf); 488 rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "_OSC", &arg, &buf);
489 489
490 if (ACPI_FAILURE(rv)) 490 if (ACPI_FAILURE(rv))
491 goto out; 491 goto out;
492 492
493 osc = buf.Pointer; 493 osc = buf.Pointer;
494 494
495 if (osc->Type != ACPI_TYPE_BUFFER) { 495 if (osc->Type != ACPI_TYPE_BUFFER) {
496 rv = AE_TYPE; 496 rv = AE_TYPE;
497 goto out; 497 goto out;
498 } 498 }
499 499
500 if (osc->Buffer.Length != sizeof(cap)) { 500 if (osc->Buffer.Length != sizeof(cap)) {
501 rv = AE_BUFFER_OVERFLOW; 501 rv = AE_BUFFER_OVERFLOW;
502 goto out; 502 goto out;
503 } 503 }
504 504
505 ptr = (uint32_t *)osc->Buffer.Pointer; 505 ptr = (uint32_t *)osc->Buffer.Pointer;
506 506
507 if ((ptr[0] & ACPI_OSC_ERROR) != 0) { 507 if ((ptr[0] & ACPI_OSC_ERROR) != 0) {
508 rv = AE_ERROR; 508 rv = AE_ERROR;
509 goto out; 509 goto out;
510 } 510 }
511 511
512 if ((ptr[0] & (ACPI_OSC_ERROR_REV | ACPI_OSC_ERROR_UUID)) != 0) { 512 if ((ptr[0] & (ACPI_OSC_ERROR_REV | ACPI_OSC_ERROR_UUID)) != 0) {
513 rv = AE_BAD_PARAMETER; 513 rv = AE_BAD_PARAMETER;
514 goto out; 514 goto out;
515 } 515 }
516 516
517 /* 517 /*
518 * "It is strongly recommended that the OS evaluate 518 * "It is strongly recommended that the OS evaluate
519 * _OSC with the Query Support Flag set until _OSC 519 * _OSC with the Query Support Flag set until _OSC
520 * returns the Capabilities Masked bit clear, to 520 * returns the Capabilities Masked bit clear, to
521 * negotiate the set of features to be granted to 521 * negotiate the set of features to be granted to
522 * the OS for native support (ACPI 4.0, 6.2.10)." 522 * the OS for native support (ACPI 4.0, 6.2.10)."
523 */ 523 */
524 if ((ptr[0] & ACPI_OSC_ERROR_MASKED) != 0 && i >= 0) { 524 if ((ptr[0] & ACPI_OSC_ERROR_MASKED) != 0 && i >= 0) {
525 525
526 ACPI_FREE(buf.Pointer); 526 ACPI_FREE(buf.Pointer);
527 i--; 527 i--;
528 528
529 goto again; 529 goto again;
530 } 530 }
531 531
532 if ((cap[0] & ACPI_OSC_QUERY) != 0) { 532 if ((cap[0] & ACPI_OSC_QUERY) != 0) {
533 533
534 ACPI_FREE(buf.Pointer); 534 ACPI_FREE(buf.Pointer);
535 cap[0] &= ~ACPI_OSC_QUERY; 535 cap[0] &= ~ACPI_OSC_QUERY;
536 536
537 goto again; 537 goto again;
538 } 538 }
539 539
540 /* 540 /*
541 * It is permitted for _OSC to return all 541 * It is permitted for _OSC to return all
542 * bits cleared, but this is specified to 542 * bits cleared, but this is specified to
543 * vary on per-device basis. Assume that 543 * vary on per-device basis. Assume that
544 * everything rather than nothing will be 544 * everything rather than nothing will be
545 * supported in this case; we do not need 545 * supported in this case; we do not need
546 * the firmware to know the CPU features. 546 * the firmware to know the CPU features.
547 */ 547 */
548 *val = (ptr[1] != 0) ? ptr[1] : cap[1]; 548 *val = (ptr[1] != 0) ? ptr[1] : cap[1];
549 549
550out: 550out:
551 if (buf.Pointer != NULL) 551 if (buf.Pointer != NULL)
552 ACPI_FREE(buf.Pointer); 552 ACPI_FREE(buf.Pointer);
553 553
554 return rv; 554 return rv;
555} 555}
556 556
557static void 557static void
558acpicpu_notify(ACPI_HANDLE hdl, uint32_t evt, void *aux) 558acpicpu_notify(ACPI_HANDLE hdl, uint32_t evt, void *aux)
559{ 559{
560 ACPI_OSD_EXEC_CALLBACK func; 560 ACPI_OSD_EXEC_CALLBACK func;
561 struct acpicpu_softc *sc; 561 struct acpicpu_softc *sc;
562 device_t self = aux; 562 device_t self = aux;
563 563
564 sc = device_private(self); 564 sc = device_private(self);
565 565
566 if (sc->sc_cold != false) 566 if (sc->sc_cold != false)
567 return; 567 return;
568 568
569 if (acpicpu_dynamic != true) 569 if (acpicpu_dynamic != true)
570 return; 570 return;
571 571
572 switch (evt) { 572 switch (evt) {
573 573
574 case ACPICPU_C_NOTIFY: 574 case ACPICPU_C_NOTIFY:
575 575
576 if ((sc->sc_flags & ACPICPU_FLAG_C) == 0) 576 if ((sc->sc_flags & ACPICPU_FLAG_C) == 0)
577 return; 577 return;
578 578
579 func = acpicpu_cstate_callback; 579 func = acpicpu_cstate_callback;
580 break; 580 break;
581 581
582 case ACPICPU_P_NOTIFY: 582 case ACPICPU_P_NOTIFY:
583 583
584 if ((sc->sc_flags & ACPICPU_FLAG_P) == 0) 584 if ((sc->sc_flags & ACPICPU_FLAG_P) == 0)
585 return; 585 return;
586 586
587 func = acpicpu_pstate_callback; 587 func = acpicpu_pstate_callback;
588 break; 588 break;
589 589
590 case ACPICPU_T_NOTIFY: 590 case ACPICPU_T_NOTIFY:
591 591
592 if ((sc->sc_flags & ACPICPU_FLAG_T) == 0) 592 if ((sc->sc_flags & ACPICPU_FLAG_T) == 0)
593 return; 593 return;
594 594
595 func = acpicpu_tstate_callback; 595 func = acpicpu_tstate_callback;
596 break; 596 break;
597 597
598 default: 598 default:
599 aprint_error_dev(sc->sc_dev, "unknown notify: 0x%02X\n", evt); 599 aprint_error_dev(sc->sc_dev, "unknown notify: 0x%02X\n", evt);
600 return; 600 return;
601 } 601 }
602 602
603 (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, func, sc->sc_dev); 603 (void)AcpiOsExecute(OSL_NOTIFY_HANDLER, func, sc->sc_dev);
604} 604}
605 605
606static bool 606static bool
607acpicpu_suspend(device_t self, const pmf_qual_t *qual) 607acpicpu_suspend(device_t self, const pmf_qual_t *qual)
608{ 608{
609 struct acpicpu_softc *sc = device_private(self); 609 struct acpicpu_softc *sc = device_private(self);
610 610
611 if ((sc->sc_flags & ACPICPU_FLAG_C) != 0) 611 if ((sc->sc_flags & ACPICPU_FLAG_C) != 0)
612 (void)acpicpu_cstate_suspend(self); 612 (void)acpicpu_cstate_suspend(self);
613 613
614 if ((sc->sc_flags & ACPICPU_FLAG_P) != 0) 614 if ((sc->sc_flags & ACPICPU_FLAG_P) != 0)
615 (void)acpicpu_pstate_suspend(self); 615 (void)acpicpu_pstate_suspend(self);
616 616
617 if ((sc->sc_flags & ACPICPU_FLAG_T) != 0) 617 if ((sc->sc_flags & ACPICPU_FLAG_T) != 0)
618 (void)acpicpu_tstate_suspend(self); 618 (void)acpicpu_tstate_suspend(self);
619 619
620 sc->sc_cold = true; 620 sc->sc_cold = true;
621 621
622 return true; 622 return true;
623} 623}
624 624
625static bool 625static bool
626acpicpu_resume(device_t self, const pmf_qual_t *qual) 626acpicpu_resume(device_t self, const pmf_qual_t *qual)
627{ 627{
628 struct acpicpu_softc *sc = device_private(self); 628 struct acpicpu_softc *sc = device_private(self);
629 static const int handler = OSL_NOTIFY_HANDLER; 629 static const int handler = OSL_NOTIFY_HANDLER;
630 630
631 sc->sc_cold = false; 631 sc->sc_cold = false;
632 632
633 if ((sc->sc_flags & ACPICPU_FLAG_C) != 0) 633 if ((sc->sc_flags & ACPICPU_FLAG_C) != 0)
634 (void)AcpiOsExecute(handler, acpicpu_cstate_resume, self); 634 (void)AcpiOsExecute(handler, acpicpu_cstate_resume, self);
635 635
636 if ((sc->sc_flags & ACPICPU_FLAG_P) != 0) 636 if ((sc->sc_flags & ACPICPU_FLAG_P) != 0)
637 (void)AcpiOsExecute(handler, acpicpu_pstate_resume, self); 637 (void)AcpiOsExecute(handler, acpicpu_pstate_resume, self);
638 638
639 if ((sc->sc_flags & ACPICPU_FLAG_T) != 0) 639 if ((sc->sc_flags & ACPICPU_FLAG_T) != 0)
640 (void)AcpiOsExecute(handler, acpicpu_tstate_resume, self); 640 (void)AcpiOsExecute(handler, acpicpu_tstate_resume, self);
641 641
642 return true; 642 return true;
643} 643}
644 644
645static void 645static void
646acpicpu_evcnt_attach(device_t self) 646acpicpu_evcnt_attach(device_t self)
647{ 647{
648 struct acpicpu_softc *sc = device_private(self); 648 struct acpicpu_softc *sc = device_private(self);
649 struct acpicpu_cstate *cs; 649 struct acpicpu_cstate *cs;
650 struct acpicpu_pstate *ps; 650 struct acpicpu_pstate *ps;
651 struct acpicpu_tstate *ts; 651 struct acpicpu_tstate *ts;
652 const char *str; 652 const char *str;
653 uint32_t i; 653 uint32_t i;
654 654
655 for (i = 0; i < __arraycount(sc->sc_cstate); i++) { 655 for (i = 0; i < __arraycount(sc->sc_cstate); i++) {
656 656
657 cs = &sc->sc_cstate[i]; 657 cs = &sc->sc_cstate[i];
658 658
659 if (cs->cs_method == 0) 659 if (cs->cs_method == 0)
660 continue; 660 continue;
661 661
662 str = "HALT"; 662 str = "HALT";
663 663
664 if (cs->cs_method == ACPICPU_C_STATE_FFH) 664 if (cs->cs_method == ACPICPU_C_STATE_FFH)
665 str = "MWAIT"; 665 str = "MWAIT";
666 666
667 if (cs->cs_method == ACPICPU_C_STATE_SYSIO) 667 if (cs->cs_method == ACPICPU_C_STATE_SYSIO)
668 str = "I/O"; 668 str = "I/O";
669 669
670 (void)snprintf(cs->cs_name, sizeof(cs->cs_name), 670 (void)snprintf(cs->cs_name, sizeof(cs->cs_name),
671 "C%d (%s)", i, str); 671 "C%d (%s)", i, str);
672 672
673 evcnt_attach_dynamic(&cs->cs_evcnt, EVCNT_TYPE_MISC, 673 evcnt_attach_dynamic(&cs->cs_evcnt, EVCNT_TYPE_MISC,
674 NULL, device_xname(sc->sc_dev), cs->cs_name); 674 NULL, device_xname(sc->sc_dev), cs->cs_name);
675 } 675 }
676 676
677 for (i = 0; i < sc->sc_pstate_count; i++) { 677 for (i = 0; i < sc->sc_pstate_count; i++) {
678 678
679 ps = &sc->sc_pstate[i]; 679 ps = &sc->sc_pstate[i];
680 680
681 if (ps->ps_freq == 0) 681 if (ps->ps_freq == 0)
682 continue; 682 continue;
683 683
684 (void)snprintf(ps->ps_name, sizeof(ps->ps_name), 684 (void)snprintf(ps->ps_name, sizeof(ps->ps_name),
685 "P%u (%u MHz)", i, ps->ps_freq); 685 "P%u (%u MHz)", i, ps->ps_freq);
686 686
687 evcnt_attach_dynamic(&ps->ps_evcnt, EVCNT_TYPE_MISC, 687 evcnt_attach_dynamic(&ps->ps_evcnt, EVCNT_TYPE_MISC,
688 NULL, device_xname(sc->sc_dev), ps->ps_name); 688 NULL, device_xname(sc->sc_dev), ps->ps_name);
689 } 689 }
690 690
691 for (i = 0; i < sc->sc_tstate_count; i++) { 691 for (i = 0; i < sc->sc_tstate_count; i++) {
692 692
693 ts = &sc->sc_tstate[i]; 693 ts = &sc->sc_tstate[i];
694 694
695 if (ts->ts_percent == 0) 695 if (ts->ts_percent == 0)
696 continue; 696 continue;
697 697
698 (void)snprintf(ts->ts_name, sizeof(ts->ts_name), 698 (void)snprintf(ts->ts_name, sizeof(ts->ts_name),
699 "T%u (%u %%)", i, ts->ts_percent); 699 "T%u (%u %%)", i, ts->ts_percent);
700 700
701 evcnt_attach_dynamic(&ts->ts_evcnt, EVCNT_TYPE_MISC, 701 evcnt_attach_dynamic(&ts->ts_evcnt, EVCNT_TYPE_MISC,
702 NULL, device_xname(sc->sc_dev), ts->ts_name); 702 NULL, device_xname(sc->sc_dev), ts->ts_name);
703 } 703 }
704} 704}
705 705
706static void 706static void
707acpicpu_evcnt_detach(device_t self) 707acpicpu_evcnt_detach(device_t self)
708{ 708{
709 struct acpicpu_softc *sc = device_private(self); 709 struct acpicpu_softc *sc = device_private(self);
710 struct acpicpu_cstate *cs; 710 struct acpicpu_cstate *cs;
711 struct acpicpu_pstate *ps; 711 struct acpicpu_pstate *ps;
712 struct acpicpu_tstate *ts; 712 struct acpicpu_tstate *ts;
713 uint32_t i; 713 uint32_t i;
714 714
715 for (i = 0; i < __arraycount(sc->sc_cstate); i++) { 715 for (i = 0; i < __arraycount(sc->sc_cstate); i++) {
716 716
717 cs = &sc->sc_cstate[i]; 717 cs = &sc->sc_cstate[i];
718 718
719 if (cs->cs_method != 0) 719 if (cs->cs_method != 0)
720 evcnt_detach(&cs->cs_evcnt); 720 evcnt_detach(&cs->cs_evcnt);
721 } 721 }
722 722
723 for (i = 0; i < sc->sc_pstate_count; i++) { 723 for (i = 0; i < sc->sc_pstate_count; i++) {
724 724
725 ps = &sc->sc_pstate[i]; 725 ps = &sc->sc_pstate[i];
726 726
727 if (ps->ps_freq != 0) 727 if (ps->ps_freq != 0)
728 evcnt_detach(&ps->ps_evcnt); 728 evcnt_detach(&ps->ps_evcnt);
729 } 729 }
730 730
731 for (i = 0; i < sc->sc_tstate_count; i++) { 731 for (i = 0; i < sc->sc_tstate_count; i++) {
732 732
733 ts = &sc->sc_tstate[i]; 733 ts = &sc->sc_tstate[i];
734 734
735 if (ts->ts_percent != 0) 735 if (ts->ts_percent != 0)
736 evcnt_detach(&ts->ts_evcnt); 736 evcnt_detach(&ts->ts_evcnt);
737 } 737 }
738} 738}
739 739
740static void 740static void
741acpicpu_debug_print(device_t self) 741acpicpu_debug_print(device_t self)
742{ 742{
743 struct acpicpu_softc *sc = device_private(self); 743 struct acpicpu_softc *sc = device_private(self);
744 struct cpu_info *ci = sc->sc_ci; 744 struct cpu_info *ci = sc->sc_ci;
745 struct acpicpu_cstate *cs; 745 struct acpicpu_cstate *cs;
746 struct acpicpu_pstate *ps; 746 struct acpicpu_pstate *ps;
747 struct acpicpu_tstate *ts; 747 struct acpicpu_tstate *ts;
748 static bool once = false; 748 static bool once = false;
749 struct acpicpu_dep *dep; 749 struct acpicpu_dep *dep;
750 uint32_t i, method; 750 uint32_t i, method;
751 751
752 if (once != true) { 752 if (once != true) {
753 753
754 for (i = 0; i < __arraycount(sc->sc_cstate); i++) { 754 for (i = 0; i < __arraycount(sc->sc_cstate); i++) {
755 755
756 cs = &sc->sc_cstate[i]; 756 cs = &sc->sc_cstate[i];
757 757
758 if (cs->cs_method == 0) 758 if (cs->cs_method == 0)
759 continue; 759 continue;
760 760
761 aprint_verbose_dev(sc->sc_dev, "C%d: %3s, " 761 aprint_verbose_dev(sc->sc_dev, "C%d: %3s, "
762 "lat %3u us, pow %5u mW%s\n", i, 762 "lat %3u us, pow %5u mW%s\n", i,
763 acpicpu_debug_print_method_c(cs->cs_method), 763 acpicpu_debug_print_method_c(cs->cs_method),
764 cs->cs_latency, cs->cs_power, 764 cs->cs_latency, cs->cs_power,
765 (cs->cs_flags != 0) ? ", bus master check" : ""); 765 (cs->cs_flags != 0) ? ", bus master check" : "");
766 } 766 }
767 767
768 method = sc->sc_pstate_control.reg_spaceid; 768 method = sc->sc_pstate_control.reg_spaceid;
769 769
770 for (i = 0; i < sc->sc_pstate_count; i++) { 770 for (i = 0; i < sc->sc_pstate_count; i++) {
771 771
772 ps = &sc->sc_pstate[i]; 772 ps = &sc->sc_pstate[i];
773 773
774 if (ps->ps_freq == 0) 774 if (ps->ps_freq == 0)
775 continue; 775 continue;
776 776
777 aprint_verbose_dev(sc->sc_dev, "P%d: %3s, " 777 aprint_verbose_dev(sc->sc_dev, "P%d: %3s, "
778 "lat %3u us, pow %5u mW, %4u MHz%s\n", i, 778 "lat %3u us, pow %5u mW, %4u MHz%s\n", i,
779 acpicpu_debug_print_method_pt(method), 779 acpicpu_debug_print_method_pt(method),
780 ps->ps_latency, ps->ps_power, ps->ps_freq, 780 ps->ps_latency, ps->ps_power, ps->ps_freq,
781 (ps->ps_flags & ACPICPU_FLAG_P_TURBO) != 0 ? 781 (ps->ps_flags & ACPICPU_FLAG_P_TURBO) != 0 ?
782 ", turbo boost" : ""); 782 ", turbo boost" : "");
783 } 783 }
784 784
785 method = sc->sc_tstate_control.reg_spaceid; 785 method = sc->sc_tstate_control.reg_spaceid;
786 786
787 for (i = 0; i < sc->sc_tstate_count; i++) { 787 for (i = 0; i < sc->sc_tstate_count; i++) {
788 788
789 ts = &sc->sc_tstate[i]; 789 ts = &sc->sc_tstate[i];
790 790
791 if (ts->ts_percent == 0) 791 if (ts->ts_percent == 0)
792 continue; 792 continue;
793 793
794 aprint_verbose_dev(sc->sc_dev, "T%u: %3s, " 794 aprint_verbose_dev(sc->sc_dev, "T%u: %3s, "
795 "lat %3u us, pow %5u mW, %3u %%\n", i, 795 "lat %3u us, pow %5u mW, %3u %%\n", i,
796 acpicpu_debug_print_method_pt(method), 796 acpicpu_debug_print_method_pt(method),
797 ts->ts_latency, ts->ts_power, ts->ts_percent); 797 ts->ts_latency, ts->ts_power, ts->ts_percent);
798 } 798 }
799 799
800 once = true; 800 once = true;
801 } 801 }
802 802
803 aprint_debug_dev(sc->sc_dev, "id %u, lapic id %u, " 803 aprint_debug_dev(sc->sc_dev, "id %u, lapic id %u, "
804 "cap 0x%04x, flags 0x%08x\n", ci->ci_acpiid, 804 "cap 0x%04x, flags 0x%08x\n", ci->ci_acpiid,
805 (uint32_t)ci->ci_cpuid, sc->sc_cap, sc->sc_flags); 805 (uint32_t)ci->ci_cpuid, sc->sc_cap, sc->sc_flags);
806 806
807 if ((sc->sc_flags & ACPICPU_FLAG_C_DEP) != 0) { 807 if ((sc->sc_flags & ACPICPU_FLAG_C_DEP) != 0) {
808 808
809 dep = &sc->sc_cstate_dep; 809 dep = &sc->sc_cstate_dep;
810 810
811 aprint_debug_dev(sc->sc_dev, "C-state coordination: " 811 aprint_debug_dev(sc->sc_dev, "C-state coordination: "
812 "%u CPUs, domain %u, type %s\n", dep->dep_ncpus, 812 "%u CPUs, domain %u, type %s\n", dep->dep_ncpus,
813 dep->dep_domain, acpicpu_debug_print_dep(dep->dep_type)); 813 dep->dep_domain, acpicpu_debug_print_dep(dep->dep_type));
814 } 814 }
815 815
816 if ((sc->sc_flags & ACPICPU_FLAG_P_DEP) != 0) { 816 if ((sc->sc_flags & ACPICPU_FLAG_P_DEP) != 0) {
817 817
818 dep = &sc->sc_pstate_dep; 818 dep = &sc->sc_pstate_dep;
819 819
820 aprint_debug_dev(sc->sc_dev, "P-state coordination: " 820 aprint_debug_dev(sc->sc_dev, "P-state coordination: "
821 "%u CPUs, domain %u, type %s\n", dep->dep_ncpus, 821 "%u CPUs, domain %u, type %s\n", dep->dep_ncpus,
822 dep->dep_domain, acpicpu_debug_print_dep(dep->dep_type)); 822 dep->dep_domain, acpicpu_debug_print_dep(dep->dep_type));
823 } 823 }
824 824
825 if ((sc->sc_flags & ACPICPU_FLAG_T_DEP) != 0) { 825 if ((sc->sc_flags & ACPICPU_FLAG_T_DEP) != 0) {
826 826
827 dep = &sc->sc_tstate_dep; 827 dep = &sc->sc_tstate_dep;
828 828
829 aprint_debug_dev(sc->sc_dev, "T-state coordination: " 829 aprint_debug_dev(sc->sc_dev, "T-state coordination: "
830 "%u CPUs, domain %u, type %s\n", dep->dep_ncpus, 830 "%u CPUs, domain %u, type %s\n", dep->dep_ncpus,
831 dep->dep_domain, acpicpu_debug_print_dep(dep->dep_type)); 831 dep->dep_domain, acpicpu_debug_print_dep(dep->dep_type));
832 } 832 }
833} 833}
834 834
835static const char * 835static const char *
836acpicpu_debug_print_method_c(uint8_t val) 836acpicpu_debug_print_method_c(uint8_t val)
837{ 837{
838 838
839 if (val == ACPICPU_C_STATE_FFH) 839 if (val == ACPICPU_C_STATE_FFH)
840 return "FFH"; 840 return "FFH";
841 841
842 if (val == ACPICPU_C_STATE_HALT) 842 if (val == ACPICPU_C_STATE_HALT)
843 return "HLT"; 843 return "HLT";
844 844
845 if (val == ACPICPU_C_STATE_SYSIO) 845 if (val == ACPICPU_C_STATE_SYSIO)
846 return "I/O"; 846 return "I/O";
847 847
848 return "???"; 848 return "???";
849} 849}
850 850
851static const char * 851static const char *
852acpicpu_debug_print_method_pt(uint8_t val) 852acpicpu_debug_print_method_pt(uint8_t val)
853{ 853{
854 854
855 if (val == ACPI_ADR_SPACE_SYSTEM_IO) 855 if (val == ACPI_ADR_SPACE_SYSTEM_IO)
856 return "I/O"; 856 return "I/O";
857 857
858 if (val == ACPI_ADR_SPACE_FIXED_HARDWARE) 858 if (val == ACPI_ADR_SPACE_FIXED_HARDWARE)
859 return "FFH"; 859 return "FFH";
860 860
861 return "???"; 861 return "???";
862} 862}
863 863
864static const char * 864static const char *
865acpicpu_debug_print_dep(uint32_t val) 865acpicpu_debug_print_dep(uint32_t val)
866{ 866{
867 867
868 switch (val) { 868 switch (val) {
869 869
870 case ACPICPU_DEP_SW_ALL: 870 case ACPICPU_DEP_SW_ALL:
871 return "SW_ALL"; 871 return "SW_ALL";
872 872
873 case ACPICPU_DEP_SW_ANY: 873 case ACPICPU_DEP_SW_ANY:
874 return "SW_ANY"; 874 return "SW_ANY";
875 875
876 case ACPICPU_DEP_HW_ALL: 876 case ACPICPU_DEP_HW_ALL:
877 return "HW_ALL"; 877 return "HW_ALL";
878 878
879 default: 879 default:
880 return "unknown"; 880 return "unknown";
881 } 881 }
882} 882}
883 883
884MODULE(MODULE_CLASS_DRIVER, acpicpu, NULL); 884MODULE(MODULE_CLASS_DRIVER, acpicpu, NULL);
885 885
886#ifdef _MODULE 886#ifdef _MODULE
887#include "ioconf.c" 887#include "ioconf.c"
888#endif 888#endif
889 889
890static int 890static int
891acpicpu_modcmd(modcmd_t cmd, void *aux) 891acpicpu_modcmd(modcmd_t cmd, void *aux)
892{ 892{
893 int rv = 0; 893 int rv = 0;
894 894
895 switch (cmd) { 895 switch (cmd) {
896 896
897 case MODULE_CMD_INIT: 897 case MODULE_CMD_INIT:
898 898
899#ifdef _MODULE 899#ifdef _MODULE
900 rv = config_init_component(cfdriver_ioconf_acpicpu, 900 rv = config_init_component(cfdriver_ioconf_acpicpu,
901 cfattach_ioconf_acpicpu, cfdata_ioconf_acpicpu); 901 cfattach_ioconf_acpicpu, cfdata_ioconf_acpicpu);
902#endif 902#endif
903 break; 903 break;
904 904
905 case MODULE_CMD_FINI: 905 case MODULE_CMD_FINI:
906 906
907#ifdef _MODULE 907#ifdef _MODULE
908 rv = config_fini_component(cfdriver_ioconf_acpicpu, 908 rv = config_fini_component(cfdriver_ioconf_acpicpu,
909 cfattach_ioconf_acpicpu, cfdata_ioconf_acpicpu); 909 cfattach_ioconf_acpicpu, cfdata_ioconf_acpicpu);
910#endif 910#endif
911 break; 911 break;
912 912
913 default: 913 default:
914 rv = ENOTTY; 914 rv = ENOTTY;
915 } 915 }
916 916
917 return rv; 917 return rv;
918} 918}

cvs diff -r1.19 -r1.20 src/sys/dev/acpi/acpi_quirks.c (switch to unified diff)

--- src/sys/dev/acpi/acpi_quirks.c 2011/02/20 06:45:32 1.19
+++ src/sys/dev/acpi/acpi_quirks.c 2011/11/14 02:44:59 1.20
@@ -1,271 +1,271 @@ @@ -1,271 +1,271 @@
1/* $NetBSD: acpi_quirks.c,v 1.19 2011/02/20 06:45:32 jruoho Exp $ */ 1/* $NetBSD: acpi_quirks.c,v 1.20 2011/11/14 02:44:59 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 10 *
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE. 27 * SUCH DAMAGE.
28 */ 28 */
29 29
30/* 30/*
31 * Copyright 2002 Wasabi Systems, Inc. 31 * Copyright 2002 Wasabi Systems, Inc.
32 * All rights reserved. 32 * All rights reserved.
33 * 33 *
34 * Written by Frank van der Linden for Wasabi Systems, Inc. 34 * Written by Frank van der Linden for Wasabi Systems, Inc.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software 44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement: 45 * must display the following acknowledgement:
46 * This product includes software developed for the NetBSD Project by 46 * This product includes software developed for the NetBSD Project by
47 * Wasabi Systems, Inc. 47 * Wasabi Systems, Inc.
48 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 48 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
49 * or promote products derived from this software without specific prior 49 * or promote products derived from this software without specific prior
50 * written permission. 50 * written permission.
51 * 51 *
52 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 52 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
54 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 54 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
55 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 55 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
56 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 56 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
57 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 57 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
58 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 58 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
59 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 59 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
60 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
61 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 61 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
62 * POSSIBILITY OF SUCH DAMAGE. 62 * POSSIBILITY OF SUCH DAMAGE.
63 */ 63 */
64 64
65#include <sys/cdefs.h> 65#include <sys/cdefs.h>
66 66
67__KERNEL_RCSID(0, "$NetBSD: acpi_quirks.c,v 1.19 2011/02/20 06:45:32 jruoho Exp $"); 67__KERNEL_RCSID(0, "$NetBSD: acpi_quirks.c,v 1.20 2011/11/14 02:44:59 jmcneill Exp $");
68 68
69#include "opt_acpi.h" 69#include "opt_acpi.h"
70 70
71#include <sys/param.h> 71#include <sys/param.h>
72 72
73#include <dev/acpi/acpireg.h> 73#include <dev/acpi/acpireg.h>
74#include <dev/acpi/acpivar.h> 74#include <dev/acpi/acpivar.h>
75 75
76#define _COMPONENT ACPI_UTILITIES 76#define _COMPONENT ACPI_UTILITIES
77ACPI_MODULE_NAME ("acpi_quirks") 77ACPI_MODULE_NAME ("acpi_quirks")
78 78
79#define AQ_GT 0 /* > */ 79#define AQ_GT 0 /* > */
80#define AQ_LT 1 /* < */ 80#define AQ_LT 1 /* < */
81#define AQ_GTE 2 /* >= */ 81#define AQ_GTE 2 /* >= */
82#define AQ_LTE 3 /* <= */ 82#define AQ_LTE 3 /* <= */
83#define AQ_EQ 4 /* == */ 83#define AQ_EQ 4 /* == */
84 84
85static int acpi_quirks_revcmp(uint32_t, uint32_t, int); 85static int acpi_quirks_revcmp(uint32_t, uint32_t, int);
86 86
87static struct acpi_quirk acpi_quirks[] = { 87static struct acpi_quirk acpi_quirks[] = {
88 88
89 { ACPI_SIG_FADT, "ASUS ", 0x30303031, AQ_LTE, "CUV4X-D ", 89 { ACPI_SIG_FADT, "ASUS ", 0x30303031, AQ_LTE, "CUV4X-D ",
90 ACPI_QUIRK_BROKEN }, 90 ACPI_QUIRK_BROKEN },
91 91
92 { ACPI_SIG_FADT, "PTLTD ", 0x06040000, AQ_LTE, " FACP ", 92 { ACPI_SIG_FADT, "PTLTD ", 0x06040000, AQ_LTE, " FACP ",
93 ACPI_QUIRK_BROKEN }, 93 ACPI_QUIRK_BROKEN },
94 94
95 { ACPI_SIG_FADT, "NVIDIA", 0x06040000, AQ_EQ, "CK8 ", 95 { ACPI_SIG_FADT, "NVIDIA", 0x06040000, AQ_EQ, "CK8 ",
96 ACPI_QUIRK_IRQ0 }, 96 ACPI_QUIRK_IRQ0 },
97 97
98 { ACPI_SIG_FADT, "HP ", 0x06040012, AQ_LTE, "HWPC20F ", 98 { ACPI_SIG_FADT, "HP ", 0x06040012, AQ_LTE, "HWPC20F ",
99 ACPI_QUIRK_BROKEN }, 99 ACPI_QUIRK_BROKEN },
100}; 100};
101 101
102static int 102static int
103acpi_quirks_revcmp(uint32_t tabval, uint32_t wanted, int op) 103acpi_quirks_revcmp(uint32_t tabval, uint32_t wanted, int op)
104{ 104{
105 105
106 switch (op) { 106 switch (op) {
107 107
108 case AQ_GT: 108 case AQ_GT:
109 return (tabval > wanted) ? 0 : 1; 109 return (tabval > wanted) ? 0 : 1;
110 110
111 case AQ_LT: 111 case AQ_LT:
112 return (tabval < wanted) ? 0 : 1; 112 return (tabval < wanted) ? 0 : 1;
113 113
114 case AQ_LTE: 114 case AQ_LTE:
115 return (tabval <= wanted) ? 0 : 1; 115 return (tabval <= wanted) ? 0 : 1;
116 116
117 case AQ_GTE: 117 case AQ_GTE:
118 return (tabval >= wanted) ? 0 : 1; 118 return (tabval >= wanted) ? 0 : 1;
119 119
120 case AQ_EQ: 120 case AQ_EQ:
121 return (tabval == wanted) ? 0 : 1; 121 return (tabval == wanted) ? 0 : 1;
122 122
123 default: 123 default:
124 return 1; 124 return 1;
125 } 125 }
126} 126}
127 127
128#ifdef ACPI_BLACKLIST_YEAR 128#ifdef ACPI_BLACKLIST_YEAR
129static int 129static int
130acpi_quirks_bios_year(void) 130acpi_quirks_bios_year(void)
131{ 131{
132 const char *datestr = pmf_get_platform("firmware-date"); 132 const char *datestr = pmf_get_platform("bios-date");
133 unsigned long date; 133 unsigned long date;
134 134
135 if (datestr == NULL) 135 if (datestr == NULL)
136 return -1; 136 return -1;
137 137
138 date = strtoul(datestr, NULL, 10); 138 date = strtoul(datestr, NULL, 10);
139 if (date == 0 || date == ULONG_MAX) 139 if (date == 0 || date == ULONG_MAX)
140 return -1; 140 return -1;
141 if (date < 19000000 || date > 99999999) 141 if (date < 19000000 || date > 99999999)
142 return -1; 142 return -1;
143 return date / 10000; 143 return date / 10000;
144} 144}
145#endif 145#endif
146 146
147/* 147/*
148 * Simple function to search the quirk table. Only to be 148 * Simple function to search the quirk table. Only to be
149 * used after AcpiLoadTables() has been successfully called. 149 * used after AcpiLoadTables() has been successfully called.
150 */ 150 */
151int 151int
152acpi_find_quirks(void) 152acpi_find_quirks(void)
153{ 153{
154 ACPI_TABLE_HEADER fadt, dsdt, xsdt, *hdr; 154 ACPI_TABLE_HEADER fadt, dsdt, xsdt, *hdr;
155 struct acpi_quirk *aq; 155 struct acpi_quirk *aq;
156 ACPI_STATUS rv; 156 ACPI_STATUS rv;
157 size_t i, len; 157 size_t i, len;
158 158
159#ifdef ACPI_BLACKLIST_YEAR 159#ifdef ACPI_BLACKLIST_YEAR
160 int year = acpi_quirks_bios_year(); 160 int year = acpi_quirks_bios_year();
161 161
162 if (year != -1 && year <= ACPI_BLACKLIST_YEAR) 162 if (year != -1 && year <= ACPI_BLACKLIST_YEAR)
163 return ACPI_QUIRK_OLDBIOS; 163 return ACPI_QUIRK_OLDBIOS;
164#endif 164#endif
165 165
166 rv = AcpiGetTableHeader(ACPI_SIG_FADT, 0, &fadt); 166 rv = AcpiGetTableHeader(ACPI_SIG_FADT, 0, &fadt);
167 167
168 if (ACPI_FAILURE(rv)) 168 if (ACPI_FAILURE(rv))
169 (void)memset(&fadt, 0, sizeof(fadt)); 169 (void)memset(&fadt, 0, sizeof(fadt));
170 170
171 rv = AcpiGetTableHeader(ACPI_SIG_DSDT, 0, &dsdt); 171 rv = AcpiGetTableHeader(ACPI_SIG_DSDT, 0, &dsdt);
172 172
173 if (ACPI_FAILURE(rv)) 173 if (ACPI_FAILURE(rv))
174 (void)memset(&dsdt, 0, sizeof(dsdt)); 174 (void)memset(&dsdt, 0, sizeof(dsdt));
175 175
176 rv = AcpiGetTableHeader(ACPI_SIG_XSDT, 0, &xsdt); 176 rv = AcpiGetTableHeader(ACPI_SIG_XSDT, 0, &xsdt);
177 177
178 if (ACPI_FAILURE(rv)) 178 if (ACPI_FAILURE(rv))
179 (void)memset(&xsdt, 0, sizeof(xsdt)); 179 (void)memset(&xsdt, 0, sizeof(xsdt));
180 180
181 for (i = 0; i < __arraycount(acpi_quirks); i++) { 181 for (i = 0; i < __arraycount(acpi_quirks); i++) {
182 182
183 aq = &acpi_quirks[i]; 183 aq = &acpi_quirks[i];
184 184
185 if (strncmp(aq->aq_tabletype, ACPI_SIG_DSDT, 4) == 0) 185 if (strncmp(aq->aq_tabletype, ACPI_SIG_DSDT, 4) == 0)
186 hdr = &dsdt; 186 hdr = &dsdt;
187 else if (strncmp(aq->aq_tabletype, ACPI_SIG_XSDT, 4) == 0) 187 else if (strncmp(aq->aq_tabletype, ACPI_SIG_XSDT, 4) == 0)
188 hdr = &xsdt; 188 hdr = &xsdt;
189 else if (strncmp(aq->aq_tabletype, ACPI_SIG_FADT, 4) == 0) 189 else if (strncmp(aq->aq_tabletype, ACPI_SIG_FADT, 4) == 0)
190 hdr = &fadt; 190 hdr = &fadt;
191 else { 191 else {
192 continue; 192 continue;
193 } 193 }
194 194
195 len = strlen(aq->aq_oemid); 195 len = strlen(aq->aq_oemid);
196 196
197 if (strncmp(aq->aq_oemid, hdr->OemId, len) != 0) 197 if (strncmp(aq->aq_oemid, hdr->OemId, len) != 0)
198 continue; 198 continue;
199 199
200 if (acpi_quirks_revcmp(aq->aq_oemrev, 200 if (acpi_quirks_revcmp(aq->aq_oemrev,
201 hdr->OemRevision, aq->aq_cmpop) != 0) 201 hdr->OemRevision, aq->aq_cmpop) != 0)
202 continue; 202 continue;
203 203
204 len = strlen(aq->aq_tabid); 204 len = strlen(aq->aq_tabid);
205 205
206 if (strncmp(aq->aq_tabid, hdr->OemTableId, len) != 0) 206 if (strncmp(aq->aq_tabid, hdr->OemTableId, len) != 0)
207 continue; 207 continue;
208 208
209 return aq->aq_quirks; 209 return aq->aq_quirks;
210 } 210 }
211 211
212 return 0; 212 return 0;
213} 213}
214 214
215/* 215/*
216 * Add or delete a string to the list that should return 216 * Add or delete a string to the list that should return
217 * true when _OSI is being queried. The defaults are: 217 * true when _OSI is being queried. The defaults are:
218 * 218 *
219 * "Windows 2000" # Windows 2000 219 * "Windows 2000" # Windows 2000
220 * "Windows 2001" # Windows XP 220 * "Windows 2001" # Windows XP
221 * "Windows 2001 SP1" # Windows XP SP1 221 * "Windows 2001 SP1" # Windows XP SP1
222 * "Windows 2001.1" # Windows Server 2003 222 * "Windows 2001.1" # Windows Server 2003
223 * "Windows 2001 SP2" # Windows XP SP2 223 * "Windows 2001 SP2" # Windows XP SP2
224 * "Windows 2001.1 SP1" # Windows Server 2003 SP1 224 * "Windows 2001.1 SP1" # Windows Server 2003 SP1
225 * "Windows 2006" # Windows Vista 225 * "Windows 2006" # Windows Vista
226 * "Windows 2006.1" # Windows Server 2008 226 * "Windows 2006.1" # Windows Server 2008
227 * "Windows 2006 SP1" # Windows Vista SP1 227 * "Windows 2006 SP1" # Windows Vista SP1
228 * "Windows 2006 SP2" # Windows Vista SP2 228 * "Windows 2006 SP2" # Windows Vista SP2
229 * "Windows 2009" # Windows 7 and Server 2008 229 * "Windows 2009" # Windows 7 and Server 2008
230 */ 230 */
231int 231int
232acpi_quirks_osi_add(const char *str) 232acpi_quirks_osi_add(const char *str)
233{ 233{
234 ACPI_STATUS rv; 234 ACPI_STATUS rv;
235 235
236 if (str == NULL || *str == '\0') 236 if (str == NULL || *str == '\0')
237 return EINVAL; 237 return EINVAL;
238 238
239 rv = AcpiInstallInterface(__UNCONST(str)); 239 rv = AcpiInstallInterface(__UNCONST(str));
240 240
241 return (rv != AE_OK) ? EIO : 0; 241 return (rv != AE_OK) ? EIO : 0;
242} 242}
243 243
244int 244int
245acpi_quirks_osi_del(const char *str) 245acpi_quirks_osi_del(const char *str)
246{ 246{
247 ACPI_STATUS rv; 247 ACPI_STATUS rv;
248 248
249 if (str == NULL || *str == '\0') 249 if (str == NULL || *str == '\0')
250 return EINVAL; 250 return EINVAL;
251 251
252 rv = AcpiRemoveInterface(__UNCONST(str)); 252 rv = AcpiRemoveInterface(__UNCONST(str));
253 253
254 return (rv != AE_OK) ? EIO : 0; 254 return (rv != AE_OK) ? EIO : 0;
255} 255}
256 256
257#if 0 257#if 0
258static void 258static void
259acpi_quirks_osi_linux(void) 259acpi_quirks_osi_linux(void)
260{ 260{
261 (void)acpi_quirks_osi_add("Linux"); 261 (void)acpi_quirks_osi_add("Linux");
262} 262}
263 263
264static void 264static void
265acpi_quirks_osi_vista(void) 265acpi_quirks_osi_vista(void)
266{ 266{
267 (void)acpi_quirks_osi_del("Windows 2006"); 267 (void)acpi_quirks_osi_del("Windows 2006");
268 (void)acpi_quirks_osi_del("Windows 2006 SP1"); 268 (void)acpi_quirks_osi_del("Windows 2006 SP1");
269 (void)acpi_quirks_osi_del("Windows 2006 SP2"); 269 (void)acpi_quirks_osi_del("Windows 2006 SP2");
270} 270}
271#endif 271#endif