1
2
3
4
5
6
7
8
9
10#include <acpi/acpi.h>
11#include "accommon.h"
12
13#define _COMPONENT ACPI_UTILITIES
14ACPI_MODULE_NAME("utosi")
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53static struct acpi_interface_info acpi_default_supported_interfaces[] = {
54
55
56 {"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000},
57 {"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP},
58 {"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1},
59 {"Windows 2001.1", NULL, 0, ACPI_OSI_WINSRV_2003},
60 {"Windows 2001 SP2", NULL, 0, ACPI_OSI_WIN_XP_SP2},
61 {"Windows 2001.1 SP1", NULL, 0, ACPI_OSI_WINSRV_2003_SP1},
62 {"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA},
63 {"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008},
64 {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1},
65 {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2},
66 {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7},
67 {"Windows 2012", NULL, 0, ACPI_OSI_WIN_8},
68 {"Windows 2013", NULL, 0, ACPI_OSI_WIN_8},
69 {"Windows 2015", NULL, 0, ACPI_OSI_WIN_10},
70 {"Windows 2016", NULL, 0, ACPI_OSI_WIN_10_RS1},
71 {"Windows 2017", NULL, 0, ACPI_OSI_WIN_10_RS2},
72 {"Windows 2017.2", NULL, 0, ACPI_OSI_WIN_10_RS3},
73
74
75
76 {"Extended Address Space Descriptor", NULL, ACPI_OSI_FEATURE, 0},
77
78
79
80
81
82
83
84
85 {"Module Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
86 {"Processor Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
87 {"3.0 Thermal Model", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
88 {"3.0 _SCP Extensions", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
89 {"Processor Aggregator Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}
90};
91
92
93
94
95
96
97
98
99
100
101
102
103
104acpi_status acpi_ut_initialize_interfaces(void)
105{
106 acpi_status status;
107 u32 i;
108
109 status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
110 if (ACPI_FAILURE(status)) {
111 return (status);
112 }
113
114 acpi_gbl_supported_interfaces = acpi_default_supported_interfaces;
115
116
117
118 for (i = 0;
119 i < (ACPI_ARRAY_LENGTH(acpi_default_supported_interfaces) - 1);
120 i++) {
121 acpi_default_supported_interfaces[i].next =
122 &acpi_default_supported_interfaces[(acpi_size)i + 1];
123 }
124
125 acpi_os_release_mutex(acpi_gbl_osi_mutex);
126 return (AE_OK);
127}
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142acpi_status acpi_ut_interface_terminate(void)
143{
144 acpi_status status;
145 struct acpi_interface_info *next_interface;
146
147 status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
148 if (ACPI_FAILURE(status)) {
149 return (status);
150 }
151
152 next_interface = acpi_gbl_supported_interfaces;
153 while (next_interface) {
154 acpi_gbl_supported_interfaces = next_interface->next;
155
156 if (next_interface->flags & ACPI_OSI_DYNAMIC) {
157
158
159
160 ACPI_FREE(next_interface->name);
161 ACPI_FREE(next_interface);
162 } else {
163
164
165 if (next_interface->flags & ACPI_OSI_DEFAULT_INVALID) {
166 next_interface->flags |= ACPI_OSI_INVALID;
167 } else {
168 next_interface->flags &= ~ACPI_OSI_INVALID;
169 }
170 }
171
172 next_interface = acpi_gbl_supported_interfaces;
173 }
174
175 acpi_os_release_mutex(acpi_gbl_osi_mutex);
176 return (AE_OK);
177}
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192acpi_status acpi_ut_install_interface(acpi_string interface_name)
193{
194 struct acpi_interface_info *interface_info;
195
196
197
198 interface_info =
199 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_interface_info));
200 if (!interface_info) {
201 return (AE_NO_MEMORY);
202 }
203
204 interface_info->name = ACPI_ALLOCATE_ZEROED(strlen(interface_name) + 1);
205 if (!interface_info->name) {
206 ACPI_FREE(interface_info);
207 return (AE_NO_MEMORY);
208 }
209
210
211
212 strcpy(interface_info->name, interface_name);
213 interface_info->flags = ACPI_OSI_DYNAMIC;
214 interface_info->next = acpi_gbl_supported_interfaces;
215
216 acpi_gbl_supported_interfaces = interface_info;
217 return (AE_OK);
218}
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233acpi_status acpi_ut_remove_interface(acpi_string interface_name)
234{
235 struct acpi_interface_info *previous_interface;
236 struct acpi_interface_info *next_interface;
237
238 previous_interface = next_interface = acpi_gbl_supported_interfaces;
239 while (next_interface) {
240 if (!strcmp(interface_name, next_interface->name)) {
241
242
243
244
245 if (next_interface->flags & ACPI_OSI_DYNAMIC) {
246
247
248
249 if (previous_interface == next_interface) {
250 acpi_gbl_supported_interfaces =
251 next_interface->next;
252 } else {
253 previous_interface->next =
254 next_interface->next;
255 }
256
257 ACPI_FREE(next_interface->name);
258 ACPI_FREE(next_interface);
259 } else {
260
261
262
263
264 if (next_interface->flags & ACPI_OSI_INVALID) {
265 return (AE_NOT_EXIST);
266 }
267
268 next_interface->flags |= ACPI_OSI_INVALID;
269 }
270
271 return (AE_OK);
272 }
273
274 previous_interface = next_interface;
275 next_interface = next_interface->next;
276 }
277
278
279
280 return (AE_NOT_EXIST);
281}
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298acpi_status acpi_ut_update_interfaces(u8 action)
299{
300 struct acpi_interface_info *next_interface;
301
302 next_interface = acpi_gbl_supported_interfaces;
303 while (next_interface) {
304 if (((next_interface->flags & ACPI_OSI_FEATURE) &&
305 (action & ACPI_FEATURE_STRINGS)) ||
306 (!(next_interface->flags & ACPI_OSI_FEATURE) &&
307 (action & ACPI_VENDOR_STRINGS))) {
308 if (action & ACPI_DISABLE_INTERFACES) {
309
310
311
312 next_interface->flags |= ACPI_OSI_INVALID;
313 } else {
314
315
316 next_interface->flags &= ~ACPI_OSI_INVALID;
317 }
318 }
319
320 next_interface = next_interface->next;
321 }
322
323 return (AE_OK);
324}
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name)
340{
341 struct acpi_interface_info *next_interface;
342
343 next_interface = acpi_gbl_supported_interfaces;
344 while (next_interface) {
345 if (!strcmp(interface_name, next_interface->name)) {
346 return (next_interface);
347 }
348
349 next_interface = next_interface->next;
350 }
351
352 return (NULL);
353}
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
381{
382 union acpi_operand_object *string_desc;
383 union acpi_operand_object *return_desc;
384 struct acpi_interface_info *interface_info;
385 acpi_interface_handler interface_handler;
386 acpi_status status;
387 u64 return_value;
388
389 ACPI_FUNCTION_TRACE(ut_osi_implementation);
390
391
392
393 string_desc = walk_state->arguments[0].object;
394 if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
395 return_ACPI_STATUS(AE_TYPE);
396 }
397
398
399
400 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
401 if (!return_desc) {
402 return_ACPI_STATUS(AE_NO_MEMORY);
403 }
404
405
406
407 return_value = 0;
408 status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
409 if (ACPI_FAILURE(status)) {
410 acpi_ut_remove_reference(return_desc);
411 return_ACPI_STATUS(status);
412 }
413
414
415
416 interface_info = acpi_ut_get_interface(string_desc->string.pointer);
417 if (interface_info && !(interface_info->flags & ACPI_OSI_INVALID)) {
418
419
420
421
422
423 if (interface_info->value > acpi_gbl_osi_data) {
424 acpi_gbl_osi_data = interface_info->value;
425 }
426
427 return_value = ACPI_UINT64_MAX;
428 }
429
430 acpi_os_release_mutex(acpi_gbl_osi_mutex);
431
432
433
434
435
436
437 interface_handler = acpi_gbl_interface_handler;
438 if (interface_handler) {
439 if (interface_handler
440 (string_desc->string.pointer, (u32)return_value)) {
441 return_value = ACPI_UINT64_MAX;
442 }
443 }
444
445 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO,
446 "ACPI: BIOS _OSI(\"%s\") is %ssupported\n",
447 string_desc->string.pointer,
448 return_value == 0 ? "not " : ""));
449
450
451
452 return_desc->integer.value = return_value;
453 walk_state->return_desc = return_desc;
454 return_ACPI_STATUS(AE_OK);
455}
456