aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/namespace/nspredef.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/namespace/nspredef.c')
-rw-r--r--drivers/acpi/namespace/nspredef.c150
1 files changed, 123 insertions, 27 deletions
diff --git a/drivers/acpi/namespace/nspredef.c b/drivers/acpi/namespace/nspredef.c
index 0f17cf0898c9..3df17522117f 100644
--- a/drivers/acpi/namespace/nspredef.c
+++ b/drivers/acpi/namespace/nspredef.c
@@ -72,7 +72,7 @@ ACPI_MODULE_NAME("nspredef")
72/* Local prototypes */ 72/* Local prototypes */
73static acpi_status 73static acpi_status
74acpi_ns_check_package(char *pathname, 74acpi_ns_check_package(char *pathname,
75 union acpi_operand_object *return_object, 75 union acpi_operand_object **return_object_ptr,
76 const union acpi_predefined_info *predefined); 76 const union acpi_predefined_info *predefined);
77 77
78static acpi_status 78static acpi_status
@@ -82,13 +82,18 @@ acpi_ns_check_package_elements(char *pathname,
82 82
83static acpi_status 83static acpi_status
84acpi_ns_check_object_type(char *pathname, 84acpi_ns_check_object_type(char *pathname,
85 union acpi_operand_object *return_object, 85 union acpi_operand_object **return_object_ptr,
86 u32 expected_btypes, u32 package_index); 86 u32 expected_btypes, u32 package_index);
87 87
88static acpi_status 88static acpi_status
89acpi_ns_check_reference(char *pathname, 89acpi_ns_check_reference(char *pathname,
90 union acpi_operand_object *return_object); 90 union acpi_operand_object *return_object);
91 91
92static acpi_status
93acpi_ns_repair_object(u32 expected_btypes,
94 u32 package_index,
95 union acpi_operand_object **return_object_ptr);
96
92/* 97/*
93 * Names for the types that can be returned by the predefined objects. 98 * Names for the types that can be returned by the predefined objects.
94 * Used for warning messages. Must be in the same order as the ACPI_RTYPEs 99 * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
@@ -108,8 +113,8 @@ static const char *acpi_rtype_names[] = {
108 * FUNCTION: acpi_ns_check_predefined_names 113 * FUNCTION: acpi_ns_check_predefined_names
109 * 114 *
110 * PARAMETERS: Node - Namespace node for the method/object 115 * PARAMETERS: Node - Namespace node for the method/object
111 * return_object - Object returned from the evaluation of this 116 * return_object_ptr - Pointer to the object returned from the
112 * method/object 117 * evaluation of a method or object
113 * 118 *
114 * RETURN: Status 119 * RETURN: Status
115 * 120 *
@@ -119,8 +124,9 @@ static const char *acpi_rtype_names[] = {
119 124
120acpi_status 125acpi_status
121acpi_ns_check_predefined_names(struct acpi_namespace_node *node, 126acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
122 union acpi_operand_object *return_object) 127 union acpi_operand_object **return_object_ptr)
123{ 128{
129 union acpi_operand_object *return_object = *return_object_ptr;
124 acpi_status status = AE_OK; 130 acpi_status status = AE_OK;
125 const union acpi_predefined_info *predefined; 131 const union acpi_predefined_info *predefined;
126 char *pathname; 132 char *pathname;
@@ -182,7 +188,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
182 * Check that the type of the return object is what is expected for 188 * Check that the type of the return object is what is expected for
183 * this predefined name 189 * this predefined name
184 */ 190 */
185 status = acpi_ns_check_object_type(pathname, return_object, 191 status = acpi_ns_check_object_type(pathname, return_object_ptr,
186 predefined->info.expected_btypes, 192 predefined->info.expected_btypes,
187 ACPI_NOT_PACKAGE); 193 ACPI_NOT_PACKAGE);
188 if (ACPI_FAILURE(status)) { 194 if (ACPI_FAILURE(status)) {
@@ -193,7 +199,8 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
193 199
194 if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) { 200 if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) {
195 status = 201 status =
196 acpi_ns_check_package(pathname, return_object, predefined); 202 acpi_ns_check_package(pathname, return_object_ptr,
203 predefined);
197 } 204 }
198 205
199 exit: 206 exit:
@@ -307,8 +314,8 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct
307 * FUNCTION: acpi_ns_check_package 314 * FUNCTION: acpi_ns_check_package
308 * 315 *
309 * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 316 * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
310 * return_object - Object returned from the evaluation of a 317 * return_object_ptr - Pointer to the object returned from the
311 * method or object 318 * evaluation of a method or object
312 * Predefined - Pointer to entry in predefined name table 319 * Predefined - Pointer to entry in predefined name table
313 * 320 *
314 * RETURN: Status 321 * RETURN: Status
@@ -320,9 +327,10 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct
320 327
321static acpi_status 328static acpi_status
322acpi_ns_check_package(char *pathname, 329acpi_ns_check_package(char *pathname,
323 union acpi_operand_object *return_object, 330 union acpi_operand_object **return_object_ptr,
324 const union acpi_predefined_info *predefined) 331 const union acpi_predefined_info *predefined)
325{ 332{
333 union acpi_operand_object *return_object = *return_object_ptr;
326 const union acpi_predefined_info *package; 334 const union acpi_predefined_info *package;
327 union acpi_operand_object *sub_package; 335 union acpi_operand_object *sub_package;
328 union acpi_operand_object **elements; 336 union acpi_operand_object **elements;
@@ -408,7 +416,7 @@ acpi_ns_check_package(char *pathname,
408 * elements must be of the same type 416 * elements must be of the same type
409 */ 417 */
410 for (i = 0; i < count; i++) { 418 for (i = 0; i < count; i++) {
411 status = acpi_ns_check_object_type(pathname, *elements, 419 status = acpi_ns_check_object_type(pathname, elements,
412 package->ret_info. 420 package->ret_info.
413 object_type1, i); 421 object_type1, i);
414 if (ACPI_FAILURE(status)) { 422 if (ACPI_FAILURE(status)) {
@@ -441,7 +449,7 @@ acpi_ns_check_package(char *pathname,
441 449
442 status = 450 status =
443 acpi_ns_check_object_type(pathname, 451 acpi_ns_check_object_type(pathname,
444 *elements, 452 elements,
445 package-> 453 package->
446 ret_info3. 454 ret_info3.
447 object_type[i], 455 object_type[i],
@@ -454,7 +462,7 @@ acpi_ns_check_package(char *pathname,
454 462
455 status = 463 status =
456 acpi_ns_check_object_type(pathname, 464 acpi_ns_check_object_type(pathname,
457 *elements, 465 elements,
458 package-> 466 package->
459 ret_info3. 467 ret_info3.
460 tail_object_type, 468 tail_object_type,
@@ -471,7 +479,7 @@ acpi_ns_check_package(char *pathname,
471 479
472 /* First element is the (Integer) count of sub-packages to follow */ 480 /* First element is the (Integer) count of sub-packages to follow */
473 481
474 status = acpi_ns_check_object_type(pathname, *elements, 482 status = acpi_ns_check_object_type(pathname, elements,
475 ACPI_RTYPE_INTEGER, 0); 483 ACPI_RTYPE_INTEGER, 0);
476 if (ACPI_FAILURE(status)) { 484 if (ACPI_FAILURE(status)) {
477 return (status); 485 return (status);
@@ -509,7 +517,7 @@ acpi_ns_check_package(char *pathname,
509 /* Each sub-object must be of type Package */ 517 /* Each sub-object must be of type Package */
510 518
511 status = 519 status =
512 acpi_ns_check_object_type(pathname, sub_package, 520 acpi_ns_check_object_type(pathname, &sub_package,
513 ACPI_RTYPE_PACKAGE, i); 521 ACPI_RTYPE_PACKAGE, i);
514 if (ACPI_FAILURE(status)) { 522 if (ACPI_FAILURE(status)) {
515 return (status); 523 return (status);
@@ -567,12 +575,8 @@ acpi_ns_check_package(char *pathname,
567 for (j = 0; j < expected_count; j++) { 575 for (j = 0; j < expected_count; j++) {
568 status = 576 status =
569 acpi_ns_check_object_type(pathname, 577 acpi_ns_check_object_type(pathname,
570 sub_elements 578 &sub_elements[j],
571 [j], 579 package->ret_info2.object_type[j], j);
572 package->
573 ret_info2.
574 object_type
575 [j], j);
576 if (ACPI_FAILURE(status)) { 580 if (ACPI_FAILURE(status)) {
577 return (status); 581 return (status);
578 } 582 }
@@ -611,7 +615,7 @@ acpi_ns_check_package(char *pathname,
611 615
612 status = 616 status =
613 acpi_ns_check_object_type(pathname, 617 acpi_ns_check_object_type(pathname,
614 *sub_elements, 618 sub_elements,
615 ACPI_RTYPE_INTEGER, 619 ACPI_RTYPE_INTEGER,
616 0); 620 0);
617 if (ACPI_FAILURE(status)) { 621 if (ACPI_FAILURE(status)) {
@@ -708,7 +712,7 @@ acpi_ns_check_package_elements(char *pathname,
708 * The second group can have a count of zero. 712 * The second group can have a count of zero.
709 */ 713 */
710 for (i = 0; i < count1; i++) { 714 for (i = 0; i < count1; i++) {
711 status = acpi_ns_check_object_type(pathname, *this_element, 715 status = acpi_ns_check_object_type(pathname, this_element,
712 type1, i); 716 type1, i);
713 if (ACPI_FAILURE(status)) { 717 if (ACPI_FAILURE(status)) {
714 return (status); 718 return (status);
@@ -717,7 +721,7 @@ acpi_ns_check_package_elements(char *pathname,
717 } 721 }
718 722
719 for (i = 0; i < count2; i++) { 723 for (i = 0; i < count2; i++) {
720 status = acpi_ns_check_object_type(pathname, *this_element, 724 status = acpi_ns_check_object_type(pathname, this_element,
721 type2, (i + count1)); 725 type2, (i + count1));
722 if (ACPI_FAILURE(status)) { 726 if (ACPI_FAILURE(status)) {
723 return (status); 727 return (status);
@@ -733,8 +737,8 @@ acpi_ns_check_package_elements(char *pathname,
733 * FUNCTION: acpi_ns_check_object_type 737 * FUNCTION: acpi_ns_check_object_type
734 * 738 *
735 * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 739 * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
736 * return_object - Object return from the execution of this 740 * return_object_ptr - Pointer to the object returned from the
737 * method/object 741 * evaluation of a method or object
738 * expected_btypes - Bitmap of expected return type(s) 742 * expected_btypes - Bitmap of expected return type(s)
739 * package_index - Index of object within parent package (if 743 * package_index - Index of object within parent package (if
740 * applicable - ACPI_NOT_PACKAGE otherwise) 744 * applicable - ACPI_NOT_PACKAGE otherwise)
@@ -748,9 +752,10 @@ acpi_ns_check_package_elements(char *pathname,
748 752
749static acpi_status 753static acpi_status
750acpi_ns_check_object_type(char *pathname, 754acpi_ns_check_object_type(char *pathname,
751 union acpi_operand_object *return_object, 755 union acpi_operand_object **return_object_ptr,
752 u32 expected_btypes, u32 package_index) 756 u32 expected_btypes, u32 package_index)
753{ 757{
758 union acpi_operand_object *return_object = *return_object_ptr;
754 acpi_status status = AE_OK; 759 acpi_status status = AE_OK;
755 u32 return_btype; 760 u32 return_btype;
756 char type_buffer[48]; /* Room for 5 types */ 761 char type_buffer[48]; /* Room for 5 types */
@@ -814,6 +819,14 @@ acpi_ns_check_object_type(char *pathname,
814 /* Is the object one of the expected types? */ 819 /* Is the object one of the expected types? */
815 820
816 if (!(return_btype & expected_btypes)) { 821 if (!(return_btype & expected_btypes)) {
822
823 /* Type mismatch -- attempt repair of the returned object */
824
825 status = acpi_ns_repair_object(expected_btypes, package_index,
826 return_object_ptr);
827 if (ACPI_SUCCESS(status)) {
828 return (status);
829 }
817 goto type_error_exit; 830 goto type_error_exit;
818 } 831 }
819 832
@@ -898,3 +911,86 @@ acpi_ns_check_reference(char *pathname,
898 911
899 return (AE_AML_OPERAND_TYPE); 912 return (AE_AML_OPERAND_TYPE);
900} 913}
914
915/*******************************************************************************
916 *
917 * FUNCTION: acpi_ns_repair_object
918 *
919 * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
920 * package_index - Used to determine if target is in a package
921 * return_object_ptr - Pointer to the object returned from the
922 * evaluation of a method or object
923 *
924 * RETURN: Status. AE_OK if repair was successful.
925 *
926 * DESCRIPTION: Attempt to repair/convert a return object of a type that was
927 * not expected.
928 *
929 ******************************************************************************/
930
931static acpi_status
932acpi_ns_repair_object(u32 expected_btypes,
933 u32 package_index,
934 union acpi_operand_object **return_object_ptr)
935{
936 union acpi_operand_object *return_object = *return_object_ptr;
937 union acpi_operand_object *new_object;
938 acpi_size length;
939
940 switch (ACPI_GET_OBJECT_TYPE(return_object)) {
941 case ACPI_TYPE_BUFFER:
942
943 if (!(expected_btypes & ACPI_RTYPE_STRING)) {
944 return (AE_AML_OPERAND_TYPE);
945 }
946
947 /*
948 * Have a Buffer, expected a String, convert. Use a to_string
949 * conversion, no transform performed on the buffer data. The best
950 * example of this is the _BIF method, where the string data from
951 * the battery is often (incorrectly) returned as buffer object(s).
952 */
953 length = 0;
954 while ((length < return_object->buffer.length) &&
955 (return_object->buffer.pointer[length])) {
956 length++;
957 }
958
959 /* Allocate a new string object */
960
961 new_object = acpi_ut_create_string_object(length);
962 if (!new_object) {
963 return (AE_NO_MEMORY);
964 }
965
966 /*
967 * Copy the raw buffer data with no transform. String is already NULL
968 * terminated at Length+1.
969 */
970 ACPI_MEMCPY(new_object->string.pointer,
971 return_object->buffer.pointer, length);
972
973 /* Install the new return object */
974
975 acpi_ut_remove_reference(return_object);
976 *return_object_ptr = new_object;
977
978 /*
979 * If the object is a package element, we need to:
980 * 1. Decrement the reference count of the orignal object, it was
981 * incremented when building the package
982 * 2. Increment the reference count of the new object, it will be
983 * decremented when releasing the package
984 */
985 if (package_index != ACPI_NOT_PACKAGE) {
986 acpi_ut_remove_reference(return_object);
987 acpi_ut_add_reference(new_object);
988 }
989 return (AE_OK);
990
991 default:
992 break;
993 }
994
995 return (AE_AML_OPERAND_TYPE);
996}