]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/acpi/utilities/uteval.c
ACPI: ACPICA 20060526
[mirror_ubuntu-artful-kernel.git] / drivers / acpi / utilities / uteval.c
1 /******************************************************************************
2 *
3 * Module Name: uteval - Object evaluation
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2006, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44 #include <acpi/acpi.h>
45 #include <acpi/acnamesp.h>
46 #include <acpi/acinterp.h>
47
48 #define _COMPONENT ACPI_UTILITIES
49 ACPI_MODULE_NAME("uteval")
50
51 /* Local prototypes */
52 static void
53 acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length);
54
55 static acpi_status
56 acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
57 struct acpi_compatible_id *one_cid);
58
59 /*
60 * Strings supported by the _OSI predefined (internal) method.
61 */
62 static const char *acpi_interfaces_supported[] = {
63 /* Operating System Vendor Strings */
64
65 "Linux",
66 "Windows 2000",
67 "Windows 2001",
68 "Windows 2001 SP0",
69 "Windows 2001 SP1",
70 "Windows 2001 SP2",
71 "Windows 2001 SP3",
72 "Windows 2001 SP4",
73 "Windows 2001.1",
74 "Windows 2001.1 SP1", /* Added 03/2006 */
75 "Windows 2006", /* Added 03/2006 */
76
77 /* Feature Group Strings */
78
79 "Extended Address Space Descriptor"
80 /*
81 * All "optional" feature group strings (features that are implemented
82 * by the host) should be implemented in the host version of
83 * acpi_os_validate_interface and should not be added here.
84 */
85 };
86
87 /*******************************************************************************
88 *
89 * FUNCTION: acpi_ut_osi_implementation
90 *
91 * PARAMETERS: walk_state - Current walk state
92 *
93 * RETURN: Status
94 *
95 * DESCRIPTION: Implementation of the _OSI predefined control method
96 *
97 ******************************************************************************/
98
99 acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
100 {
101 acpi_status status;
102 union acpi_operand_object *string_desc;
103 union acpi_operand_object *return_desc;
104 acpi_native_uint i;
105
106 ACPI_FUNCTION_TRACE(ut_osi_implementation);
107
108 /* Validate the string input argument */
109
110 string_desc = walk_state->arguments[0].object;
111 if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
112 return_ACPI_STATUS(AE_TYPE);
113 }
114
115 /* Create a return object */
116
117 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
118 if (!return_desc) {
119 return_ACPI_STATUS(AE_NO_MEMORY);
120 }
121
122 /* Default return value is SUPPORTED */
123
124 return_desc->integer.value = ACPI_UINT32_MAX;
125 walk_state->return_desc = return_desc;
126
127 /* Compare input string to static table of supported interfaces */
128
129 for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
130 if (!ACPI_STRCMP
131 (string_desc->string.pointer,
132 acpi_interfaces_supported[i])) {
133
134 /* The interface is supported */
135
136 return_ACPI_STATUS(AE_CTRL_TERMINATE);
137 }
138 }
139
140 /*
141 * Did not match the string in the static table, call the host OSL to
142 * check for a match with one of the optional strings (such as
143 * "Module Device", "3.0 Thermal Model", etc.)
144 */
145 status = acpi_os_validate_interface(string_desc->string.pointer);
146 if (ACPI_SUCCESS(status)) {
147
148 /* The interface is supported */
149
150 return_ACPI_STATUS(AE_CTRL_TERMINATE);
151 }
152
153 /* The interface is not supported */
154
155 return_desc->integer.value = 0;
156 return_ACPI_STATUS(AE_CTRL_TERMINATE);
157 }
158
159 /*******************************************************************************
160 *
161 * FUNCTION: acpi_ut_evaluate_object
162 *
163 * PARAMETERS: prefix_node - Starting node
164 * Path - Path to object from starting node
165 * expected_return_types - Bitmap of allowed return types
166 * return_desc - Where a return value is stored
167 *
168 * RETURN: Status
169 *
170 * DESCRIPTION: Evaluates a namespace object and verifies the type of the
171 * return object. Common code that simplifies accessing objects
172 * that have required return objects of fixed types.
173 *
174 * NOTE: Internal function, no parameter validation
175 *
176 ******************************************************************************/
177
178 acpi_status
179 acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
180 char *path,
181 u32 expected_return_btypes,
182 union acpi_operand_object **return_desc)
183 {
184 struct acpi_evaluate_info *info;
185 acpi_status status;
186 u32 return_btype;
187
188 ACPI_FUNCTION_TRACE(ut_evaluate_object);
189
190 /* Allocate the evaluation information block */
191
192 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
193 if (!info) {
194 return_ACPI_STATUS(AE_NO_MEMORY);
195 }
196
197 info->prefix_node = prefix_node;
198 info->pathname = path;
199 info->parameter_type = ACPI_PARAM_ARGS;
200
201 /* Evaluate the object/method */
202
203 status = acpi_ns_evaluate(info);
204 if (ACPI_FAILURE(status)) {
205 if (status == AE_NOT_FOUND) {
206 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
207 "[%4.4s.%s] was not found\n",
208 acpi_ut_get_node_name(prefix_node),
209 path));
210 } else {
211 ACPI_ERROR_METHOD("Method execution failed",
212 prefix_node, path, status);
213 }
214
215 goto cleanup;
216 }
217
218 /* Did we get a return object? */
219
220 if (!info->return_object) {
221 if (expected_return_btypes) {
222 ACPI_ERROR_METHOD("No object was returned from",
223 prefix_node, path, AE_NOT_EXIST);
224
225 status = AE_NOT_EXIST;
226 }
227
228 goto cleanup;
229 }
230
231 /* Map the return object type to the bitmapped type */
232
233 switch (ACPI_GET_OBJECT_TYPE(info->return_object)) {
234 case ACPI_TYPE_INTEGER:
235 return_btype = ACPI_BTYPE_INTEGER;
236 break;
237
238 case ACPI_TYPE_BUFFER:
239 return_btype = ACPI_BTYPE_BUFFER;
240 break;
241
242 case ACPI_TYPE_STRING:
243 return_btype = ACPI_BTYPE_STRING;
244 break;
245
246 case ACPI_TYPE_PACKAGE:
247 return_btype = ACPI_BTYPE_PACKAGE;
248 break;
249
250 default:
251 return_btype = 0;
252 break;
253 }
254
255 if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) {
256 /*
257 * We received a return object, but one was not expected. This can
258 * happen frequently if the "implicit return" feature is enabled.
259 * Just delete the return object and return AE_OK.
260 */
261 acpi_ut_remove_reference(info->return_object);
262 goto cleanup;
263 }
264
265 /* Is the return object one of the expected types? */
266
267 if (!(expected_return_btypes & return_btype)) {
268 ACPI_ERROR_METHOD("Return object type is incorrect",
269 prefix_node, path, AE_TYPE);
270
271 ACPI_ERROR((AE_INFO,
272 "Type returned from %s was incorrect: %s, expected Btypes: %X",
273 path,
274 acpi_ut_get_object_type_name(info->return_object),
275 expected_return_btypes));
276
277 /* On error exit, we must delete the return object */
278
279 acpi_ut_remove_reference(info->return_object);
280 status = AE_TYPE;
281 goto cleanup;
282 }
283
284 /* Object type is OK, return it */
285
286 *return_desc = info->return_object;
287
288 cleanup:
289 ACPI_FREE(info);
290 return_ACPI_STATUS(status);
291 }
292
293 /*******************************************************************************
294 *
295 * FUNCTION: acpi_ut_evaluate_numeric_object
296 *
297 * PARAMETERS: object_name - Object name to be evaluated
298 * device_node - Node for the device
299 * Address - Where the value is returned
300 *
301 * RETURN: Status
302 *
303 * DESCRIPTION: Evaluates a numeric namespace object for a selected device
304 * and stores result in *Address.
305 *
306 * NOTE: Internal function, no parameter validation
307 *
308 ******************************************************************************/
309
310 acpi_status
311 acpi_ut_evaluate_numeric_object(char *object_name,
312 struct acpi_namespace_node *device_node,
313 acpi_integer * address)
314 {
315 union acpi_operand_object *obj_desc;
316 acpi_status status;
317
318 ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object);
319
320 status = acpi_ut_evaluate_object(device_node, object_name,
321 ACPI_BTYPE_INTEGER, &obj_desc);
322 if (ACPI_FAILURE(status)) {
323 return_ACPI_STATUS(status);
324 }
325
326 /* Get the returned Integer */
327
328 *address = obj_desc->integer.value;
329
330 /* On exit, we must delete the return object */
331
332 acpi_ut_remove_reference(obj_desc);
333 return_ACPI_STATUS(status);
334 }
335
336 /*******************************************************************************
337 *
338 * FUNCTION: acpi_ut_copy_id_string
339 *
340 * PARAMETERS: Destination - Where to copy the string
341 * Source - Source string
342 * max_length - Length of the destination buffer
343 *
344 * RETURN: None
345 *
346 * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
347 * Performs removal of a leading asterisk if present -- workaround
348 * for a known issue on a bunch of machines.
349 *
350 ******************************************************************************/
351
352 static void
353 acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length)
354 {
355
356 /*
357 * Workaround for ID strings that have a leading asterisk. This construct
358 * is not allowed by the ACPI specification (ID strings must be
359 * alphanumeric), but enough existing machines have this embedded in their
360 * ID strings that the following code is useful.
361 */
362 if (*source == '*') {
363 source++;
364 }
365
366 /* Do the actual copy */
367
368 ACPI_STRNCPY(destination, source, max_length);
369 }
370
371 /*******************************************************************************
372 *
373 * FUNCTION: acpi_ut_execute_HID
374 *
375 * PARAMETERS: device_node - Node for the device
376 * Hid - Where the HID is returned
377 *
378 * RETURN: Status
379 *
380 * DESCRIPTION: Executes the _HID control method that returns the hardware
381 * ID of the device.
382 *
383 * NOTE: Internal function, no parameter validation
384 *
385 ******************************************************************************/
386
387 acpi_status
388 acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
389 struct acpi_device_id *hid)
390 {
391 union acpi_operand_object *obj_desc;
392 acpi_status status;
393
394 ACPI_FUNCTION_TRACE(ut_execute_HID);
395
396 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
397 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
398 &obj_desc);
399 if (ACPI_FAILURE(status)) {
400 return_ACPI_STATUS(status);
401 }
402
403 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
404
405 /* Convert the Numeric HID to string */
406
407 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
408 hid->value);
409 } else {
410 /* Copy the String HID from the returned object */
411
412 acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer,
413 sizeof(hid->value));
414 }
415
416 /* On exit, we must delete the return object */
417
418 acpi_ut_remove_reference(obj_desc);
419 return_ACPI_STATUS(status);
420 }
421
422 /*******************************************************************************
423 *
424 * FUNCTION: acpi_ut_translate_one_cid
425 *
426 * PARAMETERS: obj_desc - _CID object, must be integer or string
427 * one_cid - Where the CID string is returned
428 *
429 * RETURN: Status
430 *
431 * DESCRIPTION: Return a numeric or string _CID value as a string.
432 * (Compatible ID)
433 *
434 * NOTE: Assumes a maximum _CID string length of
435 * ACPI_MAX_CID_LENGTH.
436 *
437 ******************************************************************************/
438
439 static acpi_status
440 acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
441 struct acpi_compatible_id *one_cid)
442 {
443
444 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
445 case ACPI_TYPE_INTEGER:
446
447 /* Convert the Numeric CID to string */
448
449 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
450 one_cid->value);
451 return (AE_OK);
452
453 case ACPI_TYPE_STRING:
454
455 if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
456 return (AE_AML_STRING_LIMIT);
457 }
458
459 /* Copy the String CID from the returned object */
460
461 acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer,
462 ACPI_MAX_CID_LENGTH);
463 return (AE_OK);
464
465 default:
466
467 return (AE_TYPE);
468 }
469 }
470
471 /*******************************************************************************
472 *
473 * FUNCTION: acpi_ut_execute_CID
474 *
475 * PARAMETERS: device_node - Node for the device
476 * return_cid_list - Where the CID list is returned
477 *
478 * RETURN: Status
479 *
480 * DESCRIPTION: Executes the _CID control method that returns one or more
481 * compatible hardware IDs for the device.
482 *
483 * NOTE: Internal function, no parameter validation
484 *
485 ******************************************************************************/
486
487 acpi_status
488 acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
489 struct acpi_compatible_id_list ** return_cid_list)
490 {
491 union acpi_operand_object *obj_desc;
492 acpi_status status;
493 u32 count;
494 u32 size;
495 struct acpi_compatible_id_list *cid_list;
496 acpi_native_uint i;
497
498 ACPI_FUNCTION_TRACE(ut_execute_CID);
499
500 /* Evaluate the _CID method for this device */
501
502 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
503 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
504 | ACPI_BTYPE_PACKAGE, &obj_desc);
505 if (ACPI_FAILURE(status)) {
506 return_ACPI_STATUS(status);
507 }
508
509 /* Get the number of _CIDs returned */
510
511 count = 1;
512 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
513 count = obj_desc->package.count;
514 }
515
516 /* Allocate a worst-case buffer for the _CIDs */
517
518 size = (((count - 1) * sizeof(struct acpi_compatible_id)) +
519 sizeof(struct acpi_compatible_id_list));
520
521 cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
522 if (!cid_list) {
523 return_ACPI_STATUS(AE_NO_MEMORY);
524 }
525
526 /* Init CID list */
527
528 cid_list->count = count;
529 cid_list->size = size;
530
531 /*
532 * A _CID can return either a single compatible ID or a package of
533 * compatible IDs. Each compatible ID can be one of the following:
534 * 1) Integer (32 bit compressed EISA ID) or
535 * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
536 */
537
538 /* The _CID object can be either a single CID or a package (list) of CIDs */
539
540 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
541
542 /* Translate each package element */
543
544 for (i = 0; i < count; i++) {
545 status =
546 acpi_ut_translate_one_cid(obj_desc->package.
547 elements[i],
548 &cid_list->id[i]);
549 if (ACPI_FAILURE(status)) {
550 break;
551 }
552 }
553 } else {
554 /* Only one CID, translate to a string */
555
556 status = acpi_ut_translate_one_cid(obj_desc, cid_list->id);
557 }
558
559 /* Cleanup on error */
560
561 if (ACPI_FAILURE(status)) {
562 ACPI_FREE(cid_list);
563 } else {
564 *return_cid_list = cid_list;
565 }
566
567 /* On exit, we must delete the _CID return object */
568
569 acpi_ut_remove_reference(obj_desc);
570 return_ACPI_STATUS(status);
571 }
572
573 /*******************************************************************************
574 *
575 * FUNCTION: acpi_ut_execute_UID
576 *
577 * PARAMETERS: device_node - Node for the device
578 * Uid - Where the UID is returned
579 *
580 * RETURN: Status
581 *
582 * DESCRIPTION: Executes the _UID control method that returns the hardware
583 * ID of the device.
584 *
585 * NOTE: Internal function, no parameter validation
586 *
587 ******************************************************************************/
588
589 acpi_status
590 acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
591 struct acpi_device_id *uid)
592 {
593 union acpi_operand_object *obj_desc;
594 acpi_status status;
595
596 ACPI_FUNCTION_TRACE(ut_execute_UID);
597
598 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
599 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
600 &obj_desc);
601 if (ACPI_FAILURE(status)) {
602 return_ACPI_STATUS(status);
603 }
604
605 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
606
607 /* Convert the Numeric UID to string */
608
609 acpi_ex_unsigned_integer_to_string(obj_desc->integer.value,
610 uid->value);
611 } else {
612 /* Copy the String UID from the returned object */
613
614 acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer,
615 sizeof(uid->value));
616 }
617
618 /* On exit, we must delete the return object */
619
620 acpi_ut_remove_reference(obj_desc);
621 return_ACPI_STATUS(status);
622 }
623
624 /*******************************************************************************
625 *
626 * FUNCTION: acpi_ut_execute_STA
627 *
628 * PARAMETERS: device_node - Node for the device
629 * Flags - Where the status flags are returned
630 *
631 * RETURN: Status
632 *
633 * DESCRIPTION: Executes _STA for selected device and stores results in
634 * *Flags.
635 *
636 * NOTE: Internal function, no parameter validation
637 *
638 ******************************************************************************/
639
640 acpi_status
641 acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
642 {
643 union acpi_operand_object *obj_desc;
644 acpi_status status;
645
646 ACPI_FUNCTION_TRACE(ut_execute_STA);
647
648 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA,
649 ACPI_BTYPE_INTEGER, &obj_desc);
650 if (ACPI_FAILURE(status)) {
651 if (AE_NOT_FOUND == status) {
652 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
653 "_STA on %4.4s was not found, assuming device is present\n",
654 acpi_ut_get_node_name(device_node)));
655
656 *flags = ACPI_UINT32_MAX;
657 status = AE_OK;
658 }
659
660 return_ACPI_STATUS(status);
661 }
662
663 /* Extract the status flags */
664
665 *flags = (u32) obj_desc->integer.value;
666
667 /* On exit, we must delete the return object */
668
669 acpi_ut_remove_reference(obj_desc);
670 return_ACPI_STATUS(status);
671 }
672
673 /*******************************************************************************
674 *
675 * FUNCTION: acpi_ut_execute_Sxds
676 *
677 * PARAMETERS: device_node - Node for the device
678 * Flags - Where the status flags are returned
679 *
680 * RETURN: Status
681 *
682 * DESCRIPTION: Executes _STA for selected device and stores results in
683 * *Flags.
684 *
685 * NOTE: Internal function, no parameter validation
686 *
687 ******************************************************************************/
688
689 acpi_status
690 acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest)
691 {
692 union acpi_operand_object *obj_desc;
693 acpi_status status;
694 u32 i;
695
696 ACPI_FUNCTION_TRACE(ut_execute_sxds);
697
698 for (i = 0; i < 4; i++) {
699 highest[i] = 0xFF;
700 status = acpi_ut_evaluate_object(device_node,
701 ACPI_CAST_PTR(char,
702 acpi_gbl_highest_dstate_names
703 [i]),
704 ACPI_BTYPE_INTEGER, &obj_desc);
705 if (ACPI_FAILURE(status)) {
706 if (status != AE_NOT_FOUND) {
707 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
708 "%s on Device %4.4s, %s\n",
709 ACPI_CAST_PTR(char,
710 acpi_gbl_highest_dstate_names
711 [i]),
712 acpi_ut_get_node_name
713 (device_node),
714 acpi_format_exception
715 (status)));
716
717 return_ACPI_STATUS(status);
718 }
719 } else {
720 /* Extract the Dstate value */
721
722 highest[i] = (u8) obj_desc->integer.value;
723
724 /* Delete the return object */
725
726 acpi_ut_remove_reference(obj_desc);
727 }
728 }
729
730 return_ACPI_STATUS(AE_OK);
731 }