aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2012-05-22 04:22:01 -0400
committerLen Brown <len.brown@intel.com>2012-06-01 11:51:51 -0400
commit6ccd7b5acc418e02953a8dd8a3c17e04907aacff (patch)
treece2c0285bc1aa9296a6575c16e8d07f928188509 /drivers/acpi/acpica
parent9fd7522570449bd10f6a6377cf5cb542ef527dd5 (diff)
ACPICA: Disassembler: Add support for Operation Region externals
Adds missing support for operation regions defined in another table, but referenced via a Field or BankField operator. Generate the correct External statement. 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')
-rw-r--r--drivers/acpi/acpica/dsfield.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c
index cd243cf2cab2..809843923d64 100644
--- a/drivers/acpi/acpica/dsfield.c
+++ b/drivers/acpi/acpica/dsfield.c
@@ -53,11 +53,79 @@
53ACPI_MODULE_NAME("dsfield") 53ACPI_MODULE_NAME("dsfield")
54 54
55/* Local prototypes */ 55/* Local prototypes */
56#ifdef ACPI_ASL_COMPILER
57#include "acdisasm.h"
58static acpi_status
59acpi_ds_create_external_region(acpi_status lookup_status,
60 union acpi_parse_object *op,
61 char *path,
62 struct acpi_walk_state *walk_state,
63 struct acpi_namespace_node **node);
64#endif
65
56static acpi_status 66static acpi_status
57acpi_ds_get_field_names(struct acpi_create_field_info *info, 67acpi_ds_get_field_names(struct acpi_create_field_info *info,
58 struct acpi_walk_state *walk_state, 68 struct acpi_walk_state *walk_state,
59 union acpi_parse_object *arg); 69 union acpi_parse_object *arg);
60 70
71#ifdef ACPI_ASL_COMPILER
72/*******************************************************************************
73 *
74 * FUNCTION: acpi_ds_create_external_region (i_aSL Disassembler only)
75 *
76 * PARAMETERS: lookup_status - Status from ns_lookup operation
77 * Op - Op containing the Field definition and args
78 * Path - Pathname of the region
79 * ` walk_state - Current method state
80 * Node - Where the new region node is returned
81 *
82 * RETURN: Status
83 *
84 * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
85 * region node/object.
86 *
87 ******************************************************************************/
88
89static acpi_status
90acpi_ds_create_external_region(acpi_status lookup_status,
91 union acpi_parse_object *op,
92 char *path,
93 struct acpi_walk_state *walk_state,
94 struct acpi_namespace_node **node)
95{
96 acpi_status status;
97 union acpi_operand_object *obj_desc;
98
99 if (lookup_status != AE_NOT_FOUND) {
100 return (lookup_status);
101 }
102
103 /*
104 * Table disassembly:
105 * operation_region not found. Generate an External for it, and
106 * insert the name into the namespace.
107 */
108 acpi_dm_add_to_external_list(op, path, ACPI_TYPE_REGION, 0);
109 status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION,
110 ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
111 walk_state, node);
112 if (ACPI_FAILURE(status)) {
113 return (status);
114 }
115
116 /* Must create and install a region object for the new node */
117
118 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
119 if (!obj_desc) {
120 return (AE_NO_MEMORY);
121 }
122
123 obj_desc->region.node = *node;
124 status = acpi_ns_attach_object(*node, obj_desc, ACPI_TYPE_REGION);
125 return (status);
126}
127#endif
128
61/******************************************************************************* 129/*******************************************************************************
62 * 130 *
63 * FUNCTION: acpi_ds_create_buffer_field 131 * FUNCTION: acpi_ds_create_buffer_field
@@ -413,12 +481,19 @@ acpi_ds_create_field(union acpi_parse_object *op,
413 /* First arg is the name of the parent op_region (must already exist) */ 481 /* First arg is the name of the parent op_region (must already exist) */
414 482
415 arg = op->common.value.arg; 483 arg = op->common.value.arg;
484
416 if (!region_node) { 485 if (!region_node) {
417 status = 486 status =
418 acpi_ns_lookup(walk_state->scope_info, 487 acpi_ns_lookup(walk_state->scope_info,
419 arg->common.value.name, ACPI_TYPE_REGION, 488 arg->common.value.name, ACPI_TYPE_REGION,
420 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 489 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
421 walk_state, &region_node); 490 walk_state, &region_node);
491#ifdef ACPI_ASL_COMPILER
492 status = acpi_ds_create_external_region(status, arg,
493 arg->common.value.name,
494 walk_state,
495 &region_node);
496#endif
422 if (ACPI_FAILURE(status)) { 497 if (ACPI_FAILURE(status)) {
423 ACPI_ERROR_NAMESPACE(arg->common.value.name, status); 498 ACPI_ERROR_NAMESPACE(arg->common.value.name, status);
424 return_ACPI_STATUS(status); 499 return_ACPI_STATUS(status);
@@ -591,6 +666,12 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,
591 arg->common.value.name, ACPI_TYPE_REGION, 666 arg->common.value.name, ACPI_TYPE_REGION,
592 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 667 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
593 walk_state, &region_node); 668 walk_state, &region_node);
669#ifdef ACPI_ASL_COMPILER
670 status = acpi_ds_create_external_region(status, arg,
671 arg->common.value.name,
672 walk_state,
673 &region_node);
674#endif
594 if (ACPI_FAILURE(status)) { 675 if (ACPI_FAILURE(status)) {
595 ACPI_ERROR_NAMESPACE(arg->common.value.name, status); 676 ACPI_ERROR_NAMESPACE(arg->common.value.name, status);
596 return_ACPI_STATUS(status); 677 return_ACPI_STATUS(status);