0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include <linux/kmemleak.h>
0012 #include "accommon.h"
0013 #include "acnamesp.h"
0014
0015 #define _COMPONENT ACPI_UTILITIES
0016 ACPI_MODULE_NAME("utobject")
0017
0018
0019 static acpi_status
0020 acpi_ut_get_simple_object_size(union acpi_operand_object *obj,
0021 acpi_size *obj_length);
0022
0023 static acpi_status
0024 acpi_ut_get_package_object_size(union acpi_operand_object *obj,
0025 acpi_size *obj_length);
0026
0027 static acpi_status
0028 acpi_ut_get_element_length(u8 object_type,
0029 union acpi_operand_object *source_object,
0030 union acpi_generic_state *state, void *context);
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
0054 *module_name,
0055 u32 line_number,
0056 u32 component_id,
0057 acpi_object_type
0058 type)
0059 {
0060 union acpi_operand_object *object;
0061 union acpi_operand_object *second_object;
0062
0063 ACPI_FUNCTION_TRACE_STR(ut_create_internal_object_dbg,
0064 acpi_ut_get_type_name(type));
0065
0066
0067
0068 object =
0069 acpi_ut_allocate_object_desc_dbg(module_name, line_number,
0070 component_id);
0071 if (!object) {
0072 return_PTR(NULL);
0073 }
0074 kmemleak_not_leak(object);
0075
0076 switch (type) {
0077 case ACPI_TYPE_REGION:
0078 case ACPI_TYPE_BUFFER_FIELD:
0079 case ACPI_TYPE_LOCAL_BANK_FIELD:
0080
0081
0082
0083 second_object =
0084 acpi_ut_allocate_object_desc_dbg(module_name, line_number,
0085 component_id);
0086 if (!second_object) {
0087 acpi_ut_delete_object_desc(object);
0088 return_PTR(NULL);
0089 }
0090
0091 second_object->common.type = ACPI_TYPE_LOCAL_EXTRA;
0092 second_object->common.reference_count = 1;
0093
0094
0095
0096 object->common.next_object = second_object;
0097 break;
0098
0099 default:
0100
0101
0102 break;
0103 }
0104
0105
0106
0107 object->common.type = (u8) type;
0108
0109
0110
0111 object->common.reference_count = 1;
0112
0113
0114
0115 return_PTR(object);
0116 }
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130 union acpi_operand_object *acpi_ut_create_package_object(u32 count)
0131 {
0132 union acpi_operand_object *package_desc;
0133 union acpi_operand_object **package_elements;
0134
0135 ACPI_FUNCTION_TRACE_U32(ut_create_package_object, count);
0136
0137
0138
0139 package_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
0140 if (!package_desc) {
0141 return_PTR(NULL);
0142 }
0143
0144
0145
0146
0147
0148 package_elements = ACPI_ALLOCATE_ZEROED(((acpi_size)count +
0149 1) * sizeof(void *));
0150 if (!package_elements) {
0151 ACPI_FREE(package_desc);
0152 return_PTR(NULL);
0153 }
0154
0155 package_desc->package.count = count;
0156 package_desc->package.elements = package_elements;
0157 return_PTR(package_desc);
0158 }
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172 union acpi_operand_object *acpi_ut_create_integer_object(u64 initial_value)
0173 {
0174 union acpi_operand_object *integer_desc;
0175
0176 ACPI_FUNCTION_TRACE(ut_create_integer_object);
0177
0178
0179
0180 integer_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
0181 if (!integer_desc) {
0182 return_PTR(NULL);
0183 }
0184
0185 integer_desc->integer.value = initial_value;
0186 return_PTR(integer_desc);
0187 }
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201 union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size)
0202 {
0203 union acpi_operand_object *buffer_desc;
0204 u8 *buffer = NULL;
0205
0206 ACPI_FUNCTION_TRACE_U32(ut_create_buffer_object, buffer_size);
0207
0208
0209
0210 buffer_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
0211 if (!buffer_desc) {
0212 return_PTR(NULL);
0213 }
0214
0215
0216
0217 if (buffer_size > 0) {
0218
0219
0220
0221 buffer = ACPI_ALLOCATE_ZEROED(buffer_size);
0222 if (!buffer) {
0223 ACPI_ERROR((AE_INFO, "Could not allocate size %u",
0224 (u32)buffer_size));
0225
0226 acpi_ut_remove_reference(buffer_desc);
0227 return_PTR(NULL);
0228 }
0229 }
0230
0231
0232
0233 buffer_desc->buffer.flags |= AOPOBJ_DATA_VALID;
0234 buffer_desc->buffer.pointer = buffer;
0235 buffer_desc->buffer.length = (u32) buffer_size;
0236
0237
0238
0239 return_PTR(buffer_desc);
0240 }
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256 union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size)
0257 {
0258 union acpi_operand_object *string_desc;
0259 char *string;
0260
0261 ACPI_FUNCTION_TRACE_U32(ut_create_string_object, string_size);
0262
0263
0264
0265 string_desc = acpi_ut_create_internal_object(ACPI_TYPE_STRING);
0266 if (!string_desc) {
0267 return_PTR(NULL);
0268 }
0269
0270
0271
0272
0273
0274 string = ACPI_ALLOCATE_ZEROED(string_size + 1);
0275 if (!string) {
0276 ACPI_ERROR((AE_INFO, "Could not allocate size %u",
0277 (u32)string_size));
0278
0279 acpi_ut_remove_reference(string_desc);
0280 return_PTR(NULL);
0281 }
0282
0283
0284
0285 string_desc->string.pointer = string;
0286 string_desc->string.length = (u32) string_size;
0287
0288
0289
0290 return_PTR(string_desc);
0291 }
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 u8 acpi_ut_valid_internal_object(void *object)
0306 {
0307
0308 ACPI_FUNCTION_NAME(ut_valid_internal_object);
0309
0310
0311
0312 if (!object) {
0313 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
0314 return (FALSE);
0315 }
0316
0317
0318
0319 switch (ACPI_GET_DESCRIPTOR_TYPE(object)) {
0320 case ACPI_DESC_TYPE_OPERAND:
0321
0322
0323
0324 return (TRUE);
0325
0326 default:
0327
0328 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0329 "%p is not an ACPI operand obj [%s]\n",
0330 object, acpi_ut_get_descriptor_name(object)));
0331 break;
0332 }
0333
0334 return (FALSE);
0335 }
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352 void *acpi_ut_allocate_object_desc_dbg(const char *module_name,
0353 u32 line_number, u32 component_id)
0354 {
0355 union acpi_operand_object *object;
0356
0357 ACPI_FUNCTION_TRACE(ut_allocate_object_desc_dbg);
0358
0359 object = acpi_os_acquire_object(acpi_gbl_operand_cache);
0360 if (!object) {
0361 ACPI_ERROR((module_name, line_number,
0362 "Could not allocate an object descriptor"));
0363
0364 return_PTR(NULL);
0365 }
0366
0367
0368
0369 ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_OPERAND);
0370
0371 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
0372 object, (u32) sizeof(union acpi_operand_object)));
0373
0374 return_PTR(object);
0375 }
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389 void acpi_ut_delete_object_desc(union acpi_operand_object *object)
0390 {
0391 ACPI_FUNCTION_TRACE_PTR(ut_delete_object_desc, object);
0392
0393
0394
0395 if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
0396 ACPI_ERROR((AE_INFO,
0397 "%p is not an ACPI Operand object [%s]", object,
0398 acpi_ut_get_descriptor_name(object)));
0399 return_VOID;
0400 }
0401
0402 (void)acpi_os_release_object(acpi_gbl_operand_cache, object);
0403 return_VOID;
0404 }
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423 static acpi_status
0424 acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
0425 acpi_size *obj_length)
0426 {
0427 acpi_size length;
0428 acpi_size size;
0429 acpi_status status = AE_OK;
0430
0431 ACPI_FUNCTION_TRACE_PTR(ut_get_simple_object_size, internal_object);
0432
0433
0434
0435 length = sizeof(union acpi_object);
0436
0437
0438
0439 if (!internal_object) {
0440
0441
0442
0443
0444 *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
0445 return_ACPI_STATUS(AE_OK);
0446 }
0447
0448
0449
0450 if (ACPI_GET_DESCRIPTOR_TYPE(internal_object) == ACPI_DESC_TYPE_NAMED) {
0451
0452
0453
0454 ACPI_ERROR((AE_INFO,
0455 "Received a namespace node [%4.4s] "
0456 "where an operand object is required",
0457 ACPI_CAST_PTR(struct acpi_namespace_node,
0458 internal_object)->name.ascii));
0459 return_ACPI_STATUS(AE_AML_INTERNAL);
0460 }
0461
0462
0463
0464
0465
0466
0467
0468 switch (internal_object->common.type) {
0469 case ACPI_TYPE_STRING:
0470
0471 length += (acpi_size)internal_object->string.length + 1;
0472 break;
0473
0474 case ACPI_TYPE_BUFFER:
0475
0476 length += (acpi_size)internal_object->buffer.length;
0477 break;
0478
0479 case ACPI_TYPE_INTEGER:
0480 case ACPI_TYPE_PROCESSOR:
0481 case ACPI_TYPE_POWER:
0482
0483
0484
0485 break;
0486
0487 case ACPI_TYPE_LOCAL_REFERENCE:
0488
0489 switch (internal_object->reference.class) {
0490 case ACPI_REFCLASS_NAME:
0491
0492
0493
0494
0495 size =
0496 acpi_ns_get_pathname_length(internal_object->
0497 reference.node);
0498 if (!size) {
0499 return_ACPI_STATUS(AE_BAD_PARAMETER);
0500 }
0501
0502 length += ACPI_ROUND_UP_TO_NATIVE_WORD(size);
0503 break;
0504
0505 default:
0506
0507
0508
0509
0510
0511 ACPI_ERROR((AE_INFO,
0512 "Cannot convert to external object - "
0513 "unsupported Reference Class [%s] 0x%X in object %p",
0514 acpi_ut_get_reference_name(internal_object),
0515 internal_object->reference.class,
0516 internal_object));
0517 status = AE_TYPE;
0518 break;
0519 }
0520 break;
0521
0522 default:
0523
0524 ACPI_ERROR((AE_INFO, "Cannot convert to external object - "
0525 "unsupported type [%s] 0x%X in object %p",
0526 acpi_ut_get_object_type_name(internal_object),
0527 internal_object->common.type, internal_object));
0528 status = AE_TYPE;
0529 break;
0530 }
0531
0532
0533
0534
0535
0536
0537
0538 *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
0539 return_ACPI_STATUS(status);
0540 }
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554 static acpi_status
0555 acpi_ut_get_element_length(u8 object_type,
0556 union acpi_operand_object *source_object,
0557 union acpi_generic_state *state, void *context)
0558 {
0559 acpi_status status = AE_OK;
0560 struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
0561 acpi_size object_space;
0562
0563 switch (object_type) {
0564 case ACPI_COPY_TYPE_SIMPLE:
0565
0566
0567
0568
0569 status =
0570 acpi_ut_get_simple_object_size(source_object,
0571 &object_space);
0572 if (ACPI_FAILURE(status)) {
0573 return (status);
0574 }
0575
0576 info->length += object_space;
0577 break;
0578
0579 case ACPI_COPY_TYPE_PACKAGE:
0580
0581
0582
0583 info->num_packages++;
0584 state->pkg.this_target_obj = NULL;
0585 break;
0586
0587 default:
0588
0589
0590
0591 return (AE_BAD_PARAMETER);
0592 }
0593
0594 return (status);
0595 }
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614 static acpi_status
0615 acpi_ut_get_package_object_size(union acpi_operand_object *internal_object,
0616 acpi_size *obj_length)
0617 {
0618 acpi_status status;
0619 struct acpi_pkg_info info;
0620
0621 ACPI_FUNCTION_TRACE_PTR(ut_get_package_object_size, internal_object);
0622
0623 info.length = 0;
0624 info.object_space = 0;
0625 info.num_packages = 1;
0626
0627 status =
0628 acpi_ut_walk_package_tree(internal_object, NULL,
0629 acpi_ut_get_element_length, &info);
0630 if (ACPI_FAILURE(status)) {
0631 return_ACPI_STATUS(status);
0632 }
0633
0634
0635
0636
0637
0638
0639 info.length +=
0640 ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)) *
0641 (acpi_size)info.num_packages;
0642
0643
0644
0645 *obj_length = info.length;
0646 return_ACPI_STATUS(status);
0647 }
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663 acpi_status
0664 acpi_ut_get_object_size(union acpi_operand_object *internal_object,
0665 acpi_size *obj_length)
0666 {
0667 acpi_status status;
0668
0669 ACPI_FUNCTION_ENTRY();
0670
0671 if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) ==
0672 ACPI_DESC_TYPE_OPERAND) &&
0673 (internal_object->common.type == ACPI_TYPE_PACKAGE)) {
0674 status =
0675 acpi_ut_get_package_object_size(internal_object,
0676 obj_length);
0677 } else {
0678 status =
0679 acpi_ut_get_simple_object_size(internal_object, obj_length);
0680 }
0681
0682 return (status);
0683 }