diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:52:52 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:52:52 -0700 |
commit | 08acd4f8af42affd8cbed81cc1b69fa12ddb213f (patch) | |
tree | 988d15db6233b20db6a500cd5f590c6d2041462d /drivers/acpi/dispatcher/dsobject.c | |
parent | ccf2779544eecfcc5447e2028d1029b6d4ff7bb6 (diff) | |
parent | 008238b54ac2350babf195084ecedbcf7851a202 (diff) | |
download | linux-08acd4f8af42affd8cbed81cc1b69fa12ddb213f.tar.gz linux-08acd4f8af42affd8cbed81cc1b69fa12ddb213f.tar.bz2 linux-08acd4f8af42affd8cbed81cc1b69fa12ddb213f.zip |
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (179 commits)
ACPI: Fix acpi_processor_idle and idle= boot parameters interaction
acpi: fix section mismatch warning in pnpacpi
intel_menlo: fix build warning
ACPI: Cleanup: Remove unneeded, multiple local dummy variables
ACPI: video - fix permissions on some proc entries
ACPI: video - properly handle errors when registering proc elements
ACPI: video - do not store invalid entries in attached_array list
ACPI: re-name acpi_pm_ops to acpi_suspend_ops
ACER_WMI/ASUS_LAPTOP: fix build bug
thinkpad_acpi: fix possible NULL pointer dereference if kstrdup failed
ACPI: check a return value correctly in acpi_power_get_context()
#if 0 acpi/bay.c:eject_removable_drive()
eeepc-laptop: add hwmon fan control
eeepc-laptop: add backlight
eeepc-laptop: add base driver
ACPI: thinkpad-acpi: bump up version to 0.20
ACPI: thinkpad-acpi: fix selects in Kconfig
ACPI: thinkpad-acpi: use a private workqueue
ACPI: thinkpad-acpi: fluff really minor fix
ACPI: thinkpad-acpi: use uppercase for "LED" on user documentation
...
Fixed conflicts in drivers/acpi/video.c and drivers/misc/intel_menlow.c
manually.
Diffstat (limited to 'drivers/acpi/dispatcher/dsobject.c')
-rw-r--r-- | drivers/acpi/dispatcher/dsobject.c | 101 |
1 files changed, 78 insertions, 23 deletions
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index 954ac8ce958a..1022e38994c2 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2008, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -157,7 +157,9 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, * will remain as named references. This behavior is not described * in the ACPI spec, but it appears to be an oversight. */ - obj_desc = (union acpi_operand_object *)op->common.node; + obj_desc = + ACPI_CAST_PTR(union acpi_operand_object, + op->common.node); status = acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR @@ -172,7 +174,19 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, switch (op->common.node->type) { /* * For these types, we need the actual node, not the subobject. - * However, the subobject got an extra reference count above. + * However, the subobject did not get an extra reference count above. + * + * TBD: should ex_resolve_node_to_value be changed to fix this? + */ + case ACPI_TYPE_DEVICE: + case ACPI_TYPE_THERMAL: + + acpi_ut_add_reference(op->common.node->object); + + /*lint -fallthrough */ + /* + * For these types, we need the actual node, not the subobject. + * The subobject got an extra reference count in ex_resolve_node_to_value. */ case ACPI_TYPE_MUTEX: case ACPI_TYPE_METHOD: @@ -180,25 +194,15 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_EVENT: case ACPI_TYPE_REGION: - case ACPI_TYPE_DEVICE: - case ACPI_TYPE_THERMAL: - obj_desc = - (union acpi_operand_object *)op->common. - node; + /* We will create a reference object for these types below */ break; default: - break; - } - - /* - * If above resolved to an operand object, we are done. Otherwise, - * we have a NS node, we must create the package entry as a named - * reference. - */ - if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != - ACPI_DESC_TYPE_NAMED) { + /* + * All other types - the node was resolved to an actual + * object, we are done. + */ goto exit; } } @@ -223,7 +227,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, exit: *obj_desc_ptr = obj_desc; - return_ACPI_STATUS(AE_OK); + return_ACPI_STATUS(status); } /******************************************************************************* @@ -369,7 +373,9 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, union acpi_parse_object *parent; union acpi_operand_object *obj_desc = NULL; acpi_status status = AE_OK; - acpi_native_uint i; + unsigned i; + u16 index; + u16 reference_count; ACPI_FUNCTION_TRACE(ds_build_internal_package_obj); @@ -447,13 +453,60 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, package. elements[i]); } + + if (*obj_desc_ptr) { + + /* Existing package, get existing reference count */ + + reference_count = + (*obj_desc_ptr)->common.reference_count; + if (reference_count > 1) { + + /* Make new element ref count match original ref count */ + + for (index = 0; index < (reference_count - 1); + index++) { + acpi_ut_add_reference((obj_desc-> + package. + elements[i])); + } + } + } + arg = arg->common.next; } - if (!arg) { + /* Check for match between num_elements and actual length of package_list */ + + if (arg) { + /* + * num_elements was exhausted, but there are remaining elements in the + * package_list. + * + * Note: technically, this is an error, from ACPI spec: "It is an error + * for NumElements to be less than the number of elements in the + * PackageList". However, for now, we just print an error message and + * no exception is returned. + */ + while (arg) { + + /* Find out how many elements there really are */ + + i++; + arg = arg->common.next; + } + + ACPI_ERROR((AE_INFO, + "Package List length (%X) larger than NumElements count (%X), truncated\n", + i, element_count)); + } else if (i < element_count) { + /* + * Arg list (elements) was exhausted, but we did not reach num_elements count. + * Note: this is not an error, the package is padded out with NULLs. + */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Package List length larger than NumElements count (%X), truncated\n", - element_count)); + "Package List length (%X) smaller than NumElements count (%X), padded with null elements\n", + i, element_count)); } obj_desc->package.flags |= AOPOBJ_DATA_VALID; @@ -721,6 +774,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, /* Node was saved in Op */ obj_desc->reference.node = op->common.node; + obj_desc->reference.object = + op->common.node->object; } obj_desc->reference.opcode = opcode; |