diff options
author | Bob Moore <robert.moore@intel.com> | 2009-06-29 01:39:29 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-08-27 10:17:15 -0400 |
commit | 15b8dd53f5ffaf8e2d9095c423f713423f576c0f (patch) | |
tree | 773f09435b14a810372642502352d46c29b6f148 /drivers/acpi/acpica/uteval.c | |
parent | 9c61b34cf7078da72cce276ff8cfae5d6e9955bc (diff) |
ACPICA: Major update for acpi_get_object_info external interface
Completed a major update for the acpi_get_object_info external interface.
Changes include:
- Support for variable, unlimited length HID, UID, and CID strings
- Support Processor objects the same as Devices (HID,UID,CID,ADR,STA, etc.)
- Call the _SxW power methods on behalf of a device object
- Determine if a device is a PCI root bridge
- Change the ACPI_BUFFER parameter to ACPI_DEVICE_INFO.
These changes will require an update to all callers of this interface.
See the ACPICA Programmer Reference for details.
Also, update all invocations of acpi_get_object_info interface
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/uteval.c')
-rw-r--r-- | drivers/acpi/acpica/uteval.c | 375 |
1 files changed, 41 insertions, 334 deletions
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 006b16c26017..5503307b8bb7 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c | |||
@@ -44,19 +44,10 @@ | |||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acnamesp.h" | 46 | #include "acnamesp.h" |
47 | #include "acinterp.h" | ||
48 | 47 | ||
49 | #define _COMPONENT ACPI_UTILITIES | 48 | #define _COMPONENT ACPI_UTILITIES |
50 | ACPI_MODULE_NAME("uteval") | 49 | ACPI_MODULE_NAME("uteval") |
51 | 50 | ||
52 | /* Local prototypes */ | ||
53 | static void | ||
54 | acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length); | ||
55 | |||
56 | static acpi_status | ||
57 | acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, | ||
58 | struct acpi_compatible_id *one_cid); | ||
59 | |||
60 | /* | 51 | /* |
61 | * Strings supported by the _OSI predefined (internal) method. | 52 | * Strings supported by the _OSI predefined (internal) method. |
62 | * | 53 | * |
@@ -213,7 +204,7 @@ acpi_status acpi_osi_invalidate(char *interface) | |||
213 | * RETURN: Status | 204 | * RETURN: Status |
214 | * | 205 | * |
215 | * DESCRIPTION: Evaluates a namespace object and verifies the type of the | 206 | * DESCRIPTION: Evaluates a namespace object and verifies the type of the |
216 | * return object. Common code that simplifies accessing objects | 207 | * return object. Common code that simplifies accessing objects |
217 | * that have required return objects of fixed types. | 208 | * that have required return objects of fixed types. |
218 | * | 209 | * |
219 | * NOTE: Internal function, no parameter validation | 210 | * NOTE: Internal function, no parameter validation |
@@ -298,7 +289,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
298 | 289 | ||
299 | if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { | 290 | if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { |
300 | /* | 291 | /* |
301 | * We received a return object, but one was not expected. This can | 292 | * We received a return object, but one was not expected. This can |
302 | * happen frequently if the "implicit return" feature is enabled. | 293 | * happen frequently if the "implicit return" feature is enabled. |
303 | * Just delete the return object and return AE_OK. | 294 | * Just delete the return object and return AE_OK. |
304 | */ | 295 | */ |
@@ -340,12 +331,12 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
340 | * | 331 | * |
341 | * PARAMETERS: object_name - Object name to be evaluated | 332 | * PARAMETERS: object_name - Object name to be evaluated |
342 | * device_node - Node for the device | 333 | * device_node - Node for the device |
343 | * Address - Where the value is returned | 334 | * Value - Where the value is returned |
344 | * | 335 | * |
345 | * RETURN: Status | 336 | * RETURN: Status |
346 | * | 337 | * |
347 | * DESCRIPTION: Evaluates a numeric namespace object for a selected device | 338 | * DESCRIPTION: Evaluates a numeric namespace object for a selected device |
348 | * and stores result in *Address. | 339 | * and stores result in *Value. |
349 | * | 340 | * |
350 | * NOTE: Internal function, no parameter validation | 341 | * NOTE: Internal function, no parameter validation |
351 | * | 342 | * |
@@ -354,7 +345,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
354 | acpi_status | 345 | acpi_status |
355 | acpi_ut_evaluate_numeric_object(char *object_name, | 346 | acpi_ut_evaluate_numeric_object(char *object_name, |
356 | struct acpi_namespace_node *device_node, | 347 | struct acpi_namespace_node *device_node, |
357 | acpi_integer * address) | 348 | acpi_integer *value) |
358 | { | 349 | { |
359 | union acpi_operand_object *obj_desc; | 350 | union acpi_operand_object *obj_desc; |
360 | acpi_status status; | 351 | acpi_status status; |
@@ -369,295 +360,7 @@ acpi_ut_evaluate_numeric_object(char *object_name, | |||
369 | 360 | ||
370 | /* Get the returned Integer */ | 361 | /* Get the returned Integer */ |
371 | 362 | ||
372 | *address = obj_desc->integer.value; | 363 | *value = obj_desc->integer.value; |
373 | |||
374 | /* On exit, we must delete the return object */ | ||
375 | |||
376 | acpi_ut_remove_reference(obj_desc); | ||
377 | return_ACPI_STATUS(status); | ||
378 | } | ||
379 | |||
380 | /******************************************************************************* | ||
381 | * | ||
382 | * FUNCTION: acpi_ut_copy_id_string | ||
383 | * | ||
384 | * PARAMETERS: Destination - Where to copy the string | ||
385 | * Source - Source string | ||
386 | * max_length - Length of the destination buffer | ||
387 | * | ||
388 | * RETURN: None | ||
389 | * | ||
390 | * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. | ||
391 | * Performs removal of a leading asterisk if present -- workaround | ||
392 | * for a known issue on a bunch of machines. | ||
393 | * | ||
394 | ******************************************************************************/ | ||
395 | |||
396 | static void | ||
397 | acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length) | ||
398 | { | ||
399 | |||
400 | /* | ||
401 | * Workaround for ID strings that have a leading asterisk. This construct | ||
402 | * is not allowed by the ACPI specification (ID strings must be | ||
403 | * alphanumeric), but enough existing machines have this embedded in their | ||
404 | * ID strings that the following code is useful. | ||
405 | */ | ||
406 | if (*source == '*') { | ||
407 | source++; | ||
408 | } | ||
409 | |||
410 | /* Do the actual copy */ | ||
411 | |||
412 | ACPI_STRNCPY(destination, source, max_length); | ||
413 | } | ||
414 | |||
415 | /******************************************************************************* | ||
416 | * | ||
417 | * FUNCTION: acpi_ut_execute_HID | ||
418 | * | ||
419 | * PARAMETERS: device_node - Node for the device | ||
420 | * Hid - Where the HID is returned | ||
421 | * | ||
422 | * RETURN: Status | ||
423 | * | ||
424 | * DESCRIPTION: Executes the _HID control method that returns the hardware | ||
425 | * ID of the device. | ||
426 | * | ||
427 | * NOTE: Internal function, no parameter validation | ||
428 | * | ||
429 | ******************************************************************************/ | ||
430 | |||
431 | acpi_status | ||
432 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | ||
433 | struct acpica_device_id *hid) | ||
434 | { | ||
435 | union acpi_operand_object *obj_desc; | ||
436 | acpi_status status; | ||
437 | |||
438 | ACPI_FUNCTION_TRACE(ut_execute_HID); | ||
439 | |||
440 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID, | ||
441 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | ||
442 | &obj_desc); | ||
443 | if (ACPI_FAILURE(status)) { | ||
444 | return_ACPI_STATUS(status); | ||
445 | } | ||
446 | |||
447 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
448 | |||
449 | /* Convert the Numeric HID to string */ | ||
450 | |||
451 | acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, | ||
452 | hid->value); | ||
453 | } else { | ||
454 | /* Copy the String HID from the returned object */ | ||
455 | |||
456 | acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer, | ||
457 | sizeof(hid->value)); | ||
458 | } | ||
459 | |||
460 | /* On exit, we must delete the return object */ | ||
461 | |||
462 | acpi_ut_remove_reference(obj_desc); | ||
463 | return_ACPI_STATUS(status); | ||
464 | } | ||
465 | |||
466 | /******************************************************************************* | ||
467 | * | ||
468 | * FUNCTION: acpi_ut_translate_one_cid | ||
469 | * | ||
470 | * PARAMETERS: obj_desc - _CID object, must be integer or string | ||
471 | * one_cid - Where the CID string is returned | ||
472 | * | ||
473 | * RETURN: Status | ||
474 | * | ||
475 | * DESCRIPTION: Return a numeric or string _CID value as a string. | ||
476 | * (Compatible ID) | ||
477 | * | ||
478 | * NOTE: Assumes a maximum _CID string length of | ||
479 | * ACPI_MAX_CID_LENGTH. | ||
480 | * | ||
481 | ******************************************************************************/ | ||
482 | |||
483 | static acpi_status | ||
484 | acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, | ||
485 | struct acpi_compatible_id *one_cid) | ||
486 | { | ||
487 | |||
488 | switch (obj_desc->common.type) { | ||
489 | case ACPI_TYPE_INTEGER: | ||
490 | |||
491 | /* Convert the Numeric CID to string */ | ||
492 | |||
493 | acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, | ||
494 | one_cid->value); | ||
495 | return (AE_OK); | ||
496 | |||
497 | case ACPI_TYPE_STRING: | ||
498 | |||
499 | if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) { | ||
500 | return (AE_AML_STRING_LIMIT); | ||
501 | } | ||
502 | |||
503 | /* Copy the String CID from the returned object */ | ||
504 | |||
505 | acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer, | ||
506 | ACPI_MAX_CID_LENGTH); | ||
507 | return (AE_OK); | ||
508 | |||
509 | default: | ||
510 | |||
511 | return (AE_TYPE); | ||
512 | } | ||
513 | } | ||
514 | |||
515 | /******************************************************************************* | ||
516 | * | ||
517 | * FUNCTION: acpi_ut_execute_CID | ||
518 | * | ||
519 | * PARAMETERS: device_node - Node for the device | ||
520 | * return_cid_list - Where the CID list is returned | ||
521 | * | ||
522 | * RETURN: Status | ||
523 | * | ||
524 | * DESCRIPTION: Executes the _CID control method that returns one or more | ||
525 | * compatible hardware IDs for the device. | ||
526 | * | ||
527 | * NOTE: Internal function, no parameter validation | ||
528 | * | ||
529 | ******************************************************************************/ | ||
530 | |||
531 | acpi_status | ||
532 | acpi_ut_execute_CID(struct acpi_namespace_node * device_node, | ||
533 | struct acpi_compatible_id_list ** return_cid_list) | ||
534 | { | ||
535 | union acpi_operand_object *obj_desc; | ||
536 | acpi_status status; | ||
537 | u32 count; | ||
538 | u32 size; | ||
539 | struct acpi_compatible_id_list *cid_list; | ||
540 | u32 i; | ||
541 | |||
542 | ACPI_FUNCTION_TRACE(ut_execute_CID); | ||
543 | |||
544 | /* Evaluate the _CID method for this device */ | ||
545 | |||
546 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID, | ||
547 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ||
548 | | ACPI_BTYPE_PACKAGE, &obj_desc); | ||
549 | if (ACPI_FAILURE(status)) { | ||
550 | return_ACPI_STATUS(status); | ||
551 | } | ||
552 | |||
553 | /* Get the number of _CIDs returned */ | ||
554 | |||
555 | count = 1; | ||
556 | if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { | ||
557 | count = obj_desc->package.count; | ||
558 | } | ||
559 | |||
560 | /* Allocate a worst-case buffer for the _CIDs */ | ||
561 | |||
562 | size = (((count - 1) * sizeof(struct acpi_compatible_id)) + | ||
563 | sizeof(struct acpi_compatible_id_list)); | ||
564 | |||
565 | cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); | ||
566 | if (!cid_list) { | ||
567 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
568 | } | ||
569 | |||
570 | /* Init CID list */ | ||
571 | |||
572 | cid_list->count = count; | ||
573 | cid_list->size = size; | ||
574 | |||
575 | /* | ||
576 | * A _CID can return either a single compatible ID or a package of | ||
577 | * compatible IDs. Each compatible ID can be one of the following: | ||
578 | * 1) Integer (32 bit compressed EISA ID) or | ||
579 | * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss") | ||
580 | */ | ||
581 | |||
582 | /* The _CID object can be either a single CID or a package (list) of CIDs */ | ||
583 | |||
584 | if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { | ||
585 | |||
586 | /* Translate each package element */ | ||
587 | |||
588 | for (i = 0; i < count; i++) { | ||
589 | status = | ||
590 | acpi_ut_translate_one_cid(obj_desc->package. | ||
591 | elements[i], | ||
592 | &cid_list->id[i]); | ||
593 | if (ACPI_FAILURE(status)) { | ||
594 | break; | ||
595 | } | ||
596 | } | ||
597 | } else { | ||
598 | /* Only one CID, translate to a string */ | ||
599 | |||
600 | status = acpi_ut_translate_one_cid(obj_desc, cid_list->id); | ||
601 | } | ||
602 | |||
603 | /* Cleanup on error */ | ||
604 | |||
605 | if (ACPI_FAILURE(status)) { | ||
606 | ACPI_FREE(cid_list); | ||
607 | } else { | ||
608 | *return_cid_list = cid_list; | ||
609 | } | ||
610 | |||
611 | /* On exit, we must delete the _CID return object */ | ||
612 | |||
613 | acpi_ut_remove_reference(obj_desc); | ||
614 | return_ACPI_STATUS(status); | ||
615 | } | ||
616 | |||
617 | /******************************************************************************* | ||
618 | * | ||
619 | * FUNCTION: acpi_ut_execute_UID | ||
620 | * | ||
621 | * PARAMETERS: device_node - Node for the device | ||
622 | * Uid - Where the UID is returned | ||
623 | * | ||
624 | * RETURN: Status | ||
625 | * | ||
626 | * DESCRIPTION: Executes the _UID control method that returns the hardware | ||
627 | * ID of the device. | ||
628 | * | ||
629 | * NOTE: Internal function, no parameter validation | ||
630 | * | ||
631 | ******************************************************************************/ | ||
632 | |||
633 | acpi_status | ||
634 | acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | ||
635 | struct acpica_device_id *uid) | ||
636 | { | ||
637 | union acpi_operand_object *obj_desc; | ||
638 | acpi_status status; | ||
639 | |||
640 | ACPI_FUNCTION_TRACE(ut_execute_UID); | ||
641 | |||
642 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID, | ||
643 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | ||
644 | &obj_desc); | ||
645 | if (ACPI_FAILURE(status)) { | ||
646 | return_ACPI_STATUS(status); | ||
647 | } | ||
648 | |||
649 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
650 | |||
651 | /* Convert the Numeric UID to string */ | ||
652 | |||
653 | acpi_ex_unsigned_integer_to_string(obj_desc->integer.value, | ||
654 | uid->value); | ||
655 | } else { | ||
656 | /* Copy the String UID from the returned object */ | ||
657 | |||
658 | acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer, | ||
659 | sizeof(uid->value)); | ||
660 | } | ||
661 | 364 | ||
662 | /* On exit, we must delete the return object */ | 365 | /* On exit, we must delete the return object */ |
663 | 366 | ||
@@ -716,60 +419,64 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) | |||
716 | 419 | ||
717 | /******************************************************************************* | 420 | /******************************************************************************* |
718 | * | 421 | * |
719 | * FUNCTION: acpi_ut_execute_Sxds | 422 | * FUNCTION: acpi_ut_execute_power_methods |
720 | * | 423 | * |
721 | * PARAMETERS: device_node - Node for the device | 424 | * PARAMETERS: device_node - Node for the device |
722 | * Flags - Where the status flags are returned | 425 | * method_names - Array of power method names |
426 | * method_count - Number of methods to execute | ||
427 | * out_values - Where the power method values are returned | ||
723 | * | 428 | * |
724 | * RETURN: Status | 429 | * RETURN: Status, out_values |
725 | * | 430 | * |
726 | * DESCRIPTION: Executes _STA for selected device and stores results in | 431 | * DESCRIPTION: Executes the specified power methods for the device and returns |
727 | * *Flags. | 432 | * the result(s). |
728 | * | 433 | * |
729 | * NOTE: Internal function, no parameter validation | 434 | * NOTE: Internal function, no parameter validation |
730 | * | 435 | * |
731 | ******************************************************************************/ | 436 | ******************************************************************************/ |
732 | 437 | ||
733 | acpi_status | 438 | acpi_status |
734 | acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest) | 439 | acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, |
440 | const char **method_names, | ||
441 | u8 method_count, u8 *out_values) | ||
735 | { | 442 | { |
736 | union acpi_operand_object *obj_desc; | 443 | union acpi_operand_object *obj_desc; |
737 | acpi_status status; | 444 | acpi_status status; |
445 | acpi_status final_status = AE_NOT_FOUND; | ||
738 | u32 i; | 446 | u32 i; |
739 | 447 | ||
740 | ACPI_FUNCTION_TRACE(ut_execute_sxds); | 448 | ACPI_FUNCTION_TRACE(ut_execute_power_methods); |
741 | 449 | ||
742 | for (i = 0; i < 4; i++) { | 450 | for (i = 0; i < method_count; i++) { |
743 | highest[i] = 0xFF; | 451 | /* |
452 | * Execute the power method (_sx_d or _sx_w). The only allowable | ||
453 | * return type is an Integer. | ||
454 | */ | ||
744 | status = acpi_ut_evaluate_object(device_node, | 455 | status = acpi_ut_evaluate_object(device_node, |
745 | ACPI_CAST_PTR(char, | 456 | ACPI_CAST_PTR(char, |
746 | acpi_gbl_highest_dstate_names | 457 | method_names[i]), |
747 | [i]), | ||
748 | ACPI_BTYPE_INTEGER, &obj_desc); | 458 | ACPI_BTYPE_INTEGER, &obj_desc); |
749 | if (ACPI_FAILURE(status)) { | 459 | if (ACPI_SUCCESS(status)) { |
750 | if (status != AE_NOT_FOUND) { | 460 | out_values[i] = (u8)obj_desc->integer.value; |
751 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
752 | "%s on Device %4.4s, %s\n", | ||
753 | ACPI_CAST_PTR(char, | ||
754 | acpi_gbl_highest_dstate_names | ||
755 | [i]), | ||
756 | acpi_ut_get_node_name | ||
757 | (device_node), | ||
758 | acpi_format_exception | ||
759 | (status))); | ||
760 | |||
761 | return_ACPI_STATUS(status); | ||
762 | } | ||
763 | } else { | ||
764 | /* Extract the Dstate value */ | ||
765 | |||
766 | highest[i] = (u8) obj_desc->integer.value; | ||
767 | 461 | ||
768 | /* Delete the return object */ | 462 | /* Delete the return object */ |
769 | 463 | ||
770 | acpi_ut_remove_reference(obj_desc); | 464 | acpi_ut_remove_reference(obj_desc); |
465 | final_status = AE_OK; /* At least one value is valid */ | ||
466 | continue; | ||
771 | } | 467 | } |
468 | |||
469 | out_values[i] = ACPI_UINT8_MAX; | ||
470 | if (status == AE_NOT_FOUND) { | ||
471 | continue; /* Ignore if not found */ | ||
472 | } | ||
473 | |||
474 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
475 | "Failed %s on Device %4.4s, %s\n", | ||
476 | ACPI_CAST_PTR(char, method_names[i]), | ||
477 | acpi_ut_get_node_name(device_node), | ||
478 | acpi_format_exception(status))); | ||
772 | } | 479 | } |
773 | 480 | ||
774 | return_ACPI_STATUS(AE_OK); | 481 | return_ACPI_STATUS(final_status); |
775 | } | 482 | } |