0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acnamesp.h"
0013 #include "acdispat.h"
0014 #include "acinterp.h"
0015 #include "acevents.h"
0016
0017 #define _COMPONENT ACPI_NAMESPACE
0018 ACPI_MODULE_NAME("nsinit")
0019
0020
0021 static acpi_status
0022 acpi_ns_init_one_object(acpi_handle obj_handle,
0023 u32 level, void *context, void **return_value);
0024
0025 static acpi_status
0026 acpi_ns_init_one_device(acpi_handle obj_handle,
0027 u32 nesting_level, void *context, void **return_value);
0028
0029 static acpi_status
0030 acpi_ns_find_ini_methods(acpi_handle obj_handle,
0031 u32 nesting_level, void *context, void **return_value);
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 acpi_status acpi_ns_initialize_objects(void)
0047 {
0048 acpi_status status;
0049 struct acpi_init_walk_info info;
0050
0051 ACPI_FUNCTION_TRACE(ns_initialize_objects);
0052
0053 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0054 "[Init] Completing Initialization of ACPI Objects\n"));
0055 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
0056 "**** Starting initialization of namespace objects ****\n"));
0057 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
0058 "Final data object initialization: "));
0059
0060
0061
0062 memset(&info, 0, sizeof(struct acpi_init_walk_info));
0063
0064
0065
0066
0067
0068
0069
0070
0071 status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
0072 ACPI_UINT32_MAX, acpi_ns_init_one_object,
0073 NULL, &info, NULL);
0074 if (ACPI_FAILURE(status)) {
0075 ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
0076 }
0077
0078 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
0079 "Namespace contains %u (0x%X) objects\n",
0080 info.object_count, info.object_count));
0081
0082 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
0083 "%u Control Methods found\n%u Op Regions found\n",
0084 info.method_count, info.op_region_count));
0085
0086 return_ACPI_STATUS(AE_OK);
0087 }
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 acpi_status acpi_ns_initialize_devices(u32 flags)
0106 {
0107 acpi_status status = AE_OK;
0108 struct acpi_device_walk_info info;
0109 acpi_handle handle;
0110
0111 ACPI_FUNCTION_TRACE(ns_initialize_devices);
0112
0113 if (!(flags & ACPI_NO_DEVICE_INIT)) {
0114 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0115 "[Init] Initializing ACPI Devices\n"));
0116
0117
0118
0119 info.device_count = 0;
0120 info.num_STA = 0;
0121 info.num_INI = 0;
0122
0123 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
0124 "Initializing Device/Processor/Thermal objects "
0125 "and executing _INI/_STA methods:\n"));
0126
0127
0128
0129 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
0130 ACPI_UINT32_MAX, FALSE,
0131 acpi_ns_find_ini_methods, NULL,
0132 &info, NULL);
0133 if (ACPI_FAILURE(status)) {
0134 goto error_exit;
0135 }
0136
0137
0138
0139 info.evaluate_info =
0140 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
0141 if (!info.evaluate_info) {
0142 status = AE_NO_MEMORY;
0143 goto error_exit;
0144 }
0145
0146
0147
0148
0149
0150
0151 info.evaluate_info->prefix_node = acpi_gbl_root_node;
0152 info.evaluate_info->relative_pathname = METHOD_NAME__INI;
0153 info.evaluate_info->parameters = NULL;
0154 info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE;
0155
0156 status = acpi_ns_evaluate(info.evaluate_info);
0157 if (ACPI_SUCCESS(status)) {
0158 info.num_INI++;
0159 }
0160
0161
0162
0163
0164
0165
0166 status = acpi_get_handle(NULL, "\\_SB", &handle);
0167 if (ACPI_SUCCESS(status)) {
0168 memset(info.evaluate_info, 0,
0169 sizeof(struct acpi_evaluate_info));
0170 info.evaluate_info->prefix_node = handle;
0171 info.evaluate_info->relative_pathname =
0172 METHOD_NAME__INI;
0173 info.evaluate_info->parameters = NULL;
0174 info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE;
0175
0176 status = acpi_ns_evaluate(info.evaluate_info);
0177 if (ACPI_SUCCESS(status)) {
0178 info.num_INI++;
0179 }
0180 }
0181 }
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
0197 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0198 "[Init] Executing _REG OpRegion methods\n"));
0199
0200 status = acpi_ev_initialize_op_regions();
0201 if (ACPI_FAILURE(status)) {
0202 goto error_exit;
0203 }
0204 }
0205
0206 if (!(flags & ACPI_NO_DEVICE_INIT)) {
0207
0208
0209
0210 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
0211 ACPI_UINT32_MAX, FALSE,
0212 acpi_ns_init_one_device, NULL,
0213 &info, NULL);
0214
0215
0216
0217
0218
0219
0220 if (acpi_gbl_osi_data >= ACPI_OSI_WIN_2000) {
0221 acpi_gbl_truncate_io_addresses = TRUE;
0222 }
0223
0224 ACPI_FREE(info.evaluate_info);
0225 if (ACPI_FAILURE(status)) {
0226 goto error_exit;
0227 }
0228
0229 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
0230 " Executed %u _INI methods requiring %u _STA executions "
0231 "(examined %u objects)\n",
0232 info.num_INI, info.num_STA,
0233 info.device_count));
0234 }
0235
0236 return_ACPI_STATUS(status);
0237
0238 error_exit:
0239 ACPI_EXCEPTION((AE_INFO, status, "During device initialization"));
0240 return_ACPI_STATUS(status);
0241 }
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259 acpi_status
0260 acpi_ns_init_one_package(acpi_handle obj_handle,
0261 u32 level, void *context, void **return_value)
0262 {
0263 acpi_status status;
0264 union acpi_operand_object *obj_desc;
0265 struct acpi_namespace_node *node =
0266 (struct acpi_namespace_node *)obj_handle;
0267
0268 obj_desc = acpi_ns_get_attached_object(node);
0269 if (!obj_desc) {
0270 return (AE_OK);
0271 }
0272
0273
0274
0275 if (obj_desc->package.flags & AOPOBJ_DATA_VALID) {
0276 return (AE_OK);
0277 }
0278
0279 status = acpi_ds_get_package_arguments(obj_desc);
0280 if (ACPI_FAILURE(status)) {
0281 return (AE_OK);
0282 }
0283
0284 status =
0285 acpi_ut_walk_package_tree(obj_desc, NULL,
0286 acpi_ds_init_package_element, NULL);
0287 if (ACPI_FAILURE(status)) {
0288 return (AE_OK);
0289 }
0290
0291 obj_desc->package.flags |= AOPOBJ_DATA_VALID;
0292 return (AE_OK);
0293 }
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315 static acpi_status
0316 acpi_ns_init_one_object(acpi_handle obj_handle,
0317 u32 level, void *context, void **return_value)
0318 {
0319 acpi_object_type type;
0320 acpi_status status = AE_OK;
0321 struct acpi_init_walk_info *info =
0322 (struct acpi_init_walk_info *)context;
0323 struct acpi_namespace_node *node =
0324 (struct acpi_namespace_node *)obj_handle;
0325 union acpi_operand_object *obj_desc;
0326
0327 ACPI_FUNCTION_NAME(ns_init_one_object);
0328
0329 info->object_count++;
0330
0331
0332
0333 type = acpi_ns_get_type(obj_handle);
0334 obj_desc = acpi_ns_get_attached_object(node);
0335 if (!obj_desc) {
0336 return (AE_OK);
0337 }
0338
0339
0340
0341 switch (type) {
0342 case ACPI_TYPE_REGION:
0343
0344 info->op_region_count++;
0345 break;
0346
0347 case ACPI_TYPE_BUFFER_FIELD:
0348
0349 info->field_count++;
0350 break;
0351
0352 case ACPI_TYPE_LOCAL_BANK_FIELD:
0353
0354 info->field_count++;
0355 break;
0356
0357 case ACPI_TYPE_BUFFER:
0358
0359 info->buffer_count++;
0360 break;
0361
0362 case ACPI_TYPE_PACKAGE:
0363
0364 info->package_count++;
0365 break;
0366
0367 default:
0368
0369
0370
0371 return (AE_OK);
0372 }
0373
0374
0375
0376 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
0377 return (AE_OK);
0378 }
0379
0380
0381
0382 acpi_ex_enter_interpreter();
0383
0384
0385
0386
0387
0388 switch (type) {
0389 case ACPI_TYPE_LOCAL_BANK_FIELD:
0390
0391
0392
0393 info->field_init++;
0394 status = acpi_ds_get_bank_field_arguments(obj_desc);
0395 break;
0396
0397 case ACPI_TYPE_PACKAGE:
0398
0399
0400
0401 info->package_init++;
0402 status =
0403 acpi_ns_init_one_package(obj_handle, level, NULL, NULL);
0404 break;
0405
0406 default:
0407
0408
0409
0410 status = AE_TYPE;
0411 ACPI_EXCEPTION((AE_INFO, status,
0412 "Opcode is not deferred [%4.4s] (%s)",
0413 acpi_ut_get_node_name(node),
0414 acpi_ut_get_type_name(type)));
0415 break;
0416 }
0417
0418 if (ACPI_FAILURE(status)) {
0419 ACPI_EXCEPTION((AE_INFO, status,
0420 "Could not execute arguments for [%4.4s] (%s)",
0421 acpi_ut_get_node_name(node),
0422 acpi_ut_get_type_name(type)));
0423 }
0424
0425
0426
0427
0428
0429 acpi_ex_exit_interpreter();
0430 return (AE_OK);
0431 }
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449 static acpi_status
0450 acpi_ns_find_ini_methods(acpi_handle obj_handle,
0451 u32 nesting_level, void *context, void **return_value)
0452 {
0453 struct acpi_device_walk_info *info =
0454 ACPI_CAST_PTR(struct acpi_device_walk_info, context);
0455 struct acpi_namespace_node *node;
0456 struct acpi_namespace_node *parent_node;
0457
0458
0459
0460 node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
0461 if ((node->type == ACPI_TYPE_DEVICE) ||
0462 (node->type == ACPI_TYPE_PROCESSOR) ||
0463 (node->type == ACPI_TYPE_THERMAL)) {
0464 info->device_count++;
0465 return (AE_OK);
0466 }
0467
0468
0469
0470 if (!ACPI_COMPARE_NAMESEG(node->name.ascii, METHOD_NAME__INI)) {
0471 return (AE_OK);
0472 }
0473
0474
0475
0476
0477
0478 parent_node = node->parent;
0479 switch (parent_node->type) {
0480 case ACPI_TYPE_DEVICE:
0481 case ACPI_TYPE_PROCESSOR:
0482 case ACPI_TYPE_THERMAL:
0483
0484
0485
0486 while (parent_node) {
0487 parent_node->flags |= ANOBJ_SUBTREE_HAS_INI;
0488 parent_node = parent_node->parent;
0489 }
0490 break;
0491
0492 default:
0493
0494 break;
0495 }
0496
0497 return (AE_OK);
0498 }
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514 static acpi_status
0515 acpi_ns_init_one_device(acpi_handle obj_handle,
0516 u32 nesting_level, void *context, void **return_value)
0517 {
0518 struct acpi_device_walk_info *walk_info =
0519 ACPI_CAST_PTR(struct acpi_device_walk_info, context);
0520 struct acpi_evaluate_info *info = walk_info->evaluate_info;
0521 u32 flags;
0522 acpi_status status;
0523 struct acpi_namespace_node *device_node;
0524
0525 ACPI_FUNCTION_TRACE(ns_init_one_device);
0526
0527
0528
0529 device_node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
0530 if ((device_node->type != ACPI_TYPE_DEVICE) &&
0531 (device_node->type != ACPI_TYPE_PROCESSOR) &&
0532 (device_node->type != ACPI_TYPE_THERMAL)) {
0533 return_ACPI_STATUS(AE_OK);
0534 }
0535
0536
0537
0538
0539
0540
0541
0542
0543 if (!(device_node->flags & ANOBJ_SUBTREE_HAS_INI)) {
0544 return_ACPI_STATUS(AE_CTRL_DEPTH);
0545 }
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
0559 (ACPI_TYPE_METHOD, device_node, METHOD_NAME__STA));
0560
0561 status = acpi_ut_execute_STA(device_node, &flags);
0562 if (ACPI_FAILURE(status)) {
0563
0564
0565
0566 return_ACPI_STATUS(AE_OK);
0567 }
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579 if (flags != ACPI_UINT32_MAX) {
0580 walk_info->num_STA++;
0581 }
0582
0583
0584
0585
0586
0587
0588
0589 if (!(flags & ACPI_STA_DEVICE_PRESENT)) {
0590
0591
0592
0593 if (flags & ACPI_STA_DEVICE_FUNCTIONING) {
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609 return_ACPI_STATUS(AE_OK);
0610 } else {
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622 return_ACPI_STATUS(AE_CTRL_DEPTH);
0623 }
0624 }
0625
0626
0627
0628
0629
0630
0631
0632
0633 if (!ACPI_COMPARE_NAMESEG(device_node->name.ascii, "_SB_") ||
0634 device_node->parent != acpi_gbl_root_node) {
0635 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
0636 (ACPI_TYPE_METHOD, device_node,
0637 METHOD_NAME__INI));
0638
0639 memset(info, 0, sizeof(struct acpi_evaluate_info));
0640 info->prefix_node = device_node;
0641 info->relative_pathname = METHOD_NAME__INI;
0642 info->parameters = NULL;
0643 info->flags = ACPI_IGNORE_RETURN_VALUE;
0644
0645 status = acpi_ns_evaluate(info);
0646 if (ACPI_SUCCESS(status)) {
0647 walk_info->num_INI++;
0648 }
0649 #ifdef ACPI_DEBUG_OUTPUT
0650 else if (status != AE_NOT_FOUND) {
0651
0652
0653
0654 char *scope_name =
0655 acpi_ns_get_normalized_pathname(device_node, TRUE);
0656
0657 ACPI_EXCEPTION((AE_INFO, status,
0658 "during %s._INI execution",
0659 scope_name));
0660 ACPI_FREE(scope_name);
0661 }
0662 #endif
0663 }
0664
0665
0666
0667 status = AE_OK;
0668
0669
0670
0671
0672
0673 if (acpi_gbl_init_handler) {
0674 status =
0675 acpi_gbl_init_handler(device_node, ACPI_INIT_DEVICE_INI);
0676 }
0677
0678 return_ACPI_STATUS(status);
0679 }