diff options
Diffstat (limited to 'drivers/acpi/utilities/uteval.c')
-rw-r--r-- | drivers/acpi/utilities/uteval.c | 141 |
1 files changed, 101 insertions, 40 deletions
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c index 106cc97cb4af..d6d7121583c0 100644 --- a/drivers/acpi/utilities/uteval.c +++ b/drivers/acpi/utilities/uteval.c | |||
@@ -56,6 +56,34 @@ static acpi_status | |||
56 | acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, | 56 | acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, |
57 | struct acpi_compatible_id *one_cid); | 57 | struct acpi_compatible_id *one_cid); |
58 | 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 | |||
59 | /******************************************************************************* | 87 | /******************************************************************************* |
60 | * | 88 | * |
61 | * FUNCTION: acpi_ut_osi_implementation | 89 | * FUNCTION: acpi_ut_osi_implementation |
@@ -64,18 +92,18 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, | |||
64 | * | 92 | * |
65 | * RETURN: Status | 93 | * RETURN: Status |
66 | * | 94 | * |
67 | * DESCRIPTION: Implementation of _OSI predefined control method | 95 | * DESCRIPTION: Implementation of the _OSI predefined control method |
68 | * Supported = _OSI (String) | ||
69 | * | 96 | * |
70 | ******************************************************************************/ | 97 | ******************************************************************************/ |
71 | 98 | ||
72 | acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) | 99 | acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) |
73 | { | 100 | { |
101 | acpi_status status; | ||
74 | union acpi_operand_object *string_desc; | 102 | union acpi_operand_object *string_desc; |
75 | union acpi_operand_object *return_desc; | 103 | union acpi_operand_object *return_desc; |
76 | acpi_native_uint i; | 104 | acpi_native_uint i; |
77 | 105 | ||
78 | ACPI_FUNCTION_TRACE("ut_osi_implementation"); | 106 | ACPI_FUNCTION_TRACE(ut_osi_implementation); |
79 | 107 | ||
80 | /* Validate the string input argument */ | 108 | /* Validate the string input argument */ |
81 | 109 | ||
@@ -84,28 +112,47 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) | |||
84 | return_ACPI_STATUS(AE_TYPE); | 112 | return_ACPI_STATUS(AE_TYPE); |
85 | } | 113 | } |
86 | 114 | ||
87 | /* Create a return object (Default value = 0) */ | 115 | /* Create a return object */ |
88 | 116 | ||
89 | return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); | 117 | return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); |
90 | if (!return_desc) { | 118 | if (!return_desc) { |
91 | return_ACPI_STATUS(AE_NO_MEMORY); | 119 | return_ACPI_STATUS(AE_NO_MEMORY); |
92 | } | 120 | } |
93 | 121 | ||
94 | /* Compare input string to table of supported strings */ | 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 */ | ||
95 | 128 | ||
96 | for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) { | 129 | for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { |
97 | if (!ACPI_STRCMP(string_desc->string.pointer, | 130 | if (!ACPI_STRCMP |
98 | ACPI_CAST_PTR(char, | 131 | (string_desc->string.pointer, |
99 | acpi_gbl_valid_osi_strings[i]))) | 132 | acpi_interfaces_supported[i])) { |
100 | { | ||
101 | /* This string is supported */ | ||
102 | 133 | ||
103 | return_desc->integer.value = 0xFFFFFFFF; | 134 | /* The interface is supported */ |
104 | break; | 135 | |
136 | return_ACPI_STATUS(AE_CTRL_TERMINATE); | ||
105 | } | 137 | } |
106 | } | 138 | } |
107 | 139 | ||
108 | walk_state->return_desc = return_desc; | 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; | ||
109 | return_ACPI_STATUS(AE_CTRL_TERMINATE); | 156 | return_ACPI_STATUS(AE_CTRL_TERMINATE); |
110 | } | 157 | } |
111 | 158 | ||
@@ -134,19 +181,26 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
134 | u32 expected_return_btypes, | 181 | u32 expected_return_btypes, |
135 | union acpi_operand_object **return_desc) | 182 | union acpi_operand_object **return_desc) |
136 | { | 183 | { |
137 | struct acpi_parameter_info info; | 184 | struct acpi_evaluate_info *info; |
138 | acpi_status status; | 185 | acpi_status status; |
139 | u32 return_btype; | 186 | u32 return_btype; |
140 | 187 | ||
141 | ACPI_FUNCTION_TRACE("ut_evaluate_object"); | 188 | ACPI_FUNCTION_TRACE(ut_evaluate_object); |
142 | 189 | ||
143 | info.node = prefix_node; | 190 | /* Allocate the evaluation information block */ |
144 | info.parameters = NULL; | 191 | |
145 | info.parameter_type = ACPI_PARAM_ARGS; | 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; | ||
146 | 200 | ||
147 | /* Evaluate the object/method */ | 201 | /* Evaluate the object/method */ |
148 | 202 | ||
149 | status = acpi_ns_evaluate_relative(path, &info); | 203 | status = acpi_ns_evaluate(info); |
150 | if (ACPI_FAILURE(status)) { | 204 | if (ACPI_FAILURE(status)) { |
151 | if (status == AE_NOT_FOUND) { | 205 | if (status == AE_NOT_FOUND) { |
152 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 206 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
@@ -158,25 +212,25 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
158 | prefix_node, path, status); | 212 | prefix_node, path, status); |
159 | } | 213 | } |
160 | 214 | ||
161 | return_ACPI_STATUS(status); | 215 | goto cleanup; |
162 | } | 216 | } |
163 | 217 | ||
164 | /* Did we get a return object? */ | 218 | /* Did we get a return object? */ |
165 | 219 | ||
166 | if (!info.return_object) { | 220 | if (!info->return_object) { |
167 | if (expected_return_btypes) { | 221 | if (expected_return_btypes) { |
168 | ACPI_ERROR_METHOD("No object was returned from", | 222 | ACPI_ERROR_METHOD("No object was returned from", |
169 | prefix_node, path, AE_NOT_EXIST); | 223 | prefix_node, path, AE_NOT_EXIST); |
170 | 224 | ||
171 | return_ACPI_STATUS(AE_NOT_EXIST); | 225 | status = AE_NOT_EXIST; |
172 | } | 226 | } |
173 | 227 | ||
174 | return_ACPI_STATUS(AE_OK); | 228 | goto cleanup; |
175 | } | 229 | } |
176 | 230 | ||
177 | /* Map the return object type to the bitmapped type */ | 231 | /* Map the return object type to the bitmapped type */ |
178 | 232 | ||
179 | switch (ACPI_GET_OBJECT_TYPE(info.return_object)) { | 233 | switch (ACPI_GET_OBJECT_TYPE(info->return_object)) { |
180 | case ACPI_TYPE_INTEGER: | 234 | case ACPI_TYPE_INTEGER: |
181 | return_btype = ACPI_BTYPE_INTEGER; | 235 | return_btype = ACPI_BTYPE_INTEGER; |
182 | break; | 236 | break; |
@@ -204,8 +258,8 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
204 | * happen frequently if the "implicit return" feature is enabled. | 258 | * happen frequently if the "implicit return" feature is enabled. |
205 | * Just delete the return object and return AE_OK. | 259 | * Just delete the return object and return AE_OK. |
206 | */ | 260 | */ |
207 | acpi_ut_remove_reference(info.return_object); | 261 | acpi_ut_remove_reference(info->return_object); |
208 | return_ACPI_STATUS(AE_OK); | 262 | goto cleanup; |
209 | } | 263 | } |
210 | 264 | ||
211 | /* Is the return object one of the expected types? */ | 265 | /* Is the return object one of the expected types? */ |
@@ -217,19 +271,23 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
217 | ACPI_ERROR((AE_INFO, | 271 | ACPI_ERROR((AE_INFO, |
218 | "Type returned from %s was incorrect: %s, expected Btypes: %X", | 272 | "Type returned from %s was incorrect: %s, expected Btypes: %X", |
219 | path, | 273 | path, |
220 | acpi_ut_get_object_type_name(info.return_object), | 274 | acpi_ut_get_object_type_name(info->return_object), |
221 | expected_return_btypes)); | 275 | expected_return_btypes)); |
222 | 276 | ||
223 | /* On error exit, we must delete the return object */ | 277 | /* On error exit, we must delete the return object */ |
224 | 278 | ||
225 | acpi_ut_remove_reference(info.return_object); | 279 | acpi_ut_remove_reference(info->return_object); |
226 | return_ACPI_STATUS(AE_TYPE); | 280 | status = AE_TYPE; |
281 | goto cleanup; | ||
227 | } | 282 | } |
228 | 283 | ||
229 | /* Object type is OK, return it */ | 284 | /* Object type is OK, return it */ |
230 | 285 | ||
231 | *return_desc = info.return_object; | 286 | *return_desc = info->return_object; |
232 | return_ACPI_STATUS(AE_OK); | 287 | |
288 | cleanup: | ||
289 | ACPI_FREE(info); | ||
290 | return_ACPI_STATUS(status); | ||
233 | } | 291 | } |
234 | 292 | ||
235 | /******************************************************************************* | 293 | /******************************************************************************* |
@@ -257,7 +315,7 @@ acpi_ut_evaluate_numeric_object(char *object_name, | |||
257 | union acpi_operand_object *obj_desc; | 315 | union acpi_operand_object *obj_desc; |
258 | acpi_status status; | 316 | acpi_status status; |
259 | 317 | ||
260 | ACPI_FUNCTION_TRACE("ut_evaluate_numeric_object"); | 318 | ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object); |
261 | 319 | ||
262 | status = acpi_ut_evaluate_object(device_node, object_name, | 320 | status = acpi_ut_evaluate_object(device_node, object_name, |
263 | ACPI_BTYPE_INTEGER, &obj_desc); | 321 | ACPI_BTYPE_INTEGER, &obj_desc); |
@@ -333,7 +391,7 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | |||
333 | union acpi_operand_object *obj_desc; | 391 | union acpi_operand_object *obj_desc; |
334 | acpi_status status; | 392 | acpi_status status; |
335 | 393 | ||
336 | ACPI_FUNCTION_TRACE("ut_execute_HID"); | 394 | ACPI_FUNCTION_TRACE(ut_execute_HID); |
337 | 395 | ||
338 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID, | 396 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID, |
339 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | 397 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, |
@@ -343,6 +401,7 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | |||
343 | } | 401 | } |
344 | 402 | ||
345 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { | 403 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { |
404 | |||
346 | /* Convert the Numeric HID to string */ | 405 | /* Convert the Numeric HID to string */ |
347 | 406 | ||
348 | acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, | 407 | acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, |
@@ -436,7 +495,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node, | |||
436 | struct acpi_compatible_id_list *cid_list; | 495 | struct acpi_compatible_id_list *cid_list; |
437 | acpi_native_uint i; | 496 | acpi_native_uint i; |
438 | 497 | ||
439 | ACPI_FUNCTION_TRACE("ut_execute_CID"); | 498 | ACPI_FUNCTION_TRACE(ut_execute_CID); |
440 | 499 | ||
441 | /* Evaluate the _CID method for this device */ | 500 | /* Evaluate the _CID method for this device */ |
442 | 501 | ||
@@ -459,7 +518,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node, | |||
459 | size = (((count - 1) * sizeof(struct acpi_compatible_id)) + | 518 | size = (((count - 1) * sizeof(struct acpi_compatible_id)) + |
460 | sizeof(struct acpi_compatible_id_list)); | 519 | sizeof(struct acpi_compatible_id_list)); |
461 | 520 | ||
462 | cid_list = ACPI_MEM_CALLOCATE((acpi_size) size); | 521 | cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); |
463 | if (!cid_list) { | 522 | if (!cid_list) { |
464 | return_ACPI_STATUS(AE_NO_MEMORY); | 523 | return_ACPI_STATUS(AE_NO_MEMORY); |
465 | } | 524 | } |
@@ -479,6 +538,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node, | |||
479 | /* The _CID object can be either a single CID or a package (list) of CIDs */ | 538 | /* The _CID object can be either a single CID or a package (list) of CIDs */ |
480 | 539 | ||
481 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) { | 540 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) { |
541 | |||
482 | /* Translate each package element */ | 542 | /* Translate each package element */ |
483 | 543 | ||
484 | for (i = 0; i < count; i++) { | 544 | for (i = 0; i < count; i++) { |
@@ -499,7 +559,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node, | |||
499 | /* Cleanup on error */ | 559 | /* Cleanup on error */ |
500 | 560 | ||
501 | if (ACPI_FAILURE(status)) { | 561 | if (ACPI_FAILURE(status)) { |
502 | ACPI_MEM_FREE(cid_list); | 562 | ACPI_FREE(cid_list); |
503 | } else { | 563 | } else { |
504 | *return_cid_list = cid_list; | 564 | *return_cid_list = cid_list; |
505 | } | 565 | } |
@@ -533,7 +593,7 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | |||
533 | union acpi_operand_object *obj_desc; | 593 | union acpi_operand_object *obj_desc; |
534 | acpi_status status; | 594 | acpi_status status; |
535 | 595 | ||
536 | ACPI_FUNCTION_TRACE("ut_execute_UID"); | 596 | ACPI_FUNCTION_TRACE(ut_execute_UID); |
537 | 597 | ||
538 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID, | 598 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID, |
539 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | 599 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, |
@@ -543,6 +603,7 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | |||
543 | } | 603 | } |
544 | 604 | ||
545 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { | 605 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { |
606 | |||
546 | /* Convert the Numeric UID to string */ | 607 | /* Convert the Numeric UID to string */ |
547 | 608 | ||
548 | acpi_ex_unsigned_integer_to_string(obj_desc->integer.value, | 609 | acpi_ex_unsigned_integer_to_string(obj_desc->integer.value, |
@@ -582,7 +643,7 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) | |||
582 | union acpi_operand_object *obj_desc; | 643 | union acpi_operand_object *obj_desc; |
583 | acpi_status status; | 644 | acpi_status status; |
584 | 645 | ||
585 | ACPI_FUNCTION_TRACE("ut_execute_STA"); | 646 | ACPI_FUNCTION_TRACE(ut_execute_STA); |
586 | 647 | ||
587 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA, | 648 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA, |
588 | ACPI_BTYPE_INTEGER, &obj_desc); | 649 | ACPI_BTYPE_INTEGER, &obj_desc); |
@@ -632,7 +693,7 @@ acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest) | |||
632 | acpi_status status; | 693 | acpi_status status; |
633 | u32 i; | 694 | u32 i; |
634 | 695 | ||
635 | ACPI_FUNCTION_TRACE("ut_execute_Sxds"); | 696 | ACPI_FUNCTION_TRACE(ut_execute_sxds); |
636 | 697 | ||
637 | for (i = 0; i < 4; i++) { | 698 | for (i = 0; i < 4; i++) { |
638 | highest[i] = 0xFF; | 699 | highest[i] = 0xFF; |