Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/acpi/acpica/dsinit.c
26282 views
1
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2
/******************************************************************************
3
*
4
* Module Name: dsinit - Object initialization namespace walk
5
*
6
* Copyright (C) 2000 - 2025, Intel Corp.
7
*
8
*****************************************************************************/
9
10
#include <acpi/acpi.h>
11
#include "accommon.h"
12
#include "acdispat.h"
13
#include "acnamesp.h"
14
#include "actables.h"
15
#include "acinterp.h"
16
17
#define _COMPONENT ACPI_DISPATCHER
18
ACPI_MODULE_NAME("dsinit")
19
20
/* Local prototypes */
21
static acpi_status
22
acpi_ds_init_one_object(acpi_handle obj_handle,
23
u32 level, void *context, void **return_value);
24
25
/*******************************************************************************
26
*
27
* FUNCTION: acpi_ds_init_one_object
28
*
29
* PARAMETERS: obj_handle - Node for the object
30
* level - Current nesting level
31
* context - Points to a init info struct
32
* 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
45
static acpi_status
46
acpi_ds_init_one_object(acpi_handle obj_handle,
47
u32 level, void *context, void **return_value)
48
{
49
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;
53
acpi_status status;
54
union acpi_operand_object *obj_desc;
55
56
ACPI_FUNCTION_ENTRY();
57
58
/*
59
* We are only interested in NS nodes owned by the table that
60
* was just loaded
61
*/
62
if (node->owner_id != info->owner_id) {
63
return (AE_OK);
64
}
65
66
info->object_count++;
67
68
/* And even then, we are only interested in a few object types */
69
70
switch (acpi_ns_get_type(obj_handle)) {
71
case ACPI_TYPE_REGION:
72
73
status = acpi_ds_initialize_region(obj_handle);
74
if (ACPI_FAILURE(status)) {
75
ACPI_EXCEPTION((AE_INFO, status,
76
"During Region initialization %p [%4.4s]",
77
obj_handle,
78
acpi_ut_get_node_name(obj_handle)));
79
}
80
81
info->op_region_count++;
82
break;
83
84
case ACPI_TYPE_METHOD:
85
/*
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
*/
93
info->method_count++;
94
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++;
123
break;
124
125
case ACPI_TYPE_DEVICE:
126
127
info->device_count++;
128
break;
129
130
default:
131
132
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
142
/*******************************************************************************
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
*
151
* DESCRIPTION: Walk the namespace starting at "StartNode" and perform any
152
* necessary initialization on the objects found therein
153
*
154
******************************************************************************/
155
156
acpi_status
157
acpi_ds_initialize_objects(u32 table_index,
158
struct acpi_namespace_node *start_node)
159
{
160
acpi_status status;
161
struct acpi_init_walk_info info;
162
struct acpi_table_header *table;
163
acpi_owner_id owner_id;
164
165
ACPI_FUNCTION_TRACE(ds_initialize_objects);
166
167
status = acpi_tb_get_owner_id(table_index, &owner_id);
168
if (ACPI_FAILURE(status)) {
169
return_ACPI_STATUS(status);
170
}
171
172
ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
173
"**** Starting initialization of namespace objects ****\n"));
174
175
/* Set all init info to zero */
176
177
memset(&info, 0, sizeof(struct acpi_init_walk_info));
178
179
info.owner_id = owner_id;
180
info.table_index = table_index;
181
182
/* Walk entire namespace from the supplied root */
183
184
/*
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,
190
ACPI_NS_WALK_NO_UNLOCK,
191
acpi_ds_init_one_object, NULL, &info, NULL);
192
if (ACPI_FAILURE(status)) {
193
ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
194
}
195
196
status = acpi_get_table_by_index(table_index, &table);
197
if (ACPI_FAILURE(status)) {
198
return_ACPI_STATUS(status);
199
}
200
201
/* DSDT is always the first AML table */
202
203
if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT)) {
204
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
205
"\nACPI table initialization:\n"));
206
}
207
208
/* Summary of objects initialized */
209
210
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
211
"Table [%4.4s: %-8.8s] (id %.2X) - %4u Objects with %3u Devices, "
212
"%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,
217
info.non_serial_method_count,
218
info.serialized_method_count));
219
220
ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n",
221
info.method_count, info.op_region_count));
222
223
return_ACPI_STATUS(AE_OK);
224
}
225
226