1 /******************************************************************************
2 *
3 * Module Name: uteval - Object evaluation
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2004, 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
45 #include <acpi/acpi.h>
46 #include <acpi/acnamesp.h>
47 #include <acpi/acinterp.h>
48
49
50 #define _COMPONENT ACPI_UTILITIES
51 ACPI_MODULE_NAME ("uteval")
52
53
54 /*******************************************************************************
55 *
56 * FUNCTION: acpi_ut_osi_implementation
57 *
58 * PARAMETERS: walk_state - Current walk state
59 *
60 * RETURN: Status
61 *
62 * DESCRIPTION: Implementation of _OSI predefined control method
63 * Supported = _OSI (String)
64 *
65 ******************************************************************************/
66
67 acpi_status
acpi_ut_osi_implementation(struct acpi_walk_state * walk_state)68 acpi_ut_osi_implementation (
69 struct acpi_walk_state *walk_state)
70 {
71 union acpi_operand_object *string_desc;
72 union acpi_operand_object *return_desc;
73 acpi_native_uint i;
74
75
76 ACPI_FUNCTION_TRACE ("ut_osi_implementation");
77
78
79 /* Validate the string input argument */
80
81 string_desc = walk_state->arguments[0].object;
82 if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
83 return_ACPI_STATUS (AE_TYPE);
84 }
85
86 /* Create a return object (Default value = 0) */
87
88 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
89 if (!return_desc) {
90 return_ACPI_STATUS (AE_NO_MEMORY);
91 }
92
93 /* Compare input string to table of supported strings */
94
95 for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) {
96 if (!ACPI_STRCMP (string_desc->string.pointer,
97 (char *) acpi_gbl_valid_osi_strings[i])) {
98 /* This string is supported */
99
100 return_desc->integer.value = 0xFFFFFFFF;
101 break;
102 }
103 }
104
105 walk_state->return_desc = return_desc;
106 return_ACPI_STATUS (AE_CTRL_TERMINATE);
107 }
108
109
110 /*******************************************************************************
111 *
112 * FUNCTION: acpi_ut_evaluate_object
113 *
114 * PARAMETERS: prefix_node - Starting node
115 * Path - Path to object from starting node
116 * expected_return_types - Bitmap of allowed return types
117 * return_desc - Where a return value is stored
118 *
119 * RETURN: Status
120 *
121 * DESCRIPTION: Evaluates a namespace object and verifies the type of the
122 * return object. Common code that simplifies accessing objects
123 * that have required return objects of fixed types.
124 *
125 * NOTE: Internal function, no parameter validation
126 *
127 ******************************************************************************/
128
129 acpi_status
acpi_ut_evaluate_object(struct acpi_namespace_node * prefix_node,char * path,u32 expected_return_btypes,union acpi_operand_object ** return_desc)130 acpi_ut_evaluate_object (
131 struct acpi_namespace_node *prefix_node,
132 char *path,
133 u32 expected_return_btypes,
134 union acpi_operand_object **return_desc)
135 {
136 union acpi_operand_object *obj_desc;
137 acpi_status status;
138 u32 return_btype;
139
140
141 ACPI_FUNCTION_TRACE ("ut_evaluate_object");
142
143
144 /* Evaluate the object/method */
145
146 status = acpi_ns_evaluate_relative (prefix_node, path, NULL, &obj_desc);
147 if (ACPI_FAILURE (status)) {
148 if (status == AE_NOT_FOUND) {
149 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
150 acpi_ut_get_node_name (prefix_node), path));
151 }
152 else {
153 ACPI_REPORT_METHOD_ERROR ("Method execution failed",
154 prefix_node, path, status);
155 }
156
157 return_ACPI_STATUS (status);
158 }
159
160 /* Did we get a return object? */
161
162 if (!obj_desc) {
163 if (expected_return_btypes) {
164 ACPI_REPORT_METHOD_ERROR ("No object was returned from",
165 prefix_node, path, AE_NOT_EXIST);
166
167 return_ACPI_STATUS (AE_NOT_EXIST);
168 }
169
170 return_ACPI_STATUS (AE_OK);
171 }
172
173 /* Map the return object type to the bitmapped type */
174
175 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
176 case ACPI_TYPE_INTEGER:
177 return_btype = ACPI_BTYPE_INTEGER;
178 break;
179
180 case ACPI_TYPE_BUFFER:
181 return_btype = ACPI_BTYPE_BUFFER;
182 break;
183
184 case ACPI_TYPE_STRING:
185 return_btype = ACPI_BTYPE_STRING;
186 break;
187
188 case ACPI_TYPE_PACKAGE:
189 return_btype = ACPI_BTYPE_PACKAGE;
190 break;
191
192 default:
193 return_btype = 0;
194 break;
195 }
196
197 /* Is the return object one of the expected types? */
198
199 if (!(expected_return_btypes & return_btype)) {
200 ACPI_REPORT_METHOD_ERROR ("Return object type is incorrect",
201 prefix_node, path, AE_TYPE);
202
203 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
204 "Type returned from %s was incorrect: %X\n",
205 path, ACPI_GET_OBJECT_TYPE (obj_desc)));
206
207 /* On error exit, we must delete the return object */
208
209 acpi_ut_remove_reference (obj_desc);
210 return_ACPI_STATUS (AE_TYPE);
211 }
212
213 /* Object type is OK, return it */
214
215 *return_desc = obj_desc;
216 return_ACPI_STATUS (AE_OK);
217 }
218
219
220 /*******************************************************************************
221 *
222 * FUNCTION: acpi_ut_evaluate_numeric_object
223 *
224 * PARAMETERS: *object_name - Object name to be evaluated
225 * device_node - Node for the device
226 * *Address - Where the value is returned
227 *
228 * RETURN: Status
229 *
230 * DESCRIPTION: Evaluates a numeric namespace object for a selected device
231 * and stores result in *Address.
232 *
233 * NOTE: Internal function, no parameter validation
234 *
235 ******************************************************************************/
236
237 acpi_status
acpi_ut_evaluate_numeric_object(char * object_name,struct acpi_namespace_node * device_node,acpi_integer * address)238 acpi_ut_evaluate_numeric_object (
239 char *object_name,
240 struct acpi_namespace_node *device_node,
241 acpi_integer *address)
242 {
243 union acpi_operand_object *obj_desc;
244 acpi_status status;
245
246
247 ACPI_FUNCTION_TRACE ("ut_evaluate_numeric_object");
248
249
250 status = acpi_ut_evaluate_object (device_node, object_name,
251 ACPI_BTYPE_INTEGER, &obj_desc);
252 if (ACPI_FAILURE (status)) {
253 return_ACPI_STATUS (status);
254 }
255
256 /* Get the returned Integer */
257
258 *address = obj_desc->integer.value;
259
260 /* On exit, we must delete the return object */
261
262 acpi_ut_remove_reference (obj_desc);
263 return_ACPI_STATUS (status);
264 }
265
266
267 /*******************************************************************************
268 *
269 * FUNCTION: acpi_ut_copy_id_string
270 *
271 * PARAMETERS: Destination - Where to copy the string
272 * Source - Source string
273 * max_length - Length of the destination buffer
274 *
275 * RETURN: None
276 *
277 * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
278 * Performs removal of a leading asterisk if present -- workaround
279 * for a known issue on a bunch of machines.
280 *
281 ******************************************************************************/
282
283 static void
acpi_ut_copy_id_string(char * destination,char * source,acpi_size max_length)284 acpi_ut_copy_id_string (
285 char *destination,
286 char *source,
287 acpi_size max_length)
288 {
289
290
291 /*
292 * Workaround for ID strings that have a leading asterisk. This construct
293 * is not allowed by the ACPI specification (ID strings must be
294 * alphanumeric), but enough existing machines have this embedded in their
295 * ID strings that the following code is useful.
296 */
297 if (*source == '*') {
298 source++;
299 }
300
301 /* Do the actual copy */
302
303 ACPI_STRNCPY (destination, source, max_length);
304 }
305
306
307 /*******************************************************************************
308 *
309 * FUNCTION: acpi_ut_execute_HID
310 *
311 * PARAMETERS: device_node - Node for the device
312 * *Hid - Where the HID is returned
313 *
314 * RETURN: Status
315 *
316 * DESCRIPTION: Executes the _HID control method that returns the hardware
317 * ID of the device.
318 *
319 * NOTE: Internal function, no parameter validation
320 *
321 ******************************************************************************/
322
323 acpi_status
acpi_ut_execute_HID(struct acpi_namespace_node * device_node,struct acpi_device_id * hid)324 acpi_ut_execute_HID (
325 struct acpi_namespace_node *device_node,
326 struct acpi_device_id *hid)
327 {
328 union acpi_operand_object *obj_desc;
329 acpi_status status;
330
331
332 ACPI_FUNCTION_TRACE ("ut_execute_HID");
333
334
335 status = acpi_ut_evaluate_object (device_node, METHOD_NAME__HID,
336 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc);
337 if (ACPI_FAILURE (status)) {
338 return_ACPI_STATUS (status);
339 }
340
341 if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
342 /* Convert the Numeric HID to string */
343
344 acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->value);
345 }
346 else {
347 /* Copy the String HID from the returned object */
348
349 acpi_ut_copy_id_string (hid->value, obj_desc->string.pointer,
350 sizeof (hid->value));
351 }
352
353 /* On exit, we must delete the return object */
354
355 acpi_ut_remove_reference (obj_desc);
356 return_ACPI_STATUS (status);
357 }
358
359
360 /*******************************************************************************
361 *
362 * FUNCTION: acpi_ut_translate_one_cid
363 *
364 * PARAMETERS: obj_desc - _CID object, must be integer or string
365 * one_cid - Where the CID string is returned
366 *
367 * RETURN: Status
368 *
369 * DESCRIPTION: Return a numeric or string _CID value as a string.
370 * (Compatible ID)
371 *
372 * NOTE: Assumes a maximum _CID string length of
373 * ACPI_MAX_CID_LENGTH.
374 *
375 ******************************************************************************/
376
377 static acpi_status
acpi_ut_translate_one_cid(union acpi_operand_object * obj_desc,struct acpi_compatible_id * one_cid)378 acpi_ut_translate_one_cid (
379 union acpi_operand_object *obj_desc,
380 struct acpi_compatible_id *one_cid)
381 {
382
383
384 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
385 case ACPI_TYPE_INTEGER:
386
387 /* Convert the Numeric CID to string */
388
389 acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, one_cid->value);
390 return (AE_OK);
391
392 case ACPI_TYPE_STRING:
393
394 if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
395 return (AE_AML_STRING_LIMIT);
396 }
397
398 /* Copy the String CID from the returned object */
399
400 acpi_ut_copy_id_string (one_cid->value, obj_desc->string.pointer,
401 ACPI_MAX_CID_LENGTH);
402 return (AE_OK);
403
404 default:
405
406 return (AE_TYPE);
407 }
408 }
409
410
411 /*******************************************************************************
412 *
413 * FUNCTION: acpi_ut_execute_CID
414 *
415 * PARAMETERS: device_node - Node for the device
416 * *Cid - Where the CID is returned
417 *
418 * RETURN: Status
419 *
420 * DESCRIPTION: Executes the _CID control method that returns one or more
421 * compatible hardware IDs for the device.
422 *
423 * NOTE: Internal function, no parameter validation
424 *
425 ******************************************************************************/
426
427 acpi_status
acpi_ut_execute_CID(struct acpi_namespace_node * device_node,struct acpi_compatible_id_list ** return_cid_list)428 acpi_ut_execute_CID (
429 struct acpi_namespace_node *device_node,
430 struct acpi_compatible_id_list **return_cid_list)
431 {
432 union acpi_operand_object *obj_desc;
433 acpi_status status;
434 u32 count;
435 u32 size;
436 struct acpi_compatible_id_list *cid_list;
437 acpi_native_uint i;
438
439
440 ACPI_FUNCTION_TRACE ("ut_execute_CID");
441
442
443 /* Evaluate the _CID method for this device */
444
445 status = acpi_ut_evaluate_object (device_node, METHOD_NAME__CID,
446 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE,
447 &obj_desc);
448 if (ACPI_FAILURE (status)) {
449 return_ACPI_STATUS (status);
450 }
451
452 /* Get the number of _CIDs returned */
453
454 count = 1;
455 if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
456 count = obj_desc->package.count;
457 }
458
459 /* Allocate a worst-case buffer for the _CIDs */
460
461 size = (((count - 1) * sizeof (struct acpi_compatible_id)) +
462 sizeof (struct acpi_compatible_id_list));
463
464 cid_list = ACPI_MEM_CALLOCATE ((acpi_size) size);
465 if (!cid_list) {
466 return_ACPI_STATUS (AE_NO_MEMORY);
467 }
468
469 /* Init CID list */
470
471 cid_list->count = count;
472 cid_list->size = size;
473
474 /*
475 * A _CID can return either a single compatible ID or a package of compatible
476 * IDs. Each compatible ID can be one of the following:
477 * -- Number (32 bit compressed EISA ID) or
478 * -- String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss").
479 */
480
481 /* The _CID object can be either a single CID or a package (list) of CIDs */
482
483 if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
484 /* Translate each package element */
485
486 for (i = 0; i < count; i++) {
487 status = acpi_ut_translate_one_cid (obj_desc->package.elements[i],
488 &cid_list->id[i]);
489 if (ACPI_FAILURE (status)) {
490 break;
491 }
492 }
493 }
494 else {
495 /* Only one CID, translate to a string */
496
497 status = acpi_ut_translate_one_cid (obj_desc, cid_list->id);
498 }
499
500 /* Cleanup on error */
501
502 if (ACPI_FAILURE (status)) {
503 ACPI_MEM_FREE (cid_list);
504 }
505 else {
506 *return_cid_list = cid_list;
507 }
508
509 /* On exit, we must delete the _CID return object */
510
511 acpi_ut_remove_reference (obj_desc);
512 return_ACPI_STATUS (status);
513 }
514
515
516 /*******************************************************************************
517 *
518 * FUNCTION: acpi_ut_execute_UID
519 *
520 * PARAMETERS: device_node - Node for the device
521 * *Uid - Where the UID is returned
522 *
523 * RETURN: Status
524 *
525 * DESCRIPTION: Executes the _UID control method that returns the hardware
526 * ID of the device.
527 *
528 * NOTE: Internal function, no parameter validation
529 *
530 ******************************************************************************/
531
532 acpi_status
acpi_ut_execute_UID(struct acpi_namespace_node * device_node,struct acpi_device_id * uid)533 acpi_ut_execute_UID (
534 struct acpi_namespace_node *device_node,
535 struct acpi_device_id *uid)
536 {
537 union acpi_operand_object *obj_desc;
538 acpi_status status;
539
540
541 ACPI_FUNCTION_TRACE ("ut_execute_UID");
542
543
544 status = acpi_ut_evaluate_object (device_node, METHOD_NAME__UID,
545 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc);
546 if (ACPI_FAILURE (status)) {
547 return_ACPI_STATUS (status);
548 }
549
550 if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
551 /* Convert the Numeric UID to string */
552
553 acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->value);
554 }
555 else {
556 /* Copy the String UID from the returned object */
557
558 acpi_ut_copy_id_string (uid->value, obj_desc->string.pointer,
559 sizeof (uid->value));
560 }
561
562 /* On exit, we must delete the return object */
563
564 acpi_ut_remove_reference (obj_desc);
565 return_ACPI_STATUS (status);
566 }
567
568
569 /*******************************************************************************
570 *
571 * FUNCTION: acpi_ut_execute_STA
572 *
573 * PARAMETERS: device_node - Node for the device
574 * *Flags - Where the status flags are returned
575 *
576 * RETURN: Status
577 *
578 * DESCRIPTION: Executes _STA for selected device and stores results in
579 * *Flags.
580 *
581 * NOTE: Internal function, no parameter validation
582 *
583 ******************************************************************************/
584
585 acpi_status
acpi_ut_execute_STA(struct acpi_namespace_node * device_node,u32 * flags)586 acpi_ut_execute_STA (
587 struct acpi_namespace_node *device_node,
588 u32 *flags)
589 {
590 union acpi_operand_object *obj_desc;
591 acpi_status status;
592
593
594 ACPI_FUNCTION_TRACE ("ut_execute_STA");
595
596
597 status = acpi_ut_evaluate_object (device_node, METHOD_NAME__STA,
598 ACPI_BTYPE_INTEGER, &obj_desc);
599 if (ACPI_FAILURE (status)) {
600 if (AE_NOT_FOUND == status) {
601 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
602 "_STA on %4.4s was not found, assuming device is present\n",
603 acpi_ut_get_node_name (device_node)));
604
605 *flags = 0x0F;
606 status = AE_OK;
607 }
608
609 return_ACPI_STATUS (status);
610 }
611
612 /* Extract the status flags */
613
614 *flags = (u32) obj_desc->integer.value;
615
616 /* On exit, we must delete the return object */
617
618 acpi_ut_remove_reference (obj_desc);
619 return_ACPI_STATUS (status);
620 }
621
622
623 /*******************************************************************************
624 *
625 * FUNCTION: acpi_ut_execute_Sxds
626 *
627 * PARAMETERS: device_node - Node for the device
628 * *Flags - Where the status flags are returned
629 *
630 * RETURN: Status
631 *
632 * DESCRIPTION: Executes _STA for selected device and stores results in
633 * *Flags.
634 *
635 * NOTE: Internal function, no parameter validation
636 *
637 ******************************************************************************/
638
639 acpi_status
acpi_ut_execute_sxds(struct acpi_namespace_node * device_node,u8 * highest)640 acpi_ut_execute_sxds (
641 struct acpi_namespace_node *device_node,
642 u8 *highest)
643 {
644 union acpi_operand_object *obj_desc;
645 acpi_status status;
646 u32 i;
647
648
649 ACPI_FUNCTION_TRACE ("ut_execute_Sxds");
650
651
652 for (i = 0; i < 4; i++) {
653 highest[i] = 0xFF;
654 status = acpi_ut_evaluate_object (device_node,
655 (char *) acpi_gbl_highest_dstate_names[i],
656 ACPI_BTYPE_INTEGER, &obj_desc);
657 if (ACPI_FAILURE (status)) {
658 if (status != AE_NOT_FOUND) {
659 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
660 "%s on Device %4.4s, %s\n",
661 (char *) acpi_gbl_highest_dstate_names[i],
662 acpi_ut_get_node_name (device_node),
663 acpi_format_exception (status)));
664
665 return_ACPI_STATUS (status);
666 }
667 }
668 else {
669 /* Extract the Dstate value */
670
671 highest[i] = (u8) obj_desc->integer.value;
672
673 /* Delete the return object */
674
675 acpi_ut_remove_reference (obj_desc);
676 }
677 }
678
679 return_ACPI_STATUS (AE_OK);
680 }
681