Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 128033
b: refs/heads/master
c: a647b5c
h: refs/heads/master
i:
  128031: 17f11d8
v: v3
  • Loading branch information
Bob Moore authored and Len Brown committed Dec 30, 2008
1 parent 4d2388d commit 5311779
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 31 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d037c5fd7367548191eab2b376a1d08c4ffaf7ff
refs/heads/master: a647b5c34047560d7efe7e53e756c6692ce67dc7
3 changes: 1 addition & 2 deletions trunk/drivers/acpi/namespace/nseval.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
* the method on invalid return object.
*/
(void)acpi_ns_check_predefined_names(node,
info->
return_object);
&info->return_object);
}

/* Mark the node as having been evaluated */
Expand Down
150 changes: 123 additions & 27 deletions trunk/drivers/acpi/namespace/nspredef.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
*
Expand All @@ -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;
Expand Down Expand Up @@ -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)) {
Expand All @@ -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:
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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],
Expand All @@ -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,
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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)
Expand All @@ -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 */
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
}
2 changes: 1 addition & 1 deletion trunk/include/acpi/acnamesp.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info);
*/
acpi_status
acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
union acpi_operand_object *return_object);
union acpi_operand_object **return_object);

const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct
acpi_namespace_node
Expand Down

0 comments on commit 5311779

Please sign in to comment.