|
@@ -72,7 +72,7 @@ ACPI_MODULE_NAME("nspredef")
|
|
|
/* Local prototypes */
|
|
|
static acpi_status
|
|
|
acpi_ns_check_package(char *pathname,
|
|
|
- union acpi_operand_object *return_object,
|
|
|
+ union acpi_operand_object **return_object_ptr,
|
|
|
const union acpi_predefined_info *predefined);
|
|
|
|
|
|
static acpi_status
|
|
@@ -82,13 +82,18 @@ acpi_ns_check_package_elements(char *pathname,
|
|
|
|
|
|
static acpi_status
|
|
|
acpi_ns_check_object_type(char *pathname,
|
|
|
- union acpi_operand_object *return_object,
|
|
|
+ union acpi_operand_object **return_object_ptr,
|
|
|
u32 expected_btypes, u32 package_index);
|
|
|
|
|
|
static acpi_status
|
|
|
acpi_ns_check_reference(char *pathname,
|
|
|
union acpi_operand_object *return_object);
|
|
|
|
|
|
+static acpi_status
|
|
|
+acpi_ns_repair_object(u32 expected_btypes,
|
|
|
+ u32 package_index,
|
|
|
+ union acpi_operand_object **return_object_ptr);
|
|
|
+
|
|
|
/*
|
|
|
* Names for the types that can be returned by the predefined objects.
|
|
|
* Used for warning messages. Must be in the same order as the ACPI_RTYPEs
|
|
@@ -108,8 +113,8 @@ static const char *acpi_rtype_names[] = {
|
|
|
* FUNCTION: acpi_ns_check_predefined_names
|
|
|
*
|
|
|
* PARAMETERS: Node - Namespace node for the method/object
|
|
|
- * return_object - Object returned from the evaluation of this
|
|
|
- * method/object
|
|
|
+ * return_object_ptr - Pointer to the object returned from the
|
|
|
+ * evaluation of a method or object
|
|
|
*
|
|
|
* RETURN: Status
|
|
|
*
|
|
@@ -119,8 +124,9 @@ static const char *acpi_rtype_names[] = {
|
|
|
|
|
|
acpi_status
|
|
|
acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
|
|
|
- union acpi_operand_object *return_object)
|
|
|
+ union acpi_operand_object **return_object_ptr)
|
|
|
{
|
|
|
+ union acpi_operand_object *return_object = *return_object_ptr;
|
|
|
acpi_status status = AE_OK;
|
|
|
const union acpi_predefined_info *predefined;
|
|
|
char *pathname;
|
|
@@ -182,7 +188,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
|
|
|
* Check that the type of the return object is what is expected for
|
|
|
* this predefined name
|
|
|
*/
|
|
|
- status = acpi_ns_check_object_type(pathname, return_object,
|
|
|
+ status = acpi_ns_check_object_type(pathname, return_object_ptr,
|
|
|
predefined->info.expected_btypes,
|
|
|
ACPI_NOT_PACKAGE);
|
|
|
if (ACPI_FAILURE(status)) {
|
|
@@ -193,7 +199,8 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
|
|
|
|
|
|
if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) {
|
|
|
status =
|
|
|
- acpi_ns_check_package(pathname, return_object, predefined);
|
|
|
+ acpi_ns_check_package(pathname, return_object_ptr,
|
|
|
+ predefined);
|
|
|
}
|
|
|
|
|
|
exit:
|
|
@@ -307,8 +314,8 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct
|
|
|
* FUNCTION: acpi_ns_check_package
|
|
|
*
|
|
|
* PARAMETERS: Pathname - Full pathname to the node (for error msgs)
|
|
|
- * return_object - Object returned from the evaluation of a
|
|
|
- * method or object
|
|
|
+ * return_object_ptr - Pointer to the object returned from the
|
|
|
+ * evaluation of a method or object
|
|
|
* Predefined - Pointer to entry in predefined name table
|
|
|
*
|
|
|
* RETURN: Status
|
|
@@ -320,9 +327,10 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct
|
|
|
|
|
|
static acpi_status
|
|
|
acpi_ns_check_package(char *pathname,
|
|
|
- union acpi_operand_object *return_object,
|
|
|
+ union acpi_operand_object **return_object_ptr,
|
|
|
const union acpi_predefined_info *predefined)
|
|
|
{
|
|
|
+ union acpi_operand_object *return_object = *return_object_ptr;
|
|
|
const union acpi_predefined_info *package;
|
|
|
union acpi_operand_object *sub_package;
|
|
|
union acpi_operand_object **elements;
|
|
@@ -408,7 +416,7 @@ acpi_ns_check_package(char *pathname,
|
|
|
* elements must be of the same type
|
|
|
*/
|
|
|
for (i = 0; i < count; i++) {
|
|
|
- status = acpi_ns_check_object_type(pathname, *elements,
|
|
|
+ status = acpi_ns_check_object_type(pathname, elements,
|
|
|
package->ret_info.
|
|
|
object_type1, i);
|
|
|
if (ACPI_FAILURE(status)) {
|
|
@@ -441,7 +449,7 @@ acpi_ns_check_package(char *pathname,
|
|
|
|
|
|
status =
|
|
|
acpi_ns_check_object_type(pathname,
|
|
|
- *elements,
|
|
|
+ elements,
|
|
|
package->
|
|
|
ret_info3.
|
|
|
object_type[i],
|
|
@@ -454,7 +462,7 @@ acpi_ns_check_package(char *pathname,
|
|
|
|
|
|
status =
|
|
|
acpi_ns_check_object_type(pathname,
|
|
|
- *elements,
|
|
|
+ elements,
|
|
|
package->
|
|
|
ret_info3.
|
|
|
tail_object_type,
|
|
@@ -471,7 +479,7 @@ acpi_ns_check_package(char *pathname,
|
|
|
|
|
|
/* First element is the (Integer) count of sub-packages to follow */
|
|
|
|
|
|
- status = acpi_ns_check_object_type(pathname, *elements,
|
|
|
+ status = acpi_ns_check_object_type(pathname, elements,
|
|
|
ACPI_RTYPE_INTEGER, 0);
|
|
|
if (ACPI_FAILURE(status)) {
|
|
|
return (status);
|
|
@@ -509,7 +517,7 @@ acpi_ns_check_package(char *pathname,
|
|
|
/* Each sub-object must be of type Package */
|
|
|
|
|
|
status =
|
|
|
- acpi_ns_check_object_type(pathname, sub_package,
|
|
|
+ acpi_ns_check_object_type(pathname, &sub_package,
|
|
|
ACPI_RTYPE_PACKAGE, i);
|
|
|
if (ACPI_FAILURE(status)) {
|
|
|
return (status);
|
|
@@ -567,12 +575,8 @@ acpi_ns_check_package(char *pathname,
|
|
|
for (j = 0; j < expected_count; j++) {
|
|
|
status =
|
|
|
acpi_ns_check_object_type(pathname,
|
|
|
- sub_elements
|
|
|
- [j],
|
|
|
- package->
|
|
|
- ret_info2.
|
|
|
- object_type
|
|
|
- [j], j);
|
|
|
+ &sub_elements[j],
|
|
|
+ package->ret_info2.object_type[j], j);
|
|
|
if (ACPI_FAILURE(status)) {
|
|
|
return (status);
|
|
|
}
|
|
@@ -611,7 +615,7 @@ acpi_ns_check_package(char *pathname,
|
|
|
|
|
|
status =
|
|
|
acpi_ns_check_object_type(pathname,
|
|
|
- *sub_elements,
|
|
|
+ sub_elements,
|
|
|
ACPI_RTYPE_INTEGER,
|
|
|
0);
|
|
|
if (ACPI_FAILURE(status)) {
|
|
@@ -708,7 +712,7 @@ acpi_ns_check_package_elements(char *pathname,
|
|
|
* The second group can have a count of zero.
|
|
|
*/
|
|
|
for (i = 0; i < count1; i++) {
|
|
|
- status = acpi_ns_check_object_type(pathname, *this_element,
|
|
|
+ status = acpi_ns_check_object_type(pathname, this_element,
|
|
|
type1, i);
|
|
|
if (ACPI_FAILURE(status)) {
|
|
|
return (status);
|
|
@@ -717,7 +721,7 @@ acpi_ns_check_package_elements(char *pathname,
|
|
|
}
|
|
|
|
|
|
for (i = 0; i < count2; i++) {
|
|
|
- status = acpi_ns_check_object_type(pathname, *this_element,
|
|
|
+ status = acpi_ns_check_object_type(pathname, this_element,
|
|
|
type2, (i + count1));
|
|
|
if (ACPI_FAILURE(status)) {
|
|
|
return (status);
|
|
@@ -733,8 +737,8 @@ acpi_ns_check_package_elements(char *pathname,
|
|
|
* FUNCTION: acpi_ns_check_object_type
|
|
|
*
|
|
|
* PARAMETERS: Pathname - Full pathname to the node (for error msgs)
|
|
|
- * return_object - Object return from the execution of this
|
|
|
- * method/object
|
|
|
+ * return_object_ptr - Pointer to the object returned from the
|
|
|
+ * evaluation of a method or object
|
|
|
* expected_btypes - Bitmap of expected return type(s)
|
|
|
* package_index - Index of object within parent package (if
|
|
|
* applicable - ACPI_NOT_PACKAGE otherwise)
|
|
@@ -748,9 +752,10 @@ acpi_ns_check_package_elements(char *pathname,
|
|
|
|
|
|
static acpi_status
|
|
|
acpi_ns_check_object_type(char *pathname,
|
|
|
- union acpi_operand_object *return_object,
|
|
|
+ union acpi_operand_object **return_object_ptr,
|
|
|
u32 expected_btypes, u32 package_index)
|
|
|
{
|
|
|
+ union acpi_operand_object *return_object = *return_object_ptr;
|
|
|
acpi_status status = AE_OK;
|
|
|
u32 return_btype;
|
|
|
char type_buffer[48]; /* Room for 5 types */
|
|
@@ -814,6 +819,14 @@ acpi_ns_check_object_type(char *pathname,
|
|
|
/* Is the object one of the expected types? */
|
|
|
|
|
|
if (!(return_btype & expected_btypes)) {
|
|
|
+
|
|
|
+ /* Type mismatch -- attempt repair of the returned object */
|
|
|
+
|
|
|
+ status = acpi_ns_repair_object(expected_btypes, package_index,
|
|
|
+ return_object_ptr);
|
|
|
+ if (ACPI_SUCCESS(status)) {
|
|
|
+ return (status);
|
|
|
+ }
|
|
|
goto type_error_exit;
|
|
|
}
|
|
|
|
|
@@ -898,3 +911,86 @@ acpi_ns_check_reference(char *pathname,
|
|
|
|
|
|
return (AE_AML_OPERAND_TYPE);
|
|
|
}
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+ *
|
|
|
+ * FUNCTION: acpi_ns_repair_object
|
|
|
+ *
|
|
|
+ * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
|
|
|
+ * package_index - Used to determine if target is in a package
|
|
|
+ * return_object_ptr - Pointer to the object returned from the
|
|
|
+ * evaluation of a method or object
|
|
|
+ *
|
|
|
+ * RETURN: Status. AE_OK if repair was successful.
|
|
|
+ *
|
|
|
+ * DESCRIPTION: Attempt to repair/convert a return object of a type that was
|
|
|
+ * not expected.
|
|
|
+ *
|
|
|
+ ******************************************************************************/
|
|
|
+
|
|
|
+static acpi_status
|
|
|
+acpi_ns_repair_object(u32 expected_btypes,
|
|
|
+ u32 package_index,
|
|
|
+ union acpi_operand_object **return_object_ptr)
|
|
|
+{
|
|
|
+ union acpi_operand_object *return_object = *return_object_ptr;
|
|
|
+ union acpi_operand_object *new_object;
|
|
|
+ acpi_size length;
|
|
|
+
|
|
|
+ switch (ACPI_GET_OBJECT_TYPE(return_object)) {
|
|
|
+ case ACPI_TYPE_BUFFER:
|
|
|
+
|
|
|
+ if (!(expected_btypes & ACPI_RTYPE_STRING)) {
|
|
|
+ return (AE_AML_OPERAND_TYPE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Have a Buffer, expected a String, convert. Use a to_string
|
|
|
+ * conversion, no transform performed on the buffer data. The best
|
|
|
+ * example of this is the _BIF method, where the string data from
|
|
|
+ * the battery is often (incorrectly) returned as buffer object(s).
|
|
|
+ */
|
|
|
+ length = 0;
|
|
|
+ while ((length < return_object->buffer.length) &&
|
|
|
+ (return_object->buffer.pointer[length])) {
|
|
|
+ length++;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Allocate a new string object */
|
|
|
+
|
|
|
+ new_object = acpi_ut_create_string_object(length);
|
|
|
+ if (!new_object) {
|
|
|
+ return (AE_NO_MEMORY);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Copy the raw buffer data with no transform. String is already NULL
|
|
|
+ * terminated at Length+1.
|
|
|
+ */
|
|
|
+ ACPI_MEMCPY(new_object->string.pointer,
|
|
|
+ return_object->buffer.pointer, length);
|
|
|
+
|
|
|
+ /* Install the new return object */
|
|
|
+
|
|
|
+ acpi_ut_remove_reference(return_object);
|
|
|
+ *return_object_ptr = new_object;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If the object is a package element, we need to:
|
|
|
+ * 1. Decrement the reference count of the orignal object, it was
|
|
|
+ * incremented when building the package
|
|
|
+ * 2. Increment the reference count of the new object, it will be
|
|
|
+ * decremented when releasing the package
|
|
|
+ */
|
|
|
+ if (package_index != ACPI_NOT_PACKAGE) {
|
|
|
+ acpi_ut_remove_reference(return_object);
|
|
|
+ acpi_ut_add_reference(new_object);
|
|
|
+ }
|
|
|
+ return (AE_OK);
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (AE_AML_OPERAND_TYPE);
|
|
|
+}
|