1 | // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 |
2 | /****************************************************************************** |
3 | * |
4 | * Module Name: nsinit - namespace initialization |
5 | * |
6 | * Copyright (C) 2000 - 2023, Intel Corp. |
7 | * |
8 | *****************************************************************************/ |
9 | |
10 | #include <acpi/acpi.h> |
11 | #include "accommon.h" |
12 | #include "acnamesp.h" |
13 | #include "acdispat.h" |
14 | #include "acinterp.h" |
15 | #include "acevents.h" |
16 | |
17 | #define _COMPONENT ACPI_NAMESPACE |
18 | ACPI_MODULE_NAME("nsinit" ) |
19 | |
20 | /* Local prototypes */ |
21 | static acpi_status |
22 | acpi_ns_init_one_object(acpi_handle obj_handle, |
23 | u32 level, void *context, void **return_value); |
24 | |
25 | static acpi_status |
26 | acpi_ns_init_one_device(acpi_handle obj_handle, |
27 | u32 nesting_level, void *context, void **return_value); |
28 | |
29 | static acpi_status |
30 | acpi_ns_find_ini_methods(acpi_handle obj_handle, |
31 | u32 nesting_level, void *context, void **return_value); |
32 | |
33 | /******************************************************************************* |
34 | * |
35 | * FUNCTION: acpi_ns_initialize_objects |
36 | * |
37 | * PARAMETERS: None |
38 | * |
39 | * RETURN: Status |
40 | * |
41 | * DESCRIPTION: Walk the entire namespace and perform any necessary |
42 | * initialization on the objects found therein |
43 | * |
44 | ******************************************************************************/ |
45 | |
46 | acpi_status acpi_ns_initialize_objects(void) |
47 | { |
48 | acpi_status status; |
49 | struct acpi_init_walk_info info; |
50 | |
51 | ACPI_FUNCTION_TRACE(ns_initialize_objects); |
52 | |
53 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
54 | "[Init] Completing Initialization of ACPI Objects\n" )); |
55 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
56 | "**** Starting initialization of namespace objects ****\n" )); |
57 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
58 | "Final data object initialization: " )); |
59 | |
60 | /* Clear the info block */ |
61 | |
62 | memset(&info, 0, sizeof(struct acpi_init_walk_info)); |
63 | |
64 | /* Walk entire namespace from the supplied root */ |
65 | |
66 | /* |
67 | * TBD: will become ACPI_TYPE_PACKAGE as this type object |
68 | * is now the only one that supports deferred initialization |
69 | * (forward references). |
70 | */ |
71 | status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, |
72 | ACPI_UINT32_MAX, descending_callback: acpi_ns_init_one_object, |
73 | NULL, context: &info, NULL); |
74 | if (ACPI_FAILURE(status)) { |
75 | ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace" )); |
76 | } |
77 | |
78 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
79 | "Namespace contains %u (0x%X) objects\n" , |
80 | info.object_count, info.object_count)); |
81 | |
82 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
83 | "%u Control Methods found\n%u Op Regions found\n" , |
84 | info.method_count, info.op_region_count)); |
85 | |
86 | return_ACPI_STATUS(AE_OK); |
87 | } |
88 | |
89 | /******************************************************************************* |
90 | * |
91 | * FUNCTION: acpi_ns_initialize_devices |
92 | * |
93 | * PARAMETERS: None |
94 | * |
95 | * RETURN: acpi_status |
96 | * |
97 | * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices. |
98 | * This means running _INI on all present devices. |
99 | * |
100 | * Note: We install PCI config space handler on region access, |
101 | * not here. |
102 | * |
103 | ******************************************************************************/ |
104 | |
105 | acpi_status acpi_ns_initialize_devices(u32 flags) |
106 | { |
107 | acpi_status status = AE_OK; |
108 | struct acpi_device_walk_info info; |
109 | acpi_handle handle; |
110 | |
111 | ACPI_FUNCTION_TRACE(ns_initialize_devices); |
112 | |
113 | if (!(flags & ACPI_NO_DEVICE_INIT)) { |
114 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
115 | "[Init] Initializing ACPI Devices\n" )); |
116 | |
117 | /* Init counters */ |
118 | |
119 | info.device_count = 0; |
120 | info.num_STA = 0; |
121 | info.num_INI = 0; |
122 | |
123 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
124 | "Initializing Device/Processor/Thermal objects " |
125 | "and executing _INI/_STA methods:\n" )); |
126 | |
127 | /* Tree analysis: find all subtrees that contain _INI methods */ |
128 | |
129 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, |
130 | ACPI_UINT32_MAX, FALSE, |
131 | descending_callback: acpi_ns_find_ini_methods, NULL, |
132 | context: &info, NULL); |
133 | if (ACPI_FAILURE(status)) { |
134 | goto error_exit; |
135 | } |
136 | |
137 | /* Allocate the evaluation information block */ |
138 | |
139 | info.evaluate_info = |
140 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); |
141 | if (!info.evaluate_info) { |
142 | status = AE_NO_MEMORY; |
143 | goto error_exit; |
144 | } |
145 | |
146 | /* |
147 | * Execute the "global" _INI method that may appear at the root. |
148 | * This support is provided for Windows compatibility (Vista+) and |
149 | * is not part of the ACPI specification. |
150 | */ |
151 | info.evaluate_info->prefix_node = acpi_gbl_root_node; |
152 | info.evaluate_info->relative_pathname = METHOD_NAME__INI; |
153 | info.evaluate_info->parameters = NULL; |
154 | info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE; |
155 | |
156 | status = acpi_ns_evaluate(info: info.evaluate_info); |
157 | if (ACPI_SUCCESS(status)) { |
158 | info.num_INI++; |
159 | } |
160 | |
161 | /* |
162 | * Execute \_SB._INI. |
163 | * There appears to be a strict order requirement for \_SB._INI, |
164 | * which should be evaluated before any _REG evaluations. |
165 | */ |
166 | status = acpi_get_handle(NULL, pathname: "\\_SB" , ret_handle: &handle); |
167 | if (ACPI_SUCCESS(status)) { |
168 | memset(info.evaluate_info, 0, |
169 | sizeof(struct acpi_evaluate_info)); |
170 | info.evaluate_info->prefix_node = handle; |
171 | info.evaluate_info->relative_pathname = |
172 | METHOD_NAME__INI; |
173 | info.evaluate_info->parameters = NULL; |
174 | info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE; |
175 | |
176 | status = acpi_ns_evaluate(info: info.evaluate_info); |
177 | if (ACPI_SUCCESS(status)) { |
178 | info.num_INI++; |
179 | } |
180 | } |
181 | } |
182 | |
183 | /* |
184 | * Run all _REG methods |
185 | * |
186 | * Note: Any objects accessed by the _REG methods will be automatically |
187 | * initialized, even if they contain executable AML (see the call to |
188 | * acpi_ns_initialize_objects below). |
189 | * |
190 | * Note: According to the ACPI specification, we actually needn't execute |
191 | * _REG for system_memory/system_io operation regions, but for PCI_Config |
192 | * operation regions, it is required to evaluate _REG for those on a PCI |
193 | * root bus that doesn't contain _BBN object. So this code is kept here |
194 | * in order not to break things. |
195 | */ |
196 | if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { |
197 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
198 | "[Init] Executing _REG OpRegion methods\n" )); |
199 | |
200 | status = acpi_ev_initialize_op_regions(); |
201 | if (ACPI_FAILURE(status)) { |
202 | goto error_exit; |
203 | } |
204 | } |
205 | |
206 | if (!(flags & ACPI_NO_DEVICE_INIT)) { |
207 | |
208 | /* Walk namespace to execute all _INIs on present devices */ |
209 | |
210 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, |
211 | ACPI_UINT32_MAX, FALSE, |
212 | descending_callback: acpi_ns_init_one_device, NULL, |
213 | context: &info, NULL); |
214 | |
215 | /* |
216 | * Any _OSI requests should be completed by now. If the BIOS has |
217 | * requested any Windows OSI strings, we will always truncate |
218 | * I/O addresses to 16 bits -- for Windows compatibility. |
219 | */ |
220 | if (acpi_gbl_osi_data >= ACPI_OSI_WIN_2000) { |
221 | acpi_gbl_truncate_io_addresses = TRUE; |
222 | } |
223 | |
224 | ACPI_FREE(info.evaluate_info); |
225 | if (ACPI_FAILURE(status)) { |
226 | goto error_exit; |
227 | } |
228 | |
229 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
230 | " Executed %u _INI methods requiring %u _STA executions " |
231 | "(examined %u objects)\n" , |
232 | info.num_INI, info.num_STA, |
233 | info.device_count)); |
234 | } |
235 | |
236 | return_ACPI_STATUS(status); |
237 | |
238 | error_exit: |
239 | ACPI_EXCEPTION((AE_INFO, status, "During device initialization" )); |
240 | return_ACPI_STATUS(status); |
241 | } |
242 | |
243 | /******************************************************************************* |
244 | * |
245 | * FUNCTION: acpi_ns_init_one_package |
246 | * |
247 | * PARAMETERS: obj_handle - Node |
248 | * level - Current nesting level |
249 | * context - Not used |
250 | * return_value - Not used |
251 | * |
252 | * RETURN: Status |
253 | * |
254 | * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every package |
255 | * within the namespace. Used during dynamic load of an SSDT. |
256 | * |
257 | ******************************************************************************/ |
258 | |
259 | acpi_status |
260 | acpi_ns_init_one_package(acpi_handle obj_handle, |
261 | u32 level, void *context, void **return_value) |
262 | { |
263 | acpi_status status; |
264 | union acpi_operand_object *obj_desc; |
265 | struct acpi_namespace_node *node = |
266 | (struct acpi_namespace_node *)obj_handle; |
267 | |
268 | obj_desc = acpi_ns_get_attached_object(node); |
269 | if (!obj_desc) { |
270 | return (AE_OK); |
271 | } |
272 | |
273 | /* Exit if package is already initialized */ |
274 | |
275 | if (obj_desc->package.flags & AOPOBJ_DATA_VALID) { |
276 | return (AE_OK); |
277 | } |
278 | |
279 | status = acpi_ds_get_package_arguments(obj_desc); |
280 | if (ACPI_FAILURE(status)) { |
281 | return (AE_OK); |
282 | } |
283 | |
284 | status = |
285 | acpi_ut_walk_package_tree(source_object: obj_desc, NULL, |
286 | walk_callback: acpi_ds_init_package_element, NULL); |
287 | if (ACPI_FAILURE(status)) { |
288 | return (AE_OK); |
289 | } |
290 | |
291 | obj_desc->package.flags |= AOPOBJ_DATA_VALID; |
292 | return (AE_OK); |
293 | } |
294 | |
295 | /******************************************************************************* |
296 | * |
297 | * FUNCTION: acpi_ns_init_one_object |
298 | * |
299 | * PARAMETERS: obj_handle - Node |
300 | * level - Current nesting level |
301 | * context - Points to a init info struct |
302 | * return_value - Not used |
303 | * |
304 | * RETURN: Status |
305 | * |
306 | * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object |
307 | * within the namespace. |
308 | * |
309 | * Currently, the only objects that require initialization are: |
310 | * 1) Methods |
311 | * 2) Op Regions |
312 | * |
313 | ******************************************************************************/ |
314 | |
315 | static acpi_status |
316 | acpi_ns_init_one_object(acpi_handle obj_handle, |
317 | u32 level, void *context, void **return_value) |
318 | { |
319 | acpi_object_type type; |
320 | acpi_status status = AE_OK; |
321 | struct acpi_init_walk_info *info = |
322 | (struct acpi_init_walk_info *)context; |
323 | struct acpi_namespace_node *node = |
324 | (struct acpi_namespace_node *)obj_handle; |
325 | union acpi_operand_object *obj_desc; |
326 | |
327 | ACPI_FUNCTION_NAME(ns_init_one_object); |
328 | |
329 | info->object_count++; |
330 | |
331 | /* And even then, we are only interested in a few object types */ |
332 | |
333 | type = acpi_ns_get_type(node: obj_handle); |
334 | obj_desc = acpi_ns_get_attached_object(node); |
335 | if (!obj_desc) { |
336 | return (AE_OK); |
337 | } |
338 | |
339 | /* Increment counters for object types we are looking for */ |
340 | |
341 | switch (type) { |
342 | case ACPI_TYPE_REGION: |
343 | |
344 | info->op_region_count++; |
345 | break; |
346 | |
347 | case ACPI_TYPE_BUFFER_FIELD: |
348 | |
349 | info->field_count++; |
350 | break; |
351 | |
352 | case ACPI_TYPE_LOCAL_BANK_FIELD: |
353 | |
354 | info->field_count++; |
355 | break; |
356 | |
357 | case ACPI_TYPE_BUFFER: |
358 | |
359 | info->buffer_count++; |
360 | break; |
361 | |
362 | case ACPI_TYPE_PACKAGE: |
363 | |
364 | info->package_count++; |
365 | break; |
366 | |
367 | default: |
368 | |
369 | /* No init required, just exit now */ |
370 | |
371 | return (AE_OK); |
372 | } |
373 | |
374 | /* If the object is already initialized, nothing else to do */ |
375 | |
376 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { |
377 | return (AE_OK); |
378 | } |
379 | |
380 | /* Must lock the interpreter before executing AML code */ |
381 | |
382 | acpi_ex_enter_interpreter(); |
383 | |
384 | /* |
385 | * Only initialization of Package objects can be deferred, in order |
386 | * to support forward references. |
387 | */ |
388 | switch (type) { |
389 | case ACPI_TYPE_LOCAL_BANK_FIELD: |
390 | |
391 | /* TBD: bank_fields do not require deferred init, remove this code */ |
392 | |
393 | info->field_init++; |
394 | status = acpi_ds_get_bank_field_arguments(obj_desc); |
395 | break; |
396 | |
397 | case ACPI_TYPE_PACKAGE: |
398 | |
399 | /* Complete the initialization/resolution of the package object */ |
400 | |
401 | info->package_init++; |
402 | status = |
403 | acpi_ns_init_one_package(obj_handle, level, NULL, NULL); |
404 | break; |
405 | |
406 | default: |
407 | |
408 | /* No other types should get here */ |
409 | |
410 | status = AE_TYPE; |
411 | ACPI_EXCEPTION((AE_INFO, status, |
412 | "Opcode is not deferred [%4.4s] (%s)" , |
413 | acpi_ut_get_node_name(node), |
414 | acpi_ut_get_type_name(type))); |
415 | break; |
416 | } |
417 | |
418 | if (ACPI_FAILURE(status)) { |
419 | ACPI_EXCEPTION((AE_INFO, status, |
420 | "Could not execute arguments for [%4.4s] (%s)" , |
421 | acpi_ut_get_node_name(node), |
422 | acpi_ut_get_type_name(type))); |
423 | } |
424 | |
425 | /* |
426 | * We ignore errors from above, and always return OK, since we don't want |
427 | * to abort the walk on any single error. |
428 | */ |
429 | acpi_ex_exit_interpreter(); |
430 | return (AE_OK); |
431 | } |
432 | |
433 | /******************************************************************************* |
434 | * |
435 | * FUNCTION: acpi_ns_find_ini_methods |
436 | * |
437 | * PARAMETERS: acpi_walk_callback |
438 | * |
439 | * RETURN: acpi_status |
440 | * |
441 | * DESCRIPTION: Called during namespace walk. Finds objects named _INI under |
442 | * device/processor/thermal objects, and marks the entire subtree |
443 | * with a SUBTREE_HAS_INI flag. This flag is used during the |
444 | * subsequent device initialization walk to avoid entire subtrees |
445 | * that do not contain an _INI. |
446 | * |
447 | ******************************************************************************/ |
448 | |
449 | static acpi_status |
450 | acpi_ns_find_ini_methods(acpi_handle obj_handle, |
451 | u32 nesting_level, void *context, void **return_value) |
452 | { |
453 | struct acpi_device_walk_info *info = |
454 | ACPI_CAST_PTR(struct acpi_device_walk_info, context); |
455 | struct acpi_namespace_node *node; |
456 | struct acpi_namespace_node *parent_node; |
457 | |
458 | /* Keep count of device/processor/thermal objects */ |
459 | |
460 | node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); |
461 | if ((node->type == ACPI_TYPE_DEVICE) || |
462 | (node->type == ACPI_TYPE_PROCESSOR) || |
463 | (node->type == ACPI_TYPE_THERMAL)) { |
464 | info->device_count++; |
465 | return (AE_OK); |
466 | } |
467 | |
468 | /* We are only looking for methods named _INI */ |
469 | |
470 | if (!ACPI_COMPARE_NAMESEG(node->name.ascii, METHOD_NAME__INI)) { |
471 | return (AE_OK); |
472 | } |
473 | |
474 | /* |
475 | * The only _INI methods that we care about are those that are |
476 | * present under Device, Processor, and Thermal objects. |
477 | */ |
478 | parent_node = node->parent; |
479 | switch (parent_node->type) { |
480 | case ACPI_TYPE_DEVICE: |
481 | case ACPI_TYPE_PROCESSOR: |
482 | case ACPI_TYPE_THERMAL: |
483 | |
484 | /* Mark parent and bubble up the INI present flag to the root */ |
485 | |
486 | while (parent_node) { |
487 | parent_node->flags |= ANOBJ_SUBTREE_HAS_INI; |
488 | parent_node = parent_node->parent; |
489 | } |
490 | break; |
491 | |
492 | default: |
493 | |
494 | break; |
495 | } |
496 | |
497 | return (AE_OK); |
498 | } |
499 | |
500 | /******************************************************************************* |
501 | * |
502 | * FUNCTION: acpi_ns_init_one_device |
503 | * |
504 | * PARAMETERS: acpi_walk_callback |
505 | * |
506 | * RETURN: acpi_status |
507 | * |
508 | * DESCRIPTION: This is called once per device soon after ACPI is enabled |
509 | * to initialize each device. It determines if the device is |
510 | * present, and if so, calls _INI. |
511 | * |
512 | ******************************************************************************/ |
513 | |
514 | static acpi_status |
515 | acpi_ns_init_one_device(acpi_handle obj_handle, |
516 | u32 nesting_level, void *context, void **return_value) |
517 | { |
518 | struct acpi_device_walk_info *walk_info = |
519 | ACPI_CAST_PTR(struct acpi_device_walk_info, context); |
520 | struct acpi_evaluate_info *info = walk_info->evaluate_info; |
521 | u32 flags; |
522 | acpi_status status; |
523 | struct acpi_namespace_node *device_node; |
524 | |
525 | ACPI_FUNCTION_TRACE(ns_init_one_device); |
526 | |
527 | /* We are interested in Devices, Processors and thermal_zones only */ |
528 | |
529 | device_node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); |
530 | if ((device_node->type != ACPI_TYPE_DEVICE) && |
531 | (device_node->type != ACPI_TYPE_PROCESSOR) && |
532 | (device_node->type != ACPI_TYPE_THERMAL)) { |
533 | return_ACPI_STATUS(AE_OK); |
534 | } |
535 | |
536 | /* |
537 | * Because of an earlier namespace analysis, all subtrees that contain an |
538 | * _INI method are tagged. |
539 | * |
540 | * If this device subtree does not contain any _INI methods, we |
541 | * can exit now and stop traversing this entire subtree. |
542 | */ |
543 | if (!(device_node->flags & ANOBJ_SUBTREE_HAS_INI)) { |
544 | return_ACPI_STATUS(AE_CTRL_DEPTH); |
545 | } |
546 | |
547 | /* |
548 | * Run _STA to determine if this device is present and functioning. We |
549 | * must know this information for two important reasons (from ACPI spec): |
550 | * |
551 | * 1) We can only run _INI if the device is present. |
552 | * 2) We must abort the device tree walk on this subtree if the device is |
553 | * not present and is not functional (we will not examine the children) |
554 | * |
555 | * The _STA method is not required to be present under the device, we |
556 | * assume the device is present if _STA does not exist. |
557 | */ |
558 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname |
559 | (ACPI_TYPE_METHOD, device_node, METHOD_NAME__STA)); |
560 | |
561 | status = acpi_ut_execute_STA(device_node, status_flags: &flags); |
562 | if (ACPI_FAILURE(status)) { |
563 | |
564 | /* Ignore error and move on to next device */ |
565 | |
566 | return_ACPI_STATUS(AE_OK); |
567 | } |
568 | |
569 | /* |
570 | * Flags == -1 means that _STA was not found. In this case, we assume that |
571 | * the device is both present and functional. |
572 | * |
573 | * From the ACPI spec, description of _STA: |
574 | * |
575 | * "If a device object (including the processor object) does not have an |
576 | * _STA object, then OSPM assumes that all of the above bits are set (in |
577 | * other words, the device is present, ..., and functioning)" |
578 | */ |
579 | if (flags != ACPI_UINT32_MAX) { |
580 | walk_info->num_STA++; |
581 | } |
582 | |
583 | /* |
584 | * Examine the PRESENT and FUNCTIONING status bits |
585 | * |
586 | * Note: ACPI spec does not seem to specify behavior for the present but |
587 | * not functioning case, so we assume functioning if present. |
588 | */ |
589 | if (!(flags & ACPI_STA_DEVICE_PRESENT)) { |
590 | |
591 | /* Device is not present, we must examine the Functioning bit */ |
592 | |
593 | if (flags & ACPI_STA_DEVICE_FUNCTIONING) { |
594 | /* |
595 | * Device is not present but is "functioning". In this case, |
596 | * we will not run _INI, but we continue to examine the children |
597 | * of this device. |
598 | * |
599 | * From the ACPI spec, description of _STA: (note - no mention |
600 | * of whether to run _INI or not on the device in question) |
601 | * |
602 | * "_STA may return bit 0 clear (not present) with bit 3 set |
603 | * (device is functional). This case is used to indicate a valid |
604 | * device for which no device driver should be loaded (for example, |
605 | * a bridge device.) Children of this device may be present and |
606 | * valid. OSPM should continue enumeration below a device whose |
607 | * _STA returns this bit combination" |
608 | */ |
609 | return_ACPI_STATUS(AE_OK); |
610 | } else { |
611 | /* |
612 | * Device is not present and is not functioning. We must abort the |
613 | * walk of this subtree immediately -- don't look at the children |
614 | * of such a device. |
615 | * |
616 | * From the ACPI spec, description of _INI: |
617 | * |
618 | * "If the _STA method indicates that the device is not present, |
619 | * OSPM will not run the _INI and will not examine the children |
620 | * of the device for _INI methods" |
621 | */ |
622 | return_ACPI_STATUS(AE_CTRL_DEPTH); |
623 | } |
624 | } |
625 | |
626 | /* |
627 | * The device is present or is assumed present if no _STA exists. |
628 | * Run the _INI if it exists (not required to exist) |
629 | * |
630 | * Note: We know there is an _INI within this subtree, but it may not be |
631 | * under this particular device, it may be lower in the branch. |
632 | */ |
633 | if (!ACPI_COMPARE_NAMESEG(device_node->name.ascii, "_SB_" ) || |
634 | device_node->parent != acpi_gbl_root_node) { |
635 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname |
636 | (ACPI_TYPE_METHOD, device_node, |
637 | METHOD_NAME__INI)); |
638 | |
639 | memset(info, 0, sizeof(struct acpi_evaluate_info)); |
640 | info->prefix_node = device_node; |
641 | info->relative_pathname = METHOD_NAME__INI; |
642 | info->parameters = NULL; |
643 | info->flags = ACPI_IGNORE_RETURN_VALUE; |
644 | |
645 | status = acpi_ns_evaluate(info); |
646 | if (ACPI_SUCCESS(status)) { |
647 | walk_info->num_INI++; |
648 | } |
649 | #ifdef ACPI_DEBUG_OUTPUT |
650 | else if (status != AE_NOT_FOUND) { |
651 | |
652 | /* Ignore error and move on to next device */ |
653 | |
654 | char *scope_name = |
655 | acpi_ns_get_normalized_pathname(node: device_node, TRUE); |
656 | |
657 | ACPI_EXCEPTION((AE_INFO, status, |
658 | "during %s._INI execution" , |
659 | scope_name)); |
660 | ACPI_FREE(scope_name); |
661 | } |
662 | #endif |
663 | } |
664 | |
665 | /* Ignore errors from above */ |
666 | |
667 | status = AE_OK; |
668 | |
669 | /* |
670 | * The _INI method has been run if present; call the Global Initialization |
671 | * Handler for this device. |
672 | */ |
673 | if (acpi_gbl_init_handler) { |
674 | status = |
675 | acpi_gbl_init_handler(device_node, ACPI_INIT_DEVICE_INI); |
676 | } |
677 | |
678 | return_ACPI_STATUS(status); |
679 | } |
680 | |