blob: 4ebd23700bbcb17d897056680fa6eef2fa30ed46 [file] [log] [blame]
Erik Schmauss95857632018-03-14 16:13:07 -07001// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/******************************************************************************
3 *
4 * Module Name: dsinit - Object initialization namespace walk
5 *
Bob Moore840c02c2019-01-14 09:55:25 -08006 * Copyright (C) 2000 - 2019, Intel Corp.
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 *
Erik Schmauss95857632018-03-14 16:13:07 -07008 *****************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07009
Linus Torvalds1da177e2005-04-16 15:20:36 -070010#include <acpi/acpi.h>
Len Browne2f7a772009-01-09 00:30:03 -050011#include "accommon.h"
12#include "acdispat.h"
13#include "acnamesp.h"
14#include "actables.h"
Lv Zheng8633db62016-10-26 15:42:01 +080015#include "acinterp.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070016
17#define _COMPONENT ACPI_DISPATCHER
Len Brown4be44fc2005-08-05 00:44:28 -040018ACPI_MODULE_NAME("dsinit")
Linus Torvalds1da177e2005-04-16 15:20:36 -070019
Robert Moore44f6c012005-04-18 22:49:35 -040020/* Local prototypes */
Robert Moore44f6c012005-04-18 22:49:35 -040021static acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -040022acpi_ds_init_one_object(acpi_handle obj_handle,
23 u32 level, void *context, void **return_value);
Linus Torvalds1da177e2005-04-16 15:20:36 -070024
25/*******************************************************************************
26 *
27 * FUNCTION: acpi_ds_init_one_object
28 *
Robert Moore44f6c012005-04-18 22:49:35 -040029 * PARAMETERS: obj_handle - Node for the object
Bob Mooreba494be2012-07-12 09:40:10 +080030 * level - Current nesting level
31 * context - Points to a init info struct
Linus Torvalds1da177e2005-04-16 15:20:36 -070032 * return_value - Not used
33 *
34 * RETURN: Status
35 *
36 * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object
37 * within the namespace.
38 *
39 * Currently, the only objects that require initialization are:
40 * 1) Methods
41 * 2) Operation Regions
42 *
43 ******************************************************************************/
44
Robert Moore44f6c012005-04-18 22:49:35 -040045static acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -040046acpi_ds_init_one_object(acpi_handle obj_handle,
47 u32 level, void *context, void **return_value)
Linus Torvalds1da177e2005-04-16 15:20:36 -070048{
Len Brown4be44fc2005-08-05 00:44:28 -040049 struct acpi_init_walk_info *info =
50 (struct acpi_init_walk_info *)context;
51 struct acpi_namespace_node *node =
52 (struct acpi_namespace_node *)obj_handle;
Len Brown4be44fc2005-08-05 00:44:28 -040053 acpi_status status;
Bob Moore22b5afc2014-03-24 14:49:00 +080054 union acpi_operand_object *obj_desc;
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Bob Moore4a90c7e2006-01-13 16:22:00 -050056 ACPI_FUNCTION_ENTRY();
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
58 /*
Robert Moore0c9938c2005-07-29 15:15:00 -070059 * We are only interested in NS nodes owned by the table that
Linus Torvalds1da177e2005-04-16 15:20:36 -070060 * was just loaded
61 */
Bob Mooref3d2e782007-02-02 19:48:18 +030062 if (node->owner_id != info->owner_id) {
Linus Torvalds1da177e2005-04-16 15:20:36 -070063 return (AE_OK);
64 }
65
66 info->object_count++;
67
68 /* And even then, we are only interested in a few object types */
69
Bob Moore22b5afc2014-03-24 14:49:00 +080070 switch (acpi_ns_get_type(obj_handle)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -070071 case ACPI_TYPE_REGION:
72
Len Brown4be44fc2005-08-05 00:44:28 -040073 status = acpi_ds_initialize_region(obj_handle);
74 if (ACPI_FAILURE(status)) {
Bob Mooreb8e4d892006-01-27 16:43:00 -050075 ACPI_EXCEPTION((AE_INFO, status,
76 "During Region initialization %p [%4.4s]",
77 obj_handle,
78 acpi_ut_get_node_name(obj_handle)));
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 }
80
81 info->op_region_count++;
82 break;
83
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 case ACPI_TYPE_METHOD:
Bob Moore22b5afc2014-03-24 14:49:00 +080085 /*
86 * Auto-serialization support. We will examine each method that is
87 * not_serialized to determine if it creates any Named objects. If
88 * it does, it will be marked serialized to prevent problems if
89 * the method is entered by two or more threads and an attempt is
90 * made to create the same named object twice -- which results in
91 * an AE_ALREADY_EXISTS exception and method abort.
92 */
Robert Moore0c9938c2005-07-29 15:15:00 -070093 info->method_count++;
Bob Moore22b5afc2014-03-24 14:49:00 +080094 obj_desc = acpi_ns_get_attached_object(node);
95 if (!obj_desc) {
96 break;
97 }
98
99 /* Ignore if already serialized */
100
101 if (obj_desc->method.info_flags & ACPI_METHOD_SERIALIZED) {
102 info->serial_method_count++;
103 break;
104 }
105
106 if (acpi_gbl_auto_serialize_methods) {
107
108 /* Parse/scan method and serialize it if necessary */
109
110 acpi_ds_auto_serialize_method(node, obj_desc);
111 if (obj_desc->method.
112 info_flags & ACPI_METHOD_SERIALIZED) {
113
114 /* Method was just converted to Serialized */
115
116 info->serial_method_count++;
117 info->serialized_method_count++;
118 break;
119 }
120 }
121
122 info->non_serial_method_count++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123 break;
124
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 case ACPI_TYPE_DEVICE:
126
127 info->device_count++;
128 break;
129
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 default:
Chao Guan1d1ea1b72013-06-08 00:58:14 +0000131
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 break;
133 }
134
135 /*
136 * We ignore errors from above, and always return OK, since
137 * we don't want to abort the walk on a single error.
138 */
139 return (AE_OK);
140}
141
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142/*******************************************************************************
143 *
144 * FUNCTION: acpi_ds_initialize_objects
145 *
146 * PARAMETERS: table_desc - Descriptor for parent ACPI table
147 * start_node - Root of subtree to be initialized.
148 *
149 * RETURN: Status
150 *
Bob Mooreb229cf92006-04-21 17:15:00 -0400151 * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 * necessary initialization on the objects found therein
153 *
154 ******************************************************************************/
155
156acpi_status
Bob Moore67a119f2008-06-10 13:42:13 +0800157acpi_ds_initialize_objects(u32 table_index,
Lv Zhengf5c1e1c2016-05-05 12:57:53 +0800158 struct acpi_namespace_node *start_node)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159{
Len Brown4be44fc2005-08-05 00:44:28 -0400160 acpi_status status;
161 struct acpi_init_walk_info info;
Bob Mooref3d2e782007-02-02 19:48:18 +0300162 struct acpi_table_header *table;
163 acpi_owner_id owner_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164
Bob Mooreb229cf92006-04-21 17:15:00 -0400165 ACPI_FUNCTION_TRACE(ds_initialize_objects);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166
Bob Mooref3d2e782007-02-02 19:48:18 +0300167 status = acpi_tb_get_owner_id(table_index, &owner_id);
168 if (ACPI_FAILURE(status)) {
169 return_ACPI_STATUS(status);
170 }
171
Len Brown4be44fc2005-08-05 00:44:28 -0400172 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
173 "**** Starting initialization of namespace objects ****\n"));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174
Alexey Starikovskiy96b7b7a2010-05-26 11:20:47 +0800175 /* Set all init info to zero */
176
Bob Moore4fa46162015-07-01 14:45:11 +0800177 memset(&info, 0, sizeof(struct acpi_init_walk_info));
Alexey Starikovskiy96b7b7a2010-05-26 11:20:47 +0800178
Bob Mooref3d2e782007-02-02 19:48:18 +0300179 info.owner_id = owner_id;
Alexey Starikovskiy96b7b7a2010-05-26 11:20:47 +0800180 info.table_index = table_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181
182 /* Walk entire namespace from the supplied root */
183
Bob Moore8a335a232009-03-09 16:31:04 +0800184 /*
185 * We don't use acpi_walk_namespace since we do not want to acquire
186 * the namespace reader lock.
187 */
188 status =
189 acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
Lv Zhengf7cc8742016-11-30 15:20:59 +0800190 ACPI_NS_WALK_NO_UNLOCK,
191 acpi_ds_init_one_object, NULL, &info, NULL);
Len Brown4be44fc2005-08-05 00:44:28 -0400192 if (ACPI_FAILURE(status)) {
Bob Mooreb229cf92006-04-21 17:15:00 -0400193 ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 }
195
Bob Mooref3d2e782007-02-02 19:48:18 +0300196 status = acpi_get_table_by_index(table_index, &table);
197 if (ACPI_FAILURE(status)) {
198 return_ACPI_STATUS(status);
199 }
200
Bob Moore92b21a92015-08-25 10:28:54 +0800201 /* DSDT is always the first AML table */
202
Bob Moore5599fb62019-04-08 13:42:24 -0700203 if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT)) {
Bob Moore92b21a92015-08-25 10:28:54 +0800204 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
205 "\nInitializing Namespace objects:\n"));
206 }
207
208 /* Summary of objects initialized */
209
Len Brown4be44fc2005-08-05 00:44:28 -0400210 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
Bob Moore1fad8732015-12-29 13:54:36 +0800211 "Table [%4.4s: %-8.8s] (id %.2X) - %4u Objects with %3u Devices, "
Bob Moore3c0503d2015-08-25 10:29:39 +0800212 "%3u Regions, %4u Methods (%u/%u/%u Serial/Non/Cvt)\n",
213 table->signature, table->oem_table_id, owner_id,
214 info.object_count, info.device_count,
215 info.op_region_count, info.method_count,
216 info.serial_method_count,
Bob Moore22b5afc2014-03-24 14:49:00 +0800217 info.non_serial_method_count,
218 info.serialized_method_count));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219
Bob Moore22b5afc2014-03-24 14:49:00 +0800220 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n",
221 info.method_count, info.op_region_count));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222
Len Brown4be44fc2005-08-05 00:44:28 -0400223 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224}