Branch data Line data Source code
1 : : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 : : /******************************************************************************
3 : : *
4 : : * Module Name: nsinit - namespace initialization
5 : : *
6 : : * Copyright (C) 2000 - 2020, 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 : 21 : acpi_status acpi_ns_initialize_objects(void)
47 : : {
48 : 21 : acpi_status status;
49 : 21 : struct acpi_init_walk_info info;
50 : :
51 : 21 : ACPI_FUNCTION_TRACE(ns_initialize_objects);
52 : :
53 : : ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
54 : 21 : "[Init] Completing Initialization of ACPI Objects\n"));
55 : : ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
56 : 21 : "**** Starting initialization of namespace objects ****\n"));
57 : : ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
58 : 21 : "Final data object initialization: "));
59 : :
60 : : /* Clear the info block */
61 : :
62 : 21 : 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 : 21 : status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
72 : : ACPI_UINT32_MAX, acpi_ns_init_one_object,
73 : : NULL, &info, NULL);
74 [ - + ]: 21 : if (ACPI_FAILURE(status)) {
75 : 0 : 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 : 21 : 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 : 21 : info.method_count, info.op_region_count));
85 : :
86 : 21 : 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 : 21 : acpi_status acpi_ns_initialize_devices(u32 flags)
106 : : {
107 : 21 : acpi_status status = AE_OK;
108 : 21 : struct acpi_device_walk_info info;
109 : 21 : acpi_handle handle;
110 : :
111 : 21 : ACPI_FUNCTION_TRACE(ns_initialize_devices);
112 : :
113 [ + - ]: 21 : if (!(flags & ACPI_NO_DEVICE_INIT)) {
114 : : ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
115 : 21 : "[Init] Initializing ACPI Devices\n"));
116 : :
117 : : /* Init counters */
118 : :
119 : 21 : info.device_count = 0;
120 : 21 : info.num_STA = 0;
121 : 21 : info.num_INI = 0;
122 : :
123 : : ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
124 : : "Initializing Device/Processor/Thermal objects "
125 : 21 : "and executing _INI/_STA methods:\n"));
126 : :
127 : : /* Tree analysis: find all subtrees that contain _INI methods */
128 : :
129 : 21 : status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
130 : : ACPI_UINT32_MAX, FALSE,
131 : : acpi_ns_find_ini_methods, NULL,
132 : : &info, NULL);
133 [ - + ]: 21 : if (ACPI_FAILURE(status)) {
134 : 0 : goto error_exit;
135 : : }
136 : :
137 : : /* Allocate the evaluation information block */
138 : :
139 : 42 : info.evaluate_info =
140 : 21 : ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
141 [ - + ]: 21 : if (!info.evaluate_info) {
142 : 0 : status = AE_NO_MEMORY;
143 : 0 : 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 : 21 : info.evaluate_info->prefix_node = acpi_gbl_root_node;
152 : 21 : info.evaluate_info->relative_pathname = METHOD_NAME__INI;
153 : 21 : info.evaluate_info->parameters = NULL;
154 : 21 : info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE;
155 : :
156 : 21 : status = acpi_ns_evaluate(info.evaluate_info);
157 [ - + ]: 21 : if (ACPI_SUCCESS(status)) {
158 : 0 : 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 : 21 : status = acpi_get_handle(NULL, "\\_SB", &handle);
167 [ + - ]: 21 : if (ACPI_SUCCESS(status)) {
168 : 21 : memset(info.evaluate_info, 0,
169 : : sizeof(struct acpi_evaluate_info));
170 : 21 : info.evaluate_info->prefix_node = handle;
171 : 21 : info.evaluate_info->relative_pathname =
172 : : METHOD_NAME__INI;
173 : 21 : info.evaluate_info->parameters = NULL;
174 : 21 : info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE;
175 : :
176 : 21 : status = acpi_ns_evaluate(info.evaluate_info);
177 [ - + ]: 21 : if (ACPI_SUCCESS(status)) {
178 : 0 : 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 [ + - ]: 21 : if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
197 : : ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
198 : 21 : "[Init] Executing _REG OpRegion methods\n"));
199 : :
200 : 21 : status = acpi_ev_initialize_op_regions();
201 [ - + ]: 21 : if (ACPI_FAILURE(status)) {
202 : 0 : goto error_exit;
203 : : }
204 : : }
205 : :
206 [ + - ]: 21 : if (!(flags & ACPI_NO_DEVICE_INIT)) {
207 : :
208 : : /* Walk namespace to execute all _INIs on present devices */
209 : :
210 : 21 : status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
211 : : ACPI_UINT32_MAX, FALSE,
212 : : acpi_ns_init_one_device, NULL,
213 : : &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 [ - + ]: 21 : if (acpi_gbl_osi_data >= ACPI_OSI_WIN_2000) {
221 : 0 : acpi_gbl_truncate_io_addresses = TRUE;
222 : : }
223 : :
224 : 21 : ACPI_FREE(info.evaluate_info);
225 [ - + ]: 21 : if (ACPI_FAILURE(status)) {
226 : 0 : 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 : 0 : error_exit:
239 : 0 : ACPI_EXCEPTION((AE_INFO, status, "During device initialization"));
240 : 0 : 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 : 84 : acpi_ns_init_one_package(acpi_handle obj_handle,
261 : : u32 level, void *context, void **return_value)
262 : : {
263 : 84 : acpi_status status;
264 : 84 : union acpi_operand_object *obj_desc;
265 : 84 : struct acpi_namespace_node *node =
266 : : (struct acpi_namespace_node *)obj_handle;
267 : :
268 : 84 : obj_desc = acpi_ns_get_attached_object(node);
269 [ + - ]: 84 : if (!obj_desc) {
270 : : return (AE_OK);
271 : : }
272 : :
273 : : /* Exit if package is already initialized */
274 : :
275 [ + - ]: 84 : if (obj_desc->package.flags & AOPOBJ_DATA_VALID) {
276 : : return (AE_OK);
277 : : }
278 : :
279 : 84 : status = acpi_ds_get_package_arguments(obj_desc);
280 [ + - ]: 84 : if (ACPI_FAILURE(status)) {
281 : : return (AE_OK);
282 : : }
283 : :
284 : 84 : status =
285 : 84 : acpi_ut_walk_package_tree(obj_desc, NULL,
286 : : acpi_ds_init_package_element, NULL);
287 [ + - ]: 84 : if (ACPI_FAILURE(status)) {
288 : : return (AE_OK);
289 : : }
290 : :
291 : 84 : obj_desc->package.flags |= AOPOBJ_DATA_VALID;
292 : 84 : 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 : 6195 : acpi_ns_init_one_object(acpi_handle obj_handle,
317 : : u32 level, void *context, void **return_value)
318 : : {
319 : 6195 : acpi_object_type type;
320 : 6195 : acpi_status status = AE_OK;
321 : 6195 : struct acpi_init_walk_info *info =
322 : : (struct acpi_init_walk_info *)context;
323 : 6195 : struct acpi_namespace_node *node =
324 : : (struct acpi_namespace_node *)obj_handle;
325 : 6195 : union acpi_operand_object *obj_desc;
326 : :
327 : 6195 : ACPI_FUNCTION_NAME(ns_init_one_object);
328 : :
329 : 6195 : info->object_count++;
330 : :
331 : : /* And even then, we are only interested in a few object types */
332 : :
333 : 6195 : type = acpi_ns_get_type(obj_handle);
334 : 6195 : obj_desc = acpi_ns_get_attached_object(node);
335 [ + + ]: 6195 : if (!obj_desc) {
336 : : return (AE_OK);
337 : : }
338 : :
339 : : /* Increment counters for object types we are looking for */
340 : :
341 [ + - - + : 4977 : switch (type) {
+ + ]
342 : 168 : case ACPI_TYPE_REGION:
343 : :
344 : 168 : info->op_region_count++;
345 : 168 : break;
346 : :
347 : 0 : case ACPI_TYPE_BUFFER_FIELD:
348 : :
349 : 0 : info->field_count++;
350 : 0 : break;
351 : :
352 : 0 : case ACPI_TYPE_LOCAL_BANK_FIELD:
353 : :
354 : 0 : info->field_count++;
355 : 0 : break;
356 : :
357 : 420 : case ACPI_TYPE_BUFFER:
358 : :
359 : 420 : info->buffer_count++;
360 : 420 : break;
361 : :
362 : 84 : case ACPI_TYPE_PACKAGE:
363 : :
364 : 84 : info->package_count++;
365 : 84 : 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 [ + + ]: 672 : 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 : 84 : acpi_ex_enter_interpreter();
383 : :
384 : : /*
385 : : * Only initialization of Package objects can be deferred, in order
386 : : * to support forward references.
387 : : */
388 [ - + - ]: 84 : switch (type) {
389 : 0 : case ACPI_TYPE_LOCAL_BANK_FIELD:
390 : :
391 : : /* TBD: bank_fields do not require deferred init, remove this code */
392 : :
393 : 0 : info->field_init++;
394 : 0 : status = acpi_ds_get_bank_field_arguments(obj_desc);
395 : 0 : break;
396 : :
397 : 84 : case ACPI_TYPE_PACKAGE:
398 : :
399 : : /* Complete the initialization/resolution of the package object */
400 : :
401 : 84 : info->package_init++;
402 : 84 : status =
403 : 84 : acpi_ns_init_one_package(obj_handle, level, NULL, NULL);
404 : 84 : break;
405 : :
406 : 0 : default:
407 : :
408 : : /* No other types should get here */
409 : :
410 : 0 : status = AE_TYPE;
411 : 0 : 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 : 0 : break;
416 : : }
417 : :
418 [ - + ]: 84 : if (ACPI_FAILURE(status)) {
419 : 0 : 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 : 84 : acpi_ex_exit_interpreter();
430 : 84 : 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 : 6195 : acpi_ns_find_ini_methods(acpi_handle obj_handle,
451 : : u32 nesting_level, void *context, void **return_value)
452 : : {
453 : 6195 : struct acpi_device_walk_info *info =
454 : : ACPI_CAST_PTR(struct acpi_device_walk_info, context);
455 : 6195 : struct acpi_namespace_node *node;
456 : 6195 : struct acpi_namespace_node *parent_node;
457 : :
458 : : /* Keep count of device/processor/thermal objects */
459 : :
460 : 6195 : node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
461 [ + + ]: 6195 : if ((node->type == ACPI_TYPE_DEVICE) ||
462 [ - + ]: 5019 : (node->type == ACPI_TYPE_PROCESSOR) ||
463 : : (node->type == ACPI_TYPE_THERMAL)) {
464 : 1176 : info->device_count++;
465 : 1176 : return (AE_OK);
466 : : }
467 : :
468 : : /* We are only looking for methods named _INI */
469 : :
470 [ + + ]: 5019 : 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 : 21 : parent_node = node->parent;
479 [ + - ]: 21 : 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 [ + + ]: 105 : while (parent_node) {
487 : 84 : parent_node->flags |= ANOBJ_SUBTREE_HAS_INI;
488 : 84 : 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 : 2079 : acpi_ns_init_one_device(acpi_handle obj_handle,
516 : : u32 nesting_level, void *context, void **return_value)
517 : : {
518 : 2079 : struct acpi_device_walk_info *walk_info =
519 : : ACPI_CAST_PTR(struct acpi_device_walk_info, context);
520 : 2079 : struct acpi_evaluate_info *info = walk_info->evaluate_info;
521 : 2079 : u32 flags;
522 : 2079 : acpi_status status;
523 : 2079 : struct acpi_namespace_node *device_node;
524 : :
525 : 2079 : ACPI_FUNCTION_TRACE(ns_init_one_device);
526 : :
527 : : /* We are interested in Devices, Processors and thermal_zones only */
528 : :
529 : 2079 : device_node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
530 [ + + ]: 2079 : if ((device_node->type != ACPI_TYPE_DEVICE) &&
531 [ - + ]: 1092 : (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 [ + + ]: 987 : 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 : 63 : (ACPI_TYPE_METHOD, device_node, METHOD_NAME__STA));
560 : :
561 : 63 : status = acpi_ut_execute_STA(device_node, &flags);
562 [ + - ]: 63 : 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 [ - + ]: 63 : if (flags != ACPI_UINT32_MAX) {
580 : 0 : 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 [ - + ]: 63 : if (!(flags & ACPI_STA_DEVICE_PRESENT)) {
590 : :
591 : : /* Device is not present, we must examine the Functioning bit */
592 : :
593 [ # # ]: 0 : 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 : 0 : 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 [ + + ]: 63 : if (!ACPI_COMPARE_NAMESEG(device_node->name.ascii, "_SB_") ||
634 [ - + ]: 21 : device_node->parent != acpi_gbl_root_node) {
635 : : ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
636 : : (ACPI_TYPE_METHOD, device_node,
637 : 42 : METHOD_NAME__INI));
638 : :
639 : 42 : memset(info, 0, sizeof(struct acpi_evaluate_info));
640 : 42 : info->prefix_node = device_node;
641 : 42 : info->relative_pathname = METHOD_NAME__INI;
642 : 42 : info->parameters = NULL;
643 : 42 : info->flags = ACPI_IGNORE_RETURN_VALUE;
644 : :
645 : 42 : status = acpi_ns_evaluate(info);
646 [ + + ]: 42 : if (ACPI_SUCCESS(status)) {
647 : 21 : 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(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 : 63 : 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 [ - + ]: 63 : if (acpi_gbl_init_handler) {
674 : 0 : status =
675 : 0 : acpi_gbl_init_handler(device_node, ACPI_INIT_DEVICE_INI);
676 : : }
677 : :
678 : : return_ACPI_STATUS(status);
679 : : }
|